# HG changeset patch # User Paul Boddie # Date 1202691492 -3600 # Node ID ebf7101aa96939d2193fff02972139661327ff8b # Parent 146aca040daeb47b354cb24ab5c4545f0a325260 Fixed missing code location for class top-level code. Added a test of while loops, along with some support for while, break and continue. diff -r 146aca040dae -r ebf7101aa969 micropython/__init__.py --- a/micropython/__init__.py Sun Feb 10 22:05:23 2008 +0100 +++ b/micropython/__init__.py Mon Feb 11 01:58:12 2008 +0100 @@ -137,6 +137,8 @@ pos += len(attributes.keys()) # Class-level code is generated separately. + # The code location is set within the code generation + # process for the module. # NOTE: Generate module and function code here. diff -r 146aca040dae -r ebf7101aa969 micropython/ast.py --- a/micropython/ast.py Sun Feb 10 22:05:23 2008 +0100 +++ b/micropython/ast.py Mon Feb 11 01:58:12 2008 +0100 @@ -66,6 +66,10 @@ self.labels = {} self.label_number = 0 + self.loop_labels = [] + + # The code itself. + self.code = None def get_module_code(self): @@ -197,7 +201,9 @@ def visitBitxor(self, node): pass - def visitBreak(self, node): pass + def visitBreak(self, node): + next_label, exit_label = self.loop_labels[-1] + self.new_op(Jump(exit_label)) def visitCallFunc(self, node): @@ -291,6 +297,7 @@ def visitClass(self, node): unit = self.unit self.unit = node.unit + self.unit.code_location = self.module.code_location + len(self.code) self.dispatch(node.code) self.unit = unit @@ -311,7 +318,9 @@ const = self.module.constant_values[node.value] self.new_op(LoadConst(const)) - def visitContinue(self, node): pass + def visitContinue(self, node): + next_label, exit_label = self.loop_labels[-1] + self.new_op(Jump(next_label)) def visitDecorators(self, node): pass @@ -372,7 +381,7 @@ if test is not None: self.dispatch(test) next_label = self.new_label() - self.new_op(Jump(next_label)) + self.new_op(JumpIfFalse(next_label)) self.dispatch(body) self.new_op(Jump(exit_label)) first = 0 @@ -448,7 +457,23 @@ def visitUnarySub(self, node): pass - def visitWhile(self, node): pass + def visitWhile(self, node): + exit_label = self.new_label() + self.dispatch(node.test) + self.new_op(JumpIfFalse(exit_label)) + + next_label = self.new_label() + self.set_label(next_label) + self.loop_labels.append((next_label, exit_label)) + + self.dispatch(node.body) + self.new_op(Jump(next_label)) + + if node.else_ is not None: + self.dispatch(node.else_) + + self.set_label(exit_label) + self.loop_labels.pop() def visitWith(self, node): pass diff -r 146aca040dae -r ebf7101aa969 micropython/inspect.py --- a/micropython/inspect.py Sun Feb 10 22:05:23 2008 +0100 +++ b/micropython/inspect.py Mon Feb 11 01:58:12 2008 +0100 @@ -677,7 +677,7 @@ def visitClass(self, node): if self.namespaces: - print "Class %r in %r is not global: ignored." % (node.name, self) + print "Class %r in %r is not global: ignored." % (node.name, self.namespaces[-1].full_name()) else: cls = Class(node.name, self.get_parent().full_name(), self, node) diff -r 146aca040dae -r ebf7101aa969 micropython/rsvp.py --- a/micropython/rsvp.py Sun Feb 10 22:05:23 2008 +0100 +++ b/micropython/rsvp.py Mon Feb 11 01:58:12 2008 +0100 @@ -61,6 +61,7 @@ # Invocation-related instructions. class Jump(Instruction): pass +class JumpIfFalse(Instruction): pass class LoadCallable(Instruction): pass class Return(Instruction): pass diff -r 146aca040dae -r ebf7101aa969 tests/loop_while.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/loop_while.py Mon Feb 11 01:58:12 2008 +0100 @@ -0,0 +1,9 @@ +#!/usr/bin/env python + +class C: + value = "hello" + while x > 0: + subvalue = "world" + x -= 1 + +# vim: tabstop=4 expandtab shiftwidth=4