1.1 --- a/micropython/common.py Mon Nov 25 15:03:12 2013 +0100
1.2 +++ b/micropython/common.py Thu Nov 28 15:49:39 2013 +0100
1.3 @@ -47,11 +47,14 @@
1.4 definitions = []
1.5 for n in node.getChildNodes():
1.6 if isinstance(n, (compiler.ast.Class, compiler.ast.Function)):
1.7 + self.current_definition = n
1.8 definitions.append(self.dispatch(n))
1.9 - else:
1.10 - definitions += self.process_definitions(n)
1.11 + definitions += self.process_definitions(n)
1.12 return definitions
1.13
1.14 + def processing_definition(self, n):
1.15 + return self.current_definition is n
1.16 +
1.17 # Visitor support methods.
1.18
1.19 def default(self, node, *args):
2.1 --- a/micropython/report.py Mon Nov 25 15:03:12 2013 +0100
2.2 +++ b/micropython/report.py Thu Nov 28 15:49:39 2013 +0100
2.3 @@ -1493,6 +1493,14 @@
2.4 if not first:
2.5 self.stream.write(", ")
2.6
2.7 + # NOTE: The special context argument should not be reproduced.
2.8 + # NOTE: For "dynamic" functions, the context is used to access
2.9 + # NOTE: things like defaults, but could be extended for closures to
2.10 + # NOTE: refer to many namespaces.
2.11 +
2.12 + elif param == "<context>":
2.13 + continue
2.14 +
2.15 # Handle tuple parameters.
2.16
2.17 if isinstance(param, tuple):
3.1 --- a/micropython/syspython.py Mon Nov 25 15:03:12 2013 +0100
3.2 +++ b/micropython/syspython.py Thu Nov 28 15:49:39 2013 +0100
3.3 @@ -70,7 +70,7 @@
3.4 self.module = module
3.5 self.program = program
3.6 self.objtable = program.get_object_table()
3.7 - self.in_main = False
3.8 + self.current_definition = None
3.9 self.units = []
3.10
3.11 def get_unit(self):
3.12 @@ -86,6 +86,18 @@
3.13 module = self.dispatch(self.module.astnode)
3.14 stream.write(str(module))
3.15
3.16 + def get_original_arguments(self, argnames):
3.17 +
3.18 + # NOTE: The special context argument should not be reproduced.
3.19 + # NOTE: For "dynamic" functions, the context is used to access
3.20 + # NOTE: things like defaults, but could be extended for closures to
3.21 + # NOTE: refer to many namespaces.
3.22 +
3.23 + if argnames and argnames[0] == "<context>":
3.24 + return argnames[1:]
3.25 + else:
3.26 + return argnames
3.27 +
3.28 def NOP(self, node):
3.29 return node
3.30
3.31 @@ -94,6 +106,7 @@
3.32 self.units.append(module)
3.33
3.34 definitions = self.process_definitions(node)
3.35 + self.current_definition = None
3.36
3.37 # keywords(name, ...)
3.38
3.39 @@ -116,14 +129,11 @@
3.40 # def __main__():
3.41 # ...
3.42
3.43 - self.in_main = True
3.44 -
3.45 main = compiler.ast.Function(
3.46 [], "__main__", [], [], 0, "Module initialisation.",
3.47 compiler.ast.Stmt(globalnames + self.dispatch(node.node).nodes)
3.48 )
3.49
3.50 - self.in_main = False
3.51 self.units.pop()
3.52
3.53 return compiler.ast.Module(node.doc, compiler.ast.Stmt(keywords + definitions + [main]))
3.54 @@ -163,7 +173,7 @@
3.55 try:
3.56 # Incorporate class body code in the main function.
3.57
3.58 - if self.in_main:
3.59 + if not self.processing_definition(node):
3.60 return self.dispatch(node.code)
3.61 else:
3.62 return self._visitClassDefinition(node)
3.63 @@ -332,7 +342,10 @@
3.64 self.units.append(node.unit)
3.65
3.66 try:
3.67 - if self.in_main:
3.68 + # NOTE: Need to initialise any defaults outside a definition and to
3.69 + # NOTE: transfer defaults to locals inside a definition.
3.70 +
3.71 + if not self.processing_definition(node):
3.72
3.73 # Generate rebindings of functions.
3.74
3.75 @@ -375,8 +388,9 @@
3.76 # NOTE: Should generate guards for attribute usage operations.
3.77
3.78 code = self.dispatch(node.code)
3.79 + argnames = self.get_original_arguments(node.argnames)
3.80
3.81 - return compiler.ast.Function(node.decorators, node.name, node.argnames, defaults, node.flags, node.doc,
3.82 + return compiler.ast.Function(node.decorators, node.name, argnames, defaults, node.flags, node.doc,
3.83 compiler.ast.Stmt(localnames + globalnames + code.nodes))
3.84
3.85 visitGlobal = NOP
3.86 @@ -892,9 +906,13 @@
3.87 def visitLambda(self, node):
3.88 self.units.append(node.unit)
3.89
3.90 + # NOTE: Need to initialise any defaults.
3.91 +
3.92 try:
3.93 + argnames = self.get_original_arguments(node.argnames)
3.94 +
3.95 return compiler.ast.Lambda(
3.96 - node.argnames,
3.97 + argnames,
3.98 [self.dispatch(n) for n in node.defaults],
3.99 node.flags,
3.100 self.dispatch(node.code)
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/tests/call_func_default_nested.py Thu Nov 28 15:49:39 2013 +0100
4.3 @@ -0,0 +1,11 @@
4.4 +#!/usr/bin/env python
4.5 +
4.6 +def outer(x):
4.7 + def inner(y, z=x):
4.8 + return y + z
4.9 + return inner
4.10 +
4.11 +result_3 = outer(1)(2)
4.12 +result_4 = outer(2)(2)
4.13 +
4.14 +# vim: tabstop=4 expandtab shiftwidth=4