mid-kid
5 years ago
2 changed files with 140 additions and 0 deletions
@ -0,0 +1,139 @@ |
|||||
|
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(program) |
@ -0,0 +1 @@ |
|||||
|
1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1102,1,3,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1102,26,1,1005,1101,0,24,1019,1102,1,32,1007,1101,0,704,1027,1102,0,1,1020,1101,0,348,1029,1102,28,1,1002,1101,34,0,1016,1102,29,1,1008,1102,1,30,1013,1102,25,1,1012,1101,0,33,1009,1102,1,37,1001,1101,31,0,1017,1101,245,0,1022,1102,39,1,1000,1101,27,0,1011,1102,770,1,1025,1101,0,22,1015,1102,1,1,1021,1101,711,0,1026,1101,20,0,1004,1101,0,23,1018,1101,242,0,1023,1102,21,1,1003,1101,38,0,1010,1101,0,35,1014,1101,0,36,1006,1101,0,357,1028,1102,1,775,1024,109,-3,2102,1,9,63,1008,63,36,63,1005,63,203,4,187,1105,1,207,1001,64,1,64,1002,64,2,64,109,8,21101,40,0,5,1008,1010,41,63,1005,63,227,1106,0,233,4,213,1001,64,1,64,1002,64,2,64,109,16,2105,1,2,1105,1,251,4,239,1001,64,1,64,1002,64,2,64,109,1,21107,41,40,-4,1005,1018,271,1001,64,1,64,1105,1,273,4,257,1002,64,2,64,109,-18,1207,0,21,63,1005,63,295,4,279,1001,64,1,64,1105,1,295,1002,64,2,64,109,-3,1207,0,36,63,1005,63,311,1105,1,317,4,301,1001,64,1,64,1002,64,2,64,109,6,2108,20,-3,63,1005,63,339,4,323,1001,64,1,64,1106,0,339,1002,64,2,64,109,28,2106,0,-7,4,345,1001,64,1,64,1106,0,357,1002,64,2,64,109,-18,1206,4,373,1001,64,1,64,1105,1,375,4,363,1002,64,2,64,109,-6,2107,31,-4,63,1005,63,397,4,381,1001,64,1,64,1105,1,397,1002,64,2,64,109,1,21102,42,1,-1,1008,1011,39,63,1005,63,421,1001,64,1,64,1106,0,423,4,403,1002,64,2,64,109,-2,2108,26,-2,63,1005,63,439,1106,0,445,4,429,1001,64,1,64,1002,64,2,64,109,6,21102,43,1,-5,1008,1011,43,63,1005,63,467,4,451,1105,1,471,1001,64,1,64,1002,64,2,64,109,6,21101,44,0,-3,1008,1019,44,63,1005,63,493,4,477,1105,1,497,1001,64,1,64,1002,64,2,64,109,-9,1206,7,511,4,503,1105,1,515,1001,64,1,64,1002,64,2,64,109,14,1205,-7,531,1001,64,1,64,1106,0,533,4,521,1002,64,2,64,109,-27,1201,0,0,63,1008,63,39,63,1005,63,555,4,539,1105,1,559,1001,64,1,64,1002,64,2,64,109,10,2101,0,-5,63,1008,63,24,63,1005,63,583,1001,64,1,64,1105,1,585,4,565,1002,64,2,64,109,-11,2107,21,5,63,1005,63,601,1105,1,607,4,591,1001,64,1,64,1002,64,2,64,109,10,1208,0,36,63,1005,63,627,1001,64,1,64,1106,0,629,4,613,1002,64,2,64,109,15,21108,45,45,-9,1005,1015,647,4,635,1105,1,651,1001,64,1,64,1002,64,2,64,109,-19,2101,0,-4,63,1008,63,37,63,1005,63,677,4,657,1001,64,1,64,1106,0,677,1002,64,2,64,109,22,1205,-6,695,4,683,1001,64,1,64,1105,1,695,1002,64,2,64,109,-10,2106,0,10,1001,64,1,64,1105,1,713,4,701,1002,64,2,64,109,-9,1201,-8,0,63,1008,63,36,63,1005,63,733,1105,1,739,4,719,1001,64,1,64,1002,64,2,64,109,7,21107,46,47,0,1005,1015,757,4,745,1106,0,761,1001,64,1,64,1002,64,2,64,109,14,2105,1,-5,4,767,1105,1,779,1001,64,1,64,1002,64,2,64,109,-34,2102,1,6,63,1008,63,39,63,1005,63,799,1105,1,805,4,785,1001,64,1,64,1002,64,2,64,109,25,21108,47,49,-4,1005,1016,825,1001,64,1,64,1106,0,827,4,811,1002,64,2,64,109,-6,1208,-8,36,63,1005,63,845,4,833,1106,0,849,1001,64,1,64,1002,64,2,64,109,-10,1202,2,1,63,1008,63,36,63,1005,63,875,4,855,1001,64,1,64,1105,1,875,1002,64,2,64,109,-5,1202,10,1,63,1008,63,30,63,1005,63,895,1106,0,901,4,881,1001,64,1,64,4,64,99,21101,27,0,1,21101,0,915,0,1105,1,922,21201,1,65916,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21101,942,0,0,1105,1,922,21201,1,0,-1,21201,-2,-3,1,21102,1,957,0,1105,1,922,22201,1,-1,-2,1106,0,968,22102,1,-2,-2,109,-3,2105,1,0 |
Loading…
Reference in new issue