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)