simplify

simplified/utils.py

219:dfd0634cfdb6
2007-05-27 paulb Added a MakeTuple simplified node, replacing the previous tuple initialisation mechanism.
     1 #!/usr/bin/env python     2      3 """     4 Simplified program utilities.     5      6 Copyright (C) 2006, 2007 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 # Exceptions.    27     28 class SimplifiedError(Exception):    29     30     "An error in the annotation process."    31     32     def __init__(self, exc, node, *args):    33     34         """    35         Initialise the error with an existing exception 'exc', the 'node' at    36         which this error occurs, along with additional optional arguments.    37         """    38     39         Exception.__init__(self, *args)    40         self.nodes = [node]    41         self.exc = exc    42     43     def add(self, node):    44     45         "Add the given 'node' to the path of nodes leading from the exception."    46     47         self.nodes.append(node)    48     49     def __str__(self):    50     51         "Return a string showing the principal exception details."    52     53         return "%s, %s" % (self.exc, self.nodes)    54     55 # Elementary visitor support.    56     57 class Visitor(ASTVisitor):    58     59     "A visitor base class."    60     61     def __init__(self):    62         ASTVisitor.__init__(self)    63     64     def default(self, node, *args):    65         raise SimplifiedError, (None, node)    66     67     def dispatch(self, node, *args):    68         return ASTVisitor.dispatch(self, node, *args)    69     70     def dispatches(self, nodes, *args):    71         results = []    72         for node in nodes:    73             results.append(self.dispatch(node, *args))    74         return results    75     76     def dispatch_dict(self, d, *args):    77         results = {}    78         for name, node in d.items():    79             results[name] = self.dispatch(node, *args)    80         return results    81     82 # Unique name registration.    83     84 class Naming:    85     86     "Maintain records of unique names for each simple name."    87     88     index_separator = "-"    89     90     def __init__(self):    91         self.names = {}    92     93     def get(self, obj):    94         return obj._unique_name    95     96     def set(self, obj, name):    97         if hasattr(obj, "_unique_name"):    98             return    99         if not self.names.has_key(name):   100             self.names[name] = 0   101         n = self.names[name] + 1   102         self.names[name] = n   103         obj._unique_name = "%s%s%d" % (name, self.index_separator, n)   104    105 def name(obj, name):   106    107     "Return a unique name for the given 'obj', indicating the base 'name'."   108    109     naming.set(obj, name)   110     return naming.get(obj)   111    112 # Naming singleton.   113    114 naming = Naming()   115    116 # Named nodes are those which can be referenced in some way.   117    118 class WithName:   119    120     "Node naming."   121    122     def __init__(self):   123    124         "Initialise the object's full name."   125    126         self._full_name = name(self, self.name or "$untitled")   127    128     def full_name(self):   129    130         "Return the object's full name."   131    132         return self._full_name   133    134 # Comparable nodes based on naming.   135    136 class Comparable:   137    138     "Comparable nodes implementing the 'full_name' method."   139    140     def __eq__(self, other):   141    142         "This object is equal to 'other' if the full names are the same."   143    144         # NOTE: Single instance: all instances are the same   145         # NOTE: Multiple instances: all instances are different   146         if hasattr(other, "full_name"):   147             return self.full_name() == other.full_name()   148         else:   149             return NotImplemented   150    151     def __hash__(self):   152    153         "The hash of this object is based on its full name."   154    155         return hash(self.full_name())   156    157 # Structure nodes indicating namespace-bearing objects.   158    159 class Structure(Comparable):   160    161     "A non-program node containing some kind of namespace."   162    163     def __init__(self, **kw):   164         for name, value in kw.items():   165             setattr(self, name, value)   166    167 # vim: tabstop=4 expandtab shiftwidth=4