diff --git a/src/arch/linux/main.c b/src/arch/linux/main.c index def5a7d..46926db 100644 --- a/src/arch/linux/main.c +++ b/src/arch/linux/main.c @@ -1,5 +1,6 @@ #include "../../compiler.h" #include "../../vm.h" +#include "../../test.h" #define MAX_SRC_SIZE 16384 @@ -55,12 +56,14 @@ int main(int argc, char **argv) { vm.memory_size = MEMORY_SIZE; if (argc == 1) { - repl(&vm); + test_loop_compile(&vm); + /* repl(&vm); */ } else if (argc == 2) { compileFile(argv[1], &vm); } else { fprintf(stderr, "Usage: %s \n", argv[0]); return 64; + repl(&vm); } bool running = true; diff --git a/src/compiler.c b/src/compiler.c index 7393255..18a8753 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -31,6 +31,7 @@ typedef struct { } ParseRule; Parser parser; +SymbolTable st; void errorAt(Token *token, const char *message) { if (parser.panicMode) @@ -309,11 +310,29 @@ static void expressionStatement(VM *vm) { static void intDeclaration(VM *vm) { /* insert variable name in symbol table */ + uint32_t length = parser.previous.length - 2; + if (length > SYMBOL_NAME_SIZE) { + error("Variable names cannot be longer than 24 characters."); + return; + } + st.symbols[st.sc].type = INT; + st.symbols[st.sc].frame = vm->fp; + + Frame f = vm->frames[vm->fp]; + st.symbols[st.sc].reg = f.rp; + + uint32_t i; + for (i = 0; i < length; i++) { + st.symbols[st.sc].name[i] = parser.previous.start[i + 1]; + } + st.sc++; if (match(TOKEN_EQ)) { expression(vm); } else { - /* not sure here yet */ + /* initialize as zero/null */ + emitOp(vm, OP_LOADI, vm->frames[vm->fp].rp++, 0, 0); + vm->code[vm->cp++].i = 0; } consume(TOKEN_SEMICOLON, "Expect ';' after expression."); @@ -337,6 +356,12 @@ bool compile(const char *source, VM *vm) { parser.hadError = false; parser.panicMode = false; + st.sc = 0; + st.name[0] = 'm'; + st.name[1] = 'a'; + st.name[2] = 'i'; + st.name[3] = 'n'; + advance(); while (!match(TOKEN_EOF)) { diff --git a/src/compiler.h b/src/compiler.h index 20c5057..0e7a980 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -18,7 +18,7 @@ typedef struct array_def_t { #define SYMBOL_NAME_SIZE 24 -typedef struct symbol_table_t { +typedef struct symbol_t { char name[SYMBOL_NAME_SIZE]; SymbolType type; union { @@ -26,6 +26,7 @@ typedef struct symbol_table_t { ArrayDef ad; }; int8_t reg; + uint8_t flags[3]; /* only use for padding now, might be used later*/ union { uint32_t frame; uint32_t ptr; @@ -35,10 +36,13 @@ typedef struct symbol_table_t { #define MODULE_NAME_SIZE 32 #define SYMBOL_COUNT 256 -typedef struct module_t { +typedef struct symbol_table_t { char name[MODULE_NAME_SIZE]; Symbol symbols[SYMBOL_COUNT]; -} Module; + uint32_t sc; +} SymbolTable; + +extern SymbolTable st; bool compile(const char *source, VM *vm); diff --git a/src/test.c b/src/test.c index a7cf00c..075e33f 100644 --- a/src/test.c +++ b/src/test.c @@ -1,109 +1,117 @@ -#include "test.h" -#include "vm.h" - -bool test_add_compile(VM *vm) { - vm->code[vm->cp++].u = OP(OP_LOADU, 0, 0, 0); - vm->code[vm->cp++].u = 1; - vm->code[vm->cp++].u = OP(OP_LOADU, 1, 0, 0); - vm->code[vm->cp++].u = 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_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++].f = 5.0f; - vm->code[vm->cp++].u = OP(OP_LOADI, 1, 0, 0); /* do (i = 50000, 0, -1) { */ - vm->code[vm->cp++].i = 50000; - vm->code[vm->cp++].u = OP(OP_LOADI, 2, 0, 0); /* loop check value */ - vm->code[vm->cp++].i = 0; - vm->code[vm->cp++].u = OP(OP_LOADI, 3, 0, 0); /* loop incriment value */ - vm->code[vm->cp++].i = -1; - vm->code[vm->cp++].u = OP(OP_LOADU, 4, 0, 0); /* loop start */ - uint32_t jmp = vm->cp + 1; - vm->code[vm->cp++].u = jmp; - vm->code[vm->cp++].u = OP(OP_LOADF, 5, 0, 0); - vm->code[vm->cp++].f = 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; */ - uint32_t prompt_addr = str_alloc(vm, "Enter a string:", 0); - vm->code[vm->cp++].u = OP(OP_LOADU, 5, 0, 0); - vm->code[vm->cp++].u = prompt_addr; - vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 5, 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_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_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_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++].i = 1; - 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++].i = 1; - vm->code[vm->cp++].u = OP(OP_PUSHI, 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_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_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_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_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++].i = 35; - vm->code[vm->cp++].u = OP(OP_PUSHI, 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_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_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++].i = 2; - vm->code[vm->cp++].u = OP(OP_LOADI, 2, 0, 0); /* &fib */ - vm->code[vm->cp++].i = 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++].i = 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_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++].i = 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_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_ADD_INT, 6, 5, 4); - vm->code[vm->cp++].u = OP(OP_PUSHI, 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_RETURN, 0, 0, 0); - return true; -} +#include "test.h" +#include "vm.h" + +bool test_add_compile(VM *vm) { + vm->code[vm->cp++].u = OP(OP_LOADU, 0, 0, 0); + vm->code[vm->cp++].u = 0; + int_alloc(vm, 1); + vm->code[vm->cp++].u = OP(OP_LOADU, 1, 1, 0); + vm->code[vm->cp++].u = 1; + int_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_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 */ + uint32_t addr = real_alloc(vm, 5.0f); + vm->code[vm->cp++].u = addr; + vm->code[vm->cp++].u = OP(OP_LOADI, 1, 0, 0); /* do (i = 50000, 0, -1) { */ + addr = int_alloc(vm, 50000); + vm->code[vm->cp++].u = addr; + vm->code[vm->cp++].u = OP(OP_LOADI, 2, 0, 0); /* loop check value */ + addr = int_alloc(vm, 0); + vm->code[vm->cp++].u = addr; + vm->code[vm->cp++].u = OP(OP_LOADI, 3, 0, 0); /* loop incriment value */ + addr = int_alloc(vm, -1); + vm->code[vm->cp++].u = addr; + vm->code[vm->cp++].u = OP(OP_LOADU, 4, 0, 0); /* loop start */ + int_alloc(vm, vm->cp + 1); + vm->code[vm->cp++].u = 4; + vm->code[vm->cp++].u = OP(OP_LOADF, 5, 0, 0); + addr = real_alloc(vm, 5.0f); + vm->code[vm->cp++].u = addr; + 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_LOADU, 5, 0, 0); + addr = str_alloc(vm, "Enter a string:", 0); + printf("addr=%d\n", addr); + vm->code[vm->cp++].u = addr; + vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 5, 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_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_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_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++].i = 1; + 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++].i = 1; + vm->code[vm->cp++].u = OP(OP_PUSHI, 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_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_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_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_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++].i = 35; + vm->code[vm->cp++].u = OP(OP_PUSHI, 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_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_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++].i = 2; + vm->code[vm->cp++].u = OP(OP_LOADI, 2, 0, 0); /* &fib */ + vm->code[vm->cp++].i = 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++].i = 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_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++].i = 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_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_ADD_INT, 6, 5, 4); + vm->code[vm->cp++].u = OP(OP_PUSHI, 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_RETURN, 0, 0, 0); + return true; +} diff --git a/src/vm.c b/src/vm.c index 7b47e59..198fc8c 100644 --- a/src/vm.c +++ b/src/vm.c @@ -43,6 +43,27 @@ uint32_t str_alloc(VM *vm, const char *str, uint32_t length) { return str_addr; } +uint32_t real_alloc(VM *vm, float v) { + uint32_t addr = vm->mp; + vm->memory[vm->mp++].f = v; + vm->frames[vm->fp].allocated.end++; + return addr; +} + +uint32_t nat_alloc(VM *vm, uint32_t v) { + uint32_t addr = vm->mp; + vm->memory[vm->mp++].u = v; + vm->frames[vm->fp].allocated.end++; + return addr; +} + +uint32_t int_alloc(VM *vm, int32_t v) { + uint32_t addr = vm->mp; + vm->memory[vm->mp++].i = v; + vm->frames[vm->fp].allocated.end++; + return addr; +} + /** * Step to the next opcode in the vm. */ @@ -74,23 +95,35 @@ bool step_vm(VM *vm) { vm->frames[vm->fp--].allocated.start; /* reset memory pointer to start of old slice, pop the frame */ return true; - case OP_LOADI: - vm->frames[vm->fp].registers[dest].i = vm->code[vm->pc++].i; + case OP_LOADI:{ + uint32_t ptr = vm->code[vm->pc++].u; + int32_t v = vm->memory[ptr].i; + /* printf("loadi | ptr=%d value=%d dest=%d\n", ptr, v, dest); */ + vm->frames[vm->fp].registers[dest].i = v; return true; - case OP_LOADU: - vm->frames[vm->fp].registers[dest].u = vm->code[vm->pc++].u; + } + case OP_LOADU:{ + uint32_t ptr = vm->code[vm->pc++].u; + uint32_t v = vm->memory[ptr].u; + /* printf("loadu | ptr=%d value=%d dest=%d\n", ptr, v, dest); */ + vm->frames[vm->fp].registers[dest].u = v; return true; - case OP_LOADF: - vm->frames[vm->fp].registers[dest].f = vm->code[vm->pc++].f; + } + case OP_LOADF: { + uint32_t ptr = vm->code[vm->pc++].u; + float v = vm->memory[ptr].f; + /* printf("loadf | ptr=%d value=%f dest=%d\n", ptr, v, dest); */ + vm->frames[vm->fp].registers[dest].f = v; return true; + } case OP_STOREI: - vm->code[vm->pc++].i = vm->frames[vm->fp].registers[dest].i; + vm->memory[vm->code[vm->pc++].u].i = vm->frames[vm->fp].registers[src1].i; return true; case OP_STOREU: - vm->code[vm->pc++].u = vm->frames[vm->fp].registers[dest].u; + vm->memory[vm->code[vm->pc++].u].u = vm->frames[vm->fp].registers[src1].u; return true; case OP_STOREF: - vm->code[vm->pc++].f = vm->frames[vm->fp].registers[dest].f; + vm->memory[vm->code[vm->pc++].u].f = vm->frames[vm->fp].registers[src1].f; return true; case OP_PUSHI: vm->stack[++vm->sp].i = vm->frames[vm->fp].registers[dest].i; @@ -257,10 +290,13 @@ bool step_vm(VM *vm) { case OP_PRINT_STRING: { uint32_t ptr = (uint32_t)vm->frames[vm->fp].registers[src1].u; uint32_t length = vm->memory[ptr].u; + + printf("len=%d\n", length); 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]; + printf("char=%c\n", ch); if (ch == '\0') break; putchar(ch); diff --git a/src/vm.h b/src/vm.h index d48fff2..2b0470d 100644 --- a/src/vm.h +++ b/src/vm.h @@ -6,5 +6,8 @@ VM* init_vm(); bool step_vm(VM *vm); uint32_t str_alloc(VM *vm, const char *str, uint32_t length); +uint32_t real_alloc(VM *vm, float v); +uint32_t nat_alloc(VM *vm, uint32_t v); +uint32_t int_alloc(VM *vm, int32_t v); #endif