?? 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 + -