1.1 --- a/TO_DO.txt Sat Jun 12 23:09:30 2010 +0200
1.2 +++ b/TO_DO.txt Sun Jun 13 02:24:35 2010 +0200
1.3 @@ -1,12 +1,27 @@
1.4 +Check name origin where multiple branches could yield multiple scope interpretations:
1.5 +
1.6 +----
1.7 +try:
1.8 + set # built-in name
1.9 +except NameError:
1.10 + from sets import Set as set # local definition of name
1.11 +
1.12 +set # could be confused by the local definition at run-time
1.13 +----
1.14 +
1.15 Support __init__ traversal (and other implicit names) more effectively.
1.16
1.17 Check context_value initialisation (avoiding or handling None effectively).
1.18
1.19 +__getitem__ could be written in Python, using a native method only to access fragments.
1.20 +Support slicing.
1.21 +Consider better "macro" support where new expressions need to be generated and processed.
1.22 +
1.23 +**** Constant attribute users need not maintain usage since they are already resolved. ****
1.24 +
1.25 Loop entry points should capture usage to update later assignments in the loop.
1.26 The continue and break statements should affect usage propagation.
1.27
1.28 -Constant attribute users need not maintain usage since they are already resolved.
1.29 -
1.30 Consider handling CallFunc in micropython.inspect in order to produce instances of specific classes.
1.31 Then, consider adding support for guard removal/verification where known instances are involved.
1.32 Consider handling branches of values within namespaces in order to support more precise value usage.
2.1 --- a/lib/builtins.py Sat Jun 12 23:09:30 2010 +0200
2.2 +++ b/lib/builtins.py Sun Jun 13 02:24:35 2010 +0200
2.3 @@ -233,8 +233,7 @@
2.4 class set(object):
2.5 def __init__(self, iterable): pass
2.6
2.7 -class slice(object):
2.8 - def __init__(self, start_or_end, end=None, step=None): pass
2.9 +# See below for slice.
2.10
2.11 class str(basestring):
2.12 pass
2.13 @@ -277,6 +276,7 @@
2.14
2.15 self.step = step
2.16 self.current = self.start
2.17 + self.limited = self.end is not None
2.18
2.19 def __iter__(self):
2.20
2.21 @@ -288,13 +288,24 @@
2.22
2.23 "Return the next item or raise a StopIteration exception."
2.24
2.25 - if self.step < 0 and self.current <= self.end or self.step > 0 and self.current >= self.end:
2.26 - raise StopIteration()
2.27 + if self.limited:
2.28 + if self.step < 0 and self.current <= self.end or self.step > 0 and self.current >= self.end:
2.29 + raise StopIteration()
2.30
2.31 current = self.current
2.32 self.current += self.step
2.33 return current
2.34
2.35 +class slice(xrange):
2.36 +
2.37 + "Implementation of slice."
2.38 +
2.39 + def __init__(self, start_or_end=None, end=None, step=1):
2.40 +
2.41 + "Initialise the slice with the given 'start_or_end', 'end' and 'step'."
2.42 +
2.43 + xrange.__init__(self, start_or_end, end, step)
2.44 +
2.45 # Exceptions and warnings.
2.46
2.47 class BaseException(object):
2.48 @@ -402,9 +413,29 @@
2.49 return obj.__len__()
2.50
2.51 def locals(): pass
2.52 +
2.53 def map(function, *args): pass
2.54 -def max(*args): pass
2.55 -def min(*args): pass
2.56 +
2.57 +def max(*args):
2.58 +
2.59 + "Implementation of max."
2.60 +
2.61 + highest = args[0]
2.62 + for arg in args[1:]:
2.63 + if arg > highest:
2.64 + highest = arg
2.65 + return highest
2.66 +
2.67 +def min(*args):
2.68 +
2.69 + "Implementation of min."
2.70 +
2.71 + lowest = args[0]
2.72 + for arg in args[1:]:
2.73 + if arg > lowest:
2.74 + lowest = arg
2.75 + return lowest
2.76 +
2.77 def oct(number): pass
2.78 def open(name, mode=None, buffering=None): pass
2.79 def ord(c): pass
3.1 --- a/micropython/ast.py Sat Jun 12 23:09:30 2010 +0200
3.2 +++ b/micropython/ast.py Sun Jun 13 02:24:35 2010 +0200
3.3 @@ -429,7 +429,25 @@
3.4 else:
3.5 self._visitName(node, self.name_load_instructions)
3.6
3.7 - def visitSlice(self, node): raise TranslationNotImplementedError("Slice")
3.8 + def visitSlice(self, node):
3.9 + if node.lower is None:
3.10 + if node.upper is None:
3.11 + args = []
3.12 + else:
3.13 + args = [compiler.ast.Name("None"), node.upper]
3.14 + else:
3.15 + args = [node.lower]
3.16 +
3.17 + # NOTE: Need to guarantee reliable access to the slice built-in.
3.18 +
3.19 + slice = compiler.ast.CallFunc(compiler.ast.Name("slice"), args)
3.20 +
3.21 + self.dispatch(node.expr)
3.22 + self._startCallFunc()
3.23 + self._generateAttr(node, "__getitem__", self.attribute_load_instructions)
3.24 + temp_target, target, temp_context = self._generateCallFunc([slice], node)
3.25 + self._doCallFunc(temp_target, target)
3.26 + self._endCallFunc(temp_target, target, temp_context)
3.27
3.28 def visitSubscript(self, node):
3.29 self.dispatch(node.expr)
4.1 --- a/micropython/common.py Sat Jun 12 23:09:30 2010 +0200
4.2 +++ b/micropython/common.py Sun Jun 13 02:24:35 2010 +0200
4.3 @@ -38,7 +38,13 @@
4.4 except NodeProcessingError, exc:
4.5 if exc.astnode is None:
4.6 exc.astnode = node
4.7 - exc.unit_name = self.full_name()
4.8 +
4.9 + # NOTE: Should perhaps specialise the subclasses appropriately.
4.10 +
4.11 + if hasattr(self, "unit"):
4.12 + exc.unit_name = self.unit.full_name()
4.13 + else:
4.14 + exc.unit_name = self.full_name()
4.15 raise
4.16
4.17 # Errors.
5.1 --- a/micropython/inspect.py Sat Jun 12 23:09:30 2010 +0200
5.2 +++ b/micropython/inspect.py Sun Jun 13 02:24:35 2010 +0200
5.3 @@ -273,7 +273,7 @@
5.4 # Store in the module.
5.5
5.6 if not self.namespaces:
5.7 - if self.used_in_scope(name, "builtins"):
5.8 + if self.in_loop and self.used_in_scope(name, "builtins"):
5.9 raise InspectError("Name %r already used as a built-in." % name)
5.10 else:
5.11 self.set(name, obj, not self.in_loop)
5.12 @@ -283,9 +283,9 @@
5.13 else:
5.14 locals = self.namespaces[-1]
5.15
5.16 - if locals.used_in_scope(name, "global") and not name in locals.globals:
5.17 + if self.in_loop and locals.used_in_scope(name, "global") and not name in locals.globals:
5.18 raise InspectError("Name %r already used as global." % name)
5.19 - elif locals.used_in_scope(name, "builtins"):
5.20 + elif self.in_loop and locals.used_in_scope(name, "builtins"):
5.21 raise InspectError("Name %r already used as a built-in." % name)
5.22 else:
5.23 locals.set(name, obj, not self.in_loop)
5.24 @@ -939,6 +939,7 @@
5.25
5.26 if self.importer.predefined_constants.has_key(name):
5.27 attr = self.importer.get_predefined_constant(name)
5.28 + node._scope = "constant"
5.29
5.30 # Locals.
5.31
5.32 @@ -948,6 +949,7 @@
5.33 # Note usage of the local (potentially a class attribute).
5.34
5.35 self.use_specific_attribute(None, name)
5.36 + node._scope = "local"
5.37
5.38 # Globals.
5.39
5.40 @@ -957,27 +959,26 @@
5.41 # Note usage of the module attribute.
5.42
5.43 self.use_specific_attribute(self.full_name(), name)
5.44 + node._scope = "global"
5.45
5.46 # Note global usage in any local namespace.
5.47
5.48 if self.namespaces:
5.49 - if not self.namespaces[-1].note_scope(name, "global"):
5.50 - raise InspectError("Name %r cannot be used as global." % name)
5.51 + self.namespaces[-1].note_scope(name, "global")
5.52
5.53 # Builtins.
5.54
5.55 elif self.builtins is not None and self.builtins.has_key(name):
5.56 attr = self.builtins[name]
5.57 self.use_specific_attribute(self.builtins.full_name(), name)
5.58 + node._scope = "builtins"
5.59
5.60 # Note builtins usage in any local namespace.
5.61
5.62 if self.namespaces:
5.63 - if not self.namespaces[-1].note_scope(name, "builtins"):
5.64 - raise InspectError("Name %r cannot be used as a built-in." % name)
5.65 + self.namespaces[-1].note_scope(name, "builtins")
5.66 else:
5.67 - if not self.note_scope(name, "builtins"):
5.68 - raise InspectError("Name %r cannot be used as a built-in." % name)
5.69 + self.note_scope(name, "builtins")
5.70
5.71 # Unknown.
5.72
5.73 @@ -1005,7 +1006,10 @@
5.74
5.75 visitRightShift = _visitBinary
5.76
5.77 - visitSlice = OP
5.78 + def visitSlice(self, node):
5.79 + self.use_name("slice", node)
5.80 + self.use_name("__getitem__", node)
5.81 + self.OP(node)
5.82
5.83 visitSliceobj = OP
5.84
6.1 --- a/micropython/trans.py Sat Jun 12 23:09:30 2010 +0200
6.2 +++ b/micropython/trans.py Sun Jun 13 02:24:35 2010 +0200
6.3 @@ -1160,7 +1160,7 @@
6.4
6.5 # Get the expected scope of the name.
6.6
6.7 - scope = self.get_scope(name)
6.8 + scope = getattr(node, "_scope", None) or self.get_scope(name)
6.9
6.10 #print self.module.name, node.lineno, name, predicted_scope
6.11 self._generateName(name, scope, classes, node)
7.1 --- a/tests/failure/shadow_class_global.py Sat Jun 12 23:09:30 2010 +0200
7.2 +++ b/tests/failure/shadow_class_global.py Sun Jun 13 02:24:35 2010 +0200
7.3 @@ -4,7 +4,8 @@
7.4 return x
7.5
7.6 class C:
7.7 - e = e
7.8 + for x in range(0, 10):
7.9 + e = e # right hand side name changes origin
7.10
7.11 c = C()
7.12
8.1 --- a/tests/failure/shadow_class_global_reassign.py Sat Jun 12 23:09:30 2010 +0200
8.2 +++ b/tests/failure/shadow_class_global_reassign.py Sun Jun 13 02:24:35 2010 +0200
8.3 @@ -4,12 +4,17 @@
8.4 return x
8.5
8.6 class C:
8.7 - e = f
8.8 + i = 2
8.9 +
8.10 + while i > 0:
8.11 + e = f # right hand side name changes origin
8.12
8.13 - def f(self, x):
8.14 - return x
8.15 + def f(self, x):
8.16 + return 3
8.17 +
8.18 + i -= 1
8.19
8.20 c = C()
8.21 -c.f(1)
8.22 +result_3 = c.f(1)
8.23
8.24 # vim: tabstop=4 expandtab shiftwidth=4
9.1 --- a/tests/failure/shadow_globals_builtins.py Sat Jun 12 23:09:30 2010 +0200
9.2 +++ b/tests/failure/shadow_globals_builtins.py Sun Jun 13 02:24:35 2010 +0200
9.3 @@ -1,10 +1,14 @@
9.4 #!/usr/bin/env python
9.5
9.6 -c = max(4, 5)
9.7 +i = 2
9.8 +while i > 0:
9.9 + c = len([3, 4, 5]) # right hand side name changes origin
9.10
9.11 -def max(a, b):
9.12 - return a
9.13 + def len(a):
9.14 + return a
9.15
9.16 -result_2 = max(2, 3)
9.17 + i -= 1
9.18 +
9.19 +result_2 = len(2)
9.20
9.21 # vim: tabstop=4 expandtab shiftwidth=4
10.1 --- a/tests/failure/shadow_locals_globals.py Sat Jun 12 23:09:30 2010 +0200
10.2 +++ b/tests/failure/shadow_locals_globals.py Sun Jun 13 02:24:35 2010 +0200
10.3 @@ -3,8 +3,11 @@
10.4 a = 1
10.5
10.6 def before():
10.7 - b = a
10.8 - a = 2
10.9 + i = 2
10.10 + while i > 0:
10.11 + b = a # right hand side name changes origin
10.12 + a = 2
10.13 + i -= 1
10.14 return b
10.15
10.16 result1_1 = before()
11.1 --- a/tests/failure/shadow_locals_globals_reassign.py Sat Jun 12 23:09:30 2010 +0200
11.2 +++ b/tests/failure/shadow_locals_globals_reassign.py Sun Jun 13 02:24:35 2010 +0200
11.3 @@ -2,16 +2,13 @@
11.4
11.5 a = 1
11.6
11.7 -def before():
11.8 - b = a
11.9 - a = 2
11.10 - return b
11.11 -
11.12 def reassign():
11.13 - a = a
11.14 + i = 2
11.15 + while i > 0:
11.16 + a = a # right hand side name changes origin
11.17 + i -= 1
11.18 return a
11.19
11.20 -result1_1 = before()
11.21 result2_1 = reassign()
11.22
11.23 # vim: tabstop=4 expandtab shiftwidth=4
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/tests/shadow_class_global_reassign.py Sun Jun 13 02:24:35 2010 +0200
12.3 @@ -0,0 +1,15 @@
12.4 +#!/usr/bin/env python
12.5 +
12.6 +def f(self, x):
12.7 + return x
12.8 +
12.9 +class C:
12.10 + e = f
12.11 +
12.12 + def f(self, x):
12.13 + return 3
12.14 +
12.15 +c = C()
12.16 +result_3 = c.f(1)
12.17 +
12.18 +# vim: tabstop=4 expandtab shiftwidth=4
13.1 --- a/tests/shadow_globals_builtins.py Sat Jun 12 23:09:30 2010 +0200
13.2 +++ b/tests/shadow_globals_builtins.py Sun Jun 13 02:24:35 2010 +0200
13.3 @@ -1,8 +1,10 @@
13.4 #!/usr/bin/env python
13.5
13.6 -def max(a, b):
13.7 +c = len([3, 4, 5])
13.8 +
13.9 +def len(a):
13.10 return a
13.11
13.12 -result_2 = max(2, 3)
13.13 +result_2 = len(2)
13.14
13.15 # vim: tabstop=4 expandtab shiftwidth=4
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/tests/shadow_locals_globals_unbound_local.py Sun Jun 13 02:24:35 2010 +0200
15.3 @@ -0,0 +1,12 @@
15.4 +#!/usr/bin/env python
15.5 +
15.6 +a = 1
15.7 +
15.8 +def before():
15.9 + b = a
15.10 + a = 2
15.11 + return b
15.12 +
15.13 +result1_1 = before()
15.14 +
15.15 +# vim: tabstop=4 expandtab shiftwidth=4