10.4.1 - environment
change ltumzvkwwzrzynqtwulswwnvwsrynsqw
commit 30ca1230bb5259fe118b6a341cc2279dd4c0bcb7
author Alpha Chen <alpha@kejadlen.dev>
date
parent szqvptns
diff --git a/ruby/lib/lox/environment.rb b/ruby/lib/lox/environment.rb
index 91366c6..543e07e 100644
--- a/ruby/lib/lox/environment.rb
+++ b/ruby/lib/lox/environment.rb
@@ -2,6 +2,8 @@ require_relative "error"
 
 module Lox
   class Environment
+    attr_reader :values, :enclosing
+
     def initialize(enclosing = nil)
       @enclosing = enclosing
       @values = {}
@@ -11,6 +13,12 @@ module Lox
       @values[name] = value
     end
 
+    def ancestor(distance)
+      env = self
+      distance.times { env = env.enclosing }
+      env
+    end
+
     def get(token)
       name = token.lexeme
 
@@ -23,6 +31,10 @@ module Lox
       end
     end
 
+    def get_at(distance, name)
+      ancestor(distance).values.fetch(name)
+    end
+
     def assign(name, value)
       lexeme = name.lexeme
 
diff --git a/ruby/test/lox/test_environment.rb b/ruby/test/lox/test_environment.rb
index 1838a3d..fd5b3ee 100644
--- a/ruby/test/lox/test_environment.rb
+++ b/ruby/test/lox/test_environment.rb
@@ -44,4 +44,16 @@ class TestEnvironment < Lox::Test
     assert_equal "qux", enclosed.get(NAME_TOKEN)
     assert_equal "bar", @env.get(NAME_TOKEN)
   end
+
+  def test_get_at
+    @env.define("name", "foo")
+    enclosed = Lox::Environment.new(@env)
+    enclosed.define("name", "bar")
+
+    assert_equal "foo", enclosed.get_at(1, "name")
+    assert_equal "bar", enclosed.get_at(0, "name")
+
+    assert_equal "foo", @env.get_at(0, "name")
+  end
+
 end