[pypy-svn] r53256 - pypy/branch/js-refactoring/pypy/lang/js

fijal at codespeak.net fijal at codespeak.net
Wed Apr 2 18:39:09 CEST 2008


Author: fijal
Date: Wed Apr  2 18:39:08 2008
New Revision: 53256

Modified:
   pypy/branch/js-refactoring/pypy/lang/js/jscode.py
   pypy/branch/js-refactoring/pypy/lang/js/operations.py
Log:
break and continue


Modified: pypy/branch/js-refactoring/pypy/lang/js/jscode.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/jscode.py	(original)
+++ pypy/branch/js-refactoring/pypy/lang/js/jscode.py	Wed Apr  2 18:39:08 2008
@@ -42,16 +42,44 @@
         self.label_count = 0
         self.has_labels = True
         self.stack = T()
+        self.startlooplabel = []
+        self.endlooplabel = []
 
-    def emit_label(self):
-        num = self.prealocate_label()
+    def emit_label(self, num = -1):
+        if num == -1:
+            num = self.prealocate_label()
         self.emit('LABEL', num)
         return num
 
+    def emit_startloop_label(self):
+        num = self.emit_label()
+        self.startlooplabel.append(num)
+        return num
+
     def prealocate_label(self):
         num = self.label_count
         self.label_count += 1
-        return num        
+        return num
+
+    def prealocate_endloop_label(self):
+        num = self.prealocate_label()
+        self.endlooplabel.append(num)
+        return num
+
+    def emit_endloop_label(self, label):
+        self.endlooplabel.pop()
+        self.startlooplabel.pop()
+        self.emit_label(label)
+
+    def emit_break(self):
+        if not self.endlooplabel:
+            raise ThrowError(W_String("Break outside loop"))
+        self.emit('JUMP', self.endlooplabel[-1])
+
+    def emit_continue(self):
+        if not self.startlooplabel:
+            raise ThrowError(W_String("Continue outside loop"))
+        self.emit('JUMP', self.startlooplabel[-1])
 
     def emit(self, operation, *args):
         opcode = None

Modified: pypy/branch/js-refactoring/pypy/lang/js/operations.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/operations.py	(original)
+++ pypy/branch/js-refactoring/pypy/lang/js/operations.py	Wed Apr  2 18:39:08 2008
@@ -290,15 +290,14 @@
         self.target = target
     
 class Break(Unconditional):
-    def execute(self, ctx):
-        raise ExecutionReturned('break', None, None)
-    
+    def emit(self, bytecode):
+        assert self.target is None
+        bytecode.emit_break()    
 
 class Continue(Unconditional):
-    def execute(self, ctx):
-        raise ExecutionReturned('continue', None, None)
-    
-
+    def emit(self, bytecode):
+        assert self.target is None
+        bytecode.emit_continue()
 
 class Call(Expression):
     def __init__(self, pos, left, args):
@@ -815,38 +814,23 @@
 class Do(WhileBase):
     opcode = 'DO'
     
-    def execute(self, ctx):
-        try:
-            self.body.execute(ctx)
-        except ExecutionReturned, e:
-            if e.type == 'break':
-                return
-            elif e.type == 'continue':
-                pass
-        while self.condition.eval(ctx).ToBoolean():
-            try:
-                self.body.execute(ctx)
-            except ExecutionReturned, e:
-                if e.type == 'break':
-                    break
-                elif e.type == 'continue':
-                    continue
-
     def emit(self, bytecode):
-        startlabel = bytecode.emit_label()
+        startlabel = bytecode.emit_startloop_label()
+        end = bytecode.preallocate_endloop_label()
         self.body.emit(bytecode)
         self.condition.emit(bytecode)
         bytecode.emit('JUMP_IF_TRUE', startlabel)
+        bytecode.emit_endloop_label(end)
     
 class While(WhileBase):
     def emit(self, bytecode):
-        startlabel = bytecode.emit_label()
+        startlabel = bytecode.emit_startloop_label()
         self.condition.emit(bytecode)
-        endlabel = bytecode.prealocate_label()
+        endlabel = bytecode.prealocate_endloop_label()
         bytecode.emit('JUMP_IF_FALSE', endlabel)
         self.body.emit(bytecode)
         bytecode.emit('JUMP', startlabel)
-        bytecode.emit('LABEL', endlabel)
+        bytecode.emit_endloop_label(endlabel)
 
     def execute(self, ctx):
         while self.condition.eval(ctx).ToBoolean():
@@ -918,15 +902,15 @@
     def emit(self, bytecode):
         self.setup.emit(bytecode)
         bytecode.emit('POP')
-        precond = bytecode.emit_label()
-        finish = bytecode.prealocate_label()
+        precond = bytecode.emit_startloop_label()
+        finish = bytecode.prealocate_endloop_label()
         self.condition.emit(bytecode)
         bytecode.emit('JUMP_IF_FALSE', finish)
         self.body.emit(bytecode)
         self.update.emit(bytecode)
         bytecode.emit('POP')
         bytecode.emit('JUMP', precond)
-        bytecode.emit('LABEL', finish)
+        bytecode.emit_endloop_label(finish)
     
 class Boolean(Expression):
     def __init__(self, pos, boolval):



More information about the Pypy-commit mailing list