📄 zasm.cpp
字号:
/*
文件
ZAsm.cpp
内容
汇编编译器实现
日期
12.9.2008
作者
张锦
*/
#ifndef _DATASTRUCTS_H_
#define _DATASTRUCTS_H_
// ---- 文件包含 -----------------------------------------------------------------------------
#include <iostream>
#include <iomanip>
using namespace std;
// ---- 全局常量 -----------------------------------------------------------------------------
// ---- 文件名 ---------------------------------------------------------------------------
#define MAX_FILENAME_SIZE 2048 // 文件名最大字符数
#define SOURCE_FILE_EXT ".ZASM" // 源代码文件扩展名
#define EXEC_FILE_EXT ".ZSE" // 可执行文件扩展名
// ---- 源代码 ---------------------------------------------------------------------------
#define MAX_SOURCE_CODE_SIZE 65536 // 源代码最大行数
#define MAX_SOURCE_LINE_SIZE 4096 // 源代码行最大字符数
// ---- ZSE 文件头 -----------------------------------------------------------------------
#define ZSE_ID_STRING "ZSE0" // ZSE 文件标识
#define VERSION_MAJOR 0 // 主版本号
#define VERSION_MINOR 0 // 副版本号
// ---- 指令查找表 -----------------------------------------------------------------------
#define MAX_INSTR_MNEMONIC_SIZE 16 // 指令助记符字符串的最大长度
#define MAX_INSTR_LOOKUP_COUNT 256 // 指令查找表存储的指令的最大个数
// ---- 指令操作码 -------------------------------------------------------------------
#define INSTR_MOV 0
#define INSTR_ADD 1
#define INSTR_SUB 2
#define INSTR_MUL 3
#define INSTR_DIV 4
#define INSTR_MOD 5
#define INSTR_EXP 6
#define INSTR_NEG 7
#define INSTR_INC 8
#define INSTR_DEC 9
#define INSTR_AND 10
#define INSTR_OR 11
#define INSTR_XOR 12
#define INSTR_NOT 13
#define INSTR_SHL 14
#define INSTR_SHR 15
#define INSTR_CONCAT 16
#define INSTR_GETCHAR 17
#define INSTR_SETCHAR 18
#define INSTR_JMP 19
#define INSTR_JE 20
#define INSTR_JNE 21
#define INSTR_JG 22
#define INSTR_JL 23
#define INSTR_JGE 24
#define INSTR_JLE 25
#define INSTR_PUSH 26
#define INSTR_POP 27
#define INSTR_CALL 28
#define INSTR_RET 29
#define INSTR_CALLHOST 30
#define INSTR_PAUSE 31
#define INSTR_EXIT 32
// ---- 操作数类型位域掩码 -----------------------------------------------------------
#define OP_FLAG_TYPE_INT 1 // 整形字面值
#define OP_FLAG_TYPE_FLOAT 2 // 浮点型字面值
#define OP_FLAG_TYPE_STRING 4 // 字符串型字面值
#define OP_FLAG_TYPE_MEM_REF 8 // 内存引用
#define OP_FLAG_TYPE_LINE_LABEL 16 // 行标签
#define OP_FLAG_TYPE_FUNC_NAME 32 // 函数名(用于call指令)
#define OP_FLAG_TYPE_REG 128 // 一个寄存器,即_RetVal
#define OP_FLAG_TYPE_HOST_API_CALL 64 // 主应用程序API调用(用于CallHost指令中)
// ---- 汇编指令流 -----------------------------------------------------------------------
#define OP_TYPE_INT 0 // 整形操作数
#define OP_TYPE_FLOAT 1 // 浮点型操作数
#define OP_TYPE_STRING_INDEX 2 // 字符串索引操作数
#define OP_TYPE_ABS_STACK_INDEX 3 // 绝对堆栈索引操作数
#define OP_TYPE_REL_STACK_INDEX 4 // 相对堆栈索引操作数
#define OP_TYPE_INSTR_INDEX 5 // 指令索引
#define OP_TYPE_FUNC_INDEX 6 // 函数索引
#define OP_TYPE_HOST_API_CALL_INDEX 7 // 主程序 API 调用索引
#define OP_TYPE_REG 8 // 寄存器
// ---- 词法分析 -------------------------------------------------------------------------
#define MAX_LEXEME_SIZE 256 // 词位最大长度
#define LEX_STATE_NO_STRING 0 // 词法分析按一般状态扫描
#define LEX_STATE_IN_STRING 1 // 词法分析按字符串模式扫描
#define LEX_STATE_END_STRING 2 // 词法分析按一般状态扫描,
// 并且下一状态为NO_STRING
#define TOKEN_TYPE_INT 0 // 整形字面值
#define TOKEN_TYPE_FLOAT 1 // 浮点型字面值
#define TOKEN_TYPE_STRING 2 // 字符串型字面值
#define TOKEN_TYPE_QUOTE 3 // 双引号
#define TOKEN_TYPE_IDENT 4 // 标识符
#define TOKEN_TYPE_COLON 5 // 冒号
#define TOKEN_TYPE_OPEN_BRACKET 6 // 左中括号
#define TOKEN_TYPE_CLOSE_BRACKET 7 // 右中括号
#define TOKEN_TYPE_COMMA 8 // 逗号
#define TOKEN_TYPE_OPEN_BRACE 9 // 左大括号
#define TOKEN_TYPE_CLOSE_BRACE 10 // 右大括号
#define TOKEN_TYPE_NEWLINE 11 // 换行
#define TOKEN_TYPE_INSTR 12 // 指令
#define TOKEN_TYPE_SETSTACKSIZE 13 // SetStackSize指示符
#define TOKEN_TYPE_VAR 14 // Var指示符
#define TOKEN_TYPE_FUNC 15 // Func指示符
#define TOKEN_TYPE_PARAM 16 // Param指示符
#define TOKEN_TYPE_REG_RETVAL 17 // _RetVal寄存器
#define TOKEN_TYPE_INVALID 18 // 不符合属性字的错误编码
#define END_OF_TOKEN_STREAM 19 // 到达属性字流的尾部
#define MAX_IDENT_SIZE 256 // 标识符最大长度
// ---- 函数 -----------------------------------------------------------------------------
#define MAIN_FUNC_NAME "_MAIN"
// ---- 出错处理 -------------------------------------------------------------------------
#define ERROR_MSG_LOCAL_SETSTACKSIZE \
"堆栈大小指示符 SetStackSize 只能出现在全局作用域。"
#define ERROR_MSG_MULTIPLE_SETSTACKSIZE \
"堆栈大小指示符 SetStackSize 只能出现一次。"
#define ERROR_MSG_INVALID_STACK_SIZE \
"堆栈大小不正确,SetStackSize 后面应跟一个整数。"
#define ERROR_MSG_NESTED_FUNC \
"Func 标签不能出现在函数内部。"
#define ERROR_MSG_IDENT_EXPECTED \
"此处需要标识符。"
#define ERROR_MSG_FUNC_REDEFINITION \
"函数重复定义。"
#define ERROR_MSG_IDENT_REDEFINITION \
"标识符重复定义。"
#define ERROR_MSG_INVALID_ARRAY_SIZE \
"数组大小不合法。"
#define ERROR_MSG_INVALID_INPUT \
"非法输入。"
#define ERROR_MSG_GLOBAL_PARAM \
"PARAM 指示符不能出现在全局作用域。"
#define ERROR_MSG_MAIN_PARAM \
"PARAM 指示符不能出现在_Main函数中"
#define ERROR_MSG_GLOBAL_INSTR \
"指令不能出现在全局作用域。"
#define ERROR_MSG_INVALID_INSTR \
"非法指令。"
#define ERROR_MSG_GLOBAL_LABEL \
"标签不能出现在全局作用域。"
#define ERROR_MSG_LINE_LABEL_REDEFINITION \
"行标签重复定义。"
#define ERROR_MSG_INVALID_OP \
"非法操作数。"
#define ERROR_MSG_INVALID_STRING \
"非法字符串。"
#define ERROR_MSG_UNDEFINED_IDENT \
"标识符未定义。"
#define ERROR_MSG_INVALID_ARRAY_NOT_INDEXED \
"数组必须通过索引使用。"
#define ERROR_MSG_INVALID_ARRAY \
"非法数组。"
#define ERROR_MSG_INVALID_ARRAY_INDEX \
"非法数组索引。"
#define ERROR_MSG_UNDEFINED_LINE_LABEL \
"行标签未定义"
#define ERROR_MSG_UDEFINED_FUNC \
"函数未定义。"
// ---- 数据结构 -----------------------------------------------------------------------------
// ---- 汇编指令流 -----------------------------------------------------------------------
struct Op
{
int iType; // 类型
union
{
int iIntLiteral; // 整形字面量
float fFloatLiteral; // 浮点型字面量
int iStringTableIndex; // 字符串表索引
int iStackIndex; // 堆栈索引
int iInstrIndex; // 指令索引
int iFuncIndex; // 函数索引
int iHostAPICallIndex; // 主应用程序API调用索引
int iReg; // 寄存器码
};
int iOffsetIndex; // 偏移量索引
};
struct Instr
{
int iOpcode; // 操作码
int iOpCount; // 操作数
Op *pOpList; // 指向操作数列表的指针
};
// ---- 脚本头 ---------------------------------------------------------------------------
struct ScriptHeader
{
int iStackSize; // 要求的堆栈大小
int iGlobalDataSize; // 脚本中全局数据的大小
int iIsMainFuncPresent; // _Main () 是否存在
int iMainFuncIndex; // _Main () 函数的索引
};
// ---- 词法分析 -------------------------------------------------------------------------
typedef int Token;
struct Lexer
{
int iCurrSourceLine; // 当前代码行
unsigned int iIndex0; // 取词索引0
unsigned int iIndex1; // 取词索引1
Token CurrToken; // 当前token
char pstrCurrLexeme[ MAX_LEXEME_SIZE ]; // 当前单词
int iCurrLexState; // 词法分析器当前状态
};
// ---- 简单链表 -------------------------------------------------------------------------
struct LinkedListNode
{
void *pData; // 指向节点数据的指针
LinkedListNode *pNext; // 指向链表中下一个节点的指针
};
struct LinkedList
{
LinkedListNode *pHead; // 指向链表头节点的指针
LinkedListNode *pTail; // 指向链表末节点的指针
int iNodeCount; // 连表中节点的数量
};
// ---- 函数表 ---------------------------------------------------------------------------
struct FuncNode
{
int iIndex; // 索引
char pstrName[MAX_IDENT_SIZE]; // 名称
int iEntryPoint; // 入口点
int iParamCount; // 参数个数
int iLocalDataSize; // 局部数据大小
};
// ---- 符号表 ---------------------------------------------------------------------------
struct SymbolNode
{
int iIndex; // 索引
char pstrIdent[MAX_IDENT_SIZE]; // 标识符
int iSize; // 大小
int iStackIndex; // 符号指向的堆栈索引
int iFuncIndex; // 符号所在的函数
};
// ---- 标签表 ---------------------------------------------------------------------------
struct LabelNode
{
int iIndex; // 标签表节点
int iTargetIndex; // 目标指令索引
int iFuncIndex; // 标签所属函数
char pstrIdent[MAX_IDENT_SIZE]; // 标识符
};
// ---- 指令查找表 -----------------------------------------------------------------------
typedef int OpTypes;
struct InstrLookup
{
char pstrMnemonic[MAX_INSTR_MNEMONIC_SIZE]; // 助记符
int iOpcode; // 操作码
int iOpCount; // 操作数个数
OpTypes *OpList; // 操作数类型列表指针
};
// ---- 全局变量 -----------------------------------------------------------------------------
// ---- 源代码 ---------------------------------------------------------------------------
char **g_ppstrSourceCode = 0; // 源代码缓存指针
int g_iSourceCodeSize = 0; // 源代码行数
FILE *g_pSourceFile = 0; // 源文件指针
char g_pstrSourceFileName[ MAX_FILENAME_SIZE ]; // 源代码文件名
char g_pstrExecFileName[ MAX_FILENAME_SIZE ]; // 可执行文件名
// ---- 汇编指令流 -----------------------------------------------------------------------
Instr *g_pInstrStream = 0;
int g_iInstrStreamSize = 0; // 指令流大小
int g_iCurrInstrIndex = 0; // 当前指令索引
// ---- 词法分析 -------------------------------------------------------------------------
Lexer g_Lexer; // 词法分析器结构
// ---- 脚本 -----------------------------------------------------------------------------
ScriptHeader g_ScriptHeader; // 脚本头结构
bool g_bIsSetStackSizeFound; // SetStackSize 标志
// ---- 字符串表 -------------------------------------------------------------------------
LinkedList g_StringTable;
// ---- 函数表 ---------------------------------------------------------------------------
LinkedList g_FuncTable;
// ---- 标签表 ---------------------------------------------------------------------------
LinkedList g_LabelTable;
// ---- 符号表 ---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -