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

📄 caslutil.cpp

📁 这是一个软件水平资格考试中使用的CASL汇编语言的编译器,实现文件中包括一个编译器,一个虚拟机,一个类似于Debug的调试器.
💻 CPP
📖 第 1 页 / 共 4 页
字号:

#include "Stdafx.h"
#include "CaslUtil.h"
#include "CodeTypeDef.h"
#include <algorithm>
#include "aslIFStream.h"
#include "aslOFStream.h"
#include "XmlErrorHandler.h"


extern int g_iVariableSize;
extern int g_iConstSize;
extern new_handler g_OldNewHandler;
extern vector<CaslConst> g_vecConst;   //常量表
extern vector<VariableLabelItem> g_vecVariableLabel; //变量标号表
extern vector<ConstLabelItem> g_vecConstLabel;       //常量标号表
extern vector<InstructionLabelItem> g_vecInstructionLabel; //指令标号表
extern vector<ObjectCode>   g_vecObjectCode;                //存放生成的目标代码的vector
extern vector<IntermediateCode> g_vecIntermediateCode;  //中间代码表
extern char g_szInstructionName[][INSTRUCTION_NAME_SIZE];    //指令类型名称数组
extern vector<string> g_vecSingleOperandInstructionName;   //使用单指令操作数的指令的名称vector
extern vector<string> g_vecNoOperandInstructionName;       //不使用操作数的指令的名称vector
extern vector<CompilingErrMsg> g_vecErrMsg;
extern vector<InstructionDebugInfo> g_vecVisualDebugInfo;   //可视化调试信息vector

#include <string>

namespace CaslUtil{
  
  //////////////////////////////////////////////////////////////
  //自定义宏,将int型的数据的低十六位数据赋给一个双byte数组
  //dataInt--------------int型数据
  //dataDByte------------一个unsigned char[2]的数组
  //////////////////////////////////////////////////////////////
  #define ASSIGN_INT_TO_DBYTE(dataInt, dataDByte)    \
          {   \
            int iTemp = (dataInt);     \
            unsigned char * pTemp = (dataDByte);   \
            unsigned char * pSrc = (unsigned char*)&(iTemp);   \
            *pTemp = *pSrc;   \
            *(pTemp + 1) = *(pSrc + 1);    \
          }

  int  ConvertDByteToInt(unsigned char dataDByte[2])    
  {     
    int iRet = 0;   
    unsigned char * pSrc = dataDByte;   
    unsigned char * pRet = (unsigned char*)&iRet;  
    *pRet = *pSrc;   
    *(pRet + 1) = *(pSrc + 1);   
    return iRet;  
  }
  


