📄 xasm.cpp
字号:
/*
Project.
XASM - The XtremeScript Assembler Version 0.8
Abstract.
Assembles XVM Assembly scripts to .XSE executables for use with the XtremeScript
Virtual Machine (XVM). This updated version 0.8 also preserves script-defined function
names for late binding and stores thread priority.
Date Created.
8.3.2002
Author.
Alex Varanese
*/
// ---- Include Files -------------------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// ---- Constants -----------------------------------------------------------------------------
// ---- General ---------------------------------------------------------------------------
#ifndef TRUE
#define TRUE 1 // True
#endif
#ifndef FALSE
#define FALSE 0 // False
#endif
// ---- Filename --------------------------------------------------------------------------
#define MAX_FILENAME_SIZE 2048 // Maximum filename length
#define SOURCE_FILE_EXT ".XASM" // Extension of a source code file
#define EXEC_FILE_EXT ".XSE" // Extension of an executable code file
// ---- Source Code -----------------------------------------------------------------------
#define MAX_SOURCE_CODE_SIZE 65536 // Maximum number of lines in source
// code
#define MAX_SOURCE_LINE_SIZE 4096 // Maximum source line length
// ---- ,XSE Header -----------------------------------------------------------------------
#define XSE_ID_STRING "XSE0" // Written to the file to state it's
// validity
#define VERSION_MAJOR 0 // Major version number
#define VERSION_MINOR 8 // Minor version number
// ---- Lexer -----------------------------------------------------------------------------
#define MAX_LEXEME_SIZE 256 // Maximum lexeme size
#define LEX_STATE_NO_STRING 0 // Lexemes are scanned as normal
#define LEX_STATE_IN_STRING 1 // Lexemes are scanned as strings
#define LEX_STATE_END_STRING 2 // Lexemes are scanned as normal, and the
// next state is LEXEME_STATE_NOSTRING
#define TOKEN_TYPE_INT 0 // An integer literal
#define TOKEN_TYPE_FLOAT 1 // An floating-point literal
#define TOKEN_TYPE_STRING 2 // An string literal
#define TOKEN_TYPE_QUOTE 3 // A double-quote
#define TOKEN_TYPE_IDENT 4 // An identifier
#define TOKEN_TYPE_COLON 5 // A colon
#define TOKEN_TYPE_OPEN_BRACKET 6 // An openening bracket
#define TOKEN_TYPE_CLOSE_BRACKET 7 // An closing bracket
#define TOKEN_TYPE_COMMA 8 // A comma
#define TOKEN_TYPE_OPEN_BRACE 9 // An openening curly brace
#define TOKEN_TYPE_CLOSE_BRACE 10 // An closing curly brace
#define TOKEN_TYPE_NEWLINE 11 // A newline
#define TOKEN_TYPE_INSTR 12 // An instruction
#define TOKEN_TYPE_SETSTACKSIZE 13 // The SetStackSize directive
#define TOKEN_TYPE_SETPRIORITY 14 // The SetPriority directive
#define TOKEN_TYPE_VAR 15 // The Var/Var [] directives
#define TOKEN_TYPE_FUNC 16 // The Func directives
#define TOKEN_TYPE_PARAM 17 // The Param directives
#define TOKEN_TYPE_REG_RETVAL 18 // The _RetVal directives
#define TOKEN_TYPE_INVALID 19 // Error code for invalid tokens
#define END_OF_TOKEN_STREAM 20 // The end of the stream has been
// reached
#define MAX_IDENT_SIZE 256 // Maximum identifier size
// ---- Instruction Lookup Table ----------------------------------------------------------
#define MAX_INSTR_LOOKUP_COUNT 256 // The maximum number of instructions
// the lookup table will hold
#define MAX_INSTR_MNEMONIC_SIZE 16 // Maximum size of an instruction
// mnemonic's string
// ---- Instruction Opcodes -----------------------------------------------------------
#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
// ---- Operand Type Bitfield Flags ---------------------------------------------------
// The following constants are used as flags into an operand type bit field, hence
// their values being increasing powers of 2.
#define OP_FLAG_TYPE_INT 1 // Integer literal value
#define OP_FLAG_TYPE_FLOAT 2 // Floating-point literal value
#define OP_FLAG_TYPE_STRING 4 // Integer literal value
#define OP_FLAG_TYPE_MEM_REF 8 // Memory reference (variable or array
// index, both absolute and relative)
#define OP_FLAG_TYPE_LINE_LABEL 16 // Line label (used for jumps)
#define OP_FLAG_TYPE_FUNC_NAME 32 // Function table index (used for Call)
#define OP_FLAG_TYPE_HOST_API_CALL 64 // Host API Call table index (used for
// CallHost)
#define OP_FLAG_TYPE_REG 128 // Register
// ---- Assembled Instruction Stream ------------------------------------------------------
#define OP_TYPE_INT 0 // Integer literal value
#define OP_TYPE_FLOAT 1 // Floating-point literal value
#define OP_TYPE_STRING_INDEX 2 // String literal value
#define OP_TYPE_ABS_STACK_INDEX 3 // Absolute array index
#define OP_TYPE_REL_STACK_INDEX 4 // Relative array index
#define OP_TYPE_INSTR_INDEX 5 // Instruction index
#define OP_TYPE_FUNC_INDEX 6 // Function index
#define OP_TYPE_HOST_API_CALL_INDEX 7 // Host API call index
#define OP_TYPE_REG 8 // Register
// ---- Priority Types --------------------------------------------------------------------
#define PRIORITY_USER 0 // User-defined priority
#define PRIORITY_LOW 1 // Low priority
#define PRIORITY_MED 2 // Medium priority
#define PRIORITY_HIGH 3 // High priority
#define PRIORITY_LOW_KEYWORD "Low" // Low priority keyword
#define PRIORITY_MED_KEYWORD "Med" // Low priority keyword
#define PRIORITY_HIGH_KEYWORD "High" // Low priority keyword
// ---- Functions -------------------------------------------------------------------------
#define MAIN_FUNC_NAME "_MAIN" // _Main ()'s name
// ---- Error Strings ---------------------------------------------------------------------
// The following macros are used to represent assembly-time error strings
#define ERROR_MSSG_INVALID_INPUT \
"Invalid input"
#define ERROR_MSSG_LOCAL_SETSTACKSIZE \
"SetStackSize can only appear in the global scope"
#define ERROR_MSSG_INVALID_STACK_SIZE \
"Invalid stack size"
#define ERROR_MSSG_MULTIPLE_SETSTACKSIZES \
"Multiple instances of SetStackSize illegal"
#define ERROR_MSSG_LOCAL_SETPRIORITY \
"SetPriority can only appear in the global scope"
#define ERROR_MSSG_INVALID_PRIORITY \
"Invalid priority"
#define ERROR_MSSG_MULTIPLE_SETPRIORITIES \
"Multiple instances of SetPriority illegal"
#define ERROR_MSSG_IDENT_EXPECTED \
"Identifier expected"
#define ERROR_MSSG_INVALID_ARRAY_SIZE \
"Invalid array size"
#define ERROR_MSSG_IDENT_REDEFINITION \
"Identifier redefinition"
#define ERROR_MSSG_UNDEFINED_IDENT \
"Undefined identifier"
#define ERROR_MSSG_NESTED_FUNC \
"Nested functions illegal"
#define ERROR_MSSG_FUNC_REDEFINITION \
"Function redefinition"
#define ERROR_MSSG_UNDEFINED_FUNC \
"Undefined function"
#define ERROR_MSSG_GLOBAL_PARAM \
"Parameters can only appear inside functions"
#define ERROR_MSSG_MAIN_PARAM \
"_Main () function cannot accept parameters"
#define ERROR_MSSG_GLOBAL_LINE_LABEL \
"Line labels can only appear inside functions"
#define ERROR_MSSG_LINE_LABEL_REDEFINITION \
"Line label redefinition"
#define ERROR_MSSG_UNDEFINED_LINE_LABEL \
"Undefined line label"
#define ERROR_MSSG_GLOBAL_INSTR \
"Instructions can only appear inside functions"
#define ERROR_MSSG_INVALID_INSTR \
"Invalid instruction"
#define ERROR_MSSG_INVALID_OP \
"Invalid operand"
#define ERROR_MSSG_INVALID_STRING \
"Invalid string"
#define ERROR_MSSG_INVALID_ARRAY_NOT_INDEXED \
"Arrays must be indexed"
#define ERROR_MSSG_INVALID_ARRAY \
"Invalid array"
#define ERROR_MSSG_INVALID_ARRAY_INDEX \
"Invalid array index"
// ---- Data Structures -----------------------------------------------------------------------
// ---- Linked Lists ----------------------------------------------------------------------
typedef struct _LinkedListNode // A linked list node
{
void * pData; // Pointer to the node's data
_LinkedListNode * pNext; // Pointer to the next node in the list
}
LinkedListNode;
typedef struct _LinkedList // A linked list
{
LinkedListNode * pHead, // Pointer to head node
* pTail; // Pointer to tail nail node
int iNodeCount; // The number of nodes in the list
}
LinkedList;
// ---- Lexical Analysis ------------------------------------------------------------------
typedef int Token; // Tokenizer alias type
typedef struct _Lexer // The lexical analyzer/tokenizer
{
int iCurrSourceLine; // Current line in the source
unsigned int iIndex0, // Indices into the string
iIndex1;
Token CurrToken; // Current token
char pstrCurrLexeme [ MAX_LEXEME_SIZE ]; // Current lexeme
int iCurrLexState; // The current lex state
}
Lexer;
// ---- Script ----------------------------------------------------------------------------
typedef struct _ScriptHeader // Script header data
{
int iStackSize; // Requested stack size
int iGlobalDataSize; // The size of the script's global data
int iIsMainFuncPresent; // Is _Main () present?
int iMainFuncIndex; // _Main ()'s function index
int iPriorityType; // The thread priority type
int iUserPriority; // The user-defined priority (if any)
}
ScriptHeader;
// ---- Instruction Lookup Table ----------------------------------------------------------
typedef int OpTypes; // Operand type bitfield alias type
typedef struct _InstrLookup // An instruction lookup
{
char pstrMnemonic [ MAX_INSTR_MNEMONIC_SIZE ]; // Mnemonic string
int iOpcode; // Opcode
int iOpCount; // Number of operands
OpTypes * OpList; // Pointer to operand list
}
InstrLookup;
// ---- Assembled Instruction Stream ------------------------------------------------------
typedef struct _Op // An assembled operand
{
int iType; // Type
union // The value
{
int iIntLiteral; // Integer literal
float fFloatLiteral; // Float literal
int iStringTableIndex; // String table index
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -