1 #!/usr/bin/env python 2 3 """ 4 Simplified AST nodes for easier type propagation and analysis. 5 6 Copyright (C) 2006 Paul Boddie <paul@boddie.org.uk> 7 8 This software is free software; you can redistribute it and/or 9 modify it under the terms of the GNU General Public License as 10 published by the Free Software Foundation; either version 2 of 11 the License, or (at your option) any later version. 12 13 This software is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public 19 License along with this library; see the file LICENCE.txt 20 If not, write to the Free Software Foundation, Inc., 21 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 22 """ 23 24 class Node: 25 26 """ 27 A result node with common attributes: 28 29 original The original node from which this node was created. 30 name Any name involved (variable or attribute). 31 expr Any contributing expression. 32 lvalue Any target expression. 33 test Any test expression in a conditional instruction. 34 ref Any reference to (for example) subprograms. 35 36 Invocation and subprogram attributes: 37 38 args Any collection of argument nodes. 39 params Any collection of parameter nodes and defaults. 40 41 Statement-grouping attributes: 42 43 body Any conditional code depending on the success of a test. 44 else_ Any conditional code depending on the failure of a test. 45 finally_ Any code which will be executed regardless. 46 code Any unconditional code. 47 48 Table-style attributes: 49 50 tests Any collection of tests and accompanying code. 51 handlers Any collection of tests applicable in exception handling. 52 """ 53 54 def __init__(self, original=None, **kw): 55 self.original = original 56 if self.original is not None: 57 self.original._node = self 58 for name, value in kw.items(): 59 setattr(self, name, value) 60 61 def __repr__(self): 62 if hasattr(self, "name"): 63 return "%s '%s' (at %x)" % (self.__class__, self.name, id(self)) 64 if hasattr(self, "index"): 65 return "%s (%s) (at %x)" % (self.__class__, self.index, id(self)) 66 elif hasattr(self, "value"): 67 return "%s %s (at %x)" % (self.__class__, repr(self.value), id(self)) 68 elif hasattr(self, "ref"): 69 return "%s '%s' (at %x)" % (self.__class__, self.ref.name, id(self)) 70 else: 71 return "%s (at %x)" % (self.__class__, id(self)) 72 73 def _pprint(self, indent, continuation, s): 74 if continuation: 75 print (" " * max(0, indent - len(continuation))) + continuation + s 76 else: 77 print (" " * indent) + s 78 79 def pprint(self, indent=0, continuation=None): 80 self._pprint(indent, continuation, repr(self)) 81 82 # Show other details. 83 84 if hasattr(self, "params"): 85 for name, default in self.params: 86 self._pprint(indent + 2, "( ", "%s -> %s" % (name, default)) 87 if getattr(self, "acquire_locals", 0): 88 self._pprint(indent + 2, "( ", "acquiring locals") 89 if hasattr(self, "spec"): 90 self.spec.pprint(indent + 2, "E ") 91 if hasattr(self, "test"): 92 self.test.pprint(indent + 2, "? ") 93 for attr in "code", "tests", "body", "handlers", "else_", "finally_": 94 if hasattr(self, attr) and getattr(self, attr): 95 self._pprint(indent, "", "{ (%s)" % attr) 96 for node in getattr(self, attr): 97 node.pprint(indent + 2) 98 self._pprint(indent, "", "}") 99 if hasattr(self, "expr"): 100 self.expr.pprint(indent + 2, "- ") 101 if hasattr(self, "nodes"): 102 for node in self.nodes: 103 node.pprint(indent + 2, "- ") 104 if hasattr(self, "lvalue"): 105 self.lvalue.pprint(indent + 2, "= ") 106 if hasattr(self, "args"): 107 for arg in self.args: 108 arg.pprint(indent + 2, "( ") 109 110 class Module(Node): "A Python module." 111 class Subprogram(Node): "A subprogram: functions, methods and loops." 112 class Class(Node): "A Python class." 113 class Pass(Node): "A placeholder node corresponding to pass." 114 class Invoke(Node): "A function, method or loop invocation." 115 class Return(Node): "Return an evaluated expression." 116 class Assign(Node): "A grouping node for assignment-related operations." 117 class Keyword(Node): "A grouping node for keyword arguments." 118 class Global(Node): "A global name designator." 119 class Import(Node): "A module import operation." 120 class LoadTemp(Node): "Load a previously-stored temporary value." 121 class LoadName(Node): "Load a named object." 122 class LoadAttr(Node): "Load an object attribute." 123 class LoadConst(Node): "Load a constant." 124 class LoadRef(Node): "Load a reference, typically a subprogram." 125 class LoadExc(Node): "Load a handled exception." 126 class StoreTemp(Node): "Store a temporary value." 127 class StoreName(Node): "Associate a name with an object." 128 class StoreAttr(Node): "Associate an object's attribute with a value." 129 class ReleaseTemp(Node): "Release a temporary value." 130 class If(Node): "A multitest conditional node." 131 class Conditional(Node): "A conditional node consisting of a test and outcomes." 132 class Try(Node): "A try...except...else...finally grouping node." 133 class Except(Node): "An exception handler node." 134 class Raise(Node): "An exception raising node." 135 class Not(Node): "A negation of an expression." 136 137 # vim: tabstop=4 expandtab shiftwidth=4