Mercurial > lcfOS
annotate python/ppci/c3/astnodes.py @ 394:988f3fb861e4
c3 code generator rewrite
author | Windel Bouwman |
---|---|
date | Thu, 22 May 2014 08:14:12 +0200 |
parents | 6ae782a085e0 |
children |
rev | line source |
---|---|
148 | 1 """ |
213 | 2 AST (abstract syntax tree) nodes for the c3 language. |
3 The tree is build by the parser. | |
4 Then it is checked | |
5 Finally code is generated from it. | |
148 | 6 """ |
7 | |
288 | 8 |
148 | 9 class Node: |
306 | 10 """ Base class of all nodes in a AST """ |
288 | 11 pass |
12 | |
148 | 13 |
300 | 14 # Variables, parameters, local variables, constants and named types: |
15 class Symbol(Node): | |
308 | 16 """ Symbol is the base class for all named things like variables, |
306 | 17 functions, constants and types and modules """ |
300 | 18 def __init__(self, name): |
19 self.name = name | |
20 self.refs = [] | |
21 | |
22 def addRef(self, r): | |
23 self.refs.append(r) | |
24 | |
25 @property | |
26 def References(self): | |
27 return self.refs | |
28 | |
29 | |
213 | 30 # Modules |
301 | 31 class Package(Symbol): |
213 | 32 def __init__(self, name, loc): |
301 | 33 super().__init__(name) |
213 | 34 self.loc = loc |
35 self.declarations = [] | |
251
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
249
diff
changeset
|
36 self.imports = [] |
288 | 37 |
336
d1ecc493384e
Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents:
316
diff
changeset
|
38 def add_declaration(self, decl): |
d1ecc493384e
Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents:
316
diff
changeset
|
39 self.declarations.append(decl) |
d1ecc493384e
Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents:
316
diff
changeset
|
40 if isinstance(decl, Function): |
d1ecc493384e
Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents:
316
diff
changeset
|
41 decl.package = self |
d1ecc493384e
Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents:
316
diff
changeset
|
42 |
389 | 43 @property |
44 def Types(self): | |
45 return self.innerScope.Types | |
46 | |
394 | 47 @property |
48 def Functions(self): | |
49 return self.innerScope.Functions | |
50 | |
213 | 51 def __repr__(self): |
284 | 52 return 'MODULE {}'.format(self.name) |
53 | |
213 | 54 |
149 | 55 class Type(Node): |
306 | 56 """ Base class of all types """ |
288 | 57 pass |
272 | 58 |
148 | 59 |
300 | 60 class NamedType(Type, Symbol): |
308 | 61 """ Some types are named, for example a user defined type (typedef) |
306 | 62 and built in types. That is why this class derives from both Type |
63 and Symbol. """ | |
272 | 64 def __init__(self, name): |
300 | 65 Symbol.__init__(self, name) |
66 | |
67 | |
68 class BaseType(NamedType): | |
306 | 69 """ Built in type """ |
300 | 70 def __init__(self, name): |
71 super().__init__(name) | |
272 | 72 |
73 def __repr__(self): | |
74 return '{}'.format(self.name) | |
75 | |
148 | 76 |
77 class FunctionType(Type): | |
306 | 78 """ Function blueprint, defines argument types and return type """ |
288 | 79 def __init__(self, parametertypes, returntype): |
80 self.parametertypes = parametertypes | |
81 self.returntype = returntype | |
82 | |
83 def __repr__(self): | |
84 params = ', '.join([str(v) for v in self.parametertypes]) | |
85 return '{1} f({0})'.format(params, self.returntype) | |
148 | 86 |
272 | 87 |
213 | 88 class PointerType(Type): |
288 | 89 """ A type that points to data of some other type """ |
213 | 90 def __init__(self, ptype): |
306 | 91 assert isinstance(ptype, Type) or isinstance(ptype, Expression) |
213 | 92 self.ptype = ptype |
288 | 93 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
94 def __repr__(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
95 return '({}*)'.format(self.ptype) |
213 | 96 |
230 | 97 |
227 | 98 class StructField: |
316 | 99 """ Field of a struct type """ |
227 | 100 def __init__(self, name, typ): |
306 | 101 assert type(name) is str |
227 | 102 self.name = name |
103 self.typ = typ | |
230 | 104 |
389 | 105 def __repr__(self): |
106 return 'Member {}'.format(self.name) | |
107 | |
227 | 108 |
213 | 109 class StructureType(Type): |
306 | 110 """ Struct type consisting of several named members """ |
213 | 111 def __init__(self, mems): |
112 self.mems = mems | |
306 | 113 assert all(type(mem) is StructField for mem in mems) |
230 | 114 |
225 | 115 def hasField(self, name): |
227 | 116 for mem in self.mems: |
117 if name == mem.name: | |
225 | 118 return True |
119 return False | |
230 | 120 |
225 | 121 def fieldType(self, name): |
230 | 122 return self.findField(name).typ |
123 | |
124 def fieldOffset(self, name): | |
125 return self.findField(name).offset | |
126 | |
127 def findField(self, name): | |
227 | 128 for mem in self.mems: |
129 if name == mem.name: | |
230 | 130 return mem |
131 raise KeyError(name) | |
225 | 132 |
230 | 133 def __repr__(self): |
134 return 'STRUCT' | |
213 | 135 |
272 | 136 |
354 | 137 class ArrayType(Type): |
138 """ Array type """ | |
139 def __init__(self, element_type, size): | |
140 self.element_type = element_type | |
141 self.size = size | |
142 | |
143 def __repr__(self): | |
144 return 'ARRAY {}'.format(self.size) | |
145 | |
146 | |
300 | 147 class DefinedType(NamedType): |
288 | 148 """ A named type indicating another type """ |
225 | 149 def __init__(self, name, typ, loc): |
150 assert isinstance(name, str) | |
300 | 151 super().__init__(name) |
225 | 152 self.typ = typ |
153 self.loc = loc | |
230 | 154 |
225 | 155 def __repr__(self): |
156 return 'Named type {0} of type {1}'.format(self.name, self.typ) | |
148 | 157 |
221 | 158 |
148 | 159 class Constant(Symbol): |
316 | 160 """ Constant definition """ |
213 | 161 def __init__(self, name, typ, value): |
272 | 162 super().__init__(name) |
163 self.typ = typ | |
164 self.value = value | |
165 | |
213 | 166 def __repr__(self): |
272 | 167 return 'CONSTANT {0} = {1}'.format(self.name, self.value) |
168 | |
148 | 169 |
170 class Variable(Symbol): | |
272 | 171 def __init__(self, name, typ): |
172 super().__init__(name) | |
173 self.typ = typ | |
174 self.isLocal = False | |
175 self.isParameter = False | |
176 | |
177 def __repr__(self): | |
178 return 'Var {} [{}]'.format(self.name, self.typ) | |
179 | |
180 | |
181 class LocalVariable(Variable): | |
182 def __init__(self, name, typ): | |
183 super().__init__(name, typ) | |
184 self.isLocal = True | |
185 | |
186 | |
187 class FormalParameter(Variable): | |
188 def __init__(self, name, typ): | |
189 super().__init__(name, typ) | |
190 self.isParameter = True | |
191 | |
148 | 192 |
150 | 193 # Procedure types |
194 class Function(Symbol): | |
213 | 195 """ Actual implementation of a function """ |
196 def __init__(self, name, loc): | |
197 super().__init__(name) | |
198 self.loc = loc | |
215 | 199 self.declarations = [] |
213 | 200 |
336
d1ecc493384e
Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents:
316
diff
changeset
|
201 def add_declaration(self, decl): |
d1ecc493384e
Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents:
316
diff
changeset
|
202 self.declarations.append(decl) |
d1ecc493384e
Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents:
316
diff
changeset
|
203 |
213 | 204 def __repr__(self): |
217 | 205 return 'Func {}'.format(self.name) |
148 | 206 |
288 | 207 |
163 | 208 # Operations / Expressions: |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
209 class Expression(Node): |
230 | 210 def __init__(self, loc): |
211 self.loc = loc | |
212 | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
213 |
393 | 214 class Sizeof(Expression): |
215 def __init__(self, typ, loc): | |
216 super().__init__(loc) | |
217 self.query_typ = typ | |
218 | |
219 | |
225 | 220 class Deref(Expression): |
221 def __init__(self, ptr, loc): | |
230 | 222 super().__init__(loc) |
225 | 223 assert isinstance(ptr, Expression) |
224 self.ptr = ptr | |
288 | 225 |
225 | 226 def __repr__(self): |
288 | 227 return 'DEREF {}'.format(self.ptr) |
225 | 228 |
230 | 229 |
230 class TypeCast(Expression): | |
231 def __init__(self, to_type, x, loc): | |
232 super().__init__(loc) | |
233 self.to_type = to_type | |
234 self.a = x | |
288 | 235 |
230 | 236 def __repr__(self): |
237 return 'TYPECAST {}'.format(self.to_type) | |
238 | |
239 | |
306 | 240 class Member(Expression): |
241 """ Field reference of some object, can also be package selection """ | |
225 | 242 def __init__(self, base, field, loc): |
230 | 243 super().__init__(loc) |
225 | 244 assert isinstance(base, Expression) |
245 assert isinstance(field, str) | |
246 self.base = base | |
247 self.field = field | |
288 | 248 |
225 | 249 def __repr__(self): |
306 | 250 return 'MEMBER {}.{}'.format(self.base, self.field) |
225 | 251 |
230 | 252 |
354 | 253 class Index(Expression): |
254 """ Index something, for example an array """ | |
255 def __init__(self, base, i, loc): | |
256 super().__init__(loc) | |
257 self.base = base | |
258 self.i = i | |
259 | |
260 def __repr__(self): | |
261 return 'Index {}'.format(self.i) | |
262 | |
263 | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
264 class Unop(Expression): |
306 | 265 """ Operation on one operand """ |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
266 def __init__(self, op, a, loc): |
230 | 267 super().__init__(loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
268 assert isinstance(a, Expression) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
269 assert isinstance(op, str) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
270 self.a = a |
230 | 271 self.op = op |
288 | 272 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
273 def __repr__(self): |
288 | 274 return 'UNOP {}'.format(self.op) |
275 | |
148 | 276 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
277 class Binop(Expression): |
306 | 278 """ Expression taking two operands and one operator """ |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
279 def __init__(self, a, op, b, loc): |
230 | 280 super().__init__(loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
281 assert isinstance(a, Expression), type(a) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
282 assert isinstance(b, Expression) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
283 assert isinstance(op, str) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
284 self.a = a |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
285 self.b = b |
288 | 286 self.op = op # Operation: '+', '-', '*', '/', 'mod' |
148 | 287 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
288 def __repr__(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
289 return 'BINOP {}'.format(self.op) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
290 |
288 | 291 |
306 | 292 class Identifier(Expression): |
293 """ Reference to some identifier, can be anything from package, variable | |
294 function or type, any named thing! """ | |
228 | 295 def __init__(self, target, loc): |
230 | 296 super().__init__(loc) |
228 | 297 self.target = target |
288 | 298 |
228 | 299 def __repr__(self): |
306 | 300 return 'ID {}'.format(self.target) |
163 | 301 |
284 | 302 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
303 class Literal(Expression): |
306 | 304 """ Constant value or string """ |
228 | 305 def __init__(self, val, loc): |
230 | 306 super().__init__(loc) |
228 | 307 self.val = val |
288 | 308 |
228 | 309 def __repr__(self): |
310 return 'LITERAL {}'.format(self.val) | |
150 | 311 |
284 | 312 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
313 class FunctionCall(Expression): |
306 | 314 """ Call to a some function """ |
228 | 315 def __init__(self, proc, args, loc): |
230 | 316 super().__init__(loc) |
228 | 317 self.proc = proc |
318 self.args = args | |
288 | 319 |
228 | 320 def __repr__(self): |
321 return 'CALL {0} '.format(self.proc) | |
148 | 322 |
284 | 323 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
324 # Statements |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
325 class Statement(Node): |
306 | 326 """ Base class of all statements """ |
228 | 327 def __init__(self, loc): |
328 self.loc = loc | |
329 | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
330 |
307 | 331 class Empty(Statement): |
306 | 332 """ Empty statement which does nothing! """ |
333 def __init__(self): | |
334 super().__init__(None) | |
335 | |
336 def __repr__(self): | |
337 return 'NOP' | |
338 | |
339 | |
307 | 340 class Compound(Statement): |
306 | 341 """ Statement consisting of a sequence of other statements """ |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
342 def __init__(self, statements): |
249 | 343 super().__init__(None) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
344 self.statements = statements |
228 | 345 for s in self.statements: |
346 assert isinstance(s, Statement) | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
347 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
348 def __repr__(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
349 return 'COMPOUND STATEMENT' |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
350 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
351 |
307 | 352 class Return(Statement): |
228 | 353 def __init__(self, expr, loc): |
354 super().__init__(loc) | |
355 self.expr = expr | |
356 | |
357 def __repr__(self): | |
358 return 'RETURN STATEMENT' | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
359 |
284 | 360 |
222 | 361 class Assignment(Statement): |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
362 def __init__(self, lval, rval, loc): |
228 | 363 super().__init__(loc) |
306 | 364 assert isinstance(lval, Expression) |
365 assert isinstance(rval, Expression) | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
366 self.lval = lval |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
367 self.rval = rval |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
368 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
369 def __repr__(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
370 return 'ASSIGNMENT' |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
371 |
288 | 372 |
222 | 373 class ExpressionStatement(Statement): |
374 def __init__(self, ex, loc): | |
228 | 375 super().__init__(loc) |
222 | 376 self.ex = ex |
228 | 377 |
222 | 378 def __repr__(self): |
379 return 'Epression' | |
380 | |
228 | 381 |
307 | 382 class If(Statement): |
228 | 383 def __init__(self, condition, truestatement, falsestatement, loc): |
384 super().__init__(loc) | |
385 self.condition = condition | |
386 self.truestatement = truestatement | |
387 self.falsestatement = falsestatement | |
388 | |
389 def __repr__(self): | |
390 return 'IF-statement' | |
391 | |
148 | 392 |
393 | 393 class Switch(Statement): |
394 def __init__(self, condition, loc): | |
395 super().__init__(loc) | |
396 self.condition = condition | |
397 | |
398 def __repr__(self): | |
399 return 'Switch on {}'.format(self.condition) | |
400 | |
401 | |
307 | 402 class While(Statement): |
228 | 403 def __init__(self, condition, statement, loc): |
404 super().__init__(loc) | |
405 self.condition = condition | |
406 self.statement = statement | |
148 | 407 |
228 | 408 def __repr__(self): |
409 return 'WHILE-statement' | |
315 | 410 |
411 | |
412 class For(Statement): | |
413 def __init__(self, init, condition, final, statement, loc): | |
414 super().__init__(loc) | |
415 self.init = init | |
416 self.condition = condition | |
417 self.final = final | |
418 self.statement = statement | |
419 | |
420 def __repr__(self): | |
421 return 'FOR-statement' |