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