comparison python/c3/codegenerator.py @ 222:c3f1ce8b638f

Fixup of parser
author Windel Bouwman
date Tue, 09 Jul 2013 17:36:31 +0200
parents 848c4b15fd0b
children 1c7364bd74c7
comparison
equal deleted inserted replaced
221:848c4b15fd0b 222:c3f1ce8b638f
1 import ir 1 import ir
2 from . import astnodes 2 from . import astnodes
3 from .scope import boolType 3 from .scope import boolType, intType
4 from ppci import CompilerError 4 from ppci import CompilerError
5 5
6 class CodeGenerator: 6 class CodeGenerator:
7 """ Generates intermediate code from a package """ 7 """ Generates intermediate code from a package """
8 def gencode(self, pkg): 8 def gencode(self, pkg):
15 self.genModule(pkg) 15 self.genModule(pkg)
16 return m 16 return m
17 17
18 # inner helpers: 18 # inner helpers:
19 def genModule(self, pkg): 19 def genModule(self, pkg):
20 # Take care of forward declarations: 20 # Take care of forward declarations:
21 for s in pkg.innerScope.Functions: 21 for s in pkg.innerScope.Functions:
22 f = self.builder.newFunction(s.name) 22 f = self.builder.newFunction(s.name)
23 self.funcMap[s] = f 23 self.funcMap[s] = f
24 for s in pkg.innerScope: 24 for s in pkg.innerScope:
25 if type(s) is astnodes.Variable: 25 if type(s) is astnodes.Variable:
26 v = self.builder.newVariable(s.name) 26 v = self.builder.newVariable(s.name)
27 #self.builder.addIns(ir.Alloc(v)) 27 #self.builder.addIns(ir.Alloc(v))
28 self.varMap[s] = v 28 self.varMap[s] = v
29 elif type(s) is astnodes.Function: 29 elif type(s) is astnodes.Function:
48 self.builder.setFunction(None) 48 self.builder.setFunction(None)
49 else: 49 else:
50 print(s) 50 print(s)
51 51
52 def genCode(self, code): 52 def genCode(self, code):
53 if type(code) is astnodes.CompoundStatement: 53 assert isinstance(code, astnodes.Statement)
54 if type(code) is astnodes.CompoundStatement:
54 for s in code.statements: 55 for s in code.statements:
55 self.genCode(s) 56 self.genCode(s)
56 elif type(code) is astnodes.Assignment: 57 elif type(code) is astnodes.Assignment:
57 re = self.genExprCode(code.rval) 58 re = self.genExprCode(code.rval)
58 # TODO: Handle pointers 59 # TODO: Handle pointers
59 loc = self.genExprCode(code.lval) 60 loc = self.genExprCode(code.lval)
60 # determine location of variable 61 # determine location of variable
61 self.builder.addIns(ir.Store(loc, re)) 62 self.builder.addIns(ir.Store(loc, re))
62 elif type(code) is astnodes.IfStatement: 63 elif type(code) is astnodes.ExpressionStatement:
64 self.genExprCode(code.ex)
65 elif type(code) is astnodes.IfStatement:
63 bbtrue = self.builder.newBB() 66 bbtrue = self.builder.newBB()
64 bbfalse = self.builder.newBB() 67 bbfalse = self.builder.newBB()
65 te = self.builder.newBB() 68 te = self.builder.newBB()
66 self.genCondCode(code.condition, bbtrue, bbfalse) 69 self.genCondCode(code.condition, bbtrue, bbfalse)
67 self.builder.setBB(bbtrue) 70 self.builder.setBB(bbtrue)
69 self.builder.addIns(ir.Branch(te)) 72 self.builder.addIns(ir.Branch(te))
70 self.builder.setBB(bbfalse) 73 self.builder.setBB(bbfalse)
71 self.genCode(code.falsestatement) 74 self.genCode(code.falsestatement)
72 self.builder.addIns(ir.Branch(te)) 75 self.builder.addIns(ir.Branch(te))
73 self.builder.setBB(te) 76 self.builder.setBB(te)
74 elif type(code) is astnodes.EmptyStatement: 77 elif type(code) is astnodes.EmptyStatement:
75 pass 78 pass
76 elif type(code) is astnodes.ReturnStatement: 79 elif type(code) is astnodes.ReturnStatement:
77 if code.expr: 80 if code.expr:
78 re = self.genExprCode(code.expr) 81 re = self.genExprCode(code.expr)
79 self.builder.addIns(ir.Return(re)) 82 self.builder.addIns(ir.Return(re))
80 else: 83 else:
81 self.builder.addIns(ir.Return()) 84 self.builder.addIns(ir.Return())
82 elif type(code) is astnodes.WhileStatement: 85 elif type(code) is astnodes.WhileStatement:
83 bbdo = self.builder.newBB() 86 bbdo = self.builder.newBB()
84 bbtest = self.builder.newBB() 87 bbtest = self.builder.newBB()
85 te = self.builder.newBB() 88 te = self.builder.newBB()
86 self.builder.addIns(ir.Branch(bbtest)) 89 self.builder.addIns(ir.Branch(bbtest))
87 self.builder.setBB(bbtest) 90 self.builder.setBB(bbtest)
88 self.genCondCode(code.condition, bbdo, te) 91 self.genCondCode(code.condition, bbdo, te)
89 self.builder.setBB(bbdo) 92 self.builder.setBB(bbdo)
90 self.genCode(code.statement) 93 self.genCode(code.statement)
91 self.builder.addIns(ir.Branch(bbtest)) 94 self.builder.addIns(ir.Branch(bbtest))
92 self.builder.setBB(te) 95 self.builder.setBB(te)
93 else: 96 else:
94 print('Unknown stmt:', code) 97 print('Unknown stmt:', code)
95 def genCondCode(self, expr, bbtrue, bbfalse): 98 def genCondCode(self, expr, bbtrue, bbfalse):
96 # Implement sequential logical operators 99 # Implement sequential logical operators
97 assert expr.typ == boolType 100 assert expr.typ == boolType
98 if type(expr) is astnodes.Binop: 101 if type(expr) is astnodes.Binop:
136 print('Unknown {0}'.format(expr)) 139 print('Unknown {0}'.format(expr))
137 tmp = self.builder.newTmp() 140 tmp = self.builder.newTmp()
138 # TODO 141 # TODO
139 return tmp 142 return tmp
140 elif type(expr) is astnodes.Unop: 143 elif type(expr) is astnodes.Unop:
144 ra = self.genExprCode(expr.a)
141 if expr.op == '&': 145 if expr.op == '&':
142 # Address of operator 146 # Address of operator
143 ra = self.genExprCode(expr.a)
144 tmp = self.builder.newTmp('addr') 147 tmp = self.builder.newTmp('addr')
145 return tmp 148 return tmp
146 #self.builder.addIns(ins) 149 #self.builder.addIns(ins)
150 elif expr.op == '*':
151 # dereference pointer type:
152 tmp = self.builder.newTmp('deref')
153 ins = ir.Load(ra, tmp)
154 self.builder.addIns(ins)
155 return tmp
147 else: 156 else:
148 print('Unknown {0}'.format(expr)) 157 print('Unknown {0}'.format(expr))
149 elif type(expr) is astnodes.Constant: 158 elif type(expr) is astnodes.Constant:
150 tmp = self.builder.newTmp() 159 tmp = self.builder.newTmp()
151 # TODO 160 # TODO
159 elif type(expr) is astnodes.Literal: 168 elif type(expr) is astnodes.Literal:
160 tmp = self.builder.newTmp() 169 tmp = self.builder.newTmp()
161 ins = ir.ImmLoad(tmp, expr.val) 170 ins = ir.ImmLoad(tmp, expr.val)
162 self.builder.addIns(ins) 171 self.builder.addIns(ins)
163 return tmp 172 return tmp
173 elif type(expr) is astnodes.TypeCast:
174 ar = self.genExprCode(expr.a)
175 if isinstance(expr.to_type, astnodes.PointerType):
176 if expr.a.typ is intType:
177 return ar
178 elif isinstance(expr.a.typ, astnodes.PointerType):
179 return ar
180 else:
181 raise Exception()
164 elif type(expr) is astnodes.FunctionCall: 182 elif type(expr) is astnodes.FunctionCall:
165 tmp = self.builder.newTmp("res") 183 tmp = self.builder.newTmp("res")
166 args = [] 184 args = []
167 for arg in expr.args: 185 for arg in expr.args:
168 ar = self.genExprCode(arg) 186 ar = self.genExprCode(arg)