9.4
FossilOrigin-Name: 58225e550ec53fff4dcdde3678d5850dd91a285ad4ab247baa1fbf71e8d73206
change ollskrokpoqtsmuosuzznwwtumxyrpvn
commit a22ca4f6cba55bd38fe9f8ba25c6ab61e89eb13a
author alpha <alpha@kejadlen.dev>
date
parent krlrvwwt
diff --git a/ruby/lib/lox/interpreter.rb b/ruby/lib/lox/interpreter.rb
index 3d7240e..90f087d 100644
--- a/ruby/lib/lox/interpreter.rb
+++ b/ruby/lib/lox/interpreter.rb
@@ -59,6 +59,13 @@ module Lox
       nil
     end
 
+    def visit_while(stmt)
+      while truthy?(evaluate(stmt.cond))
+        execute(stmt.body)
+      end
+      nil
+    end
+
     def visit_grouping(expr) = evaluate(expr.expr)
     def visit_literal(expr)  = expr.value
 
diff --git a/ruby/lib/lox/parser.rb b/ruby/lib/lox/parser.rb
index 421fe67..cfec840 100644
--- a/ruby/lib/lox/parser.rb
+++ b/ruby/lib/lox/parser.rb
@@ -36,9 +36,19 @@ module Lox
       Stmt::Var.new(name, initializer)
     end
 
+    def while_stmt
+      consume!(:LEFT_PAREN, "Expect '(' after 'if'.")
+      cond = expression
+      consume!(:RIGHT_PAREN, "Expect ')' after 'if'.")
+      body = statement
+
+      Stmt::While.new(cond, body)
+    end
+
     def statement
       return if_stmt if match?(:IF)
       return print if match?(:PRINT)
+      return while_stmt if match?(:WHILE)
       return Stmt::Block.new(block) if match?(:LEFT_BRACE)
 
       expression_stmt
diff --git a/ruby/lib/lox/stmt.rb b/ruby/lib/lox/stmt.rb
index 2b46968..c526e04 100644
--- a/ruby/lib/lox/stmt.rb
+++ b/ruby/lib/lox/stmt.rb
@@ -17,5 +17,6 @@ module Lox
     stmt :If, :cond, :then, :else
     stmt :Print, :expr
     stmt :Var, :name, :initializer
+    stmt :While, :cond, :body
   end
 end
diff --git a/ruby/test/lox/test_interpreter.rb b/ruby/test/lox/test_interpreter.rb
index 4f5b8be..e7ce24b 100644
--- a/ruby/test/lox/test_interpreter.rb
+++ b/ruby/test/lox/test_interpreter.rb
@@ -186,6 +186,20 @@ class TestInterpreter < Lox::Test
     SRC
   end
 
+  def test_while
+    assert_interpreted <<~EXPECTED.chomp, <<~SRC
+      0
+      1
+      2
+    EXPECTED
+      var a = 0;
+      while (a < 3) {
+        print a;
+        a = a + 1;
+      }
+    SRC
+  end
+
   private
 
   def assert_interpreted(expected, src)