/* AVM ISA v1 — C Port (Strict Functional Execution) */ #include #include #define Q16_SCALE 65536 #define AVM_Q0_MIN (-32767) #define AVM_Q0_MAX 32767 #define AVM_Q16_MIN (-2147483648) #define AVM_Q16_MAX 2147483647 /* ── Types ─────────────────────────────────────── */ typedef enum { VAL_Q0, VAL_Q16, VAL_BOOL } ValType; typedef struct { ValType ty; int32_t val; } AvmVal; AvmVal avm_q0(int32_t x) { if (x < AVM_Q0_MIN) x = AVM_Q0_MIN; if (x > AVM_Q0_MAX) x = AVM_Q0_MAX; return (AvmVal){VAL_Q0, x}; } AvmVal avm_q16(int32_t x) { return (AvmVal){VAL_Q16, x}; } AvmVal avm_bool(bool x) { return (AvmVal){VAL_BOOL, x ? 1 : 0}; } /* ── Primitives ─────────────────────────────────── */ typedef enum { PRIM_ADD_Q16, PRIM_SUB_Q16, PRIM_MUL_Q16, PRIM_DIV_Q16, PRIM_LT_Q16, PRIM_EQ_Q16, PRIM_AND, PRIM_OR, PRIM_NOT } Prim; typedef struct { AvmVal *data; int len, cap; } Stack; typedef struct { AvmVal *data; int len; } Locals; typedef struct State { int pc; Stack stack; Locals locals; int halted; } State; int64_t q16_mul(int32_t a, int32_t b) { return (int64_t)a * (int64_t)b / Q16_SCALE; } int64_t q16_div(int32_t a, int32_t b) { if (b == 0) return AVM_Q16_MAX; return (int64_t)a * Q16_SCALE / b; } /* ── Instr ──────────────────────────────────────── */ typedef enum { INSTR_PUSH_Q16, INSTR_PUSH_BOOL, INSTR_POP, INSTR_DUP, INSTR_SWAP, INSTR_LOAD, INSTR_STORE, INSTR_JUMP, INSTR_JUMP_IF, INSTR_PRIM, INSTR_HALT } InstrOp; typedef struct { InstrOp op; int32_t arg; int arg2; } Instr; Instr i_push_q16(int32_t x) { return (Instr){INSTR_PUSH_Q16, x, 0}; } Instr i_push_bool(int x) { return (Instr){INSTR_PUSH_BOOL, x, 0}; } Instr i_pop(void) { return (Instr){INSTR_POP, 0, 0}; } Instr i_dup(void) { return (Instr){INSTR_DUP, 0, 0}; } Instr i_swap(void) { return (Instr){INSTR_SWAP, 0, 0}; } Instr i_load(int i) { return (Instr){INSTR_LOAD, i, 0}; } Instr i_store(int i) { return (Instr){INSTR_STORE, i, 0}; } Instr i_jump(int t) { return (Instr){INSTR_JUMP, t, 0}; } Instr i_jump_if(int t) { return (Instr){INSTR_JUMP_IF, t, 0}; } Instr i_prim(Prim p) { return (Instr){INSTR_PRIM, p, 0}; } Instr i_halt(void) { return (Instr){INSTR_HALT, 0, 0}; } /* ── Step ───────────────────────────────────────── */ int step(State *s, Instr *prog, int prog_len) { if (s->halted) return -1; if (s->pc < 0 || s->pc >= prog_len) { s->halted = 1; return 0; } Instr instr = prog[s->pc]; s->pc++; AvmVal a, b; switch (instr.op) { case INSTR_PUSH_Q16: s->stack.data[s->stack.len++] = avm_q16(instr.arg); break; case INSTR_PUSH_BOOL: s->stack.data[s->stack.len++] = avm_bool(instr.arg); break; case INSTR_POP: s->stack.len--; break; case INSTR_DUP: s->stack.data[s->stack.len] = s->stack.data[s->stack.len - 1]; s->stack.len++; break; case INSTR_SWAP: { AvmVal t = s->stack.data[s->stack.len - 1]; s->stack.data[s->stack.len - 1] = s->stack.data[s->stack.len - 2]; s->stack.data[s->stack.len - 2] = t; break; } case INSTR_LOAD: s->stack.data[s->stack.len++] = s->locals.data[instr.arg]; break; case INSTR_STORE: s->locals.data[instr.arg] = s->stack.data[--s->stack.len]; break; case INSTR_JUMP: s->pc = instr.arg; break; case INSTR_JUMP_IF: if (s->stack.data[--s->stack.len].val) s->pc = instr.arg; break; case INSTR_PRIM: { int arity = (instr.arg == PRIM_NOT) ? 1 : 2; if (arity == 2) b = s->stack.data[--s->stack.len]; a = s->stack.data[--s->stack.len]; switch (instr.arg) { case PRIM_ADD_Q16: s->stack.data[s->stack.len++] = avm_q16(a.val + b.val); break; case PRIM_SUB_Q16: s->stack.data[s->stack.len++] = avm_q16(a.val - b.val); break; case PRIM_MUL_Q16: s->stack.data[s->stack.len++] = avm_q16(q16_mul(a.val, b.val)); break; case PRIM_DIV_Q16: s->stack.data[s->stack.len++] = avm_q16(q16_div(a.val, b.val)); break; case PRIM_LT_Q16: s->stack.data[s->stack.len++] = avm_bool(a.val < b.val); break; case PRIM_EQ_Q16: s->stack.data[s->stack.len++] = avm_bool(a.val == b.val); break; case PRIM_AND: s->stack.data[s->stack.len++] = avm_bool(a.val && b.val); break; case PRIM_OR: s->stack.data[s->stack.len++] = avm_bool(a.val || b.val); break; case PRIM_NOT: s->stack.data[s->stack.len++] = avm_bool(!a.val); break; } break; } case INSTR_HALT: s->halted = 1; break; } return 0; } int run(State *s, Instr *prog, int prog_len, int fuel) { for (int i = 0; i < fuel && !s->halted; i++) if (step(s, prog, prog_len)) return -1; return 0; }