Mercurial > lcfOS
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 """ |