From 952bd06dcefc1904a43b861576ee5fae6c137fac Mon Sep 17 00:00:00 2001 From: Alpha Chen Date: Mon, 29 Aug 2022 13:48:19 -0700 Subject: [PATCH] 12.5 --- ruby/lib/lox/instance.rb | 7 +++++-- ruby/lib/lox/interpreter.rb | 7 ++++++- ruby/lib/lox/lox_class.rb | 7 +++---- ruby/lib/lox/resolver.rb | 5 +++++ ruby/test/lox/test_interpreter.rb | 29 +++++++++++++++++++++++++++++ 5 files changed, 48 insertions(+), 7 deletions(-) diff --git a/ruby/lib/lox/instance.rb b/ruby/lib/lox/instance.rb index 8b27905..d6bd711 100644 --- a/ruby/lib/lox/instance.rb +++ b/ruby/lib/lox/instance.rb @@ -10,9 +10,12 @@ module Lox end def get(name) - raise RuntimeError.new(name, "Undefined property '#{name.lexeme}'.") unless @fields.has_key?(name.lexeme) + return @fields.fetch(name.lexeme) if @fields.has_key?(name.lexeme) - @fields.fetch(name.lexeme) + method = @klass.find_method(name.lexeme) + return method unless method.nil? + + raise RuntimeError.new(name, "Undefined property '#{name.lexeme}'.") end def set(name, value) diff --git a/ruby/lib/lox/interpreter.rb b/ruby/lib/lox/interpreter.rb index c8fe02a..39ee6b8 100644 --- a/ruby/lib/lox/interpreter.rb +++ b/ruby/lib/lox/interpreter.rb @@ -46,7 +46,12 @@ module Lox def visit_class(stmt) @env.define(stmt.name.lexeme, nil) - klass = LoxClass.new(stmt.name.lexeme) + + methods = stmt.methods.to_h {|method| + [method.name.lexeme, Function.new(method, @env)] + } + + klass = LoxClass.new(stmt.name.lexeme, methods) @env.assign(stmt.name, klass) nil end diff --git a/ruby/lib/lox/lox_class.rb b/ruby/lib/lox/lox_class.rb index 170fa36..44a9f37 100644 --- a/ruby/lib/lox/lox_class.rb +++ b/ruby/lib/lox/lox_class.rb @@ -5,14 +5,13 @@ module Lox attr_reader :name - def initialize(name) - @name = name + def initialize(name, methods) + @name, @methods = name, methods end + def find_method(name) = @methods[name] def to_s = name - def call(interpreter, args) = Instance.new(self) - def arity = 0 end diff --git a/ruby/lib/lox/resolver.rb b/ruby/lib/lox/resolver.rb index 2ea0471..2740876 100644 --- a/ruby/lib/lox/resolver.rb +++ b/ruby/lib/lox/resolver.rb @@ -26,6 +26,11 @@ module Lox def visit_class(stmt) declare(stmt.name) + + stmt.methods.each do |method| + resolve_function(method, :METHOD) + end + define(stmt.name) nil end diff --git a/ruby/test/lox/test_interpreter.rb b/ruby/test/lox/test_interpreter.rb index ad1fd14..439bd5d 100644 --- a/ruby/test/lox/test_interpreter.rb +++ b/ruby/test/lox/test_interpreter.rb @@ -345,6 +345,35 @@ class TestInterpreter < Lox::Test SRC end + def test_class_methods + assert_interpreted "Crunch crunch crunch!", <<~SRC + class Bacon { + eat() { + print "Crunch crunch crunch!"; + } + } + + Bacon().eat(); // Prints "Crunch crunch crunch!". + SRC + + # assert_interpreted "", <<~SRC + # class Person { + # sayName() { + # print this.name; + # } + # } + + # var jane = Person(); + # jane.name = "Jane"; + + # var bill = Person(); + # bill.name = "Bill"; + + # bill.sayName = jane.sayName; + # bill.sayName(); // "Jane" + # SRC + end + private def assert_interpreted(expected, src)