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)