forked from IUCompilerCourse/python-student-support-code
-
Notifications
You must be signed in to change notification settings - Fork 0
/
convert_x86.py
58 lines (51 loc) · 1.88 KB
/
convert_x86.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
# Convert from the x86 AST classes defined in utils.py into the parse
# tree format used by the interpreter.
from ast import Constant, Name
from lark import Tree
from utils import GlobalValue, label_name
from x86_ast import *
def convert_int(value):
return Tree("int_a", [value])
# if value >= 0:
# return Tree("int_a", [value])
# else:
# return Tree("neg_a", [Tree("int_a", [-value])])
def convert_arg(arg):
match arg:
case Reg(id):
return Tree('reg_a', [id])
case Variable(id):
return Tree('var_a', [id])
case Immediate(value):
return convert_int(value)
case Deref(reg, offset):
return Tree('mem_a', [convert_int(offset), reg])
case ByteReg(id):
return Tree('reg_a', [id])
case GlobalValue(id):
return Tree('global_val_a', [id, 'rip'])
case _:
raise Exception('convert_arg: unhandled ' + repr(arg))
def convert_instr(instr):
match instr:
case Instr(instr, args):
return Tree(instr, [convert_arg(arg) for arg in args])
case Callq(func, args):
return Tree('callq', [func])
case Jump(label):
return Tree('jmp', [label])
case JumpIf(cc, label):
return Tree('j' + cc, [label])
case _:
raise Exception('error in convert_instr, unhandled ' + repr(instr))
def convert_program(p):
if isinstance(p.body, list):
main_instrs = [convert_instr(instr) for instr in p.body]
main_block = Tree('block', [label_name('main')] + main_instrs)
return Tree('prog', [main_block])
elif isinstance(p.body, dict):
blocks = []
for (l, ss) in p.body.items():
blocks.append(Tree('block',
[l] + [convert_instr(instr) for instr in ss]))
return Tree('prog', blocks)