From 8350af26325184ba6cc300aedabe69d5fd1fe77d Mon Sep 17 00:00:00 2001 From: alpha Date: Fri, 12 Aug 2022 22:07:53 +0000 Subject: [PATCH] 9.4 FossilOrigin-Name: 58225e550ec53fff4dcdde3678d5850dd91a285ad4ab247baa1fbf71e8d73206 --- ruby/lib/lox/interpreter.rb | 7 +++++++ ruby/lib/lox/parser.rb | 10 ++++++++++ ruby/lib/lox/stmt.rb | 1 + ruby/test/lox/test_interpreter.rb | 14 ++++++++++++++ 4 files changed, 32 insertions(+) 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)