-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompiler.py
177 lines (165 loc) · 5 KB
/
compiler.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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import re
pp=0
symbols = {}
symbols_extern = {}
loopend = []
startif = []
def convtoassembly(files):
code = []
variable_code = []
cc=1 #for generating individual
pp=1
loopcount=0
ifcount=0
assign=re.compile('var(.*?)=(.*)') #assigning regular expressions
ext=re.compile('extern (.*)') #.*? means the first occurence of ( .(anything) *(any number of times) )
arith=re.compile('(.*?)=(.*?)[\+\-\&\|](.*?)')
arith_add=re.compile('(.*?)=(.*?)\+(.*)')
arith_sub=re.compile('(.*?)=(.*?)\-(.*)')
arith_or=re.compile('(.*?)=(.*?)\|(.*)')
arith_and=re.compile('(.*?)=(.*?)\&(.*)')
for filen in files:
f=open(filen,'r')
data=f.read() #reading file
f.close()
filename=filen.split('.')[0] #get filename
symbols[filename]= {} #dictionary with symbol of each file
symbols_extern[filename]= {} #dictionary with external symbol of each file
lines=data.splitlines() #splitting in lines
for line in lines:
line=line.strip() #remove extra white space
if assign.match(line): #if line matches var assign
asign=line[3:] #remove var part
a=re.search(r'(.*?)=(.*)',asign)
vari = a.group(1).strip() #takes out variable
val = a.group(2).strip() #takes out value
variable_code.append([vari,val])
symbols[filename][vari] = 0
pp += 0
elif ext.match(line):
var=line[6:].strip()
symbols_extern[filename][var]='extern'+var
elif arith.match(line):
a=re.search(r'(.*?)=(.*?)[\+\-\&\|](.*)',line)
if arith_add.match(line):
op='ADD '
opi='ADI '
elif arith_sub.match(line):
op='SUB '
opi='SUI '
elif arith_and.match(line):
op='ANA '
opi='ANI '
elif arith_or.match(line):
op='ORA '
opi='ORI '
vari = a.group(1).strip()
var1 = a.group(2).strip()
var2 = a.group(3).strip()
if var1.isdigit() and var2.isdigit():
code.append('MVI Areg, '+var1+'\n')
code.append(opi+var2+'\n')
code.append('STA '+vari+'\n')
pp += 3
elif var1.isdigit():
code.append('LDA '+var2+'\n')
code.append('MOV Breg, Areg\n')
code.append('MVI Areg, '+var1+'\n')
code.append(op+'Breg\n')
code.append('STA '+vari+'\n')
pp += 5
elif var2.isdigit():
code.append('LDA '+var1+'\n')
code.append(opi+var2+'\n')
code.append('STA '+vari+'\n')
pp += 3
else:
code.append('LDA '+var2+'\n')
code.append('MOV Breg, Areg\n')
code.append('LDA '+var1+'\n')
code.append(op+'Breg\n')
code.append('STA '+vari+'\n')
pp += 4
elif line.startswith('loop'):
loopcount+=1
a=re.search(r'loop(.*)',line)
count=a.group(1).strip()
code.append('L'+str(loopcount)+' '+'PUSH Dreg\n') #for nested loops
code.append('MVI Ereg, '+count+'\n')
symbols[filename]['L'+str(loopcount)] = pp
pp += 2
loopend.append(loopcount)
elif line.startswith('endloop'):
code.append('MOV Areg, Ereg\n')
code.append('SUI 1\n')
code.append('MOV Ereg, Areg\n')
code.append('JNZ '+'L'+str(loopend.pop())+'\n')
code.append('POP Dreg'+'\n')
pp += 5
elif line.startswith('if'):
a=re.search(r'if(.*?)\((.*?)\)',line) #if (condn)
cond = a.group(2)
if '>' in cond:
ifcount+=1
a=re.search(r'(.*?)>(.*)',cond)
var1 = a.group(1).strip()
var2 = a.group(2).strip()
code.append('I'+str(ifcount)+' '+'LDA '+var1+'\n')
code.append('MOV Breg, Areg\n')
code.append('LDA '+var2+'\n')
code.append('SUB Breg\n')
startif.append(ifcount)
code.append('JP P'+str(ifcount)+'\n')
code.append('JZ P'+str(ifcount)+'\n')
symbols[filename]['I'+str(ifcount)] = pp
pp += 6
elif '=' in cond:
ifcount+=1
a=re.search(r'(.*?)=(.*)',cond)
var1 = a.group(1).strip()
var2 = a.group(2).strip()
code.append('LDA '+var1+'\n')
code.append('MOV Breg, Areg\n')
code.append('LDA '+var2+'\n')
code.append('SUB Breg\n')
startif.append(ifcount)
code.append('JNZ P'+str(ifcount)+'\n')
symbols[filename]['I'+str(ifcount)] = pp
pp += 5
elif line.startswith('endif'):
currif=str(startif.pop())
code.append('P'+currif+' PASS \n')
symbols[filename]['P'+currif] = pp
pp+=1
else:
a=re.search(r'(.*?)=(.*)',line)
var=a.group(1).strip()
val=a.group(2).strip()
if val.isdigit():
code.append('MVI Areg, '+val+'\n')
code.append('STA '+var+'\n')
pp += 2
else:
code.append('LDA '+val+'\n')
code.append('STA '+var+'\n')
pp += 2
#finding values for each variable for symbol table
for val in variable_code:
code.append(val[0]+' '+'DC '+val[1]+'\n')
symbols[filename][val[0]] =pp
pp+=1
####
variable_code=[]
code.append('\n \n \n')
code.append('HLT\n')
filename='concatenated'
f=open(filename+'.link','w')
f.write(''.join(code))
f.close()
f=open(filename+'.assemble','w')
f.write(''.join(code))# join concatenates list items to a string
f.close()
print filename+'.assemble file generated.'
print(symbols)
print(symbols_extern)
return symbols