sequence/bin/main.ml

205 lines
5.1 KiB
OCaml

open Sequence
let example_program =
[|
Instr.PUSH (Instr.Int 5);
Instr.PUSH (Instr.Int 3);
Instr.ADD;
Instr.DUP;
Instr.PUSH (Instr.Int 2);
Instr.MUL;
Instr.ADD;
Instr.HALT;
|]
let arithmetic_program =
[|
Instr.PUSH (Instr.Int 10);
Instr.PUSH (Instr.Int 7);
Instr.SUB;
Instr.PUSH (Instr.Int 2);
Instr.MUL;
Instr.HALT;
|]
let conditional_program =
[|
Instr.PUSH (Instr.Int 5);
Instr.PUSH (Instr.Int 3);
Instr.LT;
Instr.JMP_IF 2;
Instr.PUSH (Instr.Int 100);
Instr.JMP 1;
Instr.PUSH (Instr.Int 200);
Instr.HALT;
|]
let comparison_program =
[|
Instr.PUSH (Instr.Int 10);
Instr.PUSH (Instr.Int 5);
Instr.GT;
Instr.PUSH (Instr.Int 5);
Instr.PUSH (Instr.Int 10);
Instr.LE;
Instr.AND;
Instr.HALT;
|]
let division_program =
[|
Instr.PUSH (Instr.Int 20);
Instr.PUSH (Instr.Int 4);
Instr.DIV;
Instr.PUSH (Instr.Int 3);
Instr.MOD;
Instr.HALT;
|]
let stack_ops_program =
[|
Instr.PUSH (Instr.Int 1);
Instr.PUSH (Instr.Int 2);
Instr.PUSH (Instr.Int 3);
Instr.ROT;
Instr.SWAP;
Instr.OVER;
Instr.ADD;
Instr.HALT;
|]
let logical_program =
[|
Instr.PUSH (Instr.Bool true);
Instr.PUSH (Instr.Bool false);
Instr.OR;
Instr.PUSH (Instr.Bool true);
Instr.AND;
Instr.NOT;
Instr.HALT;
|]
let negation_program =
[|
Instr.PUSH (Instr.Int 42);
Instr.NEG;
Instr.PUSH (Instr.Int 10);
Instr.ADD;
Instr.HALT;
|]
let closure_program =
[|
Instr.PUSH (Instr.Int 100);
Instr.MK_CLOSURE 10;
Instr.CALL;
Instr.HALT;
Instr.PUSH (Instr.Int 200);
Instr.RET;
|]
let exception_program =
[|
Instr.TRY 3;
Instr.PUSH (Instr.Int 42);
Instr.PUSH (Instr.Int 0);
Instr.DIV;
Instr.HALT;
Instr.POP;
Instr.PUSH (Instr.Int 999);
Instr.HALT;
|]
let complex_program =
[|
Instr.PUSH (Instr.Int 15);
Instr.PUSH (Instr.Int 3);
Instr.DIV;
Instr.DUP;
Instr.PUSH (Instr.Int 2);
Instr.MUL;
Instr.SWAP;
Instr.ADD;
Instr.PUSH (Instr.Int 10);
Instr.GT;
Instr.JMP_IF 2;
Instr.PUSH (Instr.Int 0);
Instr.JMP 1;
Instr.PUSH (Instr.Int 1);
Instr.HALT;
|]
let run_test name program expected =
Printf.printf "Test: %s\n" name;
match Vm.execute_program program with
| Vm.Success (Some (Instr.Int result)) ->
if result = expected then
Printf.printf " ✓ Pass: %d (expected %d)\n\n" result expected
else
Printf.printf " ✗ Fail: got %d, expected %d\n\n" result expected
| Vm.Success (Some (Instr.Bool result)) ->
Printf.printf " Result: %b\n\n" result
| Vm.Success None ->
Printf.printf " ✗ Fail: No result\n\n"
| Vm.Failure e ->
Printf.printf " ✗ Error: %s\n\n" (State.show_error e)
let run_trace_test name program =
Printf.printf "Trace test: %s\n" name;
let result, trace = Vm.execute_with_trace program in
(match result with
| Vm.Success (Some (Instr.Int n)) ->
Printf.printf " Result: %d\n" n
| Vm.Success (Some (Instr.Bool b)) ->
Printf.printf " Result: %b\n" b
| Vm.Success None ->
Printf.printf " Result: None\n"
| Vm.Failure e ->
Printf.printf " Error: %s\n" (State.show_error e));
Printf.printf " Trace entries: %d\n" (List.length trace);
if List.length trace > 0 then
(let last = List.hd (List.rev trace) in
Printf.printf " Final: pc=%d, stack_len=%d, cont_depth=%d\n"
last.Trampoline.pc last.Trampoline.stack_len last.Trampoline.cont_depth);
Printf.printf "\n"
let () =
run_test "Basic arithmetic" example_program 24;
run_test "Subtraction and multiplication" arithmetic_program 6;
run_test "Conditional branching" conditional_program 200;
run_test "Comparison operations" comparison_program 1;
run_test "Division and modulo" division_program 2;
run_test "Stack operations" stack_ops_program 5;
run_test "Logical operations" logical_program 0;
run_test "Negation" negation_program (-32);
run_test "Complex expression" complex_program 1;
let invalid_jump = [|
Instr.PUSH (Instr.Int 1);
Instr.JMP 1000;
Instr.HALT;
|] in
let errors = Vm.validate invalid_jump in
Printf.printf "Invalid jump validation: %d errors found\n" (List.length errors);
List.iter (fun (pc, err) ->
Printf.printf " PC %d: %s\n" pc (State.show_error err))
errors;
Printf.printf "\n";
let disasm = Vm.disassemble example_program in
List.iter (fun (pc, instr) ->
Printf.printf " %d: %s\n" pc instr)
disasm;
Printf.printf "\n";
run_trace_test "Traced execution" arithmetic_program;
match Vm.execute_program exception_program with
| Vm.Success (Some (Instr.Int n)) ->
Printf.printf "Exception caught, result: %d\n" n
| Vm.Success None ->
Printf.printf "Exception caught, no result\n"
| Vm.Failure e ->
Printf.printf "Exception not caught: %s\n" (State.show_error e);
Printf.printf "\n"