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 getattr(self, "structure", 0): 91 self._pprint(indent + 2, "( ", "structure '%s'" % self.structure.name) 92 if hasattr(self, "test"): 93 self.test.pprint(indent + 2, "? ") 94 for attr in "code", "body", "else_", "finally_": 95 if hasattr(self, attr) and getattr(self, attr): 96 self._pprint(indent, "", "{ (%s)" % attr) 97 for node in getattr(self, attr): 98 node.pprint(indent + 2) 99 self._pprint(indent, "", "}") 100 if hasattr(self, "handler"): 101 self.handler.pprint(indent + 2, "! ") 102 if hasattr(self, "expr"): 103 self.expr.pprint(indent + 2, "- ") 104 if hasattr(self, "nodes"): 105 for node in self.nodes: 106 node.pprint(indent + 2, "- ") 107 if hasattr(self, "lvalue"): 108 self.lvalue.pprint(indent + 2, "= ") 109 if hasattr(self, "args"): 110 for arg in self.args: 111 arg.pprint(indent + 2, "( ") 112 113 class Module(Node): "A Python module." 114 class Subprogram(Node): "A subprogram: functions, methods and loops." 115 class Class(Node): "A Python class." 116 class Pass(Node): "A placeholder node corresponding to pass." 117 class Invoke(Node): "A function, method or loop invocation." 118 class Return(Node): "Return an evaluated expression." 119 class Assign(Node): "A grouping node for assignment-related operations." 120 class Keyword(Node): "A grouping node for keyword arguments." 121 class Global(Node): "A global name designator." 122 class Import(Node): "A module import operation." 123 class LoadTemp(Node): "Load a previously-stored temporary value." 124 class LoadName(Node): "Load a named object." 125 class LoadAttr(Node): "Load an object attribute." 126 class LoadConst(Node): "Load a constant." 127 class LoadRef(Node): "Load a reference, typically a subprogram." 128 class LoadExc(Node): "Load a handled exception." 129 class StoreTemp(Node): "Store a temporary value." 130 class StoreName(Node): "Associate a name with an object." 131 class StoreAttr(Node): "Associate an object's attribute with a value." 132 class ReleaseTemp(Node): "Release a temporary value." 133 class Conditional(Node): "A conditional node consisting of a test and outcomes." 134 class Try(Node): "A try...except...else...finally grouping node." 135 class Raise(Node): "An exception raising node." 136 class Not(Node): "A negation of an expression." 137 138 # vim: tabstop=4 expandtab shiftwidth=4