11.3.3
change wznnmkwvtqkzmuqvkvkszzlvvlqzskux
commit 93ce035db7437b0e79c58bcca782570ad84a7b60
author Alpha Chen <alpha@kejadlen.dev>
date
parent zmwtlonp
diff --git a/ruby/lib/lox/error.rb b/ruby/lib/lox/error.rb
index 46897e5..8013f0d 100644
--- a/ruby/lib/lox/error.rb
+++ b/ruby/lib/lox/error.rb
@@ -1,5 +1,11 @@
 module Lox
+
   class Error < StandardError
+    attr_reader :token, :message
+
+    def initialize(token, message)
+      @token, @message = token, message
+    end
   end
 
   class ParseError < Error
@@ -8,16 +14,12 @@ module Lox
 
       error = "Error"
       error << " at #{where}" unless where.empty?
-      super("[line #{token.line}] #{error}: #{message}")
+
+      super(token, "[line #{token.line}] #{error}: #{message}")
     end
   end
 
-  class RuntimeError < Error
-    attr_reader :token
+  RuntimeError = Class.new(Error)
+  ResolverError = Class.new(Error)
 
-    def initialize(token, message)
-      @token = token
-      super(message)
-    end
-  end
 end
diff --git a/ruby/lib/lox/resolver.rb b/ruby/lib/lox/resolver.rb
index fdd385a..d2d48f4 100644
--- a/ruby/lib/lox/resolver.rb
+++ b/ruby/lib/lox/resolver.rb
@@ -1,3 +1,5 @@
+require_relative "error"
+
 module Lox
   class Resolver
 
@@ -27,12 +29,21 @@ module Lox
       nil
     end
 
+    def visit_variable(expr)
+      if !@scopes.empty? && @scopes.last[expr.name.lexeme] == false
+        raise ResolverError.new(expr.name, "Can't read local variable in its own initializer.")
+      end
+
+      resolve_local(expr, expr.name)
+      nil
+    end
+
     private
 
     def with_block
-      @scopes.push({})
+      @scopes.unshift({})
       yield
-      @scopes.pop
+      @scopes.shift
     end
 
     def declare(name)
@@ -49,5 +60,13 @@ module Lox
       scopes[name.lexeme] = true
     end
 
+    def resolve_local(expr, name)
+      scope_and_depth = @scopes.each.with_index.find {|scope, depth| scope.has_key?(name.lexeme) }
+      return unless scope_and_depth
+
+      scope, depth = scope_and_depth
+      @interpreter.resolve(expr, depth)
+    end
+
   end
 end