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 index Any index involved (temporary variable name). 32 value Any constant value. 33 ref Any reference to (for example) subprograms. 34 35 Expression-related attributes: 36 37 expr Any contributing expression. 38 lvalue Any target expression. 39 test Any test expression in a conditional instruction. 40 handler Any exception handler selector expression. 41 42 Invocation and subprogram attributes: 43 44 args Any collection of argument nodes. 45 params Any collection of parameter nodes and defaults. 46 47 Statement-grouping attributes: 48 49 body Any conditional code depending on the success of a test. 50 else_ Any conditional code depending on the failure of a test. 51 finally_ Any code which will be executed regardless. 52 code Any unconditional code. 53 """ 54 55 def __init__(self, original=None, **kw): 56 self.original = original 57 if self.original is not None: 58 self.original._node = self 59 for name, value in kw.items(): 60 setattr(self, name, value) 61 62 def __repr__(self): 63 if hasattr(self, "name"): 64 return "%s '%s' (at %x)" % (self.__class__, self.name, id(self)) 65 if hasattr(self, "index"): 66 return "%s (%s) (at %x)" % (self.__class__, self.index, id(self)) 67 elif hasattr(self, "value"): 68 return "%s %s (at %x)" % (self.__class__, repr(self.value), id(self)) 69 elif hasattr(self, "ref"): 70 return "%s '%s' (at %x)" % (self.__class__, self.ref.name, id(self)) 71 else: 72 return "%s (at %x)" % (self.__class__, id(self)) 73 74 def _pprint(self, indent, continuation, s): 75 if continuation: 76 print (" " * max(0, indent - len(continuation))) + continuation + s 77 else: 78 print (" " * indent) + s 79 80 def pprint(self, indent=0, continuation=None): 81 self._pprint(indent, continuation, repr(self)) 82 83 # Show other details. 84 85 if hasattr(self, "params"): 86 for name, default in self.params: 87 self._pprint(indent + 2, "( ", "%s -> %s" % (name, default)) 88 if getattr(self, "acquire_locals", 0): 89 self._pprint(indent + 2, "( ", "acquiring locals") 90 if hasattr(self, "test"): 91 self.test.pprint(indent + 2, "? ") 92 for attr in "code", "body", "else_", "finally_": 93 if hasattr(self, attr) and getattr(self, attr): 94 self._pprint(indent, "", "{ (%s)" % attr) 95 for node in getattr(self, attr): 96 node.pprint(indent + 2) 97 self._pprint(indent, "", "}") 98 if hasattr(self, "handler"): 99 self.handler.pprint(indent + 2, "! ") 100 if hasattr(self, "expr"): 101 self.expr.pprint(indent + 2, "- ") 102 if hasattr(self, "nodes"): 103 for node in self.nodes: 104 node.pprint(indent + 2, "- ") 105 if hasattr(self, "lvalue"): 106 self.lvalue.pprint(indent + 2, "= ") 107 if hasattr(self, "args"): 108 for arg in self.args: 109 arg.pprint(indent + 2, "( ") 110 111 class Module(Node): "A Python module." 112 class Subprogram(Node): "A subprogram: functions, methods and loops." 113 class Class(Node): "A Python class." 114 class Pass(Node): "A placeholder node corresponding to pass." 115 class Invoke(Node): "A function, method or loop invocation." 116 class Return(Node): "Return an evaluated expression." 117 class Assign(Node): "A grouping node for assignment-related operations." 118 class Keyword(Node): "A grouping node for keyword arguments." 119 class Global(Node): "A global name designator." 120 class Import(Node): "A module import operation." 121 class LoadTemp(Node): "Load a previously-stored temporary value." 122 class LoadName(Node): "Load a named object." 123 class LoadAttr(Node): "Load an object attribute." 124 class LoadConst(Node): "Load a constant." 125 class LoadRef(Node): "Load a reference, typically a subprogram." 126 class LoadExc(Node): "Load a handled exception." 127 class StoreTemp(Node): "Store a temporary value." 128 class StoreName(Node): "Associate a name with an object." 129 class StoreAttr(Node): "Associate an object's attribute with a value." 130 class ReleaseTemp(Node): "Release a temporary value." 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 Raise(Node): "An exception raising node." 134 class Not(Node): "A negation of an expression." 135 136 # vim: tabstop=4 expandtab shiftwidth=4