-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcompiler.py
More file actions
113 lines (105 loc) · 3.67 KB
/
compiler.py
File metadata and controls
113 lines (105 loc) · 3.67 KB
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
class block:
def __init__(self,symbol,tokens,asm=""):
self.symbol=symbol
self.tokens=tokens
self.operators=[] #2'nd level of ast
self.operands=[] #3'rd level of ast
self.asm=asm #for asm operators
def astGen(self): #for this operation only
for i in self.tokens:
if i[1]=="symbol":
self.operators.append(i[0])
if i[1]=="constant":
self.operands.append("$"+i[0])
if i[1]=="variable":
if i[0]=="left":
self.operands.append("16(%rsp)")
elif i[0]=="right":
self.operands.append("8(%rsp)")
def asmGen(self):
self.asm+=self.symbol+":\n" #asm function label
self.asm+="movq "+self.operands[0]+", %rbx\n"
self.asm+="movq %rbx, -8(%rsp)\n" #set accum to first operand
for i in range(len(self.operators)):
self.asm+="movq -8(%rsp), %rax\n"
self.asm+="movq %rax, -16(%rsp)\n" #accum passed as left arg
self.asm+="movq "+self.operands[i+1]+", %rax\n"
self.asm+="movq %rax, -24(%rsp)\n"
self.asm+="subq $24, %rsp\n"
self.asm+="call "+self.operators[i]+"\n"
self.asm+="addq $24, %rsp\n"
self.asm+="movq %rax, -8(%rsp)\n" #return value passed to accum
self.asm+="movq -8(%rsp), %rax\n" #accum to return
self.asm+="ret\n"
symbols=["add","sub","ifNegative", "ifPositive"]
keywords=["def","(",")","condition"]
variables=["left","right"]
tokenTypes=[symbols,keywords,variables]
tokenTypeNames=["symbol","keyword","variable"]
source=open("input.txt","r")
sourceStr=source.read()
tokens=[]
asmBlocks=[block("add",None,
"add:\n"+
"movq 16(%rsp), %rbx\n"+
"movq 8(%rsp), %rcx\n"+
"addq %rcx, %rbx\n"+
"movq %rbx, %rax\n"+
"ret\n"
),
block("sub",None,
"sub:\n"+
"movq 16(%rsp), %rbx\n"+
"movq 8(%rsp), %rcx\n"+
"subq %rcx, %rbx\n"+
"movq %rbx, %rax\n"+
"ret\n"
),
block("ifNegative",None,
"ifNegative:\n"+
"movq 16(%rsp), %rbx\n"+
"movq $1, %r9\n"+
"cmp %rbx, %r9\n"+
"jg isFalse\n"+
"movq $0, 24(%rsp)\n"+
"ret\n"+
"isFalse:\n"+
"movq 8(%rsp), %rax\n"+
"addq $32, %rsp\n"+
"ret\n"
),
block("ifPositive",None,
"ifPositive:\n"+
"movq 8(%rsp), %rax\n"+
"ret\n"
)]
#token generation
wordList=sourceStr.split()
for i in wordList:
isSymbol=True
for v in range(len(tokenTypes)):
if i.isnumeric():
tokens.append((i,"constant"))
isSymbol=False
break
if i in tokenTypes[v]:
tokens.append((i,tokenTypeNames[v]))
isSymbol=False
break
if isSymbol:
symbols.append(i)
tokens.append((i,"symbol"))
tokens.append((".","symbol"))
#definition blocks indexes
defPos=[]
for i in range(len(tokens)):
if tokens[i][0]=="def": defPos.append(i)
defPos.append(-1)
#definition blocks
for i in range(len(defPos)-1):
offset=defPos[i]
asmBlocks.append(block(tokens[offset+1][0],tokens[offset+2:defPos[i+1]]))
asmBlocks[-1].astGen()
asmBlocks[-1].asmGen()
print (".global func\n")
for i in asmBlocks: print(i.asm)