Mercurial > lcfOS
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 | 1 import ir |
2 from . import astnodes | |
151 | 3 |
155 | 4 def genModule(pkg): |
5 m = ir.Module(pkg.name) | |
6 for s in pkg.scope: | |
7 if type(s) is astnodes.Variable: | |
8 genGlobal(m, s) | |
156 | 9 elif type(s) is astnodes.Function: |
10 genFunction(m, s) | |
11 else: | |
12 print(s) | |
155 | 13 return m |
14 | |
15 def genGlobal(m, var): | |
16 v = ir.Value() | |
17 v.name = var.name | |
18 m.Globals.append(v) | |
151 | 19 |
156 | 20 def genFunction(m, fnc): |
157 | 21 ft = genType(fnc.typ) |
22 f = ir.Function(fnc.name, ft) | |
158 | 23 m.Functions.append(f) |
157 | 24 bb = ir.BasicBlock() |
25 f.BasicBlocks.append(bb) | |
26 genCode(bb, fnc.body) | |
158 | 27 bb.Instructions.append(ir.RetInstruction()) |
157 | 28 |
29 def genCode(bb, code): | |
30 if type(code) is astnodes.CompoundStatement: | |
31 for s in code.statements: | |
32 genCode(bb, s) | |
33 elif type(code) is astnodes.Assignment: | |
158 | 34 genExprCode(bb, code.rval) |
35 # TODO: store | |
157 | 36 elif type(code) is astnodes.IfStatement: |
158 | 37 genExprCode(bb, code.condition) |
38 # TODO: implement IF. | |
167 | 39 t1, t2 = 1, 2 |
158 | 40 b = ir.BranchInstruction(t1, t2) |
41 bb.Instructions.append(b) | |
157 | 42 genCode(bb, code.truestatement) |
158 | 43 genCode(bb, code.falsestatement) |
167 | 44 elif type(code) is astnodes.FunctionCall: |
158 | 45 ins = ir.CallInstruction('f', []) |
46 bb.Instructions.append(ins) | |
47 elif type(code) is astnodes.EmptyStatement: | |
48 pass | |
49 elif type(code) is astnodes.ReturnStatement: | |
50 bb.Instructions.append(ir.RetInstruction()) | |
51 else: | |
52 print('Unknown stmt:', code) | |
53 | |
54 def NumGen(): | |
55 a = 0 | |
56 while True: | |
57 yield a | |
58 a = a + 1 | |
59 | |
60 nums = NumGen() | |
61 def unique(): | |
62 return 'tmp{0}'.format(nums.__next__()) | |
63 | |
64 def genExprCode(bb, code): | |
65 if type(code) is astnodes.Binop: | |
66 a = genExprCode(bb, code.a) | |
67 b = genExprCode(bb, code.b) | |
68 ops = {'+': 'fadd', '-': 'fsub', '*':'fmul', '/':'fdiv'} | |
69 if code.op in ops: | |
70 op = ops[code.op] | |
71 tmp = unique() | |
72 ins = ir.BinaryOperator(tmp, op, a, b) | |
73 bb.Instructions.append(ins) | |
74 return tmp | |
157 | 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 | 77 bb.Instructions.append(ir.BinaryOperator('unk2', code.op, a, b)) |
78 return 'unk2' | |
157 | 79 elif type(code) is astnodes.Constant: |
158 | 80 tmp = unique() |
81 bb.Instructions.append(ir.LoadInstruction(tmp, code.value)) | |
82 return tmp | |
83 elif type(code) is astnodes.VariableUse: | |
84 tmp = unique() | |
85 ins = ir.LoadInstruction(tmp, code.target.name) | |
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 | 91 else: |
158 | 92 print('Unknown expr:', code) |
93 return 'unk' | |
157 | 94 |
95 def genType(t): | |
96 return ir.Type() | |
156 | 97 |
151 | 98 class CodeGenerator: |
99 """ Generates intermediate code """ | |
100 def gencode(self, ast): | |
155 | 101 assert type(ast) is astnodes.Package |
102 return genModule(ast) | |
151 | 103 |