FossilOrigin-Name: c1d35386c76ad60362ec68d9e94a6e4fe9cfc02c39b7c2589668a214a3f22c43
private
alpha 2 years ago
parent d6f05497e3
commit 4b48ef1a75

@ -36,6 +36,10 @@ module Lox
expr.expr.accept(self)
end
def visit_call(call)
parenthesize(call.callee.accept(self), *call.args)
end
private
def parenthesize(name, *exprs)

@ -12,6 +12,7 @@ module Lox
expr :Assign, :name, :value
expr :Binary, :left, :op, :right
expr :Call, :callee, :paren, :args
expr :Grouping, :expr
expr :Literal, :value
expr :Logical, :left, :op, :right

@ -215,13 +215,41 @@ module Lox
end
def unary
return primary unless match?(:BANG, :MINUS)
return call unless match?(:BANG, :MINUS)
op = prev
right = unary
Expr::Unary.new(op, right)
end
def call
expr = primary
loop do
if match?(:LEFT_PAREN)
expr = finish_call(expr)
else
break
end
end
expr
end
def finish_call(callee)
args = []
if !check?(:RIGHT_PAREN)
loop do
args << expression
break unless match?(:COMMA)
end
end
paren = consume!(:RIGHT_PAREN, "Expect ')' after arguments.")
Expr::Call.new(callee, paren, args)
end
def primary
return Expr::Literal.new(false) if match?(:FALSE)
return Expr::Literal.new(true) if match?(:TRUE)

@ -75,6 +75,12 @@ class TestParser < Lox::Test
SRC
end
def test_call
assert_parsed "((var foo))", :statement, "foo();"
assert_parsed "((var foo) (var bar))", :statement, "foo(bar);"
assert_parsed "((var foo) (var bar) (var baz))", :statement, "foo(bar, baz);"
end
private
def assert_parsed(expected, name, src)

Loading…
Cancel
Save