1 #!/usr/bin/env python 2 3 """ 4 Fundamental program data structure abstractions. 5 6 Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Paul Boddie <paul@boddie.org.uk> 7 8 This program is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free Software 10 Foundation; either version 3 of the License, or (at your option) any later 11 version. 12 13 This program is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 details. 17 18 You should have received a copy of the GNU General Public License along with 19 this program. If not, see <http://www.gnu.org/licenses/>. 20 """ 21 22 # Short representation display support. 23 24 def shortrepr(obj): 25 if obj is None: 26 return repr(None) 27 else: 28 return obj.__shortrepr__() 29 30 # Mix-ins and abstract classes. 31 32 class Naming: 33 34 "A mix-in providing naming conveniences." 35 36 def full_name(self): 37 if self.name is not None: 38 return self.parent.full_name() + "." + self.name 39 else: 40 return self.parent.full_name() 41 42 no_attributes = {} 43 44 class Namespace: 45 46 "A mix-in providing basic namespace functionality." 47 48 def all_attributes(self): 49 50 """ 51 Return all attributes accessible through a namespace, whether provided 52 directly by the namespace or by other mechanisms. 53 """ 54 55 return no_attributes 56 57 class Constant: 58 59 "A superclass for all constant or context-free structures." 60 61 pass 62 63 # Instances are special in that they need to be wrapped together with context in 64 # a running program, but they are not generally constant. 65 66 class Instance(Namespace): 67 68 "A placeholder indicating the involvement of an instance." 69 70 def __init__(self): 71 self.parent = None 72 73 def __repr__(self): 74 return "<instance>" 75 76 def __eq__(self, other): 77 return other.__class__ is Instance 78 79 def __ne__(self, other): 80 return not self.__eq__(other) 81 82 def __hash__(self): 83 return 0 84 85 __shortrepr__ = __repr__ 86 87 # Common instance construction. 88 89 common_instance = Instance() 90 91 def make_instance(): 92 return common_instance 93 94 class TypedInstance(Instance): 95 96 "A placeholder indicating the involvement of an instance of a known type." 97 98 def __init__(self, cls): 99 Instance.__init__(self) 100 self.cls = cls 101 102 def __repr__(self): 103 return "<instance of %s>" % shortrepr(self.cls) 104 105 def __eq__(self, other): 106 return other.__class__ is TypedInstance and other.cls is self.cls 107 108 def __ne__(self, other): 109 return not self.__eq__(other) 110 111 def __hash__(self): 112 return 0 113 114 __shortrepr__ = __repr__ 115 116 # Data objects appearing in programs before run-time. 117 118 class Const(Constant, TypedInstance): 119 120 "A constant object with no context." 121 122 def __init__(self, value): 123 Instance.__init__(self) 124 self.value = value 125 126 def get_value(self): 127 return self.value 128 129 def __repr__(self): 130 return "Const(%r)" % self.value 131 132 __shortrepr__ = __repr__ 133 134 # Support constants as dictionary keys in order to build constant tables. 135 136 def __eq__(self, other): 137 return other is not None and isinstance(other, Const) and \ 138 self.value == other.value and self.value.__class__ is other.value.__class__ 139 140 def __ne__(self, other): 141 return not self.__eq__(other) 142 143 def __hash__(self): 144 return hash(self.value) 145 146 # Constants are instances of various built-in types. 147 148 def value_type_name(self): 149 return ".".join(self.value_type_name_parts()) 150 151 def value_type_name_parts(self): 152 return "__builtins__", self.get_class_name() 153 154 def get_class_name(self): 155 return self.value.__class__.__name__ 156 157 # vim: tabstop=4 expandtab shiftwidth=4