# HG changeset patch # User Paul Boddie # Date 1228176799 -3600 # Node ID e9402bb3f2de875774614b7fd6f7466476c6dbcc # Parent a25117656161dc5300f8e879867fe08211b1fa8f Moved raw code production into the Importer class. Attempted to support full, proper positioning of objects and code blocks. Removed obsolete label support. diff -r a25117656161 -r e9402bb3f2de micropython/__init__.py --- a/micropython/__init__.py Mon Nov 10 23:57:05 2008 +0100 +++ b/micropython/__init__.py Tue Dec 02 01:13:19 2008 +0100 @@ -206,13 +206,12 @@ paramtable = self.get_parameter_table() self.finalise() - image = [] + self.code = [] # Append constants to the image. for pos, const in enumerate(self.constants()): - const.location = pos - image.append(const) + self.code.append(const) last_module = self.modules_ordered[-1] @@ -221,22 +220,21 @@ if not with_builtins and module.name == "__builtins__": continue - pos = len(image) + pos = len(self.code) # Position the module in the image and make a translation. - module.location = pos trans = micropython.ast.Translation(module, self) # Add header details. - image.append(module) + self.code.append(module) pos += 1 # Append module attributes to the image. attributes = module.module_attributes() - image += module.attributes_as_list() + self.code += module.attributes_as_list() pos += len(attributes.keys()) # Append classes and functions to the image. @@ -244,28 +242,23 @@ for obj in module.all_objects: if isinstance(obj, micropython.inspect.Class): - # Position the class in the image. - - obj.location = pos - # Add header details. - image.append(obj) + self.code.append(obj) pos += 1 # Append class attributes to the image. attributes = obj.class_attributes() - image += obj.attributes_as_list() + self.code += obj.attributes_as_list() pos += len(attributes.keys()) # Generate the instantiator/initialiser. # Append the function code to the image. instantiator = obj.get_instantiator() - instantiator.code_location = pos code = trans.get_instantiator_code(obj) - image += code + self.code += code pos += len(code) # Class-level code is generated separately at the module @@ -274,44 +267,160 @@ elif isinstance(obj, micropython.inspect.Function): - # Position the function in the image. - - obj.location = pos - # Add header details. - image.append(obj) + self.code.append(obj) pos += 1 # Append any default values to the image. # Only do this for named functions (not lambdas). if obj.name is not None: - image += obj.default_attrs + self.code += obj.default_attrs pos += len(obj.default_attrs) # Append the function code to the image. - obj.code_location = pos code = trans.get_code(obj) - image += code + self.code += code pos += len(code) - # Remember the position of the module code. - - module.code_location = pos - # Append the module top-level code to the image. code = trans.get_module_code(final=(module is last_module)) - image += code + self.code += code pos += len(code) - # Remember the generated code and the location of the first instruction. + return self.code + + def get_raw_image(self, with_builtins=0): + + "Return the raw image representation of the program." + + self.get_image(with_builtins) + + objtable = self.get_object_table() + paramtable = self.get_parameter_table() + + # Position the objects. + + pos = 0 + for item in self.code: + if isinstance(item, Block): + item.location = pos + pos += len(item.code) + elif isinstance(item, (micropython.data.Class, micropython.data.Const, + micropython.data.Function, micropython.data.Module)): + item.location = pos + pos += 1 + if isinstance(item, micropython.data.Function): + item.code_location = pos + else: + pos += 1 + + # Generate the raw code. + + self.raw_code = [] + + for item in self.code: + + if isinstance(item, micropython.data.Attr): + self.raw_code.append(( + item.context and item.context.location, + item.value and item.value.location # no useful context is provided + )) + + elif isinstance(item, Block): + self.raw_code += self.raw_block(item, len(self.raw_code)) + + # Using classcode, attrcode, codeaddr, codedetails, instance. + + elif isinstance(item, micropython.data.Class): + assert item.location == len(self.raw_code) + + # NOTE: The instantiator code is the first block of the class. + + instantiator_code_location = item.get_instantiator().blocks[0].location + + # NOTE: Need initialiser details! + self.raw_code.append(( + objtable.as_list().get_code(item.full_name()), + objtable.get_index(item.full_name()), + instantiator_code_location, + ( + len(item.get_instantiator().positional_names), + len(item.get_instantiator().defaults) + ), + 0 + )) - self.code = image + elif isinstance(item, micropython.data.Const): + assert item.location == len(self.raw_code) + + # NOTE: Need class details! + self.raw_code.append(( + objtable.as_list().get_code(item.value_type_name()), + objtable.get_index(item.value_type_name()), + None, + None, + 1 + )) + + elif isinstance(item, micropython.data.Function): + assert item.location == len(self.raw_code) + + # NOTE: Need class and parameter details! Should arguably be types.FunctionType. + self.raw_code.append(( + objtable.as_list().get_code("__builtins__.function"), + objtable.get_index("__builtins__.function"), + item.code_location, + ( + len(item.positional_names), + len(item.defaults) + ), + 0 + )) + + assert item.code_location == len(self.raw_code) + + elif isinstance(item, micropython.data.Module): + assert item.location == len(self.raw_code) + + self.raw_code.append(( + objtable.as_list().get_code(item.full_name()), + None, # module name not used as an attribute + None, + None, + 0 + )) + + else: + self.raw_code.append(item) + + # Fix the module locations. + + for module in self.modules_ordered: + + if not with_builtins and module.name == "__builtins__": + continue + + module.code_location = module.blocks[0].location + self.code_location = self.modules["__main__"].code_location - return image + return self.raw_code + + def raw_block(self, block, location): + + """ + Return the code for the given 'block', appearing at the given + 'location'. + """ + + assert block.location == location + for i, item in enumerate(block.code): + if hasattr(item, "location"): + item.location = location + i + return block.code def get_object_table(self): diff -r a25117656161 -r e9402bb3f2de micropython/ast.py --- a/micropython/ast.py Mon Nov 10 23:57:05 2008 +0100 +++ b/micropython/ast.py Tue Dec 02 01:13:19 2008 +0100 @@ -128,6 +128,7 @@ self.new_op(Return()) self.unit.temp_usage = self.max_temp_position + 1 + self.unit.blocks = self.blocks return self.blocks def get_code(self, unit): @@ -144,6 +145,7 @@ self.dispatch(unit.astnode) self.unit.temp_usage = self.max_temp_position + 1 + self.unit.blocks = self.blocks return self.blocks def get_instantiator_code(self, cls): @@ -183,6 +185,7 @@ self.new_op(StoreResult()) self.new_op(Return()) + self.unit.blocks = self.blocks return self.blocks # Allocation-related methods. @@ -271,25 +274,6 @@ def drop_exception_blocks(self): self.exception_blocks.pop() - def new_label(self): - - "Return a new label object for use with set_label." - - number = self.label_number - label = Label(number) - self.labels[label] = label - self.label_number += 1 - return label - - def set_label(self, label): - - """ - Set the location of 'label' to that within the entire image: the - location within the code combined with location of the code unit. - """ - - label.location = len(self.code) + self.unit.code_location - # Assignment expression values. def record_value(self, immediate=1): @@ -1637,7 +1621,6 @@ unit = self.unit self.unit = node.unit - self.unit.code_location = self.module.code_location # class body code is not independently addressable self.dispatch(node.code) self.unit = unit diff -r a25117656161 -r e9402bb3f2de micropython/data.py --- a/micropython/data.py Mon Nov 10 23:57:05 2008 +0100 +++ b/micropython/data.py Tue Dec 02 01:13:19 2008 +0100 @@ -404,6 +404,7 @@ # Program-related details. + self.blocks = None self.temp_usage = 0 self.local_usage = 0 self.all_local_usage = 0 @@ -749,6 +750,7 @@ # Program-related details. + self.blocks = None self.temp_usage = 0 self.local_usage = 0 self.all_local_usage = 0 @@ -943,6 +945,7 @@ # Program-related details. + self.blocks = None self.temp_usage = 0 self.local_usage = 0 self.all_local_usage = 0 diff -r a25117656161 -r e9402bb3f2de micropython/rsvp.py --- a/micropython/rsvp.py Mon Nov 10 23:57:05 2008 +0100 +++ b/micropython/rsvp.py Tue Dec 02 01:13:19 2008 +0100 @@ -19,92 +19,7 @@ this program. If not, see . """ -from micropython.common import Block -from micropython.data import Attr, Class, Const, Function, Module - -def raw(code, objtable, paramtable): - - """ - Return the raw image representation of the given 'code', using the given - 'objtable' and 'paramtable' to populate structures. - """ - - new_code = [] - - for item in code: - - if isinstance(item, Attr): - new_code.append(( - item.context and item.context.location, - item.value and item.value.location # no useful context is provided - )) - - elif isinstance(item, Block): - new_code += raw_block(item, len(new_code)) - - # Using classcode, attrcode, codeaddr, codedetails, instance. - - elif isinstance(item, Class): - # NOTE: Need initialiser details! - new_code.append(( - objtable.as_list().get_code(item.full_name()), - objtable.get_index(item.full_name()), - item.get_instantiator().code_location, - ( - len(item.get_instantiator().positional_names), - len(item.get_instantiator().defaults) - ), - 0 - )) - - elif isinstance(item, Const): - # NOTE: Need class details! - new_code.append(( - objtable.as_list().get_code(item.value_type_name()), - objtable.get_index(item.value_type_name()), - None, - None, - 1 - )) - - elif isinstance(item, Function): - # NOTE: Need class and parameter details! Should arguably be types.FunctionType. - new_code.append(( - objtable.as_list().get_code("__builtins__.function"), - objtable.get_index("__builtins__.function"), - item.code_location, - ( - len(item.positional_names), - len(item.defaults) - ), - 0 - )) - - elif isinstance(item, Module): - new_code.append(( - objtable.as_list().get_code(item.full_name()), - None, # module name not used as an attribute - None, - None, - 0 - )) - - else: - new_code.append(item) - - return new_code - -def raw_block(block, location): - - """ - Return the code for the given 'block', appearing at the given location. - """ - - block.location = location - for i, item in enumerate(block.code): - if hasattr(item, "location"): - item.location = location + i - return block.code +from micropython.data import Attr def name(attr): if isinstance(attr, Attr): diff -r a25117656161 -r e9402bb3f2de test.py --- a/test.py Mon Nov 10 23:57:05 2008 +0100 +++ b/test.py Tue Dec 02 01:13:19 2008 +0100 @@ -1,7 +1,6 @@ #!/usr/bin/env python import micropython -from micropython.rsvp import raw from micropython.graph import get_graph import rsvp import sys @@ -17,6 +16,9 @@ global code code = importer.get_image(with_builtins) +def raw(importer, with_builtins=0): + return importer.get_raw_image() + def show_code(code): for i, x in enumerate(code): print i, x @@ -38,7 +40,7 @@ attr_error = objlist.access("__builtins__", "AttributeError").value.location type_error = objlist.access("__builtins__", "TypeError").value.location print "Getting raw image..." - rc = raw(importer.get_image(), ot, pt) + rc = importer.get_raw_image() print "Initialising the machine..." rm = rsvp.RSVPMachine(rc, objlist.as_raw(), paramlist.as_raw(), attr_error, type_error, debug=debug) rm.pc = importer.code_location diff -r a25117656161 -r e9402bb3f2de tests/attributes1.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/attributes1.py Tue Dec 02 01:13:19 2008 +0100 @@ -0,0 +1,18 @@ +#!/usr/bin/env python + +class C: + clsattr = 123 + + def __init__(self, value): + self.instattr = value + self.clsattr + + def update(self, value): + self.attr = value + C.clsattr + +C +C.clsattr +C(456).update(789) + +# vim: tabstop=4 expandtab shiftwidth=4