📄 labelmaniger_h.h
字号:
//---------------------------------------------------------------------------
//-------- LabelManiger_H.h -------------------------------------------------
//---------------------------------------------------------------------------
#ifndef LabelManiger_H.h // 防止被重复引用
#define LabelManiger_H.h
//---------------------------------------------------------------------------
#include "JsGlobal_H.h"
#include "JLabelNode_H.h"
#include "TriVal_H.h"
#include "OBJrecord_H.h"
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 特殊功能寄存器信息描述结构体
//---------------------------------------------------------------------------
struct SpecialRegs
{ char* name; // 名称
int8u vtyp; // 类型(DATA, BIT)
int8u addr; // 地址
}; // end SpecialRegs
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
// 标号, 变量 计算器, 管理器
//
//---------------------------------------------------------------------------
typedef int32(*TvFuncPt)(int32 a, int32 b); // 指向函数的指针。
const int8u Max_nest_depth = 16; // 表达式最大嵌套层数。
const int8u MaxNameLen = 40; // 标号名字最大长度。
const int16u Max_LBL_Sum = 65530; // 链表最大长度。
//---------------------------------------------------------------------------
// 标号, 变量 计算器, 管理器
//---------------------------------------------------------------------------
class LabelManager : public JObject
{ private:
MacroAsmber& masm; // 指向他的父亲
JLabelNode* head; // 标号表头
JLabelNode* tail; // 标号表尾
int16u LBL_NUM; // 标号表的表长
int8u nest; // 表达式嵌套计数器
// ------ private functions ------
static int32 ValueAnd(int32 a, int32 b) { return a & b; } // 内部函数。
static int32 ValueOr (int32 a, int32 b) { return a | b; } // 内部函数。
static int32 ValueXor(int32 a, int32 b) { return a ^ b; } // 内部函数。
static int32 ValueEqu(int32 a, int32 b) { return a == b; } // 内部函数。
static int32 ValueLes(int32 a, int32 b) { return a < b; } // 内部函数。
static int32 ValueGrt(int32 a, int32 b) { return a > b; } // 内部函数。
static int32 ValueNotEqu(int32 a, int32 b) { return a != b; } // 内部函数。
static int32 ValueLesEqu(int32 a, int32 b) { return a <= b; } // 内部函数。
static int32 ValueGrtEqu(int32 a, int32 b) { return a >= b; } // 内部函数。
static int32 ValueShl(int32 a, int32 b) { return a << b; } // 内部函数。
static int32 ValueShr(int32 a, int32 b) { return a >> b; } // 内部函数。
ERR OPEquLesGrt(TriVal &a, TriVal &b, TriVal &c, TvFuncPt fun); // 内部函数。
ERR OPAndOrXor(TriVal &a, TriVal &b, TriVal &c, TvFuncPt fun); // 内部函数。
ERR OPShlShr(TriVal &a, TriVal &b, TriVal &c, TvFuncPt fun); // 内部函数。
ERR OPAdd(TriVal &a, TriVal &b, TriVal &c); // c = a + b
ERR OPSub(TriVal &a, TriVal &b, TriVal &c); // c = a - b
ERR OPMul(TriVal &a, TriVal &b, TriVal &c); // c = a * b
ERR OPDiv(TriVal &a, TriVal &b, TriVal &c); // c = a / b
ERR OPMod(TriVal &a, TriVal &b, TriVal &c); // c = a % b
ERR OPDot(TriVal &a, TriVal &b, TriVal &c); // c = a . b
ERR OPNot(TriVal &a); // a = NOT a
ERR OPPlus(TriVal &a); // a = + a
ERR OPNeg(TriVal &a); // a = - a
ERR OPHigh(TriVal &a, TokenStack& optr); // a = HIGH a
ERR OPLow(TriVal &a, TokenStack& optr); // a = LOW a
ERR OPShl(TriVal &a, TriVal &b, TriVal &c)
{ return OPShlShr(a, b, c, ValueShl); } // c = a SHL b;
ERR OPShr(TriVal &a, TriVal &b, TriVal &c)
{ return OPShlShr(a, b, c, ValueShr); } // c = a SHR b;
ERR OPAnd(TriVal &a, TriVal &b, TriVal &c)
{ return OPAndOrXor(a, b, c, ValueAnd); } // c = a AND b;
ERR OPOr(TriVal &a, TriVal &b, TriVal &c)
{ return OPAndOrXor(a, b, c, ValueOr); } // c = a OR b;
ERR OPXor(TriVal &a, TriVal &b, TriVal &c)
{ return OPAndOrXor(a, b, c, ValueXor); } // c = a XOR b;
ERR OPEqu(TriVal &a, TriVal &b, TriVal &c)
{ return OPEquLesGrt(a, b, c, ValueEqu); } // c = a EQ b;
ERR OPLes(TriVal &a, TriVal &b, TriVal &c)
{ return OPEquLesGrt(a, b, c, ValueLes); } // c = a LT b;
ERR OPGrt(TriVal &a, TriVal &b, TriVal &c)
{ return OPEquLesGrt(a, b, c, ValueGrt); } // c = a GT b;
ERR OPGrtEqu(TriVal &a, TriVal &b, TriVal &c)
{ return OPEquLesGrt(a, b, c, ValueGrtEqu); } // c = a GE b;
ERR OPLesEqu(TriVal &a, TriVal &b, TriVal &c)
{ return OPEquLesGrt(a, b, c, ValueLesEqu); } // c = a LE b;
ERR OPNotEqu(TriVal &a, TriVal &b, TriVal &c)
{ return OPEquLesGrt(a, b, c, ValueNotEqu); } // c = a NE b;
// 规限标号名字的长度。(MaxNameLen)
void TruncLBsName(Jstring& name);
// 内部函数。计算表达式,返回指针。
const TriVal* CalExpr(ERR &err, Tokenfield* Pt,
JLabelNode *const RfLb, bool typmode);
// 往标号链表中添加一个标号节点。
// 节点已创建好,输入该结点的指针进行操作。
void AddLabelNode(JLabelNode* t); // 添加一个结点
// 根据Lab中pt指向的表达式,给Lab标号的Value赋值,并作检查。
ERR CalLabValChk(JLabelNode &Lab); // 对Lab进行处理。
// 表达式操作符栈操作。
ERR OPTRAct(TokenStack &optr, TriValStack &opnd);
// 表达式操作数栈操作。给TriVal赋值。
ERR OPNDAct(Tokenfield* Pt, TriVal &t, JLabelNode *const RfLb);
public:
LabelManager(MacroAsmber& m); // constructor
~LabelManager(); // destructor
// ----- public functions ----------
// 标号管理器初始化时预装标号的标号装载器。
void LoadSFR51(SpecialRegs* init); // 装载特别功能寄存器信息。
// 表达式嵌套计数器清零。(应该在每次计算表达式的入口调用。)
void clearNest() { nest = 0; } // end clearNest
// 得到链表中标号的总数。
int16u GetLabelSum() { return LBL_NUM; } // end GetLabelSum
// 初始化头结点, 使tp指向链表中的第一个节点(不包括头节点)。
void InitListPtr(JLabelNode* &tp) { tp = head->next; } // end InitListPtr
// 在使用标号链表前,需要预先添加的结点(名称,类型,地址)。
void LabelPreAdd(const Jstring& name, char typ, int32 val);
// 从beginning开始查找一个标号。查到返回true。返回标号名称和结点指针。
bool SearchLabel(const Jstring& str, JLabelNode* &p,
JLabelNode *const beginning = NULL);
// 总是从链表头开始查找一个标号。查到返回true。返回标号名称和结点指针。
bool SearchLinkList(const Jstring& str, JLabelNode* &p);
// 整理标号
ERR LabelFresh();
// 检查输入的TriVal的正确性。
ERR CheckTriVal(TriVal &t);
// 根据给出的标号名,找到该标号, 如果ValOK,返回该标号,否则返回NULL.
// 如果发生各种各样的错误,则带回相应的错误码。
// 它是SearchLabel()的增强版。RfLb是搜索参考点。
// 该程序会对标号的Value和ValOK进行操控。
JLabelNode* SearchLabelCal(const Jstring& name, ERR &err, JLabelNode *const RfLb);
// 数值表达式计算入口。
const TriVal* CalExpression(ERR &err, Tokenfield* Pt,
JLabelNode *const RfLb = NULL, bool typmode = false);
// 往表中添加标号结点,标号名为Name, 并返回指针。如果有err,添加失败。
// 如果pt==NULL, 则不计算Value值。否则根据pt所指的表达式计算Value值。
// 如果var==true, 则添加的标号为变量。否则为常量。
// Crln是创建该标号的行号。Ind==true是间接寻址,Ext==true是外部变量。
JLabelNode* AddLabel( ERR &err, Jstring &name, int8u labelTp,
bool var, AsmLine* Crln, Tokenfield* pt,
ASM_Segment* rSeg = NULL, bool Ind = false,
bool Ext = false );
// 根据创建顺序对标号排序。在显示时才用,计算时不能用。调用后不能再计算表达式。
void SortLabelByCrno();
// 找出链表中的下一个PUBLIC标号(参照点为tp)。
JLabelNode* GetAPublicLabel(JLabelNode* &tp);
// 找出链表中的下一个LOCAL标号(参照点为tp)。
JLabelNode* GetALocalLabel(JLabelNode* &tp);
// ----- debug functions -------------------
void ShowLabelList();
// ----- friend members --------------------
friend class MacroAsmber;
friend class OBJmodule;
friend class LISTFile;
}; // end LabelManager
//---------------------------------------------------------------------------
//------ 构造器 -------------------------------------------------------------
inline LabelManager::LabelManager(MacroAsmber& m)
: masm(m), LBL_NUM(0), nest(0)
{ tail = head = new JLabelNode("", NULL, LB_CODE, 'A'); // 初始化链头
} // end constructor
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
// 内联函数实现
//
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 往表里预添加一个常量.
//---------------------------------------------------------------------------
inline void LabelManager::LabelPreAdd(const Jstring& name, char typ, int32 val)
{ // 创建一个预定义的新结点
// JLabelNode( const Jstring& name, int8u labelTp, int8u atrb,
// bool var = false,
// AsmLine* crln = NULL,
// ASM_Segment* refSeg = NULL,
// Tokenfield* expt = NULL,
// bool Ind = false ) : Value(0),ValOk(false),next(NULL)
JLabelNode* temp = new JLabelNode( name, NULL, typ, 'A' ); // Create a node.
temp->SetValue(val); // ValOK now is true.
AddLabelNode(temp); // Add into the linklist.
} // end LabelPreAdd
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
inline const TriVal* LabelManager::
CalExpression(ERR &err, Tokenfield* Pt, JLabelNode *const RfLb, bool typmode)
{ clearNest();
return CalExpr(err, Pt, RfLb, typmode);
} // end CalExpression
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 错误消息
//---------------------------------------------------------------------------
#define DividedByZero 1
#define BitAddrOutRange 2
#define LocAddrOutRange 3
#define ShiftsOverflow 4
#define DATAAddrOutRange 5
#define REGOutRange 6
#define StackOverFlow 9
//---------------------------------------------------------------------------
#define LabNotExist 10
#define LabNotReady 11
#define LabValNotOk 12
#define LabelNameDulplicated 13
#define LabelTypeNotMatch 14
#define BadRelExp 15
#define IllExpTypOp 16
#define ShiftsOuts 17
#define DataExceedLen 18
#define LabelNameTooLong 19
#define UnknownOPs 20
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
// Written by JamesyFront. ZLGmcu Dev.Co.Ltd. 2002.
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -