lib/loxxy/back_end/resolver.rb in loxxy-0.1.17 vs lib/loxxy/back_end/resolver.rb in loxxy-0.2.00
- old
+ new
@@ -65,17 +65,28 @@
def after_class_stmt(aClassStmt, aVisitor)
previous_class = current_class
@current_class = :class
define(aClassStmt.name)
+ if aClassStmt.superclass
+ if aClassStmt.name == aClassStmt.superclass.name
+ raise StandardError, "'A class can't inherit from itself."
+ end
+
+ @current_class = :subclass
+ aClassStmt.superclass.accept(aVisitor)
+ begin_scope
+ define('super')
+ end
begin_scope
define('this')
aClassStmt.body.each do |fun_stmt|
mth_type = fun_stmt.name == 'init' ? :initializer : :method
resolve_function(fun_stmt, mth_type, aVisitor)
end
end_scope
+ end_scope if aClassStmt.superclass
@current_class = previous_class
end
def before_for_stmt(aForStmt)
before_block_stmt(aForStmt)
@@ -166,9 +177,28 @@
def after_this_expr(aThisExpr, aVisitor)
# 'this' behaves closely to a local variable
resolve_local(aThisExpr, aVisitor)
end
+
+ # rubocop: disable Style/CaseLikeIf
+ # rubocop: disable Style/StringConcatenation
+ def after_super_expr(aSuperExpr, aVisitor)
+ msg_prefix = "Error at 'super': Can't use 'super' "
+ if current_class == :none
+ err_msg = msg_prefix + 'outside of a class.'
+ raise StandardError, err_msg
+
+ elsif current_class == :class
+ err_msg = msg_prefix + 'in a class without superclass.'
+ raise StandardError, err_msg
+
+ end
+ # 'super' behaves closely to a local variable
+ resolve_local(aSuperExpr, aVisitor)
+ end
+ # rubocop: enable Style/StringConcatenation
+ # rubocop: enable Style/CaseLikeIf
# function declaration creates a new scope for its body & binds its parameters for that scope
def before_fun_stmt(aFunStmt, aVisitor)
declare(aFunStmt.name)
define(aFunStmt.name)