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

📄 labelmaniger_c.cpp

📁 单片机宏汇编器的源程序。给一些爱好者作为学习编译原理和 C 程序设计的例子.
💻 CPP
📖 第 1 页 / 共 4 页
字号:

  Lab.SetValue(result->val);  // ValueOK
  return OK_no_Err;        // OK
} // end CalLabValChk
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// 给出一个ExpToken指向的表达式的头指针,根据表达式计算结果.
// err = 0, 成功返回。
// ----- 来自OPAct's err: -----
// err = BadRelExp
// err = IllExpTypOp
// err = DividedByZero
// err = BitAddrOutRange
// err = ShiftsOverflow
// ----- 来自OPNDAct's err: -----
// err = LabNotExist     10    (Pass  x)
// err = LabNotReady     11
// err = LabValNotOk     12    (??? printf)
//---------------------------------------------------------------------------
#define getOpKn         OpKn = ( Pt ? Pt->Token : ' ' );
#define getNextOp       Pt = Pt->next; getOpKn
//---------------------------------------------------------------------------
// 根据当前汇编行,pt指向的表达式,计算表达式的值,带回err值。
//---------------------------------------------------------------------------
const TriVal* LabelManager::
CalExpr(ERR &err, Tokenfield* Pt, JLabelNode *const RfLb, bool typmode)
{ static TriVal t;  // 静态分配空间

  DebugMsg( if(Pt == NULL) { printf("\nExpr NULL error!"); return &t; } ) // debug

  if(++nest > Max_nest_depth)
   { err = StackOverFlow; masm.OutputErr(StkOverFlowErr); return NULL; } // endif

  err = OK_no_Err; TokenStack optr; TriValStack opnd;

  int16u OpKn;
  getOpKn;

  while( OpKn !=' ' || optr.Notempty() )
  { // ..................................................................
    if( IsOPTR(OpKn) ) // 是个运算符
     { // 已经得到一个运算符.
            // cout<<"\nget an OPTR ["<<(char)OpKn<<"].";
       switch( OPsuperior( optr.gettop(), OpKn ) )
       { case '<' : { optr.push(OpKn); getNextOp; break; } // end case
         case '=' : { optr.pop();      getNextOp; break; } // end case
         case '>' : { err = OPTRAct(optr, opnd); // 给err赋值
                      if(err) { DebugMsg(puts("\nExpression error!"); Debugkey;);
                                return NULL; } // endif
                      break;
                    } // end case
         default: { FatalErr(); } // end default
       } // end switch
     } // endif IsOPTR(Token)
    else // 不是运算符, 而是操作数, 则进栈。根据Pt所指向的Token,给Trival赋值。
     { err = OPNDAct(Pt, t, RfLb); // 给err赋值, 带回t, t是一个TriVal结构体。
       if(err)               // 操作数出错
        { if( typmode )   // 如果是typmode==true, 该错误err会被丢弃。
           { return &t; } // endif  立刻返回,t有值。err有值。
          if(err != LabNotReady) { return NULL; } // endif
          // err == LabNotReady
          if(!masm.Pass)   // Pass2
           { masm.OutputErr(LabelNotReadyErr); return &t; } // 报错信息。
          //else in Pass1 该错误被忽略。t仍然参加运算。
        } // endif
       opnd.push(t);                // 入栈
       getNextOp;
     } // end else
    // ..................................................................
  } // end while

  t = opnd.pop(); // No error. 得到结果。
  Assert( if( Pt || !optr.empty() || !opnd.empty() )
           { printf("\nError in OPstack!!"); Debugkey; return NULL; } // endif
         );
  if(!typmode && !err) { err = CheckTriVal(t); } // endif   // 正确性检查
  return &t;         // 返回指向 t 的指针。
} // end CalExpr
//---------------------------------------------------------------------------
#undef getOpKn
#undef getNextOp
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// 根据Pt所指向的Token,给Trival赋值。
// 出错返回err值:
// ------ 来自CalLabelValue(). -------
// err = LabNotExist     10    (Pass  x)
// err = LabNotReady     11
// err = LabValNotOk     12    (??? printf)
//---------------------------------------------------------------------------
ERR LabelManager::OPNDAct(Tokenfield* Pt, TriVal &t, JLabelNode *const RfLb)
{ // 对不同的Token做不同的动作。
  switch(Pt->Token)
  { case ValueToken:
     { t.evaluate(Pt->Value, LB_NUM, 'A', NULL); // seg==NULL,表示不属于任何段
       return OK_no_Err;           // no error
     } // end case
    case RegisterKn:
     { t.evaluate(Pt->Token2, LB_REG, 'A', NULL); // seg==NULL,表示不属于任何段
       return OK_no_Err;           // no error
     } // end case
    case WordSToken:
     { ERR err;
       JLabelNode* Lt = SearchLabelCal(Pt->Name, err, RfLb); // err带值返回。
       // 查找并计算标号, 带回err值。也带回了指向标号的指针。
       switch(err)
       { case OK_no_Err:      // 标号中的Value已得到 <==> No err.
          { if(Lt->Attrb == 'E')
             { t.evaluatE(0, Lt->vv.LBLTyp, 'E', Lt->GetExtID()); return OK_no_Err; } // endif
            else
             { t.evaluate(Lt->Value, Lt->vv.LBLTyp, Lt->Attrb, Lt->RefSeg); return OK_no_Err; } // end else
          } // end case
         case LabNotReady: // 标号中的Value未得到  <==> err == Have_Errs
          { // 错误仅仅是LabNotReady, 用虚值代替Value。(用于typemode)
            t.evaluate((int16u)Lt->Value, Lt->vv.LBLTyp, Lt->Attrb, Lt->RefSeg);
            return LabNotReady;
          } // end case
         case LabNotExist:
          { t.evaluate(0, LB_NUM, 'A', NULL);
            return LabNotExist;
          } // end case
         default : { return err; } // with err
       } // end switch
     } // end case
    case    '$'    :    // 地址计数器
     { if(masm.Ln->IsOK)     // 当前汇编行的地址OK
        { t.evaluate( masm.Ln->lc,           // 当前行lc
                      masm.Ln->sgpt->GetSegType(), // 当前段类型,要求(LB_CODE==SEG_CODE)
                      masm.Ln->sgpt->GetRelType(),
                      masm.Ln->sgpt );
          return OK_no_Err;
        } // endif
       else   // (Ln->IsOK == false)
        { t.evaluate( masm.SegPt->SegLc,     // 虚值
                      masm.SegPt->GetSegType(), // 当前段类型,要求(LB_CODE==SEG_CODE)
                      masm.SegPt->GetRelType(),
                      masm.SegPt );
          return LabNotReady;
        } // end else
     } // end case
    default: { EThrows(puts("\nOPNDAct out of run!"); Debugkey;)
               return Have_Errs; } // end default
  } // end switch
} // end OPNDAct
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// 对TriVal进行正确性检查。
//---------------------------------------------------------------------------
ERR LabelManager::CheckTriVal(TriVal &t)
{   // 正确性检查
  if(t.typ == LB_NUM) { return OK_no_Err; } // endif // no error
  if(t.val < 0)
   { masm.OutWarning(NegTakeAsCplxWarn); } // endif
  switch(t.typ)
  { case LB_BIT:
     { if(not8bit(t.val))    // 7 bit addr out of range. ??
        { masm.OutputErr(BitAddrOutRangeErr); return BitAddrOutRange; } // endif
        break;         // no error
     } // end case
    case LB_DATA:    case LB_IDATA:
     { if(not8bit(t.val))    // 8 bit addr out of range.
        { masm.OutputErr(DATAOutRangeErr); return DATAAddrOutRange; } // endif
       break;         // no error
     } // end case
    case LB_CODE:    case LB_XDATA:    case LB_SEG:
     { if(not16bit(t.val))
        { masm.OutputErr(LocAddrOutRangeErr); return LocAddrOutRange; } // endif
       break;         // no error
     } // end case   
    case LB_REG:
     { if( t.val < _R0 || t.val > _A_PC )
        { masm.OutputErr(REGOutRangeErr); return REGOutRange; } // endif
       break;         // no error
     } // end case
    default : { EThrows(cout<<"\nCheckTriVal out of run!"; Debugkey;)
                return Have_Errs; } // end default
  } // end switch
  return OK_no_Err;
} // end CheckTriVal
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
#define pop2AndAct(func);                                                       \
          TriVal b = opnd.pop();                                                \
          TriVal a = opnd.pop();                                                \
          err = func(a, b, a);                                                  \
          if(err) { return err; }                                               \
          opnd.push(a);
