From fbff4dd1887c2141aeb6576040df34f50b0119dc Mon Sep 17 00:00:00 2001 From: zongor Date: Sat, 21 Feb 2026 11:09:22 -0800 Subject: [PATCH] Move common lexer up to use for both assembler and compiler. Start work on compiler. --- Makefile | 10 +- src/arch/linux/main.c | 50 +- src/tools/assembler/assembler.c | 1406 ++++++++++++++--------------- src/tools/assembler/assembler.h | 49 +- src/tools/codegen.h | 91 ++ src/tools/compiler/compiler.c | 11 +- src/tools/compiler/compiler.h | 88 +- src/tools/compiler/parser.c | 515 ----------- src/tools/compiler/parser.h | 89 -- src/tools/{assembler => }/lexer.c | 23 +- src/tools/{assembler => }/lexer.h | 3 +- test/add.uir.ul | 2 +- 12 files changed, 856 insertions(+), 1481 deletions(-) create mode 100644 src/tools/codegen.h delete mode 100644 src/tools/compiler/parser.c delete mode 100644 src/tools/compiler/parser.h rename src/tools/{assembler => }/lexer.c (96%) rename src/tools/{assembler => }/lexer.h (97%) diff --git a/Makefile b/Makefile index fd48781..aacc8de 100644 --- a/Makefile +++ b/Makefile @@ -90,13 +90,15 @@ VM_SOURCES := \ ifeq ($(BUILD_MODE), release) PLATFORM_SOURCE := $(ARCH_DIR)/main.c \ $(ARCH_DIR)/devices.c\ - $(SRC_DIR)/tools/assembler/lexer.c \ - $(SRC_DIR)/tools/assembler/assembler.c + $(SRC_DIR)/tools/lexer.c \ + $(SRC_DIR)/tools/assembler/assembler.c \ + $(SRC_DIR)/tools/compiler/compiler.c else PLATFORM_SOURCE := $(ARCH_DIR)/main.c \ $(ARCH_DIR)/devices.c \ - $(SRC_DIR)/tools/assembler/lexer.c \ - $(SRC_DIR)/tools/assembler/assembler.c + $(SRC_DIR)/tools/lexer.c \ + $(SRC_DIR)/tools/assembler/assembler.c \ + $(SRC_DIR)/tools/compiler/compiler.c endif # --- OBJECT FILES --- diff --git a/src/arch/linux/main.c b/src/arch/linux/main.c index e3c7a21..ac9f5c0 100644 --- a/src/arch/linux/main.c +++ b/src/arch/linux/main.c @@ -1,3 +1,4 @@ +#include "../../tools/compiler/compiler.h" #include "../../tools/assembler/assembler.h" #include "../../vm/vm.h" #include "devices.h" @@ -120,15 +121,6 @@ bool loadVM(const char *filename, VM *vm) { return true; } -// Function to compile and optionally save -bool compileAndSave(const char *source_file, const char *output_file, VM *vm) { - USED(vm); - USED(output_file); - USED(source_file); - - return true; -} - #ifdef STATIC #define SCOPES_COUNT 2048 SymbolTable scopes[SCOPES_COUNT]; @@ -210,6 +202,46 @@ bool assembleAndSave(const char *source_file, const char *output_file, VM *vm) { return true; } +// Function to compile and optionally save +bool compileAndSave(const char *source_file, const char *output_file, VM *vm) { + FILE *f = fopen(source_file, "rb"); + if (!f) { + perror("fopen"); + return false; + } + + static char source[MAX_SRC_SIZE + 1]; + + fseek(f, 0, SEEK_END); + long len = ftell(f); + fseek(f, 0, SEEK_SET); + if (len >= MAX_SRC_SIZE) { + fprintf(stderr, "Source is larger than buffer\n"); + fclose(f); + return false; + } + size_t read = fread(source, 1, len, f); + source[read] = '\0'; + fclose(f); + + ScopeTable table = {0}; + symbol_table_init(&table); + compile(vm, &table, source); +#ifndef STATIC + free(table.scopes); +#endif + + if (output_file) { + if (!saveVM(output_file, vm)) { + printf("Failed to save VM to %s\n", output_file); + return false; + } + printf("VM saved to %s\n", output_file); + } + return true; + return true; +} + void scale_mouse_pos(u32 mouse_x, u32 mouse_y, u32 *vm_x, u32 *vm_y) { int win_w, win_h; SDL_GetWindowSize(screen_data.window, &win_w, &win_h); diff --git a/src/tools/assembler/assembler.c b/src/tools/assembler/assembler.c index 87fa5a2..6c1c109 100644 --- a/src/tools/assembler/assembler.c +++ b/src/tools/assembler/assembler.c @@ -3,8 +3,8 @@ #include "../../vm/libc.h" #include "../../vm/opcodes.h" +#include "../lexer.h" #include "assembler.h" -#include "lexer.h" /* FIXME: remove these and replace with libc.h instead */ #include @@ -141,28 +141,28 @@ const char *opcode_to_string(Opcode op) { return name ? name : ""; } -void emit_op(VM *vm, u8 byte) { +void asm_emit_op(VM *vm, u8 byte) { #ifdef DEBUG_PRINT printf("code[%d] = %s\n", vm->cp, opcode_to_string(byte)); #endif vm->code[vm->cp] = byte; } -void emit_byte(VM *vm, u8 byte) { +void asm_emit_byte(VM *vm, u8 byte) { #ifdef DEBUG_PRINT printf("code[%d] = %d\n", vm->cp, byte); #endif vm->code[vm->cp] = byte; } -void emit_u32(VM *vm, u32 value) { +void asm_emit_u32(VM *vm, u32 value) { #ifdef DEBUG_PRINT printf("code[%d..%d] = %d\n", vm->cp, vm->cp + 3, value); #endif write_u32(vm, code, vm->cp, value); } -Symbol *symbol_table_lookup(ScopeTable *table, const char *name, u32 length, +Symbol *asm_symbol_table_lookup(ScopeTable *table, const char *name, u32 length, i32 scope_ref) { SymbolTable st = table->scopes[scope_ref]; for (u32 i = 0; i < st.count; i++) { @@ -174,12 +174,12 @@ Symbol *symbol_table_lookup(ScopeTable *table, const char *name, u32 length, } if (st.parent < 0) return nil; - return symbol_table_lookup(table, name, length, st.parent); + return asm_symbol_table_lookup(table, name, length, st.parent); } -u8 symbol_table_add(ScopeTable *table, Symbol s) { +u8 asm_symbol_table_add(ScopeTable *table, Symbol s) { Symbol *sym = - symbol_table_lookup(table, s.name, s.name_length, table->scope_ref); + asm_symbol_table_lookup(table, s.name, s.name_length, table->scope_ref); if (sym != nil) { fprintf(stderr, "Error: Symbol '%.*s' already defined, in this scope" @@ -220,8 +220,8 @@ u8 symbol_table_add(ScopeTable *table, Symbol s) { return index; } -u32 get_ref(ScopeTable *st, const char *name, u32 length) { - Symbol *sym = symbol_table_lookup(st, name, length, st->scope_ref); +u32 asm_get_ref(ScopeTable *st, const char *name, u32 length) { + Symbol *sym = asm_symbol_table_lookup(st, name, length, st->scope_ref); if (!sym) { fprintf(stderr, "Error: Assembler has no idea what Symbol '%.*s' means.\n", length, name); @@ -231,9 +231,9 @@ u32 get_ref(ScopeTable *st, const char *name, u32 length) { return sym->ref; } -u32 get_ptr(Token token, ScopeTable *st) { +u32 asm_get_ptr(Token token, ScopeTable *st) { if (token.type == TOKEN_IDENTIFIER) { - return get_ref(st, token.start, token.length); + return asm_get_ref(st, token.start, token.length); } if (token.type == TOKEN_LITERAL_INT) { @@ -256,9 +256,9 @@ u32 get_ptr(Token token, ScopeTable *st) { exit(1); } -u32 get_reg(Token token, ScopeTable *st) { +u32 asm_get_reg(Token token, ScopeTable *st) { if (token.type == TOKEN_IDENTIFIER) { - return get_ref(st, token.start, token.length); + return asm_get_ref(st, token.start, token.length); } if (token.type == TOKEN_BIG_MONEY) { @@ -271,37 +271,7 @@ u32 get_reg(Token token, ScopeTable *st) { exit(1); } -Token next_id_or_reg() { - Token token = next_token(); - if (token.type == TOKEN_IDENTIFIER) { - return token; - } - - if (token.type == TOKEN_BIG_MONEY) { - token = next_token(); - return token; - } - - printf("Not an ID or register at line %d: %.*s\n", token.line, token.length, - token.start); - exit(1); - - return token; -} - -Token next_id_or_ptr() { - Token token = next_token(); - - if (token.type != TOKEN_IDENTIFIER && token.type != TOKEN_LITERAL_NAT && - token.type != TOKEN_LITERAL_INT && token.type != TOKEN_LITERAL_REAL) { - printf("Not an ID or register at line %d: %.*s\n", token.line, token.length, - token.start); - exit(1); - } - return token; -} - -Token next_token_is(TokenType type) { +Token asm_next_token_is(TokenType type) { Token token = next_token(); if (token.type != type) { printf("ERROR at line %d: %.*s\n", token.line, token.length, token.start); @@ -313,7 +283,7 @@ Token next_token_is(TokenType type) { /** * Global . */ -bool define_global(VM *vm, ScopeTable *st) { +bool asm_define_global(VM *vm, ScopeTable *st) { Symbol s; Token token_type = next_token(); @@ -359,7 +329,7 @@ bool define_global(VM *vm, ScopeTable *st) { return false; } - Token name = next_token_is(TOKEN_IDENTIFIER); + Token name = asm_next_token_is(TOKEN_IDENTIFIER); if (name.length > MAX_SYMBOL_NAME_LENGTH) { return false; } @@ -372,7 +342,7 @@ bool define_global(VM *vm, ScopeTable *st) { s.ref = addr; s.scope = GLOBAL; - next_token_is(TOKEN_EQ); + asm_next_token_is(TOKEN_EQ); Token value = next_token(); switch (value.type) { @@ -473,16 +443,16 @@ bool define_global(VM *vm, ScopeTable *st) { default: return false; } - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); - symbol_table_add(st, s); + asm_symbol_table_add(st, s); return true; } /** * Var . */ -void define_var(ScopeTable *st, Token regType) { +void asm_define_var(ScopeTable *st, Token regType) { Symbol s; s.scope = VAR; switch (regType.type) { @@ -542,7 +512,7 @@ void define_var(ScopeTable *st, Token regType) { exit(1); } - Token name = next_token_is(TOKEN_IDENTIFIER); + Token name = asm_next_token_is(TOKEN_IDENTIFIER); if (name.length > MAX_SYMBOL_NAME_LENGTH) { printf("VARIABLE NAME TOO LONG at line %d: %.*s\n", regType.line, regType.length, regType.start); @@ -553,22 +523,22 @@ void define_var(ScopeTable *st, Token regType) { s.name[name.length] = '\0'; s.name_length = name.length; - next_token_is(TOKEN_BIG_MONEY); + asm_next_token_is(TOKEN_BIG_MONEY); - Token reg_num = next_token_is(TOKEN_LITERAL_INT); + Token reg_num = asm_next_token_is(TOKEN_LITERAL_INT); s.ref = atoi(reg_num.start); - symbol_table_add(st, s); + asm_symbol_table_add(st, s); } /** * function . */ -void define_function(VM *vm, ScopeTable *st) { +void asm_define_function(VM *vm, ScopeTable *st) { Symbol s; s.scope = LOCAL; s.type = FUNCTION; - Token name = next_token_is(TOKEN_IDENTIFIER); + Token name = asm_next_token_is(TOKEN_IDENTIFIER); if (name.length > MAX_SYMBOL_NAME_LENGTH) { printf("FUNCITON NAME TOO LONG at line %d: %.*s\n", name.line, name.length, name.start); @@ -578,7 +548,7 @@ void define_function(VM *vm, ScopeTable *st) { s.name[name.length] = '\0'; s.name_length = name.length; - next_token_is(TOKEN_LPAREN); + asm_next_token_is(TOKEN_LPAREN); i32 temp = st->scope_ref; @@ -588,7 +558,7 @@ void define_function(VM *vm, ScopeTable *st) { Token next = next_token(); while (next.type != TOKEN_RPAREN) { - define_var(st, next); + asm_define_var(st, next); next = next_token(); if (next.type == TOKEN_COMMA) { next = next_token(); @@ -601,22 +571,22 @@ void define_function(VM *vm, ScopeTable *st) { } } s.ref = vm->cp; - next = next_token_is(TOKEN_LBRACE); + next = asm_next_token_is(TOKEN_LBRACE); st->scope_ref = temp; // need to add to the parents scope - symbol_table_add(st, s); + asm_symbol_table_add(st, s); st->scope_ref = (i32)st->count; } /** * Branch. */ -void define_branch(VM *vm, ScopeTable *st) { +void asm_define_branch(VM *vm, ScopeTable *st) { Symbol s; s.scope = LOCAL; s.type = VOID; - Token name = next_token_is(TOKEN_IDENTIFIER); + Token name = asm_next_token_is(TOKEN_IDENTIFIER); if (name.length > MAX_SYMBOL_NAME_LENGTH) { printf("BRANCH NAME TOO LONG at line %d: %.*s\n", name.line, name.length, name.start); @@ -627,10 +597,10 @@ void define_branch(VM *vm, ScopeTable *st) { s.name[name.length] = '\0'; s.ref = vm->cp; - symbol_table_add(st, s); + asm_symbol_table_add(st, s); } -int get_instruction_byte_size(const char *opname) { +int asm_get_instruction_byte_size(const char *opname) { if (strcmp(opname, "return") == 0) { return 2; @@ -729,15 +699,15 @@ int get_instruction_byte_size(const char *opname) { token = next_token(); \ } \ /*printf("code[%d]=%s\n %d + %d = %d\n", vm->cp, op, \ - * get_instruction_byte_size(op), vm->cp, vm->cp + \ - * get_instruction_byte_size(op)); */ \ - vm->cp += get_instruction_byte_size(op); \ + * asm_get_instruction_byte_size(op), vm->cp, vm->cp + \ + * asm_get_instruction_byte_size(op)); */ \ + vm->cp += asm_get_instruction_byte_size(op); \ } while (0); /** * Build the symbol table and calculate the types/size/offsets of all values. */ -void build_symbol_table(VM *vm, char *source, ScopeTable *st) { +void asm_build_symbol_table(VM *vm, char *source, ScopeTable *st) { Token token; init_lexer(source); do { @@ -765,12 +735,12 @@ void build_symbol_table(VM *vm, char *source, ScopeTable *st) { } if (token.type == TOKEN_KEYWORD_GLOBAL) { - define_global(vm, st); + asm_define_global(vm, st); continue; } if (token.type == TOKEN_KEYWORD_FN) { - define_function(vm, st); + asm_define_function(vm, st); continue; } @@ -779,15 +749,15 @@ void build_symbol_table(VM *vm, char *source, ScopeTable *st) { token.type == TOKEN_TYPE_U8 || token.type == TOKEN_TYPE_U16 || token.type == TOKEN_TYPE_NAT || token.type == TOKEN_TYPE_REAL || token.type == TOKEN_TYPE_STR || token.type == TOKEN_TYPE_BOOL) { - define_var(st, token); - next_token_is(TOKEN_SEMICOLON); + asm_define_var(st, token); + asm_next_token_is(TOKEN_SEMICOLON); continue; } if (token.type == TOKEN_KEYWORD_LOOP || token.type == TOKEN_KEYWORD_IF || token.type == TOKEN_KEYWORD_ELSE || token.type == TOKEN_KEYWORD_DO || token.type == TOKEN_KEYWORD_FOR) { - define_branch(vm, st); + asm_define_branch(vm, st); continue; } @@ -801,9 +771,9 @@ void build_symbol_table(VM *vm, char *source, ScopeTable *st) { continue; } - get_reg(next, st); + asm_get_reg(next, st); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); continue; } @@ -823,19 +793,19 @@ void build_symbol_table(VM *vm, char *source, ScopeTable *st) { printf("code[%d] = exit\n", vm->cp); #endif - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "call", token.length)) { vm->cp++; - next_token_is(TOKEN_IDENTIFIER); + asm_next_token_is(TOKEN_IDENTIFIER); vm->cp += 4; vm->cp++; - Token next = next_token_is(TOKEN_LPAREN); + Token next = asm_next_token_is(TOKEN_LPAREN); next = next_token(); while (next.type != TOKEN_RPAREN) { - get_reg(next, st); + asm_get_reg(next, st); vm->cp++; next = next_token(); } @@ -845,7 +815,7 @@ void build_symbol_table(VM *vm, char *source, ScopeTable *st) { vm->cp++; } else { next = next_token(); - get_reg(next, st); + asm_get_reg(next, st); vm->cp++; } #ifdef DEBUG_PRINT @@ -861,7 +831,7 @@ void build_symbol_table(VM *vm, char *source, ScopeTable *st) { next = next_token(); while (next.type != TOKEN_SEMICOLON) { - get_reg(next, st); + asm_get_reg(next, st); vm->cp++; next = next_token(); } @@ -968,7 +938,7 @@ void build_symbol_table(VM *vm, char *source, ScopeTable *st) { /** * 2nd pass, emit the bytecode */ -void emit_bytecode(VM *vm, char *source, ScopeTable *st) { +void asm_emit_bytecode(VM *vm, char *source, ScopeTable *st) { Token token; init_lexer(source); do { @@ -1034,21 +1004,21 @@ void emit_bytecode(VM *vm, char *source, ScopeTable *st) { } if (token.type == TOKEN_KEYWORD_RETURN) { - emit_op(vm, OP_RETURN); + asm_emit_op(vm, OP_RETURN); vm->cp++; Token next = next_token(); if (next.type == TOKEN_SEMICOLON) { /* put 0xFF as return register */ - emit_byte(vm, 0xFF); + asm_emit_byte(vm, 0xFF); vm->cp++; continue; } - u32 reg = get_reg(next, st); - emit_byte(vm, reg); + u32 reg = asm_get_reg(next, st); + asm_emit_byte(vm, reg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); continue; } @@ -1059,32 +1029,32 @@ void emit_bytecode(VM *vm, char *source, ScopeTable *st) { /* check to see if it is an opcode first */ if (strleq(token.start, "exit", token.length)) { - emit_op(vm, OP_EXIT); + asm_emit_op(vm, OP_EXIT); vm->cp++; Token next = next_token(); - u32 ptr = get_ptr(next, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(next, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "call", token.length)) { - emit_op(vm, OP_CALL); + asm_emit_op(vm, OP_CALL); vm->cp++; - Token id = next_token_is(TOKEN_IDENTIFIER); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + Token id = asm_next_token_is(TOKEN_IDENTIFIER); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; u8 arg_count = 0; u32 arg_pos = vm->cp++; - Token next = next_token_is(TOKEN_LPAREN); + Token next = asm_next_token_is(TOKEN_LPAREN); next = next_token(); while (next.type != TOKEN_RPAREN) { - u8 arg = get_reg(next, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; arg_count++; next = next_token(); @@ -1098,19 +1068,19 @@ void emit_bytecode(VM *vm, char *source, ScopeTable *st) { next = next_token(); if (next.type == TOKEN_SEMICOLON) { - emit_byte(vm, 255); + asm_emit_byte(vm, 255); vm->cp++; } else { next = next_token(); - u8 arg = get_reg(next, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; } continue; } else if (strleq(token.start, "syscall", token.length)) { - emit_op(vm, OP_SYSCALL); + asm_emit_op(vm, OP_SYSCALL); vm->cp++; Token next = next_token(); @@ -1132,43 +1102,43 @@ void emit_bytecode(VM *vm, char *source, ScopeTable *st) { else if (strleq(syscall_name, "REFRESH", next.length)) syscall_id = SYSCALL_DEVICE_REFRESH; - emit_u32(vm, syscall_id); + asm_emit_u32(vm, syscall_id); vm->cp += 4; next = next_token(); while (next.type != TOKEN_SEMICOLON && next.type != TOKEN_ARROW_RIGHT) { - u8 arg = get_reg(next, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; next = next_token(); } if (next.type == TOKEN_ARROW_RIGHT) { next = next_token(); - u8 arg = get_reg(next, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; } } else if (strleq(token.start, "load_immediate", token.length)) { - emit_op(vm, OP_LOAD_IMM); + asm_emit_op(vm, OP_LOAD_IMM); vm->cp++; Token value = next_token(); switch (value.type) { case TOKEN_KEYWORD_TRUE: { - emit_u32(vm, 1); + asm_emit_u32(vm, 1); break; } case TOKEN_KEYWORD_FALSE: { - emit_u32(vm, 0); + asm_emit_u32(vm, 0); break; } case TOKEN_LITERAL_INT: { i32 out = atoi(value.start); - emit_u32(vm, out); + asm_emit_u32(vm, out); break; } case TOKEN_LITERAL_NAT: { @@ -1179,12 +1149,12 @@ void emit_bytecode(VM *vm, char *source, ScopeTable *st) { token.start); exit(1); } - emit_u32(vm, out); + asm_emit_u32(vm, out); break; } case TOKEN_LITERAL_REAL: { r32 out = float_to_real(atof(value.start)); - emit_u32(vm, out); + asm_emit_u32(vm, out); break; } default: { @@ -1196,1256 +1166,1256 @@ void emit_bytecode(VM *vm, char *source, ScopeTable *st) { vm->cp += 4; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_address", token.length)) { - emit_op(vm, OP_LOAD_IMM); + asm_emit_op(vm, OP_LOAD_IMM); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "malloc", token.length)) { - emit_op(vm, OP_MALLOC); + asm_emit_op(vm, OP_MALLOC); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "memset_8", token.length)) { - emit_op(vm, OP_MEMSET_8); + asm_emit_op(vm, OP_MEMSET_8); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "memset_16", token.length)) { - emit_op(vm, OP_MEMSET_16); + asm_emit_op(vm, OP_MEMSET_16); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "memset_32", token.length)) { - emit_op(vm, OP_MEMSET_32); + asm_emit_op(vm, OP_MEMSET_32); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_offset_8", token.length)) { - emit_op(vm, OP_LOAD_OFF_8); + asm_emit_op(vm, OP_LOAD_OFF_8); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_offset_16", token.length)) { - emit_op(vm, OP_LOAD_OFF_16); + asm_emit_op(vm, OP_LOAD_OFF_16); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_offset_32", token.length)) { - emit_op(vm, OP_LOAD_OFF_32); + asm_emit_op(vm, OP_LOAD_OFF_32); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_indirect_8", token.length)) { - emit_op(vm, OP_LOAD_IND_8); + asm_emit_op(vm, OP_LOAD_IND_8); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_indirect_16", token.length)) { - emit_op(vm, OP_LOAD_IND_16); + asm_emit_op(vm, OP_LOAD_IND_16); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_indirect_32", token.length)) { - emit_op(vm, OP_LOAD_IND_32); + asm_emit_op(vm, OP_LOAD_IND_32); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_absolute_8", token.length)) { - emit_op(vm, OP_LOAD_ABS_8); + asm_emit_op(vm, OP_LOAD_ABS_8); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_absolute_16", token.length)) { - emit_op(vm, OP_LOAD_ABS_16); + asm_emit_op(vm, OP_LOAD_ABS_16); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_absolute_32", token.length)) { - emit_op(vm, OP_LOAD_ABS_32); + asm_emit_op(vm, OP_LOAD_ABS_32); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_absolute_8", token.length)) { - emit_op(vm, OP_STORE_ABS_8); + asm_emit_op(vm, OP_STORE_ABS_8); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_absolute_16", token.length)) { - emit_op(vm, OP_STORE_ABS_16); + asm_emit_op(vm, OP_STORE_ABS_16); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_absolute_32", token.length)) { - emit_op(vm, OP_STORE_ABS_32); + asm_emit_op(vm, OP_STORE_ABS_32); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_indirect_8", token.length)) { - emit_op(vm, OP_STORE_IND_8); + asm_emit_op(vm, OP_STORE_IND_8); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_indirect_16", token.length)) { - emit_op(vm, OP_STORE_IND_16); + asm_emit_op(vm, OP_STORE_IND_16); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_indirect_32", token.length)) { - emit_op(vm, OP_STORE_IND_32); + asm_emit_op(vm, OP_STORE_IND_32); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_offset_8", token.length)) { - emit_op(vm, OP_STORE_OFF_8); + asm_emit_op(vm, OP_STORE_OFF_8); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_offset_16", token.length)) { - emit_op(vm, OP_STORE_OFF_16); + asm_emit_op(vm, OP_STORE_OFF_16); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_offset_32", token.length)) { - emit_op(vm, OP_STORE_OFF_32); + asm_emit_op(vm, OP_STORE_OFF_32); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "register_move", token.length)) { - emit_op(vm, OP_REG_MOV); + asm_emit_op(vm, OP_REG_MOV); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "add_int", token.length)) { - emit_op(vm, OP_ADD_INT); + asm_emit_op(vm, OP_ADD_INT); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "sub_int", token.length)) { - emit_op(vm, OP_SUB_INT); + asm_emit_op(vm, OP_SUB_INT); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "mul_int", token.length)) { - emit_op(vm, OP_MUL_INT); + asm_emit_op(vm, OP_MUL_INT); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "div_int", token.length)) { - emit_op(vm, OP_DIV_INT); + asm_emit_op(vm, OP_DIV_INT); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "abs_int", token.length)) { - emit_op(vm, OP_ABS_INT); + asm_emit_op(vm, OP_ABS_INT); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "neg_int", token.length)) { - emit_op(vm, OP_NEG_INT); + asm_emit_op(vm, OP_NEG_INT); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "add_nat", token.length)) { - emit_op(vm, OP_ADD_NAT); + asm_emit_op(vm, OP_ADD_NAT); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "sub_nat", token.length)) { - emit_op(vm, OP_SUB_NAT); + asm_emit_op(vm, OP_SUB_NAT); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "mul_nat", token.length)) { - emit_op(vm, OP_MUL_NAT); + asm_emit_op(vm, OP_MUL_NAT); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "div_nat", token.length)) { - emit_op(vm, OP_DIV_NAT); + asm_emit_op(vm, OP_DIV_NAT); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "abs_nat", token.length)) { - emit_op(vm, OP_ABS_NAT); + asm_emit_op(vm, OP_ABS_NAT); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "neg_nat", token.length)) { - emit_op(vm, OP_NEG_NAT); + asm_emit_op(vm, OP_NEG_NAT); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "add_real", token.length)) { - emit_op(vm, OP_ADD_REAL); + asm_emit_op(vm, OP_ADD_REAL); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); ; } else if (strleq(token.start, "sub_real", token.length)) { - emit_op(vm, OP_SUB_REAL); + asm_emit_op(vm, OP_SUB_REAL); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "mul_real", token.length)) { - emit_op(vm, OP_MUL_REAL); + asm_emit_op(vm, OP_MUL_REAL); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "div_real", token.length)) { - emit_op(vm, OP_DIV_REAL); + asm_emit_op(vm, OP_DIV_REAL); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "abs_real", token.length)) { - emit_op(vm, OP_ABS_REAL); + asm_emit_op(vm, OP_ABS_REAL); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "neg_real", token.length)) { - emit_op(vm, OP_NEG_REAL); + asm_emit_op(vm, OP_NEG_REAL); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "int_to_real", token.length)) { - emit_op(vm, OP_INT_TO_REAL); + asm_emit_op(vm, OP_INT_TO_REAL); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "nat_to_real", token.length)) { - emit_op(vm, OP_NAT_TO_REAL); + asm_emit_op(vm, OP_NAT_TO_REAL); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "real_to_int", token.length)) { - emit_op(vm, OP_REAL_TO_INT); + asm_emit_op(vm, OP_REAL_TO_INT); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "real_to_nat", token.length)) { - emit_op(vm, OP_REAL_TO_NAT); + asm_emit_op(vm, OP_REAL_TO_NAT); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "bit_shift_left", token.length)) { - emit_op(vm, OP_BIT_SHIFT_LEFT); + asm_emit_op(vm, OP_BIT_SHIFT_LEFT); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "bit_shift_right", token.length)) { - emit_op(vm, OP_BIT_SHIFT_RIGHT); + asm_emit_op(vm, OP_BIT_SHIFT_RIGHT); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "bit_shift_r_ext", token.length)) { - emit_op(vm, OP_BIT_SHIFT_R_EXT); + asm_emit_op(vm, OP_BIT_SHIFT_R_EXT); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "bit_and", token.length)) { - emit_op(vm, OP_BAND); + asm_emit_op(vm, OP_BAND); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "bit_or", token.length)) { - emit_op(vm, OP_BOR); + asm_emit_op(vm, OP_BOR); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "bit_xor", token.length)) { - emit_op(vm, OP_BXOR); + asm_emit_op(vm, OP_BXOR); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); + arg = asm_get_reg(next, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump", token.length)) { - emit_op(vm, OP_JMP); + asm_emit_op(vm, OP_JMP); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_if_flag", token.length)) { - emit_op(vm, OP_JMPF); + asm_emit_op(vm, OP_JMPF); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_eq_int", token.length)) { - emit_op(vm, OP_JEQ_INT); + asm_emit_op(vm, OP_JEQ_INT); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_neq_int", token.length)) { - emit_op(vm, OP_JNEQ_INT); + asm_emit_op(vm, OP_JNEQ_INT); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_gt_int", token.length)) { - emit_op(vm, OP_JGT_INT); + asm_emit_op(vm, OP_JGT_INT); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_lt_int", token.length)) { - emit_op(vm, OP_JLT_INT); + asm_emit_op(vm, OP_JLT_INT); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_le_int", token.length)) { - emit_op(vm, OP_JLE_INT); + asm_emit_op(vm, OP_JLE_INT); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_ge_int", token.length)) { - emit_op(vm, OP_JGE_INT); + asm_emit_op(vm, OP_JGE_INT); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_eq_nat", token.length)) { - emit_op(vm, OP_JEQ_NAT); + asm_emit_op(vm, OP_JEQ_NAT); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_neq_nat", token.length)) { - emit_op(vm, OP_JNEQ_NAT); + asm_emit_op(vm, OP_JNEQ_NAT); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_gt_nat", token.length)) { - emit_op(vm, OP_JGT_NAT); + asm_emit_op(vm, OP_JGT_NAT); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_lt_nat", token.length)) { - emit_op(vm, OP_JLT_NAT); + asm_emit_op(vm, OP_JLT_NAT); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_le_nat", token.length)) { - emit_op(vm, OP_JLE_NAT); + asm_emit_op(vm, OP_JLE_NAT); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_ge_nat", token.length)) { - emit_op(vm, OP_JGE_NAT); + asm_emit_op(vm, OP_JGE_NAT); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_eq_real", token.length)) { - emit_op(vm, OP_JEQ_REAL); + asm_emit_op(vm, OP_JEQ_REAL); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_neq_real", token.length)) { - emit_op(vm, OP_JNEQ_REAL); + asm_emit_op(vm, OP_JNEQ_REAL); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_ge_real", token.length)) { - emit_op(vm, OP_JGE_REAL); + asm_emit_op(vm, OP_JGE_REAL); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_gt_real", token.length)) { - emit_op(vm, OP_JGT_REAL); + asm_emit_op(vm, OP_JGT_REAL); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_lt_real", token.length)) { - emit_op(vm, OP_JLT_REAL); + asm_emit_op(vm, OP_JLT_REAL); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_le_real", token.length)) { - emit_op(vm, OP_JLE_REAL); + asm_emit_op(vm, OP_JLE_REAL); vm->cp++; Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); + u32 ptr = asm_get_ptr(id, st); + asm_emit_u32(vm, ptr); vm->cp += 4; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "string_length", token.length)) { - emit_op(vm, OP_STRLEN); + asm_emit_op(vm, OP_STRLEN); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "int_to_string", token.length)) { - emit_op(vm, OP_INT_TO_STRING); + asm_emit_op(vm, OP_INT_TO_STRING); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "nat_to_string", token.length)) { - emit_op(vm, OP_NAT_TO_STRING); + asm_emit_op(vm, OP_NAT_TO_STRING); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "real_to_string", token.length)) { - emit_op(vm, OP_REAL_TO_STRING); + asm_emit_op(vm, OP_REAL_TO_STRING); vm->cp++; Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); + u8 arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); + asm_next_token_is(TOKEN_ARROW_RIGHT); reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); + arg = asm_get_reg(reg, st); + asm_emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON); + asm_next_token_is(TOKEN_SEMICOLON); ; } else if (strleq(token.start, "string_eq", token.length)) { } else if (strleq(token.start, "string_concat", token.length)) { @@ -2470,8 +2440,8 @@ void emit_bytecode(VM *vm, char *source, ScopeTable *st) { * Emit bytecode to the VM from the source string. */ void assemble(VM *vm, ScopeTable *st, char *source) { - build_symbol_table(vm, source, st); + asm_build_symbol_table(vm, source, st); vm->cp = 0; /* actually start emitting code */ st->count = 0; - emit_bytecode(vm, source, st); + asm_emit_bytecode(vm, source, st); } diff --git a/src/tools/assembler/assembler.h b/src/tools/assembler/assembler.h index ba2492d..ee455ca 100644 --- a/src/tools/assembler/assembler.h +++ b/src/tools/assembler/assembler.h @@ -1,55 +1,10 @@ #ifndef UNDAR_IR_ASSEMBLER_H #define UNDAR_IR_ASSEMBLER_H +#include "../lexer.h" +#include "../codegen.h" #include "../../vm/common.h" #include "../../vm/opcodes.h" -#include "lexer.h" - -typedef enum { GLOBAL, LOCAL, VAR } ScopeType; -typedef enum { - VOID, - BOOL, - I8, - I16, - I32, - U8, - U16, - U32, - F8, - F16, - F32, - STR, - PLEX, - ARRAY, - FUNCTION -} SymbolType; - -typedef struct symbol_s Symbol; -typedef struct symbol_tab_s SymbolTable; -typedef struct scope_tab_s ScopeTable; - -#define MAX_SYMBOL_NAME_LENGTH 64 -struct symbol_s { - char name[MAX_SYMBOL_NAME_LENGTH]; - u8 name_length; - SymbolType type; - ScopeType scope; - u32 ref; // vm->mp if global, vm->pc local, register if var - u32 size; // size of symbol -}; - -struct symbol_tab_s { - Symbol symbols[256]; - u8 count; - i32 parent; -}; - -struct scope_tab_s { - SymbolTable *scopes; - u32 count; - u32 capacity; - i32 scope_ref; -}; void assemble(VM *vm, ScopeTable *st, char *source); extern bool table_realloc(ScopeTable *table);/* implement this in arch/ not here */ diff --git a/src/tools/codegen.h b/src/tools/codegen.h new file mode 100644 index 0000000..e5b2ccd --- /dev/null +++ b/src/tools/codegen.h @@ -0,0 +1,91 @@ +#ifndef UNDAR_CODEGEN_H +#define UNDAR_CODEGEN_H + +#include "../vm/common.h" + +typedef enum { GLOBAL, LOCAL, VAR } ScopeType; +typedef enum { + VOID, + BOOL, + I8, + I16, + I32, + U8, + U16, + U32, + F8, + F16, + F32, + STR, + PLEX, + ARRAY, + FUNCTION +} SymbolType; + +typedef struct symbol_s Symbol; +typedef struct symbol_tab_s SymbolTable; +typedef struct value_type_s ValueType; +typedef struct plex_fields_tab_s PlexFieldsTable; +typedef struct plex_def_s PlexDef; +typedef struct plex_tab_s PlexTable; +typedef struct scope_s Scope; +typedef struct scope_tab_s ScopeTable; + +#define MAX_SYMBOL_NAME_LENGTH 64 + +struct value_type_s { + SymbolType type; + char name[MAX_SYMBOL_NAME_LENGTH]; + u8 name_length; + u32 size; + u32 table_ref; // if it is a heap object +}; + +struct plex_fields_tab_s { + u32 *plex_refs; + ValueType *fields; + u32 count; + u32 capacity; +}; + +struct plex_def_s { + char name[MAX_SYMBOL_NAME_LENGTH]; + u8 name_length; + u32 size; + u32 field_ref_start; + u32 field_count; +}; + +struct plex_tab_s { + PlexDef *symbols; + u32 count; + u32 capacity; +}; + +struct symbol_s { + char name[MAX_SYMBOL_NAME_LENGTH]; + u8 name_length; + SymbolType type; + ScopeType scope; + u32 ref; // vm->mp if global, vm->pc local, register if var + u32 size; // size of symbol +}; + +struct symbol_tab_s { + Symbol symbols[256]; + u8 count; + i32 parent; +}; + +struct scope_tab_s { + SymbolTable *scopes; + u32 count; + u32 capacity; + i32 scope_ref; + u32 depth; + u8 last_used_registers[1024]; + u32 reg_count; + u8 current_reg; +}; + +#endif \ No newline at end of file diff --git a/src/tools/compiler/compiler.c b/src/tools/compiler/compiler.c index b6b3d38..8b350fd 100644 --- a/src/tools/compiler/compiler.c +++ b/src/tools/compiler/compiler.c @@ -3,7 +3,7 @@ #include "../../vm/libc.h" #include "../../vm/opcodes.h" -#include "parser.h" +#include "../lexer.h" #include "compiler.h" /* FIXME: remove these and replace with libc.h instead */ @@ -150,6 +150,8 @@ Token next_token_is(TokenType type) { * Const . */ bool parse_const(VM *vm, ScopeTable *st) { + USED(vm); + USED(st); return true; } @@ -411,7 +413,8 @@ void define_var(ScopeTable *st, Token regType) { * Plex . */ void define_plex(VM *vm, ScopeTable *st) { - + USED(vm); + USED(st); } @@ -602,7 +605,7 @@ int get_instruction_byte_size(const char *opname) { */ void build_symbol_table(VM *vm, char *source, ScopeTable *st) { Token token; - init_parser(source); + init_lexer(source); do { token = next_token(); if (token.type == TOKEN_ERROR) { @@ -839,7 +842,7 @@ void build_symbol_table(VM *vm, char *source, ScopeTable *st) { */ void emit_bytecode(VM *vm, char *source, ScopeTable *st) { Token token; - init_parser(source); + init_lexer(source); do { token = next_token(); if (token.type == TOKEN_ERROR) { diff --git a/src/tools/compiler/compiler.h b/src/tools/compiler/compiler.h index 8593db8..4600bdd 100644 --- a/src/tools/compiler/compiler.h +++ b/src/tools/compiler/compiler.h @@ -1,94 +1,10 @@ #ifndef UNDAR_COMPILER_H #define UNDAR_COMPILER_H -#import "../../vm/common.h" +#include "../codegen.h" +#include "../../vm/common.h" #include "../../vm/opcodes.h" -typedef enum { GLOBAL, LOCAL, VAR } ScopeType; -typedef enum { - VOID, - BOOL, - I8, - I16, - I32, - U8, - U16, - U32, - F8, - F16, - F32, - STR, - PLEX, - ARRAY, - FUNCTION -} SymbolType; - -typedef struct symbol_s Symbol; -typedef struct symbol_tab_s SymbolTable; -typedef struct value_type_s ValueType; -typedef struct plex_fields_tab_s PlexFieldsTable; -typedef struct plex_def_s PlexDef; -typedef struct plex_tab_s PlexTable; -typedef struct scope_s Scope; -typedef struct scope_tab_s ScopeTable; - -#define MAX_SYMBOL_NAME_LENGTH 64 - -struct value_type_s { - SymbolType type; - char name[MAX_SYMBOL_NAME_LENGTH]; - u8 name_length; - u32 size; - u32 table_ref; // if it is a heap object -}; - -struct plex_fields_tab_s { - u32 *plex_refs; - ValueType *fields; - u32 count; - u32 capacity; -}; - -struct plex_def_s { - char name[MAX_SYMBOL_NAME_LENGTH]; - u8 name_length; - u32 size; - u32 field_ref_start; - u32 field_count; -}; - -struct plex_tab_s { - PlexDef *symbols; - u32 count; - u32 capacity; -}; - -struct symbol_s { - char name[MAX_SYMBOL_NAME_LENGTH]; - u8 name_length; - SymbolType type; - ScopeType scope; - u32 ref; // vm->mp if global, vm->pc local, register if var - u32 size; // size of symbol -}; - -struct symbol_tab_s { - Symbol symbols[256]; - u8 count; - i32 parent; -}; - -struct scope_tab_s { - SymbolTable *scopes; - u32 count; - u32 capacity; - i32 scope_ref; - u32 depth; - u8 last_used_registers[1024]; - u32 reg_count; - u8 current_reg; -}; - bool compile(VM *vm, ScopeTable *st, char *source); extern bool table_realloc(ScopeTable *table);/* implement this in arch/ not here */ diff --git a/src/tools/compiler/parser.c b/src/tools/compiler/parser.c deleted file mode 100644 index 01f83f4..0000000 --- a/src/tools/compiler/parser.c +++ /dev/null @@ -1,515 +0,0 @@ -#include - -#include "../../vm/common.h" -#include "parser.h" - -typedef struct { - const char *start; - const char *current; - int line; -} Parser; - -Parser parser; - -void init_parser(const char *source) { - parser.start = source; - parser.current = source; - parser.line = 1; -} - -static bool isAlpha(char c) { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'; -} - -static bool isDigit(char c) { return c >= '0' && c <= '9'; } - -static bool isAtEnd() { return *parser.current == '\0'; } - -static char advance() { - parser.current++; - return parser.current[-1]; -} - -static char peek() { return *parser.current; } - -static char peekNext() { - if (isAtEnd()) - return '\0'; - return parser.current[1]; -} - -static bool match(char expected) { - if (isAtEnd()) - return false; - if (*parser.current != expected) - return false; - parser.current++; - return true; -} - -static Token makeToken(TokenType type) { - Token token; - token.type = type; - token.start = parser.start; - token.length = (int)(parser.current - parser.start); - token.line = parser.line; - return token; -} - -static Token errorToken(const char *message) { - Token token; - token.type = TOKEN_ERROR; - token.start = message; - token.length = (int)strlen(message); - token.line = parser.line; - return token; -} - -static void skipWhitespace() { - for (;;) { - char c = peek(); - switch (c) { - case ' ': - case '\r': - case '\t': - advance(); - break; - case '\n': - parser.line++; - advance(); - break; - case '/': - if (peekNext() == '/') { - // Single-line comment: skip until newline or end of file - advance(); - while (peek() != '\n' && !isAtEnd()) - advance(); - } else if (peekNext() == '*') { - // Multi-line comment: skip until '*/' or end of file - advance(); - advance(); - while (!isAtEnd()) { - if (peek() == '\n') - parser.line++; - if (peek() == '*' && peekNext() == '/') { - advance(); - advance(); - break; // Exit loop, comment ended - } - advance(); - } - } else { - return; // Not a comment, let tokenization handle it - } - break; - default: - return; - } - } -} - -static TokenType checkKeyword(int start, int length, const char *rest, - TokenType type) { - if (parser.current - parser.start == start + length && - memcmp(parser.start + start, rest, length) == 0) { - return type; - } - - return TOKEN_IDENTIFIER; -} - -static TokenType identifierType() { - switch (parser.start[0]) { - case 'a': - if (parser.current - parser.start > 1) { - switch (parser.start[1]) { - case 'n': - return checkKeyword(2, 1, "d", TOKEN_OPERATOR_AND); - case 's': - return checkKeyword(2, 0, "", TOKEN_KEYWORD_AS); - } - } - break; - case 'c': - if (parser.current - parser.start > 1) { - switch (parser.start[1]) { - case 'l': - return checkKeyword(2, 3, "ose", TOKEN_KEYWORD_CLOSE); - case 'o': - return checkKeyword(2, 3, "nst", TOKEN_KEYWORD_CONST); - } - } - break; - case 'e': - return checkKeyword(1, 3, "lse", TOKEN_KEYWORD_ELSE); - case 'f': - if (parser.current - parser.start > 1) { - switch (parser.start[1]) { - case 'a': - return checkKeyword(2, 3, "lse", TOKEN_KEYWORD_FALSE); - case 'o': - return checkKeyword(2, 1, "r", TOKEN_KEYWORD_FOR); - case '3': - return checkKeyword(2, 1, "2", TOKEN_TYPE_REAL); - } - return checkKeyword(1, 7, "unction", TOKEN_KEYWORD_FN); - } - break; - case 'i': - if (parser.current - parser.start > 1) { - switch (parser.start[1]) { - case 'f': - return checkKeyword(2, 0, "", TOKEN_KEYWORD_IF); - case 's': - return checkKeyword(2, 0, "", TOKEN_KEYWORD_IS); - case '8': - return checkKeyword(2, 0, "", TOKEN_TYPE_I8); - case '1': - return checkKeyword(2, 1, "6", TOKEN_TYPE_I16); - case '3': - return checkKeyword(2, 1, "2", TOKEN_TYPE_INT); - case 'n': - if (parser.current - parser.start > 2) { - switch (parser.start[2]) { - case 'i': - return checkKeyword(3, 2, "t", TOKEN_KEYWORD_INIT); - case 't': - return checkKeyword(3, 0, "", TOKEN_TYPE_INT); - } - } - break; - } - } - break; - case 'n': - if (parser.current - parser.start > 1) { - switch (parser.start[1]) { - case 'a': - return checkKeyword(2, 1, "t", TOKEN_TYPE_NAT); - case 'i': - return checkKeyword(2, 1, "l", TOKEN_KEYWORD_NIL); - } - } - break; - case 'o': - if (parser.current - parser.start > 1) { - switch (parser.start[1]) { - case 'p': - return checkKeyword(2, 2, "en", TOKEN_KEYWORD_OPEN); - case 'r': - return checkKeyword(2, 0, "", TOKEN_OPERATOR_OR); - } - } - break; - case 'p': - if (parser.current - parser.start > 1) { - switch (parser.start[1]) { - case 't': - return checkKeyword(2, 1, "r", TOKEN_TYPE_PTR); - case 'l': - return checkKeyword(2, 2, "ex", TOKEN_KEYWORD_PLEX); - } - } - break; - case 'r': - if (parser.current - parser.start > 1) { - switch (parser.start[1]) { - case 'e': - if (parser.current - parser.start > 2) { - switch (parser.start[2]) { - case 'a': - return checkKeyword(3, 1, "d", TOKEN_KEYWORD_READ); - case 't': - return checkKeyword(3, 3, "urn", TOKEN_KEYWORD_RETURN); - } - } - break; - } - } - break; - case 's': - if (parser.current - parser.start > 1) { - switch (parser.start[1]) { - case 't': - if (parser.current - parser.start > 2) { - switch (parser.start[2]) { - case 'r': - return checkKeyword(2, 0, "", TOKEN_TYPE_STR); - case 'a': - return checkKeyword(2, 1, "t", TOKEN_KEYWORD_STAT); - } - } - } - } - break; - case 't': - if (parser.current - parser.start > 1) { - switch (parser.start[1]) { - case 'h': - return checkKeyword(2, 2, "is", TOKEN_KEYWORD_THIS); - case 'r': - return checkKeyword(2, 2, "ue", TOKEN_KEYWORD_TRUE); - } - } - break; - case 'u': - if (parser.current - parser.start > 1) { - switch (parser.start[1]) { - case 's': - return checkKeyword(2, 1, "e", TOKEN_KEYWORD_USE); - case '8': - return checkKeyword(2, 0, "", TOKEN_TYPE_U8); - case '1': - return checkKeyword(2, 1, "6", TOKEN_TYPE_U16); - case '3': - return checkKeyword(2, 1, "2", TOKEN_TYPE_NAT); - } - } - break; - case 'w': - if (parser.current - parser.start > 1) { - switch (parser.start[1]) { - case 'h': - return checkKeyword(2, 3, "ile", TOKEN_KEYWORD_WHILE); - case 'r': - return checkKeyword(2, 3, "ite", TOKEN_KEYWORD_WRITE); - } - } - break; - } - - return TOKEN_IDENTIFIER; -} - -static Token identifier() { - while (isAlpha(peek()) || isDigit(peek())) - advance(); - return makeToken(identifierType()); -} - -static Token number() { - while (isDigit(peek())) - advance(); - - /* Look for a fractional part. */ - if (peek() == '.' && isDigit(peekNext())) { - /* Consume the ".". */ - advance(); - - while (isDigit(peek())) - advance(); - - return makeToken(TOKEN_LITERAL_REAL); - } - - return makeToken(TOKEN_LITERAL_INT); -} - -static Token string() { - while (peek() != '"' && !isAtEnd()) { - if (peek() == '\n') - parser.line++; - advance(); - } - - if (isAtEnd()) - return errorToken("Unterminated string."); - - /* The closing quote. */ - advance(); - return makeToken(TOKEN_LITERAL_STR); -} - -Token next_token() { - skipWhitespace(); - parser.start = parser.current; - - if (isAtEnd()) - return makeToken(TOKEN_EOF); - - char c = advance(); - if (isAlpha(c)) - return identifier(); - if (isDigit(c)) - return number(); - - switch (c) { - case '(': - return makeToken(TOKEN_LPAREN); - case ')': - return makeToken(TOKEN_RPAREN); - case '{': - return makeToken(TOKEN_LBRACE); - case '}': - return makeToken(TOKEN_RBRACE); - case '[': - return makeToken(TOKEN_LBRACKET); - case ']': - return makeToken(TOKEN_RBRACKET); - case ';': - return makeToken(TOKEN_SEMICOLON); - case ',': - return makeToken(TOKEN_COMMA); - case '.': - return makeToken(TOKEN_DOT); - case '-': - return makeToken(match('>') ? TOKEN_ARROW_RIGHT : TOKEN_MINUS); - case '+': - return makeToken(TOKEN_PLUS); - case '/': - return makeToken(TOKEN_SLASH); - case '&': - return makeToken(match('&') ? TOKEN_AND_AND : TOKEN_AND); - case '#': - return makeToken(TOKEN_MESH); - case '$': - return makeToken(TOKEN_BIG_MONEY); - case '*': - return makeToken(TOKEN_STAR); - case '!': - return makeToken(match('=') ? TOKEN_BANG_EQ : TOKEN_BANG); - case '=': - return makeToken(match('=') ? TOKEN_EQ_EQ : TOKEN_EQ); - case '<': - return makeToken(match('=') ? TOKEN_LTE : TOKEN_LT); - case '>': - return makeToken(match('=') ? TOKEN_GTE : TOKEN_GT); - case '"': - return string(); - } - - return errorToken("Unexpected character."); -} - -const char *token_type_to_string(TokenType type) { - switch (type) { - case TOKEN_EOF: - return "EOF"; - case TOKEN_IDENTIFIER: - return "IDENTIFIER"; - case TOKEN_LITERAL_INT: - return "LITERAL_INT"; - case TOKEN_LITERAL_NAT: - return "LITERAL_NAT"; - case TOKEN_LITERAL_REAL: - return "LITERAL_REAL"; - case TOKEN_LITERAL_STR: - return "LITERAL_STR"; - case TOKEN_TYPE_INT: - return "TYPE_INT"; - case TOKEN_TYPE_NAT: - return "TYPE_NAT"; - case TOKEN_TYPE_REAL: - return "TYPE_REAL"; - case TOKEN_TYPE_STR: - return "TYPE_STR"; - case TOKEN_TYPE_PTR: - return "TYPE_PTR"; - case TOKEN_KEYWORD_PLEX: - return "KEYWORD_PLEX"; - case TOKEN_KEYWORD_FN: - return "KEYWORD_FN"; - case TOKEN_KEYWORD_CONST: - return "KEYWORD_CONST"; - case TOKEN_KEYWORD_IF: - return "KEYWORD_IF"; - case TOKEN_KEYWORD_IS: - return "IS"; - case TOKEN_KEYWORD_AS: - return "AS"; - case TOKEN_KEYWORD_ELSE: - return "KEYWORD_ELSE"; - case TOKEN_KEYWORD_WHILE: - return "KEYWORD_WHILE"; - case TOKEN_KEYWORD_FOR: - return "KEYWORD_FOR"; - case TOKEN_KEYWORD_RETURN: - return "KEYWORD_RETURN"; - case TOKEN_KEYWORD_USE: - return "KEYWORD_USE"; - case TOKEN_KEYWORD_INIT: - return "KEYWORD_INIT"; - case TOKEN_KEYWORD_THIS: - return "KEYWORD_THIS"; - case TOKEN_KEYWORD_OPEN: - return "TOKEN_KEYWORD_OPEN"; - case TOKEN_KEYWORD_READ: - return "TOKEN_KEYWORD_READ"; - case TOKEN_KEYWORD_WRITE: - return "TOKEN_KEYWORD_WRITE"; - case TOKEN_KEYWORD_STAT: - return "TOKEN_KEYWORD_STAT"; - case TOKEN_KEYWORD_CLOSE: - return "TOKEN_KEYWORD_CLOSE"; - case TOKEN_KEYWORD_NIL: - return "KEYWORD_NIL"; - case TOKEN_KEYWORD_TRUE: - return "KEYWORD_TRUE"; - case TOKEN_KEYWORD_FALSE: - return "KEYWORD_FALSE"; - case TOKEN_OPERATOR_NOT: - return "OPERATOR_NOT"; - case TOKEN_OPERATOR_AND: - return "OPERATOR_AND"; - case TOKEN_OPERATOR_OR: - return "OPERATOR_OR"; - case TOKEN_BANG: - return "BANG"; - case TOKEN_BANG_EQ: - return "BANG_EQ"; - case TOKEN_EQ: - return "EQ"; - case TOKEN_EQ_EQ: - return "EQ_EQ"; - case TOKEN_GT: - return "GT"; - case TOKEN_LT: - return "LT"; - case TOKEN_GTE: - return "GTE"; - case TOKEN_LTE: - return "LTE"; - case TOKEN_DOT: - return "DOT"; - case TOKEN_COMMA: - return "COMMA"; - case TOKEN_COLON: - return "COLON"; - case TOKEN_SEMICOLON: - return "SEMICOLON"; - case TOKEN_PLUS: - return "PLUS"; - case TOKEN_MINUS: - return "MINUS"; - case TOKEN_STAR: - return "STAR"; - case TOKEN_SLASH: - return "SLASH"; - case TOKEN_LPAREN: - return "LPAREN"; - case TOKEN_RPAREN: - return "RPAREN"; - case TOKEN_LBRACE: - return "LBRACE"; - case TOKEN_RBRACE: - return "RBRACE"; - case TOKEN_LBRACKET: - return "LBRACKET"; - case TOKEN_RBRACKET: - return "RBRACKET"; - case TOKEN_ARROW_RIGHT: - return "ARROW_RIGHT"; - case TOKEN_MESH: - return "MESH"; - case TOKEN_BIG_MONEY: - return "BIG_MONEY"; - case TOKEN_AND: - return "AND"; - case TOKEN_AND_AND: - return "AND_AND"; - case TOKEN_ERROR: - return "ERROR"; - default: - return "UNKNOWN_TOKEN"; - } -} diff --git a/src/tools/compiler/parser.h b/src/tools/compiler/parser.h deleted file mode 100644 index f8282e4..0000000 --- a/src/tools/compiler/parser.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef UNDAR_LEXER_H -#define UNDAR_LEXER_H - -typedef enum { - TOKEN_EOF, - TOKEN_IDENTIFIER, - TOKEN_LITERAL_INT, - TOKEN_LITERAL_NAT, - TOKEN_LITERAL_REAL, - TOKEN_LITERAL_STR, - TOKEN_TYPE_I8, - TOKEN_TYPE_I16, - TOKEN_TYPE_INT, - TOKEN_TYPE_U8, - TOKEN_TYPE_U16, - TOKEN_TYPE_NAT, - TOKEN_TYPE_REAL, - TOKEN_TYPE_STR, - TOKEN_TYPE_BOOL, - TOKEN_TYPE_VOID, - TOKEN_TYPE_PTR, - TOKEN_KEYWORD_PLEX, - TOKEN_KEYWORD_FN, - TOKEN_KEYWORD_CONST, - TOKEN_KEYWORD_IF, - TOKEN_KEYWORD_IS, - TOKEN_KEYWORD_AS, - TOKEN_KEYWORD_ELSE, - TOKEN_KEYWORD_WHILE, - TOKEN_KEYWORD_FOR, - TOKEN_KEYWORD_RETURN, - TOKEN_KEYWORD_USE, - TOKEN_KEYWORD_INIT, - TOKEN_KEYWORD_THIS, - TOKEN_KEYWORD_OPEN, - TOKEN_KEYWORD_READ, - TOKEN_KEYWORD_WRITE, - TOKEN_KEYWORD_STAT, - TOKEN_KEYWORD_CLOSE, - TOKEN_KEYWORD_LOOP, - TOKEN_KEYWORD_DO, - TOKEN_KEYWORD_NIL, - TOKEN_KEYWORD_TRUE, - TOKEN_KEYWORD_FALSE, - TOKEN_OPERATOR_NOT, - TOKEN_OPERATOR_AND, - TOKEN_OPERATOR_OR, - TOKEN_BANG, - TOKEN_BANG_EQ, - TOKEN_EQ, - TOKEN_EQ_EQ, - TOKEN_AND, - TOKEN_AND_AND, - TOKEN_GT, - TOKEN_LT, - TOKEN_GTE, - TOKEN_LTE, - TOKEN_DOT, - TOKEN_COMMA, - TOKEN_COLON, - TOKEN_SEMICOLON, - TOKEN_PLUS, - TOKEN_MINUS, - TOKEN_STAR, - TOKEN_SLASH, - TOKEN_MESH, - TOKEN_BIG_MONEY, - TOKEN_LPAREN, - TOKEN_RPAREN, - TOKEN_LBRACE, - TOKEN_RBRACE, - TOKEN_LBRACKET, - TOKEN_RBRACKET, - TOKEN_ARROW_RIGHT, - TOKEN_ERROR -} TokenType; - -typedef struct { - TokenType type; - const char *start; - int length; - int line; -} Token; - -void init_parser(const char *source); -Token next_token(); -const char* token_type_to_string(TokenType type); - -#endif diff --git a/src/tools/assembler/lexer.c b/src/tools/lexer.c similarity index 96% rename from src/tools/assembler/lexer.c rename to src/tools/lexer.c index 58a2078..977a437 100644 --- a/src/tools/assembler/lexer.c +++ b/src/tools/lexer.c @@ -1,6 +1,6 @@ #include -#include "../../vm/common.h" +#include "../vm/common.h" #include "lexer.h" typedef struct { @@ -203,7 +203,9 @@ static TokenType identifierType() { break; case 'p': if (lexer.current - lexer.start > 1) { - switch (lexer.start[1]) { + switch (lexer.start[1]) { case 't': + return check_keyword(2, 1, "r", TOKEN_TYPE_PTR); + case 'l': return check_keyword(2, 2, "ex", TOKEN_KEYWORD_PLEX); } @@ -215,8 +217,6 @@ static TokenType identifierType() { case 'e': if (lexer.current - lexer.start > 2) { switch (lexer.start[2]) { - case 'f': - return check_keyword(3, 4, "resh", TOKEN_KEYWORD_REFRESH); case 't': return check_keyword(3, 3, "urn", TOKEN_KEYWORD_RETURN); case 'a': @@ -238,7 +238,14 @@ static TokenType identifierType() { if (lexer.current - lexer.start > 1) { switch (lexer.start[1]) { case 't': - return check_keyword(2, 1, "r", TOKEN_TYPE_STR); + if (lexer.current - lexer.start > 2) { + switch (lexer.start[2]) { + case 'r': + return check_keyword(3, 0, "", TOKEN_TYPE_STR); + case 'a': + return check_keyword(3, 1, "t", TOKEN_KEYWORD_STAT); + } + } } } break; @@ -422,6 +429,8 @@ const char *token_type_to_string(TokenType type) { return "TYPE_REAL"; case TOKEN_TYPE_STR: return "TYPE_STR"; + case TOKEN_TYPE_PTR: + return "TYPE_PTR"; case TOKEN_KEYWORD_PLEX: return "KEYWORD_PLEX"; case TOKEN_KEYWORD_FN: @@ -454,8 +463,8 @@ const char *token_type_to_string(TokenType type) { return "TOKEN_KEYWORD_READ"; case TOKEN_KEYWORD_WRITE: return "TOKEN_KEYWORD_WRITE"; - case TOKEN_KEYWORD_REFRESH: - return "TOKEN_KEYWORD_REFRESH"; + case TOKEN_KEYWORD_STAT: + return "TOKEN_KEYWORD_STAT"; case TOKEN_KEYWORD_CLOSE: return "TOKEN_KEYWORD_CLOSE"; case TOKEN_KEYWORD_NIL: diff --git a/src/tools/assembler/lexer.h b/src/tools/lexer.h similarity index 97% rename from src/tools/assembler/lexer.h rename to src/tools/lexer.h index debd5ce..fb4448f 100644 --- a/src/tools/assembler/lexer.h +++ b/src/tools/lexer.h @@ -18,6 +18,7 @@ typedef enum { TOKEN_TYPE_STR, TOKEN_TYPE_BOOL, TOKEN_TYPE_VOID, + TOKEN_TYPE_PTR, TOKEN_KEYWORD_PLEX, TOKEN_KEYWORD_FN, TOKEN_KEYWORD_CONST, @@ -35,7 +36,7 @@ typedef enum { TOKEN_KEYWORD_OPEN, TOKEN_KEYWORD_READ, TOKEN_KEYWORD_WRITE, - TOKEN_KEYWORD_REFRESH, + TOKEN_KEYWORD_STAT, TOKEN_KEYWORD_CLOSE, TOKEN_KEYWORD_LOOP, TOKEN_KEYWORD_DO, diff --git a/test/add.uir.ul b/test/add.uir.ul index 95e3df0..49ed9e3 100644 --- a/test/add.uir.ul +++ b/test/add.uir.ul @@ -7,7 +7,7 @@ function main () { int local_x; int local_y; int result; - int result_str; + str result_str; load_absolute_32 x -> local_x; load_absolute_32 y -> local_y;