var NOP = 0 var LDA = 1 var STA = 2 var ADD = 3 var SUB = 4 var BRZ = 5 var JMP = 6 var STP = 7 var ops = {"NOP": NOP, "LDA": LDA, "STA": STA, "ADD": ADD, "SUB": SUB, "BRZ": BRZ, "JMP": JMP, "STP": STP} var load = Fn.new { |prog| var mem = List.filled(32, 0) var lines = prog.trimEnd().split("\n") for (i in 0...lines.count) { var line = lines[i].trim() var split = line.split(" ") var instr = split[0] var addr = 0 if (split.count == 2) addr = Num.fromString(split[1]) if (ops[instr]) { mem[i] = ops[instr] * 32 + addr } else { var v = Num.fromString(instr) if (v) mem[i] = v } } return mem } var output = Fn.new { |acc| System.print(acc) } var interp = Fn.new { |prog| var acc = 0 var pc = 0 var mem = load.call(prog) while (true) { var instr = mem[pc] >> 5 var addr = mem[pc] % 32 pc = pc + 1 if (instr == LDA) { acc = mem[addr] } else if (instr == STA) { mem[addr] = acc } else if (instr == ADD) { acc = acc + mem[addr] if (acc > 255) acc = acc - 256 } else if (instr == SUB) { acc = acc - mem[addr] if (acc < 0) acc = acc + 256 } else if (instr == BRZ) { if (acc == 0) pc = addr } else if (instr == JMP) { pc = addr } if (instr == STP || pc > 31) break } output.call(acc) } var progs = [ """ LDA 3 ADD 4 STP 2 2 """, """ LDA 12 ADD 10 STA 12 LDA 11 SUB 13 STA 11 BRZ 8 JMP 0 LDA 12 STP 8 7 0 1 """, """ LDA 14 STA 15 ADD 13 STA 14 LDA 15 STA 13 LDA 16 SUB 17 BRZ 11 STA 16 JMP 0 LDA 14 STP 1 1 0 8 1 """, """ LDA 13 ADD 15 STA 5 ADD 16 STA 7 NOP STA 14 NOP BRZ 11 STA 15 JMP 0 LDA 14 STP LDA 0 0 28 1 6 0 2 26 5 20 3 30 1 22 4 24 """, """ 0 0 STP NOP LDA 3 SUB 29 BRZ 18 LDA 3 STA 29 BRZ 14 LDA 1 ADD 31 STA 1 JMP 2 LDA 0 ADD 31 STA 0 JMP 2 LDA 3 STA 29 LDA 0 ADD 30 ADD 3 STA 0 LDA 1 ADD 30 ADD 3 STA 1 JMP 2 0 1 3 """ ] for (prog in progs) interp.call(prog)