From 43ebed65535bebd3789326155a4c1d95d6401147 Mon Sep 17 00:00:00 2001 From: zongor Date: Fri, 29 Aug 2025 22:02:19 -0700 Subject: [PATCH] update to opcodes, go with tunnels and syscals, partial refactor of memory, try out fixed size again --- src/compiler.c | 11 ++- src/compiler.h | 6 +- src/fixed.c | 201 +++++++++++++++++++++++++++++++++++++++++++++++++ src/fixed.h | 55 ++++++++++++++ src/opcodes.h | 148 +++++++++++++++++------------------- src/vm.c | 127 +++++-------------------------- 6 files changed, 355 insertions(+), 193 deletions(-) create mode 100644 src/fixed.c create mode 100644 src/fixed.h diff --git a/src/compiler.c b/src/compiler.c index 18a8753..16cbaf2 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -1,4 +1,5 @@ #include "compiler.h" +#include "vm.h" #include typedef struct { @@ -33,6 +34,8 @@ typedef struct { Parser parser; SymbolTable st; +const char *internalErrorMsg = "FLAGRANT COMPILER ERROR\n\nCompiler over.\nBug = Very Yes."; + void errorAt(Token *token, const char *message) { if (parser.panicMode) return; @@ -99,17 +102,17 @@ void number(VM *vm) { char *endptr; int32_t value = (int32_t)strtol(parser.previous.start, &endptr, 10); emitOp(vm, OP_LOADI, vm->frames[vm->fp].rp++, 0, 0); - vm->code[vm->cp++].i = value; + vm->code[vm->cp++].u = int_alloc(vm, value); return; } else if (parser.previous.type == TOKEN_UINT_LITERAL) { long value = atol(parser.previous.start); emitOp(vm, OP_LOADU, vm->frames[vm->fp].rp++, 0, 0); - vm->code[vm->cp++].u = value; + vm->code[vm->cp++].u = nat_alloc(vm, value); return; } else if (parser.previous.type == TOKEN_FLOAT_LITERAL) { float value = atof(parser.previous.start); emitOp(vm, OP_LOADF, vm->frames[vm->fp].rp++, 0, 0); - vm->code[vm->cp++].f = value; + vm->code[vm->cp++].u = real_alloc(vm, value); return; } errorAtCurrent("Invalid number format"); @@ -128,7 +131,7 @@ void string(VM *vm) { } } vm->frames[vm->fp].allocated.end += length / 4; - emitOp(vm, OP_LOADU, vm->frames[vm->fp].rp++, 0, 0); + emitOp(vm, OP_LOADP, vm->frames[vm->fp].rp++, 0, 0); vm->code[vm->cp++].u = str_addr; } diff --git a/src/compiler.h b/src/compiler.h index 0e7a980..156cb79 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -27,10 +27,8 @@ typedef struct symbol_t { }; int8_t reg; uint8_t flags[3]; /* only use for padding now, might be used later*/ - union { - uint32_t frame; - uint32_t ptr; - }; + uint32_t frame; + uint32_t ptr; } Symbol; #define MODULE_NAME_SIZE 32 diff --git a/src/fixed.c b/src/fixed.c new file mode 100644 index 0000000..47b3b8e --- /dev/null +++ b/src/fixed.c @@ -0,0 +1,201 @@ +/* fixed.c - Q16.16 Fixed-Point Math Implementation */ + +#include "fixed.h" + +/* Conversion functions */ +fixed_t int_to_fixed(int32_t i) { + return i << 16; +} + +int32_t fixed_to_int(fixed_t f) { + return f >> 16; +} + +fixed_t float_to_fixed(float f) { + return (fixed_t)(f * 65536.0f); +} + +float fixed_to_float(fixed_t f) { + return (float)f / 65536.0f; +} + +fixed_t fixed_add(fixed_t a, fixed_t b) { + return a + b; +} + +fixed_t fixed_sub(fixed_t a, fixed_t b) { + return a - b; +} + +fixed_t fixed_mul(fixed_t a, fixed_t b) { + /* Extract high and low parts */ + int32_t a_hi = a >> 16; + uint32_t a_lo = (uint32_t)a & 0xFFFFU; + int32_t b_hi = b >> 16; + uint32_t b_lo = (uint32_t)b & 0xFFFFU; + + /* Compute partial products */ + int32_t p0 = (int32_t)(a_lo * b_lo) >> 16; /* Low * Low */ + int32_t p1 = a_hi * (int32_t)b_lo; /* High * Low */ + int32_t p2 = (int32_t)a_lo * b_hi; /* Low * High */ + int32_t p3 = (a_hi * b_hi) << 16; /* High * High */ + + /* Combine results */ + return p0 + p1 + p2 + p3; +} + +fixed_t fixed_div(fixed_t a, fixed_t b) { + if (b == 0) return 0; /* Handle division by zero */ + + /* Determine sign */ + int negative = ((a < 0) ^ (b < 0)); + + /* Work with absolute values */ + uint32_t ua = (a < 0) ? -a : a; + uint32_t ub = (b < 0) ? -b : b; + + /* Perform division using long division in base 2^16 */ + uint32_t quotient = 0; + uint32_t remainder = 0; + int i; + + for (i = 0; i < 32; i++) { + remainder <<= 1; + if (ua & 0x80000000U) { + remainder |= 1; + } + ua <<= 1; + + if (remainder >= ub) { + remainder -= ub; + quotient |= 1; + } + + if (i < 31) { + quotient <<= 1; + } + } + + return negative ? -(int32_t)quotient : (int32_t)quotient; +} + +int fixed_eq(fixed_t a, fixed_t b) { + return a == b; +} + +int fixed_ne(fixed_t a, fixed_t b) { + return a != b; +} + +int fixed_lt(fixed_t a, fixed_t b) { + return a < b; +} + +int fixed_le(fixed_t a, fixed_t b) { + return a <= b; +} + +int fixed_gt(fixed_t a, fixed_t b) { + return a > b; +} + +int fixed_ge(fixed_t a, fixed_t b) { + return a >= b; +} + +/* Unary operations */ +fixed_t fixed_neg(fixed_t f) { + return -f; +} + +fixed_t fixed_abs(fixed_t f) { + return (f < 0) ? -f : f; +} + +/* Square root using Newton-Raphson method */ +fixed_t fixed_sqrt(fixed_t f) { + if (f <= 0) return 0; + + fixed_t x = f; + fixed_t prev; + + /* Newton-Raphson iteration: x = (x + f/x) / 2 */ + do { + prev = x; + x = fixed_div(fixed_add(x, fixed_div(f, x)), int_to_fixed(2)); + } while (fixed_gt(fixed_abs(fixed_sub(x, prev)), 1)); /* Precision to 1/65536 */ + + return x; +} + +/* Sine function using Taylor series */ +fixed_t fixed_sin(fixed_t f) { + /* Normalize angle to [-π, π] */ + fixed_t pi2 = fixed_mul(FIXED_PI, int_to_fixed(2)); + while (fixed_gt(f, FIXED_PI)) f = fixed_sub(f, pi2); + while (fixed_lt(f, fixed_neg(FIXED_PI))) f = fixed_add(f, pi2); + + /* Taylor series: sin(x) = x - x³/3! + x⁵/5! - x⁷/7! + ... */ + fixed_t result = f; + fixed_t term = f; + fixed_t f_squared = fixed_mul(f, f); + + /* Calculate first few terms for reasonable precision */ + int i; + for (i = 3; i <= 11; i += 2) { + term = fixed_mul(term, f_squared); + term = fixed_div(term, int_to_fixed(i * (i - 1))); + + if ((i / 2) % 2 == 0) { + result = fixed_add(result, term); + } else { + result = fixed_sub(result, term); + } + } + + return result; +} + +/* Cosine function using Taylor series */ +fixed_t fixed_cos(fixed_t f) { + /* cos(x) = 1 - x²/2! + x⁴/4! - x⁶/6! + ... */ + fixed_t result = FIXED_ONE; + fixed_t term = FIXED_ONE; + fixed_t f_squared = fixed_mul(f, f); + + int i; + for (i = 2; i <= 12; i += 2) { + term = fixed_mul(term, f_squared); + term = fixed_div(term, int_to_fixed(i * (i - 1))); + + if ((i / 2) % 2 == 0) { + result = fixed_add(result, term); + } else { + result = fixed_sub(result, term); + } + } + + return result; +} + +/* Tangent function */ +fixed_t fixed_tan(fixed_t f) { + fixed_t cos_val = fixed_cos(f); + if (cos_val == 0) return 0; /* Handle undefined case */ + return fixed_div(fixed_sin(f), cos_val); +} + +/* Utility functions */ +fixed_t fixed_min(fixed_t a, fixed_t b) { + return (a < b) ? a : b; +} + +fixed_t fixed_max(fixed_t a, fixed_t b) { + return (a > b) ? a : b; +} + +fixed_t fixed_clamp(fixed_t f, fixed_t min_val, fixed_t max_val) { + if (f < min_val) return min_val; + if (f > max_val) return max_val; + return f; +} diff --git a/src/fixed.h b/src/fixed.h new file mode 100644 index 0000000..26dbb8b --- /dev/null +++ b/src/fixed.h @@ -0,0 +1,55 @@ +/* fixed.h - Q16.16 Fixed-Point Math Library in C89 */ + +#ifndef FIXED_H +#define FIXED_H + +#include + +/* Q16.16 fixed-point type */ +typedef int32_t fixed_t; + +/* Constants */ +#define FIXED_ONE 0x00010000L /* 1.0 in Q16.16 */ +#define FIXED_ZERO 0x00000000L /* 0.0 in Q16.16 */ +#define FIXED_HALF 0x00008000L /* 0.5 in Q16.16 */ +#define FIXED_PI 0x0003243FL /* π ≈ 3.14159 */ +#define FIXED_E 0x0002B7E1L /* e ≈ 2.71828 */ +#define FIXED_MAX 0x7FFFFFFFL /* Maximum positive value */ +#define FIXED_MIN 0x80000000L /* Minimum negative value */ + +/* Conversion functions */ +fixed_t int_to_fixed(int32_t i); +int32_t fixed_to_int(fixed_t f); +fixed_t float_to_fixed(float f); +float fixed_to_float(fixed_t f); + +/* Basic arithmetic operations */ +fixed_t fixed_add(fixed_t a, fixed_t b); +fixed_t fixed_sub(fixed_t a, fixed_t b); +fixed_t fixed_mul(fixed_t a, fixed_t b); +fixed_t fixed_div(fixed_t a, fixed_t b); + +/* Comparison functions */ +int fixed_eq(fixed_t a, fixed_t b); +int fixed_ne(fixed_t a, fixed_t b); +int fixed_lt(fixed_t a, fixed_t b); +int fixed_le(fixed_t a, fixed_t b); +int fixed_gt(fixed_t a, fixed_t b); +int fixed_ge(fixed_t a, fixed_t b); + +/* Unary operations */ +fixed_t fixed_neg(fixed_t f); +fixed_t fixed_abs(fixed_t f); + +/* Advanced math functions */ +fixed_t fixed_sqrt(fixed_t f); +fixed_t fixed_sin(fixed_t f); /* f in radians */ +fixed_t fixed_cos(fixed_t f); /* f in radians */ +fixed_t fixed_tan(fixed_t f); /* f in radians */ + +/* Utility functions */ +fixed_t fixed_min(fixed_t a, fixed_t b); +fixed_t fixed_max(fixed_t a, fixed_t b); +fixed_t fixed_clamp(fixed_t f, fixed_t min, fixed_t max); + +#endif /* FIXED_H */ diff --git a/src/opcodes.h b/src/opcodes.h index 6cc3380..a2a5a02 100644 --- a/src/opcodes.h +++ b/src/opcodes.h @@ -3,6 +3,67 @@ #include "common.h" +typedef enum { + OP_HALT, /* halt : terminate execution */ + OP_JMP, /* jump : jump to address src1 unconditionally */ + OP_CALL, /* call : creates a new frame */ + OP_RETURN, /* retn : returns from a frame to the parent frame */ + OP_LOAD, /* load : dest = &[next memory location] */ + OP_STORE, /* stor : next memory location = src1 as float */ + OP_PUSH, /* push : push str ref from register onto the stack and copy str */ + OP_POP, /* pop : pop int from stack onto the register */ + OP_REG_MOV, /* rmov : dest = src1 */ + OP_REG_SWAP, /* rswp : dest = src1, src1 = dest */ + OP_MEM_SWAP, /* mswp : &dest = &src1, &src1 = &dest */ + OP_MEM_MOV, /* mmov : &dest = &src1 */ + OP_MEM_ALLOC, /* aloc : dest [next memory location as size] */ + OP_REF, /* ref : dest = &memory[src1] */ + OP_DEREF, /* dref : dest = memory[src1] */ + OP_SYSCALL, /* sysc : */ + OP_ADD_INT, /* addi : dest = src1 + src2 */ + OP_SUB_INT, /* subi : dest = src1 - src2 */ + OP_MUL_INT, /* muli : dest = src1 * src2 */ + OP_DIV_INT, /* divi : dest = src1 / src2 */ + OP_ADD_UINT, /* addu : dest = src1 + src2 */ + OP_SUB_UINT, /* subu : dest = src1 - src2 */ + OP_MUL_UINT, /* mulu : dest = src1 * src2 */ + OP_DIV_UINT, /* divu : dest = src1 / src2 */ + OP_ADD_REAL, /* addr : dest = src1 + src2 */ + OP_SUB_REAL, /* subr : dest = src1 - src2 */ + OP_MUL_REAL, /* mulr : dest = src1 * src2 */ + OP_DIV_REAL, /* divr : dest = src1 / src2 */ + OP_INT_TO_REAL, /* itor : dest = src1 as real */ + OP_UINT_TO_REAL, /* utor : dest = src1 as real */ + OP_REAL_TO_INT, /* rtoi : dest = src1 as int */ + OP_REAL_TO_UINT, /* rtou : dest = src1 as uint */ + OP_JEQ_INT, /* jeqi : jump to address dest if src1 as int == src2 as int */ + OP_JGT_INT, /* jgti : jump to address dest if src1 as int > src2 as int*/ + OP_JLT_INT, /* jlti : jump to address dest if src1 as int < src2 as int */ + OP_JLE_INT, /* jlei : jump to address dest if src1 as int <= src2 as int */ + OP_JGE_INT, /* jgei : jump to address dest if src1 as int >= src2 as int*/ + OP_JEQ_UINT, /* jequ : jump to address dest if src1 as int == src2 as uint */ + OP_JGT_UINT, /* jgtu : jump to address dest if src1 as int > src2 as uint*/ + OP_JLT_UINT, /* jltu : jump to address dest if src1 as int < src2 as uint */ + OP_JLE_UINT, /* jleu : jump to address dest if src1 as int <= src2 as uint */ + OP_JGE_UINT, /* jgeu : jump to address dest if src1 as int >= src2 as uint*/ + OP_JEQ_REAL, /* jeqr : jump to address dest if src1 as real == src2 as real */ + OP_JGE_REAL, /* jgtr : jump to address dest if src1 as real >= src2 as real */ + OP_JGT_REAL, /* jltr : jump to address dest if src1 as real > src2 as real */ + OP_JLT_REAL, /* jler : jump to address dest if src1 as real < src2 as real */ + OP_JLE_REAL, /* jger : jump to address dest if src1 as real <= src2 as real */ + OP_INT_TO_STRING, /* itos : dest = src1 as str */ + OP_UINT_TO_STRING, /* utos : dest = src1 as str */ + OP_REAL_TO_STRING, /* rtos : dest = src1 as str */ + OP_CMP_STRING, /* cmps : dest = (str == src2) as bool */ + OP_STRING_TO_INT, /* stoi : dest = src1 as int */ + OP_STRING_TO_UINT, /* stou : dest = src1 as uint */ + OP_STRING_TO_REAL, /* stor : dest = src1 as real */ +} Opcode; + +/* defines a uint32 opcode */ +#define OP(opcode, dest, src1, src2) \ + ((opcode << 24) | (dest << 16) | (src1 << 8) | src2) + typedef union value_u { int32_t i; /* Integers */ float f; /* Float */ @@ -42,12 +103,21 @@ typedef struct keyboard_t { const uint8_t *keys; } Keyboard; +typedef enum { + SCREEN, + MOUSE, + KEYBOARD, + CONTROLLER, + AUDIO, + TUNNEL, +} Devicecode; + typedef union device_u { uint8_t type; Screen s; Mouse m; Keyboard k; - /* File f; */ + /* Audio a; */ /* Tunnel t; */ } Device; @@ -78,80 +148,4 @@ typedef struct vm_s { Value memory[MEMORY_SIZE]; /* memory block */ } VM; -typedef enum { - OP_HALT, /* halt : terminate execution */ - 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 */ - OP_PUSHI, /* pshi : push int from register onto the stack */ - OP_PUSHU, /* pshu : push uint from register onto the stack */ - OP_PUSHF, /* pshf : push float from register onto the stack */ - OP_PUSHS, /* pshs : push str ref from register onto the stack and copy str */ - OP_POPI, /* popi : pop int from stack onto the register */ - OP_POPU, /* popu : pop uint from stack onto the register */ - OP_POPF, /* popf : pop float from stack onto the register */ - OP_POPS, /* pops : pop str ref from stack and move/copy to register */ - OP_ADD_INT, /* addi : dest = src1 + src2 */ - OP_SUB_INT, /* subi : dest = src1 - src2 */ - OP_MUL_INT, /* muli : dest = src1 * src2 */ - OP_DIV_INT, /* divi : dest = src1 / src2 */ - OP_JEQ_INT, /* jeqi : jump to address dest if src1 as int == src2 as int */ - OP_JGT_INT, /* jgti : jump to address dest if src1 as int > src2 as int*/ - OP_JLT_INT, /* jlti : jump to address dest if src1 as int < src2 as int */ - OP_JLE_INT, /* jlei : jump to address dest if src1 as int <= src2 as int */ - OP_JGE_INT, /* jgei : jump to address dest if src1 as int >= src2 as int*/ - OP_INT_TO_REAL, /* itor : dest = src1 as f32 */ - OP_ADD_UINT, /* addu : dest = src1 + src2 */ - OP_SUB_UINT, /* subu : dest = src1 - src2 */ - OP_MUL_UINT, /* mulu : dest = src1 * src2 */ - OP_DIV_UINT, /* divu : dest = src1 / src2 */ - OP_JEQ_UINT, /* jequ : jump to address dest if src1 as int == src2 as uint */ - OP_JGT_UINT, /* jgtu : jump to address dest if src1 as int > src2 as uint*/ - OP_JLT_UINT, /* jltu : jump to address dest if src1 as int < src2 as uint */ - OP_JLE_UINT, /* jleu : jump to address dest if src1 as int <= src2 as uint */ - OP_JGE_UINT, /* jgeu : jump to address dest if src1 as int >= src2 as uint*/ - OP_UINT_TO_REAL, /* utor : dest = src1 as f32 */ - OP_ADD_REAL, /* addr : dest = src1 + src2 */ - OP_SUB_REAL, /* subr : dest = src1 - src2 */ - OP_MUL_REAL, /* mulr : dest = src1 * src2 */ - OP_DIV_REAL, /* divr : dest = src1 / src2 */ - OP_JEQ_REAL, /* jeqr : jump to address dest if src1 as real == src2 as real */ - OP_JGE_REAL, /* jgtr : jump to address dest if src1 as real >= src2 as real */ - OP_JGT_REAL, /* jltr : jump to address dest if src1 as real > src2 as real */ - OP_JLT_REAL, /* jler : jump to address dest if src1 as real < src2 as real */ - OP_JLE_REAL, /* jger : jump to address dest if src1 as real <= src2 as real */ - OP_REAL_TO_INT, /* rtoi : dest = src1 as int */ - OP_REAL_TO_UINT, /* rtou : dest = src1 as uint */ - OP_REG_MOV, /* rmov : dest = src1 */ - OP_REG_SWAP, /* rswp : dest = src1, src1 = dest */ - OP_JMP, /* jump : jump to address src1 unconditionally */ - OP_CALL, /* call : creates a new frame */ - OP_RETURN, /* retn : returns from a frame to the parent frame */ - OP_INT_TO_STRING, /* itos : dest = src1 as str */ - OP_UINT_TO_STRING, /* utos : dest = src1 as str */ - OP_REAL_TO_STRING, /* rtos : dest = src1 as str */ - OP_READ_STRING, /* gets : dest = gets as str */ - OP_PRINT_STRING, /* puts : write src1 to stdout */ - OP_CMP_STRING, /* cmps : dest = (str == src2) as bool */ - OP_NOT, /* not : dest = not src1 */ - OP_MEM_ALLOC, /* alloc : dest = &ptr */ - OP_MEM_SWAP, /* swap : &dest = &src1, &src1 = &dest */ - OP_MEM_MOV, /* mov : &dest = &src1 */ -} Opcode; - -typedef enum { - SCREEN, - MOUSE, - KEYBOARD, - CONTROLLER, - AUDIO, -} Devicecode; - -/* defines a uint32 opcode */ -#define OP(opcode, dest, src1, src2) ((opcode << 24) | (dest << 16) | (src1 << 8) | src2) - #endif diff --git a/src/vm.c b/src/vm.c index 76e6d2a..0e7cd71 100644 --- a/src/vm.c +++ b/src/vm.c @@ -98,63 +98,22 @@ bool step_vm(VM *vm) { of old slice, pop the frame */ return true; } - case OP_LOADI: { + case OP_LOAD: { uint32_t ptr = vm->code[vm->pc++].u; - int32_t v = vm->memory[ptr].i; - vm->frames[vm->fp].registers[dest].i = v; + vm->frames[vm->fp].registers[dest] = vm->memory[ptr]; return true; } - case OP_LOADU: { + case OP_STORE: { uint32_t ptr = vm->code[vm->pc++].u; - uint32_t v = vm->memory[ptr].u; - vm->frames[vm->fp].registers[dest].u = v; + vm->memory[ptr] = vm->frames[vm->fp].registers[src1]; return true; } - case OP_LOADF: { - uint32_t ptr = vm->code[vm->pc++].u; - float v = vm->memory[ptr].f; - vm->frames[vm->fp].registers[dest].f = v; + case OP_PUSH: { + vm->stack[++vm->sp] = vm->frames[vm->fp].registers[dest]; return true; } - 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: { - vm->memory[vm->code[vm->pc++].u].u = vm->frames[vm->fp].registers[src1].u; - return true; - } - case OP_STOREF: { - 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; - return true; - } - case OP_PUSHU: { - vm->stack[++vm->sp].u = vm->frames[vm->fp].registers[dest].u; - return true; - } - case OP_PUSHF: { - vm->stack[++vm->sp].f = vm->frames[vm->fp].registers[dest].f; - return true; - } - case OP_POPI: { - vm->frames[vm->fp].registers[dest].i = vm->stack[vm->sp--].i; - return true; - } - case OP_POPU: { - vm->frames[vm->fp].registers[dest].u = vm->stack[vm->sp--].u; - return true; - } - case OP_POPF: { - vm->frames[vm->fp].registers[dest].f = vm->stack[vm->sp--].f; + case OP_POP: { + vm->frames[vm->fp].registers[dest] = vm->stack[vm->sp--]; return true; } case OP_ADD_INT: @@ -263,10 +222,6 @@ bool step_vm(VM *vm) { case OP_JLE_REAL: { COMPARE_AND_JUMP(float, u, <=); } - 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]; @@ -291,48 +246,6 @@ bool step_vm(VM *vm) { vm->frames[vm->fp].registers[dest].u = ptr; return true; } - case OP_READ_STRING: { - uint32_t str_addr = vm->mp++; - uint32_t length = 0; - 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++; - } - - 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; - 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]; - if (ch == '\0') - break; - putchar(ch); - } - putchar('\n'); - return true; - } case OP_CMP_STRING: { uint32_t addr1 = (uint32_t)vm->frames[vm->fp].registers[src1].u; uint32_t addr2 = (uint32_t)vm->frames[vm->fp].registers[src2].u; @@ -366,26 +279,24 @@ bool step_vm(VM *vm) { .allocated.end; /* get start of unallocated */ vm->frames[vm->fp].registers[dest].u = mem_dest; /* store ptr of array to dest register */ - uint32_t length = vm->code[vm->pc++].u; - vm->memory[mem_dest].u = length; - if (src1) { /* if has inline data */ - uint32_t i = 0; - for (i = 0; i < length; i++) { - vm->memory[mem_dest + i] = vm->code[vm->pc++]; - } - } + uint32_t size = (uint32_t)vm->frames[vm->fp].registers[src1].u; + vm->memory[mem_dest].u = size; vm->frames[vm->fp].allocated.end += - length; /* increment to end of allocated */ + size; /* increment to end of allocated */ return true; } case OP_MEM_MOV: { - vm->memory[dest] = vm->memory[src1]; + uint32_t dest_addr = (uint32_t)vm->frames[vm->fp].registers[dest].u; + uint32_t src_addr = (uint32_t)vm->frames[vm->fp].registers[src1].u; + vm->memory[dest_addr] = vm->memory[src_addr]; return true; } 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; + uint32_t dest_addr = (uint32_t)vm->frames[vm->fp].registers[dest].u; + uint32_t src_addr = (uint32_t)vm->frames[vm->fp].registers[src1].u; + vm->memory[dest_addr].u ^= vm->memory[src_addr].u; + vm->memory[src_addr].u ^= vm->memory[dest_addr].u; + vm->memory[dest_addr].u ^= vm->memory[src_addr].u; return true; } }