2020-12-07 02:36:36 -08:00
|
|
|
def new_interpreter(f, p)
|
|
|
|
prog = {} of Int64 => Int64
|
|
|
|
p.each_with_index do |v, i|
|
|
|
|
prog[i.to_i64] = v.to_i64
|
|
|
|
end
|
|
|
|
|
|
|
|
input = Channel(Int64).new
|
|
|
|
output = Channel(Int64?).new
|
2020-12-04 18:17:39 -08:00
|
|
|
spawn do
|
|
|
|
op = ""
|
2020-12-07 02:36:36 -08:00
|
|
|
pc = 0_i64
|
|
|
|
base = 0_i64
|
|
|
|
index = ->(i : Int32) {
|
|
|
|
case op[-(3+i)]
|
|
|
|
when '0'
|
|
|
|
prog[pc+1+i]
|
|
|
|
when '1'
|
|
|
|
pc+1+i
|
|
|
|
else
|
|
|
|
prog[pc+1+i] + base
|
|
|
|
end
|
|
|
|
}
|
|
|
|
get = ->(i : Int32) { prog[index.call(i)]? || 0_i64 }
|
|
|
|
set = ->(i : Int32, v : Int64) { prog[index.call(i)] = v }
|
2020-12-04 18:17:39 -08:00
|
|
|
loop do
|
|
|
|
op = "0000" + prog[pc].to_s
|
|
|
|
case op
|
|
|
|
when .ends_with? "1"
|
2020-12-07 02:36:36 -08:00
|
|
|
set.call(2, get.call(0) + get.call(1))
|
2020-12-04 18:17:39 -08:00
|
|
|
pc += 4
|
|
|
|
when .ends_with? "2"
|
2020-12-07 02:36:36 -08:00
|
|
|
set.call(2, get.call(0) * get.call(1))
|
2020-12-04 18:17:39 -08:00
|
|
|
pc += 4
|
|
|
|
when .ends_with? "3"
|
2020-12-07 02:36:36 -08:00
|
|
|
set.call(0, input.receive)
|
2020-12-04 18:17:39 -08:00
|
|
|
pc += 2
|
|
|
|
when .ends_with? "4"
|
2020-12-07 02:36:36 -08:00
|
|
|
output.send(get.call(0))
|
2020-12-04 18:17:39 -08:00
|
|
|
pc += 2
|
|
|
|
when .ends_with? "5"
|
2020-12-07 02:36:36 -08:00
|
|
|
pc = get.call(0) != 0 ? get.call(1) : pc + 3
|
2020-12-04 18:17:39 -08:00
|
|
|
when .ends_with? "6"
|
2020-12-07 02:36:36 -08:00
|
|
|
pc = get.call(0) == 0 ? get.call(1) : pc + 3
|
2020-12-04 18:17:39 -08:00
|
|
|
when .ends_with? "7"
|
2020-12-07 02:36:36 -08:00
|
|
|
set.call(2, get.call(0) < get.call(1) ? 1_i64 : 0_i64)
|
2020-12-04 18:17:39 -08:00
|
|
|
pc += 4
|
|
|
|
when .ends_with? "8"
|
2020-12-07 02:36:36 -08:00
|
|
|
set.call(2, get.call(0) == get.call(1) ? 1_i64 : 0_i64)
|
2020-12-04 18:17:39 -08:00
|
|
|
pc += 4
|
|
|
|
when .ends_with? "99"
|
|
|
|
input.receive
|
|
|
|
output.send(nil)
|
|
|
|
break
|
2020-12-07 02:36:36 -08:00
|
|
|
when .ends_with? "9"
|
|
|
|
base += get.call(0)
|
|
|
|
pc += 2
|
2020-12-04 18:17:39 -08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
{input, output}
|
|
|
|
end
|