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