1.1 --- a/docs/invocation.txt Mon Jul 13 01:02:42 2009 +0200
1.2 +++ b/docs/invocation.txt Tue Jul 14 00:37:04 2009 +0200
1.3 @@ -209,7 +209,29 @@
1.4 One motivation: avoid explicitly making sequences.
1.5 Opportunity: avoid expensive dynamic allocation of sequences?
1.6
1.7 -Star parameters, known callables and sequences:
1.8 +Star parameters, approach #1:
1.9 +
1.10 + Make a sequence to hold the extra arguments, either in the caller for known
1.11 + callables or in the function itself.
1.12 +
1.13 + Such a sequence would need allocating and its contents copying from the
1.14 + stack.
1.15 +
1.16 +Star parameters, approach #2:
1.17 +
1.18 + Keep the extra arguments in the stack.
1.19 +
1.20 + Access to the star parameter would need to consider assignment to other
1.21 + things and "escape situations" for the parameter:
1.22 +
1.23 + def f(*args):
1.24 + return args # need to allocate and return the sequence
1.25 +
1.26 + Access to elements of the extra argument sequence would behave slightly
1.27 + differently to normal sequences, but this could be identified at
1.28 + compile-time.
1.29 +
1.30 +Star parameters, known callables and sequences, approach #1:
1.31
1.32 g(1, 2, 3, 4) # g known as function g(a, *args) at compile-time
1.33
1.34 @@ -217,10 +239,17 @@
1.35 1 -> argument #1
1.36 2 -> reference to sequence containing arguments #2, #3, #4
1.37
1.38 - (This according to approach #1 described for unknown callables. With approach
1.39 - #2, normal argument positioning would occur.)
1.40 +Star parameters, known callables and sequences, approach #2:
1.41 +
1.42 + g(1, 2, 3, 4) # g known as function g(a, *args) at compile-time
1.43
1.44 -Star parameters, unknown callables:
1.45 + g -> don't get any context information
1.46 + 1 -> argument #1
1.47 + 2 -> argument #2
1.48 + 3 -> argument #3
1.49 + 4 -> argument #4
1.50 +
1.51 +Star parameters, unknown callables, both approach #1 and #2:
1.52
1.53 g(1, 2, 3, 4) # g not known at compile-time
1.54
2.1 --- a/micropython/ast.py Mon Jul 13 01:02:42 2009 +0200
2.2 +++ b/micropython/ast.py Tue Jul 14 00:37:04 2009 +0200
2.3 @@ -421,9 +421,15 @@
2.4 def visitListCompIf(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "ListCompIf")
2.5
2.6 def visitName(self, node):
2.7 +
2.8 + # Handle names referring to constants.
2.9 +
2.10 if self.importer.predefined_constants.has_key(node.name):
2.11 const = self.importer.get_predefined_constant(node.name)
2.12 self.new_op(LoadConst(const))
2.13 +
2.14 + # Handle all other names.
2.15 +
2.16 else:
2.17 self._visitName(node, self.name_load_instructions)
2.18
2.19 @@ -606,6 +612,13 @@
2.20
2.21 self.set_block(fn.body_block)
2.22
2.23 + # For functions with star parameters, make a special list for the
2.24 + # extra arguments and re-map the parameter.
2.25 +
2.26 + if fn.has_star:
2.27 + self.new_op(CopyExtra(nparams))
2.28 + self.new_op(StoreName(nparams - 1))
2.29 +
2.30 extend = ExtendFrame()
2.31 self.new_op(extend)
2.32
3.1 --- a/micropython/rsvp.py Mon Jul 13 01:02:42 2009 +0200
3.2 +++ b/micropython/rsvp.py Tue Jul 14 00:37:04 2009 +0200
3.3 @@ -212,6 +212,7 @@
3.4 class CheckFrame(Immediate): "Check the frame for the correct number of arguments."
3.5 class FillDefaults(Immediate): "Fill frame positions with defaults, if appropriate."
3.6 class ExtendFrame(Immediate): "Extend the current frame for temporary storage use."
3.7 +class CopyExtra(Immediate): "Copy extra arguments into a separate sequence, starting from the given position."
3.8
3.9 # Invocation-related instructions, using a special result "register".
3.10
3.11 @@ -251,7 +252,8 @@
3.12 LoadAddress, LoadAddressContext, LoadAddressContextCond,
3.13 LoadAttr, LoadAttrIndex, LoadAttrIndexContextCond,
3.14 LoadCallable, LoadContext, LoadResult,
3.15 - LoadException, MakeInstance, MakeFragment
3.16 + LoadException, MakeInstance, MakeFragment,
3.17 + CopyExtra
3.18 )
3.19
3.20 # vim: tabstop=4 expandtab shiftwidth=4
4.1 --- a/rsvp.py Mon Jul 13 01:02:42 2009 +0200
4.2 +++ b/rsvp.py Tue Jul 14 00:37:04 2009 +0200
4.3 @@ -127,6 +127,9 @@
4.4 cls = self._get_class("__builtins__", "TypeError")
4.5 self.type_error = cls.location
4.6 self.type_error_instance = cls.instance_template_location
4.7 + cls = self.machine._get_class("__builtins__", "tuple")
4.8 + self.tuple_class = cls.location
4.9 + self.tuple_instance = cls.instance_template_location
4.10
4.11 # Debugging attributes.
4.12
4.13 @@ -615,6 +618,28 @@
4.14 default += 1
4.15 pos += 1
4.16
4.17 + def CopyExtra(self):
4.18 + start = self.operand
4.19 +
4.20 + # The frame is the source of the extra arguments.
4.21 +
4.22 + frame = self.local_sp_stack[-1]
4.23 + nlocals = len(self.frame_stack[frame:])
4.24 +
4.25 + # Make a tuple to hold the arguments.
4.26 +
4.27 + ref = self._MakeObject(nlocals - start + 1, self.tuple_instance)
4.28 +
4.29 + extra = 0
4.30 + pos = start
4.31 +
4.32 + while pos < nlocals:
4.33 + self.save(ref + extra + 1, self.frame_stack[frame + pos]) # skip header when storing
4.34 + extra += 1
4.35 + pos += 1
4.36 +
4.37 + self.value = ref, ref
4.38 +
4.39 def CheckSelf(self):
4.40 context, ref = self.value
4.41 context_context, context_ref = self.source
4.42 @@ -781,10 +806,10 @@
4.43 cls = self.machine._get_class("__builtins__", "IndexError")
4.44 self.index_error = cls.location
4.45 self.index_error_instance = cls.instance_template_location
4.46 - cls = self.machine._get_class("__builtins__", "tuple")
4.47 - self.tuple_class = cls.location
4.48
4.49 + self.tuple_class = self.machine.tuple_class
4.50 self.type_error_instance = self.machine.type_error_instance
4.51 +
4.52 self.frame_stack = self.machine.frame_stack
4.53 self.local_sp_stack = self.machine.local_sp_stack
4.54