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)