# HG changeset patch # User Paul Boddie # Date 1276210568 -7200 # Node ID c368d83770c7d0f4f1f87227efd30ba9170de336 # Parent 62c4e5c5a2540bdb5d0379d092f6acdd81a1404e Replaced the native mechanism for list initialisation with a Python-based list.__init__ method and a simplified native method for initialising the initial list fragment. Introduced automatic namespace traversal of __init__ attributes for any namespace providing such attributes. Unfortunately, this inflates the program size substantially and needs to be reviewed. Enabled proper testing of xrange instances using the updated support for list initialisation. diff -r 62c4e5c5a254 -r c368d83770c7 TO_DO.txt --- a/TO_DO.txt Sat Jun 05 01:39:16 2010 +0200 +++ b/TO_DO.txt Fri Jun 11 00:56:08 2010 +0200 @@ -1,3 +1,7 @@ +Support __init__ traversal (and other implicit names) more effectively. + +Check context_value initialisation (avoiding or handling None effectively). + Loop entry points should capture usage to update later assignments in the loop. The continue and break statements should affect usage propagation. diff -r 62c4e5c5a254 -r c368d83770c7 lib/builtins.py --- a/lib/builtins.py Sat Jun 05 01:39:16 2010 +0200 +++ b/lib/builtins.py Fri Jun 11 00:56:08 2010 +0200 @@ -143,7 +143,22 @@ def __rrshift__(self): pass class list(object): - def __init__(self, args=()): pass + + "Implementation of list." + + def __init__(self, args=None): + + "Initialise the list." + + self.__new__() + + if args is not None: + for arg in args: + self.append(arg) + + def __new__(self): + self._elements = None # defined in a native method + def __getitem__(self, index): pass def __setitem__(self, index, value): pass def __getslice__(self, start, end=None): pass diff -r 62c4e5c5a254 -r c368d83770c7 micropython/__init__.py --- a/micropython/__init__.py Sat Jun 05 01:39:16 2010 +0200 +++ b/micropython/__init__.py Fri Jun 11 00:56:08 2010 +0200 @@ -5,7 +5,7 @@ from the simplify package but has had various details related to that package removed. -Copyright (C) 2006, 2007, 2008, 2009 Paul Boddie +Copyright (C) 2006, 2007, 2008, 2009, 2010 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -334,7 +334,7 @@ } names_always_used = [ - "bool", "__init__", "__call__", "__bool__", "__builtins__", "__main__" + "bool", "__init__", "__call__", "__bool__" ] def __init__(self, path=None, verbose=0, optimisations=None): @@ -498,9 +498,10 @@ # Include names which may not be explicitly used in programs. # NOTE: Potentially declare these when inspecting. - for name in self.names_always_used: - for objname in objtable.all_possible_objects([name]): - self.use_attribute(objname, name) + for attrname in self.names_always_used: + for objname in objtable.all_possible_objects([attrname]): + self.use_attribute(objname, attrname) + self._collect_attributes(objname + "." + attrname, objtable) def _collect_attributes(self, from_name, objtable): @@ -536,6 +537,13 @@ self.use_attribute(objname, attrname) self._collect_attributes(objname + "." + attrname, objtable) + # Where the object has an __init__ attribute, assume that it is an + # initialiser which is called at some point, and collect attributes used + # in this initialiser. + + if "__init__" in objtable.table.get(from_name, []): + self._collect_attributes(from_name + ".__init__", objtable) + # Constant accounting. def init_predefined_constants(self): diff -r 62c4e5c5a254 -r c368d83770c7 rsvplib.py --- a/rsvplib.py Sat Jun 05 01:39:16 2010 +0200 +++ b/rsvplib.py Fri Jun 11 00:56:08 2010 +0200 @@ -254,36 +254,19 @@ def builtins_list_new(self): frame = self.local_sp_stack[-1] - # The first parameter should be empty. - # NOTE: Specific copying of tuples/lists. + # The first parameter should be the instance. - args_value = self.frame_stack[frame + 1] + list_value = self.frame_stack[frame] - # Test operand suitability. + # Make a new sequence. + # NOTE: Using an arbitrary size. - if self.machine._CheckInstance(args_value.ref, self.list_class): - sequence = self.machine.load(args_value.ref + 1) - header = self.machine.load(sequence.ref) - size = header.occupied_size - elif self.machine._CheckInstance(args_value.ref, self.tuple_class): - sequence = args_value.ref - header = self.machine.load(sequence) - size = header.size - else: - self.machine.exception = self.machine._MakeObject(2, self.type_error_instance) - return self.machine.RaiseException() + new_fragment = self.machine._MakeFragment(5) - # Copy the sequence contents. - - new_fragment = self.machine._MakeFragment(size) - for i in range(1, size): - self.machine.save(new_fragment + i, self.machine.load(sequence + i)) + # Complete the list instance by saving the fragment reference. - # Make the list instance. - - addr = self.machine._MakeObject(2, self.list_instance) - self.machine.save(addr + 1, DataValue(None, new_fragment)) - + addr = list_value.ref + 1 + self.machine.save(addr, DataValue(None, new_fragment)) self.machine.result = DataValue(addr, addr) def builtins_list_getitem(self): @@ -500,9 +483,9 @@ "__builtins__.object.__init__" : builtins_object_init, # NOTE: A no-operation. "__builtins__.BaseException.__init__" : builtins_object_init, # NOTE: To be made distinct, potentially in the builtins module. - # Native instantiators: + # Native instantiator helpers: - "__builtins__.list" : builtins_list_new, + "__builtins__.list.__new__" : builtins_list_new, } # vim: tabstop=4 expandtab shiftwidth=4 diff -r 62c4e5c5a254 -r c368d83770c7 tests/xrange.py --- a/tests/xrange.py Sat Jun 05 01:39:16 2010 +0200 +++ b/tests/xrange.py Fri Jun 11 00:56:08 2010 +0200 @@ -1,6 +1,7 @@ #!/usr/bin/env python xr = xrange(0, 10, 1) +l = list(xr) result_0 = xr.start result_10 = xr.end result_1 = xr.step