|
|
|
@ -4,27 +4,38 @@ package fr.celticinfo.lox
|
|
|
|
* The Resolver class is used to resolve the scope of the variables.
|
|
|
|
* The Resolver class is used to resolve the scope of the variables.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
class Resolver(private val interpreter: Interpreter) : ExprVisitor<Unit>, StmtVisitor<Unit> {
|
|
|
|
class Resolver(private val interpreter: Interpreter) : ExprVisitor<Unit>, StmtVisitor<Unit> {
|
|
|
|
private val scopes = mutableListOf<MutableMap<String, Boolean>>()
|
|
|
|
private val scopes = mutableListOf<MutableMap<String, Boolean>>()
|
|
|
|
private var currentFunctionType = FunctionType.NONE
|
|
|
|
private var currentFunctionType = FunctionType.NONE
|
|
|
|
|
|
|
|
private var currentClassType = ClassType.NONE
|
|
|
|
|
|
|
|
|
|
|
|
init {
|
|
|
|
|
|
|
|
scopes.add(mutableMapOf())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
override fun visitBlock(stmt: Block) {
|
|
|
|
init {
|
|
|
|
beginScope()
|
|
|
|
scopes.add(mutableMapOf())
|
|
|
|
resolve(stmt.statements)
|
|
|
|
}
|
|
|
|
endScope()
|
|
|
|
|
|
|
|
}
|
|
|
|
override fun visitBlock(stmt: Block) {
|
|
|
|
|
|
|
|
beginScope()
|
|
|
|
|
|
|
|
resolve(stmt.statements)
|
|
|
|
|
|
|
|
endScope()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
override fun visitClassStmt(stmt: ClassStmt) {
|
|
|
|
override fun visitClassStmt(stmt: ClassStmt) {
|
|
|
|
|
|
|
|
val enclosingClassType = currentClassType
|
|
|
|
|
|
|
|
currentClassType = ClassType.CLASS
|
|
|
|
|
|
|
|
|
|
|
|
declare(stmt.name)
|
|
|
|
declare(stmt.name)
|
|
|
|
define(stmt.name)
|
|
|
|
define(stmt.name)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
beginScope()
|
|
|
|
|
|
|
|
scopes.last()["this"] = true
|
|
|
|
|
|
|
|
|
|
|
|
for (method in stmt.methods) {
|
|
|
|
for (method in stmt.methods) {
|
|
|
|
val declaration = FunctionType.METHOD
|
|
|
|
val declaration = FunctionType.METHOD
|
|
|
|
resolveFunction(method, declaration)
|
|
|
|
resolveFunction(method, declaration)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
endScope()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
currentClassType = enclosingClassType
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
override fun visitExpression(stmt: Expression) {
|
|
|
|
override fun visitExpression(stmt: Expression) {
|
|
|
|
@ -110,6 +121,14 @@ class Resolver(private val interpreter: Interpreter) : ExprVisitor<Unit>, StmtVi
|
|
|
|
resolve(expr.obj)
|
|
|
|
resolve(expr.obj)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
override fun visitThis(expr: This) {
|
|
|
|
|
|
|
|
if (currentClassType == ClassType.NONE) {
|
|
|
|
|
|
|
|
Lox.error(expr.keyword, "Cannot use 'this' outside of a class.")
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
resolveLocal(expr, expr.keyword)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
override fun visitUnary(expr: Unary) {
|
|
|
|
override fun visitUnary(expr: Unary) {
|
|
|
|
resolve(expr.right)
|
|
|
|
resolve(expr.right)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -180,3 +199,8 @@ enum class FunctionType {
|
|
|
|
FUNCTION,
|
|
|
|
FUNCTION,
|
|
|
|
METHOD
|
|
|
|
METHOD
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
enum class ClassType {
|
|
|
|
|
|
|
|
NONE,
|
|
|
|
|
|
|
|
CLASS
|
|
|
|
|
|
|
|
}
|