annotate python/c3/codegenerator.py @ 170:4348da5ca307

Cleanup of ir dir
author Windel Bouwman
date Fri, 29 Mar 2013 17:33:17 +0100
parents ee0d30533dae
children 3eb9b9e2958d
rev   line source
155
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 151
diff changeset
1 import ir
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 151
diff changeset
2 from . import astnodes
151
afc8c0207984 Added ir code generator stub
Windel Bouwman
parents:
diff changeset
3
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
4 def NumGen():
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
5 a = 0
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
6 while True:
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
7 yield a
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
8 a = a + 1
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
9
170
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
10 class NameGenerator:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
11 def __init__(self, prefix):
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
12 self.prefix = prefix
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
13 self.nums = NumGen()
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
14 def gen(self):
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
15 return '{0}{1}'.format(self.prefix, self.nums.__next__())
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
16
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
17 class CodeGenerator:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
18 """ Generates intermediate code from a package """
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
19 def gencode(self, pkg):
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
20 assert type(pkg) is astnodes.Package
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
21 self.m = ir.Module(pkg.name)
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
22 self.newTmp = NameGenerator('t').gen
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
23 self.newLab = NameGenerator('lab').gen
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
24 self.genModule(pkg)
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
25 return self.m
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
26
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
27 # Helpers:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
28 def addIns(self, i):
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
29 self.m.Instructions.append(i)
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
30 # inner helpers:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
31 def genModule(self, pkg):
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
32 for s in pkg.scope:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
33 if type(s) is astnodes.Variable:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
34 # TODO
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
35 pass
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
36 elif type(s) is astnodes.Function:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
37 # TODO: handle arguments
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
38 # TODO handle return?
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
39 self.addIns(ir.LabelInstruction(s.name))
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
40 self.genCode(s.body)
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
41 self.addIns(ir.RetInstruction())
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
42 else:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
43 print(s)
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
44
170
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
45 def genCode(self, code):
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
46 if type(code) is astnodes.CompoundStatement:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
47 for s in code.statements:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
48 self.genCode(s)
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
49 elif type(code) is astnodes.Assignment:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
50 re = self.genExprCode(code.rval)
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
51 self.addIns(ir.StoreInstruction(code.lval, re))
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
52 elif type(code) is astnodes.IfStatement:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
53 cr = self.genExprCode(code.condition)
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
54 t1, t2, te = self.newLab(), self.newLab(), self.newLab()
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
55 self.addIns(ir.IfInstruction(cr, t1, t2))
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
56 self.addIns(ir.LabelInstruction(t1))
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
57 self.genCode(code.truestatement)
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
58 self.addIns(ir.BranchInstruction(te))
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
59 self.addIns(ir.LabelInstruction(t2))
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
60 self.genCode(code.falsestatement)
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
61 self.addIns(ir.LabelInstruction(te))
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
62 elif type(code) is astnodes.FunctionCall:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
63 pass
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
64 elif type(code) is astnodes.EmptyStatement:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
65 pass
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
66 elif type(code) is astnodes.ReturnStatement:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
67 pass
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
68 else:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
69 print('Unknown stmt:', code)
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
70
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
71 def genExprCode(self, expr):
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
72 if type(expr) is astnodes.Binop:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
73 ra = self.genExprCode(expr.a)
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
74 rb = self.genExprCode(expr.b)
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
75 ops = ['+', '-', '*', '/', 'and', 'or']
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
76 if expr.op in ops:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
77 op = expr.op
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
78 tmp = self.newTmp()
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
79 ins = ir.BinaryOperator(tmp, op, ra, rb)
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
80 self.addIns(ins)
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
81 return tmp
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
82 else:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
83 print('Unknown binop {0}'.format(expr))
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
84 elif type(expr) is astnodes.Constant:
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
85 tmp = unique()
170
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
86 elif type(expr) is astnodes.VariableUse:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
87 tmp = self.newTmp()
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
88 elif type(expr) is astnodes.Literal:
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
89 tmp = self.newTmp()
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
90 ins = ir.MoveInstruction(tmp, expr.val)
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
91 self.addIns(ins)
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
92 return tmp
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
93 else:
170
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 169
diff changeset
94 print('Unknown expr:', code)
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
95