📄 masmber_c6.cpp
字号:
//---------------------------------------------------------------------------
//-------- MAsmber_C6.cpp ---------------------------------------------------
//---------------------------------------------------------------------------
#include "MAsmber_H.h"
#include "AsmF_H.h"
#include "OBJfile_H.h"
#include "ListFile_H.h"
#include "OBJModule_H.h"
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
// 控制汇编的指令处理群
//
//---------------------------------------------------------------------------
#define DebugKit(str) DebugMsg(str)
//---------------------------------------------------------------------------
// 从字串str中取出数字放入val。遇到数字后面的','自动去除。
// str受影响。报错时,需要使用Ln。
// err = 0: ok; err = 1: error; 不是数串 err = 255: end。
//---------------------------------------------------------------------------
ERR MacroAsmber::FetchVal(int32u &val, Jstring &str)
{ val = 0;
char* behind; int16u len;
char ss[256];
Jassert(str.getLen()<255);
const char* aNumWord = GetNumWord(str.makeStr(ss), len, behind); // 到字串str里找一个数字或单词。
// 如果是单词和数开头,返回一个指向串中第一个单词和数的指针。
// len返回单词长度, behind指向单词后一个字符。
// 不是单词和数开头,则返回NULL。len=0,behind指向文本行中的第一个可见符或者行末。
if(aNumWord != NULL)
// Now, 得到了一个单词和数
{ Jstring ts(aNumWord,len);
if( ts.ValueStrToValue(val) ) // val 带值返回。
{ if(*behind == ',') { ++behind; } // endif
str = behind; // !! 此处修改了str!
return OK_no_Err;
} // endif
else // 不是数串
{ OutputErr(ArguExcevErr); return Have_Errs; } // end else
} // endif
else
{ return 255; } // end else
} // end FetchVal
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 根据输入的字串str提取参数,设置REGISTERBANK。
//---------------------------------------------------------------------------
ERR MacroAsmber::RegBank_Do(Jstring &str) // 注意, 这里是传引用!
{ if( str.IsEmpty() )
{ OutputErr(ArguInsufErr); return Have_Errs; } // endif
JModulePt->NoRegBank();
ERR err; int8u i;
for( i = 0; i < 4; ++i )
{ register int32u val;
err = FetchVal(val, str); // val, str 带值返回。
if(err) { break; } // endif break from for i
if(val > 3)
{ OutputErr(UsingWrongErr); return Have_Errs; } // endif
JModulePt->setUseBank((int8u)val); // 对RegBank进行设置。
} // end for
if(err == 255) { err = OK_no_Err; } // endif
if( str.IsNotEmpty() )
{ OutputErr(ArguExcevErr); err = Have_Errs; } // endif
return err;
} // end RegBank_Do
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
ERR MacroAsmber::Date_Do(Jstring &str) // 注意, 这里是传引用!
{ int32u val[3];
ERR err; int8u i;
for( i = 0; i < 3; ++i )
{ err = FetchVal(val[i], str); // val, str 带值返回。
if(err) { break; } // endif break from for i
} // end for
if(err == 255) { err = OK_no_Err; } // endif
if(err) { return err; } // endif
if( str.IsNotEmpty() )
{ OutputErr(ArguExcevErr); return Have_Errs; } // endif
// Now, no error. Set the date.
if(val[0]>=100 && val[1]<=12 && val[2]<=31 )
{ LstFilePt->jdate.year = val[0];
LstFilePt->jdate.month = val[1];
LstFilePt->jdate.day = val[2];
return OK_no_Err;
} // endif
if(val[0]<=31 && val[1]<=12)
{ LstFilePt->jdate.day = val[0];
LstFilePt->jdate.month = val[1];
LstFilePt->jdate.year = val[2];
return OK_no_Err;
} // endif
OutWarning(NumOutRangeWarn);
return OK_no_Err;
} // end Date_Do
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#define ItisWrong_BeSkip(p) (p)->Token2 = Dog_Skip; pt = pt->next;
//---------------------------------------------------------------------------
// 测试所带参数是否为空。为使报错时该行存在,所以节点不能删除。
//---------------------------------------------------------------------------
#define EmptyThenWarn(p,warn) \
if((p)->Name.IsEmpty()) \
{ OutWarning(warn); ItisWrong_BeSkip(p); break; }
//---------------------------------------------------------------------------
#define TestConflictAndSet(bn,p); \
if(bn) { OutputErr(CtrlConflictErr); ItisWrong_BeSkip(p); break; } \
(bn) = true;
//---------------------------------------------------------------------------
#define DoneAndRemoveItBreak(); \
TokenOper::DelTokenNode(pt->next); break;
//---------------------------------------------------------------------------
#define MajorCtrlSolution(bn,p,statements) \
TestConflictAndSet(bn,p); \
statements \
DoneAndRemoveItBreak();
//---------------------------------------------------------------------------
#define Do_If_err_Break(statement) \
err = statement; \
if(err) { ItisWrong_BeSkip(p); break; }
//---------------------------------------------------------------------------
// 首要汇编控制指令语法分析器。(其参数就在Name域中。)
//---------------------------------------------------------------------------
ERR MacroAsmber::MajorCtrlParse(AsmLine* &line)
{ ERR err = OK_no_Err;
// printf("\n\n\n $Major control here.\n\n");
Tokenfield* pt;
for( pt = line->head; pt->next; ) // 一个接一个Token分析。
{ register Tokenfield* p = pt->next; // p是当前分析的Token,pt是p的上一个。
if(p->Token != Dog_Ctrl)
{ OutputErr(DogCtrlIllErr); err = Have_Errs; break; } // endif
switch(p->Token2)
{ case DEBUG_Tn :
{ MajorCtrlSolution(xBn.db_bn, p, JModulePt->SetDebug(true); ); } // end case
case NODEBUG_Tn:
{ MajorCtrlSolution(xBn.db_bn, p, JModulePt->SetDebug(false); ); } // end case
case RB_Tn :
{ MajorCtrlSolution(xBn.rb_bn, p, Do_If_err_Break( RegBank_Do(p->Name) ) ); } // end case
case NORB_Tn :
{ MajorCtrlSolution(xBn.rb_bn, p, JModulePt->NoRegBank(); ); } // end case
case NOMOD51_Tn:
{ MajorCtrlSolution(xBn.mo_bn, p, SFR51 = false; ); } // end case
case MOD51_Tn :
{ MajorCtrlSolution(xBn.mo_bn, p, SFR51 = true; ); } // end case
case TITLE_Tn : { TestConflictAndSet(xBn.tt_bn,p); // 冲突测试。
EmptyThenWarn(p,MissTitleWarn); // 有错,不删除节点。
LstFilePt->Title = p->Name; // 列表文件的标题改为TITLE!
DoneAndRemoveItBreak();
} // end case
case DATE_Tn : { TestConflictAndSet(xBn.da_bn,p); // 冲突测试。
EmptyThenWarn(p,MissDateWarn); // 有错,不删除节点。
Do_If_err_Break( Date_Do(p->Name) )
DoneAndRemoveItBreak();
} // end case
case ERR_PR_Tn :
{ TestConflictAndSet(xBn.ep_bn,p); ErrPrint = true;
EpFile.SetEPfile(err, p->Name);
if(err) { OutputErr(spFileOpenErr); ItisWrong_BeSkip(p); } // endif
else { TokenOper::DelTokenNode(pt->next); } // end else
break;
} // end case
case NO_EP_Tn :
{ MajorCtrlSolution(xBn.ep_bn, p, ErrPrint = false; ); } // end case
case OBJOJ_Tn :
{ MajorCtrlSolution(xBn.oj_bn, p, ObjFile = true;
if(p->Name.IsNotEmpty()) { objFilePt->FileName = p->Name; } // endif
);
} // end case
case NOOJ_Tn :
{ MajorCtrlSolution(xBn.oj_bn, p, ObjFile = false; ); } // end case
case PR_Tn :
{ MajorCtrlSolution(xBn.pr_bn, p, LstFile = true;
if(p->Name.IsNotEmpty()) { LstFilePt->FileName = p->Name; } // endif
);
} // end case
case NOPR_Tn :
{ MajorCtrlSolution(xBn.pr_bn, p, LstFile = false; ); } // end case
case SB_Tn :
{ MajorCtrlSolution(xBn.sb_bn, p, LstFilePt->setn.symbols = true; ); } // end case
case NOSB_Tn :
{ MajorCtrlSolution(xBn.sb_bn, p, LstFilePt->setn.symbols = false; ); } // end case
case XR_Tn :
{ MajorCtrlSolution(xBn.xr_bn, p, LstFilePt->setn.Xref = true;
LstFilePt->setn.symbols = true; ); } // end case
case NOXR_Tn :
{ MajorCtrlSolution(xBn.xr_bn, p, LstFilePt->setn.Xref = false; ); } // end case
case COND_Tn :
{ MajorCtrlSolution(xBn.co_bn, p, noCond = false; ); } // end case
case NOCOND_Tn :
{ MajorCtrlSolution(xBn.co_bn, p, noCond = true; ); } // end case
case MARO_Tn :
{ MajorCtrlSolution(xBn.ma_bn, p, Dismacro = false; ); } // end case
case NOMARO_Tn :
{ MajorCtrlSolution(xBn.ma_bn, p, Dismacro = true; ); } // end case
/*
case PGLEN_Tn :
{ MajorCtrlSolution(pl_bn, p, // do sth
); } // end case
case PGWIDTH_Tn:
{ MajorCtrlSolution(pw_bn, p, // do sth
); } // end case
*/
default : { pt = pt->next; } // end default
} // end switch
} // end for
return err;
} // MajorCtrlParse
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 遇上INCLUDE控制指令的操作。
//---------------------------------------------------------------------------
inline void MacroAsmber::
Case_Include_Do(ERR &err, AsmLine* &line, Tokenfield* &p)
{ if(p->next != NULL) // 把INCLUDE后面的命令移到下一行。
{ AsmLine* newln = new AsmLine;
newln->LineNo = line->LineNo; // 给新行赋行号值
newln->Includ = true; // 打上一个标记。
newln->HeadToken()= MacroCTRLn;
newln->head->next = p->next;
p->next = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -