annotate python/c3/codegenerator.py @ 158:9683a4cd848f

Added some functions for code generation
author Windel Bouwman
date Fri, 08 Mar 2013 16:52:44 +0100
parents 8f3924b6076e
children 0b5b2ee6b435
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.
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
39 t1, t2 = 1,2
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)
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
44 elif type(code) is astnodes.ProcedureCall:
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:
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
76 print('Unknown binop')
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
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
87 else:
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
88 print('Unknown expr:', code)
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
89 return 'unk'
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
90
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
91 def genType(t):
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
92 return ir.Type()
156
1b4a85bdd99c change types
Windel Bouwman
parents: 155
diff changeset
93
151
afc8c0207984 Added ir code generator stub
Windel Bouwman
parents:
diff changeset
94 class CodeGenerator:
afc8c0207984 Added ir code generator stub
Windel Bouwman
parents:
diff changeset
95 """ Generates intermediate code """
afc8c0207984 Added ir code generator stub
Windel Bouwman
parents:
diff changeset
96 def gencode(self, ast):
155
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 151
diff changeset
97 assert type(ast) is astnodes.Package
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 151
diff changeset
98 return genModule(ast)
151
afc8c0207984 Added ir code generator stub
Windel Bouwman
parents:
diff changeset
99