10.6
change mrrwnzuyutoowmqlknknusmwzkrorlyx
commit acc4f5e1053721452e16679e147e236a59a78cfc
author Alpha Chen <alpha@kejadlen.dev>
date
parent klsknrsq
diff --git a/ruby/lib/lox/function.rb b/ruby/lib/lox/function.rb
index 2f291a0..cc92c2f 100644
--- a/ruby/lib/lox/function.rb
+++ b/ruby/lib/lox/function.rb
@@ -2,14 +2,14 @@ require_relative "environment"
 
 module Lox
   class Function
-    def initialize(decl)
-      @decl = decl
+    def initialize(decl, closure)
+      @decl, @closure = decl, closure
     end
 
     def arity = @decl.params.size
 
     def call(interpreter, args)
-      env = Environment.new(interpreter.globals)
+      env = Environment.new(@closure)
       @decl.params.map(&:lexeme).zip(args).each do |name, value|
         env.define(name, value)
       end
diff --git a/ruby/lib/lox/interpreter.rb b/ruby/lib/lox/interpreter.rb
index 1cd5536..34cf8f3 100644
--- a/ruby/lib/lox/interpreter.rb
+++ b/ruby/lib/lox/interpreter.rb
@@ -50,7 +50,7 @@ module Lox
     end
 
     def visit_function(stmt)
-      function = Function.new(stmt)
+      function = Function.new(stmt, @env)
       @env.define(stmt.name.lexeme, function)
       nil
     end
diff --git a/ruby/test/lox/test_interpreter.rb b/ruby/test/lox/test_interpreter.rb
index 3b89b2f..0799786 100644
--- a/ruby/test/lox/test_interpreter.rb
+++ b/ruby/test/lox/test_interpreter.rb
@@ -257,6 +257,27 @@ class TestInterpreter < Lox::Test
     SRC
   end
 
+  def test_local_functions_and_closures
+    assert_interpreted <<~EXPECTED.chomp, <<~SRC
+      1
+      2
+    EXPECTED
+      fun makeCounter() {
+        var i = 0;
+        fun count() {
+          i = i + 1;
+          print i;
+        }
+
+        return count;
+      }
+
+      var counter = makeCounter();
+      counter(); // "1".
+      counter(); // "2".
+    SRC
+  end
+
   private
 
   def assert_interpreted(expected, src)