Mercurial > lcfOS
comparison 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 |
comparison
equal
deleted
inserted
replaced
169:ee0d30533dae | 170:4348da5ca307 |
---|---|
1 import ir | 1 import ir |
2 from . import astnodes | 2 from . import astnodes |
3 | |
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) | |
9 elif type(s) is astnodes.Function: | |
10 genFunction(m, s) | |
11 else: | |
12 print(s) | |
13 return m | |
14 | |
15 def genGlobal(m, var): | |
16 v = ir.Value() | |
17 v.name = var.name | |
18 m.Globals.append(v) | |
19 | |
20 def genFunction(m, fnc): | |
21 ft = genType(fnc.typ) | |
22 f = ir.Function(fnc.name, ft) | |
23 m.Functions.append(f) | |
24 bb = ir.BasicBlock() | |
25 f.BasicBlocks.append(bb) | |
26 genCode(bb, fnc.body) | |
27 bb.Instructions.append(ir.RetInstruction()) | |
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: | |
34 genExprCode(bb, code.rval) | |
35 # TODO: store | |
36 elif type(code) is astnodes.IfStatement: | |
37 genExprCode(bb, code.condition) | |
38 # TODO: implement IF. | |
39 t1, t2 = 1, 2 | |
40 b = ir.BranchInstruction(t1, t2) | |
41 bb.Instructions.append(b) | |
42 genCode(bb, code.truestatement) | |
43 genCode(bb, code.falsestatement) | |
44 elif type(code) is astnodes.FunctionCall: | |
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 | 3 |
54 def NumGen(): | 4 def NumGen(): |
55 a = 0 | 5 a = 0 |
56 while True: | 6 while True: |
57 yield a | 7 yield a |
58 a = a + 1 | 8 a = a + 1 |
59 | 9 |
60 nums = NumGen() | 10 class NameGenerator: |
61 def unique(): | 11 def __init__(self, prefix): |
62 return 'tmp{0}'.format(nums.__next__()) | 12 self.prefix = prefix |
13 self.nums = NumGen() | |
14 def gen(self): | |
15 return '{0}{1}'.format(self.prefix, self.nums.__next__()) | |
63 | 16 |
64 def genExprCode(bb, code): | 17 class CodeGenerator: |
65 if type(code) is astnodes.Binop: | 18 """ Generates intermediate code from a package """ |
66 a = genExprCode(bb, code.a) | 19 def gencode(self, pkg): |
67 b = genExprCode(bb, code.b) | 20 assert type(pkg) is astnodes.Package |
68 ops = {'+': 'fadd', '-': 'fsub', '*':'fmul', '/':'fdiv'} | 21 self.m = ir.Module(pkg.name) |
69 if code.op in ops: | 22 self.newTmp = NameGenerator('t').gen |
70 op = ops[code.op] | 23 self.newLab = NameGenerator('lab').gen |
24 self.genModule(pkg) | |
25 return self.m | |
26 | |
27 # Helpers: | |
28 def addIns(self, i): | |
29 self.m.Instructions.append(i) | |
30 # inner helpers: | |
31 def genModule(self, pkg): | |
32 for s in pkg.scope: | |
33 if type(s) is astnodes.Variable: | |
34 # TODO | |
35 pass | |
36 elif type(s) is astnodes.Function: | |
37 # TODO: handle arguments | |
38 # TODO handle return? | |
39 self.addIns(ir.LabelInstruction(s.name)) | |
40 self.genCode(s.body) | |
41 self.addIns(ir.RetInstruction()) | |
42 else: | |
43 print(s) | |
44 | |
45 def genCode(self, code): | |
46 if type(code) is astnodes.CompoundStatement: | |
47 for s in code.statements: | |
48 self.genCode(s) | |
49 elif type(code) is astnodes.Assignment: | |
50 re = self.genExprCode(code.rval) | |
51 self.addIns(ir.StoreInstruction(code.lval, re)) | |
52 elif type(code) is astnodes.IfStatement: | |
53 cr = self.genExprCode(code.condition) | |
54 t1, t2, te = self.newLab(), self.newLab(), self.newLab() | |
55 self.addIns(ir.IfInstruction(cr, t1, t2)) | |
56 self.addIns(ir.LabelInstruction(t1)) | |
57 self.genCode(code.truestatement) | |
58 self.addIns(ir.BranchInstruction(te)) | |
59 self.addIns(ir.LabelInstruction(t2)) | |
60 self.genCode(code.falsestatement) | |
61 self.addIns(ir.LabelInstruction(te)) | |
62 elif type(code) is astnodes.FunctionCall: | |
63 pass | |
64 elif type(code) is astnodes.EmptyStatement: | |
65 pass | |
66 elif type(code) is astnodes.ReturnStatement: | |
67 pass | |
68 else: | |
69 print('Unknown stmt:', code) | |
70 | |
71 def genExprCode(self, expr): | |
72 if type(expr) is astnodes.Binop: | |
73 ra = self.genExprCode(expr.a) | |
74 rb = self.genExprCode(expr.b) | |
75 ops = ['+', '-', '*', '/', 'and', 'or'] | |
76 if expr.op in ops: | |
77 op = expr.op | |
78 tmp = self.newTmp() | |
79 ins = ir.BinaryOperator(tmp, op, ra, rb) | |
80 self.addIns(ins) | |
81 return tmp | |
82 else: | |
83 print('Unknown binop {0}'.format(expr)) | |
84 elif type(expr) is astnodes.Constant: | |
71 tmp = unique() | 85 tmp = unique() |
72 ins = ir.BinaryOperator(tmp, op, a, b) | 86 elif type(expr) is astnodes.VariableUse: |
73 bb.Instructions.append(ins) | 87 tmp = self.newTmp() |
88 elif type(expr) is astnodes.Literal: | |
89 tmp = self.newTmp() | |
90 ins = ir.MoveInstruction(tmp, expr.val) | |
91 self.addIns(ins) | |
74 return tmp | 92 return tmp |
75 else: | 93 else: |
76 print('Unknown binop {0}'.format(code)) | 94 print('Unknown expr:', code) |
77 bb.Instructions.append(ir.BinaryOperator('unk2', code.op, a, b)) | |
78 return 'unk2' | |
79 elif type(code) is astnodes.Constant: | |
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 | |
87 elif type(code) is astnodes.Literal: | |
88 tmp = unique() | |
89 ins = ir.LoadInstruction(tmp, code.val) | |
90 return tmp | |
91 else: | |
92 print('Unknown expr:', code) | |
93 return 'unk' | |
94 | 95 |
95 def genType(t): | |
96 return ir.Type() | |
97 | |
98 class CodeGenerator: | |
99 """ Generates intermediate code """ | |
100 def gencode(self, ast): | |
101 assert type(ast) is astnodes.Package | |
102 return genModule(ast) | |
103 |