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