10.1
FossilOrigin-Name: c1d35386c76ad60362ec68d9e94a6e4fe9cfc02c39b7c2589668a214a3f22c43
change wukmutqutntkmvxynzuwtzkzmuspknqp
commit c03e9e6726b99c5cec4ddfe027b0fafbac9d284d
author alpha <alpha@kejadlen.dev>
date
parent uwuvsyyl
diff --git a/ruby/lib/lox/ast_printer.rb b/ruby/lib/lox/ast_printer.rb
index a303c5f..154c9b9 100644
--- a/ruby/lib/lox/ast_printer.rb
+++ b/ruby/lib/lox/ast_printer.rb
@@ -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)
diff --git a/ruby/lib/lox/expr.rb b/ruby/lib/lox/expr.rb
index 2737930..a3f40a2 100644
--- a/ruby/lib/lox/expr.rb
+++ b/ruby/lib/lox/expr.rb
@@ -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
diff --git a/ruby/lib/lox/parser.rb b/ruby/lib/lox/parser.rb
index 0f6ce9f..c6e8e24 100644
--- a/ruby/lib/lox/parser.rb
+++ b/ruby/lib/lox/parser.rb
@@ -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)
diff --git a/ruby/test/lox/test_parser.rb b/ruby/test/lox/test_parser.rb
index aaad61e..11a7904 100644
--- a/ruby/test/lox/test_parser.rb
+++ b/ruby/test/lox/test_parser.rb
@@ -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)