# HG changeset patch # User Paul Boddie # Date 1244935085 -7200 # Node ID 6cf226d3df537400b071431a10f6976b031de5cc # Parent 2a64685ab6dcacdca7a299f708d18520dbd55e1c Fixed the constant input optimisation test to ensure that instances are not generally considered constant. Added a test for ambiguous classes where classes are defined using the same name in the same module namespace. Improved the test method in the RSVP implementation to handle missing results. Improved test coverage. diff -r 2a64685ab6dc -r 6cf226d3df53 docs/concepts.txt --- a/docs/concepts.txt Fri Jun 12 22:03:56 2009 +0200 +++ b/docs/concepts.txt Sun Jun 14 01:18:05 2009 +0200 @@ -26,6 +26,13 @@ permitting the use of tables (described below). Module and class attributes can also be finalised in this way in order to permit certain optimisations. +An additional restriction required for the current implementation of tables +(as described below) applies to class definitions: each class must be defined +using a unique name; repeated definition of classes having the same name is +thus not permitted. This restriction arises from the use of the "full name" of +a class as a key to the object table, where the full name is a qualified path +via the module hierarchy ending with the name of the class. + See rejected.txt for complicating mechanisms which could be applied to mitigate the effects of these restrictions on optimisations. diff -r 2a64685ab6dc -r 6cf226d3df53 micropython/__init__.py --- a/micropython/__init__.py Fri Jun 12 22:03:56 2009 +0200 +++ b/micropython/__init__.py Sun Jun 14 01:18:05 2009 +0200 @@ -343,10 +343,21 @@ for obj in module.all_objects: if isinstance(obj, micropython.inspect.Class): - attributes = {obj.full_name() : obj} + + # Prevent ambiguous classes. + + full_name = obj.full_name() + name = obj.name + + if module.has_key(name) and module[name].defines_ambiguous_class(): + raise TableGenerationError, "Class %r in module %r is ambiguously defined." % (name, module.full_name()) + + # Define a table entry for the class. + + attributes = {full_name : obj} attributes.update(obj.all_attributes()) attributes.update(obj.all_descendants()) - t.add(obj.full_name(), attributes) + t.add(full_name, attributes) return self.objtable diff -r 2a64685ab6dc -r 6cf226d3df53 micropython/common.py --- a/micropython/common.py Fri Jun 12 22:03:56 2009 +0200 +++ b/micropython/common.py Sun Jun 14 01:18:05 2009 +0200 @@ -44,6 +44,12 @@ pass +class TableGenerationError(ProcessingError): + + "An error occurring when generating a lookup table." + + pass + class NodeProcessingError(ProcessingError): "A processing error associated with a particular program node." diff -r 2a64685ab6dc -r 6cf226d3df53 micropython/data.py --- a/micropython/data.py Fri Jun 12 22:03:56 2009 +0200 +++ b/micropython/data.py Sun Jun 14 01:18:05 2009 +0200 @@ -361,6 +361,20 @@ return isinstance(self.parent, (Class, Module)) + def defines_ambiguous_class(self): + + "Return whether this attribute defines more than one class." + + if self.assignments > 1: + have_class = 0 + for obj in self.get_values(): + if isinstance(obj, Class): + if have_class: + return 1 + have_class = 1 + + return 0 + def defined_within_hierarchy(self): """ diff -r 2a64685ab6dc -r 6cf226d3df53 micropython/opt.py --- a/micropython/opt.py Fri Jun 12 22:03:56 2009 +0200 +++ b/micropython/opt.py Sun Jun 14 01:18:05 2009 +0200 @@ -152,7 +152,8 @@ "Return whether 'instruction' provides a constant input." - return isinstance(instruction, LoadAddress) and instruction.attr.assignments == 1 or \ + return isinstance(instruction, LoadAddress) and instruction.attr.assignments == 1 and \ + isinstance(instruction.attr.get_value(), Constant) or \ isinstance(instruction, (LoadConst, LoadClass, LoadFunction)) def is_constant_target(self, instruction): diff -r 2a64685ab6dc -r 6cf226d3df53 micropython/program.py --- a/micropython/program.py Fri Jun 12 22:03:56 2009 +0200 +++ b/micropython/program.py Sun Jun 14 01:18:05 2009 +0200 @@ -61,6 +61,8 @@ def __nonzero__(self): return self.truth_value + __shortrepr__ = __repr__ + # A representation of a context that is replaced upon certain assignment # operations. diff -r 2a64685ab6dc -r 6cf226d3df53 rsvp.py --- a/rsvp.py Fri Jun 12 22:03:56 2009 +0200 +++ b/rsvp.py Sun Jun 14 01:18:05 2009 +0200 @@ -291,10 +291,14 @@ attr_location = module.location + 1 + attr.position context, ref = self.load(attr_location) - content = self.load(ref + 1) - print label, expected, content - success = success and (int(expected) == content) + if ref is not None: + content = self.load(ref + 1) + print label, expected, content + success = success and (int(expected) == content) + else: + print label, expected, "missing" + success = 0 return success else: @@ -901,9 +905,10 @@ def builtins_list_new(self): frame = self.local_sp_stack[-1] + # The first parameter should be empty. # NOTE: Specific copying of tuples/lists. - args_context, args = self.frame_stack[frame] + args_context, args = self.frame_stack[frame + 1] header = self.load(args) list = self._MakeObject(header.size, self.list_instance) diff -r 2a64685ab6dc -r 6cf226d3df53 tests/failure/instance_multiple_classes.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/failure/instance_multiple_classes.py Sun Jun 14 01:18:05 2009 +0200 @@ -0,0 +1,13 @@ +#!/usr/bin/env python + +class C: + x = 111 + +class C: + def __init__(self): + self.x = 222 + +c = C() +result_222 = c.x + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 2a64685ab6dc -r 6cf226d3df53 tests/instance.py --- a/tests/instance.py Fri Jun 12 22:03:56 2009 +0200 +++ b/tests/instance.py Sun Jun 14 01:18:05 2009 +0200 @@ -1,28 +1,9 @@ #!/usr/bin/env python class C: - pass - -class D: - def __init__(self): - pass - -class E: - def __init__(self, x): - pass - -class F: - def __init__(self, x=1): - pass + x = 111 c = C() -X = C -x = X() -d = D() -e = E(1) -f = F() -f = F(2) -X = F -x = X() +result_111 = c.x # vim: tabstop=4 expandtab shiftwidth=4 diff -r 2a64685ab6dc -r 6cf226d3df53 tests/instance_initialisation.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/instance_initialisation.py Sun Jun 14 01:18:05 2009 +0200 @@ -0,0 +1,10 @@ +#!/usr/bin/env python + +class D: + def __init__(self): + self.x = 222 + +d = D() +result_222 = d.x + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 2a64685ab6dc -r 6cf226d3df53 tests/instance_initialisation_parameters.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/instance_initialisation_parameters.py Sun Jun 14 01:18:05 2009 +0200 @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +class E: + def __init__(self, x): + self.x = x + +class F: + def __init__(self, x=3): + self.x = x + +e = E(1) +f = F() +g = F(2) +X = F +x = X() + +result_1 = e.x +result1_3 = f.x +result_2 = g.x +result2_3 = x.x + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 2a64685ab6dc -r 6cf226d3df53 tests/instance_uncertain.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/instance_uncertain.py Sun Jun 14 01:18:05 2009 +0200 @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +class C: + x = 111 + +X = 1 +X = C +x = X() + +result_111 = x.x + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 2a64685ab6dc -r 6cf226d3df53 tests/list.py --- a/tests/list.py Fri Jun 12 22:03:56 2009 +0200 +++ b/tests/list.py Sun Jun 14 01:18:05 2009 +0200 @@ -1,8 +1,12 @@ #!/usr/bin/env python -[1, 2, 3] a = [1, 2, 3] -[1, [2, 3], 4, 5] -b = list((9, 8, 7)) +b = [1, [2, 3], 4, 5] +c = list((9, 8, 7)) + +result_3 = a[2] +result_4 = b[2] +result_2 = b[1][0] +result_9 = c[0] # vim: tabstop=4 expandtab shiftwidth=4 diff -r 2a64685ab6dc -r 6cf226d3df53 tests/list_assign.py --- a/tests/list_assign.py Fri Jun 12 22:03:56 2009 +0200 +++ b/tests/list_assign.py Sun Jun 14 01:18:05 2009 +0200 @@ -1,6 +1,9 @@ #!/usr/bin/env python [a, b, c] = [1, 2, 3] -[x, y, z] = list((9, 8, 7)) + +result_1 = a +result_2 = b +result_3 = c # vim: tabstop=4 expandtab shiftwidth=4 diff -r 2a64685ab6dc -r 6cf226d3df53 tests/list_assign2.py --- a/tests/list_assign2.py Fri Jun 12 22:03:56 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -#!/usr/bin/env python - -[d, [e, f], g] = [4, [5, 6], 7] - -# vim: tabstop=4 expandtab shiftwidth=4 diff -r 2a64685ab6dc -r 6cf226d3df53 tests/list_assign_constructor.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/list_assign_constructor.py Sun Jun 14 01:18:05 2009 +0200 @@ -0,0 +1,9 @@ +#!/usr/bin/env python + +[x, y, z] = list((9, 8, 7)) + +result_9 = x +result_8 = y +result_7 = z + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 2a64685ab6dc -r 6cf226d3df53 tests/list_assign_nested.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/list_assign_nested.py Sun Jun 14 01:18:05 2009 +0200 @@ -0,0 +1,10 @@ +#!/usr/bin/env python + +[d, [e, f], g] = [4, [5, 6], 7] + +result_4 = d +result_5 = e +result_6 = f +result_7 = g + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 2a64685ab6dc -r 6cf226d3df53 tests/logical.py --- a/tests/logical.py Fri Jun 12 22:03:56 2009 +0200 +++ b/tests/logical.py Sun Jun 14 01:18:05 2009 +0200 @@ -2,7 +2,7 @@ a = 1 b = 0 -c = a and b -d = a or b +result_0 = a and b +result_1 = a or b # vim: tabstop=4 expandtab shiftwidth=4