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)