|
|
@@ -8,6 +8,20 @@ package com.craftinginterpreters.lox;
|
|
|
* @desc
|
|
|
*/
|
|
|
public class Interpreter implements Expr.Visitor<Object> {
|
|
|
+ /**
|
|
|
+ * public API
|
|
|
+ *
|
|
|
+ * @param expression
|
|
|
+ */
|
|
|
+ void interpret(Expr expression) {
|
|
|
+ try {
|
|
|
+ Object value = evaluate(expression);
|
|
|
+ System.out.println(stringify(value));
|
|
|
+ } catch (RuntimeError error) {
|
|
|
+ Lox.runtimeError(error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public Object visitBinaryExpr(Expr.Binary expr) {
|
|
|
Object left = evaluate(expr.left);
|
|
|
@@ -43,7 +57,7 @@ public class Interpreter implements Expr.Visitor<Object> {
|
|
|
if (left instanceof String && right instanceof String) {
|
|
|
yield left + (String) right;
|
|
|
}
|
|
|
- yield null;
|
|
|
+ throw new RuntimeError(expr.operator, "Operands must be two numbers or two Strings.");
|
|
|
}
|
|
|
case SLASH -> {
|
|
|
checkNumberOperand(expr.operator, left, right);
|
|
|
@@ -97,6 +111,20 @@ public class Interpreter implements Expr.Visitor<Object> {
|
|
|
return a.equals(b);
|
|
|
}
|
|
|
|
|
|
+ private String stringify(Object object) {
|
|
|
+ if (object == null) return "nil";
|
|
|
+
|
|
|
+ if (object instanceof Double) {
|
|
|
+ String text = object.toString();
|
|
|
+ if (text.endsWith(".0")) {
|
|
|
+ text = text.substring(0, text.length() - 2);
|
|
|
+ }
|
|
|
+ return text;
|
|
|
+ }
|
|
|
+
|
|
|
+ return object.toString();
|
|
|
+ }
|
|
|
+
|
|
|
private void checkNumberOperand(Token operator, Object operand) {
|
|
|
if (operand instanceof Double) return;
|
|
|
throw new RuntimeError(operator, "Operand must be a number.");
|