Mercurial > lcfOS
comparison python/ppci/c3/codegenerator.py @ 306:b145f8e6050b
Start on c3 rewrite
author | Windel Bouwman |
---|---|
date | Mon, 09 Dec 2013 19:00:21 +0100 |
parents | 0615b5308710 |
children | e609d5296ee9 |
comparison
equal
deleted
inserted
replaced
305:0615b5308710 | 306:b145f8e6050b |
---|---|
1 import logging | 1 import logging |
2 from .. import ir | 2 from .. import ir |
3 from . import astnodes | 3 from . import astnodes |
4 from .scope import boolType, intType | |
5 from ppci import CompilerError | 4 from ppci import CompilerError |
6 from .analyse import theType | 5 from .analyse import theType |
7 | 6 |
8 | 7 |
9 class CodeGenerator(ir.Builder): | 8 class CodeGenerator(ir.Builder): |
41 | 40 |
42 def genFunction(self, fn): | 41 def genFunction(self, fn): |
43 # TODO: handle arguments | 42 # TODO: handle arguments |
44 f = self.funcMap[fn] | 43 f = self.funcMap[fn] |
45 f.return_value = self.newTemp() | 44 f.return_value = self.newTemp() |
46 # TODO reserve room for stack, this can be done at later point? | |
47 self.setFunction(f) | 45 self.setFunction(f) |
48 l2 = self.newBlock() | 46 l2 = self.newBlock() |
49 self.emit(ir.Jump(l2)) | 47 self.emit(ir.Jump(l2)) |
50 self.setBlock(l2) | 48 self.setBlock(l2) |
51 # generate room for locals: | 49 # generate room for locals: |
75 assert isinstance(code, astnodes.Statement) | 73 assert isinstance(code, astnodes.Statement) |
76 self.setLoc(code.loc) | 74 self.setLoc(code.loc) |
77 if type(code) is astnodes.CompoundStatement: | 75 if type(code) is astnodes.CompoundStatement: |
78 for s in code.statements: | 76 for s in code.statements: |
79 self.genCode(s) | 77 self.genCode(s) |
78 elif type(code) is astnodes.EmptyStatement: | |
79 pass | |
80 elif type(code) is astnodes.Assignment: | 80 elif type(code) is astnodes.Assignment: |
81 rval = self.genExprCode(code.rval) | 81 rval = self.genExprCode(code.rval) |
82 lval = self.genExprCode(code.lval) | 82 lval = self.genExprCode(code.lval) |
83 self.emit(ir.Move(lval, rval)) | 83 self.emit(ir.Move(lval, rval)) |
84 elif type(code) is astnodes.ExpressionStatement: | 84 elif type(code) is astnodes.ExpressionStatement: |
90 self.genCondCode(code.condition, bbtrue, bbfalse) | 90 self.genCondCode(code.condition, bbtrue, bbfalse) |
91 self.setBlock(bbtrue) | 91 self.setBlock(bbtrue) |
92 self.genCode(code.truestatement) | 92 self.genCode(code.truestatement) |
93 self.emit(ir.Jump(te)) | 93 self.emit(ir.Jump(te)) |
94 self.setBlock(bbfalse) | 94 self.setBlock(bbfalse) |
95 if code.falsestatement: | 95 self.genCode(code.falsestatement) |
96 self.genCode(code.falsestatement) | |
97 self.emit(ir.Jump(te)) | 96 self.emit(ir.Jump(te)) |
98 self.setBlock(te) | 97 self.setBlock(te) |
99 elif type(code) is astnodes.ReturnStatement: | 98 elif type(code) is astnodes.ReturnStatement: |
100 assert code.expr | |
101 re = self.genExprCode(code.expr) | 99 re = self.genExprCode(code.expr) |
102 self.emit(ir.Move(self.fn.return_value, re)) | 100 self.emit(ir.Move(self.fn.return_value, re)) |
103 self.emit(ir.Jump(self.fn.epiloog)) | 101 self.emit(ir.Jump(self.fn.epiloog)) |
104 b = self.newBlock() | 102 b = self.newBlock() |
105 self.setBlock(b) | 103 self.setBlock(b) |
117 else: | 115 else: |
118 raise NotImplementedError('Unknown stmt {}'.format(code)) | 116 raise NotImplementedError('Unknown stmt {}'.format(code)) |
119 | 117 |
120 def genCondCode(self, expr, bbtrue, bbfalse): | 118 def genCondCode(self, expr, bbtrue, bbfalse): |
121 # Implement sequential logical operators | 119 # Implement sequential logical operators |
122 assert expr.typ == boolType | |
123 if type(expr) is astnodes.Binop: | 120 if type(expr) is astnodes.Binop: |
124 if expr.op == 'or': | 121 if expr.op == 'or': |
125 l2 = self.newBlock() | 122 l2 = self.newBlock() |
126 self.genCondCode(expr.a, bbtrue, l2) | 123 self.genCondCode(expr.a, bbtrue, l2) |
127 self.setBlock(l2) | 124 self.setBlock(l2) |
178 elif type(expr) is astnodes.TypeCast: | 175 elif type(expr) is astnodes.TypeCast: |
179 # TODO: improve this mess: | 176 # TODO: improve this mess: |
180 ar = self.genExprCode(expr.a) | 177 ar = self.genExprCode(expr.a) |
181 tt = theType(expr.to_type) | 178 tt = theType(expr.to_type) |
182 if isinstance(tt, astnodes.PointerType): | 179 if isinstance(tt, astnodes.PointerType): |
183 if expr.a.typ is intType: | 180 if expr.a.typ is expr.scope['int']: |
184 return ar | 181 return ar |
185 elif isinstance(expr.a.typ, astnodes.PointerType): | 182 elif isinstance(expr.a.typ, astnodes.PointerType): |
186 return ar | 183 return ar |
187 else: | 184 else: |
188 raise Exception() | 185 raise Exception() |