1.1 --- a/micropython/data.py Thu Jan 13 23:58:12 2011 +0100
1.2 +++ b/micropython/data.py Sat Jan 29 21:07:27 2011 +0100
1.3 @@ -7,7 +7,7 @@
1.4 program but which are wrapped in context-dependent structures in the running
1.5 program.
1.6
1.7 -Copyright (C) 2007, 2008, 2009, 2010 Paul Boddie <paul@boddie.org.uk>
1.8 +Copyright (C) 2007, 2008, 2009, 2010, 2011 Paul Boddie <paul@boddie.org.uk>
1.9
1.10 This program is free software; you can redistribute it and/or modify it under
1.11 the terms of the GNU General Public License as published by the Free Software
1.12 @@ -150,6 +150,9 @@
1.13 def vacuum_item(self, name):
1.14 if self.has_key(name):
1.15 del self[name]
1.16 + return 1
1.17 + else:
1.18 + return 0
1.19
1.20 def add_lambda(self, obj):
1.21 attr = Attr(None, self, obj.name)
1.22 @@ -955,7 +958,7 @@
1.23 as a class or a module.
1.24 """
1.25
1.26 - return isinstance(self.parent, (Class, Module))
1.27 + return isinstance(self.parent, (Class, Module)) and self.name != "__class__"
1.28
1.29 def defines_ambiguous_class(self):
1.30
1.31 @@ -1109,13 +1112,14 @@
1.32
1.33 class Class(NamespaceDict, Naming, Constant):
1.34
1.35 - "An inspected class."
1.36 -
1.37 - def __init__(self, name, parent, module=None, node=None):
1.38 + "A base class for common/normal classes and the type class."
1.39 +
1.40 + def __init__(self, name, parent=None, module=None, node=None):
1.41
1.42 """
1.43 - Initialise the class with the given 'name', 'parent' object, optional
1.44 - 'module' and optional AST 'node'.
1.45 + Initialise the class with the given 'name', optional 'parent' object,
1.46 + 'module' and AST 'node'. The optional information must be set at a later
1.47 + point using the 'set_context' method if omitted.
1.48 """
1.49
1.50 NamespaceDict.__init__(self, module)
1.51 @@ -1152,9 +1156,19 @@
1.52 self.local_usage = 0
1.53 self.all_local_usage = 0
1.54
1.55 - # Add this class to its attributes.
1.56 -
1.57 - self.set("__class__", self)
1.58 + # Add __class__ attributes to this class and to instances of it.
1.59 +
1.60 + if self.parent is not None:
1.61 + self.initialise_class_attribute()
1.62 + self.add_instance_attribute("__class__")
1.63 +
1.64 + def set_context(self, parent, module, node):
1.65 + self.parent = parent
1.66 + self.module = module
1.67 + self.astnode = node
1.68 +
1.69 + self.initialise_class_attribute()
1.70 + self.add_instance_attribute("__class__")
1.71
1.72 def reset_caches(self):
1.73
1.74 @@ -1204,6 +1218,17 @@
1.75
1.76 # Administrative methods.
1.77
1.78 + def items_for_vacuum(self):
1.79 + items = []
1.80 + for name in self.instattr:
1.81 + items.append((name, None))
1.82 + return NamespaceDict.items_for_vacuum(self) + items
1.83 +
1.84 + def vacuum_item(self, name):
1.85 + if not NamespaceDict.vacuum_item(self, name):
1.86 + self.instattr.remove(name)
1.87 + return 1
1.88 +
1.89 def finalise_attributes(self):
1.90
1.91 "Make sure that all attributes are fully defined."
1.92 @@ -1457,17 +1482,34 @@
1.93 """
1.94 Return all attributes for an instance, indicating either the class which
1.95 provides them or that the instance itself provides them.
1.96 +
1.97 + Note that __class__ acts like an instance attribute for both instances
1.98 + and classes.
1.99 """
1.100
1.101 if self.allattr is None:
1.102 self.allattr = {}
1.103 self.allattr.update(self.all_class_attributes())
1.104 for name, attr in self.instance_attributes().items():
1.105 - if self.allattr.has_key(name):
1.106 + if self.allattr.has_key(name) and name != "__class__":
1.107 print "Warning: instance attribute %r in %r overrides class attribute." % (name, self)
1.108 self.allattr[name] = attr
1.109 return self.allattr
1.110
1.111 +class TypeClass(Class):
1.112 +
1.113 + "A special class for the type class."
1.114 +
1.115 + def initialise_class_attribute(self):
1.116 + self.set("__class__", self)
1.117 +
1.118 +class CommonClass(Class):
1.119 +
1.120 + "An inspected class."
1.121 +
1.122 + def initialise_class_attribute(self):
1.123 + self.set("__class__", type_class)
1.124 +
1.125 class Function(NamespaceDict, Naming, Constant):
1.126
1.127 "An inspected function."
1.128 @@ -1716,6 +1758,7 @@
1.129
1.130 def vacuum_item(self, name):
1.131 del self.lambdas[name]
1.132 + return 1
1.133
1.134 def finalise_attributes(self):
1.135
1.136 @@ -1868,4 +1911,23 @@
1.137
1.138 return dict(self)
1.139
1.140 +# Pre-made instances.
1.141 +
1.142 +type_class = TypeClass("type") # details to be filled in later
1.143 +
1.144 +# Class construction.
1.145 +
1.146 +def get_class(name, parent, module, node):
1.147 +
1.148 + """
1.149 + Return a Class instance for the class with the given 'name', 'parent',
1.150 + 'module' and 'node'.
1.151 + """
1.152 +
1.153 + if name == "type" and module.full_name() == "__builtins__":
1.154 + type_class.set_context(parent, module, node)
1.155 + return type_class
1.156 + else:
1.157 + return CommonClass(name, parent, module, node)
1.158 +
1.159 # vim: tabstop=4 expandtab shiftwidth=4