|
|
|
function get_arg(mem, pos, arg)
|
|
|
|
local param_mode = mem[pos] // (10 ^ (arg + 1)) % 10
|
|
|
|
if #mem < pos + arg then
|
|
|
|
print(string.format("Error: Opcode too short at end of memory: %d", pos))
|
|
|
|
os.exit(false)
|
|
|
|
end
|
|
|
|
local arg = mem[pos + arg]
|
|
|
|
if param_mode == 0 then
|
|
|
|
arg = arg + 1
|
|
|
|
if #mem < arg then
|
|
|
|
print(string.format("Error: Memory offset out of bounds: %d", arg))
|
|
|
|
os.exit(false)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return arg
|
|
|
|
end
|
|
|
|
|
|
|
|
function get_param(mem, pos, arg)
|
|
|
|
local param_mode = mem[pos] // (10 ^ (arg + 1)) % 10
|
|
|
|
local arg = get_arg(mem, pos, arg)
|
|
|
|
if param_mode == 0 then
|
|
|
|
return mem[arg]
|
|
|
|
end
|
|
|
|
return arg
|
|
|
|
end
|
|
|
|
|
|
|
|
function interpret(mem)
|
|
|
|
local pos = 1
|
|
|
|
while true do
|
|
|
|
if #mem < pos then
|
|
|
|
print(string.format("Instruction pointer ran off of memory"))
|
|
|
|
os.exit(false)
|
|
|
|
end
|
|
|
|
|
|
|
|
local opcode = mem[pos] % 100
|
|
|
|
|
|
|
|
if opcode == 1 then
|
|
|
|
mem[get_arg(mem, pos, 3)] = get_param(mem, pos, 1) + get_param(mem, pos, 2)
|
|
|
|
pos = pos + 4
|
|
|
|
elseif opcode == 2 then
|
|
|
|
mem[get_arg(mem, pos, 3)] = get_param(mem, pos, 1) * get_param(mem, pos, 2)
|
|
|
|
pos = pos + 4
|
|
|
|
elseif opcode == 3 then
|
|
|
|
io.stdout:write("> ")
|
|
|
|
mem[get_arg(mem, pos, 1)] = io.stdin:read("n")
|
|
|
|
pos = pos + 2
|
|
|
|
elseif opcode == 4 then
|
|
|
|
io.stdout:write(get_param(mem, pos, 1))
|
|
|
|
io.stdout:write("\n")
|
|
|
|
pos = pos + 2
|
|
|
|
elseif opcode == 5 then
|
|
|
|
if get_param(mem, pos, 1) ~= 0 then
|
|
|
|
pos = get_param(mem, pos, 2) + 1
|
|
|
|
else
|
|
|
|
pos = pos + 3
|
|
|
|
end
|
|
|
|
elseif opcode == 6 then
|
|
|
|
if get_param(mem, pos, 1) == 0 then
|
|
|
|
pos = get_param(mem, pos, 2) + 1
|
|
|
|
else
|
|
|
|
pos = pos + 3
|
|
|
|
end
|
|
|
|
elseif opcode == 7 then
|
|
|
|
mem[get_arg(mem, pos, 3)] = get_param(mem, pos, 1) < get_param(mem, pos, 2) and 1 or 0
|
|
|
|
pos = pos + 4
|
|
|
|
elseif opcode == 8 then
|
|
|
|
mem[get_arg(mem, pos, 3)] = get_param(mem, pos, 1) == get_param(mem, pos, 2) and 1 or 0
|
|
|
|
pos = pos + 4
|
|
|
|
elseif opcode == 99 then
|
|
|
|
return
|
|
|
|
else
|
|
|
|
print(string.format("Error: Invalid opcode %d at %d", opcode, pos - 1))
|
|
|
|
os.exit(false)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
file = io.open(arg[1])
|
|
|
|
memory = {}
|
|
|
|
for num in string.gmatch(file:read(), "(-?%d+),?") do
|
|
|
|
table.insert(memory, tonumber(num))
|
|
|
|
end
|
|
|
|
file:close()
|
|
|
|
|
|
|
|
interpret(memory)
|