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