103
|
1 """
|
|
2 Generates ir code from ast tree.
|
|
3 """
|
|
4
|
|
5 from .nodes import *
|
110
|
6 from .builtin import real, integer, boolean, char, void
|
|
7
|
|
8 def coreType(typ):
|
|
9 """ Return the correct core type given a type """
|
|
10 if type(typ) is BaseType:
|
|
11 if typ is integer:
|
|
12 return core.i32
|
|
13 if typ is void:
|
|
14 return core.void
|
|
15 elif type(typ) is ProcedureType:
|
|
16 rType = coreType(typ.returntype)
|
|
17 fpTypes = [coreType(p.typ) for p in typ.parameters]
|
|
18 return core.FunctionType(rType, fpTypes)
|
|
19 print(typ)
|
|
20 raise NotImplementedError()
|
103
|
21
|
|
22 class KsIrGenerator:
|
|
23 def __init__(self):
|
110
|
24 self.builder = core.IRBuilder()
|
103
|
25 # Code generation functions:
|
|
26 def genexprcode(self, node):
|
110
|
27 """ Generate code for expressions! """
|
103
|
28 if isinstance(node, Binop):
|
|
29 """ Handle a binary operation (two arguments) of some kind """
|
110
|
30 lhs = self.genexprcode(node.a)
|
|
31 rhs = self.genexprcode(node.b)
|
103
|
32
|
110
|
33 if node.op == '*':
|
103
|
34 if node.typ.isType(integer):
|
110
|
35 return self.builder.createMul(lhs, rhs)
|
103
|
36 elif node.op == '+':
|
|
37 if node.typ.isType(integer):
|
110
|
38 return self.builder.createAdd(lhs, rhs)
|
103
|
39 elif node.op == '-':
|
|
40 if node.typ.isType(integer):
|
110
|
41 return self.builder.createSub(lhs, rhs)
|
|
42 Error('Unknown binop or type {0}'.format(node))
|
103
|
43
|
|
44 elif isinstance(node, Designator):
|
|
45 # dereference, array index. Make sure that the result comes into a register
|
|
46 if len(node.selectors) > 0:
|
110
|
47 Error('Only integer types implemented')
|
103
|
48 else:
|
|
49 # No selectors, load variable directly
|
110
|
50 print(node)
|
|
51 #Error('Cannot load variable type {0}'.format(node.typ))
|
103
|
52 elif type(node) is Constant:
|
110
|
53 return core.Constant(node.value, coreType(node.typ))
|
103
|
54 else:
|
|
55 Error('Cannot generate expression code for: {0}'.format(node))
|
|
56
|
|
57 def gencode(self, node):
|
|
58 """ Code generation function for AST nodes """
|
|
59 if isinstance(node, Module):
|
110
|
60 # Create module:
|
|
61 self.mod = core.Module(node.name)
|
107
|
62
|
110
|
63 globs = node.symtable.getAllLocal(Variable)
|
|
64 for g in globs:
|
|
65 print('global:', g)
|
|
66 # Loop over all functions:
|
107
|
67 print(node.symtable)
|
|
68 node.symtable.printTable()
|
|
69 funcs = node.symtable.getAllLocal(Procedure)
|
|
70 for f in funcs:
|
110
|
71 self.gencode(f)
|
104
|
72 # Create a function called init for this module:
|
|
73 self.mod.dump()
|
|
74 return self.mod
|
103
|
75
|
|
76 elif type(node) is Procedure:
|
110
|
77 ftype = coreType(node.typ)
|
|
78 print('function', node, ftype)
|
|
79 func = core.Function(ftype, node.name, self.mod)
|
|
80 bb = core.BasicBlock()
|
|
81 func.basicblocks.append(bb)
|
|
82 self.builder.setInsertPoint(bb)
|
|
83 self.gencode(node.block)
|
|
84 self.builder.setInsertPoint(None)
|
|
85 variables = node.symtable.getAllLocal(Variable)
|
|
86 print(variables)
|
103
|
87
|
|
88 elif isinstance(node, StatementSequence):
|
|
89 for s in node.statements:
|
|
90 self.gencode(s)
|
|
91
|
|
92 elif type(node) is ProcedureCall:
|
|
93 # Prepare parameters on the stack:
|
110
|
94 print("TODO")
|
103
|
95
|
|
96 elif type(node) is Assignment:
|
|
97 if node.lval.typ.isType(integer):
|
110
|
98 print('assign')
|
|
99 rhs = self.genexprcode(node.rval) # Calculate the value that has to be stored.
|
|
100 #self.gencode(node.lval)
|
|
101 print("TODO: assigment")
|
|
102
|
103
|
103 else:
|
|
104 Error('Assignments of other types not implemented')
|
|
105
|
|
106 elif type(node) is IfStatement:
|
|
107 self.genexprcode(node.condition)
|
104
|
108 print("TODO IF")
|
103
|
109 if node.falsestatement:
|
|
110 # If with else clause
|
104
|
111 pass
|
103
|
112 else:
|
|
113 # If without else clause
|
104
|
114 pass
|
103
|
115
|
|
116 elif isinstance(node, WhileStatement):
|
|
117 self.genexprcode(node.condition)
|
|
118 self.gencode(node.dostatements)
|
|
119 elif type(node) is ForStatement:
|
|
120 # Initial load of iterator variable:
|
|
121 self.genexprcode(node.begin)
|
|
122 self.genexprcode(node.end)
|
|
123 self.gencode(node.statements)
|
|
124 Error('No implementation of FOR statement')
|
|
125
|
|
126 elif isinstance(node, EmptyStatement):
|
110
|
127 pass # That was easy :)
|
103
|
128
|
|
129 elif type(node) is StringConstant:
|
|
130 self.strings.append(node)
|
|
131
|
|
132 elif type(node) is Designator:
|
110
|
133 Error('Can only gencode for designator with selectors')
|
103
|
134 else:
|
|
135 print('not generating code for {0}'.format(node))
|
|
136
|
104
|
137 def generateIr(self, context, ast):
|
103
|
138 """ ir generation front end """
|
104
|
139 # Create a new context for this code.
|
|
140 self.context = context
|
103
|
141 return self.gencode(ast)
|
|
142
|