//---------------------------------------------------------------------------
#define pop1AndAct(func);                                                       \
          TriVal a = opnd.pop();                                                \
          err = func(a);                                                        \
          if(err) { return err; }                                               \
          opnd.push(a);
//---------------------------------------------------------------------------
#define pop_And_Call(func);                                                     \
          TriVal a = opnd.pop();                                                \
          err = func(a, optr);                                                  \
          if(err) { return err; }                                               \
          opnd.push(a);
//---------------------------------------------------------------------------
ERR LabelManager::OPTRAct(TokenStack &optr, TriValStack &opnd)
{ ERR err;
  switch(optr.pop())
  { // 双目运算
    case '+' : { pop2AndAct(OPAdd); break; } // end case
    case '-' : { pop2AndAct(OPSub); break; } // end case
    case '*' : { pop2AndAct(OPMul); break; } // end case
    case '/' : { pop2AndAct(OPDiv); break; } // end case
    case '%' : { pop2AndAct(OPMod); break; } // end case
    case '.' : { pop2AndAct(OPDot); break; } // end case

    case AND : { pop2AndAct(OPAnd); break; } // end case
    case  OR : { pop2AndAct(OPOr);  break; } // end case
    case XOR : { pop2AndAct(OPXor); break; } // end case

    case '=' : { pop2AndAct(OPEqu); break; } // end case
    case '<' : { pop2AndAct(OPLes); break; } // end case
    case '>' : { pop2AndAct(OPGrt); break; } // end case

    case GRtEQUKen: { pop2AndAct(OPGrtEqu); break; } // end case
    case LessEQUKn: { pop2AndAct(OPLesEqu); break; } // end case
    case NotEqual : { pop2AndAct(OPNotEqu); break; } // end case

    case SHL : { pop2AndAct(OPShl); break; } // end case
    case SHR : { pop2AndAct(OPShr); break; } // end case

    // 单目运算
    case NOT : { pop1AndAct(OPNot);    break; } // end case
    case HIGH: { pop_And_Call(OPHigh); break; } // end case
    case LOW:  { pop_And_Call(OPLow);  break; } // end case

    case SingleNeg : { pop1AndAct(OPNeg); break; } // end case
    case SinglePlus: { pop1AndAct(OPPlus); break; } // end case

    default  : EThrows(cout<<"\nOPTR ACT out of run!!";) Debugkey; return UnknownOPs;
  } // end switch
 return OK_no_Err;
} // end OPTRAct
//---------------------------------------------------------------------------
#undef pop2AndAct
#undef pop1AndAct
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
//    HIGH A
//---------------------------------------------------------------------------
ERR LabelManager::OPHigh(TriVal &a, TokenStack& optr)
{ if(not16bit(a.val)) // Only can "HIGH" data <= 16-bit

⌨️ 快捷键说明

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