Mercurial > lcfOS
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) |