Mercurial > lcfOS
comparison python/c3/codegenerator.py @ 174:3eb06f5fb987
Added memory alloc for locals
author | Windel Bouwman |
---|---|
date | Fri, 19 Apr 2013 19:22:52 +0200 |
parents | 5a7d37d615ee |
children | a51b3c956386 |
comparison
equal
deleted
inserted
replaced
173:c1d2b6b9f9a7 | 174:3eb06f5fb987 |
---|---|
4 | 4 |
5 class CodeGenerator: | 5 class CodeGenerator: |
6 """ Generates intermediate code from a package """ | 6 """ Generates intermediate code from a package """ |
7 def gencode(self, pkg): | 7 def gencode(self, pkg): |
8 assert type(pkg) is astnodes.Package | 8 assert type(pkg) is astnodes.Package |
9 self.varMap = {} # Maps variables to storage locations. | |
9 self.builder = ir.Builder() | 10 self.builder = ir.Builder() |
10 m = ir.Module(pkg.name) | 11 m = ir.Module(pkg.name) |
11 self.builder.setModule(m) | 12 self.builder.setModule(m) |
12 self.genModule(pkg) | 13 self.genModule(pkg) |
13 return m | 14 return m |
23 f = self.builder.newFunc(s.name) | 24 f = self.builder.newFunc(s.name) |
24 self.builder.setFunc(f) | 25 self.builder.setFunc(f) |
25 bb = self.builder.newBB() | 26 bb = self.builder.newBB() |
26 f.entry = bb | 27 f.entry = bb |
27 self.builder.setBB(bb) | 28 self.builder.setBB(bb) |
29 # generate room for locals: | |
30 | |
31 for sym in s.scope: | |
32 v = self.builder.newTmp(sym.name) | |
33 self.builder.addIns(ir.Alloc(v)) | |
34 self.varMap[sym] = v | |
35 | |
28 self.genCode(s.body) | 36 self.genCode(s.body) |
29 # TODO handle return? | 37 # TODO handle return? |
30 self.builder.addIns(ir.Return()) | 38 self.builder.addIns(ir.Return()) |
31 self.builder.setFunc(None) | 39 self.builder.setFunc(None) |
32 else: | 40 else: |
36 if type(code) is astnodes.CompoundStatement: | 44 if type(code) is astnodes.CompoundStatement: |
37 for s in code.statements: | 45 for s in code.statements: |
38 self.genCode(s) | 46 self.genCode(s) |
39 elif type(code) is astnodes.Assignment: | 47 elif type(code) is astnodes.Assignment: |
40 re = self.genExprCode(code.rval) | 48 re = self.genExprCode(code.rval) |
41 self.builder.addIns(ir.Store(code.lval, re)) | 49 print(code.lval) |
50 loc = self.varMap[code.lval.target] | |
51 self.builder.addIns(ir.Store(loc, re)) | |
42 elif type(code) is astnodes.IfStatement: | 52 elif type(code) is astnodes.IfStatement: |
43 bbtrue = self.builder.newBB() | 53 bbtrue = self.builder.newBB() |
44 bbfalse = self.builder.newBB() | 54 bbfalse = self.builder.newBB() |
45 te = self.builder.newBB() | 55 te = self.builder.newBB() |
46 self.genCondCode(code.condition, bbtrue, bbfalse) | 56 self.genCondCode(code.condition, bbtrue, bbfalse) |
54 elif type(code) is astnodes.FunctionCall: | 64 elif type(code) is astnodes.FunctionCall: |
55 pass | 65 pass |
56 elif type(code) is astnodes.EmptyStatement: | 66 elif type(code) is astnodes.EmptyStatement: |
57 pass | 67 pass |
58 elif type(code) is astnodes.ReturnStatement: | 68 elif type(code) is astnodes.ReturnStatement: |
59 pass | 69 if code.expr: |
70 re = self.genExprCode(code.expr) | |
71 self.builder.addIns(ir.Return(re)) | |
72 else: | |
73 self.builder.addIns(ir.Return()) | |
60 else: | 74 else: |
61 print('Unknown stmt:', code) | 75 print('Unknown stmt:', code) |
62 def genCondCode(self, expr, bbtrue, bbfalse): | 76 def genCondCode(self, expr, bbtrue, bbfalse): |
63 # Implement sequential logical operators | 77 # Implement sequential logical operators |
64 assert expr.typ == boolType | 78 assert expr.typ == boolType |
77 ta = self.genExprCode(expr.a) | 91 ta = self.genExprCode(expr.a) |
78 tb = self.genExprCode(expr.b) | 92 tb = self.genExprCode(expr.b) |
79 i = ir.ConditionalBranch(ta, expr.op, tb, bbtrue, bbfalse) | 93 i = ir.ConditionalBranch(ta, expr.op, tb, bbtrue, bbfalse) |
80 self.builder.addIns(i) | 94 self.builder.addIns(i) |
81 else: | 95 else: |
82 raise NotImlementedError() | 96 raise NotImlementedError('Unknown condition {0}'.format(expr)) |
83 print('Unknown cond', expr) | |
84 elif type(expr) is astnodes.Literal: | 97 elif type(expr) is astnodes.Literal: |
85 if expr.val: | 98 if expr.val: |
86 self.builder.addIns(ir.BranchInstruction(bbtrue)) | 99 self.builder.addIns(ir.BranchInstruction(bbtrue)) |
87 else: | 100 else: |
88 self.builder.addIns(ir.BranchInstruction(bbfalse)) | 101 self.builder.addIns(ir.BranchInstruction(bbfalse)) |
107 tmp = self.builder.newTmp() | 120 tmp = self.builder.newTmp() |
108 # TODO | 121 # TODO |
109 return tmp | 122 return tmp |
110 elif type(expr) is astnodes.VariableUse: | 123 elif type(expr) is astnodes.VariableUse: |
111 tmp = self.builder.newTmp() | 124 tmp = self.builder.newTmp() |
112 i = ir.Load(expr, tmp) | 125 loc = self.varMap[expr.target] |
126 i = ir.Load(loc, tmp) | |
113 self.builder.addIns(i) | 127 self.builder.addIns(i) |
114 return tmp | 128 return tmp |
115 elif type(expr) is astnodes.Literal: | 129 elif type(expr) is astnodes.Literal: |
116 tmp = self.builder.newTmp() | 130 tmp = self.builder.newTmp() |
117 ins = ir.ImmLoad(tmp, expr.val) | 131 ins = ir.ImmLoad(tmp, expr.val) |