Mercurial > lcfOS
comparison python/c3/codegenerator.py @ 228:7f18ed9b6b7e
Removal of emptystatement class
author | Windel Bouwman |
---|---|
date | Sat, 13 Jul 2013 11:12:24 +0200 |
parents | 82dfe6a32717 |
children | 88a1e0baef65 |
comparison
equal
deleted
inserted
replaced
227:82dfe6a32717 | 228:7f18ed9b6b7e |
---|---|
1 import ir | 1 import ir |
2 from . import astnodes | 2 from . import astnodes |
3 from .scope import boolType, intType | 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): |
9 assert type(pkg) is astnodes.Package | 9 assert type(pkg) is astnodes.Package |
10 self.varMap = {} # Maps variables to storage locations. | 10 self.varMap = {} # Maps variables to storage locations. |
53 assert isinstance(code, astnodes.Statement) | 53 assert isinstance(code, astnodes.Statement) |
54 if type(code) is astnodes.CompoundStatement: | 54 if type(code) is astnodes.CompoundStatement: |
55 for s in code.statements: | 55 for s in code.statements: |
56 self.genCode(s) | 56 self.genCode(s) |
57 elif type(code) is astnodes.Assignment: | 57 elif type(code) is astnodes.Assignment: |
58 re = self.genExprCode(code.rval) | 58 re = self.genExprCode(code.rval) |
59 # TODO: Handle pointers | 59 # TODO: Handle pointers |
60 loc = self.genExprCode(code.lval) | 60 loc = self.genExprCode(code.lval) |
61 # determine location of variable | 61 # determine location of variable |
62 self.builder.addIns(ir.Store(loc, re)) | 62 self.builder.addIns(ir.Store(loc, re)) |
63 elif type(code) is astnodes.ExpressionStatement: | 63 elif type(code) is astnodes.ExpressionStatement: |
64 self.genExprCode(code.ex) | 64 self.genExprCode(code.ex) |
65 elif type(code) is astnodes.IfStatement: | 65 elif type(code) is astnodes.IfStatement: |
66 bbtrue = self.builder.newBB() | 66 bbtrue = self.builder.newBB() |
67 bbfalse = self.builder.newBB() | 67 bbfalse = self.builder.newBB() |
68 te = self.builder.newBB() | 68 te = self.builder.newBB() |
69 self.genCondCode(code.condition, bbtrue, bbfalse) | 69 self.genCondCode(code.condition, bbtrue, bbfalse) |
70 self.builder.setBB(bbtrue) | 70 self.builder.setBB(bbtrue) |
71 self.genCode(code.truestatement) | 71 self.genCode(code.truestatement) |
72 self.builder.addIns(ir.Branch(te)) | 72 self.builder.addIns(ir.Branch(te)) |
73 self.builder.setBB(bbfalse) | 73 self.builder.setBB(bbfalse) |
74 self.genCode(code.falsestatement) | 74 if code.falsestatement: |
75 self.builder.addIns(ir.Branch(te)) | 75 self.genCode(code.falsestatement) |
76 self.builder.setBB(te) | 76 self.builder.addIns(ir.Branch(te)) |
77 elif type(code) is astnodes.EmptyStatement: | 77 self.builder.setBB(te) |
78 pass | |
79 elif type(code) is astnodes.ReturnStatement: | 78 elif type(code) is astnodes.ReturnStatement: |
80 if code.expr: | 79 if code.expr: |
81 re = self.genExprCode(code.expr) | 80 re = self.genExprCode(code.expr) |
82 self.builder.addIns(ir.Return(re)) | 81 self.builder.addIns(ir.Return(re)) |
83 else: | 82 else: |
84 self.builder.addIns(ir.Return()) | 83 self.builder.addIns(ir.Return()) |
85 elif type(code) is astnodes.WhileStatement: | 84 elif type(code) is astnodes.WhileStatement: |
86 bbdo = self.builder.newBB() | 85 bbdo = self.builder.newBB() |
87 bbtest = self.builder.newBB() | 86 bbtest = self.builder.newBB() |
88 te = self.builder.newBB() | 87 te = self.builder.newBB() |
89 self.builder.addIns(ir.Branch(bbtest)) | 88 self.builder.addIns(ir.Branch(bbtest)) |
90 self.builder.setBB(bbtest) | 89 self.builder.setBB(bbtest) |
91 self.genCondCode(code.condition, bbdo, te) | 90 self.genCondCode(code.condition, bbdo, te) |
92 self.builder.setBB(bbdo) | 91 self.builder.setBB(bbdo) |
93 self.genCode(code.statement) | 92 self.genCode(code.statement) |
94 self.builder.addIns(ir.Branch(bbtest)) | 93 self.builder.addIns(ir.Branch(bbtest)) |
95 self.builder.setBB(te) | 94 self.builder.setBB(te) |
96 else: | 95 else: |
97 print('Unknown stmt:', code) | 96 print('Unknown stmt:', code) |
98 def genCondCode(self, expr, bbtrue, bbfalse): | 97 def genCondCode(self, expr, bbtrue, bbfalse): |
99 # Implement sequential logical operators | 98 # Implement sequential logical operators |
100 assert expr.typ == boolType | 99 assert expr.typ == boolType |
101 if type(expr) is astnodes.Binop: | 100 if type(expr) is astnodes.Binop: |
102 if expr.op == 'or': | 101 if expr.op == 'or': |
103 l2 = self.builder.newBB() | 102 l2 = self.builder.newBB() |
104 self.genCondCode(expr.a, bbtrue, l2) | 103 self.genCondCode(expr.a, bbtrue, l2) |
105 self.builder.setBB(l2) | 104 self.builder.setBB(l2) |
106 self.genCondCode(expr.b, bbtrue, bbfalse) | 105 self.genCondCode(expr.b, bbtrue, bbfalse) |
107 elif expr.op == 'and': | 106 elif expr.op == 'and': |
108 l2 = self.builder.newBB() | 107 l2 = self.builder.newBB() |
109 self.genCondCode(expr.a, l2, bbfalse) | 108 self.genCondCode(expr.a, l2, bbfalse) |
110 self.builder.setBB(l2) | 109 self.builder.setBB(l2) |
111 self.genCondCode(expr.b, bbtrue, bbfalse) | 110 self.genCondCode(expr.b, bbtrue, bbfalse) |
112 elif expr.op in ['==', '>', '<']: | 111 elif expr.op in ['==', '>', '<']: |
113 ta = self.genExprCode(expr.a) | 112 ta = self.genExprCode(expr.a) |
114 tb = self.genExprCode(expr.b) | 113 tb = self.genExprCode(expr.b) |
115 i = ir.ConditionalBranch(ta, expr.op, tb, bbtrue, bbfalse) | 114 i = ir.ConditionalBranch(ta, expr.op, tb, bbtrue, bbfalse) |
116 self.builder.addIns(i) | 115 self.builder.addIns(i) |
117 else: | 116 else: |
118 raise NotImlementedError('Unknown condition {0}'.format(expr)) | 117 raise NotImlementedError('Unknown condition {0}'.format(expr)) |
119 elif type(expr) is astnodes.Literal: | 118 elif type(expr) is astnodes.Literal: |
120 if expr.val: | 119 if expr.val: |
121 self.builder.addIns(ir.Branch(bbtrue)) | 120 self.builder.addIns(ir.Branch(bbtrue)) |
122 else: | 121 else: |
123 self.builder.addIns(ir.Branch(bbfalse)) | 122 self.builder.addIns(ir.Branch(bbfalse)) |
124 else: | 123 else: |
125 print('Unknown cond', expr) | 124 print('Unknown cond', expr) |
126 def genExprCode(self, expr): | 125 def genExprCode(self, expr): |
127 if type(expr) is astnodes.Binop: | 126 if type(expr) is astnodes.Binop: |
128 ra = self.genExprCode(expr.a) | 127 ra = self.genExprCode(expr.a) |
129 rb = self.genExprCode(expr.b) | 128 rb = self.genExprCode(expr.b) |
130 ops = ['+', '-', '*', '/', '|', '&'] | 129 ops = ['+', '-', '*', '/', '|', '&'] |
131 if expr.op in ops: | 130 if expr.op in ops: |
132 tmpnames = {'+':'add', '-':'sub', '*': 'mul', '/':'div', '|':'or', '&':'and'} | 131 tmpnames = {'+':'add', '-':'sub', '*': 'mul', '/':'div', '|':'or', '&':'and'} |
133 tmp = self.builder.newTmp(tmpnames[expr.op]) | 132 tmp = self.builder.newTmp(tmpnames[expr.op]) |
134 op = expr.op | 133 op = expr.op |
135 ins = ir.BinaryOperator(tmp, op, ra, rb) | 134 ins = ir.BinaryOperator(tmp, op, ra, rb) |
136 self.builder.addIns(ins) | 135 self.builder.addIns(ins) |
137 return tmp | 136 return tmp |
138 else: | 137 else: |
139 print('Unknown {0}'.format(expr)) | 138 print('Unknown {0}'.format(expr)) |
140 tmp = self.builder.newTmp() | 139 tmp = self.builder.newTmp() |
141 # TODO | 140 # TODO |
142 return tmp | 141 return tmp |
143 elif type(expr) is astnodes.Unop: | 142 elif type(expr) is astnodes.Unop: |
144 ra = self.genExprCode(expr.a) | 143 ra = self.genExprCode(expr.a) |
145 if expr.op == '&': | 144 if expr.op == '&': |
146 # Address of operator | 145 # Address of operator |
147 tmp = self.builder.newTmp('addr') | 146 tmp = self.builder.newTmp('addr') |
184 elif isinstance(expr.a.typ, astnodes.PointerType): | 183 elif isinstance(expr.a.typ, astnodes.PointerType): |
185 return ar | 184 return ar |
186 else: | 185 else: |
187 raise Exception() | 186 raise Exception() |
188 elif type(expr) is astnodes.FunctionCall: | 187 elif type(expr) is astnodes.FunctionCall: |
189 tmp = self.builder.newTmp("res") | 188 tmp = self.builder.newTmp("res") |
190 args = [] | 189 args = [] |
191 for arg in expr.args: | 190 for arg in expr.args: |
192 ar = self.genExprCode(arg) | 191 ar = self.genExprCode(arg) |
193 args.append(ar) | 192 args.append(ar) |
194 fn = self.funcMap[expr.proc] | 193 fn = self.funcMap[expr.proc] |
195 ins = ir.Call(fn, args, tmp) | 194 ins = ir.Call(fn, args, tmp) |
196 self.builder.addIns(ins) | 195 self.builder.addIns(ins) |
197 return tmp | 196 return tmp |
198 else: | 197 else: |
199 raise CompilerError('Unknown expr {}'.format(expr)) | 198 raise CompilerError('Unknown expr {}'.format(expr)) |
200 | 199 |