⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macromanager_c.cpp

📁 MCS-51单片机宏汇编器源程序,单片机初学者必看
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  // 约束性检查
  if(trv->rel != 'A') { err = ExpeABSdataErr; return 0; } // endif
  if(trv->val < 0) { err = NegDatNotAllowErr; return 0; } // endif
  if(trv->typ != LB_NUM)
   { masm.OutWarning(DataTakeAsNUMWarn); } // endif
  if(not16bit(trv->val))
   { masm.OutWarning(DataBeTrun16Warn); } // endif

  TokenOper::DelExpTkn(pt->next);    // 释放表达式内存
  TokenOper::DelTokenList(pt->next); // 释放内存
  return pt->Value;           // No error.
} // end REPT_Parser
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// REPT宏 重复处理。
// err 带回错误号。
// 带Ln值返回。Ln值受影响。
//---------------------------------------------------------------------------
ERR MacrosManager::MacroREPTdo(AsmLine* &Ln)
{ ERR err;
  int16u RepVal = REPT_Parser(err, Ln); // 语法分析。
  if(err) { masm.OutputErr(err); return Have_Errs; } // endif
  // 结果存入RepVal。这是一个很重要的值(重复次数)!
  Ln = Ln->next;
  // Now, Ln指向REPT汇编行之后。可能是LOCAL,或者宏体,或者ENDM。
  MacroDefBody ReptBody(NULL);  // 创建一个无名字的宏体。
  // 因为没有Argv,ReptBody.arguPtr = NULL。
  // 寻找LOCAL语句。
  err = TryLocalParse(Ln, ReptBody.localPtr, NULL); // Ln带值返回。localPtr带值返回。
  if(err) { return err; } // endif         ?????
  // Now, Ln指向LOCAL的下一行。
  // 扫描宏体,识别其中的形参和局参,改成FormalArgv和LocalArgv。
  ReptBody.MroBodyScanAndRecg(Ln); // Ln带值返回。Ln指向ENDM。

  AsmLine* BaseLn = Ln;
  AsmLine* LastLn = Ln;
  // 把他们按重复值拷贝到ENDM后。
  for( ; RepVal != 0; --RepVal )
  { //...................................................
    // 给局参赋值。
    for( register Tokenfield* gt = ReptBody.localPtr;
             gt;
                 gt = gt->next )
     { gt->Value = AssaignLocalLabelNo(); } // end for
    // 给宏定义体初始化好形参和局参后,送宏展开,词法分析器。
    err = MacroToToken(&ReptBody,BaseLn,LastLn,LastLn);
    if(err)
     { masm.OutputErr(MacroLexErr); break; } // endif
    //...................................................
  } // end for RepVal

  Ln = BaseLn; // 重置Ln。
  return err;
} // end MacroREPTdo
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// 对遇到的Word看看是否为宏,是则进行语法分析。
// pt->Token 应该是一个WordSToken。
// 返回true为宏,返回false不是宏。带err值返回。
//---------------------------------------------------------------------------
bool MacrosManager::IsMacroAndParse(ERR &err, Tokenfield* pt)
{ err = OK_no_Err;
  Assert( if(pt->Token != WordSToken) // Just for debug !!
           { printf("\nBug in IsMacroAndParse. pt is not word."); Debugkey; } // endif
         );
  MacroDefBody* mt = MRList->SearchMacro(pt->Name); // 找该宏......
  if( !mt ) { return false; } // endif   找不到该宏
  // mt != NULL, 找到了该宏。
  pt->Token = MacroRefkn; // Token 进化!
  pt->MacroPt = mt;       // MacroRefkn 的Pt指针指向宏定义体。

  if(pt->next == NULL) // MACRO 后面没有实参了。正常返回。
   { return true; } // endif
  // 有实参,把它后面的实参parse一下。 // pt 指向实参。
  for( Tokenfield* gt = mt->arguPtr;   // gt 指向形参。
           gt && pt->next;
               gt = gt->next, pt = pt->next )
   { // Now, pt should point to a word or sth.
     register Tokenfield* t = pt->next;
     if(t->Token == ',')         // 实参直接是一个','!
      { t->Token = MroParamtn;   // Token进化!把','改成宏实参。
        t->Name  = "";           // 传递空串。
      } // endif
     else // 不是一个','
      { if(t->Token < WordSToken)         // 是其他符号
         { masm.OutputErr(ArguExcevErr); // 输入错误
           err = Have_Errs; return true;
         } // endif
        // Yes, it is a word or reserve
        t->Token = MroParamtn;   // Token进化!把Word改成宏实参。
        if(t->next && t->next->Token == ',')
         { TokenOper::DelnextTokenNode(t); } // endif
        // 已经把参数前面的逗号删除了。
      } // end else
   } // end for
  // 少了不管,多了删除。
  if(pt->next != NULL)  // 多余的参数将被去掉。
   { masm.OutWarning(ExcesParaMroWarn);
     TokenOper::DelTokenList(pt->next);
   } // endif
  return true;
} // end IsMacroAndParse
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// IRP 的语法分析。
// 输入line为IRP或IRPC所在的汇编行。
// 输出FormArgv为形参指针, ParaArgv指向LRstringKn, 内有实参字串。
//---------------------------------------------------------------------------
ERR MacrosManager::
IRP_Parse(AsmLine* line, Tokenfield* &FormArgv, Tokenfield* &ParaArgv)
{ Tokenfield* pt = line->head;
  for( ; pt && pt->Token != IRPTkn; pt = pt->next ); // end for
  // Now, pt == IRPTkn or NULL, pt->next should be a Word. or NULL.

  if(pt->next == NULL || pt->next->Token != WordSToken)
   { masm.OutputErr(MissFomArguErr); return Have_Errs; } // endif

  FormArgv = pt->next; // Now, FormArgv指向形参。

  if(FormArgv->next == NULL || FormArgv->next->Token != ',')
   { masm.OutputErr(OPadExcessErr); return Have_Errs; } // endif

  ParaArgv = FormArgv->next->next; // Now, ParaArgv指向NULL或ArgvList.
  if(ParaArgv == NULL)
   { masm.OutputErr(MissParasErr); return Have_Errs; } // endif

  FormArgv->Token = ArgvWordkn;  // Token 进化!
  TokenOper::DelnextTokenNode(FormArgv); // 删除','
  FormArgv->next = NULL;   // 结束FormArgv链表。

  pt->next = NULL;         // pt->IRP; 打断IRP后的Token链。

  if(ParaArgv->Token != LRstringKn)
   { masm.OutputErr(ParaMissLtErr); return Have_Errs; } // endif
  if(ParaArgv->next != NULL)
   { masm.OutputErr(ArguExcevErr); return Have_Errs; } // endif

  return OK_no_Err;
} // end IRP_Parse
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// 遇到IRP指令的宏展开。
//---------------------------------------------------------------------------
ERR MacrosManager::MacroIRP_do(AsmLine* &Ln)
{ ERR err;
  MacroDefBody Mbody(NULL);
  Tokenfield* ParaArgv;

  err = IRP_Parse(Ln, Mbody.arguPtr, ParaArgv); // 带值返回!
  if(err) { return Have_Errs; } // endif

  Ln = Ln->next;    // Ln不应该空。

  err = TryLocalParse(Ln, Mbody.localPtr, NULL);
  if(err) { return Have_Errs; } // endif

  Mbody.MroBodyScanAndRecg(Ln); // Ln带值返回,返回时指向ENDM。

  Tokenfield ParaToken(MroParamtn);   // 预留一个Tokenfield空间作承载。
  Mbody.arguPtr->ExpPt = &ParaToken;  // 极其重要!

  AsmLine* BaseLn = Ln;
  AsmLine* LastLn = Ln;

  // 把他们按重复值拷贝到ENDM后。
  for( ; FetchAParaWord(ParaArgv->Name, ParaToken); )
  { //...................................................
    // 给局参赋值。
    for( register Tokenfield* gt = Mbody.localPtr;
             gt != NULL;
                 gt = gt->next )
     { gt->Value = AssaignLocalLabelNo(); } // end for
    // 给宏定义体初始化好形参和局参后,送宏展开,词法分析器。
    err = MacroToToken(&Mbody,BaseLn,LastLn,LastLn);
    if(err) { masm.OutputErr(MacroLexErr); break; } // endif
    //...................................................
  } // end for RepVal

  Ln = BaseLn; // 重置Ln。
  delete ParaArgv;       // 顺便释放, 以免泄漏.
  return OK_no_Err;
} // end MacroIRP_do
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// IRPC 的语法分析。
// 输入line为IRP或IRPC所在的汇编行。
// 输出FormArgv为形参指针, ParaArgv指向LRstringKn, 内有实参字串。
//---------------------------------------------------------------------------
ERR MacrosManager::
IRPC_Parse(AsmLine* line, Tokenfield* &FormArgv, Tokenfield* &ParaArgv)
{ Tokenfield* pt = line->head;
  for( ; pt && pt->Token != IRPCTkn; pt = pt->next ); // end for
  // Now, pt == IRPTkn or NULL, pt->next should be a Word. or NULL.

  if(pt->next == NULL || pt->next->Token != WordSToken)
   { masm.OutputErr(MissFomArguErr); return Have_Errs; } // endif

  FormArgv = pt->next; // Now, FormArgv指向形参。

  if(FormArgv->next == NULL || FormArgv->next->Token != ',')
   { masm.OutputErr(OPadExcessErr); return Have_Errs; } // endif

  ParaArgv = FormArgv->next->next; // Now, ParaArgv指向NULL或ArgvList.
  if(ParaArgv == NULL)
   { masm.OutputErr(MissParasErr); return Have_Errs; } // endif

  FormArgv->Token = ArgvWordkn;  // Token 进化!
  TokenOper::DelnextTokenNode(FormArgv); // 删除','
  FormArgv->next = NULL;   // 结束FormArgv链表。

  pt->next = NULL;         // pt->IRP; 打断IRP后的Token链。

  if(ParaArgv->Token != LRstringKn)
   { masm.OutputErr(ParaMissLRtErr); return Have_Errs; } // endif
  if(ParaArgv->next != NULL)
   { masm.OutputErr(ArguExcevErr); return Have_Errs; } // endif

  return OK_no_Err;
} // end IRPC_Parse
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// 遇到IRPC指令的宏展开。
//---------------------------------------------------------------------------
ERR MacrosManager::MacroIRPC_do(AsmLine* &Ln)
{ ERR err;
  MacroDefBody Mbody(NULL);
  Tokenfield* ParaArgv;

  err = IRPC_Parse(Ln, Mbody.arguPtr, ParaArgv); // 带值返回!
  if(err) { return Have_Errs; } // endif

  Ln = Ln->next;    // Ln不应该空。

  err = TryLocalParse(Ln, Mbody.localPtr, NULL);
  if(err) { return Have_Errs; } // endif

  Mbody.MroBodyScanAndRecg(Ln); // Ln带值返回,返回时指向ENDM。

  Tokenfield ParaToken(MroParamtn);   // 预留一个Tokenfield空间作承载。
  Mbody.arguPtr->ExpPt = &ParaToken;  // 极其重要!

  AsmLine* BaseLn = Ln;
  AsmLine* LastLn = Ln;

  // 把他们按重复值拷贝到ENDM后。
  for( ; FetchAParaLetter(ParaArgv->Name, ParaToken); )
  { //...................................................
    // 给局参赋值。
    for( register Tokenfield* gt = Mbody.localPtr;
             gt != NULL;
                 gt = gt->next )
     { gt->Value = AssaignLocalLabelNo(); } // end for
    // 给宏定义体初始化好形参和局参后,送宏展开,词法分析器。
    err = MacroToToken(&Mbody,BaseLn,LastLn,LastLn);
    if(err) { masm.OutputErr(MacroLexErr); break; } // endif
    //...................................................
  } // end for RepVal

  Ln = BaseLn; // 重置Ln。
  delete ParaArgv;       // 顺便释放, 以免泄漏.
  return OK_no_Err;
} // end MacroIRPC_do
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// 从str中截取一个单词, 放入para->Name中。str带值返回。
//---------------------------------------------------------------------------
bool MacrosManager::FetchAParaWord(Jstring &str, Tokenfield &para)
{ register const char* t = (const char*)str;
  if(*t == '\0') { return false; } // endif
  register int16u i = 0;
  for( ; t[i] != '\0' && t[i] != ','; ++i )
   { if(t[i] == '!')
      { str.DelCharInStr(i); } // endif
   } // end for
  para.Name.Loadstr(str,i);
  if(t[i] != '\0') { ++i; } // endif
  str.ReplaceBySubstr(i);
  return true;
} // end FetchAParaWord
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// 从str中截取一个字母, 放入para->Name中。str带值返回。
//---------------------------------------------------------------------------
bool MacrosManager::FetchAParaLetter(Jstring &str, Tokenfield &para)
{ register const char* t = (const char*)str;
  if(*t == '\0') { return false; } // endif
  if(*t == '!') { str.DelHead(); } // endif

  para.Name.Loadstr(str,1);
  str.DelHead();
  return true;
} // end FetchAParaLetter
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
int16u MacrosManager::LocalLabelIDnum = 0;
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// end MacroManager_C.cpp
//---------------------------------------------------------------------------
//               Written by JamesyFront.    ZLGmcu Dev.Co.Ltd.  2002.
//---------------------------------------------------------------------------



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -