diff --git a/src/arch/linux/main.c b/src/arch/linux/main.c index 46593e6..5d935c7 100644 --- a/src/arch/linux/main.c +++ b/src/arch/linux/main.c @@ -10,13 +10,11 @@ int main(int argc, char **argv) { vm.stack_size = STACK_SIZE; vm.memory_size = MEMORY_SIZE; - uint32_t end = 0; - - /* test_add_compile(vm.memory); */ - /* test_add_function_compile(vm.memory); */ - /* end = test_loop_compile(vm.memory); */ - end = test_hello_world_compile(vm.memory); - /* test_recursive_function_compile(vm.memory); */ + /* test_add_compile(&vm); */ + /* test_add_function_compile(&vm); */ + /* test_loop_compile(&vm); */ + test_hello_world_compile(&vm); + /* test_recursive_function_compile(&vm); */ uint32_t buffer_size = 640 * 480 * sizeof(uint32_t); @@ -24,8 +22,8 @@ int main(int argc, char **argv) { screen.type = SCREEN; screen.s = (Screen){.width = (uint8_t)480, .height = (uint8_t)640, - .allocated = {end, buffer_size}, - .buffer = &vm.memory[end]}; + .allocated = {vm.mp, buffer_size}, + .buffer = &vm.memory[vm.mp]}; vm.devices[vm.dp++] = screen; vm.mp += buffer_size; diff --git a/src/opcodes.h b/src/opcodes.h index 213e890..15a8e65 100644 --- a/src/opcodes.h +++ b/src/opcodes.h @@ -55,15 +55,17 @@ typedef union device_u { } Device; #define MEMORY_SIZE 65536 +#define CODE_SIZE 8192 #define FRAMES_SIZE 128 #define STACK_SIZE 256 #define DEVICES_SIZE 8 typedef struct vm_s { - uint32_t pc; /* Program counter */ - uint32_t fp; /* Frame pointer (current frame) */ + uint32_t pc; /* program counter */ + uint32_t cp; /* code pointer (last allocated opcode) */ + uint32_t fp; /* frame pointer (current frame) */ uint32_t sp; /* stack pointer (top of stack) */ uint32_t rp; /* return stack pointer (top of stack) */ - uint32_t mp; /* Memory pointer (last allocated value) */ + uint32_t mp; /* memory pointer (last allocated value) */ uint32_t dp; /* device pointer (last allocated device) */ uint8_t devices_size; Device devices[DEVICES_SIZE]; @@ -73,8 +75,10 @@ typedef struct vm_s { Value stack[STACK_SIZE]; /* main stack */ uint32_t return_stack_size; Value return_stack[STACK_SIZE]; /* return stack (for recursion) */ + uint32_t code_size; + Value code[CODE_SIZE]; /* code block */ uint32_t memory_size; - Value memory[MEMORY_SIZE]; /* memory array */ + Value memory[MEMORY_SIZE]; /* memory block */ } VM; typedef enum { diff --git a/src/test.c b/src/test.c index c2342cb..0956563 100644 --- a/src/test.c +++ b/src/test.c @@ -1,130 +1,125 @@ #include "test.h" -uint32_t test_hello_world_compile(Value *memory) { - uint32_t i = 0; - memory[i++].u = OP(OP_LOADU, 1, 0, 0); - memory[i++].u = 4; - memory[i++].u = OP(OP_PRINT_STRING, 0, 1, 0); /* print("nuqneH 'u'?"); */ - memory[i++].u = OP(OP_HALT, 0, 0, 0); /* explicit halt */ - memory[i++].u = 12; - memory[i].c[0] = 'n'; - memory[i].c[1] = 'u'; - memory[i].c[2] = 'q'; - memory[i++].c[3] = 'n'; - memory[i].c[0] = 'e'; - memory[i].c[1] = 'H'; - memory[i].c[2] = ' '; - memory[i++].c[3] = '\''; - memory[i].c[0] = 'u'; - memory[i].c[1] = '\''; - memory[i].c[2] = '?'; - memory[i++].c[3] = '\0'; - return i; +bool test_hello_world_compile(VM *vm) { + vm->code[vm->cp++].u = OP(OP_LOADU, 1, 0, 0); + vm->code[vm->cp++].u = 0; + vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 1, 0); /* print("nuqneH 'u'?"); */ + vm->code[vm->cp++].u = OP(OP_HALT, 0, 0, 0); /* explicit halt */ + vm->memory[vm->mp++].u = 12; + vm->memory[vm->mp].c[0] = 'n'; + vm->memory[vm->mp].c[1] = 'u'; + vm->memory[vm->mp].c[2] = 'q'; + vm->memory[vm->mp++].c[3] = 'n'; + vm->memory[vm->mp].c[0] = 'e'; + vm->memory[vm->mp].c[1] = 'H'; + vm->memory[vm->mp].c[2] = ' '; + vm->memory[vm->mp++].c[3] = '\''; + vm->memory[vm->mp].c[0] = 'u'; + vm->memory[vm->mp].c[1] = '\''; + vm->memory[vm->mp].c[2] = '?'; + vm->memory[vm->mp++].c[3] = '\0'; + return true; } -uint32_t test_add_compile(Value *memory) { - uint32_t i = 0; - memory[i++].u = OP(OP_LOADU, 0, 0, 0); - memory[i++].u = 1; - memory[i++].u = OP(OP_LOADU, 1, 0, 0); - memory[i++].u = 2; - memory[i++].u = OP(OP_ADD_UINT, 2, 1, 0); /* let sum = 1 + 2; */ - memory[i++].u = OP(OP_UINT_TO_STRING, 3, 2, 0); - memory[i++].u = OP(OP_PRINT_STRING, 0, 3, 0); /* print(sum.toS()); */ - memory[i++].u = OP(OP_HALT, 0, 0, 0); /* explicit halt */ - return i; +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; } -uint32_t test_loop_compile(Value *memory) { - uint32_t i = 0; - memory[i++].u = OP(OP_LOADF, 0, 0, 0); /* let a = 5.0 */ - memory[i++].f = 5.0f; - memory[i++].u = OP(OP_LOADI, 1, 0, 0); /* do (i = 5, 0, -1) { */ - memory[i++].i = 5000; - memory[i++].u = OP(OP_LOADI, 2, 0, 0); /* loop check value */ - memory[i++].i = 0; - memory[i++].u = OP(OP_LOADI, 3, 0, 0); /* loop incriment value */ - memory[i++].i = -1; - memory[i++].u = OP(OP_LOADU, 4, 0, 0); /* loop start */ - uint32_t jmp = i + 1; - memory[i++].u = jmp; - memory[i++].u = OP(OP_LOADF, 5, 0, 0); - memory[i++].f = 5.0f; - memory[i++].u = OP(OP_ADD_REAL, 0, 0, 5); /* a += 5.0; */ - memory[i++].u = OP(OP_ADD_INT, 1, 1, 3); /* (implied by loop) i = i + (-1) */ - memory[i++].u = OP(OP_JGE_INT, 4, 1, 2); /* } */ - memory[i++].u = OP(OP_REAL_TO_UINT, 1, 0, 0); /* let b = a as nat; */ - memory[i++].u = OP(OP_READ_STRING, 2, 0, 0); /* let user_string = gets(); */ - memory[i++].u = OP(OP_UINT_TO_STRING, 3, 1, 0); - memory[i++].u = OP(OP_PRINT_STRING, 0, 3, 0); /* print(a.toS()); */ - memory[i++].u = OP(OP_REAL_TO_STRING, 3, 0, 0); - memory[i++].u = OP(OP_PRINT_STRING, 0, 3, 0); /* print(b.toS()); */ - memory[i++].u = OP(OP_PRINT_STRING, 0, 2, 0); /* print(user_string); */ - memory[i++].u = OP(OP_HALT, 0, 0, 0); /* program done */ - return i; +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; */ + 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; } -uint32_t test_add_function_compile(Value *memory) { - uint32_t i = 0; +bool test_add_function_compile(VM *vm) { /* fn 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); - memory[i++].u = OP(OP_CALL, 0, 0, 0); /* ); */ - memory[i++].u = 12; - 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); + 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() */ - memory[i++].u = OP(OP_POPI, 0, 0, 0); /* a int */ - memory[i++].u = OP(OP_POPI, 1, 0, 0); /* b int */ - memory[i++].u = OP(OP_ADD_INT, 2, 1, 0); /* a + b */ - memory[i++].u = OP(OP_PUSHI, 2, 0, 0); /* push on stack */ - memory[i++].u = OP(OP_RETURN, 0, 0, 0); - return i; + 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; } -uint32_t test_recursive_function_compile(Value *memory) { - uint32_t i = 0; +bool test_recursive_function_compile(VM *vm) { /* fn main() */ - memory[i++].u = OP(OP_LOADI, 0, 0, 0); /* 35 */ - memory[i++].i = 35; - memory[i++].u = OP(OP_PUSHI, 0, 0, 0); - memory[i++].u = OP(OP_CALL, 0, 0, 0); /* ); */ - memory[i++].u = 9; - 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(fib(35).toS()); */ - memory[i++].u = OP(OP_HALT, 0, 0, 0); + 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() */ - memory[i++].u = OP(OP_POPI, 0, 0, 0); /* n int */ - memory[i++].u = OP(OP_LOADI, 1, 0, 0); /* 2 */ - memory[i++].i = 2; - memory[i++].u = OP(OP_LOADI, 2, 0, 0); /* &fib */ - memory[i++].i = 32; - memory[i++].u = OP(OP_JLT_INT, 2, 0, 1); - memory[i++].u = OP(OP_LOADI, 3, 0, 0); /* 2 */ - memory[i++].i = 2; - memory[i++].u = OP(OP_SUB_INT, 4, 0, 3); - memory[i++].u = OP(OP_PUSHI, 4, 0, 0); - memory[i++].u = OP(OP_CALL, 0, 0, 0); /* fib(n - 2) */ - memory[i++].u = 9; - memory[i++].u = OP(OP_LOADI, 3, 0, 0); /* 1 */ - memory[i++].i = 1; - memory[i++].u = OP(OP_SUB_INT, 4, 0, 3); - memory[i++].u = OP(OP_PUSHI, 4, 0, 0); - memory[i++].u = OP(OP_CALL, 0, 0, 0); /* fib(n - 1) */ - memory[i++].u = 9; - memory[i++].u = OP(OP_POPI, 4, 0, 0); - memory[i++].u = OP(OP_POPI, 5, 0, 0); - memory[i++].u = OP(OP_ADD_INT, 6, 5, 4); - memory[i++].u = OP(OP_PUSHI, 6, 0, 0); - memory[i++].u = OP(OP_RETURN, 0, 0, 0); - memory[i++].u = OP(OP_PUSHI, 0, 0, 0); - memory[i++].u = OP(OP_RETURN, 0, 0, 0); - return i; + 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/test.h b/src/test.h index b79bc3c..bee509d 100644 --- a/src/test.h +++ b/src/test.h @@ -3,10 +3,10 @@ #include "opcodes.h" -uint32_t test_hello_world_compile (Value *memory); -uint32_t test_add_compile (Value *memory); -uint32_t test_loop_compile (Value *memory); -uint32_t test_add_function_compile(Value *memory); -uint32_t test_recursive_function_compile(Value *memory); +bool test_hello_world_compile (VM *vm); +bool test_add_compile (VM *vm); +bool test_loop_compile (VM *vm); +bool test_add_function_compile(VM *vm); +bool test_recursive_function_compile(VM *vm); #endif diff --git a/src/vm.c b/src/vm.c index 67097c9..2f352a6 100644 --- a/src/vm.c +++ b/src/vm.c @@ -41,7 +41,7 @@ void mem_strcpy(Value *memory, const char *str, uint32_t length, */ bool step_vm(VM *vm) { /* Get current instruction & Advance to next instruction */ - uint32_t instruction = vm->memory[vm->pc++].u; + uint32_t instruction = vm->code[vm->pc++].u; uint8_t opcode = (instruction >> 24) & 0xFF; uint8_t dest = (instruction >> 16) & 0xFF; @@ -52,7 +52,7 @@ bool step_vm(VM *vm) { case OP_HALT: return false; case OP_CALL:; /* whats up with this semicolon? ANSI C does not allow you to create a variabel after a case, so this noop is here */ - uint32_t jmp = vm->memory[vm->pc++].u; /* location of function in memory */ + uint32_t jmp = vm->code[vm->pc++].u; /* location of function in code */ vm->return_stack[vm->rp++].u = vm->pc; /* set return address */ vm->fp++; /* increment to the next free frame */ vm->frames[vm->fp].allocated.start = vm->mp; /* set start of new memory block */ @@ -63,22 +63,22 @@ bool step_vm(VM *vm) { vm->mp = 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->memory[vm->pc++].i; + vm->frames[vm->fp].registers[dest].i = vm->code[vm->pc++].i; return true; case OP_LOADU: - vm->frames[vm->fp].registers[dest].u = vm->memory[vm->pc++].u; + vm->frames[vm->fp].registers[dest].u = vm->code[vm->pc++].u; return true; case OP_LOADF: - vm->frames[vm->fp].registers[dest].f = vm->memory[vm->pc++].f; + vm->frames[vm->fp].registers[dest].f = vm->code[vm->pc++].f; return true; case OP_STOREI: - vm->memory[vm->pc++].i = vm->frames[vm->fp].registers[dest].i; + vm->code[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[dest].u; + vm->code[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[dest].f; + vm->code[vm->pc++].f = vm->frames[vm->fp].registers[dest].f; return true; case OP_PUSHI: vm->stack[++vm->sp].i = vm->frames[vm->fp].registers[dest].i; diff --git a/test/loop.lua b/test/loop.lua index e73282f..2b5aa57 100644 --- a/test/loop.lua +++ b/test/loop.lua @@ -1,5 +1,5 @@ local a = 5.0 -for i = 5, 0, -1 do +for i = 50000, 0, -1 do a = a + 5.0 end local b = math.floor(a) diff --git a/test/loop.pl b/test/loop.pl index 9427079..5183ae9 100644 --- a/test/loop.pl +++ b/test/loop.pl @@ -1,5 +1,5 @@ my $a = 5.0; -for (my $i = 5; $i >= 0; $i--) { +for (my $i = 50000; $i >= 0; $i--) { $a += 5.0; } my $b = int($a); diff --git a/test/loop.py b/test/loop.py index 00a0d6a..16295c8 100644 --- a/test/loop.py +++ b/test/loop.py @@ -1,5 +1,5 @@ a = 5.0 -for i in range(5, -1, -1): +for i in range(50000, -1, -1): a += 5.0 b = int(a) user_string = input("Enter a string: ") diff --git a/test/loop.zre b/test/loop.zre index d1979e3..92b5382 100644 --- a/test/loop.zre +++ b/test/loop.zre @@ -1,5 +1,5 @@ let a = 5.0; -do (let i = 5, 0, -1) { +do (let i = 50000, 0, -1) { a += 5.0; } let b = a as nat;