  //////////////////////////////////////////////////////////////////
  //函数名称:GetValueOfStringConst
  //函数功能:获得字符串常量的实际数值(实际上就是去除字符串两边的单引号) 
  //入口参数:char * argSrc----------------要被处理的字符串
  //出口参数:char * argSrc----------------处理以后的字符串
  //返回值:CaslUtilStatus---------返回操作后的状态码
  //开发人员:杨军
  //开发日期:2004-3-18
  //修改人员:
  //修改日期:
  //////////////////////////////////////////////////////////////////
  CaslUtilStatus GetValueOfStringConst(char * argSrc)
  {
    int iLen = strlen(argSrc);
    if (NULL == argSrc)     //源字符串为空
    {
      return STRING_NULL;   
    }
    if (iLen > MAX_STR_SIZE)  //源字符串过长
    {
      return STRING_TOO_LONG;
    }
    if (iLen < 2)            //源字符串过短
    {
      return STRING_TOO_SHORT;
    }
    //为提高效率,考虑引入汇编处理这种共通函数
    if ('\'' == argSrc[0] && '\'' == argSrc[iLen - 1])
    {
      argSrc[iLen - 1] = '\0';
      strcpy(argSrc, argSrc + 1);
    }
    else
    {
      return STRING_CONST_INVALID;   //不是合法的字符串常量格式
    }
    return CASL_UTIL_OP_OK;
  }

  
  //////////////////////////////////////////////////////////////////
  //函数名称:GetValueOfHexConst
  //函数功能:获得十六进制常量的实际数值
  //入口参数:const char * argSrc---------十六进制常量的字符串格式数据(不带'#'号,只含十六进制的数据位部分)
  //出口参数:int& argDataOut------------十六进制常量的实际数据值
  //返回值:CaslUtilStatus----------------操作状态,CASL_UTIL_OP_OK表示操作成功,其他表示操作失败
  //开发人员:杨军
  //开发日期:2004-3-18
  //修改人员:
  //修改日期:
  //////////////////////////////////////////////////////////////////
  CaslUtilStatus GetValueOfHexConst(const char * argSrc, int& argDataOut)
  {
    int iTemp = 0;

    int i = 0;
    int iLen = strlen(argSrc);

    if (NULL == argSrc)     //源字符串为空
    {
      return STRING_NULL;   
    }
    if (iLen <= 0)            //源字符串过短
    {
      argDataOut = 0;
    }
    argDataOut = 0;
    //计算实际的十六进制数据
    for (i = 0; i < iLen;  i++)
    {
      if ('0' <= argSrc[i] && argSrc[i] <= '9')
      {
        iTemp = argSrc[i] - '0';
      }
      else if ('A' <= argSrc[i] && argSrc[i] <= 'F')
      {
        iTemp = argSrc[i] - 'A' + 10;
      }
      else if ('a' <= argSrc[i] && argSrc[i] <= 'f')
      {
        iTemp = argSrc[i] - 'a' + 10;
      }
      else
      {
        return HEX_CONST_INVALID;  //十六进制数格式有误
      }
      argDataOut = argDataOut * 0x10 + iTemp;
    }
    return CASL_UTIL_OP_OK;
  }
  
  //////////////////////////////////////////////////////////////////
  //函数名称:MakeVariableLabelTable
  //函数功能:依据中间代码变量表生成变量标号表,供生成目标代码使用
  //入口参数:const vector<CaslVariable>& argVecSrc---------------中间代码变量表
  //出口参数:vector<VariableLabelItem>& argVecDst----------------生成的变量标号表
  //返回值:CaslUtilStatus----------------操作状态,CASL_UTIL_OP_OK表示操作成功,其他表示操作失败
  //开发人员:杨军
  //开发日期:2004-3-18
  //修改人员:
  //修改日期:
  //////////////////////////////////////////////////////////////////
  CaslUtilStatus MakeVariableLabelTable(const vector<CaslVariable>& argVecSrc, vector<VariableLabelItem>& argVecDst)
  {
    //----------------------变量定义部分begins----------------------
    VariableLabelItem varLabelItem;

    int iCurrentOffset = 0;

    size_t i = 0;
    size_t uiSize = 0;
    //----------------------变量定义部分ends----------------------
    //预先清空结果vector
    argVecDst.clear();
    //注意,这里的偏移全部是相对于目标代码中变量定义部分的起始位置而言的!!!!!!!!!!!!!!1
    uiSize = argVecSrc.size();
    //变量信息表为空,直接返回
    if (0 == uiSize)
    {
      return CASL_UTIL_OP_OK; 
    }

    for (i = 0; i < uiSize; i++)
    {
      //变量前有标号定义,则生成一个新的标号项
      if (strlen(argVecSrc[i].strLabelName) > 0)
      {
        //将上一个变量标号元素放入vector中
        if (0 != i)
        {
          argVecDst.push_back(varLabelItem);
        }
        strcpy(varLabelItem.strLabelName, argVecSrc[i].strLabelName);
        varLabelItem.iOffset = iCurrentOffset;
        iCurrentOffset += argVecSrc[i].iSpaceCnt;
      }
      //变量前无标号定义,则沿用上一个标号
      else
      {
        //第一个变量定义前没有标号,报错,返回
        if (0 == i)
        {
          //cerr << "There are errors about the table of labels of variables ";
          //return ;
        }
        iCurrentOffset += argVecSrc[i].iSpaceCnt;
      }
    }
    //把最后一个变量标号元素放入vector中
    argVecDst.push_back(varLabelItem);
    //应当设置一个变量记录变量表的大小(即一共为变量分配多少内存空间)
    g_iVariableSize = iCurrentOffset;
#ifdef DEBUG_MODE
    cout << "---------------------变量标号表------------------------------------";
    cout << endl;
    uiSize = argVecDst.size();
    cout << "变量表大小: " << uiSize << endl;
    for (i = 0; i < uiSize; i++)
    {
      cout << argVecDst[i].strLabelName << "   "  << argVecDst[i].iOffset;
      cout << endl;
    }
#endif

    return CASL_UTIL_OP_OK;
  }
  
