13.3.3
change okzstxsltmqvvtkvmrlvznwzrntmqswv
commit b032c2dd6c0c7e20af6ed5a6e043c85aaaf1a703
author Alpha Chen <alpha@kejadlen.dev>
date
parent zrrrlyrt
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)