Mercurial > lcfOS
comparison python/c3/codegenerator.py @ 175:a51b3c956386
Added function call in expressions
author | Windel Bouwman |
---|---|
date | Fri, 19 Apr 2013 22:15:54 +0200 |
parents | 3eb06f5fb987 |
children | 5fd02aa38b42 |
comparison
equal
deleted
inserted
replaced
174:3eb06f5fb987 | 175:a51b3c956386 |
---|---|
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.varMap = {} # Maps variables to storage locations. |
10 self.funcMap = {} | |
10 self.builder = ir.Builder() | 11 self.builder = ir.Builder() |
11 m = ir.Module(pkg.name) | 12 m = ir.Module(pkg.name) |
12 self.builder.setModule(m) | 13 self.builder.setModule(m) |
13 self.genModule(pkg) | 14 self.genModule(pkg) |
14 return m | 15 return m |
15 | 16 |
16 # inner helpers: | 17 # inner helpers: |
17 def genModule(self, pkg): | 18 def genModule(self, pkg): |
19 # Take care of forward declarations: | |
20 for s in pkg.scope: | |
21 if type(s) is astnodes.Function: | |
22 f = self.builder.newFunc(s.name) | |
23 self.funcMap[s] = f | |
18 for s in pkg.scope: | 24 for s in pkg.scope: |
19 if type(s) is astnodes.Variable: | 25 if type(s) is astnodes.Variable: |
20 # TODO | 26 # TODO |
21 pass | 27 pass |
22 elif type(s) is astnodes.Function: | 28 elif type(s) is astnodes.Function: |
23 # TODO: handle arguments | 29 # TODO: handle arguments |
24 f = self.builder.newFunc(s.name) | 30 f = self.funcMap[s] |
25 self.builder.setFunc(f) | 31 self.builder.setFunc(f) |
26 bb = self.builder.newBB() | 32 bb = self.builder.newBB() |
27 f.entry = bb | 33 f.entry = bb |
28 self.builder.setBB(bb) | 34 self.builder.setBB(bb) |
29 # generate room for locals: | 35 # generate room for locals: |
30 | 36 |
31 for sym in s.scope: | 37 for sym in s.scope: |
38 #print(sym, sym.isParameter) | |
39 # TODO: handle parameters different | |
32 v = self.builder.newTmp(sym.name) | 40 v = self.builder.newTmp(sym.name) |
33 self.builder.addIns(ir.Alloc(v)) | 41 self.builder.addIns(ir.Alloc(v)) |
34 self.varMap[sym] = v | 42 self.varMap[sym] = v |
35 | 43 |
36 self.genCode(s.body) | 44 self.genCode(s.body) |
44 if type(code) is astnodes.CompoundStatement: | 52 if type(code) is astnodes.CompoundStatement: |
45 for s in code.statements: | 53 for s in code.statements: |
46 self.genCode(s) | 54 self.genCode(s) |
47 elif type(code) is astnodes.Assignment: | 55 elif type(code) is astnodes.Assignment: |
48 re = self.genExprCode(code.rval) | 56 re = self.genExprCode(code.rval) |
49 print(code.lval) | |
50 loc = self.varMap[code.lval.target] | 57 loc = self.varMap[code.lval.target] |
51 self.builder.addIns(ir.Store(loc, re)) | 58 self.builder.addIns(ir.Store(loc, re)) |
52 elif type(code) is astnodes.IfStatement: | 59 elif type(code) is astnodes.IfStatement: |
53 bbtrue = self.builder.newBB() | 60 bbtrue = self.builder.newBB() |
54 bbfalse = self.builder.newBB() | 61 bbfalse = self.builder.newBB() |
129 elif type(expr) is astnodes.Literal: | 136 elif type(expr) is astnodes.Literal: |
130 tmp = self.builder.newTmp() | 137 tmp = self.builder.newTmp() |
131 ins = ir.ImmLoad(tmp, expr.val) | 138 ins = ir.ImmLoad(tmp, expr.val) |
132 self.builder.addIns(ins) | 139 self.builder.addIns(ins) |
133 return tmp | 140 return tmp |
141 elif type(expr) is astnodes.FunctionCall: | |
142 tmp = self.builder.newTmp("res") | |
143 args = [] | |
144 for arg in expr.args: | |
145 ar = self.genExprCode(arg) | |
146 args.append(ar) | |
147 fn = self.funcMap[expr.proc] | |
148 ins = ir.Call(fn, args, tmp) | |
149 self.builder.addIns(ins) | |
150 return tmp | |
134 else: | 151 else: |
135 print('Unknown expr:', code) | 152 print('Unknown expr:', code) |
136 | 153 |