43 lines
1.1 KiB
Crystal
43 lines
1.1 KiB
Crystal
def new_interpreter(f, prog)
|
|
prog = prog.clone
|
|
input = Channel(Int32).new
|
|
output = Channel(Int32?).new
|
|
spawn do
|
|
op = ""
|
|
pc = 0
|
|
arg = ->(i : Int32) { op[-(3+i)] == '0' ? prog[prog[pc+1+i]] : prog[pc+1+i] }
|
|
loop do
|
|
op = "0000" + prog[pc].to_s
|
|
case op
|
|
when .ends_with? "1"
|
|
prog[prog[pc+3]] = arg.call(0) + arg.call(1)
|
|
pc += 4
|
|
when .ends_with? "2"
|
|
prog[prog[pc+3]] = arg.call(0) * arg.call(1)
|
|
pc += 4
|
|
when .ends_with? "3"
|
|
prog[prog[pc+1]] = input.receive
|
|
pc += 2
|
|
when .ends_with? "4"
|
|
output.send(arg.call(0))
|
|
pc += 2
|
|
when .ends_with? "5"
|
|
pc = arg.call(0) != 0 ? arg.call(1) : pc + 3
|
|
when .ends_with? "6"
|
|
pc = arg.call(0) == 0 ? arg.call(1) : pc + 3
|
|
when .ends_with? "7"
|
|
prog[prog[pc+3]] = arg.call(0) < arg.call(1) ? 1 : 0
|
|
pc += 4
|
|
when .ends_with? "8"
|
|
prog[prog[pc+3]] = arg.call(0) == arg.call(1) ? 1 : 0
|
|
pc += 4
|
|
when .ends_with? "99"
|
|
input.receive
|
|
output.send(nil)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
{input, output}
|
|
end
|