comparison python/ppci/frontends/ks/irgenerator.py @ 110:9e552d34bd60

Work on compiler
author Windel Bouwman
date Fri, 04 Jan 2013 15:25:58 +0100
parents 1544e7a4aa98
children
comparison
equal deleted inserted replaced
108:8267ba1dbce3 110:9e552d34bd60
3 """ 3 """
4 4
5 from .nodes import * 5 from .nodes import *
6 from ...core.errors import Error 6 from ...core.errors import Error
7 from ... import core 7 from ... import core
8 from .builtin import real, integer, boolean, char 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()
9 23
10 class KsIrGenerator: 24 class KsIrGenerator:
11 def __init__(self): 25 def __init__(self):
12 pass 26 self.builder = core.IRBuilder()
13
14 # Code generation functions: 27 # Code generation functions:
15 def genexprcode(self, node): 28 def genexprcode(self, node):
16 """ 29 """ Generate code for expressions! """
17 Generate code for expressions!
18 Recursively evaluates, and ensures a register contains the answer.
19 register is an integer register or a floating point reg
20 """
21 if isinstance(node, Binop): 30 if isinstance(node, Binop):
22 """ Handle a binary operation (two arguments) of some kind """ 31 """ Handle a binary operation (two arguments) of some kind """
23 self.genexprcode(node.a) 32 lhs = self.genexprcode(node.a)
24 self.genexprcode(node.b) 33 rhs = self.genexprcode(node.b)
25 34
26 if node.op == 'mod': 35 if node.op == '*':
27 assert(node.typ.isType(integer))
28 elif node.op == 'div':
29 assert(node.typ.isType(integer))
30 elif node.op == '*':
31 if node.typ.isType(integer): 36 if node.typ.isType(integer):
32 pass 37 return self.builder.createMul(lhs, rhs)
33 elif node.op == '+': 38 elif node.op == '+':
34 if node.typ.isType(integer): 39 if node.typ.isType(integer):
35 pass 40 return self.builder.createAdd(lhs, rhs)
36 elif node.op == '-': 41 elif node.op == '-':
37 if node.typ.isType(integer): 42 if node.typ.isType(integer):
38 pass 43 return self.builder.createSub(lhs, rhs)
39 else: 44 Error('Unknown binop or type {0}'.format(node))
40 Error('Unknown Binop {0}'.format(node.op))
41
42 elif type(node) is Unop:
43 if node.op == 'INTTOREAL':
44 self.genexprcode(node.a)
45 code.append('Unop inttoreal TODO')
46 elif node.op == 'ABS':
47 if isType(node.typ, real):
48 Error('ABS error integer')
49 elif isType(node.typ, integer):
50 code = []
51 Error('ABS error integer')
52 else:
53 Error('ABS error')
54 else:
55 Error('Unknown Unop {0}'.format(node.op))
56 45
57 elif isinstance(node, Designator): 46 elif isinstance(node, Designator):
58 # dereference, array index. Make sure that the result comes into a register 47 # dereference, array index. Make sure that the result comes into a register
59 if len(node.selectors) > 0: 48 if len(node.selectors) > 0:
60 self.gencode(node) # Load the pointer into some register 49 Error('Only integer types implemented')
61
62 # Now we can access the object at location '[node.reg]':
63 if node.typ.isType(integer):
64 self.addCode( mov(node.reg, [node.reg, 0x0]) )
65 else:
66 Error('Only integer types implemented')
67 else: 50 else:
68 # No selectors, load variable directly 51 # No selectors, load variable directly
69 if node.obj.typ.isType(integer): 52 print(node)
70 if type(node.obj) is Constant: 53 #Error('Cannot load variable type {0}'.format(node.typ))
71 self.genexprcode(node.obj)
72 node.reg = node.obj.reg
73 else:
74 pass
75 # Get a register to store the integer value
76 else:
77 Error('Cannot load variable type {0}'.format(node.typ))
78 elif type(node) is Constant: 54 elif type(node) is Constant:
79 print('TODO: constant') 55 return core.Constant(node.value, coreType(node.typ))
80 else: 56 else:
81 Error('Cannot generate expression code for: {0}'.format(node)) 57 Error('Cannot generate expression code for: {0}'.format(node))
82 58
83 def gencode(self, node): 59 def gencode(self, node):
84 """ Code generation function for AST nodes """ 60 """ Code generation function for AST nodes """
85 if isinstance(node, Module): 61 if isinstance(node, Module):
86 # TODO: recurse! 62 # Create module:
63 self.mod = core.Module(node.name)
87 64
65 globs = node.symtable.getAllLocal(Variable)
66 for g in globs:
67 print('global:', g)
68 # Loop over all functions:
88 print(node.symtable) 69 print(node.symtable)
89 node.symtable.printTable() 70 node.symtable.printTable()
90 funcs = node.symtable.getAllLocal(Procedure) 71 funcs = node.symtable.getAllLocal(Procedure)
91 for f in funcs: 72 for f in funcs:
92 print('function', f) 73 self.gencode(f)
93 ftype = f.typ.coreType()
94 ftype = core.FunctionType(retType)
95
96 self.mod = core.Module(node.name)
97 # Create a function called init for this module: 74 # Create a function called init for this module:
98 ftype = core.FunctionType(self.context.VoidType, [])
99 func = core.Function(ftype, "init", self.mod)
100 bb = self.gencode(node.initcode)
101 self.mod.dump() 75 self.mod.dump()
102 return self.mod 76 return self.mod
103 77
104 elif type(node) is Procedure: 78 elif type(node) is Procedure:
105 # calculate offsets for local variables and parameters 79 ftype = coreType(node.typ)
106 # Variable location relative to 'rbp' register 80 print('function', node, ftype)
107 variables = node.symtable.getAllLocal(Variable) 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)
108 89
109 elif isinstance(node, StatementSequence): 90 elif isinstance(node, StatementSequence):
110 for s in node.statements: 91 for s in node.statements:
111 self.gencode(s) 92 self.gencode(s)
112 93
113 elif type(node) is ProcedureCall: 94 elif type(node) is ProcedureCall:
114 # Prepare parameters on the stack: 95 # Prepare parameters on the stack:
115 assert(len(node.args) == len(node.proc.typ.parameters)) 96 print("TODO")
116 for arg, param in zip(node.args, node.proc.typ.parameters):
117
118 if param.kind == 'value':
119 self.genexprcode(arg)
120 self.addCode( push(arg.reg) )
121 self.freereg( arg )
122 stacksize += 8
123 else:
124 Error('Parameter kind other than value')
125 97
126 elif type(node) is Assignment: 98 elif type(node) is Assignment:
127 if node.lval.typ.isType(integer): 99 if node.lval.typ.isType(integer):
128 # TODO if node.rval is Constant of some datatype, move it to mem directly 100 print('assign')
129 self.genexprcode(node.rval) # Calculate the value that has to be stored. 101 rhs = self.genexprcode(node.rval) # Calculate the value that has to be stored.
130 print("TODO") 102 #self.gencode(node.lval)
103 print("TODO: assigment")
104
131 else: 105 else:
132 Error('Assignments of other types not implemented') 106 Error('Assignments of other types not implemented')
133 # TODO if left and right are designators, do some sort of memcpy.
134 107
135 elif type(node) is IfStatement: 108 elif type(node) is IfStatement:
136 self.genexprcode(node.condition) 109 self.genexprcode(node.condition)
137 print("TODO IF") 110 print("TODO IF")
138 if node.falsestatement: 111 if node.falsestatement:
150 self.genexprcode(node.begin) 123 self.genexprcode(node.begin)
151 self.genexprcode(node.end) 124 self.genexprcode(node.end)
152 self.gencode(node.statements) 125 self.gencode(node.statements)
153 Error('No implementation of FOR statement') 126 Error('No implementation of FOR statement')
154 127
155 elif type(node) is AsmCode:
156 def processOperand(op):
157 if type(op) is list:
158 if type(op[0]) is Variable:
159 var = op[0]
160 if var.isLocal:
161 return ['rbp', var.offset]
162 else:
163 Error('Can only use local variables in inline assembler')
164 return op
165 for asmline in node.asmcode:
166 opcode, operands = asmline
167 operands = [processOperand(opx) for opx in operands]
168 print('assembling', opcode, *operands)
169 func,nargs = opcodes[opcode]
170 code = func(*operands)
171 self.addCode(code)
172
173 elif isinstance(node, EmptyStatement): 128 elif isinstance(node, EmptyStatement):
174 pass 129 pass # That was easy :)
175 130
176 elif type(node) is StringConstant: 131 elif type(node) is StringConstant:
177 self.strings.append(node) 132 self.strings.append(node)
178 self.data.append(node.value) # Add string to the data section
179 133
180 elif type(node) is Designator: 134 elif type(node) is Designator:
181 if len(node.selectors) > 0: 135 Error('Can only gencode for designator with selectors')
182 self.getreg(node)
183 # Load starting address
184 if node.obj.isLocal:
185 self.addCode( leareg64(node.reg, ['rbp', node.obj.offset]) )
186 else:
187 # Global variables need to be relocated...
188 self.addCode(leareg64(node.reg, ['RIP', 0]))
189 self.fixCode(self.rip - 4, imm32(node.obj.offset - self.rip))
190 # Loop over all designators..
191 for selector in node.selectors:
192 if type(selector) is Index:
193 # Deref an array index
194 self.genexprcode(selector.index)
195 self.freereg(selector)
196 elif type(selector) is Field:
197 print('Field')
198 Error('Field not implemented')
199 else:
200 Error('Unknown selector')
201 else:
202 Error('Can only gencode for designator with selectors')
203 else: 136 else:
204 print('not generating code for {0}'.format(node)) 137 print('not generating code for {0}'.format(node))
205 138
206 def generateIr(self, context, ast): 139 def generateIr(self, context, ast):
207 """ ir generation front end """ 140 """ ir generation front end """