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