# HG changeset patch # User Paul Boddie # Date 1217027762 -7200 # Node ID 1f407246b42c616b39828b9f1d29491efad50130 # Parent f21cc9738695b41871fbd6960ac0954b816b6837 Added some support for lambda. Fixed the importer tests. Improved the lambda test. diff -r f21cc9738695 -r 1f407246b42c micropython/ast.py --- a/micropython/ast.py Mon Jul 21 00:42:54 2008 +0200 +++ b/micropython/ast.py Sat Jul 26 01:16:02 2008 +0200 @@ -1087,6 +1087,18 @@ self.discard_temp(temp1) self.discard_temp(temp2) + def _generateFunctionDefaults(self, function): + + "Generate the default initialisation code for 'function'." + + for attr, default in zip(function.default_attrs, function.defaults): + self.dispatch(default) + + self.record_value() + self.new_op(StoreAddress(attr)) + self.set_source() + self.discard_value() + # Concrete visitor methods. def visitAdd(self, node): @@ -1297,19 +1309,11 @@ self.new_op(LoadConst(node.unit)) self.record_value() - self._visitName(node, self.name_store_instructions) + self._visitName(node, self.name_store_instructions) # AssName equivalent self.set_source() self.discard_value() - # Generate the default initialisation code. - - for attr, default in zip(node.unit.default_attrs, node.unit.defaults): - self.dispatch(default) - - self.record_value() - self.new_op(StoreAddress(attr)) - self.set_source() - self.discard_value() + self._generateFunctionDefaults(node.unit) # Visiting of the code occurs when get_code is invoked on this node. @@ -1338,7 +1342,11 @@ first = 1 exit_label = self.new_label() - for test, body in node.tests + [(None, node.else_)]: + clauses = node.tests + [(None, node.else_)] + last_clause = clauses[-1] + + for clause in clauses: + test, body = clause if body is None: break if not first: @@ -1348,7 +1356,8 @@ next_label = self.new_label() self.new_op(JumpIfFalse(next_label)) self.dispatch(body) - self.new_op(Jump(exit_label)) + if clause is not last_clause: + self.new_op(Jump(exit_label)) first = 0 self.set_label(exit_label) @@ -1360,7 +1369,21 @@ def visitKeyword(self, node): pass - def visitLambda(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Lambda") + def visitLambda(self, node): + + # Produce the reference to this function when visiting this node from + # outside. + + if self.unit is not node.unit: + self._generateFunctionDefaults(node.unit) + self.new_op(LoadConst(node.unit)) + + # Visiting of the code occurs when get_code is invoked on this node. + + else: + self.dispatch(node.code) + self.new_op(StoreResult()) + self.new_op(Return()) def visitLeftShift(self, node): self._visitBinary(node, "__lshift__", "__rlshift__") diff -r f21cc9738695 -r 1f407246b42c tests/failure/importer.py --- a/tests/failure/importer.py Mon Jul 21 00:42:54 2008 +0200 +++ b/tests/failure/importer.py Sat Jul 26 01:16:02 2008 +0200 @@ -10,6 +10,10 @@ imported.x = 1 # detected with warning (despite no collision) +class C: # hack: make an attribute called y known to the system + y = None # hack: this prevents compilation errors with the statements + # hack: below + n = None n = imported n.y = 2 # not detected due to reassignment of n diff -r f21cc9738695 -r 1f407246b42c tests/importer.py --- a/tests/importer.py Mon Jul 21 00:42:54 2008 +0200 +++ b/tests/importer.py Sat Jul 26 01:16:02 2008 +0200 @@ -2,13 +2,11 @@ import imported -imported.attr = 456 # detected with warning +imported.attr # cannot assign to this m = imported -imported.a = 9 # detected with warning -m.a = 8 # detected with warning (m is always imported) - -imported.x = 1 # detected with warning (despite no collision) +imported.a # cannot assign to this +m.a # cannot assign to this (m is known) class C: # hack: make an attribute called y known to the system y = None # hack: this prevents compilation errors with the statements @@ -16,6 +14,7 @@ n = None n = imported +n.a = 1 # not detected due to reassignment of n n.y = 2 # not detected due to reassignment of n n.y = 3 # not detected due to reassignment of n diff -r f21cc9738695 -r 1f407246b42c tests/lambda.py --- a/tests/lambda.py Mon Jul 21 00:42:54 2008 +0200 +++ b/tests/lambda.py Sat Jul 26 01:16:02 2008 +0200 @@ -1,6 +1,18 @@ #!/usr/bin/env python identity = lambda x: x -lambda a, b=2: a + b + +def f(): + return lambda a, b=2: a + b + +def f2(c): + return lambda a, b=c: a + b + +def g(f, x): + return f(x) + +g(identity, 1) +g(f(), 1) +g(f2(3), 1) # vim: tabstop=4 expandtab shiftwidth=4