From 66726f8e6954f4d00c6cee36729ad22195a6a50d Mon Sep 17 00:00:00 2001 From: alpha Date: Fri, 12 Aug 2022 22:58:09 +0000 Subject: [PATCH] 9.5.1 FossilOrigin-Name: e6003611fc9c7f22e8ab96c338f79c3f8a0ddd7ff15b21a37568b4b6c3f54329 --- ruby/lib/lox/parser.rb | 39 +++++++++++++++++++++++++++++++ ruby/test/lox/test_interpreter.rb | 24 +++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/ruby/lib/lox/parser.rb b/ruby/lib/lox/parser.rb index cfec840..0f6ce9f 100644 --- a/ruby/lib/lox/parser.rb +++ b/ruby/lib/lox/parser.rb @@ -46,6 +46,7 @@ module Lox end def statement + return for_stmt if match?(:FOR) return if_stmt if match?(:IF) return print if match?(:PRINT) return while_stmt if match?(:WHILE) @@ -54,6 +55,44 @@ module Lox expression_stmt end + def for_stmt + consume!(:LEFT_PAREN, "Expect '(' after 'if'.") + + initializer = if match?(:SEMICOLON) + nil + elsif match?(:VAR) + var_declaration + else + expression_stmt + end + + condition = !check?(:SEMICOLON) ? expression : Expr::Literal(true) + consume!(:SEMICOLON, "Expect ';' after loop condition.") + + increment = !check?(:RIGHT_PAREN) ? expression : nil + consume!(:RIGHT_PAREN, "Expect ')' after for clauses.") + + body = statement + + if increment + body = Stmt::Block.new([ + body, + Stmt::Expr.new(increment), + ]) + end + + body = Stmt::While.new(condition, body); + + if initializer + body = Stmt::Block.new([ + initializer, + body, + ]) + end + + body + end + def if_stmt consume!(:LEFT_PAREN, "Expect '(' after 'if'.") cond = expression diff --git a/ruby/test/lox/test_interpreter.rb b/ruby/test/lox/test_interpreter.rb index e7ce24b..21a1258 100644 --- a/ruby/test/lox/test_interpreter.rb +++ b/ruby/test/lox/test_interpreter.rb @@ -200,6 +200,30 @@ class TestInterpreter < Lox::Test SRC end + def test_for + assert_interpreted <<~EXPECTED.chomp, <<~SRC + 0 + 1 + 1 + 2 + 3 + 5 + 8 + 13 + 21 + 34 + EXPECTED + var a = 0; + var temp; + + for (var b = 1; a < 50; b = temp + b) { + print a; + temp = a; + a = b; + } + SRC + end + private def assert_interpreted(expected, src)