  //////////////////////////////////////////////////////////////////
  //函数名称:MakeConstLabelTable
  //函数功能:依据中间代码常量表生成常量标号表,供生成目标代码使用
  //入口参数:const vector<CaslConst>& argVecSrc--------------中间代码常量表
  //出口参数:vector<ConstLabelItem>& argVecDst---------------生成的常量标号表
  //返回值:CaslUtilStatus----------------操作状态,CASL_UTIL_OP_OK表示操作成功,其他表示操作失败
  //开发人员:杨军
  //开发日期:2004-3-18
  //修改人员:
  //修改日期:
  //////////////////////////////////////////////////////////////////
  CaslUtilStatus MakeConstLabelTable(const vector<CaslConst>& argVecSrc, vector<ConstLabelItem>& argVecDst)
  {
    //----------------------变量定义部分begins----------------------
    ConstLabelItem constLabelItem;

    int iCurrentOffset = 0;

    size_t i = 0;
    size_t uiSize = 0;
#ifdef DEBUG_MODE
    cout << "before make Const Label Table:" << endl;
#endif
    //----------------------变量定义部分ends----------------------
    //预先清空结果vector
    argVecDst.clear();
    //注意,这里的偏移全部是相对于目标代码中常量定义部分的起始位置而言的!!!!!!!!!!!!!!1
    uiSize = argVecSrc.size();
    //如果常量标号表为空,则直接返回
    if (0 == uiSize)
    {
      return CASL_UTIL_OP_OK;
    }

    for (i = 0; i < uiSize; i++)
    {
      //常量前有标号定义,则生成一个新的标号项
      if (strlen(argVecSrc[i].strLabelName) > 0)
      {
        //将上一个常量标号元素放入vector中
        if (0 != i)
        {
          argVecDst.push_back(constLabelItem);
        }
        
        strcpy(constLabelItem.strLabelName, argVecSrc[i].strLabelName);
        constLabelItem.iOffset = iCurrentOffset;
        switch (argVecSrc[i].type)
        {
        case DEC_CONST:
          iCurrentOffset += 1;
          break;
        case HEX_CONST:
          iCurrentOffset += 1;
          break;
        case STR_CONST:
          iCurrentOffset += strlen(argVecSrc[i].constData.strVal);
          break;
        case LABEL_CONST:
          iCurrentOffset += 1;
          break;
        }
        
      }
      //常量前无标号定义,则沿用上一个标号
      else
      {
        //第一个常量定义前没有标号,报错,返回
        if (0 == i)
        {
          //cerr << "There are errors about the table of labels of variables ";
          //return ;
        }
        switch (argVecSrc[i].type)
        {
        case DEC_CONST:
          iCurrentOffset += 1;
          break;
        case HEX_CONST:
          iCurrentOffset += 1;
          break;
        case STR_CONST:
          iCurrentOffset += strlen(argVecSrc[i].constData.strVal);
          break;
        case LABEL_CONST:
          iCurrentOffset += 1;
          break;
        }
      }
    }
    //把最后一个常量标号元素放入vector中
    argVecDst.push_back(constLabelItem);

⌨️ 快捷键说明

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