diff --git a/src/tools/assembler/assembler.c b/src/tools/assembler/assembler.c index 3fdc9a9..244cdcd 100644 --- a/src/tools/assembler/assembler.c +++ b/src/tools/assembler/assembler.c @@ -8,10 +8,151 @@ #include #include -void emit_byte(VM *vm, u8 byte) { vm->code[vm->cp] = byte; } +const char *opcode_to_string(Opcode op) { + static const char *names[] = { + [OP_EXIT] = "exit", + [OP_JMP] = "jump", + [OP_JMPF] = "jump-if-flag", + [OP_CALL] = "call", + [OP_RETURN] = "return", + + /* Immediate loads (only 32-bit variant needed) */ + [OP_LOAD_IMM] = "load-immediate", + + /* Register-indirect loads */ + [OP_LOAD_IND_8] = "load-indirect-8", + [OP_LOAD_IND_16] = "load-indirect-16", + [OP_LOAD_IND_32] = "load-indirect-32", + + /* Absolute address loads */ + [OP_LOAD_ABS_8] = "load-absolute-8", + [OP_LOAD_ABS_16] = "load-absolute-16", + [OP_LOAD_ABS_32] = "load-absolute-32", + + /* Base+offset loads */ + [OP_LOAD_OFF_8] = "load-offset-8", + [OP_LOAD_OFF_16] = "load-offset-16", + [OP_LOAD_OFF_32] = "load-offset-32", + + /* Absolute address stores */ + [OP_STORE_ABS_8] = "store-absolute-8", + [OP_STORE_ABS_16] = "store-absolute-16", + [OP_STORE_ABS_32] = "store-absolute-32", + + /* Register-indirect stores */ + [OP_STORE_IND_8] = "store-indirect-8", + [OP_STORE_IND_16] = "store-indirect-16", + [OP_STORE_IND_32] = "store-indirect-32", + + /* Base+offset stores */ + [OP_STORE_OFF_8] = "store-offset-8", + [OP_STORE_OFF_16] = "store-offset-16", + [OP_STORE_OFF_32] = "store-offset-32", + + /* Memory operations */ + [OP_MALLOC] = "malloc", + [OP_MEMSET_8] = "memset-8", + [OP_MEMSET_16] = "memset-16", + [OP_MEMSET_32] = "memset-32", + + /* Register operations */ + [OP_REG_MOV] = "register-move", + [OP_SYSCALL] = "syscall", + + /* Bit operations */ + [OP_BIT_SHIFT_LEFT] = "bit-shift-left", + [OP_BIT_SHIFT_RIGHT] = "bit-shift-right", + [OP_BIT_SHIFT_R_EXT] = "bit-shift-re", + [OP_BAND] = "bit-and", + [OP_BOR] = "bit-or", + [OP_BXOR] = "bit-xor", + + /* Integer arithmetic */ + [OP_ADD_INT] = "add-int", + [OP_SUB_INT] = "sub-int", + [OP_MUL_INT] = "mul-int", + [OP_DIV_INT] = "div-int", + + /* Natural number arithmetic */ + [OP_ADD_NAT] = "add-nat", + [OP_SUB_NAT] = "sub-nat", + [OP_MUL_NAT] = "mul-nat", + [OP_DIV_NAT] = "div-nat", + + /* Floating point operations */ + [OP_ADD_REAL] = "add-real", + [OP_SUB_REAL] = "sub-real", + [OP_MUL_REAL] = "mul-real", + [OP_DIV_REAL] = "div-real", + + /* Type conversions */ + [OP_INT_TO_REAL] = "int-to-real", + [OP_NAT_TO_REAL] = "nat-to-real", + [OP_REAL_TO_INT] = "real-to-int", + [OP_REAL_TO_NAT] = "real-to-nat", + + /* Integer comparisons */ + [OP_JEQ_INT] = "jump-eq-int", + [OP_JNEQ_INT] = "jump-neq-int", + [OP_JGT_INT] = "jump-gt-int", + [OP_JLT_INT] = "jump-lt-int", + [OP_JLE_INT] = "jump-le-int", + [OP_JGE_INT] = "jump-ge-int", + + /* Natural number comparisons */ + [OP_JEQ_NAT] = "jump-eq-nat", + [OP_JNEQ_NAT] = "jump-neq-nat", + [OP_JGT_NAT] = "jump-gt-nat", + [OP_JLT_NAT] = "jump-lt-nat", + [OP_JLE_NAT] = "jump-le-nat", + [OP_JGE_NAT] = "jump-ge-nat", + + /* Floating point comparisons */ + [OP_JEQ_REAL] = "jump-eq-real", + [OP_JNEQ_REAL] = "jump-neq-real", + [OP_JGE_REAL] = "jump-ge-real", + [OP_JGT_REAL] = "jump-gt-real", + [OP_JLT_REAL] = "jump-lt-real", + [OP_JLE_REAL] = "jump-le-real", + + /* String operations */ + [OP_STRLEN] = "string-length", + [OP_STREQ] = "string-eq", + [OP_STRCAT] = "string-concat", + [OP_STR_GET_CHAR] = "string-get-char", + [OP_STR_FIND_CHAR] = "string-find-char", + [OP_STR_SLICE] = "string-slice", + + /* String conversions */ + [OP_INT_TO_STRING] = "int-to-string", + [OP_NAT_TO_STRING] = "nat-to-string", + [OP_REAL_TO_STRING] = "real-to-string", + [OP_STRING_TO_INT] = "string-to-int", + [OP_STRING_TO_NAT] = "string-to-nat", + [OP_STRING_TO_REAL] = "string-to-real" + }; -void emit_u32(VM *vm, u32 value) { - write_u32(vm, code, vm->cp, value); + if (op < 0 || op >= (int)(sizeof(names) / sizeof(names[0]))) { + return ""; + } + + const char *name = names[op]; + return name ? name : ""; +} + +void emit_op(VM *vm, u8 byte) { + printf("vm->code[%d] = %s\n", vm->cp, opcode_to_string(byte)); + vm->code[vm->cp] = byte; +} + +void emit_byte(VM *vm, u8 byte) { + printf("vm->code[%d] = %d\n", vm->cp, byte); + vm->code[vm->cp] = byte; +} + +void emit_u32(VM *vm, u32 value) { + printf("vm->code[%d..%d] = %d\n", vm->cp, vm->cp+3, value); + write_u32(vm, code, vm->cp, value); } void symbol_table_init(SymbolTable *table) { @@ -26,6 +167,15 @@ u32 symbol_table_add(SymbolTable *table, Symbol s) { table->symbols = realloc(table->symbols, table->capacity * sizeof(Symbol)); } + if (s.scope == VAR) { + // ignore for now + // printf("$%d = %s\n", s.ref, s.name); + } else if (s.scope == GLOBAL) { + printf("memory[%d] = %s\n", s.ref, s.name); + } else { + printf("code[%d] = %s\n", s.ref, s.name); + } + table->symbols[table->count] = s; u32 index = table->count; table->count++; @@ -66,13 +216,15 @@ u32 get_ptr(Token token, SymbolTable *st) { char *endptr; u32 out = (u32)strtoul(token.start, &endptr, 10); if (endptr == token.start || *endptr != '\0') { - fprintf(stderr, "Invalid decimal literal: '%.*s'\n", token.length, token.start); + fprintf(stderr, "Invalid decimal literal: '%.*s'\n", token.length, + token.start); exit(1); } return out; } - fprintf(stderr, "Error: Not a register or symbol '%.*s'\n", token.length, token.start); + fprintf(stderr, "Error: Not a register or symbol '%.*s'\n", token.length, + token.start); exit(1); } @@ -86,7 +238,8 @@ u32 get_reg(Token token, SymbolTable *st) { return atoi(token.start); } - fprintf(stderr, "Error: Not a register or symbol '%.*s'\n", token.length, token.start); + fprintf(stderr, "Error: Not a register or symbol '%.*s'\n", token.length, + token.start); exit(1); } @@ -185,6 +338,7 @@ bool define_global(VM *vm, SymbolTable *st) { memcpy(s.name, name.start, name.length); s.name_length = name.length; + s.name[name.length] = '\0'; u32 addr = vm->mp; s.ref = addr; @@ -491,6 +645,7 @@ void build_symbol_table(VM *vm, char *source, SymbolTable *st) { continue; } + get_reg(next, st); vm->cp++; next_token_is(TOKEN_SEMICOLON); continue; @@ -501,35 +656,41 @@ void build_symbol_table(VM *vm, char *source, SymbolTable *st) { if (strleq(token.start, "exit", token.length)) { vm->cp++; - next_id_or_ptr(); + next_token(); vm->cp += 4; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "call", token.length)) { - vm->cp++; + vm->cp++; - next_token_is(TOKEN_IDENTIFIER); + next_token_is(TOKEN_IDENTIFIER); + vm->cp += 4; - vm->cp += 4; + bool has_return = false; + vm->cp++; - Token next = next_token(); - while (next.type != TOKEN_SEMICOLON) { - if (next.type != TOKEN_ARROW_RIGHT) { - vm->cp++; + Token next = next_token(); + while (next.type != TOKEN_SEMICOLON) { + if (next.type != TOKEN_ARROW_RIGHT) { + get_reg(next, st); + vm->cp++; + } else { + has_return = true; + } + next = next_token(); } - next = next_token(); - } - - vm->cp++; /* number of args (implied) */ + if (!has_return) { + vm->cp+=2; + continue; + } } else if (strleq(token.start, "syscall", token.length)) { vm->cp++; - next_token_is(TOKEN_IDENTIFIER); - + Token next = next_token(); vm->cp += 4; - Token next = next_token(); + next = next_token(); while (next.type != TOKEN_SEMICOLON) { if (next.type != TOKEN_ARROW_RIGHT) { vm->cp++; @@ -538,1006 +699,433 @@ void build_symbol_table(VM *vm, char *source, SymbolTable *st) { } } else if (strleq(token.start, "load_immediate", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_token(); // literal vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_address", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "malloc", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "memset_8", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - next_id_or_reg(); vm->cp++; - next_id_or_reg(); vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "memset_16", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - next_id_or_reg(); vm->cp++; - next_id_or_reg(); vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "memset_32", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - next_id_or_reg(); vm->cp++; - next_id_or_reg(); vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "load_offset_8", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_ptr(); vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_offset_16", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_ptr(); vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_offset_32", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_ptr(); vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_indirect_8", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_indirect_16", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_indirect_32", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_absolute_8", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_absolute_16", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_absolute_32", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_absolute_8", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_ptr(); vm->cp += 4; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_absolute_16", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_ptr(); vm->cp += 4; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_absolute_32", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_ptr(); vm->cp += 4; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_indirect_8", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_ptr(); vm->cp += 4; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_indirect_16", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_ptr(); vm->cp += 4; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_indirect_32", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_ptr(); vm->cp += 4; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_offset_8", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); /* src1 */ vm->cp++; - - next_token_is(TOKEN_LITERAL_NAT); /* offset */ vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); /* dest */ vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_offset_16", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); /* src1 */ vm->cp++; - - next_token_is(TOKEN_LITERAL_NAT); /* offset */ vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); /* dest */ vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_offset_32", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); /* src1 */ vm->cp++; - - next_token_is(TOKEN_LITERAL_NAT); /* offset */ vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); /* dest */ vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "register_move", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "add_int", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "sub_int", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "mul_int", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "div_int", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "abs_int", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "neg_int", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "add_nat", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "sub_nat", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "mul_nat", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "div_nat", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "abs_nat", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "neg_nat", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "add_real", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "sub_real", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "mul_real", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "div_real", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "abs_real", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "neg_real", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "int_to_real", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "nat_to_real", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "real_to_int", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "real_to_nat", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "bit_shift_left", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "bit_shift_right", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "bit_shift_r_ext", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "bit_and", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "bit_or", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "bit_xor", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_token_is(TOKEN_SEMICOLON); + vm->cp+=4; } else if (strleq(token.start, "jump_if_flag", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_token_is(TOKEN_SEMICOLON); + vm->cp+=4; } else if (strleq(token.start, "jump_eq_int", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_neq_int", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_gt_int", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_lt_int", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_le_int", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_ge_int", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_eq_nat", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_neq_nat", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_gt_nat", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_lt_nat", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_le_nat", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_ge_nat", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_eq_real", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_neq_real", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_ge_real", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_gt_real", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_lt_real", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_le_real", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_ptr(); - vm->cp += 4; - - next_id_or_reg(); + vm->cp+=4; vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "string_length", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "int_to_string", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "nat_to_string", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "real_to_string", token.length)) { + while (token.type != TOKEN_SEMICOLON) token = next_token(); vm->cp++; - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - next_id_or_reg(); vm->cp++; - - next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "string_eq", token.length)) { } else if (strleq(token.start, "string_concat", token.length)) { } else if (strleq(token.start, "string_get_char", token.length)) { @@ -1571,9 +1159,9 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { break; } if (token.type != TOKEN_EOF) { - printf("[Generate Bytecode cp=%d mp=%d ] Line %d [%s]: %.*s\n", vm->cp, - vm->mp, token.line, token_type_to_string(token.type), token.length, - token.start); + //printf("[Generate Bytecode cp=%d mp=%d ] Line %d [%s]: %.*s\n", vm->cp, + // vm->mp, token.line, token_type_to_string(token.type), token.length, + // token.start); if (token.type == TOKEN_KEYWORD_GLOBAL) { // ignore, already processed @@ -1615,7 +1203,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { } if (token.type == TOKEN_KEYWORD_RETURN) { - emit_byte(vm, OP_RETURN); + emit_op(vm, OP_RETURN); vm->cp++; Token next = next_token(); @@ -1637,7 +1225,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { // check to see if it is an opcode first if (strleq(token.start, "exit", token.length)) { - emit_byte(vm, OP_EXIT); + emit_op(vm, OP_EXIT); vm->cp++; Token next = next_token(); @@ -1648,7 +1236,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "call", token.length)) { - emit_byte(vm, OP_CALL); + emit_op(vm, OP_CALL); vm->cp++; Token id = next_token_is(TOKEN_IDENTIFIER); @@ -1659,6 +1247,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { bool has_return = false; u8 arg_count = 0; u32 arg_pos = vm->cp++; + printf("vm->code[%d] = ?\n", arg_pos); Token next = next_token(); while (next.type != TOKEN_SEMICOLON) { @@ -1669,6 +1258,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { arg_count++; } else { has_return = true; + arg_count--; // is a return not an arg } next = next_token(); } @@ -1676,14 +1266,16 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { /* patch number of args */ vm->code[arg_pos] = arg_count; - if (!has_return) { - vm->cp++; + printf("^vm->code[%d] = %d\n", arg_pos, arg_count); + + if (!has_return) { + vm->cp+=2; emit_byte(vm, 255); continue; } } else if (strleq(token.start, "syscall", token.length)) { - emit_byte(vm, OP_SYSCALL); + emit_op(vm, OP_SYSCALL); vm->cp++; Token next = next_token(); @@ -1720,43 +1312,45 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { } else if (strleq(token.start, "load_immediate", token.length)) { - emit_byte(vm, OP_LOAD_IMM); + emit_op(vm, OP_LOAD_IMM); vm->cp++; Token value = next_token(); switch (value.type) { - case TOKEN_KEYWORD_TRUE: { - emit_u32(vm, 1); - break; - } - case TOKEN_KEYWORD_FALSE: { - emit_u32(vm, 0); - break; - } - case TOKEN_LITERAL_INT: { - i32 out = atoi(value.start); - emit_u32(vm, out); - break; - } - case TOKEN_LITERAL_NAT: { - char *endptr; - u32 out = (u32)strtoul(value.start, &endptr, 10); - if (endptr == value.start || *endptr != '\0') { - fprintf(stderr, "Invalid 'real' number: '%.*s'\n", token.length, token.start); - exit(1); - } - emit_u32(vm, out); - break; - } - case TOKEN_LITERAL_REAL: { - fixed_t out = float_to_fixed(atof(value.start)); - emit_u32(vm, out); - break; - } - default:{ - fprintf(stderr, "Unknown immediate: '%.*s'\n", token.length, token.start); + case TOKEN_KEYWORD_TRUE: { + emit_u32(vm, 1); + break; + } + case TOKEN_KEYWORD_FALSE: { + emit_u32(vm, 0); + break; + } + case TOKEN_LITERAL_INT: { + i32 out = atoi(value.start); + emit_u32(vm, out); + break; + } + case TOKEN_LITERAL_NAT: { + char *endptr; + u32 out = (u32)strtoul(value.start, &endptr, 10); + if (endptr == value.start || *endptr != '\0') { + fprintf(stderr, "Invalid 'real' number: '%.*s'\n", token.length, + token.start); exit(1); } + emit_u32(vm, out); + break; + } + case TOKEN_LITERAL_REAL: { + fixed_t out = float_to_fixed(atof(value.start)); + emit_u32(vm, out); + break; + } + default: { + fprintf(stderr, "Unknown immediate: '%.*s'\n", token.length, + token.start); + exit(1); + } } vm->cp += 4; @@ -1770,7 +1364,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_address", token.length)) { - emit_byte(vm, OP_LOAD_IMM); + emit_op(vm, OP_LOAD_IMM); vm->cp++; Token id = next_token(); @@ -1787,7 +1381,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "malloc", token.length)) { - emit_byte(vm, OP_MALLOC); + emit_op(vm, OP_MALLOC); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -1800,7 +1394,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "memset_8", token.length)) { - emit_byte(vm, OP_MEMSET_8); + emit_op(vm, OP_MEMSET_8); vm->cp++; Token reg = next_token(); @@ -1820,7 +1414,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "memset_16", token.length)) { - emit_byte(vm, OP_MEMSET_16); + emit_op(vm, OP_MEMSET_16); vm->cp++; Token reg = next_token(); @@ -1840,7 +1434,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "memset_32", token.length)) { - emit_byte(vm, OP_MEMSET_32); + emit_op(vm, OP_MEMSET_32); vm->cp++; Token reg = next_token(); @@ -1860,7 +1454,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_offset_8", token.length)) { - emit_byte(vm, OP_LOAD_OFF_8); + emit_op(vm, OP_LOAD_OFF_8); vm->cp++; Token reg = next_token(); @@ -1882,7 +1476,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_offset_16", token.length)) { - emit_byte(vm, OP_LOAD_OFF_16); + emit_op(vm, OP_LOAD_OFF_16); vm->cp++; Token reg = next_token(); @@ -1904,7 +1498,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_offset_32", token.length)) { - emit_byte(vm, OP_LOAD_OFF_32); + emit_op(vm, OP_LOAD_OFF_32); vm->cp++; Token reg = next_token(); @@ -1926,7 +1520,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_indirect_8", token.length)) { - emit_byte(vm, OP_LOAD_IND_8); + emit_op(vm, OP_LOAD_IND_8); vm->cp++; Token id = next_token(); @@ -1943,7 +1537,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_indirect_16", token.length)) { - emit_byte(vm, OP_LOAD_IND_16); + emit_op(vm, OP_LOAD_IND_16); vm->cp++; Token id = next_token(); @@ -1960,7 +1554,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_indirect_32", token.length)) { - emit_byte(vm, OP_LOAD_IND_32); + emit_op(vm, OP_LOAD_IND_32); vm->cp++; Token id = next_token(); @@ -1977,7 +1571,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_absolute_8", token.length)) { - emit_byte(vm, OP_LOAD_ABS_8); + emit_op(vm, OP_LOAD_ABS_8); vm->cp++; Token id = next_token(); @@ -1994,7 +1588,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_absolute_16", token.length)) { - emit_byte(vm, OP_LOAD_ABS_16); + emit_op(vm, OP_LOAD_ABS_16); vm->cp++; Token id = next_token(); @@ -2011,7 +1605,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "load_absolute_32", token.length)) { - emit_byte(vm, OP_LOAD_ABS_32); + emit_op(vm, OP_LOAD_ABS_32); vm->cp++; Token id = next_token(); @@ -2028,7 +1622,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_absolute_8", token.length)) { - emit_byte(vm, OP_STORE_ABS_8); + emit_op(vm, OP_STORE_ABS_8); vm->cp++; Token reg = next_token(); @@ -2045,7 +1639,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_absolute_16", token.length)) { - emit_byte(vm, OP_STORE_ABS_16); + emit_op(vm, OP_STORE_ABS_16); vm->cp++; Token reg = next_token(); @@ -2062,7 +1656,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_absolute_32", token.length)) { - emit_byte(vm, OP_STORE_ABS_32); + emit_op(vm, OP_STORE_ABS_32); vm->cp++; Token reg = next_token(); @@ -2079,7 +1673,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_indirect_8", token.length)) { - emit_byte(vm, OP_STORE_IND_8); + emit_op(vm, OP_STORE_IND_8); vm->cp++; Token reg = next_token(); @@ -2096,7 +1690,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_indirect_16", token.length)) { - emit_byte(vm, OP_STORE_IND_16); + emit_op(vm, OP_STORE_IND_16); vm->cp++; Token reg = next_token(); @@ -2113,7 +1707,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_indirect_32", token.length)) { - emit_byte(vm, OP_STORE_IND_32); + emit_op(vm, OP_STORE_IND_32); vm->cp++; Token reg = next_token(); @@ -2130,7 +1724,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_offset_8", token.length)) { - emit_byte(vm, OP_STORE_OFF_8); + emit_op(vm, OP_STORE_OFF_8); vm->cp++; Token reg = next_token(); @@ -2152,7 +1746,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_offset_16", token.length)) { - emit_byte(vm, OP_STORE_OFF_16); + emit_op(vm, OP_STORE_OFF_16); vm->cp++; Token reg = next_token(); @@ -2174,7 +1768,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "store_offset_32", token.length)) { - emit_byte(vm, OP_STORE_OFF_32); + emit_op(vm, OP_STORE_OFF_32); vm->cp++; Token reg = next_token(); @@ -2196,7 +1790,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "register_move", token.length)) { - emit_byte(vm, OP_REG_MOV); + emit_op(vm, OP_REG_MOV); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2209,7 +1803,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "add_int", token.length)) { - emit_byte(vm, OP_ADD_INT); + emit_op(vm, OP_ADD_INT); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2226,7 +1820,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "sub_int", token.length)) { - emit_byte(vm, OP_SUB_INT); + emit_op(vm, OP_SUB_INT); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2243,7 +1837,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "mul_int", token.length)) { - emit_byte(vm, OP_MUL_INT); + emit_op(vm, OP_MUL_INT); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2260,7 +1854,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "div_int", token.length)) { - emit_byte(vm, OP_DIV_INT); + emit_op(vm, OP_DIV_INT); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2277,7 +1871,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "abs_int", token.length)) { - emit_byte(vm, OP_ABS_INT); + emit_op(vm, OP_ABS_INT); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2290,7 +1884,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "neg_int", token.length)) { - emit_byte(vm, OP_NEG_INT); + emit_op(vm, OP_NEG_INT); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2303,7 +1897,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "add_nat", token.length)) { - emit_byte(vm, OP_ADD_NAT); + emit_op(vm, OP_ADD_NAT); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2320,7 +1914,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "sub_nat", token.length)) { - emit_byte(vm, OP_SUB_NAT); + emit_op(vm, OP_SUB_NAT); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2337,7 +1931,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "mul_nat", token.length)) { - emit_byte(vm, OP_MUL_NAT); + emit_op(vm, OP_MUL_NAT); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2354,7 +1948,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "div_nat", token.length)) { - emit_byte(vm, OP_DIV_NAT); + emit_op(vm, OP_DIV_NAT); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2371,7 +1965,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "abs_nat", token.length)) { - emit_byte(vm, OP_ABS_NAT); + emit_op(vm, OP_ABS_NAT); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2384,7 +1978,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "neg_nat", token.length)) { - emit_byte(vm, OP_NEG_NAT); + emit_op(vm, OP_NEG_NAT); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2397,7 +1991,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "add_real", token.length)) { - emit_byte(vm, OP_ADD_REAL); + emit_op(vm, OP_ADD_REAL); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2412,9 +2006,10 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { arg = get_reg(next, st); emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON);; + next_token_is(TOKEN_SEMICOLON); + ; } else if (strleq(token.start, "sub_real", token.length)) { - emit_byte(vm, OP_SUB_REAL); + emit_op(vm, OP_SUB_REAL); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2431,7 +2026,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "mul_real", token.length)) { - emit_byte(vm, OP_MUL_REAL); + emit_op(vm, OP_MUL_REAL); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2448,7 +2043,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "div_real", token.length)) { - emit_byte(vm, OP_DIV_REAL); + emit_op(vm, OP_DIV_REAL); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2465,7 +2060,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "abs_real", token.length)) { - emit_byte(vm, OP_ABS_REAL); + emit_op(vm, OP_ABS_REAL); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2478,7 +2073,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "neg_real", token.length)) { - emit_byte(vm, OP_NEG_REAL); + emit_op(vm, OP_NEG_REAL); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2491,7 +2086,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "int_to_real", token.length)) { - emit_byte(vm, OP_INT_TO_REAL); + emit_op(vm, OP_INT_TO_REAL); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2504,7 +2099,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "nat_to_real", token.length)) { - emit_byte(vm, OP_NAT_TO_REAL); + emit_op(vm, OP_NAT_TO_REAL); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2517,7 +2112,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "real_to_int", token.length)) { - emit_byte(vm, OP_REAL_TO_INT); + emit_op(vm, OP_REAL_TO_INT); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2530,7 +2125,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "real_to_nat", token.length)) { - emit_byte(vm, OP_REAL_TO_NAT); + emit_op(vm, OP_REAL_TO_NAT); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2543,7 +2138,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "bit_shift_left", token.length)) { - emit_byte(vm, OP_BIT_SHIFT_LEFT); + emit_op(vm, OP_BIT_SHIFT_LEFT); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2560,7 +2155,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "bit_shift_right", token.length)) { - emit_byte(vm, OP_BIT_SHIFT_RIGHT); + emit_op(vm, OP_BIT_SHIFT_RIGHT); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2577,7 +2172,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "bit_shift_r_ext", token.length)) { - emit_byte(vm, OP_BIT_SHIFT_R_EXT); + emit_op(vm, OP_BIT_SHIFT_R_EXT); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2594,7 +2189,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "bit_and", token.length)) { - emit_byte(vm, OP_BAND); + emit_op(vm, OP_BAND); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2611,7 +2206,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "bit_or", token.length)) { - emit_byte(vm, OP_BOR); + emit_op(vm, OP_BOR); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2628,7 +2223,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "bit_xor", token.length)) { - emit_byte(vm, OP_BXOR); + emit_op(vm, OP_BXOR); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2645,7 +2240,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump", token.length)) { - emit_byte(vm, OP_JMP); + emit_op(vm, OP_JMP); vm->cp++; Token id = next_token(); @@ -2655,7 +2250,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_if_flag", token.length)) { - emit_byte(vm, OP_JMPF); + emit_op(vm, OP_JMPF); vm->cp++; Token id = next_token(); @@ -2665,7 +2260,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_eq_int", token.length)) { - emit_byte(vm, OP_JEQ_INT); + emit_op(vm, OP_JEQ_INT); vm->cp++; Token id = next_token(); u32 ptr = get_ptr(id, st); @@ -2681,7 +2276,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_neq_int", token.length)) { - emit_byte(vm, OP_JNEQ_INT); + emit_op(vm, OP_JNEQ_INT); vm->cp++; Token id = next_token(); u32 ptr = get_ptr(id, st); @@ -2697,7 +2292,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_gt_int", token.length)) { - emit_byte(vm, OP_JGT_INT); + emit_op(vm, OP_JGT_INT); vm->cp++; Token id = next_token(); u32 ptr = get_ptr(id, st); @@ -2713,7 +2308,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_lt_int", token.length)) { - emit_byte(vm, OP_JLT_INT); + emit_op(vm, OP_JLT_INT); vm->cp++; Token id = next_token(); u32 ptr = get_ptr(id, st); @@ -2729,7 +2324,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_le_int", token.length)) { - emit_byte(vm, OP_JLE_INT); + emit_op(vm, OP_JLE_INT); vm->cp++; Token id = next_token(); u32 ptr = get_ptr(id, st); @@ -2745,7 +2340,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_ge_int", token.length)) { - emit_byte(vm, OP_JGE_INT); + emit_op(vm, OP_JGE_INT); vm->cp++; Token id = next_token(); u32 ptr = get_ptr(id, st); @@ -2761,7 +2356,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_eq_nat", token.length)) { - emit_byte(vm, OP_JEQ_NAT); + emit_op(vm, OP_JEQ_NAT); vm->cp++; Token id = next_token(); u32 ptr = get_ptr(id, st); @@ -2777,7 +2372,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_neq_nat", token.length)) { - emit_byte(vm, OP_JNEQ_NAT); + emit_op(vm, OP_JNEQ_NAT); vm->cp++; Token id = next_token(); u32 ptr = get_ptr(id, st); @@ -2793,7 +2388,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_gt_nat", token.length)) { - emit_byte(vm, OP_JGT_NAT); + emit_op(vm, OP_JGT_NAT); vm->cp++; Token id = next_token(); u32 ptr = get_ptr(id, st); @@ -2809,7 +2404,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_lt_nat", token.length)) { - emit_byte(vm, OP_JLT_NAT); + emit_op(vm, OP_JLT_NAT); vm->cp++; Token id = next_token(); u32 ptr = get_ptr(id, st); @@ -2825,7 +2420,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_le_nat", token.length)) { - emit_byte(vm, OP_JLE_NAT); + emit_op(vm, OP_JLE_NAT); vm->cp++; Token id = next_token(); u32 ptr = get_ptr(id, st); @@ -2841,7 +2436,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_ge_nat", token.length)) { - emit_byte(vm, OP_JGE_NAT); + emit_op(vm, OP_JGE_NAT); vm->cp++; Token id = next_token(); u32 ptr = get_ptr(id, st); @@ -2857,7 +2452,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_eq_real", token.length)) { - emit_byte(vm, OP_JEQ_REAL); + emit_op(vm, OP_JEQ_REAL); vm->cp++; Token id = next_token(); u32 ptr = get_ptr(id, st); @@ -2873,7 +2468,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_neq_real", token.length)) { - emit_byte(vm, OP_JNEQ_REAL); + emit_op(vm, OP_JNEQ_REAL); vm->cp++; Token id = next_token(); u32 ptr = get_ptr(id, st); @@ -2889,7 +2484,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_ge_real", token.length)) { - emit_byte(vm, OP_JGE_REAL); + emit_op(vm, OP_JGE_REAL); vm->cp++; Token id = next_token(); u32 ptr = get_ptr(id, st); @@ -2905,7 +2500,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_gt_real", token.length)) { - emit_byte(vm, OP_JGT_REAL); + emit_op(vm, OP_JGT_REAL); vm->cp++; Token id = next_token(); u32 ptr = get_ptr(id, st); @@ -2921,7 +2516,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_lt_real", token.length)) { - emit_byte(vm, OP_JLT_REAL); + emit_op(vm, OP_JLT_REAL); vm->cp++; Token id = next_token(); u32 ptr = get_ptr(id, st); @@ -2937,7 +2532,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "jump_le_real", token.length)) { - emit_byte(vm, OP_JLE_REAL); + emit_op(vm, OP_JLE_REAL); vm->cp++; Token id = next_token(); u32 ptr = get_ptr(id, st); @@ -2953,7 +2548,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "string_length", token.length)) { - emit_byte(vm, OP_STRLEN); + emit_op(vm, OP_STRLEN); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2966,7 +2561,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "int_to_string", token.length)) { - emit_byte(vm, OP_INT_TO_STRING); + emit_op(vm, OP_INT_TO_STRING); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2979,7 +2574,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "nat_to_string", token.length)) { - emit_byte(vm, OP_NAT_TO_STRING); + emit_op(vm, OP_NAT_TO_STRING); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -2992,7 +2587,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { vm->cp++; next_token_is(TOKEN_SEMICOLON); } else if (strleq(token.start, "real_to_string", token.length)) { - emit_byte(vm, OP_REAL_TO_STRING); + emit_op(vm, OP_REAL_TO_STRING); vm->cp++; Token reg = next_token(); u8 arg = get_reg(reg, st); @@ -3003,7 +2598,8 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { arg = get_reg(reg, st); emit_byte(vm, arg); vm->cp++; - next_token_is(TOKEN_SEMICOLON);; + next_token_is(TOKEN_SEMICOLON); + ; } else if (strleq(token.start, "string_eq", token.length)) { } else if (strleq(token.start, "string_concat", token.length)) { } else if (strleq(token.start, "string_get_char", token.length)) {