-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path17.py
94 lines (86 loc) · 3.1 KB
/
17.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
import argparse
import re
import to_python
import optimize
import verify
import logger
FUNCTIONS = '([0-9a-g]+) ?{([^}]*)}'
MAX = 2**64
def parse(code):
ast = {}
for name, data in re.findall(FUNCTIONS, code):
if name in ast:
print('Duplicate function:', name)
exit()
name = int(name, 17)
ops = []
for op in re.findall('([\S]+)', data):
if re.fullmatch('[0-9a-g]+', op):
ops.append(('INT', int(op, 17) % MAX))
elif re.fullmatch(r'\+', op):
ops.append(('ADD', op))
elif re.fullmatch(r'\-', op):
ops.append(('SUB', op))
elif re.fullmatch(r'\*', op):
ops.append(('MUL', op))
elif re.fullmatch(r'\/', op):
ops.append(('DIV', op))
elif re.fullmatch(r'\@', op):
ops.append(('STORE', op))
elif re.fullmatch(r'\#', op):
ops.append(('LOAD', op))
elif re.fullmatch(r':', op):
ops.append(('DUP', op))
elif re.fullmatch(r'==', op):
ops.append(('EQ', op))
elif re.fullmatch(r'!', op):
ops.append(('NT', op))
elif re.fullmatch(r'>', op):
ops.append(('GREATER', op))
elif re.fullmatch(r'<', op):
ops.append(('LESS', op))
elif re.fullmatch(r'\%', op):
ops.append(('MOD', op))
elif re.fullmatch(r'I', op):
ops.append(('INPUT', op))
elif re.fullmatch(r'\$', op):
ops.append(('OUTPUT', op))
elif re.fullmatch(r'\$\$', op):
ops.append(('OUTPUT_NUM', op))
else:
print('Unknown OP:', op)
if ops:
ast[name] = ops
return ast
def main():
parser = argparse.ArgumentParser()
parser.add_argument('file', help='Code file for 17')
parser.add_argument('-o', '--output', default='output')
parser.add_argument('-t', '--target', help='Target language',
default='python')
parser.add_argument('-O', '--optimize', type=int, default=1)
parser.add_argument('-v', '--verbose', type=int, default=0)
args = parser.parse_args()
LOGGER = logger.Logger(level=args.verbose)
with open(args.file) as file:
code = file.read()
ast = parse(code)
LOGGER.info('Parsed')
result = verify.verify_stack_size(ast, MAX, LOGGER)
if result:
LOGGER.error('Not enought items in stack for op (%s) in function %s'
% result)
exit(1)
LOGGER.info('Verified')
ast = optimize.optimize(ast, MAX, args.optimize, LOGGER)
LOGGER.info('Optimized')
if args.target == 'python':
output = to_python.to_python(ast, MAX, args.optimize, LOGGER)
else:
LOGGER.error('Unknown language')
exit(1)
LOGGER.info('Compiled')
with open(args.output, 'w') as file:
file.write(output)
if __name__ == '__main__':
main()