Download tests/test_subleq.py from Snapkitty/semantic-engine: direct link, hf CLI and curl.
- Browser
- Download file 3.64 kB
-
https://huggingface.co/Snapkitty/semantic-engine/resolve/main/tests/test_subleq.py
- Command line
-
hf download hf://Snapkitty/semantic-engine/tests/test_subleq.py
-
curl -L -o test_subleq.py https://huggingface.co/Snapkitty/semantic-engine/resolve/main/tests/test_subleq.py
3.64 kB
| # This Source Code Form is subject to the terms of the Mozilla Public | |
| # License, v. 2.0. If a copy of the MPL was not distributed with this | |
| # file, You can obtain one at https://mozilla.org/MPL/2.0/. | |
| """Tests: Phases 12-13 — SUBLEQ IR and VM.""" | |
| import pytest | |
| from semantic_engine.subleq import ( | |
| SubleqInstruction, SubleqProgram, SubleqMemory, SubleqVM, | |
| HALT_ADDRESS, MAX_MEMORY, | |
| ) | |
| from semantic_engine.types import PipelineError | |
| def halt_prog() -> SubleqProgram: | |
| prog = SubleqProgram() | |
| prog.data[0] = 0 # zero cell | |
| prog.add(SubleqInstruction(A=0, B=0, C=HALT_ADDRESS, comment="HALT")) | |
| return prog | |
| def test_instruction_repr(): | |
| instr = SubleqInstruction(A=1, B=2, C=3) | |
| r = repr(instr) | |
| assert "SUBLEQ" in r | |
| def test_instruction_halt_repr(): | |
| instr = SubleqInstruction(A=0, B=0, C=HALT_ADDRESS) | |
| assert "HALT" in repr(instr) | |
| def test_program_add_and_label(): | |
| prog = SubleqProgram() | |
| prog.add(SubleqInstruction(A=0, B=0, C=HALT_ADDRESS, label="start")) | |
| assert "start" in prog.labels | |
| assert prog.labels["start"] == 0 | |
| def test_program_resolve_label(): | |
| prog = SubleqProgram() | |
| prog.add(SubleqInstruction(A=0, B=0, C=HALT_ADDRESS, label="end")) | |
| assert prog.resolve_label("end") == 0 | |
| def test_program_resolve_missing_label(): | |
| prog = SubleqProgram() | |
| with pytest.raises(PipelineError): | |
| prog.resolve_label("missing") | |
| def test_assemble_disassemble_roundtrip(): | |
| prog = SubleqProgram() | |
| prog.add(SubleqInstruction(A=1, B=2, C=3)) | |
| prog.add(SubleqInstruction(A=4, B=5, C=HALT_ADDRESS)) | |
| binary = prog.assemble() | |
| recovered = SubleqProgram.disassemble(binary) | |
| assert len(recovered.instructions) == 2 | |
| assert recovered.instructions[0].A == 1 | |
| assert recovered.instructions[0].B == 2 | |
| assert recovered.instructions[1].C == HALT_ADDRESS | |
| def test_assemble_bad_alignment(): | |
| with pytest.raises(PipelineError): | |
| SubleqProgram.disassemble(b"\x00\x01\x02\x03") | |
| def test_memory_read_write(): | |
| mem = SubleqMemory() | |
| mem.write(100, 42) | |
| assert mem.read(100) == 42 | |
| def test_memory_out_of_bounds(): | |
| mem = SubleqMemory() | |
| with pytest.raises(PipelineError): | |
| mem.read(MAX_MEMORY + 1) | |
| with pytest.raises(PipelineError): | |
| mem.write(-1, 0) | |
| def test_vm_halts(): | |
| prog = halt_prog() | |
| vm = SubleqVM() | |
| vm.load(prog) | |
| vm.execute() | |
| assert vm.halted | |
| def test_vm_step_returns_false_on_halt(): | |
| prog = halt_prog() | |
| vm = SubleqVM() | |
| vm.load(prog) | |
| while not vm.halted: | |
| result = vm.step() | |
| assert not result | |
| def test_vm_trace_recorded(): | |
| prog = halt_prog() | |
| vm = SubleqVM() | |
| vm.load(prog) | |
| trace = vm.execute() | |
| assert len(trace) >= 1 | |
| assert trace[0].pc >= 0 # PC starts at base offset | |
| def test_vm_max_steps_exceeded(): | |
| prog = SubleqProgram() | |
| # Infinite loop: SUBLEQ 0 0 0 | |
| prog.data[0] = 0 | |
| prog.add(SubleqInstruction(A=0, B=0, C=0)) | |
| vm = SubleqVM(max_steps=10) | |
| vm.load(prog) | |
| with pytest.raises(PipelineError) as exc: | |
| vm.execute() | |
| assert "max" in str(exc.value).lower() or "steps" in str(exc.value).lower() | |
| def test_verify_halts(): | |
| prog = halt_prog() | |
| vm = SubleqVM() | |
| assert vm.verify_halts(prog) | |
| def test_subleq_arithmetic(): | |
| """SUBLEQ(A, B, C): mem[B] -= mem[A]; branch if <=0""" | |
| prog = SubleqProgram() | |
| # Use addresses 10, 11 for data (well below base=100 for instructions) | |
| prog.data[10] = 5 | |
| prog.data[11] = 3 | |
| prog.add(SubleqInstruction(A=10, B=11, C=HALT_ADDRESS)) | |
| vm = SubleqVM() | |
| vm.load(prog) | |
| vm.execute() | |
| assert vm.memory.read(11) == -2 | |