From 7ec2f90d382ae8593fcdafa9906fb49df02e29fd Mon Sep 17 00:00:00 2001 From: zongor Date: Sat, 5 Jul 2025 23:29:07 -0400 Subject: [PATCH] add function example --- src/compiler.c | 32 ++++++++++++++++++++++++++------ src/debug.c | 24 ++++++++++++++++++++++++ src/main.c | 2 +- src/opcodes.h | 8 ++++---- src/vm.c | 27 ++++++++++++++++++++++----- 5 files changed, 77 insertions(+), 16 deletions(-) diff --git a/src/compiler.c b/src/compiler.c index 4c77639..68a4c83 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -44,19 +44,39 @@ uint32_t test_loop_compile(Value *memory) { } uint32_t test_add_function_compile(Value *memory) { - uint32_t i = 0; - memory[i++].u = OP(OP_POP_ARGS, 0, 0, 0); - memory[i++].u = OP(OP_ADD_INT, 2, 1, 0); + uint32_t i = 3; + memory[i++].u = OP(OP_POPU, 0, 0, 0); /* return ptr */ + memory[i++].u = OP(OP_POPI, 1, 0, 0); /* a int */ + memory[i++].u = OP(OP_POPI, 2, 0, 0); /* b int */ + memory[i++].u = OP(OP_ADD_INT, 3, 2, 1); /* a + b */ + memory[i++].u = OP(OP_PUSHI, 3, 0, 0); /* return */ memory[i++].u = OP(OP_RETURN, 0, 0, 0); + uint32_t main = i; + memory[0].u = OP(OP_LOADF, 0, 0, 0); + memory[1].u = main; + memory[2].u = OP(OP_JMP, 0, 0, 0); /* jump to 'main' */ + memory[i++].u = OP(OP_LOADI, 0, 0, 0); /* 1 */ + memory[i++].i = 1; + memory[i++].u = OP(OP_PUSHI, 0, 0, 0); + memory[i++].u = OP(OP_LOADI, 0, 0, 0); /* 1 */ + memory[i++].i = 1; + memory[i++].u = OP(OP_PUSHI, 0, 0, 0); + uint32_t add_fn_return = i + 6; /* after the call */ + memory[i++].u = OP(OP_LOADI, 0, 0, 0); /* return */ + memory[i++].u = add_fn_return; + memory[i++].u = OP(OP_PUSHU, 0, 0, 0); + memory[i++].u = OP(OP_LOADU, 0, 0, 0); /* add fn ptr */ + memory[i++].u = 3; + memory[i++].u = OP(OP_CALL, 0, 0, 0); /* ); */ + memory[i++].u = OP(OP_POPI, 0, 0, 0); /* get return value */ + memory[i++].u = OP(OP_INT_TO_STRING, 1, 0, 0); + memory[i++].u = OP(OP_PRINT_STRING, 0, 1, 0); /* print(sum.toS()); */ memory[i++].u = OP(OP_HALT, 0, 0, 0); return i; } uint32_t test_recursive_function_compile(Value *memory) { uint32_t i = 0; - memory[i++].u = OP(OP_POP_ARGS, 0, 0, 0); - memory[i++].u = OP(OP_ADD_INT, 2, 1, 0); - memory[i++].u = OP(OP_RETURN, 0, 0, 0); memory[i++].u = OP(OP_HALT, 0, 0, 0); return i; } diff --git a/src/debug.c b/src/debug.c index 693f9b0..778812f 100644 --- a/src/debug.c +++ b/src/debug.c @@ -23,6 +23,12 @@ void printOp(uint8_t op, uint8_t dest, uint8_t src1, uint8_t src2) { case OP_HALT: printf("[HALT] $%d, $%d, $%d\n", dest, src1, src2); break; + case OP_CALL: + printf("[CALL] $%d, $%d, $%d\n", dest, src1, src2); + break; + case OP_RETURN: + printf("[RETURN] $%d, $%d, $%d\n", dest, src1, src2); + break; case OP_LOADI: printf("[LOADI] $%d, $%d, $%d\n", dest, src1, src2); break; @@ -41,6 +47,24 @@ void printOp(uint8_t op, uint8_t dest, uint8_t src1, uint8_t src2) { case OP_STOREF: printf("[STOREF] $%d, $%d, $%d\n", dest, src1, src2); break; + case OP_PUSHI: + printf("[PUSHI] $%d, $%d, $%d\n", dest, src1, src2); + break; + case OP_PUSHU: + printf("[PUSHU] $%d, $%d, $%d\n", dest, src1, src2); + break; + case OP_PUSHF: + printf("[PUSHF] $%d, $%d, $%d\n", dest, src1, src2); + break; + case OP_POPI: + printf("[POPI] $%d, $%d, $%d\n", dest, src1, src2); + break; + case OP_POPU: + printf("[POPU] $%d, $%d, $%d\n", dest, src1, src2); + break; + case OP_POPF: + printf("[POPF] $%d, $%d, $%d\n", dest, src1, src2); + break; case OP_ADD_INT: printf("[ADD_INT] $%d, $%d, $%d\n", dest, src1, src2); break; diff --git a/src/main.c b/src/main.c index bad2cfb..7159d44 100644 --- a/src/main.c +++ b/src/main.c @@ -54,7 +54,7 @@ int main(int argc, char **argv) { vm.frames_size = FRAMES_SIZE; vm.stack_size = STACK_SIZE; vm.memory_size = MEMORY_SIZE; - vm.frames[vm.fp].allocated.end = test_loop_compile(vm.memory); + vm.frames[vm.fp].allocated.end = test_add_function_compile(vm.memory); #ifdef __EMSCRIPTEN__ emscripten_set_main_loop(mainloop, 0, 1); diff --git a/src/opcodes.h b/src/opcodes.h index 4eb6fc9..e5b91f8 100644 --- a/src/opcodes.h +++ b/src/opcodes.h @@ -17,7 +17,7 @@ typedef struct { #define MAX_REGS 256 typedef struct { - Value registers[MAX_REGS]; /* R0-R[MAX_REGS-1] */ + Value registers[MAX_REGS]; /* R0-R255 */ uint32_t rp; /* register pointer (last unused) */ Slice allocated; /* start and end of global allocated block */ } Frame; @@ -31,11 +31,11 @@ typedef struct { uint32_t rp; /* Return stack pointer (top of stack) */ uint32_t mp; /* Memory pointer (last allocated value) */ uint32_t frames_size; - Frame frames[FRAMES_SIZE]; + Frame frames[FRAMES_SIZE]; /* function call frames */ uint32_t stack_size; - Value stack[STACK_SIZE]; + Value stack[STACK_SIZE]; /* main stack */ uint32_t memory_size; - Value memory[MEMORY_SIZE]; /* Memory array */ + Value memory[MEMORY_SIZE]; /* memory array */ } VM; typedef enum { diff --git a/src/vm.c b/src/vm.c index f523f3a..7f002e0 100644 --- a/src/vm.c +++ b/src/vm.c @@ -54,7 +54,6 @@ bool step_vm(VM *vm) { case OP_HALT: return false; case OP_CALL: - vm->stack[++vm->rp].u = vm->pc; /* push return address */ vm->pc = vm->frames[vm->fp] .registers[dest] .u; /* set pc to location of function in memory */ @@ -85,13 +84,31 @@ bool step_vm(VM *vm) { vm->frames[vm->fp].registers[dest].f = vm->memory[vm->pc++].f; return true; case OP_STOREI: - vm->memory[vm->pc++].i = vm->frames[vm->fp].registers[src1].i; + vm->memory[vm->pc++].i = vm->frames[vm->fp].registers[dest].i; return true; case OP_STOREU: - vm->memory[vm->pc++].u = vm->frames[vm->fp].registers[src1].u; + vm->memory[vm->pc++].u = vm->frames[vm->fp].registers[dest].u; return true; case OP_STOREF: - vm->memory[vm->pc++].f = vm->frames[vm->fp].registers[src1].f; + vm->memory[vm->pc++].f = vm->frames[vm->fp].registers[dest].f; + return true; + case OP_PUSHI: + vm->stack[++vm->rp].i = vm->frames[vm->fp].registers[dest].i; + return true; + case OP_PUSHU: + vm->stack[++vm->rp].u = vm->frames[vm->fp].registers[dest].u; + return true; + case OP_PUSHF: + vm->stack[++vm->rp].f = vm->frames[vm->fp].registers[dest].f; + return true; + case OP_POPI: + vm->frames[vm->fp].registers[dest].i = vm->stack[vm->rp--].i; + return true; + case OP_POPU: + vm->frames[vm->fp].registers[dest].u = vm->stack[vm->rp--].u; + return true; + case OP_POPF: + vm->frames[vm->fp].registers[dest].f = vm->stack[vm->rp--].f; return true; case OP_ADD_INT: MATH_OP(i, +); @@ -137,7 +154,7 @@ bool step_vm(VM *vm) { vm->frames[vm->fp].registers[dest] = vm->frames[vm->fp].registers[src1]; return true; case OP_JMP: - vm->pc = vm->frames[vm->fp].registers[src1].u; /* Jump to address */ + vm->pc = vm->frames[vm->fp].registers[dest].u; /* Jump to address */ return true; case OP_JEQ_UINT: { COMPARE_AND_JUMP(uint32_t, u, ==);