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

📄 labelmaniger_h.h

📁 单片机宏汇编器的源程序。给一些爱好者作为学习编译原理和 C 程序设计的例子.
💻 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 + -