1.1 --- a/README.txt Wed Mar 19 20:57:38 2008 +0100
1.2 +++ b/README.txt Thu Mar 20 01:13:48 2008 +0100
1.3 @@ -269,6 +269,19 @@
1.4 argument, in order to optimise instance attribute access in methods, we should
1.5 seek to restrict the object type.
1.6
1.7 +Verifying Supplied Arguments
1.8 +----------------------------
1.9 +
1.10 +In order to ensure a correct invocation, it is also necessary to check the
1.11 +number of supplied arguments. If the target of the invocation is known at
1.12 +compile-time, no additional instructions need to be emitted; otherwise, the
1.13 +generated code must test for the following situations:
1.14 +
1.15 + 1. That the number of supplied arguments is equal to the number of expected
1.16 + parameters.
1.17 +
1.18 + 2. That no keyword argument overwrites an existing positional parameter.
1.19 +
1.20 Tuples, Frames and Allocation
1.21 -----------------------------
1.22
2.1 --- a/micropython/ast.py Wed Mar 19 20:57:38 2008 +0100
2.2 +++ b/micropython/ast.py Thu Mar 20 01:13:48 2008 +0100
2.3 @@ -262,11 +262,14 @@
2.4 # Evaluate the arguments.
2.5
2.6 positional = 1
2.7 + start_keywords = None
2.8 + employed_keywords = set()
2.9
2.10 for i, arg in enumerate(args):
2.11 if isinstance(arg, compiler.ast.Keyword):
2.12 if positional:
2.13 self.new_op(ReserveFrame(len(args) - i))
2.14 + start_keywords = i
2.15 positional = 0
2.16
2.17 self.dispatch(arg.expr)
2.18 @@ -294,6 +297,17 @@
2.19 raise
2.20
2.21 pos = table_entry[arg.name]
2.22 +
2.23 + # Test for illegal conditions.
2.24 +
2.25 + if pos < start_keywords:
2.26 + raise TranslateError(self.module.full_name(), node,
2.27 + "Keyword argument %r overwrites parameter %r." % (arg.name, pos))
2.28 + elif pos in employed_keywords:
2.29 + raise TranslateError(self.module.full_name(), node,
2.30 + "Keyword argument %r is repeated, overwriting parameter %r." % (arg.name, pos))
2.31 +
2.32 + employed_keywords.add(pos)
2.33 self.new_op(StoreFrame(pos))
2.34
2.35 # Otherwise, generate the code needed to obtain the details of
3.1 --- a/micropython/common.py Wed Mar 19 20:57:38 2008 +0100
3.2 +++ b/micropython/common.py Thu Mar 20 01:13:48 2008 +0100
3.3 @@ -29,7 +29,7 @@
3.4 self.message = message
3.5
3.6 def __repr__(self):
3.7 - return "ProcessingError in %r at line %d: %s" % (self.unit_name, self.node.lineno, self.message)
3.8 + return "Error in %r at line %d: %s" % (self.unit_name, self.node.lineno, self.message)
3.9
3.10 def __str__(self):
3.11 return repr(self)
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/tests/failure/keyword_conflict.py Thu Mar 20 01:13:48 2008 +0100
4.3 @@ -0,0 +1,18 @@
4.4 +#!/usr/bin/env python
4.5 +
4.6 +def f(a, b, c):
4.7 + pass
4.8 +
4.9 +g = f
4.10 +g(1, a=3, b=2) # uncertain target - not detected
4.11 +
4.12 +def g(a, c, b):
4.13 + pass
4.14 +
4.15 +g(1, a=3, b=2)
4.16 +
4.17 +f(1, 2, 3)
4.18 +f(1, a=2, c=3)
4.19 +f(c=3, b=2, a=1)
4.20 +
4.21 +# vim: tabstop=4 expandtab shiftwidth=4
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/tests/failure/keyword_repeat.py Thu Mar 20 01:13:48 2008 +0100
5.3 @@ -0,0 +1,19 @@
5.4 +#!/usr/bin/env python
5.5 +
5.6 +def f(a, b, c):
5.7 + pass
5.8 +
5.9 +g = f
5.10 +g(1, b=3, b=2)
5.11 +g(c=3, b=2, a=1, b=0) # uncertain target - not detected
5.12 +
5.13 +def g(a, c, b):
5.14 + pass
5.15 +
5.16 +g(1, a=3, b=2)
5.17 +
5.18 +f(1, 2, 3)
5.19 +f(1, b=2, c=3)
5.20 +f(c=3, b=2, a=1, b=0)
5.21 +
5.22 +# vim: tabstop=4 expandtab shiftwidth=4