Alpha Chen 2 years ago
parent f2501a1d41
commit 952bd06dce

@ -10,9 +10,12 @@ module Lox
end end
def get(name) 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 end
def set(name, value) def set(name, value)

@ -46,7 +46,12 @@ module Lox
def visit_class(stmt) def visit_class(stmt)
@env.define(stmt.name.lexeme, nil) @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) @env.assign(stmt.name, klass)
nil nil
end end

@ -5,14 +5,13 @@ module Lox
attr_reader :name attr_reader :name
def initialize(name) def initialize(name, methods)
@name = name @name, @methods = name, methods
end end
def find_method(name) = @methods[name]
def to_s = name def to_s = name
def call(interpreter, args) = Instance.new(self) def call(interpreter, args) = Instance.new(self)
def arity = 0 def arity = 0
end end

@ -26,6 +26,11 @@ module Lox
def visit_class(stmt) def visit_class(stmt)
declare(stmt.name) declare(stmt.name)
stmt.methods.each do |method|
resolve_function(method, :METHOD)
end
define(stmt.name) define(stmt.name)
nil nil
end end

@ -345,6 +345,35 @@ class TestInterpreter < Lox::Test
SRC SRC
end 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 private
def assert_interpreted(expected, src) def assert_interpreted(expected, src)

Loading…
Cancel
Save