FossilOrigin-Name: d0e9947d95fd8cad638edb04ff5d9d450516434320a54f6d478214d6e90800b5
private
alpha 2 years ago
parent 42dd033fb4
commit 556e5e796c

@ -26,6 +26,16 @@ module Lox
parenthesize("block", *expr.stmts) parenthesize("block", *expr.stmts)
end end
def visit_if(stmt)
exprs = [stmt.cond, stmt.then]
exprs << stmt.else if stmt.else
parenthesize("if", *exprs)
end
def visit_expr(expr)
expr.expr.accept(self)
end
private private
def parenthesize(name, *exprs) def parenthesize(name, *exprs)

@ -39,6 +39,15 @@ module Lox
nil nil
end end
def visit_if(stmt)
if truthy?(evaluate(stmt.cond))
evaluate(stmt.then)
elsif stmt.else
evaluate(stmt.else)
end
nil
end
def visit_print(expr) def visit_print(expr)
puts stringify(evaluate(expr.expr)) puts stringify(evaluate(expr.expr))
nil nil

@ -37,12 +37,24 @@ module Lox
end end
def statement def statement
return if_stmt if match?(:IF)
return print if match?(:PRINT) return print if match?(:PRINT)
return Stmt::Block.new(block) if match?(:LEFT_BRACE) return Stmt::Block.new(block) if match?(:LEFT_BRACE)
expression_stmt expression_stmt
end end
def if_stmt
consume!(:LEFT_PAREN, "Expect '(' after 'if'.")
cond = expression
consume!(:RIGHT_PAREN, "Expect ')' after 'if'.")
then_stmt = statement
else_stmt = match?(:ELSE) ? statement : nil
Stmt::If.new(cond, then_stmt, else_stmt)
end
def print def print
value = expression value = expression
consume!(:SEMICOLON, "Expect ';' after value.") consume!(:SEMICOLON, "Expect ';' after value.")

@ -10,6 +10,10 @@ module Lox
include Visitable include Visitable
end end
If = Struct.new(:cond, :then, :else) do
include Visitable
end
Print = Struct.new(:expr) do Print = Struct.new(:expr) do
include Visitable include Visitable
end end

@ -159,6 +159,23 @@ class TestInterpreter < Lox::Test
SRC SRC
end end
def test_if
assert_interpreted <<~EXPECTED.chomp, <<~SRC
true
false
EXPECTED
if (true)
print "true";
else
print "false";
if (false)
print "true";
else
print "false";
SRC
end
private private
def assert_interpreted(expected, src) def assert_interpreted(expected, src)

@ -69,6 +69,12 @@ class TestParser < Lox::Test
SRC SRC
end end
def test_if
assert_parsed "(if (var first) (if (var second) true false))", :statement, <<~SRC
if (first) if (second) true; else false;
SRC
end
private private
def assert_parsed(expected, name, src) def assert_parsed(expected, name, src)

Loading…
Cancel
Save