10.3
change nqyzmrwotzrntknsluvrtuluxuwquvts
commit 5072399281b7b9e670f64c276d09472b9f046ff9
author Alpha Chen <alpha@kejadlen.dev>
date
parent qyxupqzq
diff --git a/ruby/lib/lox/parser.rb b/ruby/lib/lox/parser.rb
index 1e14e53..7ac47d3 100644
--- a/ruby/lib/lox/parser.rb
+++ b/ruby/lib/lox/parser.rb
@@ -23,6 +23,7 @@ module Lox
     private
 
     def declaration
+      return function("function") if match?(:FUN)
       return var_declaration if match?(:VAR)
 
       statement
@@ -116,6 +117,26 @@ module Lox
       Stmt::Expr.new(value)
     end
 
+    def function(kind)
+      name = consume!(:IDENTIFIER, "Expect #{kind} name.")
+      consume!(:LEFT_PAREN, "Expect '(' after #{kind} name.")
+      params = []
+      unless check?(:RIGHT_PAREN)
+        loop do
+          raise ParseError.new(peek, "Can't have more than 255 parameters.") if params.size >= 255
+
+          params << consume!(:IDENTIFIER, "Expect parameter name.")
+          break unless match?(:COMMA)
+        end
+      end
+      consume!(:RIGHT_PAREN, "Expect ')' after parameters.")
+
+      consume!(:LEFT_BRACE, "Expect '{' before #{kind} body.")
+      body = block
+
+      Stmt::Function.new(name, params, body)
+    end
+
     def block
       statements = []
       until check?(:RIGHT_BRACE) || eot?
diff --git a/ruby/lib/lox/stmt.rb b/ruby/lib/lox/stmt.rb
index c526e04..0f377d7 100644
--- a/ruby/lib/lox/stmt.rb
+++ b/ruby/lib/lox/stmt.rb
@@ -13,6 +13,7 @@ module Lox
     end
 
     stmt :Block, :stmts
+    stmt :Fun, :name, :params, :body
     stmt :Expr, :expr
     stmt :If, :cond, :then, :else
     stmt :Print, :expr