You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							85 lines
						
					
					
						
							2.5 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							85 lines
						
					
					
						
							2.5 KiB
						
					
					
				| 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)
 | |
| 
 |