#pragma once #include #include #include "compiler/source_code/source_code.h" typedef enum FasmToken : uint8_t { // no operation (does nothing) FASM_TOKEN_NOOP = 0, // pushes operand to stack FASM_TOKEN_PUSH8, FASM_TOKEN_PUSH16, FASM_TOKEN_PUSH32, FASM_TOKEN_PUSH64, // dereferences stack.top and pushes its' value to stack FASM_TOKEN_LOAD8, FASM_TOKEN_LOAD16, FASM_TOKEN_LOAD32, FASM_TOKEN_LOAD64, // pops value stack.(top-1) to address which is stack.top FASM_TOKEN_POP8, FASM_TOKEN_POP16, FASM_TOKEN_POP32, FASM_TOKEN_POP64, // duplicates stack.top FASM_TOKEN_DUP8, FASM_TOKEN_DUP16, FASM_TOKEN_DUP32, FASM_TOKEN_DUP64, // swaps stack.top with stack.(top-1) FASM_TOKEN_SWAP8, FASM_TOKEN_SWAP16, FASM_TOKEN_SWAP32, FASM_TOKEN_SWAP64, // drops stack.top FASM_TOKEN_DROP8, FASM_TOKEN_DROP16, FASM_TOKEN_DROP32, FASM_TOKEN_DROP64, // adds two stack top integers FASM_TOKEN_ADD_I8, FASM_TOKEN_ADD_I16, FASM_TOKEN_ADD_I32, FASM_TOKEN_ADD_I64, // adds two stack top floats FASM_TOKEN_ADD_F32, FASM_TOKEN_ADD_F64, // subtracts two stack top integers FASM_TOKEN_SUB_I8, FASM_TOKEN_SUB_I16, FASM_TOKEN_SUB_I32, FASM_TOKEN_SUB_I64, // subtracts two stack top floats FASM_TOKEN_SUB_F32, FASM_TOKEN_SUB_F64, // negates stack top integer and pushes it back FASM_TOKEN_NEG_I8, FASM_TOKEN_NEG_I16, FASM_TOKEN_NEG_I32, FASM_TOKEN_NEG_I64, // negates stack top float and pushes it back FASM_TOKEN_NEG_F32, FASM_TOKEN_NEG_F64, // multiplies two stack top singed integers FASM_TOKEN_MUL_I8, FASM_TOKEN_MUL_I16, FASM_TOKEN_MUL_I32, FASM_TOKEN_MUL_I64, // multiplies two stack top unsinged integers FASM_TOKEN_MUL_U8, FASM_TOKEN_MUL_U16, FASM_TOKEN_MUL_U32, FASM_TOKEN_MUL_U64, // multiplies two stack top floats FASM_TOKEN_MUL_F32, FASM_TOKEN_MUL_F64, // divides two stack top singed integers FASM_TOKEN_DIV_I8, FASM_TOKEN_DIV_I16, FASM_TOKEN_DIV_I32, FASM_TOKEN_DIV_I64, // divides two stack top unsinged integers FASM_TOKEN_DIV_U8, FASM_TOKEN_DIV_U16, FASM_TOKEN_DIV_U32, FASM_TOKEN_DIV_U64, // divides two stack top floats FASM_TOKEN_DIV_F32, FASM_TOKEN_DIV_F64, // reminders two stack top singed integers FASM_TOKEN_REM_I8, FASM_TOKEN_REM_I16, FASM_TOKEN_REM_I32, FASM_TOKEN_REM_I64, // reminders two stack top unsinged integers FASM_TOKEN_REM_U8, FASM_TOKEN_REM_U16, FASM_TOKEN_REM_U32, FASM_TOKEN_REM_U64, // unsigned casts 8 bit to 64 bit FASM_TOKEN_CAST_I8_I64, // unsigned casts 16 bit to 64 bit FASM_TOKEN_CAST_I16_I64, // unsigned casts 32 bit to 64 bit FASM_TOKEN_CAST_I32_I64, // unsigned casts 64 bit to 8 bit FASM_TOKEN_CAST_I64_I8, // unsigned casts 64 bit to 16 bit FASM_TOKEN_CAST_I64_I16, // unsigned casts 64 bit to 32 bit FASM_TOKEN_CAST_I64_I32, // casts unsigned int 64 bit to float 64 bit FASM_TOKEN_CAST_F64_I64, // casts float 64 bit to unsigned int 64 bit FASM_TOKEN_CAST_I64_F64, // signed casts 8 bit to 64 bit FASM_TOKEN_CAST_U8_U64, // signed casts 16 bit to 64 bit FASM_TOKEN_CAST_U16_U64, // signed casts 32 bit to 64 bit FASM_TOKEN_CAST_U32_U64, // signed casts 64 bit to 8 bit FASM_TOKEN_CAST_U64_U8, // signed casts 64 bit to 16 bit FASM_TOKEN_CAST_U64_U16, // signed casts 64 bit to 32 bit FASM_TOKEN_CAST_U64_U32, // casts signed int 64 bit to float 64 bit FASM_TOKEN_CAST_F64_U64, // casts float 64 bit to signed int 64 bit FASM_TOKEN_CAST_U64_F64, // casts float 32 bit to float 64 bit FASM_TOKEN_CAST_F32_F64, // casts float 64 bit to float 32 bit FASM_TOKEN_CAST_F64_F32, // unconditional jump to instruction (sets IP to stack.top) FASM_TOKEN_JUMP, // conditionally jumps to stack.top if stack.(top-1) as 8 bit is // zero FASM_TOKEN_JZ_I8, // not zero FASM_TOKEN_JNZ_I8, // negative FASM_TOKEN_JN_I8, // not negative FASM_TOKEN_JNN_I8, // positive FASM_TOKEN_JP_I8, // not positive FASM_TOKEN_JNP_I8, // conditionally jumps to stack.top if stack.(top-1) as 16 bit is // zero FASM_TOKEN_JZ_I16, // not zero FASM_TOKEN_JNZ_I16, // negative FASM_TOKEN_JN_I16, // not negative FASM_TOKEN_JNN_I16, // positive FASM_TOKEN_JP_I16, // not positive FASM_TOKEN_JNP_I16, // conditionally jumps to stack.top if stack.(top-1) as 32 bit is // zero FASM_TOKEN_JZ_I32, // not zero FASM_TOKEN_JNZ_I32, // negative FASM_TOKEN_JN_I32, // not negative FASM_TOKEN_JNN_I32, // positive FASM_TOKEN_JP_I32, // not positive FASM_TOKEN_JNP_I32, // conditionally jumps to stack.top if stack.(top-1) as 64 bit is // zero FASM_TOKEN_JZ_I64, // not zero FASM_TOKEN_JNZ_I64, // negative FASM_TOKEN_JN_I64, // not negative FASM_TOKEN_JNN_I64, // positive FASM_TOKEN_JP_I64, // not positive FASM_TOKEN_JNP_I64, // conditionally jumps to stack.top if stack.(top-1) as 32 bit float is // zero FASM_TOKEN_JZ_F32, // not zero FASM_TOKEN_JNZ_F32, // negative FASM_TOKEN_JN_F32, // not negative FASM_TOKEN_JNN_F32, // positive FASM_TOKEN_JP_F32, // not positive FASM_TOKEN_JNP_F32, // conditionally jumps to stack.top if stack.(top-1) as 64 bit float is // zero FASM_TOKEN_JZ_F64, // not zero FASM_TOKEN_JNZ_F64, // negative FASM_TOKEN_JN_F64, // not negative FASM_TOKEN_JNN_F64, // positive FASM_TOKEN_JP_F64, // not positive FASM_TOKEN_JNP_F64, // allocates n bytes to heap and pushes its' address to stack (n = stack.top) FASM_TOKEN_ALLOC_HEAP, // allocates n bytes to stack (n = stack.top) FASM_TOKEN_ALLOC_STACK, // frees what address is in stack.top FASM_TOKEN_FREE_HEAP, // gives stack root address FASM_TOKEN_GET_STACK_ADDRESS, // gives global root address FASM_TOKEN_GET_GLOBAL_ADDRESS, // calls function (stores to current IP (instruction pointer) into call stack) FASM_TOKEN_CALL, // pops call stack to IP (instruction pointer) FASM_TOKEN_RET, // stack.top as u8 is id of syscall FASM_TOKEN_SYSCALL, FASM_TOKEN_DEFINE_BYTE, FASM_TOKEN_DEFINE_WORD, FASM_TOKEN_DEFINE_DWORD, FASM_TOKEN_DEFINE_QWORD, FASM_TOKEN_NONE, } FasmToken; extern const char *FASM_TOKEN_STRINGS[]; extern const size_t FASM_TOKEN_STRINGS_SIZE; typedef enum FasmSyscall : uint8_t { // stack = [...,u64 count,i8* buf,u32 fd] -> stack = [...] FASM_SYSCALL_READ = 0, // stack = [...,u64 count,i8* buf,u32 fd] -> stack = [...] FASM_SYSCALL_WRITE, // stack = [...,i32 mode,i32 flags,const i8* filename] -> stack = [...,u32 fd] FASM_SYSCALL_OPEN, // stack = [...,u32 fd] -> stack = [...] FASM_SYSCALL_CLOSE, // stack = [...,u32 status] -> stack = [...] FASM_SYSCALL_EXIT, } FasmSyscall; typedef enum FasmLineLookingFor { FASM_LINE_LOOKING_FOR_LABEL_OR_INSTRUCTION = 0, FASM_LINE_LOOKING_FOR_INSTRUCTION, FASM_LINE_LOOKING_FOR_OPERAND, FASM_LINE_LOOKING_FOR_OPERAND_OR_END, FASM_LINE_LOOKING_FOR_COMMA_OR_END, } FasmLineLookingFor; extern const char *FASM_LINE_LOOKING_FOR_STRINGS[]; typedef enum FasmSection { FASM_SECTION_NONE, FASM_SECTION_CODE, FASM_SECTION_DATA, } FasmSection; typedef struct FasmOperand { char *begin; char *end; } FasmOperand; typedef struct FasmLine { char const *begin; char const *end; char const *labelBegin; char const *labelEnd; FasmToken instruction; FasmOperand *operands; size_t operands_size; } FasmLine; typedef struct FasmLines { FasmLine *lines; size_t lines_size; FasmLine *data; size_t data_size; } FasmLines; extern void fasmLinePrint(FasmLine line); extern void fasmLinesPrint(FasmLines lines); extern void fasmLineDeleteInner(FasmLine line); extern void fasmLinesDeleteInner(FasmLines lines); extern FasmLines *fasmLexer(SourceCode *sourceCode); extern FasmLines fasmLexerCode(Code *code, SourceCode *sourceCode); extern bool fasmLexerPushLine(FasmLines *lines, FasmLine *line, char const *iter, FasmSection section, SourceCode *sourceCode); extern void _fasmLexerPushLine(FasmLine **lines, size_t *lines_size, FasmLine *line, char const *iter); extern bool fasmLexerIsAllowed(FasmLine line, FasmSection section); extern char *fasmLexerGetNextWord(char *iter); extern FasmToken fasmLexerTokenFromIdentifier(char *begin, char *end); extern bool fasmLexerIsSpace(char c); extern bool fasmLexerIsSectionIndicator(char c); extern bool fasmLexerIsLabel(char c); extern bool fasmLexerIsWord(char c); extern bool fasmLexerIsIdentifierSymbol(char c); extern bool fasmLexerIsString(char c); extern bool fasmLexerIsOperandSeparator(char c); extern bool fasmLexerIsLineSeparator(char c);