Commits

Alex Gaynor committed 8181d1a

Support for while in the compiler.

Comments (0)

Files changed (4)

minijs/astcompiler.py

         for arg in args:
             self.data.append(chr(arg))
 
-    def emit_conditional_jump(self, bc):
-        pos = len(self.data)
-        self.emit(bc, 0)
-        return pos + 1
+    def get_pos(self):
+        return len(self.data)
 
     def patch_jump(self, pos):
-        self.data[pos] = chr(len(self.data))
+        self.data[pos + 1] = chr(len(self.data))
 
     def create_name(self, name):
         if name not in self.names:
     ("BINARY_SUB", 0, -1),
     ("BINARY_MUL", 0, -1),
     ("BINARY_DIV", 0, -1),
+    ("BINARY_LT", 0, -1),
 
+    ("JUMP", 1, 0),
     ("JUMP_IF_FALSE", 1, -1),
 
     ("DISCARD_TOP", 0, -1),
     "-": BINARY_SUB,
     "*": BINARY_MUL,
     "/": BINARY_DIV,
+    "<": BINARY_LT,
 }
 
     def compile(self, ctx):
         self.cond.compile(ctx)
-        pos = ctx.emit_conditional_jump(consts.JUMP_IF_FALSE)
+        pos = ctx.get_pos()
+        ctx.emit(consts.JUMP_IF_FALSE, 0)
         self.body.compile(ctx)
         ctx.patch_jump(pos)
 
 class While(Node):
     def __init__(self, cond, body):
-        self.cnod = cond
+        self.cond = cond
         self.body = body
 
+    def compile(self, ctx):
+        back_jump_target = ctx.get_pos()
+        self.cond.compile(ctx)
+        pos = ctx.get_pos()
+        ctx.emit(consts.JUMP_IF_FALSE, 0)
+        self.body.compile(ctx)
+        ctx.emit(consts.JUMP, back_jump_target)
+        ctx.patch_jump(pos)
+
+
 class BinOp(Node):
     def __init__(self, op, lhs, rhs):
         self.op = op

tests/test_compiler.py

         BINARY_ADD
         DISCARD_TOP
         RETURN_NULL
+        """)
+
+    def test_while(self, space):
+        self.assert_compiles(space, """
+        i = 0;
+        while (i < 10) {
+            i = i + 1;
+        }
+        """, """
+        LOAD_CONST 0
+        STORE_NAME 0
+        DISCARD_TOP
+        LOAD_NAME 0
+        LOAD_CONST 1
+        BINARY_LT
+        JUMP_IF_FALSE 22
+        LOAD_NAME 0
+        LOAD_CONST 2
+        BINARY_ADD
+        STORE_NAME 0
+        DISCARD_TOP
+        JUMP 5
+        RETURN_NULL
         """)