lib/loxxy/back_end/resolver.rb in loxxy-0.1.13 vs lib/loxxy/back_end/resolver.rb in loxxy-0.1.14
- old
+ new
@@ -24,14 +24,19 @@
# An indicator that tells we're in the middle of a function declaration
# @return [Symbol] must be one of: :none, :function
attr_reader :current_function
+ # An indicator that tells we're in the middle of a class declaration
+ # @return [Symbol] must be one of: :none, :class
+ attr_reader :current_class
+
def initialize
@scopes = []
@locals = {}
@current_function = :none
+ @current_class = :none
end
# Given an abstract syntax parse tree visitor, launch the visit
# and execute the visit events in the output stream.
# @param aVisitor [AST::ASTVisitor]
@@ -57,14 +62,20 @@
def before_class_stmt(aClassStmt)
declare(aClassStmt.name)
end
def after_class_stmt(aClassStmt, aVisitor)
+ previous_class = current_class
+ @current_class = :class
define(aClassStmt.name)
+ begin_scope
+ define('this')
aClassStmt.body.each do |fun_stmt|
resolve_function(fun_stmt, :method, aVisitor)
end
+ end_scope
+ @current_class = previous_class
end
def before_for_stmt(aForStmt)
before_block_stmt(aForStmt)
end
@@ -136,9 +147,21 @@
end
def after_get_expr(aGetExpr, aVisitor)
# Evaluate object part
aGetExpr.object.accept(aVisitor)
+ end
+
+ def before_this_expr(_thisExpr)
+ if current_class == :none
+ msg = "Error at 'this': Can't use 'this' outside of a class."
+ raise StandardError, msg
+ end
+ end
+
+ def after_this_expr(aThisExpr, aVisitor)
+ # 'this' behaves closely to a local variable
+ resolve_local(aThisExpr, aVisitor)
end
# function declaration creates a new scope for its body & binds its parameters for that scope
def before_fun_stmt(aFunStmt, aVisitor)
declare(aFunStmt.name)