From 18697c92b6ce72453fcf0625481ed1228f775ca4 Mon Sep 17 00:00:00 2001 From: zongor Date: Wed, 11 Feb 2026 21:00:20 -0800 Subject: [PATCH] fib example --- arch/linux/tui/main.c | 91 ++++++++++++++++++++++++++------- tools/compiler/compiler.c | 5 ++ vm/vm.c | 104 +++++++++++++++++++------------------- vm/vm.h | 7 +++ 4 files changed, 137 insertions(+), 70 deletions(-) diff --git a/arch/linux/tui/main.c b/arch/linux/tui/main.c index 4c25067..bc3dc37 100644 --- a/arch/linux/tui/main.c +++ b/arch/linux/tui/main.c @@ -71,31 +71,86 @@ u32 syscall(u32 id, u32 mem_ptr) { return 1; // generic error } -static void repl() { - ScopeTable st; - char line[1024]; - for (;;) { - printf("> "); +//static void repl() { +// ScopeTable st; +// char line[1024]; +// for (;;) { +// printf("> "); +// +// if (!fgets(line, sizeof(line), stdin)) { +// printf("\n"); +// break; +// } +// +// reset(); +// +// compile(&st, line); +// +// while(step_vm()) {} +// +// syscall(SYSCALL_CONSOLE_WRITE, stack[0]); +// } +//} - if (!fgets(line, sizeof(line), stdin)) { - printf("\n"); - break; - } +void fib() { + u8 fib_ptr = 10; + code[cp++] = OP_PUSH_8; + code[cp++] = 35; + code[cp++] = OP_PUSH_8; + code[cp++] = fib_ptr; + code[cp++] = OP_CALL; + code[cp++] = OP_INT_TO_STR; + code[cp++] = OP_PUSH_8; + code[cp++] = SYSCALL_CONSOLE_WRITE; + code[cp++] = OP_SYSCALL; + code[cp++] = OP_HALT; + /* fib (int n) int */ + code[cp++] = OP_SET_IMM; + code[cp++] = 0; + /* if (n < 2) { */ + code[cp++] = OP_GET_IMM; + code[cp++] = 0; + code[cp++] = OP_PUSH_8; + code[cp++] = 2; + code[cp++] = OP_LTS; + code[cp++] = OP_PUSH_8; + u8 if_true = cp + 5; + code[cp++] = if_true; + code[cp++] = OP_JNZ; + code[cp++] = OP_PUSH_8; + u8 if_false = cp + 5; + code[cp++] = if_false; + code[cp++] = OP_JMP; + code[cp++] = OP_GET_IMM; + code[cp++] = 0; + code[cp++] = OP_RETURN; + code[cp++] = OP_GET_IMM; + code[cp++] = 0; + code[cp++] = OP_PUSH_8; + code[cp++] = 2; + code[cp++] = OP_SUB_INT; + code[cp++] = OP_PUSH_8; + code[cp++] = fib_ptr; + code[cp++] = OP_CALL; + code[cp++] = OP_GET_IMM; + code[cp++] = 0; + code[cp++] = OP_PUSH_8; + code[cp++] = 1; + code[cp++] = OP_SUB_INT; + code[cp++] = OP_PUSH_8; + code[cp++] = fib_ptr; + code[cp++] = OP_CALL; + code[cp++] = OP_ADD_INT; + code[cp++] = OP_RETURN; - reset(); - - compile(&st, line); - - while(step_vm()) {} - - syscall(SYSCALL_CONSOLE_WRITE, stack[0]); - } + while(step_vm()) {} } i32 main() { init_vm(); - repl(); + fib(); + //repl(); return 0; } diff --git a/tools/compiler/compiler.c b/tools/compiler/compiler.c index 950010d..7226c8e 100644 --- a/tools/compiler/compiler.c +++ b/tools/compiler/compiler.c @@ -4,6 +4,11 @@ #include #include +Token operator_stack[128]; +u8 osp; +Token value_stack[256]; +u8 vsp; + Parser parser; Symbol *symbol_table_lookup(ScopeTable *table, const char *name, u32 length, diff --git a/vm/vm.c b/vm/vm.c index b0d2bf6..5505364 100644 --- a/vm/vm.c +++ b/vm/vm.c @@ -28,66 +28,25 @@ u32 str_alloc(char *str, u32 length) { } bool step_vm() { - - u8 opcode = code[pc++]; - /*u32 *locals = (u32*)(&mem[fp]);*/ - u32 *globals = (u32*)(mem); + u16 opcode = code[pc++]; switch (opcode) { case OP_HALT: { - /* no need to decode, all are zeros */ return false; } case OP_CALL: { - /* function to jump to */ u32 fn_ptr = stack[--sp]; - /* get mp in 'global indexing mode' */ - u32 *header = &globals[mp / 4]; - /* push parents frame value to reset the heap to */ - (*header++) = fp; - /* increase the mp to new size */ - mp += FRAME_HEADER_SIZE; - /* now set the frame pointer, where the locals start */ - fp = mp; - /* move mp forward by count many locals */ - mp += stack[--sp]; - /* jump to dest_ptr */ + frames[fp].return_pc = pc; + frames[fp++].start_mp = mp; pc = fn_ptr; - return false; + return true; } case OP_RETURN: { - /* TODO: Fix this one so it makes sense with a stack based system */ - u32 size = 0; - u32 return_value = stack[--sp]; - bool is_ptr = (((u32)(1)) << 15) & return_value; - - /* reset mp to saved mp, use header size to get "real" start of frame */ - u32 *frame_start = &globals[(fp / 4) - 3]; - u32 parent_fp = *frame_start++; - u32 return_address = *frame_start++; - u32 parent_local_return_address = *frame_start++; - - /* reset memory to parents end of memory */ - mp = fp - FRAME_HEADER_SIZE; - /* reset the frame pointer */ - fp = parent_fp; - - if (is_ptr) { - /* copy value to end of mp if it is a pointer */ - globals[parent_local_return_address/4] = mp; - size = globals[return_value/4]; - globals[mp/4] = size; - mp += 4; - mcpy(&mem[mp], &mem[return_value], size); - mp += size; - } else { - /* otherwise just write the return value to its location */ - mcpy(&mem[parent_local_return_address], &return_value, sizeof(u32)); - } - - /* jump to parent frame */ - pc = return_address; - return false; + u32 return_pc = frames[--fp].return_pc; + u32 return_mp = frames[fp].start_mp; + mp = return_mp; + pc = return_pc; + return true; } case OP_SYSCALL: { u32 id = stack[--sp]; /* syscall id */ @@ -115,10 +74,48 @@ bool step_vm() { stack[sp++] = value; return true; } + case OP_PUSH_MP: { + stack[sp++] = mp; + return true; + } + case OP_PUSH_START_MP: { + stack[sp++] = frames[fp - 1].start_mp; + return true; + } case OP_POP: { --sp; return true; } + case OP_SET:{ + Frame *f = &frames[fp - 1]; + u32 *locals = f->locals; + u8 ptr = (u8)stack[--sp]; + u32 value = stack[--sp]; + locals[ptr] = value; + return true; + } + case OP_SET_IMM:{ + Frame *f = &frames[fp - 1]; + u32 *locals = f->locals; + u8 ptr = code[pc++]; + u32 value = stack[--sp]; + locals[ptr] = value; + return true; + } + case OP_GET:{ + Frame *f = &frames[fp - 1]; + u32 *locals = f->locals; + u8 ptr = (u8)stack[--sp]; + stack[sp++] = locals[ptr]; + return true; + } + case OP_GET_IMM:{ + Frame *f = &frames[fp - 1]; + u32 *locals = f->locals; + u8 ptr = code[pc++]; + stack[sp++] = locals[ptr]; + return true; + } case OP_LOAD_8: { u32 ptr = stack[--sp]; u32 value = mem[ptr]; @@ -180,6 +177,7 @@ bool step_vm() { ptr_dest = &mem[dest]; ptr_src = &mem[src]; + if (ptr_dest == ptr_src) { return true; } mcpy(ptr_dest, ptr_src, count*sizeof(u8)); status = 0; @@ -199,6 +197,7 @@ bool step_vm() { ptr_dest = &mem[dest]; ptr_src = &mem[src]; + if (ptr_dest == ptr_src) { return true; } mcpy(ptr_dest, ptr_src, count*sizeof(u16)); status = 0; @@ -218,6 +217,7 @@ bool step_vm() { ptr_dest = &mem[dest]; ptr_src = &mem[src]; + if (ptr_dest == ptr_src) { return true; } mcpy(ptr_dest, ptr_src, count*sizeof(u32)); status = 0; @@ -472,9 +472,9 @@ bool step_vm() { return true; } case OP_JNZ: { - u32 mask, target; + u32 mask; + u32 target = stack[--sp]; i32 cond = stack[--sp]; - target = stack[--sp]; mask = -(u32)cond; pc = (target & mask) | (pc & ~mask); return true; diff --git a/vm/vm.h b/vm/vm.h index cce5a37..51b21e3 100644 --- a/vm/vm.h +++ b/vm/vm.h @@ -18,6 +18,12 @@ typedef enum { OP_PUSH_8, /* const `push8` obj1 | push a 8 bit const onto the stack */ OP_PUSH_16, /* const `push16` obj1 | push a 16 bit const onto the stack */ OP_PUSH_32, /* const `push32` obj1 | push a 32 bit const onto the stack */ + OP_PUSH_MP, /* - `pmp` mp | push current mp to stack */ + OP_PUSH_START_MP, /* - `psmp` mp | push the frames start mp to stack (parent frames end mp); used for returning heap values to parent */ + OP_SET, /* obj dest `set` - | sets a local to the next value on top of the stack (max 255) */ + OP_GET, /* dest `get` obj | pushes a local from the value on top of the stack (max 255) */ + OP_SET_IMM, /* obj #dest `seti` - | sets a local to the next immediate location (max 255) */ + OP_GET_IMM, /* #dest `geti` obj | pushes a local from the immediate location (max 255) */ OP_POP, /* - `pop` - | removes top item from the stack */ OP_DUP, /* obj1 `dup` obj1 obj1 | duplicates the top of the stack */ OP_EXCH, /* obj2 obj1 `exch` obj1 obj2 | swaps the top two values on the stack */ @@ -89,6 +95,7 @@ typedef enum { typedef struct frame_s Frame; struct frame_s { + u32 locals[256]; u32 return_pc; u32 start_mp; };