From 68a2ebd34fc94488e89ffb82b359ec6e7e152ae9 Mon Sep 17 00:00:00 2001 From: Tom Willemse Date: Thu, 8 Jul 2021 00:14:31 -0700 Subject: Restructure project to make room for clox --- src/com/craftinginterpreters/lox/Resolver.java | 299 ------------------------- 1 file changed, 299 deletions(-) delete mode 100644 src/com/craftinginterpreters/lox/Resolver.java (limited to 'src/com/craftinginterpreters/lox/Resolver.java') diff --git a/src/com/craftinginterpreters/lox/Resolver.java b/src/com/craftinginterpreters/lox/Resolver.java deleted file mode 100644 index fe3a641..0000000 --- a/src/com/craftinginterpreters/lox/Resolver.java +++ /dev/null @@ -1,299 +0,0 @@ -package com.craftinginterpreters.lox; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Stack; - -class Resolver implements Expr.Visitor, Stmt.Visitor { - private final Interpreter interpreter; - private final Stack> scopes = new Stack<>(); - private FunctionType currentFunction = FunctionType.NONE; - - Resolver(Interpreter interpreter) { - this.interpreter = interpreter; - } - - private enum FunctionType { - NONE, FUNCTION, INITIALIZER, METHOD - } - - private enum ClassType { - NONE, CLASS, SUBCLASS - } - - private ClassType currentClass = ClassType.NONE; - - public void resolve(List statements) { - for (Stmt statement : statements) { - resolve(statement); - } - } - - @Override - public Void visitBlockStmt(Stmt.Block stmt) { - beginScope(); - resolve(stmt.statements); - endScope(); - return null; - } - - @Override - public Void visitClassStmt(Stmt.Class stmt) { - ClassType enclosingClass = currentClass; - currentClass = ClassType.CLASS; - - declare(stmt.name); - define(stmt.name); - - if (stmt.superclass != null && stmt.name.lexeme.equals(stmt.superclass.name.lexeme)) { - Lox.error(stmt.superclass.name, "A class can't inherit from itself."); - } - - if (stmt.superclass != null) { - currentClass = ClassType.SUBCLASS; - - resolve(stmt.superclass); - } - - if (stmt.superclass != null) { - beginScope(); - scopes.peek().put("super", true); - } - - beginScope(); - scopes.peek().put("this", true); - - for (Stmt.Function method : stmt.methods) { - FunctionType declaration = FunctionType.METHOD; - if (method.name.lexeme.equals("init")) { - declaration = FunctionType.INITIALIZER; - } - resolveFunction(method, declaration); - } - - endScope(); - - if (stmt.superclass != null) { - endScope(); - } - - currentClass = enclosingClass; - return null; - } - - @Override - public Void visitExpressionStmt(Stmt.Expression stmt) { - resolve(stmt.expression); - return null; - } - - @Override - public Void visitFunctionStmt(Stmt.Function stmt) { - declare(stmt.name); - define(stmt.name); - - resolveFunction(stmt, FunctionType.FUNCTION); - return null; - } - - @Override - public Void visitIfStmt(Stmt.If stmt) { - resolve(stmt.condition); - resolve(stmt.thenBranch); - if (stmt.elseBranch != null) - resolve(stmt.elseBranch); - return null; - } - - @Override - public Void visitPrintStmt(Stmt.Print stmt) { - resolve(stmt.expression); - return null; - } - - @Override - public Void visitReturnStmt(Stmt.Return stmt) { - if (currentFunction == FunctionType.NONE) { - Lox.error(stmt.keyword, "Can't return from top-level code."); - } - - if (stmt.value != null) { - if (currentFunction == FunctionType.INITIALIZER) { - Lox.error(stmt.keyword, "Can't return a value from an initializer."); - } - resolve(stmt.value); - } - - return null; - } - - @Override - public Void visitVarStmt(Stmt.Var stmt) { - declare(stmt.name); - if (stmt.initializer != null) { - resolve(stmt.initializer); - } - define(stmt.name); - return null; - } - - @Override - public Void visitWhileStmt(Stmt.While stmt) { - resolve(stmt.condition); - resolve(stmt.body); - return null; - } - - @Override - public Void visitAssignExpr(Expr.Assign expr) { - resolve(expr.value); - resolveLocal(expr, expr.name); - return null; - } - - @Override - public Void visitBinaryExpr(Expr.Binary expr) { - resolve(expr.left); - resolve(expr.right); - return null; - } - - @Override - public Void visitCallExpr(Expr.Call expr) { - resolve(expr.callee); - - for (Expr argument : expr.arguments) { - resolve(argument); - } - - return null; - } - - @Override - public Void visitGetExpr(Expr.Get expr) { - resolve(expr.object); - return null; - } - - @Override - public Void visitGroupingExpr(Expr.Grouping expr) { - resolve(expr.expression); - return null; - } - - @Override - public Void visitLiteralExpr(Expr.Literal expr) { - return null; - } - - @Override - public Void visitSetExpr(Expr.Set expr) { - resolve(expr.value); - resolve(expr.object); - return null; - } - - @Override - public Void visitSuperExpr(Expr.Super expr) { - if (currentClass == ClassType.NONE) { - Lox.error(expr.keyword, "Can't use 'super' outside of a class."); - } else if (currentClass != ClassType.SUBCLASS) { - Lox.error(expr.keyword, "Can't use 'super' in a class with no superclass."); - } - - resolveLocal(expr, expr.keyword); - return null; - } - - @Override - public Void visitThisExpr(Expr.This expr) { - if (currentClass == ClassType.NONE) { - Lox.error(expr.keyword, "Can't use 'this' outside of a class."); - return null; - } - - resolveLocal(expr, expr.keyword); - return null; - } - - @Override - public Void visitLogicalExpr(Expr.Logical expr) { - resolve(expr.left); - resolve(expr.right); - return null; - } - - @Override - public Void visitUnaryExpr(Expr.Unary expr) { - resolve(expr.right); - return null; - } - - @Override - public Void visitVariableExpr(Expr.Variable expr) { - if (!scopes.isEmpty() && scopes.peek().get(expr.name.lexeme) == Boolean.FALSE) { - Lox.error(expr.name, "Can't read local variable in its own initializer."); - } - - resolveLocal(expr, expr.name); - return null; - } - - private void resolve(Stmt stmt) { - stmt.accept(this); - } - - private void resolve(Expr expr) { - expr.accept(this); - } - - private void resolveFunction(Stmt.Function function, FunctionType type) { - FunctionType enclosingFunction = currentFunction; - currentFunction = type; - - beginScope(); - for (Token param : function.params) { - declare(param); - define(param); - } - resolve(function.body); - endScope(); - currentFunction = enclosingFunction; - } - - private void beginScope() { - scopes.push(new HashMap()); - } - - private void endScope() { - scopes.pop(); - - } - - private void declare(Token name) { - if (scopes.isEmpty()) - return; - - Map scope = scopes.peek(); - if (scope.containsKey(name.lexeme)) { - Lox.error(name, "Already variable with this name in this scope."); - } - scope.put(name.lexeme, false); - } - - private void define(Token name) { - if (scopes.isEmpty()) - return; - scopes.peek().put(name.lexeme, true); - } - - private void resolveLocal(Expr expr, Token name) { - for (int i = scopes.size() - 1; i >= 0; i--) { - if (scopes.get(i).containsKey(name.lexeme)) { - interpreter.resolve(expr, scopes.size() - 1 - i); - return; - } - } - } -} -- cgit v1.2.3-54-g00ecf