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