diff --git a/ruby/lib/lox/resolver.rb b/ruby/lib/lox/resolver.rb
index c52819c..25e14c6 100644
--- a/ruby/lib/lox/resolver.rb
+++ b/ruby/lib/lox/resolver.rb
@@ -33,7 +33,8 @@ module Lox
@scopes.last["this"] = true
stmt.methods.each do |method|
- resolve_function(method, :METHOD)
+ decl = method.name.lexeme == "init" ? :INIT : :METHOD
+ resolve_function(method, decl)
end
define(stmt.name)
@@ -59,9 +60,15 @@ module Lox
end
def visit_print(stmt) = resolve(stmt.expr)
+
def visit_return(stmt)
raise ResolverError.new(stmt.keyword, "Can't return from top-level code.") if @current_func == :NONE
- resolve(stmt.value) if stmt.value
+
+ return unless stmt.value
+
+ raise ResolverError.new(stmt.keyword, "Can't return a value from an initializer.") if @current_func == :INIT
+
+ resolve(stmt.value)
end
def visit_var(stmt)
diff --git a/ruby/test/lox/test_interpreter.rb b/ruby/test/lox/test_interpreter.rb
index 849af6b..a3f5073 100644
--- a/ruby/test/lox/test_interpreter.rb
+++ b/ruby/test/lox/test_interpreter.rb
@@ -431,6 +431,24 @@ class TestInterpreter < Lox::Test
var foo = Foo();
print foo.init();
SRC
+
+ assert_raises Lox::ResolverError do
+ interpret(<<~SRC)
+ class Foo {
+ init() {
+ return "something else";
+ }
+ }
+ SRC
+ end
+
+ assert_interpreted "", <<~SRC
+ class Foo {
+ init() {
+ return;
+ }
+ }
+ SRC
end
private