Mercurial > lcfOS
annotate python/c3/astnodes.py @ 230:88a1e0baef65
Added some tests for IR-code
author | Windel Bouwman |
---|---|
date | Sat, 13 Jul 2013 19:53:44 +0200 |
parents | 7f18ed9b6b7e |
children | e41e4109addd |
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 |
148 | 10 class Node: |
163 | 11 pass |
148 | 12 |
213 | 13 # Modules |
14 class Package(Node): | |
15 def __init__(self, name, loc): | |
16 self.name = name | |
17 self.loc = loc | |
18 self.declarations = [] | |
19 def __repr__(self): | |
20 return 'PACKAGE {}'.format(self.name) | |
21 | |
150 | 22 class Designator(Node): |
213 | 23 def __init__(self, tname, loc): |
24 self.tname = tname | |
25 self.loc = loc | |
26 def __repr__(self): | |
27 return 'DESIGNATOR {}'.format(self.tname) | |
148 | 28 |
29 """ | |
30 Type classes | |
213 | 31 |
32 types must be comparable. | |
33 | |
34 There are the following types: | |
228 | 35 - base type -> basic type (built in) |
36 - struct type -> a composite type that contains a list of named fields | |
37 of other types | |
38 - pointer type -> a type that points to some other type | |
39 - typedef type -> a named type indicating another type | |
213 | 40 - function type |
148 | 41 """ |
42 | |
149 | 43 class Type(Node): |
148 | 44 def isType(self, b): |
45 return isType(self, b) | |
46 | |
47 class BaseType(Type): | |
48 def __init__(self, name): | |
49 self.name = name | |
50 def __repr__(self): | |
212 | 51 return '{}'.format(self.name) |
148 | 52 |
53 class FunctionType(Type): | |
167 | 54 def __init__(self, parametertypes, returntype): |
55 self.parametertypes = parametertypes | |
148 | 56 self.returntype = returntype |
57 def __repr__(self): | |
167 | 58 params = ', '.join([str(v) for v in self.parametertypes]) |
165 | 59 return '{1} f({0})'.format(params, self.returntype) |
148 | 60 |
213 | 61 class PointerType(Type): |
62 def __init__(self, ptype): | |
225 | 63 assert isinstance(ptype, Type) or isinstance(ptype, Designator) |
213 | 64 self.ptype = ptype |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
65 def __repr__(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
66 return '({}*)'.format(self.ptype) |
213 | 67 |
230 | 68 |
227 | 69 class StructField: |
70 def __init__(self, name, typ): | |
71 self.name = name | |
72 self.typ = typ | |
230 | 73 self.offset = 0 |
74 | |
227 | 75 |
213 | 76 class StructureType(Type): |
77 def __init__(self, mems): | |
78 self.mems = mems | |
227 | 79 for mem in mems: |
80 assert type(mem) is StructField | |
81 assert type(mem.name) is str | |
230 | 82 |
225 | 83 def hasField(self, name): |
227 | 84 for mem in self.mems: |
85 if name == mem.name: | |
225 | 86 return True |
87 return False | |
230 | 88 |
225 | 89 def fieldType(self, name): |
230 | 90 return self.findField(name).typ |
91 | |
92 def fieldOffset(self, name): | |
93 return self.findField(name).offset | |
94 | |
95 def findField(self, name): | |
227 | 96 for mem in self.mems: |
97 if name == mem.name: | |
230 | 98 return mem |
99 raise KeyError(name) | |
225 | 100 |
230 | 101 def __repr__(self): |
102 return 'STRUCT' | |
213 | 103 |
148 | 104 class DefinedType(Type): |
225 | 105 def __init__(self, name, typ, loc): |
106 assert isinstance(name, str) | |
107 self.name = name | |
108 self.typ = typ | |
109 self.loc = loc | |
230 | 110 |
225 | 111 def __repr__(self): |
112 return 'Named type {0} of type {1}'.format(self.name, self.typ) | |
148 | 113 |
221 | 114 |
148 | 115 # Variables, parameters, local variables, constants: |
116 class Symbol(Node): | |
213 | 117 def __init__(self, name): |
163 | 118 self.name = name |
119 self.refs = [] | |
213 | 120 def addRef(self, r): |
163 | 121 self.refs.append(r) |
213 | 122 @property |
123 def References(self): | |
163 | 124 return self.refs |
148 | 125 |
126 class Constant(Symbol): | |
213 | 127 def __init__(self, name, typ, value): |
163 | 128 super().__init__(name) |
129 self.typ = typ | |
148 | 130 self.value = value |
213 | 131 def __repr__(self): |
148 | 132 return 'CONSTANT {0} = {1}'.format(self.name, self.value) |
133 | |
134 class Variable(Symbol): | |
213 | 135 def __init__(self, name, typ): |
163 | 136 super().__init__(name) |
148 | 137 self.typ = typ |
213 | 138 self.ival = None |
148 | 139 self.isLocal = False |
140 self.isReadOnly = False | |
141 self.isParameter = False | |
142 def __repr__(self): | |
225 | 143 return 'Var {} [{}]'.format(self.name, self.typ) |
148 | 144 |
150 | 145 # Procedure types |
146 class Function(Symbol): | |
213 | 147 """ Actual implementation of a function """ |
148 def __init__(self, name, loc): | |
149 super().__init__(name) | |
150 self.loc = loc | |
215 | 151 self.declarations = [] |
213 | 152 |
153 def __repr__(self): | |
217 | 154 return 'Func {}'.format(self.name) |
148 | 155 |
163 | 156 # Operations / Expressions: |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
157 class Expression(Node): |
230 | 158 def __init__(self, loc): |
159 self.loc = loc | |
160 | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
161 |
225 | 162 class Deref(Expression): |
163 def __init__(self, ptr, loc): | |
230 | 164 super().__init__(loc) |
225 | 165 assert isinstance(ptr, Expression) |
166 self.ptr = ptr | |
167 def __repr__(self): | |
168 return 'DEREF {}'.format(self.ptr) | |
169 | |
230 | 170 |
171 class TypeCast(Expression): | |
172 def __init__(self, to_type, x, loc): | |
173 super().__init__(loc) | |
174 self.to_type = to_type | |
175 self.a = x | |
176 def __repr__(self): | |
177 return 'TYPECAST {}'.format(self.to_type) | |
178 | |
179 | |
225 | 180 class FieldRef(Expression): |
181 def __init__(self, base, field, loc): | |
230 | 182 super().__init__(loc) |
225 | 183 assert isinstance(base, Expression) |
184 assert isinstance(field, str) | |
185 self.base = base | |
186 self.field = field | |
187 def __repr__(self): | |
188 return 'FIELD {}.{}'.format(self.base, self.field) | |
189 | |
230 | 190 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
191 class Unop(Expression): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
192 def __init__(self, op, a, loc): |
230 | 193 super().__init__(loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
194 assert isinstance(a, Expression) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
195 assert isinstance(op, str) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
196 self.a = a |
230 | 197 self.op = op |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
198 def __repr__(self): |
212 | 199 return 'UNOP {}'.format(self.op) |
148 | 200 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
201 class Binop(Expression): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
202 def __init__(self, a, op, b, loc): |
230 | 203 super().__init__(loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
204 assert isinstance(a, Expression), type(a) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
205 assert isinstance(b, Expression) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
206 assert isinstance(op, str) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
207 self.a = a |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
208 self.b = b |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
209 self.op = op # Operation: '+', '-', '*', '/', 'mod' |
148 | 210 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
211 def __repr__(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
212 return 'BINOP {}'.format(self.op) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
213 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
214 class VariableUse(Expression): |
228 | 215 def __init__(self, target, loc): |
230 | 216 super().__init__(loc) |
228 | 217 self.target = target |
218 def __repr__(self): | |
219 nm = self.target | |
220 return 'VAR USE {}'.format(nm) | |
163 | 221 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
222 class Literal(Expression): |
228 | 223 def __init__(self, val, loc): |
230 | 224 super().__init__(loc) |
228 | 225 self.val = val |
226 def __repr__(self): | |
227 return 'LITERAL {}'.format(self.val) | |
150 | 228 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
229 class FunctionCall(Expression): |
228 | 230 def __init__(self, proc, args, loc): |
230 | 231 super().__init__(loc) |
228 | 232 self.proc = proc |
233 self.args = args | |
234 def __repr__(self): | |
235 return 'CALL {0} '.format(self.proc) | |
148 | 236 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
237 # Statements |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
238 class Statement(Node): |
228 | 239 def __init__(self, loc): |
240 self.loc = loc | |
241 | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
242 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
243 class CompoundStatement(Statement): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
244 def __init__(self, statements): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
245 self.statements = statements |
228 | 246 for s in self.statements: |
247 assert isinstance(s, Statement) | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
248 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
249 def __repr__(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
250 return 'COMPOUND STATEMENT' |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
251 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
252 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
253 class ReturnStatement(Statement): |
228 | 254 def __init__(self, expr, loc): |
255 super().__init__(loc) | |
256 self.expr = expr | |
257 | |
258 def __repr__(self): | |
259 return 'RETURN STATEMENT' | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
260 |
222 | 261 class Assignment(Statement): |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
262 def __init__(self, lval, rval, loc): |
228 | 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(lval, Node) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
265 assert isinstance(rval, Node) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
266 self.lval = lval |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
267 self.rval = rval |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
268 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
269 def __repr__(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
270 return 'ASSIGNMENT' |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
271 |
222 | 272 class ExpressionStatement(Statement): |
273 def __init__(self, ex, loc): | |
228 | 274 super().__init__(loc) |
222 | 275 self.ex = ex |
228 | 276 |
222 | 277 def __repr__(self): |
278 return 'Epression' | |
279 | |
228 | 280 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
281 class IfStatement(Statement): |
228 | 282 def __init__(self, condition, truestatement, falsestatement, loc): |
283 super().__init__(loc) | |
284 self.condition = condition | |
285 self.truestatement = truestatement | |
286 self.falsestatement = falsestatement | |
287 | |
288 def __repr__(self): | |
289 return 'IF-statement' | |
290 | |
148 | 291 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
292 class WhileStatement(Statement): |
228 | 293 def __init__(self, condition, statement, loc): |
294 super().__init__(loc) | |
295 self.condition = condition | |
296 self.statement = statement | |
148 | 297 |
228 | 298 def __repr__(self): |
299 return 'WHILE-statement' | |
300 |