9.4
FossilOrigin-Name: 58225e550ec53fff4dcdde3678d5850dd91a285ad4ab247baa1fbf71e8d73206
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)