mirror of
https://github.com/allaunthefox/SilverSight.git
synced 2026-07-31 01:25:21 +00:00
Python port rewritten to match spec: - Added Q0_16, PUSH_Q0, PUSH_BOOL as separate opcodes - Added V6 comparison (lt_q16_v6) - Added floor division (Lean Int.ediv) - Added stack depth limit (AVM_MAX_STACK = 1024) - Added type checking in exec_prim - All 10 tests passing Go AVM port: added test_avm_test.go with 8 test cases Milestone: Python → ✅, Go → 🔄
131 lines
3.8 KiB
Matlab
131 lines
3.8 KiB
Matlab
% AVM ISA v1 — Octave Port (Strict Functional Execution)
|
|
% All functions are pure (no global mutation).
|
|
|
|
Q16_SCALE = 65536;
|
|
|
|
function r = q16_mul(a, b)
|
|
r = int32((int64(a) * int64(b)) / Q16_SCALE);
|
|
end
|
|
|
|
function r = q16_div(a, b)
|
|
if b == 0, error("div by zero"); end
|
|
r = int32((int64(a) * Q16_SCALE) / int64(b));
|
|
end
|
|
|
|
% ── Constructors ──────────────────────────────────
|
|
function v = make_q16(x)
|
|
v.ty = 'q16'; v.val = int32(x);
|
|
end
|
|
function v = make_bool(x)
|
|
v.ty = 'bool'; v.val = int32(x);
|
|
end
|
|
function i = make_instr(op, arg)
|
|
i.op = int8(op); i.arg = int32(arg);
|
|
end
|
|
|
|
% ── Instructions ──────────────────────────────────
|
|
function i = push_q16(x); i = make_instr(0, x); end
|
|
function i = push_bool(x); i = make_instr(1, x); end
|
|
function i = pop(); i = make_instr(2, 0); end
|
|
function i = dup(); i = make_instr(3, 0); end
|
|
function i = swap(); i = make_instr(4, 0); end
|
|
function i = load(x); i = make_instr(5, x); end
|
|
function i = store(x); i = make_instr(6, x); end
|
|
function i = jump(x); i = make_instr(7, x); end
|
|
function i = jump_if(x); i = make_instr(8, x); end
|
|
function i = prim(x); i = make_instr(9, x); end
|
|
function i = halt(); i = make_instr(10, 0); end
|
|
|
|
% Primitives
|
|
PRIM_ADD=0; PRIM_SUB=1; PRIM_MUL=2; PRIM_DIV=3;
|
|
PRIM_LT=4; PRIM_EQ=5; PRIM_AND=6; PRIM_OR=7; PRIM_NOT=8;
|
|
|
|
% ── State ─────────────────────────────────────────
|
|
function s = new_state(n)
|
|
s.pc = 1;
|
|
s.stack = cell(1024, 1); s.sp = 0;
|
|
s.locals = cell(n, 1);
|
|
s.halted = false;
|
|
end
|
|
|
|
function s = state_push(s, v)
|
|
s.sp = s.sp + 1;
|
|
s.stack{s.sp} = v;
|
|
end
|
|
|
|
function [v, s] = state_pop(s)
|
|
v = s.stack{s.sp};
|
|
s.sp = s.sp - 1;
|
|
end
|
|
|
|
% ── Step ──────────────────────────────────────────
|
|
function ns = step(state, prog)
|
|
ns = state;
|
|
if ns.halted, return; end
|
|
if ns.pc < 1 || ns.pc > length(prog)
|
|
ns.halted = true; return;
|
|
end
|
|
|
|
instr = prog{ns.pc};
|
|
|
|
switch instr.op
|
|
case 0 % push_q16
|
|
ns = state_push(ns, make_q16(instr.arg));
|
|
case 1 % push_bool
|
|
ns = state_push(ns, make_bool(instr.arg));
|
|
case 2 % pop
|
|
[~, ns] = state_pop(ns);
|
|
case 3 % dup
|
|
ns = state_push(ns, ns.stack{ns.sp});
|
|
case 4 % swap
|
|
[a, ns] = state_pop(ns); [b, ns] = state_pop(ns);
|
|
ns = state_push(ns, a); ns = state_push(ns, b);
|
|
case 5 % load
|
|
ns = state_push(ns, ns.locals{instr.arg + 1});
|
|
case 6 % store
|
|
[v, ns] = state_pop(ns);
|
|
ns.locals{instr.arg + 1} = v;
|
|
case 7 % jump
|
|
ns.pc = instr.arg; return;
|
|
case 8 % jump_if
|
|
[v, ns] = state_pop(ns);
|
|
if v.val != 0, ns.pc = instr.arg; end
|
|
case 9 % prim
|
|
arity = 2;
|
|
if instr.arg == PRIM_NOT, arity = 1; end
|
|
if arity >= 2, [b, ns] = state_pop(ns); end
|
|
[a, ns] = state_pop(ns);
|
|
switch instr.arg
|
|
case PRIM_ADD
|
|
r = make_q16(a.val + b.val);
|
|
case PRIM_SUB
|
|
r = make_q16(a.val - b.val);
|
|
case PRIM_MUL
|
|
r = make_q16(q16_mul(a.val, b.val));
|
|
case PRIM_DIV
|
|
r = make_q16(q16_div(a.val, b.val));
|
|
case PRIM_LT
|
|
r = make_bool(a.val < b.val);
|
|
case PRIM_EQ
|
|
r = make_bool(a.val == b.val);
|
|
case PRIM_AND
|
|
r = make_bool(a.val && b.val);
|
|
case PRIM_OR
|
|
r = make_bool(a.val || b.val);
|
|
case PRIM_NOT
|
|
r = make_bool(a.val == 0);
|
|
end
|
|
ns = state_push(ns, r);
|
|
case 10 % halt
|
|
ns.halted = true;
|
|
end
|
|
ns.pc = ns.pc + 1;
|
|
end
|
|
|
|
function s = run(init, prog, fuel)
|
|
s = init;
|
|
for i = 1:fuel
|
|
if s.halted, break; end
|
|
s = step(s, prog);
|
|
end
|
|
end
|