# HG changeset patch # User Paul Boddie # Date 1242001032 -7200 # Node ID 3063e2b7ff639b58aad1c2f8ad5de6fc3e7214fe # Parent 9cb85e5768fac0baf36a8f5e9430de4d38bffd9d Started to add support for star parameters. diff -r 9cb85e5768fa -r 3063e2b7ff63 docs/concepts.txt --- a/docs/concepts.txt Sat May 09 03:21:15 2009 +0200 +++ b/docs/concepts.txt Mon May 11 02:17:12 2009 +0200 @@ -196,8 +196,9 @@ 0 1 2 3 4 5 6 7 8 classcode attrcode/ invocation invocation funccode size __class__ attribute ... instance reference #args, reference reference - status defaults - reference + status defaults, + * parameter + details Classcode --------- @@ -220,6 +221,24 @@ removed and the attrcode is not specified for classes: the presence of an attrcode indicates that a given object is an instance. +Invocation Reference +-------------------- + +Used when an object is called. + +This is the address of the code to be executed when an invocation is performed +on the object. + +Invocation Arguments +-------------------- + +Used when an object is called. + +The argument details consist of the number of positional arguments involved in +an invocation, the number of defaults available to compensate for missing +arguments, and whether a star (*) parameter is available to accept superfluous +arguments. + Attributes ---------- @@ -236,24 +255,27 @@ 0 1 2 3 4 5 6 7 8 classcode (unused) __new__ __new__ funccode size class type attribute ... for C reference #args, for reference reference - defaults instantiator - reference + defaults, instantiator + * parameter + details Instance of C: 0 1 2 3 4 5 6 7 8 classcode attrcode C.__call__ C.__call__ funccode size class C attribute ... for C for C reference #args, for reference reference - (if exists) defaults C.__call__ - reference + (if exists) defaults, C.__call__ + * parameter + details Function f: 0 1 2 3 4 5 6 7 8 classcode attrcode code code funccode size class attribute ... for for reference #args, function (default) - function function defaults reference reference - reference + function function defaults, reference reference + * parameter + details Module m: diff -r 9cb85e5768fa -r 3063e2b7ff63 docs/invocation.txt --- a/docs/invocation.txt Sat May 09 03:21:15 2009 +0200 +++ b/docs/invocation.txt Mon May 11 02:17:12 2009 +0200 @@ -17,7 +17,7 @@ f(1, 2, 3) # positional, f is appropriate function pointer # ie. (*f)(A, B, C) -Least expensive cases: +Least expensive cases (positional plus defaults): f(1, 2, 3) # put arguments in frame # if f is not known, add arguments vs. parameters check @@ -25,7 +25,7 @@ # not enough arguments are given # if f is not known, this is obviously done at run-time -More expensive cases: +More expensive cases (keywords plus defaults): f(1, 2, c=3) # prepare frame using parameter details # (provided c is a known parameter) @@ -37,9 +37,15 @@ # assigned (since their positions and thus the positions # of missing parameters cannot be known) -Awkward cases: +Awkward cases (extra arguments): - f(1, 2, 3, 4) # extra positional arguments + f(1, 2, 3, 4) # put arguments in frame + # if f is not known, add arguments vs. parameters check + # target unpacks superfluous arguments from the end of the + # frame + +Very awkward cases: + f(1, 2, 3, d=4) # extra keyword arguments f(1, 2, *args) # positional bundles (possibly with defaults) f(1, 2, **kw) # keyword bundles (possibly with defaults) diff -r 9cb85e5768fa -r 3063e2b7ff63 lib/builtins.py --- a/lib/builtins.py Sat May 09 03:21:15 2009 +0200 +++ b/lib/builtins.py Mon May 11 02:17:12 2009 +0200 @@ -295,7 +295,7 @@ def globals(): pass def hasattr(obj, name): pass def hash(obj): pass -def help(*args, **kw): pass +def help(*args): pass def hex(number): pass def id(obj): pass def input(prompt=None): pass @@ -305,8 +305,8 @@ def len(obj): pass def locals(): pass def map(function, *args): pass -def max(*args, **kw): pass -def min(*args, **kw): pass +def max(*args): pass +def min(*args): pass def oct(number): pass def open(name, mode=None, buffering=None): pass def ord(c): pass diff -r 9cb85e5768fa -r 3063e2b7ff63 micropython/ast.py --- a/micropython/ast.py Sat May 09 03:21:15 2009 +0200 +++ b/micropython/ast.py Mon May 11 02:17:12 2009 +0200 @@ -596,6 +596,11 @@ extend = ExtendFrame() self.new_op(extend) + # Handle * parameters. + # NOTE: Not handling ** parameters yet. + + # Make a tuple from the arguments corresponding to the * parameter. + self.dispatch(node.code) if not isinstance(self.last_op(), Return): self.dispatch(compiler.ast.Name("None")) diff -r 9cb85e5768fa -r 3063e2b7ff63 micropython/data.py --- a/micropython/data.py Sat May 09 03:21:15 2009 +0200 +++ b/micropython/data.py Mon May 11 02:17:12 2009 +0200 @@ -581,6 +581,7 @@ ( call_method_value and len(call_method_value.positional_names), call_method_value and len(call_method_value.defaults) + # NOTE: Add * parameter availability. ), self.full_name(), len(self.instance_attributes()) + 1, # size @@ -596,6 +597,7 @@ ( len(self.get_instantiator().positional_names), len(self.get_instantiator().defaults) + # NOTE: Add * parameter availability. ), self.full_name(), len(self.class_attributes()) + 1, # size @@ -976,6 +978,7 @@ ( len(self.positional_names), len(self.defaults) + # NOTE: Add * parameter availability. ), "__builtins__.function", len(self.defaults) + 1, # size diff -r 9cb85e5768fa -r 3063e2b7ff63 micropython/trans.py --- a/micropython/trans.py Sat May 09 03:21:15 2009 +0200 +++ b/micropython/trans.py Mon May 11 02:17:12 2009 +0200 @@ -701,6 +701,8 @@ ndefaults = len(target.defaults) nargs_min = nargs_max - ndefaults + # Visit each argument position and look for a supplied argument. + for i in range(ncontext, nargs_min): if i not in employed_positions: raise TranslateError(self.module.full_name(), node, @@ -708,17 +710,32 @@ nargs = frame_pos - if nargs > nargs_max and not target.has_star and not target.has_dstar: + # Determine whether too many arguments have been given and how big + # the frame should be. + + # For parameter lists with * or ** parameters, accept as many + # arguments as are allowed or as many as we have. + + if target.has_star or target.has_dstar: + frame_size = max(nargs, nargs_max) + + # For other parameter lists, only accept as many arguments as we are + # allowed. + + elif nargs > nargs_max: raise TranslateError(self.module.full_name(), node, "Too many arguments for %r: need at most %d argument(s)." % (target.name, nargs_max)) + else: + frame_size = nargs_max + # Where defaults are involved, put them into the frame. self._generateCallFuncDefaultArgs(target, temp, nargs_min, nargs_max, employed_positions) # Set the frame size. - self._endCallFuncArgs(nargs_max) + self._endCallFuncArgs(frame_size) # Or generate instructions to do this at run-time. diff -r 9cb85e5768fa -r 3063e2b7ff63 tests/call_func_star_parameter.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/call_func_star_parameter.py Mon May 11 02:17:12 2009 +0200 @@ -0,0 +1,8 @@ +#!/usr/bin/env python + +def f(*args): + return args + +x = f(1, 2, 3) + +# vim: tabstop=4 expandtab shiftwidth=4