mid-kid
5 years ago
2 changed files with 144 additions and 0 deletions
@ -0,0 +1,143 @@ |
|||
function get_param(state, arg) |
|||
local param_mode = state.mem[state.pos] // (10 ^ (arg + 1)) % 10 |
|||
if #state.mem < state.pos + arg then |
|||
print(string.format("Error: Opcode too short at end of memory: %d", state.pos)) |
|||
os.exit(false) |
|||
end |
|||
local arg = state.mem[state.pos + arg] |
|||
if param_mode == 0 then |
|||
arg = arg + 1 |
|||
elseif param_mode == 2 then |
|||
arg = arg + state.relbase |
|||
end |
|||
return arg |
|||
end |
|||
|
|||
function read_mem(state, arg) |
|||
local param_mode = state.mem[state.pos] // (10 ^ (arg + 1)) % 10 |
|||
local arg = get_param(state, arg) |
|||
if param_mode == 1 then |
|||
return arg |
|||
end |
|||
arg = state.mem[arg] |
|||
if not arg then |
|||
return 0 |
|||
end |
|||
return arg |
|||
end |
|||
|
|||
function write_mem(state, arg, val) |
|||
local param_mode = state.mem[state.pos] // (10 ^ (arg + 1)) % 10 |
|||
local arg = get_param(state, arg) |
|||
if param_mode == 1 then |
|||
print(string.format("Error: Invalid inmediate write: %d", arg)) |
|||
end |
|||
state.mem[arg] = val |
|||
end |
|||
|
|||
function interpret(state) |
|||
if not state.mem then |
|||
state.mem = state |
|||
end |
|||
if not state.pos then |
|||
state.pos = 1 |
|||
state.relbase = 1 |
|||
end |
|||
if not state.input then |
|||
state.input = input_stdin |
|||
end |
|||
if not state.output then |
|||
state.output = output_stdout |
|||
end |
|||
|
|||
while true do |
|||
if #state.mem < state.pos then |
|||
print(string.format("Instruction pointer ran off of memory")) |
|||
os.exit(false) |
|||
end |
|||
|
|||
local opcode = state.mem[state.pos] % 100 |
|||
local instr_size = 1 |
|||
|
|||
if opcode == 1 then |
|||
write_mem(state, 3, read_mem(state, 1) + read_mem(state, 2)) |
|||
instr_size = 4 |
|||
elseif opcode == 2 then |
|||
write_mem(state, 3, read_mem(state, 1) * read_mem(state, 2)) |
|||
instr_size = 4 |
|||
elseif opcode == 3 then |
|||
local val = state.input() |
|||
if not val then return true end |
|||
write_mem(state, 1, val) |
|||
instr_size = 2 |
|||
elseif opcode == 4 then |
|||
state.output(read_mem(state, 1)) |
|||
instr_size = 2 |
|||
elseif opcode == 5 then |
|||
instr_size = 3 |
|||
if read_mem(state, 1) ~= 0 then |
|||
state.pos = read_mem(state, 2) + 1 |
|||
instr_size = 0 |
|||
end |
|||
elseif opcode == 6 then |
|||
instr_size = 3 |
|||
if read_mem(state, 1) == 0 then |
|||
state.pos = read_mem(state, 2) + 1 |
|||
instr_size = 0 |
|||
end |
|||
elseif opcode == 7 then |
|||
write_mem(state, 3, read_mem(state, 1) < read_mem(state, 2) and 1 or 0) |
|||
instr_size = 4 |
|||
elseif opcode == 8 then |
|||
write_mem(state, 3, read_mem(state, 1) == read_mem(state, 2) and 1 or 0) |
|||
instr_size = 4 |
|||
elseif opcode == 9 then |
|||
state.relbase = state.relbase + read_mem(state, 1) |
|||
instr_size = 2 |
|||
elseif opcode == 99 then |
|||
return false |
|||
else |
|||
print(string.format("Error: Invalid opcode %d at %d", opcode, state.pos - 1)) |
|||
os.exit(false) |
|||
end |
|||
|
|||
state.pos = state.pos + instr_size |
|||
end |
|||
end |
|||
|
|||
function input_stdin() |
|||
io.stdout:write("> ") |
|||
return io.stdin:read("n") |
|||
end |
|||
|
|||
function output_stdout(val) |
|||
io.stdout:write(val) |
|||
io.stdout:write("\n") |
|||
end |
|||
|
|||
function input_array(array) |
|||
function inner() |
|||
return table.remove(array, 1) |
|||
end |
|||
return inner |
|||
end |
|||
|
|||
function output_array(array) |
|||
function inner(val) |
|||
table.insert(array, val) |
|||
end |
|||
return inner |
|||
end |
|||
|
|||
file = io.open(arg[1]) |
|||
program = {} |
|||
for num in string.gmatch(file:read(), "(-?%d+),?") do |
|||
table.insert(program, tonumber(num)) |
|||
end |
|||
file:close() |
|||
|
|||
interpret({mem=program, output=function(val) |
|||
io.stdout:write(string.char(val)) |
|||
end, input=function() |
|||
return string.byte(io.stdin:read(1)) |
|||
end}) |
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue