Mercurial > lcfOS
annotate python/ppci/c3/astnodes.py @ 389:2ec730e45ea1
Added check for recursive struct
author | Windel Bouwman |
---|---|
date | Fri, 16 May 2014 12:29:31 +0200 |
parents | 5477e499b039 |
children | 6ae782a085e0 |
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 |
225 | 210 class Deref(Expression): |
211 def __init__(self, ptr, loc): | |
230 | 212 super().__init__(loc) |
225 | 213 assert isinstance(ptr, Expression) |
214 self.ptr = ptr | |
288 | 215 |
225 | 216 def __repr__(self): |
288 | 217 return 'DEREF {}'.format(self.ptr) |
225 | 218 |
230 | 219 |
220 class TypeCast(Expression): | |
221 def __init__(self, to_type, x, loc): | |
222 super().__init__(loc) | |
223 self.to_type = to_type | |
224 self.a = x | |
288 | 225 |
230 | 226 def __repr__(self): |
227 return 'TYPECAST {}'.format(self.to_type) | |
228 | |
229 | |
306 | 230 class Member(Expression): |
231 """ Field reference of some object, can also be package selection """ | |
225 | 232 def __init__(self, base, field, loc): |
230 | 233 super().__init__(loc) |
225 | 234 assert isinstance(base, Expression) |
235 assert isinstance(field, str) | |
236 self.base = base | |
237 self.field = field | |
288 | 238 |
225 | 239 def __repr__(self): |
306 | 240 return 'MEMBER {}.{}'.format(self.base, self.field) |
225 | 241 |
230 | 242 |
354 | 243 class Index(Expression): |
244 """ Index something, for example an array """ | |
245 def __init__(self, base, i, loc): | |
246 super().__init__(loc) | |
247 self.base = base | |
248 self.i = i | |
249 | |
250 def __repr__(self): | |
251 return 'Index {}'.format(self.i) | |
252 | |
253 | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
254 class Unop(Expression): |
306 | 255 """ Operation on one operand """ |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
256 def __init__(self, op, a, loc): |
230 | 257 super().__init__(loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
258 assert isinstance(a, Expression) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
259 assert isinstance(op, str) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
260 self.a = a |
230 | 261 self.op = op |
288 | 262 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
263 def __repr__(self): |
288 | 264 return 'UNOP {}'.format(self.op) |
265 | |
148 | 266 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
267 class Binop(Expression): |
306 | 268 """ 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
|
269 def __init__(self, a, op, b, loc): |
230 | 270 super().__init__(loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
271 assert isinstance(a, Expression), type(a) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
272 assert isinstance(b, Expression) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
273 assert isinstance(op, str) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
274 self.a = a |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
275 self.b = b |
288 | 276 self.op = op # Operation: '+', '-', '*', '/', 'mod' |
148 | 277 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
278 def __repr__(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
279 return 'BINOP {}'.format(self.op) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
280 |
288 | 281 |
306 | 282 class Identifier(Expression): |
283 """ Reference to some identifier, can be anything from package, variable | |
284 function or type, any named thing! """ | |
228 | 285 def __init__(self, target, loc): |
230 | 286 super().__init__(loc) |
228 | 287 self.target = target |
288 | 288 |
228 | 289 def __repr__(self): |
306 | 290 return 'ID {}'.format(self.target) |
163 | 291 |
284 | 292 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
293 class Literal(Expression): |
306 | 294 """ Constant value or string """ |
228 | 295 def __init__(self, val, loc): |
230 | 296 super().__init__(loc) |
228 | 297 self.val = val |
288 | 298 |
228 | 299 def __repr__(self): |
300 return 'LITERAL {}'.format(self.val) | |
150 | 301 |
284 | 302 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
303 class FunctionCall(Expression): |
306 | 304 """ Call to a some function """ |
228 | 305 def __init__(self, proc, args, loc): |
230 | 306 super().__init__(loc) |
228 | 307 self.proc = proc |
308 self.args = args | |
288 | 309 |
228 | 310 def __repr__(self): |
311 return 'CALL {0} '.format(self.proc) | |
148 | 312 |
284 | 313 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
314 # Statements |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
315 class Statement(Node): |
306 | 316 """ Base class of all statements """ |
228 | 317 def __init__(self, loc): |
318 self.loc = loc | |
319 | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
320 |
307 | 321 class Empty(Statement): |
306 | 322 """ Empty statement which does nothing! """ |
323 def __init__(self): | |
324 super().__init__(None) | |
325 | |
326 def __repr__(self): | |
327 return 'NOP' | |
328 | |
329 | |
307 | 330 class Compound(Statement): |
306 | 331 """ 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
|
332 def __init__(self, statements): |
249 | 333 super().__init__(None) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
334 self.statements = statements |
228 | 335 for s in self.statements: |
336 assert isinstance(s, Statement) | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
337 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
338 def __repr__(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
339 return 'COMPOUND STATEMENT' |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
340 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
341 |
307 | 342 class Return(Statement): |
228 | 343 def __init__(self, expr, loc): |
344 super().__init__(loc) | |
345 self.expr = expr | |
346 | |
347 def __repr__(self): | |
348 return 'RETURN STATEMENT' | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
349 |
284 | 350 |
222 | 351 class Assignment(Statement): |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
352 def __init__(self, lval, rval, loc): |
228 | 353 super().__init__(loc) |
306 | 354 assert isinstance(lval, Expression) |
355 assert isinstance(rval, Expression) | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
356 self.lval = lval |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
357 self.rval = rval |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
358 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
359 def __repr__(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
360 return 'ASSIGNMENT' |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
361 |
288 | 362 |
222 | 363 class ExpressionStatement(Statement): |
364 def __init__(self, ex, loc): | |
228 | 365 super().__init__(loc) |
222 | 366 self.ex = ex |
228 | 367 |
222 | 368 def __repr__(self): |
369 return 'Epression' | |
370 | |
228 | 371 |
307 | 372 class If(Statement): |
228 | 373 def __init__(self, condition, truestatement, falsestatement, loc): |
374 super().__init__(loc) | |
375 self.condition = condition | |
376 self.truestatement = truestatement | |
377 self.falsestatement = falsestatement | |
378 | |
379 def __repr__(self): | |
380 return 'IF-statement' | |
381 | |
148 | 382 |
307 | 383 class While(Statement): |
228 | 384 def __init__(self, condition, statement, loc): |
385 super().__init__(loc) | |
386 self.condition = condition | |
387 self.statement = statement | |
148 | 388 |
228 | 389 def __repr__(self): |
390 return 'WHILE-statement' | |
315 | 391 |
392 | |
393 class For(Statement): | |
394 def __init__(self, init, condition, final, statement, loc): | |
395 super().__init__(loc) | |
396 self.init = init | |
397 self.condition = condition | |
398 self.final = final | |
399 self.statement = statement | |
400 | |
401 def __repr__(self): | |
402 return 'FOR-statement' |