Mercurial > lcfOS
comparison python/ks/irgenerator.py @ 146:91af0e40f868
Moved several files
author | Windel Bouwman |
---|---|
date | Fri, 22 Feb 2013 10:31:58 +0100 |
parents | python/ppci/frontends/ks/irgenerator.py@9e552d34bd60 |
children | 4fd075e8259c |
comparison
equal
deleted
inserted
replaced
145:c101826ffe2b | 146:91af0e40f868 |
---|---|
1 """ | |
2 Generates ir code from ast tree. | |
3 """ | |
4 | |
5 from .nodes import * | |
6 from ...core.errors import Error | |
7 from ... import core | |
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() | |
23 | |
24 class KsIrGenerator: | |
25 def __init__(self): | |
26 self.builder = core.IRBuilder() | |
27 # Code generation functions: | |
28 def genexprcode(self, node): | |
29 """ Generate code for expressions! """ | |
30 if isinstance(node, Binop): | |
31 """ Handle a binary operation (two arguments) of some kind """ | |
32 lhs = self.genexprcode(node.a) | |
33 rhs = self.genexprcode(node.b) | |
34 | |
35 if node.op == '*': | |
36 if node.typ.isType(integer): | |
37 return self.builder.createMul(lhs, rhs) | |
38 elif node.op == '+': | |
39 if node.typ.isType(integer): | |
40 return self.builder.createAdd(lhs, rhs) | |
41 elif node.op == '-': | |
42 if node.typ.isType(integer): | |
43 return self.builder.createSub(lhs, rhs) | |
44 Error('Unknown binop or type {0}'.format(node)) | |
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: | |
49 Error('Only integer types implemented') | |
50 else: | |
51 # No selectors, load variable directly | |
52 print(node) | |
53 #Error('Cannot load variable type {0}'.format(node.typ)) | |
54 elif type(node) is Constant: | |
55 return core.Constant(node.value, coreType(node.typ)) | |
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): | |
62 # Create module: | |
63 self.mod = core.Module(node.name) | |
64 | |
65 globs = node.symtable.getAllLocal(Variable) | |
66 for g in globs: | |
67 print('global:', g) | |
68 # Loop over all functions: | |
69 print(node.symtable) | |
70 node.symtable.printTable() | |
71 funcs = node.symtable.getAllLocal(Procedure) | |
72 for f in funcs: | |
73 self.gencode(f) | |
74 # Create a function called init for this module: | |
75 self.mod.dump() | |
76 return self.mod | |
77 | |
78 elif type(node) is Procedure: | |
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) | |
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: | |
96 print("TODO") | |
97 | |
98 elif type(node) is Assignment: | |
99 if node.lval.typ.isType(integer): | |
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 | |
105 else: | |
106 Error('Assignments of other types not implemented') | |
107 | |
108 elif type(node) is IfStatement: | |
109 self.genexprcode(node.condition) | |
110 print("TODO IF") | |
111 if node.falsestatement: | |
112 # If with else clause | |
113 pass | |
114 else: | |
115 # If without else clause | |
116 pass | |
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): | |
129 pass # That was easy :) | |
130 | |
131 elif type(node) is StringConstant: | |
132 self.strings.append(node) | |
133 | |
134 elif type(node) is Designator: | |
135 Error('Can only gencode for designator with selectors') | |
136 else: | |
137 print('not generating code for {0}'.format(node)) | |
138 | |
139 def generateIr(self, context, ast): | |
140 """ ir generation front end """ | |
141 # Create a new context for this code. | |
142 self.context = context | |
143 return self.gencode(ast) | |
144 |