-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathto_python.py
149 lines (144 loc) · 6.3 KB
/
to_python.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
def to_python(ast, MAX, OPTIMIZE, logger, size=17**3):
code = '''
from array import array
import sys
stack = []
class InfVector:
def __init__(self):
self.data = dict()
def get(self, key):
new_key = key // SIZE
if new_key in self.data:
return self.data[new_key][1][key % SIZE]
return 17
def set(self, key, value):
new_key = key // SIZE
if new_key in self.data:
if value == 17:
if self.data[new_key][1][key % SIZE] != 17:
self.data[new_key][0] -= 1
if self.data[new_key][0] == 0:
del self.data[new_key]
else:
self.data[new_key][1][key % 4913] = 17
#value, but thats already known
else:
if self.data[new_key][1][key % SIZE] == 17:
self.data[new_key][0] += 1
self.data[new_key][1][key % SIZE] = value
else:
self.data[new_key] = [1, array('Q', [17] * SIZE)]
self.data[new_key][1][key % SIZE] = value
stack = array('Q')
mem = InfVector()
mem.set(0, int('777', 17))
while True:
name = mem.get(0)
'''.replace('SIZE', str(size))
for name in ast:
code += 'if name == %s:\n' % name
for op_type, op in ast[name]:
if OPTIMIZE < 2:
code += '\n{t}# (%s, %s)\n' % (op_type, op)
if op_type == 'INT':
code += '{t}stack.append(%s)\n' % op
elif op_type == 'ADD':
if isinstance(op, int):
code += '{t}stack[-1] = (stack[-1] + '
code += str(op) + ' ) % {MAX}\n'
else:
code += '{t}stack[-2] = (stack[-2] + stack[-1]) % {MAX}\n'
code += '{t}del stack[-1]\n'
elif op_type == 'SUB':
if isinstance(op, int):
code += '{t}stack[-1] = (stack[-1] - '
code += str(op) + ' ) % {MAX}\n'
else:
code += '{t}stack[-2] = (stack[-2] - stack[-1]) % {MAX}\n'
code += '{t}del stack[-1]\n'
elif op_type == 'MUL':
if isinstance(op, int):
code += '{t}stack[-1] = (stack[-1] * '
code += str(op) + ' ) % {MAX}\n'
else:
code += '{t}stack[-2] = (stack[-2] * stack[-1]) % {MAX}\n'
code += '{t}del stack[-1]\n'
elif op_type == 'DIV':
if isinstance(op, int):
if op == 0:
code += '{t}stack[-1] = 17\n'
else:
code += '{t}stack[-1] //= %s\n' % o
else:
code += '{t}try:\n'
code += '{t} {t}stack[-2] = (stack[-2] // stack[-1])\n'
code += '{t}except ZeroDivisionError:\n'
code += '{t} stack[-2] = 17\n'
code += '{t}del stack[-1]\n'
elif op_type == 'STORE':
if isinstance(op, tuple):
code += '{t}mem.set(%s, %s)\n' % (op[1], op[0])
elif isinstance(op, int):
code += '{t}mem.set(%s, stack[-1])\n' % op
code += '{t}del stack[-1]\n'
else:
code += '{t}mem.set(stack[-1], stack[-2])\n'
code += '{t}del stack[-2:]\n'
elif op_type == 'LOAD':
if isinstance(op, int):
code += '{t}stack.append(mem.get(%s))\n' % op
else:
code += '{t}stack.append(mem.get(stack.pop(-1)))\n'
elif op_type == 'DUP':
if isinstance(op, int):
code += '{t}stack.append(%s)\n' % op
else:
code += '{t}stack.append(stack[-1])\n'
elif op_type == 'EQ':
if isinstance(op, int):
code += '{t}stack[-1] = int(stack[-1] == %s)\n' % op
else:
code += '{t}stack[-2] = int(stack[-2] == stack[-1])\n'
code += '{t}del stack[-1]\n'
elif op_type == 'NT':
code += '{t}stack[-1] = int(not stack[-1])\n'
elif op_type == 'GREATER':
if isinstance(op, int):
code += '{t}stack[-1] = int(stack[-1] > %s)\n' % op
else:
code += '{t}stack[-2] = int(stack[-2] > stack[-1])\n'
code += '{t}del stack[-1]\n'
elif op_type == 'LESS':
if isinstance(op, int):
code += '{t}stack[-1] = int(stack[-1] < %s)\n' % op
else:
code += '{t}stack[-2] = int(stack[-2] < stack[-1])\n'
code += '{t}del stack[-1]\n'
elif op_type == 'MOD':
if isinstance(op, int):
code += '{t}stack[-1] = int(stack[-1] %% %s)\n' % op
else:
code += '{t}stack[-2] = int(stack[-2] % stack[-1])\n'
code += '{t}del stack[-1]\n'
elif op_type == 'INPUT':
code += '{t}stack.append(ord(sys.stdin.read(1)))\n'
elif op_type == 'OUTPUT':
if isinstance(op, list):
if op == [ord('\n')]:
code += '{t}print()\n'
elif op[-1:] == [ord('\n')]:
code += '{t}print(%s)\n' % repr(''.join(map(chr, op[:-1])))
else:
code += '{t}print(%s, end="")\n' % repr(''.join(map(chr, op)))
else:
code += '{t}print(chr(stack.pop(-1)), end="")\n'
elif op_type == 'OUTPUT_NUM':
if isinstance(op, int):
code += '{t}print(%s, end="")\n' % op
else:
code += '{t}print(stack.pop(-1), end="")\n'
else:
logger.warning('Unknown op_type:', op_type)
code += ' el'
code += 'se:\n break'
return code.format(MAX=MAX, t=' ' * 8)