Alpha Chen 2 years ago
parent 91dc2b2c66
commit 264b30200c

@ -40,6 +40,11 @@ module Lox
parenthesize(call.callee.accept(self), *call.args) parenthesize(call.callee.accept(self), *call.args)
end end
def visit_return(stmt)
exprs = stmt.value ? [stmt.value] : []
parenthesize("return", *exprs)
end
private private
def parenthesize(name, *exprs) def parenthesize(name, *exprs)

@ -50,6 +50,7 @@ module Lox
return for_stmt if match?(:FOR) return for_stmt if match?(:FOR)
return if_stmt if match?(:IF) return if_stmt if match?(:IF)
return print if match?(:PRINT) return print if match?(:PRINT)
return return_stmt if match?(:RETURN)
return while_stmt if match?(:WHILE) return while_stmt if match?(:WHILE)
return Stmt::Block.new(block) if match?(:LEFT_BRACE) return Stmt::Block.new(block) if match?(:LEFT_BRACE)
@ -111,6 +112,13 @@ module Lox
Stmt::Print.new(value) Stmt::Print.new(value)
end end
def return_stmt
keyword = prev
value = check?(:SEMICOLON) ? nil : expression
consume!(:SEMICOLON, "Expect ';' after return value.")
Stmt::Return.new(keyword, value)
end
def expression_stmt def expression_stmt
value = expression value = expression
consume!(:SEMICOLON, "Expect ';' after value.") consume!(:SEMICOLON, "Expect ';' after value.")

@ -17,6 +17,7 @@ module Lox
stmt :Expr, :expr stmt :Expr, :expr
stmt :If, :cond, :then, :else stmt :If, :cond, :then, :else
stmt :Print, :expr stmt :Print, :expr
stmt :Return, :keyword, :value
stmt :Var, :name, :initializer stmt :Var, :name, :initializer
stmt :While, :cond, :body stmt :While, :cond, :body
end end

@ -81,6 +81,11 @@ class TestParser < Lox::Test
assert_parsed "((var foo) (var bar) (var baz))", :statement, "foo(bar, baz);" assert_parsed "((var foo) (var bar) (var baz))", :statement, "foo(bar, baz);"
end end
def test_return
assert_parsed "(return)", :statement, "return;"
assert_parsed "(return (var foo))", :statement, "return foo;"
end
private private
def assert_parsed(expected, name, src) def assert_parsed(expected, name, src)

Loading…
Cancel
Save