annotate python/c3/codegenerator.py @ 169:ee0d30533dae

Added more tests and improved the diagnostic update
author Windel Bouwman
date Sat, 23 Mar 2013 18:34:41 +0100
parents 0b5b2ee6b435
children 4348da5ca307
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
155
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 151
diff changeset
4 def genModule(pkg):
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 151
diff changeset
5 m = ir.Module(pkg.name)
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 151
diff changeset
6 for s in pkg.scope:
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 151
diff changeset
7 if type(s) is astnodes.Variable:
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 151
diff changeset
8 genGlobal(m, s)
156
1b4a85bdd99c change types
Windel Bouwman
parents: 155
diff changeset
9 elif type(s) is astnodes.Function:
1b4a85bdd99c change types
Windel Bouwman
parents: 155
diff changeset
10 genFunction(m, s)
1b4a85bdd99c change types
Windel Bouwman
parents: 155
diff changeset
11 else:
1b4a85bdd99c change types
Windel Bouwman
parents: 155
diff changeset
12 print(s)
155
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 151
diff changeset
13 return m
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 151
diff changeset
14
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 151
diff changeset
15 def genGlobal(m, var):
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 151
diff changeset
16 v = ir.Value()
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 151
diff changeset
17 v.name = var.name
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 151
diff changeset
18 m.Globals.append(v)
151
afc8c0207984 Added ir code generator stub
Windel Bouwman
parents:
diff changeset
19
156
1b4a85bdd99c change types
Windel Bouwman
parents: 155
diff changeset
20 def genFunction(m, fnc):
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
21 ft = genType(fnc.typ)
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
22 f = ir.Function(fnc.name, ft)
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
23 m.Functions.append(f)
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
24 bb = ir.BasicBlock()
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
25 f.BasicBlocks.append(bb)
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
26 genCode(bb, fnc.body)
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
27 bb.Instructions.append(ir.RetInstruction())
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
28
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
29 def genCode(bb, code):
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
30 if type(code) is astnodes.CompoundStatement:
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
31 for s in code.statements:
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
32 genCode(bb, s)
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
33 elif type(code) is astnodes.Assignment:
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
34 genExprCode(bb, code.rval)
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
35 # TODO: store
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
36 elif type(code) is astnodes.IfStatement:
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
37 genExprCode(bb, code.condition)
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
38 # TODO: implement IF.
167
0b5b2ee6b435 Added 2 unit tests
Windel Bouwman
parents: 158
diff changeset
39 t1, t2 = 1, 2
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
40 b = ir.BranchInstruction(t1, t2)
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
41 bb.Instructions.append(b)
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
42 genCode(bb, code.truestatement)
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
43 genCode(bb, code.falsestatement)
167
0b5b2ee6b435 Added 2 unit tests
Windel Bouwman
parents: 158
diff changeset
44 elif type(code) is astnodes.FunctionCall:
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
45 ins = ir.CallInstruction('f', [])
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
46 bb.Instructions.append(ins)
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
47 elif type(code) is astnodes.EmptyStatement:
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
48 pass
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
49 elif type(code) is astnodes.ReturnStatement:
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
50 bb.Instructions.append(ir.RetInstruction())
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
51 else:
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
52 print('Unknown stmt:', code)
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
53
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
54 def NumGen():
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
55 a = 0
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
56 while True:
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
57 yield a
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
58 a = a + 1
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
59
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
60 nums = NumGen()
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
61 def unique():
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
62 return 'tmp{0}'.format(nums.__next__())
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
63
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
64 def genExprCode(bb, code):
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
65 if type(code) is astnodes.Binop:
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
66 a = genExprCode(bb, code.a)
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
67 b = genExprCode(bb, code.b)
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
68 ops = {'+': 'fadd', '-': 'fsub', '*':'fmul', '/':'fdiv'}
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
69 if code.op in ops:
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
70 op = ops[code.op]
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
71 tmp = unique()
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
72 ins = ir.BinaryOperator(tmp, op, a, b)
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
73 bb.Instructions.append(ins)
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
74 return tmp
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
75 else:
169
ee0d30533dae Added more tests and improved the diagnostic update
Windel Bouwman
parents: 167
diff changeset
76 print('Unknown binop {0}'.format(code))
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
77 bb.Instructions.append(ir.BinaryOperator('unk2', code.op, a, b))
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
78 return 'unk2'
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
79 elif type(code) is astnodes.Constant:
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
80 tmp = unique()
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
81 bb.Instructions.append(ir.LoadInstruction(tmp, code.value))
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
82 return tmp
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
83 elif type(code) is astnodes.VariableUse:
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
84 tmp = unique()
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
85 ins = ir.LoadInstruction(tmp, code.target.name)
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
86 return tmp
169
ee0d30533dae Added more tests and improved the diagnostic update
Windel Bouwman
parents: 167
diff changeset
87 elif type(code) is astnodes.Literal:
ee0d30533dae Added more tests and improved the diagnostic update
Windel Bouwman
parents: 167
diff changeset
88 tmp = unique()
ee0d30533dae Added more tests and improved the diagnostic update
Windel Bouwman
parents: 167
diff changeset
89 ins = ir.LoadInstruction(tmp, code.val)
ee0d30533dae Added more tests and improved the diagnostic update
Windel Bouwman
parents: 167
diff changeset
90 return tmp
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
91 else:
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
92 print('Unknown expr:', code)
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
93 return 'unk'
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
94
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
95 def genType(t):
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
96 return ir.Type()
156
1b4a85bdd99c change types
Windel Bouwman
parents: 155
diff changeset
97
151
afc8c0207984 Added ir code generator stub
Windel Bouwman
parents:
diff changeset
98 class CodeGenerator:
afc8c0207984 Added ir code generator stub
Windel Bouwman
parents:
diff changeset
99 """ Generates intermediate code """
afc8c0207984 Added ir code generator stub
Windel Bouwman
parents:
diff changeset
100 def gencode(self, ast):
155
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 151
diff changeset
101 assert type(ast) is astnodes.Package
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 151
diff changeset
102 return genModule(ast)
151
afc8c0207984 Added ir code generator stub
Windel Bouwman
parents:
diff changeset
103