From f1edd4267f10849a6b9de17c5adb00a95d425620 Mon Sep 17 00:00:00 2001 From: zongor Date: Sun, 24 Aug 2025 00:06:24 -0700 Subject: [PATCH] fix loop compile --- src/arch/linux/main.c | 2 +- src/opcodes.h | 3 +- src/test.c | 13 ++--- src/vm.c | 127 ++++++++++++++++++++++++++---------------- 4 files changed, 88 insertions(+), 57 deletions(-) diff --git a/src/arch/linux/main.c b/src/arch/linux/main.c index 46926db..22d1ef5 100644 --- a/src/arch/linux/main.c +++ b/src/arch/linux/main.c @@ -56,7 +56,7 @@ int main(int argc, char **argv) { vm.memory_size = MEMORY_SIZE; if (argc == 1) { - test_loop_compile(&vm); + test_add_compile(&vm); /* repl(&vm); */ } else if (argc == 2) { compileFile(argv[1], &vm); diff --git a/src/opcodes.h b/src/opcodes.h index c773774..6cc3380 100644 --- a/src/opcodes.h +++ b/src/opcodes.h @@ -83,6 +83,7 @@ typedef enum { OP_LOADI, /* lodi : dest = next memory location as int */ OP_LOADU, /* lodu : dest = next memory location as uint */ OP_LOADF, /* lodf : dest = next memory location as float */ + OP_LOADP, /* lodp : dest = &[next memory location] */ OP_STOREI, /* stri : next memory location = src1 as int */ OP_STOREU, /* stru : next memory location = src1 as uint */ OP_STOREF, /* strf : next memory location = src1 as float */ @@ -151,6 +152,6 @@ typedef enum { } Devicecode; /* defines a uint32 opcode */ -#define OP(opcode, a, b, c) ((opcode << 24) | (a << 16) | (b << 8) | c) +#define OP(opcode, dest, src1, src2) ((opcode << 24) | (dest << 16) | (src1 << 8) | src2) #endif diff --git a/src/test.c b/src/test.c index 075e33f..52326c6 100644 --- a/src/test.c +++ b/src/test.c @@ -4,10 +4,10 @@ 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); + nat_alloc(vm, 1); vm->code[vm->cp++].u = OP(OP_LOADU, 1, 1, 0); vm->code[vm->cp++].u = 1; - int_alloc(vm, 2); + 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()); */ @@ -29,8 +29,8 @@ bool test_loop_compile(VM *vm) { 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; + addr = int_alloc(vm, vm->cp + 1); + vm->code[vm->cp++].u = addr; vm->code[vm->cp++].u = OP(OP_LOADF, 5, 0, 0); addr = real_alloc(vm, 5.0f); vm->code[vm->cp++].u = addr; @@ -38,11 +38,10 @@ bool test_loop_compile(VM *vm) { 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); + vm->code[vm->cp++].u = OP(OP_LOADP, 6, 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_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_UINT_TO_STRING, 3, 1, 0); vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 3, 0); /* print(a.toS()); */ diff --git a/src/vm.c b/src/vm.c index 198fc8c..76e6d2a 100644 --- a/src/vm.c +++ b/src/vm.c @@ -27,8 +27,9 @@ * Embeds a string into the VM */ uint32_t str_alloc(VM *vm, const char *str, uint32_t length) { - if (!length) + if (!length) { length = strlen(str); + } uint32_t str_addr = vm->mp; vm->memory[vm->mp++].u = length; uint32_t i, j = 0; @@ -77,8 +78,9 @@ bool step_vm(VM *vm) { uint8_t src2 = instruction & 0xFF; switch (opcode) { - case OP_HALT: + case OP_HALT: { return false; + } case OP_CALL: { uint32_t jmp = vm->code[vm->pc++].u; /* location of function in code */ vm->return_stack[vm->rp++].u = vm->pc; /* set return address */ @@ -88,61 +90,73 @@ bool step_vm(VM *vm) { vm->pc = jmp; return true; } - case OP_RETURN: + case OP_RETURN: { vm->frames[vm->fp].rp = 0; /* reset register ptr */ vm->pc = vm->return_stack[--vm->rp].u; /* set pc to return address */ vm->mp = vm->frames[vm->fp--].allocated.start; /* reset memory pointer to start of old slice, pop the frame */ return true; - case OP_LOADI:{ + } + 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:{ + 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: { 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: + case OP_LOADP: { + uint32_t ptr = vm->code[vm->pc++].u; + vm->frames[vm->fp].registers[dest].u = ptr; + return true; + } + case OP_STOREI: { vm->memory[vm->code[vm->pc++].u].i = vm->frames[vm->fp].registers[src1].i; return true; - case OP_STOREU: + } + case OP_STOREU: { vm->memory[vm->code[vm->pc++].u].u = vm->frames[vm->fp].registers[src1].u; return true; - case OP_STOREF: + } + case OP_STOREF: { vm->memory[vm->code[vm->pc++].u].f = vm->frames[vm->fp].registers[src1].f; return true; - case OP_PUSHI: + } + case OP_PUSHI: { vm->stack[++vm->sp].i = vm->frames[vm->fp].registers[dest].i; return true; - case OP_PUSHU: + } + case OP_PUSHU: { vm->stack[++vm->sp].u = vm->frames[vm->fp].registers[dest].u; return true; - case OP_PUSHF: + } + case OP_PUSHF: { vm->stack[++vm->sp].f = vm->frames[vm->fp].registers[dest].f; return true; - case OP_POPI: + } + case OP_POPI: { vm->frames[vm->fp].registers[dest].i = vm->stack[vm->sp--].i; return true; - case OP_POPU: + } + case OP_POPU: { vm->frames[vm->fp].registers[dest].u = vm->stack[vm->sp--].u; return true; - case OP_POPF: + } + case OP_POPF: { vm->frames[vm->fp].registers[dest].f = vm->stack[vm->sp--].f; return true; + } case OP_ADD_INT: MATH_OP(i, +); case OP_SUB_INT: @@ -167,23 +181,27 @@ bool step_vm(VM *vm) { MATH_OP(f, *); case OP_DIV_REAL: MATH_OP(f, /); - case OP_REAL_TO_INT: + case OP_REAL_TO_INT: { vm->frames[vm->fp].registers[dest].i = (int32_t)(vm->frames[vm->fp].registers[src1].f); return true; - case OP_INT_TO_REAL: + } + case OP_INT_TO_REAL: { vm->frames[vm->fp].registers[dest].f = (float)(vm->frames[vm->fp].registers[src1].i); return true; - case OP_REAL_TO_UINT: + } + case OP_REAL_TO_UINT: { vm->frames[vm->fp].registers[dest].u = (uint32_t)(vm->frames[vm->fp].registers[src1].f); return true; - case OP_UINT_TO_REAL: + } + case OP_UINT_TO_REAL: { vm->frames[vm->fp].registers[dest].f = (float)(vm->frames[vm->fp].registers[src1].u); return true; - case OP_REG_SWAP: + } + case OP_REG_SWAP: { vm->frames[vm->fp].registers[dest].u ^= vm->frames[vm->fp].registers[src1].u; vm->frames[vm->fp].registers[src1].u ^= @@ -191,12 +209,15 @@ bool step_vm(VM *vm) { vm->frames[vm->fp].registers[dest].u ^= vm->frames[vm->fp].registers[src1].u; return true; - case OP_REG_MOV: - vm->frames[vm->fp].registers[dest].i = vm->code[vm->pc++].i; + } + case OP_REG_MOV: { + vm->frames[vm->fp].registers[dest].i = vm->frames[vm->fp].registers[src1].i; return true; - case OP_JMP: + } + case OP_JMP: { vm->pc = vm->frames[vm->fp].registers[dest].u; /* Jump to address */ return true; + } case OP_JEQ_UINT: { COMPARE_AND_JUMP(uint32_t, u, ==); } @@ -244,59 +265,67 @@ bool step_vm(VM *vm) { } case OP_NOT: { /* TODO implement not */ + return false; } case OP_INT_TO_STRING: { int32_t a = (int32_t)vm->frames[vm->fp].registers[src1].i; /* get value */ char buffer[32]; int len = sprintf(buffer, "%d", a); - str_alloc(vm, buffer, len); /* copy buffer to dest */ + uint32_t ptr = str_alloc(vm, buffer, len); /* copy buffer to dest */ + vm->frames[vm->fp].registers[dest].u = ptr; return true; } case OP_UINT_TO_STRING: { uint32_t a = (uint32_t)vm->frames[vm->fp].registers[src1].u; /* get value */ char buffer[32]; int len = sprintf(buffer, "%d", a); - str_alloc(vm, buffer, len); /* copy buffer to dest */ + uint32_t ptr = str_alloc(vm, buffer, len); /* copy buffer to dest */ + vm->frames[vm->fp].registers[dest].u = ptr; return true; } case OP_REAL_TO_STRING: { float a = (float)vm->frames[vm->fp].registers[src1].f; /* get value */ char buffer[32]; int len = sprintf(buffer, "%f", a); - str_alloc(vm, buffer, len); /* copy buffer to dest */ + uint32_t ptr = str_alloc(vm, buffer, len); /* copy buffer to dest */ + vm->frames[vm->fp].registers[dest].u = ptr; return true; } case OP_READ_STRING: { - uint32_t str_dest = (uint32_t)vm->frames[vm->fp] - .allocated.end; /* get start of unallocated */ - vm->frames[vm->fp].registers[dest].u = - str_dest; /* store ptr of string to dest register */ - uint32_t buffer = str_dest + 1; + uint32_t str_addr = vm->mp++; uint32_t length = 0; - while (1) { - int ch = getchar(); - if (ch == '\n' || ch == EOF) { - vm->memory[buffer + (length / 4)].c[length % 4] = '\0'; - break; - } - vm->memory[buffer + (length / 4)].c[length % 4] = ch; + 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++; } - vm->memory[str_dest].u = length; - vm->frames[vm->fp].allocated.end += - ((length / 4) + (length % 4) + 1); /* increment to end of allocated */ + + 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_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); @@ -349,14 +378,16 @@ bool step_vm(VM *vm) { length; /* increment to end of allocated */ return true; } - case OP_MEM_MOV: + case OP_MEM_MOV: { vm->memory[dest] = vm->memory[src1]; return true; - case OP_MEM_SWAP: + } + case OP_MEM_SWAP: { vm->memory[dest].u ^= vm->memory[src1].u; vm->memory[src1].u ^= vm->memory[dest].u; vm->memory[dest].u ^= vm->memory[src1].u; return true; } + } return false; /* something bad happened */ }