package Interpreter; import java.util.List; import Interpreter.Expression.*; import Interpreter.Statement.ExpressionStatement; import Interpreter.Statement.PrintStatement; import Interpreter.Statement.VariableDeclaration; public class Interpreter { private Environment environment = new Environment(); void interpret(List statements){ try{ for (Statement statement: statements){ evaluateStatement(statement); } } catch (Error e){ } } private Object evaluateStatement(Statement statement){ switch(statement.getStatmentType()){ case "exprStmt": return evalExpressionStatement((ExpressionStatement)statement); case "vardec": return evalVariableDeclaration((VariableDeclaration)statement); case "print": return evalPrintStatement((PrintStatement)statement); default: return null; } } private Object evalExpressionStatement(ExpressionStatement stmt){ return evaluateExpression(stmt.expr); } private Object evalVariableDeclaration(VariableDeclaration vardec){ environment.defineVariable(vardec.name.text, null); return null; } private Object evalPrintStatement(PrintStatement print){ System.out.println(evaluateExpression(print.expr)); return null; } private Object evaluateExpression(Expression expression){ switch(expression.getExpressionType()){ case "binary": return evaluateBinaryExpression((Binary)expression); case "literal": return evaluateLiteralExpression((Literal)expression); case "bracket": return evaluateBracketedExpression((BracketedExpression)expression); case "assign": return evaluateAssignmentExpression((AssignmentExpression)expression); case "var": return evaluateVariableExpression((Variable)expression); default: return null; } } private Object evaluateBinaryExpression(Binary expr){ Object leftEval = evaluateExpression(expr.left); Object rightEval = evaluateExpression(expr.right); switch (expr.op.type){ case PLUS: if (checkOperandsNum(leftEval, leftEval)){ return (double)leftEval + (double)rightEval; } case STAR: if (checkOperandsNum(leftEval, leftEval)){ return (double)leftEval * (double)rightEval; } case MINUS: if (checkOperandsNum(leftEval, leftEval)){ return (double)leftEval - (double)rightEval; } case SLASH: if (checkOperandsNum(leftEval, leftEval)){ return (double)leftEval / (double)rightEval; } case GREATER: if (checkOperandsNum(leftEval, leftEval)){ return (double)leftEval > (double)rightEval; } case LESS: if (checkOperandsNum(leftEval, leftEval)){ return (double)leftEval < (double)rightEval; } case EQUALITY: return leftEval.equals(rightEval); default: break; } return null; } private Object evaluateLiteralExpression(Literal expr){ return expr.value.value; } private Object evaluateBracketedExpression(BracketedExpression expr){ return evaluateExpression(expr.expr); } private Object evaluateAssignmentExpression(AssignmentExpression expr){ Object assignedValue = evaluateExpression(expr.value); environment.assignVariable(expr.name.text, assignedValue); return null; } private Object evaluateVariableExpression(Variable expr){ return environment.getVariable(expr.name.text); } private boolean checkOperandsNum(Object left, Object right){ if (left instanceof Double && right instanceof Double){ return true; } else { Language.displayError("Operands must be numbers"); throw new Error(); } } }