# HG changeset patch # User Paul Boddie # Date 1217197589 -7200 # Node ID b198f939f7bb314c5d816fcd49e6ca1175afc010 # Parent 88ffc0d1c657a52c42a4aee4be5efd5d69ff620a Added notes about handling default parameter values at run-time. Added a details field to the structure layouts. Fixed the temporary storage optimisation to ensure that references to existing temporary storage locations are preserved correctly. Added some support for tuples. Improved the instance test, adding a failing version. diff -r 88ffc0d1c657 -r b198f939f7bb docs/invocation.txt --- a/docs/invocation.txt Sun Jul 27 02:00:31 2008 +0200 +++ b/docs/invocation.txt Mon Jul 28 00:26:29 2008 +0200 @@ -116,6 +116,17 @@ is instance: no change +Defaults for unknown callables: + + f(obj) # f not known at compile-time + + f -> f + -> load context for argument #1 + obj -> argument #2 + + Then, check the number of arguments and the availability of defaults against + the details provided by the callable's structure. + Functions as methods: def f(x, y, z): ... diff -r 88ffc0d1c657 -r b198f939f7bb docs/structures.txt --- a/docs/structures.txt Sun Jul 27 02:00:31 2008 +0200 +++ b/docs/structures.txt Mon Jul 28 00:26:29 2008 +0200 @@ -107,11 +107,12 @@ A suitable structure layout might be something like this: - Identifier Address Type Object ... + Identifier Address Details Type Object ... - 0 1 2 3 4 - classcode invocation __class__ attribute ... - reference reference reference + 0 1 2 3 4 5 + classcode invocation invocation __class__ attribute ... + reference #args, reference reference + #defaults Here, the classcode refers to the attribute lookup table for the object. Since classes and instances share the same classcode, they might resemble the @@ -119,16 +120,17 @@ Class C: - 0 1 2 3 4 - code for C __new__ class type attribute ... - reference reference reference + 0 1 2 3 4 5 + code for C __new__ __new__ class type attribute ... + reference #args, reference reference + #defaults Instance of C: - 0 1 2 3 4 - code for C C.__call__ class C attribute ... - reference reference reference - (if exists) + 0 1 2 3 4 5 + code for C C.__call__ C.__call__ class C attribute ... + reference #args, reference reference + (if exists) #defaults The __new__ reference would lead to code consisting of the following instructions: @@ -144,10 +146,10 @@ Function f: - 0 1 2 3 4 - code for code class attribute ... - function reference function reference - reference + 0 1 2 3 4 5 + code for code code class attribute ... + function reference #args, function reference + #defaults reference Here, the code reference would lead to code for the function. Note that the function locals are completely distinct from this structure and are not @@ -158,10 +160,10 @@ Module m: - 0 1 2 3 4 - code for m (unused) module type attribute ... - reference (global) - reference + 0 1 2 3 4 5 + code for m (unused) (unused) module type attribute ... + reference (global) + reference Both classes and modules have code in their definitions, but this would be generated in order and not referenced externally. diff -r 88ffc0d1c657 -r b198f939f7bb micropython/ast.py --- a/micropython/ast.py Sun Jul 27 02:00:31 2008 +0200 +++ b/micropython/ast.py Mon Jul 28 00:26:29 2008 +0200 @@ -220,6 +220,10 @@ self.new_op(StoreTemp(temp_position)) return LoadTemp(temp_position) + def ensure_temp(self): + if isinstance(self.active, LoadTemp): + self.temp_position = max(self.temp_position, self.active.attr + 1) + def reserve_temp(self, n): temp_position = self.temp_position self.temp_position += n @@ -475,6 +479,11 @@ if self._should_optimise_temp_storage() and \ self._have_temp_compatible_access(): + # Where an existing temporary storage reference will be retained, + # keep it active. + + self.ensure_temp() + last = self.last_op() self.remove_op() return last @@ -811,13 +820,13 @@ for i in range(ncontext, nargs_min): if i not in employed_positions: raise TranslateError(self.module.full_name(), node, - "Argument %r not supplied for %r: need at least %d arguments." % (i+1, target.name, nargs_min)) + "Argument %r not supplied for %r: need at least %d argument(s)." % (i+1, target.name, nargs_min)) nargs = len(args) if nargs > nargs_max and not target.has_star and not target.has_dstar: raise TranslateError(self.module.full_name(), node, - "Too many arguments for %r: need at most %d arguments." % (target.name, nargs_max)) + "Too many arguments for %r: need at most %d argument(s)." % (target.name, nargs_max)) # Where defaults are involved, put them into the frame. @@ -1613,7 +1622,20 @@ def visitTryFinally(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "TryFinally") - def visitTuple(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Tuple") + def visitTuple(self, node): + self.new_op(MakeObject(len(node.nodes))) + temp = self.get_temp() + + for i, n in enumerate(node.nodes): + self.dispatch(n) + self.record_value() + self.new_op(temp) + self.new_op(StoreAttr(Attr(i, None, None, None))) + self.set_source() + self.discard_value() + + self.new_op(temp) + self.discard_temp(temp) def visitUnaryAdd(self, node): self._visitUnary(node, "__pos__") diff -r 88ffc0d1c657 -r b198f939f7bb tests/failure/instance.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/failure/instance.py Mon Jul 28 00:26:29 2008 +0200 @@ -0,0 +1,18 @@ +#!/usr/bin/env python + +class C: + pass + +class D: + def __init__(self): + pass + +class E: + def __init__(self, x): + pass + +c = C() +d = D() +e = E() + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 88ffc0d1c657 -r b198f939f7bb tests/instance.py --- a/tests/instance.py Sun Jul 27 02:00:31 2008 +0200 +++ b/tests/instance.py Mon Jul 28 00:26:29 2008 +0200 @@ -7,7 +7,12 @@ def __init__(self): pass +class E: + def __init__(self, x): + pass + c = C() d = D() +e = E(1) # vim: tabstop=4 expandtab shiftwidth=4 diff -r 88ffc0d1c657 -r b198f939f7bb tests/tuple.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/tuple.py Mon Jul 28 00:26:29 2008 +0200 @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +1, 2, 3 +a = (1, 2, 3) +1, (2, 3), 4, 5 + +# vim: tabstop=4 expandtab shiftwidth=4