1.1 --- a/docs/related.txt Sat Feb 06 21:00:28 2010 +0100
1.2 +++ b/docs/related.txt Sun Feb 07 02:02:15 2010 +0100
1.3 @@ -22,3 +22,8 @@
1.4
1.5 http://mail.python.org/pipermail/python-list/2009-November/1227265.html
1.6 http://groups.google.com/group/comp.lang.python/browse_frm/thread/c07268689549cf01/
1.7 +
1.8 +A discussion of how closures often obscure intent and how the use of classes
1.9 +and functions is often preferable:
1.10 +
1.11 +http://artificialcode.blogspot.com/2009/04/python-functional-programming.html
2.1 --- a/micropython/table.py Sat Feb 06 21:00:28 2010 +0100
2.2 +++ b/micropython/table.py Sun Feb 07 02:02:15 2010 +0100
2.3 @@ -3,7 +3,7 @@
2.4 """
2.5 Preparation of run-time attribute lookup tables.
2.6
2.7 -Copyright (C) 2007, 2008 Paul Boddie <paul@boddie.org.uk>
2.8 +Copyright (C) 2007, 2008, 2009, 2010 Paul Boddie <paul@boddie.org.uk>
2.9
2.10 This program is free software; you can redistribute it and/or modify it under
2.11 the terms of the GNU General Public License as published by the Free Software
2.12 @@ -353,6 +353,37 @@
2.13
2.14 list_class = ObjectList
2.15
2.16 + def all_possible_objects_plus_status(self, names):
2.17 +
2.18 + """
2.19 + Return all objects supporting attributes with the given 'names' plus
2.20 + whether such attributes can be exclusively static or may belong to
2.21 + instances. A list of tuples of the form (object name, is_static) is thus
2.22 + returned.
2.23 + """
2.24 +
2.25 + possible = []
2.26 + for objname in self.all_possible_objects(names):
2.27 + attributes = self.table[objname]
2.28 +
2.29 + is_static = 0
2.30 + is_instance = 0
2.31 +
2.32 + for name in names:
2.33 + if attributes[name].is_static_attribute():
2.34 + is_static = 1
2.35 + else:
2.36 + is_instance = 1
2.37 +
2.38 + if is_static and not is_instance:
2.39 + is_static = 1
2.40 + else:
2.41 + is_static = 0
2.42 +
2.43 + possible.append((objname, is_static))
2.44 +
2.45 + return possible
2.46 +
2.47 class ParameterTable(Table):
2.48
2.49 "A parameter table."
3.1 --- a/micropython/trans.py Sat Feb 06 21:00:28 2010 +0100
3.2 +++ b/micropython/trans.py Sun Feb 07 02:02:15 2010 +0100
3.3 @@ -317,13 +317,13 @@
3.4
3.5 # Get the names of all object types supporting these names.
3.6
3.7 - target_names = self.objtable.all_possible_objects(names_used)
3.8 + targets = self.objtable.all_possible_objects_plus_status(names_used)
3.9
3.10 # Where only one object type is suggested, produce a guard.
3.11 # NOTE: This only supports classes as types, not modules.
3.12
3.13 - if len(target_names) == 1:
3.14 - target_name = target_names[0]
3.15 + if len(targets) == 1:
3.16 + target_name, is_static = targets[0]
3.17
3.18 # Access the object table to get the attribute.
3.19 # NOTE: This depends on the special entry in the table
3.20 @@ -343,15 +343,22 @@
3.21 self.new_op(LoadClass(attr))
3.22 temp_target = self.optimiser.optimise_temp_storage()
3.23
3.24 - # Generate name is target (for classes).
3.25 + # For only static attributes, classes are acceptable.
3.26 +
3.27 + if is_static:
3.28 +
3.29 + # Generate name is target (for classes).
3.30
3.31 - self.dispatch(compiler.ast.Name(name))
3.32 - self.new_op(TestIdentity())
3.33 - self.optimiser.set_source(temp_target)
3.34 + self.dispatch(compiler.ast.Name(name))
3.35 + self.new_op(TestIdentity())
3.36 + self.optimiser.set_source(temp_target)
3.37
3.38 - # Jump to the next guard or the code if successful.
3.39 + # Jump to the next guard or the code if successful.
3.40
3.41 - self.new_op(JumpIfTrue(after_test_block))
3.42 + self.new_op(JumpIfTrue(after_test_block))
3.43 +
3.44 + # Where instance attributes are involved, only instances are
3.45 + # acceptable.
3.46
3.47 # Generate isinstance(name, target).
3.48
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/tests/attribute_access_type_restriction_single_instance.py Sun Feb 07 02:02:15 2010 +0100
4.3 @@ -0,0 +1,36 @@
4.4 +#!/usr/bin/env python
4.5 +
4.6 +"""
4.7 +This test attempts to guard 'obj' in 'test_one' with only an instance check for
4.8 +D instances. In the process, the unused methods should be discarded.
4.9 +"""
4.10 +
4.11 +class C:
4.12 + def f(self): # unused
4.13 + return 1
4.14 +
4.15 +class D:
4.16 + def f(self):
4.17 + return 2
4.18 +
4.19 + def __init__(self, g):
4.20 + self.g = g
4.21 +
4.22 +class E:
4.23 + def f(self): # unused
4.24 + return 4
4.25 +
4.26 + def h(self): # unused
4.27 + return 5
4.28 +
4.29 +def test_one(obj):
4.30 + # obj: D (f, g)
4.31 + obj.f() # C, D, E (f)
4.32 + return obj.g # D (f, g) - instance only
4.33 +
4.34 +c = C()
4.35 +d = D(4)
4.36 +e = E()
4.37 +result1_4 = test_one(d)
4.38 +
4.39 +# vim: tabstop=4 expandtab shiftwidth=4