import unittest from beamboot.two_layer_cpu import TwoLayerCPU from beamboot.large_cpu import LargeCPU, LargeRuntime class TwoLayerCPUTests(unittest.TestCase): def test_compiled_address_and_transition(self): program = [('LDI', 7), ('STORE', 3), ('LDI', 2), ('ADDM', 3), ('STORE', 4), ('LOAD', 3), ('OUT', 0), ('LOAD', 4), ('OUT', 0), ('SUB', 9), ('JZ', 12), ('HALT', 0), ('HALT', 0)] actual, ref = TwoLayerCPU(program), LargeRuntime(LargeCPU(program)) for _ in range(30): result, expected = actual.step(), ref.step() self.assertEqual(result, expected) if result.halt: break self.assertTrue(actual.halted) def test_rom_is_not_read_by_host_after_compilation(self): program = [('LDI', 11), ('STORE', 8), ('LDI', 0), ('LOAD', 8), ('OUT', 0), ('HALT', 0)] machine = TwoLayerCPU(program) machine.program = None output = [] for _ in range(10): step = machine.step() if step.output: output.append(step.acc) if step.halt: break self.assertEqual(output, [11]) self.assertTrue(machine.halted) def test_boot_and_commands(self): from beamboot.os import OperatingMonitor machine = OperatingMonitor(backend='two-layer') self.assertEqual(machine.boot(), 'BEAM>\n') self.assertEqual(machine.version(), 'BEAMBOOT 0.1\n') self.assertEqual(machine.add(7, 8), 15) self.assertEqual(machine.add(15, 3), 2) def test_seeded_programs_against_python_interpreter(self): import random rng = random.Random(519) ops = ('LDI', 'ADD', 'SUB', 'LOAD', 'STORE', 'ADDM', 'SUBM', 'OUT') for _ in range(3): program = [(rng.choice(ops), rng.randrange(16)) for _ in range(50)] + [('HALT', 0)] machine = TwoLayerCPU(program) machine.program = None ram, acc = [0] * 16, 0 for pc, (op, arg) in enumerate(program): step = machine.step() if op == 'LDI': acc = arg elif op == 'ADD': acc = (acc + arg) & 15 elif op == 'SUB': acc = (acc - arg) & 15 elif op == 'LOAD': acc = ram[arg] elif op == 'STORE': ram[arg] = acc elif op == 'ADDM': acc = (acc + ram[arg]) & 15 elif op == 'SUBM': acc = (acc - ram[arg]) & 15 self.assertEqual((step.pc, step.acc), (pc if op == 'HALT' else pc + 1, acc)) self.assertEqual((step.write, step.output, step.halt), (op == 'STORE', op == 'OUT', op == 'HALT')) if step.write: self.assertEqual((step.address, step.value), (arg, acc))