diff --git a/src/interpreter/resolver.py b/src/interpreter/resolver.py index a743b60..473df12 100644 --- a/src/interpreter/resolver.py +++ b/src/interpreter/resolver.py @@ -26,12 +26,18 @@ class LoopType(Enum): FOR = auto() +class ClassType(Enum): + NONE = auto() + CLASS = auto() + + class Resolver(Expr.Visitor[None], Stmt.Visitor[None]): def __init__(self, interpreter: Interpreter): self.interpreter: Interpreter = interpreter self.scopes: list[dict[str, bool]] = [] self.current_func: FunctionType = FunctionType.NONE self.current_loop: LoopType = LoopType.NONE + self.current_class: ClassType = ClassType.NONE def resolve(self, *objects: Expr | Stmt) -> None: for obj in objects: @@ -111,6 +117,8 @@ class Resolver(Expr.Visitor[None], Stmt.Visitor[None]): self.resolve(expr.object) def visit_this_expr(self, expr: ThisExpr) -> None: + if self.current_class == ClassType.NONE: + Pebble.token_error(expr.keyword, "Cannot use 'this' outside of a class.") self.resolve_local(expr, expr.keyword) def visit_block_stmt(self, stmt: BlockStmt) -> None: @@ -119,6 +127,8 @@ class Resolver(Expr.Visitor[None], Stmt.Visitor[None]): self.end_scope() def visit_class_stmt(self, stmt: ClassStmt) -> None: + enclosing_class: ClassType = self.current_class + self.current_class = ClassType.CLASS self.declare(stmt.name) self.define(stmt.name) @@ -129,6 +139,7 @@ class Resolver(Expr.Visitor[None], Stmt.Visitor[None]): self.resolve_function(method, FunctionType.METHOD) self.end_scope() + self.current_class = enclosing_class def visit_expression_stmt(self, stmt: ExpressionStmt) -> None: self.resolve(stmt.expression)