# HG changeset patch # User Paul Boddie # Date 1194055183 -3600 # Node ID 26517d26da42763c4c5c0658fc744c8478655d03 # Parent 53f7be1245245f421096a8923891c4238cce5e77 Made a special Builtins class, separating the core module functionality into the Module class and providing the visitor functionality in the InspectedModule class. Added various upcoming features to the Importer. Added notes about namespace definitions. diff -r 53f7be124524 -r 26517d26da42 README.txt --- a/README.txt Fri Nov 02 23:59:34 2007 +0100 +++ b/README.txt Sat Nov 03 02:59:43 2007 +0100 @@ -1,3 +1,14 @@ +Namespace Definition +==================== + +Module attributes are defined either at the module level or by global +statements. + +Class attributes are defined only within class statements. + +Instance attributes are defined only by assignments to attributes of self +within __init__ methods. + Data Structures =============== diff -r 53f7be124524 -r 26517d26da42 micropython/__init__.py --- a/micropython/__init__.py Fri Nov 02 23:59:34 2007 +0100 +++ b/micropython/__init__.py Sat Nov 03 02:59:43 2007 +0100 @@ -33,6 +33,7 @@ functionality of the micropython package may be accessed. """ +#import micropython.ast import micropython.inspect import micropython.table import os @@ -79,7 +80,14 @@ image = [] for module in self.get_modules(): pos = len(image) + + # Position the module in the image and make a translation. + module.location = pos + #trans = micropython.ast.Translation(module) + + # Append module attributes to the image. + attributes = module.module_attributes() for name in module.module_attribute_names(): @@ -87,20 +95,55 @@ image.append(attr) pos += 1 + # Append classes and functions to the image. + for obj in module.all_objects: if isinstance(obj, micropython.inspect.Class): + + # Position the class in the image. + obj.location = pos + + # Append class attributes to the image. + attributes = obj.class_attributes() + for name in obj.class_attribute_names(): attr = attributes[name] image.append(attr) pos += 1 + # Append the class-level code to the image. + # NOTE: An extra optimisation would involve + # NOTE: pre-initialisation of attributes and no code being + # NOTE: generated here, or perhaps the pre-initialisation of + # NOTE: methods and only other attribute-related code being + # NOTE: generated here. + + #code = trans.get_code(obj) + #image += code + #pos += len(code) + # NOTE: Generate module and function code here. elif isinstance(obj, micropython.inspect.Function): + + # Position the function in the image. + obj.location = pos + # Append the function code to the image. + + #code = trans.get_code(obj) + #image += code + #pos += len(code) + + # Append the module top-level code to the image. + + #code = trans.get_module_code() + #image += code + #pos += len(code) + return image def get_object_table(self): @@ -302,7 +345,7 @@ """ if not self.modules.has_key(module_name): - self.modules[module_name] = module = micropython.inspect.Module(module_name, self) + self.modules[module_name] = module = micropython.inspect.InspectedModule(module_name, self) else: module = self.modules[module_name] return module diff -r 53f7be124524 -r 26517d26da42 micropython/inspect.py --- a/micropython/inspect.py Fri Nov 02 23:59:34 2007 +0100 +++ b/micropython/inspect.py Sat Nov 03 02:59:43 2007 +0100 @@ -45,6 +45,9 @@ def __getitem__(self, name): return self.namespace[name] + def get(self, name, default=None): + return self.namespace.get(name, default) + def __setitem__(self, name, value): if name not in self.globals: self.namespace[name] = value @@ -318,18 +321,11 @@ # Program visitors. -class Module(ASTVisitor, NamespaceDict): - - "An inspected module." +class Module(NamespaceDict): - def __init__(self, name, importer=None): - ASTVisitor.__init__(self) + def __init__(self, name): NamespaceDict.__init__(self) - self.visitor = self - self.name = name - self.importer = importer - self.loaded = 0 # Module attributes. @@ -340,6 +336,50 @@ self.all_objects = [] + # Image generation details. + + self.location = None + + def full_name(self): + return self.name + + def __repr__(self): + return "Module(%r, location=%r)" % (self.name, self.location) + + # Attribute methods. + + def module_attribute_names(self): + + "Return the module attribute names provided by the module." + + if self.modattr_names is None: + self.module_attributes() + return self.modattr_names + + def module_attributes(self): + + "Return a dictionary mapping names to module attributes." + + if self.modattr is None: + self.modattr = {} + self.modattr_names = self.keys() + for i, name in enumerate(self.modattr_names): + self.modattr[name] = Attr(i, self, self[name]) + + return self.modattr + +class InspectedModule(ASTVisitor, Module): + + "An inspected module." + + def __init__(self, name, importer=None): + ASTVisitor.__init__(self) + Module.__init__(self, name) + self.visitor = self + + self.importer = importer + self.loaded = 0 + # Current expression state. self.expr = None @@ -350,10 +390,6 @@ self.namespaces = [] self.module = None - # Image generation details. - - self.location = None - def parse(self, filename): "Parse the file having the given 'filename'." @@ -382,34 +418,6 @@ if isinstance(value, Module) and not value.loaded: del self[name] - def full_name(self): - return self.name - - def __repr__(self): - return "Module(%r, location=%r)" % (self.name, self.location) - - # Attribute methods. - - def module_attribute_names(self): - - "Return the module attribute names provided by the module." - - if self.modattr_names is None: - self.module_attributes() - return self.modattr_names - - def module_attributes(self): - - "Return a dictionary mapping names to module attributes." - - if self.modattr is None: - self.modattr = {} - self.modattr_names = self.keys() - for i, name in enumerate(self.modattr_names): - self.modattr[name] = Attr(i, self, self[name]) - - return self.modattr - # Namespace methods. def store(self, name, obj): @@ -431,8 +439,10 @@ "Record instance attribute 'name' in the current class." if self.in_init: + # Current namespace is the function. # Previous namespace is the class. + self.namespaces[-2].add_instance_attribute(name) def get_parent(self): @@ -573,10 +583,13 @@ ) self.namespaces.append(function) + # Current namespace is the function. # Previous namespace is the class. + if node.name == "__init__" and isinstance(self.namespaces[-2], Class): self.in_init = 1 + self.dispatch(node.code) self.in_init = 0 self.namespaces.pop() @@ -599,12 +612,14 @@ return expr.namespace.get(node.attrname) elif isinstance(expr, UnresolvedName): return UnresolvedName(node.attrname, expr.full_name()) - return builtins_namespace.get(node.attrname) + return builtins.get(node.attrname) def visitGlobal(self, node): if self.namespaces: for name in node.names: self.namespaces[-1].make_global(name) + if not self.has_key(name): + self[name] = None def visitIf(self, node): for test, body in node.tests: @@ -656,8 +671,8 @@ return Self() elif self.has_key(name): return self[name] - elif builtins_namespace.has_key(name): - return builtins_namespace[name] + elif builtins.has_key(name): + return builtins[name] else: return None @@ -720,23 +735,31 @@ # Built-in types initialisation. -builtins_namespace = {} -for key in ['ArithmeticError', 'AssertionError', 'AttributeError', - 'BaseException', 'DeprecationWarning', 'EOFError', 'Ellipsis', - 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', - 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', - 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', - 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', - 'None', 'NotImplemented', 'NotImplementedError', 'OSError', - 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', - 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', - 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', - 'TabError', 'True', 'TypeError', 'UnboundLocalError', - 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', - 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', - 'ValueError', 'Warning', 'ZeroDivisionError', - 'bool', 'buffer', 'complex', 'dict', 'file', 'float', 'int', 'list', - 'long', 'object', 'slice', 'str', 'tuple', 'type', 'unicode']: - builtins_namespace[key] = Class(key, "__builtins__") +class Builtins(Module): + + "The special built-in types module." + + def __init__(self): + Module.__init__(self, "__builtins__") + + for key in ['ArithmeticError', 'AssertionError', 'AttributeError', + 'BaseException', 'DeprecationWarning', 'EOFError', 'Ellipsis', + 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', + 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', + 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', + 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', + 'None', 'NotImplemented', 'NotImplementedError', 'OSError', + 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', + 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', + 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', + 'TabError', 'True', 'TypeError', 'UnboundLocalError', + 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', + 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', + 'ValueError', 'Warning', 'ZeroDivisionError', + 'bool', 'buffer', 'complex', 'dict', 'file', 'float', 'int', 'list', + 'long', 'object', 'slice', 'str', 'tuple', 'type', 'unicode']: + self[key] = Class(key, self.full_name()) + +builtins = Builtins() # vim: tabstop=4 expandtab shiftwidth=4