📄 macromanager_c.cpp
字号:
// 约束性检查
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 ¶)
{ 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 ¶)
{ 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 + -