diff --git a/ruby/lib/lox/resolver.rb b/ruby/lib/lox/resolver.rb
index 0683335..381efe9 100644
--- a/ruby/lib/lox/resolver.rb
+++ b/ruby/lib/lox/resolver.rb
@@ -32,6 +32,7 @@ module Lox
with_superclass_scope = if stmt.superclass
raise ResolverError.new(stmt.superclass.name, "A class can't inherit from itself.") if stmt.name.lexeme == stmt.superclass.name.lexeme
+ @current_class = :SUBCLASS
resolve(stmt.superclass)
->(&block) { with_scope(super: true) { block.call } }
else
@@ -121,6 +122,9 @@ module Lox
end
def visit_super(expr)
+ raise ResolverError.new(expr.keyword, "Can't use 'super' outside of a class.") if @current_class == :NONE
+ raise ResolverError.new(expr.keyword, "Can't use 'super' in a class with no superclass.") if @current_class != :SUBCLASS
+
resolve_local(expr, expr.keyword)
nil
end
diff --git a/ruby/test/lox/test_interpreter.rb b/ruby/test/lox/test_interpreter.rb
index 446af71..237395c 100644
--- a/ruby/test/lox/test_interpreter.rb
+++ b/ruby/test/lox/test_interpreter.rb
@@ -528,6 +528,23 @@ class TestInterpreter < Lox::Test
SRC
end
+ def test_invalid_super
+ assert_raises Lox::ResolverError do
+ interpret(<<~SRC)
+ class Eclair {
+ cook() {
+ super.cook();
+ print "Pipe full of crème pâtissière.";
+ }
+ }
+ SRC
+ end
+
+ assert_raises Lox::ResolverError do
+ interpret("super.notEvenInAClass();")
+ end
+ end
+
private
def assert_interpreted(expected, src)