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)
|
156
|
23 m.Globals.append(f)
|
157
|
24 bb = ir.BasicBlock()
|
|
25 f.BasicBlocks.append(bb)
|
|
26 genCode(bb, fnc.body)
|
|
27
|
|
28 def genCode(bb, code):
|
|
29 if type(code) is astnodes.CompoundStatement:
|
|
30 for s in code.statements:
|
|
31 genCode(bb, s)
|
|
32 elif type(code) is astnodes.Assignment:
|
|
33 genCode(bb, code.rval)
|
|
34 print('assign')
|
|
35 elif type(code) is astnodes.IfStatement:
|
|
36 genCode(bb, code.condition)
|
|
37 genCode(bb, code.truestatement)
|
|
38 print('If!')
|
|
39 elif type(code) is astnodes.Binop:
|
|
40 genCode(bb, code.a)
|
|
41 genCode(bb, code.b)
|
|
42 a = 1
|
|
43 b = 2
|
|
44 if code.op == '+':
|
|
45 bb.Instructions.append(ir.AddInstruction(a, b))
|
|
46 else:
|
|
47 bb.Instructions.append(ir.BinaryOperator(code.op, a, b))
|
|
48 elif type(code) is astnodes.Constant:
|
|
49 print('CST')
|
|
50 bb.Instructions.append(ir.ImmLoadInstruction(code.value))
|
|
51 else:
|
|
52 print('Unknown:', code)
|
|
53
|
|
54 def genType(t):
|
|
55 return ir.Type()
|
156
|
56
|
151
|
57 class CodeGenerator:
|
|
58 """ Generates intermediate code """
|
|
59 def gencode(self, ast):
|
155
|
60 assert type(ast) is astnodes.Package
|
|
61 return genModule(ast)
|
151
|
62
|