From 6be5a4d3f9fe333f0cd449c7ace5b64bd6e560cd Mon Sep 17 00:00:00 2001 From: zongor Date: Sat, 30 Aug 2025 07:56:08 -0700 Subject: [PATCH] fix tests --- src/compiler.c | 18 ++++++------ src/opcodes.h | 3 ++ src/test.c | 78 +++++++++++++++++++++++++------------------------- src/vm.c | 42 +++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 48 deletions(-) diff --git a/src/compiler.c b/src/compiler.c index 16cbaf2..fc45293 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -101,17 +101,17 @@ void number(VM *vm) { if (parser.previous.type == TOKEN_INT_LITERAL) { char *endptr; int32_t value = (int32_t)strtol(parser.previous.start, &endptr, 10); - emitOp(vm, OP_LOADI, vm->frames[vm->fp].rp++, 0, 0); + emitOp(vm, OP_LOAD, vm->frames[vm->fp].rp++, 0, 0); vm->code[vm->cp++].u = int_alloc(vm, value); return; } else if (parser.previous.type == TOKEN_UINT_LITERAL) { long value = atol(parser.previous.start); - emitOp(vm, OP_LOADU, vm->frames[vm->fp].rp++, 0, 0); + emitOp(vm, OP_LOAD, vm->frames[vm->fp].rp++, 0, 0); vm->code[vm->cp++].u = nat_alloc(vm, value); return; } else if (parser.previous.type == TOKEN_FLOAT_LITERAL) { float value = atof(parser.previous.start); - emitOp(vm, OP_LOADF, vm->frames[vm->fp].rp++, 0, 0); + emitOp(vm, OP_LOAD, vm->frames[vm->fp].rp++, 0, 0); vm->code[vm->cp++].u = real_alloc(vm, value); return; } @@ -131,7 +131,7 @@ void string(VM *vm) { } } vm->frames[vm->fp].allocated.end += length / 4; - emitOp(vm, OP_LOADP, vm->frames[vm->fp].rp++, 0, 0); + emitOp(vm, OP_LOAD, vm->frames[vm->fp].rp++, 0, 0); vm->code[vm->cp++].u = str_addr; } @@ -154,17 +154,17 @@ void unary(VM *vm) { static void literal(VM *vm) { switch (parser.previous.type) { case TOKEN_KEYWORD_NIL: { - emitOp(vm, OP_LOADU, vm->frames[vm->fp].rp++, 0, 0); + emitOp(vm, OP_LOAD, vm->frames[vm->fp].rp++, 0, 0); vm->code[vm->cp++].u = 0; break; } case TOKEN_KEYWORD_FALSE: { - emitOp(vm, OP_LOADU, vm->frames[vm->fp].rp++, 0, 0); + emitOp(vm, OP_LOAD, vm->frames[vm->fp].rp++, 0, 0); vm->code[vm->cp++].u = 0; break; } case TOKEN_KEYWORD_TRUE: { - emitOp(vm, OP_LOADU, vm->frames[vm->fp].rp++, 0, 0); + emitOp(vm, OP_LOAD, vm->frames[vm->fp].rp++, 0, 0); vm->code[vm->cp++].u = 1; break; } @@ -303,7 +303,7 @@ void printStatement(VM *vm) { expression(vm); consume(TOKEN_SEMICOLON, "Expect ';' after value."); Frame f = vm->frames[vm->fp]; - vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, f.rp--, 0); + vm->code[vm->cp++].u = OP(OP_DBG_PRINT_STRING, 0, f.rp--, 0); } static void expressionStatement(VM *vm) { @@ -334,7 +334,7 @@ static void intDeclaration(VM *vm) { expression(vm); } else { /* initialize as zero/null */ - emitOp(vm, OP_LOADI, vm->frames[vm->fp].rp++, 0, 0); + emitOp(vm, OP_LOAD, vm->frames[vm->fp].rp++, 0, 0); vm->code[vm->cp++].i = 0; } diff --git a/src/opcodes.h b/src/opcodes.h index a2a5a02..e7e45e0 100644 --- a/src/opcodes.h +++ b/src/opcodes.h @@ -58,6 +58,9 @@ typedef enum { OP_STRING_TO_INT, /* stoi : dest = src1 as int */ OP_STRING_TO_UINT, /* stou : dest = src1 as uint */ OP_STRING_TO_REAL, /* stor : dest = src1 as real */ + /* to remove, just for testing for now */ + OP_DBG_PRINT_STRING, + OP_DBG_READ_STRING, } Opcode; /* defines a uint32 opcode */ diff --git a/src/test.c b/src/test.c index daf1068..50fb8d6 100644 --- a/src/test.c +++ b/src/test.c @@ -23,108 +23,108 @@ bool compile_internal_test(const char* filename, VM* vm) { } bool test_add_compile(VM *vm) { - vm->code[vm->cp++].u = OP(OP_LOADU, 0, 0, 0); + vm->code[vm->cp++].u = OP(OP_LOAD, 0, 0, 0); vm->code[vm->cp++].u = nat_alloc(vm, 1); - vm->code[vm->cp++].u = OP(OP_LOADU, 1, 1, 0); + vm->code[vm->cp++].u = OP(OP_LOAD, 1, 1, 0); vm->code[vm->cp++].u = nat_alloc(vm, 2); vm->code[vm->cp++].u = OP(OP_ADD_UINT, 2, 1, 0); /* let sum = 1 + 2; */ vm->code[vm->cp++].u = OP(OP_UINT_TO_STRING, 3, 2, 0); - vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 3, 0); /* print(sum.toS()); */ + vm->code[vm->cp++].u = OP(OP_DBG_PRINT_STRING, 0, 3, 0); /* print(sum.toS()); */ vm->code[vm->cp++].u = OP(OP_HALT, 0, 0, 0); /* explicit halt */ return true; } bool test_loop_compile(VM *vm) { - vm->code[vm->cp++].u = OP(OP_LOADF, 0, 0, 0); /* let a = 5.0 */ + vm->code[vm->cp++].u = OP(OP_LOAD, 0, 0, 0); /* let a = 5.0 */ vm->code[vm->cp++].u = real_alloc(vm, 5.0f); - vm->code[vm->cp++].u = OP(OP_LOADI, 1, 0, 0); /* do (i = 50000, 0, -1) { */ + vm->code[vm->cp++].u = OP(OP_LOAD, 1, 0, 0); /* do (i = 50000, 0, -1) { */ vm->code[vm->cp++].u = int_alloc(vm, 50000); - vm->code[vm->cp++].u = OP(OP_LOADI, 2, 0, 0); /* loop check value */ + vm->code[vm->cp++].u = OP(OP_LOAD, 2, 0, 0); /* loop check value */ vm->code[vm->cp++].u = int_alloc(vm, 0); - vm->code[vm->cp++].u = OP(OP_LOADI, 3, 0, 0); /* loop incriment value */ + vm->code[vm->cp++].u = OP(OP_LOAD, 3, 0, 0); /* loop incriment value */ vm->code[vm->cp++].u = int_alloc(vm, -1); - vm->code[vm->cp++].u = OP(OP_LOADU, 4, 0, 0); /* loop start */ + vm->code[vm->cp++].u = OP(OP_LOAD, 4, 0, 0); /* loop start */ uint32_t addr = vm->cp + 1; vm->code[vm->cp++].u = int_alloc(vm, addr); - vm->code[vm->cp++].u = OP(OP_LOADF, 5, 0, 0); + vm->code[vm->cp++].u = OP(OP_LOAD, 5, 0, 0); vm->code[vm->cp++].u = real_alloc(vm, 5.0f); vm->code[vm->cp++].u = OP(OP_ADD_REAL, 0, 0, 5); /* a += 5.0; */ vm->code[vm->cp++].u = OP(OP_ADD_INT, 1, 1, 3); /* (implied by loop) i = i + (-1) */ vm->code[vm->cp++].u = OP(OP_JGE_INT, 4, 1, 2); /* } */ vm->code[vm->cp++].u = OP(OP_REAL_TO_UINT, 1, 0, 0); /* let b = a as nat; */ - vm->code[vm->cp++].u = OP(OP_LOADP, 6, 0, 0); + vm->code[vm->cp++].u = OP(OP_LOAD, 6, 0, 0); vm->code[vm->cp++].u = str_alloc(vm, "Enter a string:", 0); - vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 6, 0); /* print("Enter a string: "); */ - vm->code[vm->cp++].u = OP(OP_READ_STRING, 2, 0, 0); /* let user_string = gets(); */ + vm->code[vm->cp++].u = OP(OP_DBG_PRINT_STRING, 0, 6, 0); /* print("Enter a string: "); */ + vm->code[vm->cp++].u = OP(OP_DBG_READ_STRING, 2, 0, 0); /* let user_string = gets(); */ vm->code[vm->cp++].u = OP(OP_UINT_TO_STRING, 3, 1, 0); - vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 3, 0); /* print(a.toS()); */ + vm->code[vm->cp++].u = OP(OP_DBG_PRINT_STRING, 0, 3, 0); /* print(a.toS()); */ vm->code[vm->cp++].u = OP(OP_REAL_TO_STRING, 3, 0, 0); - vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 3, 0); /* print(b.toS()); */ - vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 2, 0); /* print(user_string); */ + vm->code[vm->cp++].u = OP(OP_DBG_PRINT_STRING, 0, 3, 0); /* print(b.toS()); */ + vm->code[vm->cp++].u = OP(OP_DBG_PRINT_STRING, 0, 2, 0); /* print(user_string); */ vm->code[vm->cp++].u = OP(OP_HALT, 0, 0, 0); /* program done */ return true; } bool test_add_function_compile(VM *vm) { /* fn main() */ - vm->code[vm->cp++].u = OP(OP_LOADI, 0, 0, 0); /* 1 */ + vm->code[vm->cp++].u = OP(OP_LOAD, 0, 0, 0); /* 1 */ uint32_t addr = int_alloc(vm, 1); vm->code[vm->cp++].u = addr; - vm->code[vm->cp++].u = OP(OP_PUSHI, 0, 0, 0); - vm->code[vm->cp++].u = OP(OP_LOADI, 0, 0, 0); /* 1 */ + vm->code[vm->cp++].u = OP(OP_PUSH, 0, 0, 0); + vm->code[vm->cp++].u = OP(OP_LOAD, 0, 0, 0); /* 1 */ vm->code[vm->cp++].u = addr; - vm->code[vm->cp++].u = OP(OP_PUSHI, 0, 0, 0); + vm->code[vm->cp++].u = OP(OP_PUSH, 0, 0, 0); vm->code[vm->cp++].u = OP(OP_CALL, 0, 0, 0); /* ); */ vm->code[vm->cp++].u = 12; - vm->code[vm->cp++].u = OP(OP_POPI, 0, 0, 0); /* get return value */ + vm->code[vm->cp++].u = OP(OP_POP, 0, 0, 0); /* get return value */ vm->code[vm->cp++].u = OP(OP_INT_TO_STRING, 1, 0, 0); - vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 1, 0); /* print(sum.toS()); */ + vm->code[vm->cp++].u = OP(OP_DBG_PRINT_STRING, 0, 1, 0); /* print(sum.toS()); */ vm->code[vm->cp++].u = OP(OP_HALT, 0, 0, 0); /* fn add() */ - vm->code[vm->cp++].u = OP(OP_POPI, 0, 0, 0); /* a int */ - vm->code[vm->cp++].u = OP(OP_POPI, 1, 0, 0); /* b int */ + vm->code[vm->cp++].u = OP(OP_POP, 0, 0, 0); /* a int */ + vm->code[vm->cp++].u = OP(OP_POP, 1, 0, 0); /* b int */ vm->code[vm->cp++].u = OP(OP_ADD_INT, 2, 1, 0); /* a + b */ - vm->code[vm->cp++].u = OP(OP_PUSHI, 2, 0, 0); /* push on stack */ + vm->code[vm->cp++].u = OP(OP_PUSH, 2, 0, 0); /* push on stack */ vm->code[vm->cp++].u = OP(OP_RETURN, 0, 0, 0); return true; } bool test_recursive_function_compile(VM *vm) { /* fn main() */ - vm->code[vm->cp++].u = OP(OP_LOADI, 0, 0, 0); /* 35 */ + vm->code[vm->cp++].u = OP(OP_LOAD, 0, 0, 0); /* 35 */ vm->code[vm->cp++].u = int_alloc(vm, 35); - vm->code[vm->cp++].u = OP(OP_PUSHI, 0, 0, 0); + vm->code[vm->cp++].u = OP(OP_PUSH, 0, 0, 0); vm->code[vm->cp++].u = OP(OP_CALL, 0, 0, 0); /* ); */ vm->code[vm->cp++].u = 9; - vm->code[vm->cp++].u = OP(OP_POPI, 0, 0, 0); /* get return value */ + vm->code[vm->cp++].u = OP(OP_POP, 0, 0, 0); /* get return value */ vm->code[vm->cp++].u = OP(OP_INT_TO_STRING, 1, 0, 0); - vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 1, 0); /* print(fib(35).toS()); */ + vm->code[vm->cp++].u = OP(OP_DBG_PRINT_STRING, 0, 1, 0); /* print(fib(35).toS()); */ vm->code[vm->cp++].u = OP(OP_HALT, 0, 0, 0); /* fn fib() */ - vm->code[vm->cp++].u = OP(OP_POPI, 0, 0, 0); /* n int */ - vm->code[vm->cp++].u = OP(OP_LOADI, 1, 0, 0); /* 2 */ + vm->code[vm->cp++].u = OP(OP_POP, 0, 0, 0); /* n int */ + vm->code[vm->cp++].u = OP(OP_LOAD, 1, 0, 0); /* 2 */ vm->code[vm->cp++].u = int_alloc(vm, 2); - vm->code[vm->cp++].u = OP(OP_LOADI, 2, 0, 0); /* &fib */ + vm->code[vm->cp++].u = OP(OP_LOAD, 2, 0, 0); /* &fib */ vm->code[vm->cp++].u = int_alloc(vm, 32); vm->code[vm->cp++].u = OP(OP_JLT_INT, 2, 0, 1); - vm->code[vm->cp++].u = OP(OP_LOADI, 3, 0, 0); /* 2 */ + vm->code[vm->cp++].u = OP(OP_LOAD, 3, 0, 0); /* 2 */ vm->code[vm->cp++].u = int_alloc(vm, 2); vm->code[vm->cp++].u = OP(OP_SUB_INT, 4, 0, 3); - vm->code[vm->cp++].u = OP(OP_PUSHI, 4, 0, 0); + vm->code[vm->cp++].u = OP(OP_PUSH, 4, 0, 0); vm->code[vm->cp++].u = OP(OP_CALL, 0, 0, 0); /* fib(n - 2) */ vm->code[vm->cp++].u = 9; - vm->code[vm->cp++].u = OP(OP_LOADI, 3, 0, 0); /* 1 */ + vm->code[vm->cp++].u = OP(OP_LOAD, 3, 0, 0); /* 1 */ vm->code[vm->cp++].u = int_alloc(vm, 1); vm->code[vm->cp++].u = OP(OP_SUB_INT, 4, 0, 3); - vm->code[vm->cp++].u = OP(OP_PUSHI, 4, 0, 0); + vm->code[vm->cp++].u = OP(OP_PUSH, 4, 0, 0); vm->code[vm->cp++].u = OP(OP_CALL, 0, 0, 0); /* fib(n - 1) */ vm->code[vm->cp++].u = 9; - vm->code[vm->cp++].u = OP(OP_POPI, 4, 0, 0); - vm->code[vm->cp++].u = OP(OP_POPI, 5, 0, 0); + vm->code[vm->cp++].u = OP(OP_POP, 4, 0, 0); + vm->code[vm->cp++].u = OP(OP_POP, 5, 0, 0); vm->code[vm->cp++].u = OP(OP_ADD_INT, 6, 5, 4); - vm->code[vm->cp++].u = OP(OP_PUSHI, 6, 0, 0); + vm->code[vm->cp++].u = OP(OP_PUSH, 6, 0, 0); vm->code[vm->cp++].u = OP(OP_RETURN, 0, 0, 0); - vm->code[vm->cp++].u = OP(OP_PUSHI, 0, 0, 0); + vm->code[vm->cp++].u = OP(OP_PUSH, 0, 0, 0); vm->code[vm->cp++].u = OP(OP_RETURN, 0, 0, 0); return true; } diff --git a/src/vm.c b/src/vm.c index 0e7cd71..1df2387 100644 --- a/src/vm.c +++ b/src/vm.c @@ -246,6 +246,48 @@ bool step_vm(VM *vm) { vm->frames[vm->fp].registers[dest].u = ptr; return true; } + case OP_DBG_READ_STRING: { + uint32_t str_addr = vm->mp++; + uint32_t length = 0; + int ch; + + while ((ch = getchar()) != '\n' && ch != EOF) { + uint32_t idx = length % 4; + vm->memory[vm->mp].c[idx] = (char)ch; + length++; + + if (idx == 3) + vm->mp++; + } + + uint32_t i, rem = length % 4; + if (rem != 0) { + for (i = rem; i < 4; i++) { + vm->memory[vm->mp].c[i] = '\0'; + } + vm->mp++; + } + + vm->memory[str_addr].u = length; + vm->frames[vm->fp].allocated.end = vm->mp; + vm->frames[vm->fp].registers[dest].u = str_addr; + + return true; + } + case OP_DBG_PRINT_STRING: { + uint32_t ptr = (uint32_t)vm->frames[vm->fp].registers[src1].u; + uint32_t length = vm->memory[ptr].u; + uint32_t str_src = ptr + 1; + uint32_t i; + for (i = 0; i < length; i++) { + uint8_t ch = vm->memory[str_src + (i / 4)].c[i % 4]; + if (ch == '\0') + break; + putchar(ch); + } + putchar('\n'); + return true; + } case OP_CMP_STRING: { uint32_t addr1 = (uint32_t)vm->frames[vm->fp].registers[src1].u; uint32_t addr2 = (uint32_t)vm->frames[vm->fp].registers[src2].u;