# HG changeset patch # User Paul Boddie # Date 1235264597 -3600 # Node ID 9ae98b889fe7355698969d26cc53e85063b148c3 # Parent 80ddd8db26120ae048719a72d47335ec4e5de276 Changed inspected context details to more accurately reflect the current policy. Added more precise documentation about contexts, assignments and accesses. Expanded the tests and reference programs around context behaviour. Split the addition tests into more precise programs. Fixed the RSVP integer addition result and instance tests. Added a -m option to the test program to make an RSVP machine immediately. diff -r 80ddd8db2612 -r 9ae98b889fe7 docs/assignment.txt --- a/docs/assignment.txt Fri Feb 20 01:24:14 2009 +0100 +++ b/docs/assignment.txt Sun Feb 22 02:03:17 2009 +0100 @@ -1,13 +1,44 @@ +Object contexts: + + Object Context + ------ ------- + function overridable + method defining/originating class + class null + instance self + module null + Assignment types: Assignment of stored value to... Effect on context -------------------------------- ----------------- local preserved global (module) preserved - class preserved + class overridden (if overridable) instance preserved - Assignment to a namespace preserves the context + Assignment to a namespace preserves the context except for some class + assignments + +Assigning to classes: + + Assignment of... Effect on context + ---------------- ----------------- + function (overridable context) overridden by class (becomes method) + method (existing context) preserved + class (null context) preserved + instance (self context) preserved + module (null context) preserved + +With run-time restrictions on assignment targets: + + Assignment of stored value to... Effect on context Optimised instruction Unoptimised instruction + -------------------------------- ----------------- --------------------- ----------------------- + local preserved StoreName + global (module) preserved StoreAddress StoreAttrIndex + instance preserved StoreAttr StoreAttrIndex + + Class assignments are not permitted Access types: diff -r 80ddd8db2612 -r 9ae98b889fe7 micropython/ast.py --- a/micropython/ast.py Fri Feb 20 01:24:14 2009 +0100 +++ b/micropython/ast.py Sun Feb 22 02:03:17 2009 +0100 @@ -523,6 +523,7 @@ return # Or generate an instruction operating on a class attribute. + # NOTE: Any simple instruction providing self is not removed. except KeyError: diff -r 80ddd8db2612 -r 9ae98b889fe7 micropython/data.py --- a/micropython/data.py Fri Feb 20 01:24:14 2009 +0100 +++ b/micropython/data.py Sun Feb 22 02:03:17 2009 +0100 @@ -119,7 +119,10 @@ def _set(self, name, value): - "The underlying set operation associating 'name' with 'value'." + """ + The underlying set operation associating 'name' with 'value'. + See: docs/assignment.txt + """ if not self.namespace.has_key(name): @@ -129,10 +132,13 @@ if value.context is not None: self.namespace[name] = Attr(None, self, value.context, name, value.value) return self.namespace[name] + + # Or accept the value of the attribute. + else: value = value.value - # Or attempt to fix the context. + # Then/or attempt to fix the context. context = self._context(value) self.namespace[name] = Attr(None, self, context, name, value) @@ -143,11 +149,15 @@ """ Return the context to be used when storing the given 'value'. - NOTE: This context is not likely to be useful when preparing an image - NOTE: since only instance contexts have significant effects at run-time. + See: docs/assignment.txt """ - return None + # Set the context of instances to themselves. + + if isinstance(value, Instance): + return value + else: + return None def make_global(self, name): if not self.namespace.has_key(name): @@ -427,18 +437,22 @@ """ Return the context to be used when storing the given 'value'. - NOTE: This context is not likely to be useful when preparing an image - NOTE: since only instance contexts have significant effects at run-time. + See: docs/assignment.txt """ if value is not None: - context = value.parent - if isinstance(context, Module): - return self - else: - return context - else: - return None + + # Change the ownership of functions. + + if isinstance(value, Function): + context = value.parent + + if isinstance(context, Module): + return self + else: + return context + + return NamespaceDict._context(self, value) def finalise_attributes(self): diff -r 80ddd8db2612 -r 9ae98b889fe7 micropython/opt.py --- a/micropython/opt.py Fri Feb 20 01:24:14 2009 +0100 +++ b/micropython/opt.py Sun Feb 22 02:03:17 2009 +0100 @@ -3,7 +3,7 @@ """ Optimise code produced by the AST translator. -Copyright (C) 2007, 2008 Paul Boddie +Copyright (C) 2007, 2008, 2009 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 diff -r 80ddd8db2612 -r 9ae98b889fe7 rsvp.py --- a/rsvp.py Fri Feb 20 01:24:14 2009 +0100 +++ b/rsvp.py Sun Feb 22 02:03:17 2009 +0100 @@ -560,7 +560,7 @@ # Test operand suitability. - if not self._CheckInstance(left, self.int_class) and self._CheckInstance(right, self.int_class): + if not self._CheckInstance(left, self.int_instance_location) and self._CheckInstance(right, self.int_instance_location): self.exception = self.type_error return self.RaiseException() @@ -574,9 +574,10 @@ addr = self._MakeObject(2, self.int_instance_location) self.save(addr + 1, self.load(left_data) + self.load(right_data)) - # Return the new object (with a null context). + # Return the new object. + # Introduce object as context for the new object. - self.result = None, addr + self.result = addr, addr native_functions = { "__builtins__.object.__init__" : builtins_object_init, diff -r 80ddd8db2612 -r 9ae98b889fe7 test.py --- a/test.py Fri Feb 20 01:24:14 2009 +0100 +++ b/test.py Sun Feb 22 02:03:17 2009 +0100 @@ -86,4 +86,7 @@ ot = p.get_object_table() pt = p.get_parameter_table() + if "-m" in args: + rm = machine(p) + # vim: tabstop=4 expandtab shiftwidth=4 diff -r 80ddd8db2612 -r 9ae98b889fe7 tests/classes.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/classes.py Sun Feb 22 02:03:17 2009 +0100 @@ -0,0 +1,17 @@ +#!/usr/bin/env python + +class B: + pass + +class A: + c0 = B + def __init__(self): + self.c2 = B + +a = A() + + # context on A attribute context on a attribute +A.c0 # none none +a.c2 # N/A none + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 80ddd8db2612 -r 9ae98b889fe7 tests/methods.py --- a/tests/methods.py Fri Feb 20 01:24:14 2009 +0100 +++ b/tests/methods.py Sun Feb 22 02:03:17 2009 +0100 @@ -1,13 +1,11 @@ #!/usr/bin/env python -def f(x): - pass - class B: def f(self): pass - Bf = f # context == parent +def f(self): + pass b = B() @@ -16,7 +14,6 @@ f1 = f # unbound (A) bound (a) f2 = B.f # unbound (B) unbound (B) f3 = b.f # bound (b) bound (b) - Bf = B.Bf # unbound (B) unbound (B) def __init__(self): self.f4 = f # N/A function @@ -24,14 +21,15 @@ self.f6 = b.f # N/A bound (b) def m(self): - self.f1 - self.f2 - self.f3 - self.f4 - self.f5 - self.f6 + x = self.f1 # should use optimised attribute access + x = self.f2 + x = self.f3 + x = self.f4 + x = self.f5 + x = self.f6 a = A() +a.m() A.f1 A.f2 diff -r 80ddd8db2612 -r 9ae98b889fe7 tests/op_add.py --- a/tests/op_add.py Fri Feb 20 01:24:14 2009 +0100 +++ b/tests/op_add.py Sun Feb 22 02:03:17 2009 +0100 @@ -1,8 +1,5 @@ #!/usr/bin/env python -def f(a, b, c=a+b): - return a + b - a = 1 b = 2 c = a + b diff -r 80ddd8db2612 -r 9ae98b889fe7 tests/op_add_default.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/op_add_default.py Sun Feb 22 02:03:17 2009 +0100 @@ -0,0 +1,8 @@ +#!/usr/bin/env python + +def f(a, b, c=a+b): + return a + b + c + +x = f(1, 2) + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 80ddd8db2612 -r 9ae98b889fe7 tests/reference/classes.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/reference/classes.py Sun Feb 22 02:03:17 2009 +0100 @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +class B: + pass + +class A: + c0 = B + + # context on A attribute context on a attribute +A.c0 # none none +A.c1 = B # none none +a = A() +a.c2 = B # N/A none + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 80ddd8db2612 -r 9ae98b889fe7 tests/reference/methods.py --- a/tests/reference/methods.py Fri Feb 20 01:24:14 2009 +0100 +++ b/tests/reference/methods.py Sun Feb 22 02:03:17 2009 +0100 @@ -1,8 +1,5 @@ #!/usr/bin/env python -class A: - pass - class B: def f(self): print self @@ -10,10 +7,14 @@ def f(self): print self +class A: + f0 = f + b = B() # on A on a context on A attribute context on a attribute -A.f1 = f # unbound bound (a) A a +A.f0 # unbound bound (a) A (need A instance) a +A.f1 = f # unbound bound (a) A (need A instance) a A.f2 = B.f # unbound unbound B (need B instance) B (need B instance) A.f3 = b.f # bound (b) bound (b) b b a = A()