Mercurial > lcfOS
comparison ide/compiler/nodes.py @ 1:92df07bc2081
Initial import of compiler
author | windel |
---|---|
date | Sun, 18 Sep 2011 19:00:29 +0200 |
parents | |
children | 0d5ef85b8698 |
comparison
equal
deleted
inserted
replaced
0:1a4faf9ef1ea | 1:92df07bc2081 |
---|---|
1 """ | |
2 Parse tree elements | |
3 """ | |
4 class Node: | |
5 def getChildren(self): | |
6 children = [] | |
7 members = dir(self) | |
8 for member in members: | |
9 member = getattr(self, member) | |
10 if isinstance(member, Node): | |
11 children.append(member) | |
12 elif type(member) is list: | |
13 for mi in member: | |
14 if isinstance(mi, Node): | |
15 children.append(mi) | |
16 return children | |
17 | |
18 class Symbol(Node): | |
19 pass | |
20 | |
21 # Selectors: | |
22 class Field(Node): | |
23 def __init__(self, fieldname): | |
24 self.fieldname = fieldname | |
25 def __repr__(self): | |
26 return 'FLD {0}'.format(self.fieldname) | |
27 | |
28 class Index(Node): | |
29 def __init__(self, index, typ): | |
30 self.index = index | |
31 self.typ = typ | |
32 def __repr__(self): | |
33 return 'IDX {0}'.format(self.index) | |
34 | |
35 class Deref(Node): | |
36 pass | |
37 | |
38 class Designator(Node): | |
39 def __init__(self, obj, selectors, typ): | |
40 self.obj = obj | |
41 self.selectors = selectors | |
42 self.typ = typ | |
43 def __repr__(self): | |
44 return 'DESIGNATOR {0}, selectors {1}, type {2}'.format(self.obj, self.selectors, self.typ) | |
45 | |
46 """ | |
47 Type classes | |
48 """ | |
49 def isType(a, b): | |
50 """ Compare types a and b and check if they are equal """ | |
51 if type(a) is type(b): | |
52 if type(a) is BaseType: | |
53 return (a.name == b.name) and (a.size == b.size) | |
54 elif type(a) is ArrayType: | |
55 return (a.dimension == b.dimension) and isType(a.elementType, b.elementType) | |
56 elif type(a) is ProcedureType: | |
57 if len(a.parameters) != len(b.parameters): | |
58 print('Number of parameters does not match') | |
59 return False | |
60 for aparam, bparam in zip(a.parameters, b.parameters): | |
61 if not isType(aparam.typ, bparam.typ): | |
62 print('Parameter {0} does not match parameter {1}'.format(aparam, bparam)) | |
63 return False | |
64 if a.result is None: | |
65 # TODO: how to handle a None return type?? | |
66 pass | |
67 if not isType(a.result, b.result): | |
68 print('Procedure return value mismatch {0} != {1}'.format(a.result, b.result)) | |
69 return False | |
70 return True | |
71 else: | |
72 print(a) | |
73 print(b) | |
74 Error('Not implemented {0}'.format(a)) | |
75 else: | |
76 return False | |
77 | |
78 class Type: | |
79 def isType(self, b): | |
80 return isType(self, b) | |
81 | |
82 class BaseType(Type): | |
83 def __init__(self, name, size): | |
84 self.name = name | |
85 self.size = size | |
86 def __repr__(self): | |
87 return '[TYPE {0}]'.format(self.name) | |
88 | |
89 class NilType(Node): | |
90 # TODO: how to handle nil values?? | |
91 def __repr__(self): | |
92 return 'NILTYPE' | |
93 | |
94 class ArrayType(Type): | |
95 def __init__(self, dimension, elementType): | |
96 self.dimension = dimension | |
97 self.elementType = elementType | |
98 self.size = elementType.size * dimension | |
99 def __repr__(self): | |
100 return '[ARRAY {0} of {1}]'.format(self.dimension, self.elementType) | |
101 | |
102 class RecordType(Type): | |
103 def __init__(self, fields): | |
104 self.fields = fields | |
105 self.size = 0 | |
106 for fieldname in self.fields: | |
107 self.size += self.fields[fieldname].size | |
108 def __repr__(self): | |
109 return '[RECORD {0}]'.format(self.fields) | |
110 | |
111 class PointerType(Type): | |
112 def __init__(self, pointedType): | |
113 self.pointedType = pointedType | |
114 self.size = 8 | |
115 def __repr__(self): | |
116 return '[POINTER {0}]'.format(self.pointedType) | |
117 | |
118 class ProcedureType(Type): | |
119 def __init__(self, parameters, returntype): | |
120 self.parameters = parameters | |
121 self.returntype = returntype | |
122 def __repr__(self): | |
123 return '[PROCTYPE {0} RET {1}]'.format(self.parameters, self.returntype) | |
124 | |
125 class DefinedType(Type): | |
126 def __init__(self, name, typ): | |
127 self.name = name | |
128 self.typ = typ | |
129 def __repr__(self): | |
130 return 'Named type {0} of type {1}'.format(self.name, self.typ) | |
131 | |
132 # Classes for constants like numbers and strings: | |
133 class StringConstant(Symbol): | |
134 def __init__(self, txt): | |
135 self.txt = txt | |
136 self.typ = 'string' | |
137 def __repr__(self): | |
138 return "STRING '{0}'".format(self.txt) | |
139 | |
140 # Variables, parameters, local variables, constants: | |
141 class Constant(Symbol): | |
142 def __init__(self, value, typ, name=None, public=False): | |
143 self.name = name | |
144 self.value = value | |
145 self.typ = typ | |
146 self.public = public | |
147 def __repr__(self): | |
148 return 'CONSTANT {0} = {1}'.format(self.name, self.value) | |
149 | |
150 class Variable(Symbol): | |
151 def __init__(self, name, typ, public): | |
152 self.name = name | |
153 self.typ = typ | |
154 self.public = public | |
155 self.isLocal = False | |
156 self.isReadOnly = False | |
157 self.isParameter = False | |
158 def __repr__(self): | |
159 txt = '[public] ' if self.public else '' | |
160 return '{2}VAR {0} : {1}'.format(self.name, self.typ, txt) | |
161 | |
162 class Parameter(Node): | |
163 """ A parameter has a passing method, name and typ """ | |
164 def __init__(self, kind, name, typ): | |
165 self.kind = kind | |
166 self.name = name | |
167 self.typ = typ | |
168 def __repr__(self): | |
169 return 'PARAM {0} {1} {2}'.format(self.kind, self.name, self.typ) | |
170 | |
171 # Operations: | |
172 class Unop(Node): | |
173 def __init__(self, a, op, typ): | |
174 self.a = a | |
175 self.op = op # Operation: '+', '-', '*', '/', 'mod' | |
176 self.typ = typ | |
177 self.place = None | |
178 def __repr__(self): | |
179 return 'UNOP {0}'.format(self.op) | |
180 | |
181 class Binop(Node): | |
182 def __init__(self, a, op, b, typ): | |
183 self.a = a | |
184 self.b = b | |
185 self.op = op # Operation: '+', '-', '*', '/', 'mod' | |
186 self.typ = typ # Resulting type :) | |
187 self.place = None | |
188 def __repr__(self): | |
189 return 'BINOP {0} {1}'.format(self.op, self.typ) | |
190 | |
191 class Relop(Node): | |
192 def __init__(self, a, relop, b, typ): | |
193 self.a = a | |
194 self.relop = relop | |
195 self.b = b | |
196 self.typ = typ | |
197 def __repr__(self): | |
198 return 'RELOP {0}'.format(self.relop) | |
199 | |
200 # Modules | |
201 class Module(Node): | |
202 def __init__(self, name): | |
203 self.name = name | |
204 def __repr__(self): | |
205 return 'MODULE {0}'.format(self.name) | |
206 | |
207 # Imports and Exports: | |
208 class ImportedSymbol(Node): | |
209 def __init__(self, modname, name): | |
210 self.modname = modname | |
211 self.name = name | |
212 def __repr__(self): | |
213 return 'IMPORTED SYMBOL {0}'.format(self.name) | |
214 | |
215 class ExportedSymbol(Node): | |
216 def __init__(self, name, typ): | |
217 self.name = name | |
218 self.typ = typ | |
219 def __repr__(self): | |
220 return 'EXPORTED PROCEDURE {0} : {1}'.format(self.name, self.typ) | |
221 | |
222 # Procedure types | |
223 class BuiltinProcedure(Node): | |
224 def __init__(self, name, typ): | |
225 self.name = name | |
226 self.typ = typ | |
227 def __repr__(self): | |
228 return 'BUILTIN PROCEDURE {0} : {1}'.format(self.name, self.typ) | |
229 | |
230 class Procedure(Symbol): | |
231 """ Actual implementation of a function """ | |
232 def __init__(self, name, typ, block, symtable, retexpr): | |
233 self.name = name | |
234 self.block = block | |
235 self.symtable = symtable | |
236 self.typ = typ | |
237 self.retexpr = retexpr | |
238 def __repr__(self): | |
239 return 'PROCEDURE {0} {1}'.format(self.name, self.typ) | |
240 | |
241 # Statements | |
242 class StatementSequence(Node): | |
243 def __init__(self, statements): | |
244 self.statements = statements | |
245 def __repr__(self): | |
246 return 'STATEMENTSEQUENCE' | |
247 | |
248 class EmptyStatement(Node): | |
249 def __repr__(self): | |
250 return 'EMPTY STATEMENT' | |
251 | |
252 class Assignment(Node): | |
253 def __init__(self, lval, rval): | |
254 self.lval = lval | |
255 self.rval = rval | |
256 def __repr__(self): | |
257 return 'ASSIGNMENT' | |
258 | |
259 class ProcedureCall(Node): | |
260 def __init__(self, proc, args): | |
261 self.proc = proc | |
262 self.args = args | |
263 self.typ = proc.typ.returntype | |
264 def __repr__(self): | |
265 return 'CALL {0} '.format(self.proc) | |
266 | |
267 class IfStatement(Node): | |
268 def __init__(self, condition, truestatement, falsestatement=None): | |
269 self.condition = condition | |
270 self.truestatement = truestatement | |
271 self.falsestatement = falsestatement | |
272 def __repr__(self): | |
273 return 'IF-statement' | |
274 | |
275 class CaseStatement(Node): | |
276 def __init__(self, condition): | |
277 self.condition = condition | |
278 def __repr__(self): | |
279 return 'CASE-statement' | |
280 | |
281 class WhileStatement(Node): | |
282 def __init__(self, condition, statements): | |
283 self.condition = condition | |
284 self.dostatements = statements | |
285 def __repr__(self): | |
286 return 'WHILE-statement' | |
287 | |
288 class ForStatement(Node): | |
289 def __init__(self, variable, begin, end, increment, statements): | |
290 self.variable = variable | |
291 self.begin = begin | |
292 self.end = end | |
293 self.increment = increment | |
294 self.statements = statements | |
295 def __repr__(self): | |
296 return 'FOR-statement' | |
297 | |
298 class AsmCode(Node): | |
299 def __init__(self, asmcode): | |
300 self.asmcode = asmcode | |
301 def __repr__(self): | |
302 return 'ASM CODE' | |
303 |