1.1 --- a/simplified/utils.py Sun May 27 18:19:01 2007 +0200
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,167 +0,0 @@
1.4 -#!/usr/bin/env python
1.5 -
1.6 -"""
1.7 -Simplified program utilities.
1.8 -
1.9 -Copyright (C) 2006, 2007 Paul Boddie <paul@boddie.org.uk>
1.10 -
1.11 -This software is free software; you can redistribute it and/or
1.12 -modify it under the terms of the GNU General Public License as
1.13 -published by the Free Software Foundation; either version 2 of
1.14 -the License, or (at your option) any later version.
1.15 -
1.16 -This software is distributed in the hope that it will be useful,
1.17 -but WITHOUT ANY WARRANTY; without even the implied warranty of
1.18 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.19 -GNU General Public License for more details.
1.20 -
1.21 -You should have received a copy of the GNU General Public
1.22 -License along with this library; see the file LICENCE.txt
1.23 -If not, write to the Free Software Foundation, Inc.,
1.24 -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
1.25 -"""
1.26 -
1.27 -from compiler.visitor import ASTVisitor
1.28 -
1.29 -# Exceptions.
1.30 -
1.31 -class SimplifiedError(Exception):
1.32 -
1.33 - "An error in the annotation process."
1.34 -
1.35 - def __init__(self, exc, node, *args):
1.36 -
1.37 - """
1.38 - Initialise the error with an existing exception 'exc', the 'node' at
1.39 - which this error occurs, along with additional optional arguments.
1.40 - """
1.41 -
1.42 - Exception.__init__(self, *args)
1.43 - self.nodes = [node]
1.44 - self.exc = exc
1.45 -
1.46 - def add(self, node):
1.47 -
1.48 - "Add the given 'node' to the path of nodes leading from the exception."
1.49 -
1.50 - self.nodes.append(node)
1.51 -
1.52 - def __str__(self):
1.53 -
1.54 - "Return a string showing the principal exception details."
1.55 -
1.56 - return "%s, %s" % (self.exc, self.nodes)
1.57 -
1.58 -# Elementary visitor support.
1.59 -
1.60 -class Visitor(ASTVisitor):
1.61 -
1.62 - "A visitor base class."
1.63 -
1.64 - def __init__(self):
1.65 - ASTVisitor.__init__(self)
1.66 -
1.67 - def default(self, node, *args):
1.68 - raise SimplifiedError, (None, node)
1.69 -
1.70 - def dispatch(self, node, *args):
1.71 - return ASTVisitor.dispatch(self, node, *args)
1.72 -
1.73 - def dispatches(self, nodes, *args):
1.74 - results = []
1.75 - for node in nodes:
1.76 - results.append(self.dispatch(node, *args))
1.77 - return results
1.78 -
1.79 - def dispatch_dict(self, d, *args):
1.80 - results = {}
1.81 - for name, node in d.items():
1.82 - results[name] = self.dispatch(node, *args)
1.83 - return results
1.84 -
1.85 -# Unique name registration.
1.86 -
1.87 -class Naming:
1.88 -
1.89 - "Maintain records of unique names for each simple name."
1.90 -
1.91 - index_separator = "-"
1.92 -
1.93 - def __init__(self):
1.94 - self.names = {}
1.95 -
1.96 - def get(self, obj):
1.97 - return obj._unique_name
1.98 -
1.99 - def set(self, obj, name):
1.100 - if hasattr(obj, "_unique_name"):
1.101 - return
1.102 - if not self.names.has_key(name):
1.103 - self.names[name] = 0
1.104 - n = self.names[name] + 1
1.105 - self.names[name] = n
1.106 - obj._unique_name = "%s%s%d" % (name, self.index_separator, n)
1.107 -
1.108 -def name(obj, name):
1.109 -
1.110 - "Return a unique name for the given 'obj', indicating the base 'name'."
1.111 -
1.112 - naming.set(obj, name)
1.113 - return naming.get(obj)
1.114 -
1.115 -# Naming singleton.
1.116 -
1.117 -naming = Naming()
1.118 -
1.119 -# Named nodes are those which can be referenced in some way.
1.120 -
1.121 -class WithName:
1.122 -
1.123 - "Node naming."
1.124 -
1.125 - def __init__(self):
1.126 -
1.127 - "Initialise the object's full name."
1.128 -
1.129 - self._full_name = name(self, self.name or "$untitled")
1.130 -
1.131 - def full_name(self):
1.132 -
1.133 - "Return the object's full name."
1.134 -
1.135 - return self._full_name
1.136 -
1.137 -# Comparable nodes based on naming.
1.138 -
1.139 -class Comparable:
1.140 -
1.141 - "Comparable nodes implementing the 'full_name' method."
1.142 -
1.143 - def __eq__(self, other):
1.144 -
1.145 - "This object is equal to 'other' if the full names are the same."
1.146 -
1.147 - # NOTE: Single instance: all instances are the same
1.148 - # NOTE: Multiple instances: all instances are different
1.149 - if hasattr(other, "full_name"):
1.150 - return self.full_name() == other.full_name()
1.151 - else:
1.152 - return NotImplemented
1.153 -
1.154 - def __hash__(self):
1.155 -
1.156 - "The hash of this object is based on its full name."
1.157 -
1.158 - return hash(self.full_name())
1.159 -
1.160 -# Structure nodes indicating namespace-bearing objects.
1.161 -
1.162 -class Structure(Comparable):
1.163 -
1.164 - "A non-program node containing some kind of namespace."
1.165 -
1.166 - def __init__(self, **kw):
1.167 - for name, value in kw.items():
1.168 - setattr(self, name, value)
1.169 -
1.170 -# vim: tabstop=4 expandtab shiftwidth=4