Mercurial > lcfOS
annotate python/ppci/c3/visitor.py @ 366:39bf68bf1891
Fix sample tests and deterministic build
author | Windel Bouwman |
---|---|
date | Fri, 21 Mar 2014 09:43:01 +0100 |
parents | c05ab629976a |
children | 6ae782a085e0 |
rev | line source |
---|---|
163 | 1 from .astnodes import * |
2 | |
288 | 3 |
163 | 4 class Visitor: |
228 | 5 """ |
215 | 6 Visitor that can visit all nodes in the AST |
7 and run pre and post functions. | |
8 """ | |
9 def visit(self, node, f_pre=None, f_post=None): | |
10 self.f_pre = f_pre | |
11 self.f_post = f_post | |
12 self.do(node) | |
13 | |
14 def do(self, node): | |
306 | 15 # Run pre function: |
228 | 16 if self.f_pre: |
215 | 17 self.f_pre(node) |
18 | |
228 | 19 # Descent into subnodes: |
20 if type(node) is Package: | |
215 | 21 for decl in node.declarations: |
22 self.do(decl) | |
228 | 23 elif type(node) is Function: |
215 | 24 for s in node.declarations: |
25 self.do(s) | |
306 | 26 self.do(node.typ) |
362 | 27 if node.body: |
28 self.do(node.body) | |
307 | 29 elif type(node) is Compound: |
230 | 30 for s in node.statements: |
31 self.do(s) | |
307 | 32 elif type(node) is If: |
228 | 33 self.do(node.condition) |
34 self.do(node.truestatement) | |
306 | 35 self.do(node.falsestatement) |
307 | 36 elif type(node) is While: |
37 self.do(node.condition) | |
38 self.do(node.statement) | |
315 | 39 elif type(node) is For: |
40 self.do(node.init) | |
41 self.do(node.condition) | |
42 self.do(node.final) | |
43 self.do(node.statement) | |
307 | 44 elif type(node) is Assignment: |
45 self.do(node.lval) | |
46 self.do(node.rval) | |
228 | 47 elif type(node) is FunctionCall: |
48 for arg in node.args: | |
49 self.do(arg) | |
306 | 50 self.do(node.proc) |
307 | 51 elif type(node) is Return: |
228 | 52 self.do(node.expr) |
53 elif type(node) is Binop: | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
215
diff
changeset
|
54 self.do(node.a) |
228 | 55 self.do(node.b) |
56 elif type(node) is Unop: | |
57 self.do(node.a) | |
58 elif type(node) is ExpressionStatement: | |
222 | 59 self.do(node.ex) |
228 | 60 elif type(node) is TypeCast: |
222 | 61 self.do(node.a) |
307 | 62 self.do(node.to_type) |
306 | 63 elif type(node) is Member: |
225 | 64 self.do(node.base) |
354 | 65 elif type(node) is Index: |
66 self.do(node.base) | |
67 self.do(node.i) | |
228 | 68 elif type(node) is Deref: |
225 | 69 self.do(node.ptr) |
228 | 70 elif type(node) is Constant: |
313 | 71 self.do(node.typ) |
230 | 72 self.do(node.value) |
306 | 73 elif type(node) is DefinedType: |
74 self.do(node.typ) | |
75 elif isinstance(node, Variable): | |
76 self.do(node.typ) | |
77 elif type(node) is PointerType: | |
78 self.do(node.ptype) | |
79 elif type(node) is StructureType: | |
80 for m in node.mems: | |
81 self.do(m.typ) | |
354 | 82 elif type(node) is ArrayType: |
83 self.do(node.element_type) | |
84 self.do(node.size) | |
306 | 85 elif type(node) is FunctionType: |
86 for pt in node.parametertypes: | |
87 self.do(pt) | |
88 self.do(node.returntype) | |
307 | 89 elif type(node) in [Identifier, Literal, Empty]: |
230 | 90 # Those nodes do not have child nodes. |
91 pass | |
228 | 92 else: |
230 | 93 raise Exception('Could not visit "{0}"'.format(node)) |
163 | 94 |
228 | 95 # run post function |
96 if self.f_post: | |
215 | 97 self.f_post(node) |
98 | |
288 | 99 |
100 class AstPrinter: | |
101 """ Prints an AST as text """ | |
313 | 102 def printAst(self, pkg, f): |
103 self.indent = 2 | |
104 self.f = f | |
288 | 105 visitor = Visitor() |
106 visitor.visit(pkg, self.print1, self.print2) | |
107 | |
108 def print1(self, node): | |
313 | 109 print(' ' * self.indent + str(node), file=self.f) |
288 | 110 self.indent += 2 |
111 | |
112 def print2(self, node): | |
113 self.indent -= 2 |