runningwater 2 år sedan
förälder
incheckning
5ac782a190

+ 10 - 0
.idea/inspectionProfiles/Project_Default.xml

@@ -0,0 +1,10 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
+      <Languages>
+        <language minSize="47" name="Java" />
+      </Languages>
+    </inspection_tool>
+  </profile>
+</component>

+ 29 - 1
src/main/java/com/craftinginterpreters/lox/Interpreter.java

@@ -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.");

+ 10 - 1
src/main/java/com/craftinginterpreters/lox/Lox.java

@@ -16,7 +16,9 @@ import java.util.List;
  * @desc
  */
 public class Lox {
+  private static final Interpreter interpreter = new Interpreter();
   private static boolean hadError = false;
+  private static boolean hadRuntimeError = false;
 
   public static void main(String[] args) throws IOException {
     if (args.length > 1) {
@@ -41,6 +43,7 @@ public class Lox {
 
     // Indicate an error in the exit code.
     if (hadError) System.exit(65);
+    if (hadRuntimeError) System.exit(70);
   }
 
   /** 提示符里面输入 */
@@ -73,7 +76,8 @@ public class Lox {
     // Stop if there was a syntax error.
     if (hadError) return;
 
-    System.out.println(new AstPrinter().print(expression));
+    System.out.println("  ...AST: " + new AstPrinter().print(expression));
+    interpreter.interpret(expression);
   }
 
   /**
@@ -98,4 +102,9 @@ public class Lox {
       report(token.line, " at '" + token.lexeme + "'", message);
     }
   }
+
+  public static void runtimeError(RuntimeError error) {
+    System.err.println(error.getMessage() + "\n[line " + error.token.line + "]");
+    hadRuntimeError = true;
+  }
 }