⬅ interpreter.py source

1 from collections import deque
  • F401 'time.sleep' imported but unused
2 from time import sleep
3 from sys import stdin
4 import argparse
5  
6  
7 def encode(s):
8 result = []
9 for x in s:
10 result += [1, 1 if x else 0]
11 return result + [0, 0]
12  
13  
  • E251 Unexpected spaces around keyword / parameter equals (in 2 places)
14 def decode(s, start = 0):
15 result = []
16 i = start
17 while True:
18 pair = (1 if s[i] else 0, 1 if s[i + 1] else 0)
19 assert pair != (0, 1)
20 if pair == (0, 0):
21 return result
22 result.append(pair[1])
23 i += 2
24  
25  
26 def move_left():
27 global current_pos
28 if current_pos == 0:
29 cells.appendleft(0)
30 else:
31 current_pos -= 1
32  
33  
34 def move_right():
35 global current_pos
36 if current_pos == len(cells) - 1:
37 cells.append(0)
38 current_pos += 1
39  
40  
41 def mark():
42 cells[current_pos] = 1
43  
44  
45 def unmark():
46 cells[current_pos] = 0
47  
48  
49 def dump():
50 print(*cells, sep='')
51 print(" " * current_pos + "^")
52  
53  
54 if __name__ == "__main__":
55 parser = argparse.ArgumentParser(description="PTM interpreter")
  • W291 Trailing whitespace
56 parser.add_argument('program', type=argparse.FileType('r'), nargs='*',
  • E501 Line too long (83 > 79 characters)
57 help='file with a PTM program to interpret', default=stdin)
  • E501 Line too long (84 > 79 characters)
58 parser.add_argument('--input', type=str, help='input binary string', default='')
59 args = parser.parse_args()
60  
61 cells = deque(encode([1 if c == "1" else 0 for c in args.input]))
62 current_pos = 0
63 cnt_ops = 0
64  
65 for current_program in args.program:
66 with current_program as program_file:
67 original_lines = program_file.readlines()
68 lines = [line.split("#", 1)[0].split() for line in original_lines]
69  
70 current_line = 0
71 current_cmd = 0
72  
73 while current_line < len(lines):
74 prev_line = current_line
75 # print(original_lines[current_line], end='')
76 move_occured = False
77 while current_cmd < len(lines[current_line]):
78 cmd = lines[current_line][current_cmd]
79 cnt_ops += 1
80 if cmd == "?":
81 assert current_cmd + 2 < len(lines[current_line])
82 arg1 = lines[current_line][current_cmd + 1]
83 arg2 = lines[current_line][current_cmd + 2]
84 move_occured = True
  • E501 Line too long (87 > 79 characters)
85 current_line = (int(arg1) if cells[current_pos] else int(arg2)) - 1
86 current_cmd = 0
87 break
88 if cmd == "1":
89 mark()
90 elif cmd == "0":
91 unmark()
92 elif cmd == "<":
93 move_left()
94 elif cmd == ">":
95 move_right()
96 elif cmd == "!":
97 current_line = len(lines)
98 move_occured = True
99 break
100 current_cmd += 1
101  
102 if lines[prev_line]:
  • E115 Expected an indented block (comment)
103 # dump()
104 pass
105  
106 if move_occured:
107 continue
108  
109 current_line += 1
110 current_cmd = 0
111 # print(*decode(cells, current_pos), sep='')
112  
113  
  • E303 Too many blank lines (2)
114 print(*decode(cells, current_pos), sep='')
115 print(f"Finished in {cnt_ops} operations")