From 963e1234186910d92d8bd561ed7787f5d0bc3265 Mon Sep 17 00:00:00 2001 From: Alpha Chen Date: Tue, 23 Aug 2022 15:26:22 -0700 Subject: [PATCH] thx @tenderlove --- ruby/lib/lox/interpreter.rb | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/ruby/lib/lox/interpreter.rb b/ruby/lib/lox/interpreter.rb index 826e260..79bea5e 100644 --- a/ruby/lib/lox/interpreter.rb +++ b/ruby/lib/lox/interpreter.rb @@ -11,6 +11,11 @@ module Lox @env = @globals @locals = {} + # We do **NOT** want struct equality for getting the depth of a local + # since we can have multiple locals referencing the same variable in + # different scopes on a single line. + @locals.compare_by_identity + @globals.define("clock", Class.new { def arity = 0 def call(*) = Time.now.to_f @@ -30,11 +35,7 @@ module Lox def execute(stmt) = stmt.accept(self) def resolve(expr, depth) - # HACK We use the object id here since we do **NOT** want - # struct equality for getting the depth of a local since - # we can have multiple locals referencing the same variable - # in different scopes on a single line. - @locals[expr.object_id] = depth + @locals[expr] = depth end def visit_block(stmt) @@ -129,8 +130,8 @@ module Lox end def lookup_var(name, expr) - if @locals.has_key?(expr.object_id) - distance = @locals.fetch(expr.object_id) + if @locals.has_key?(expr) + distance = @locals.fetch(expr) @env.get_at(distance, name.lexeme) else @globals.get(name) @@ -140,8 +141,8 @@ module Lox def visit_assign(expr) value = evaluate(expr.value) - if @locals.has_key?(expr.object_id) - distance = @locals.fetch(expr.object_id) + if @locals.has_key?(expr) + distance = @locals.fetch(expr) @env.assign_at(distance, expr.name, value) else @globals.assign(expr.name, value)