checkpoint
[sbp.git] / src / edu / berkeley / sbp / ParseFailed.java
index 27f87e8..d5474ae 100644 (file)
@@ -13,11 +13,43 @@ import java.util.*;
 public class ParseFailed extends Exception {
 
     private final Input.Location location;
+    private final Input.Region region;
+    private final Input input;
     private final String message;
-    ParseFailed() { this("", null); }
-    ParseFailed(String message, Input.Location loc) { this.location = loc; this.message = message; }
+    ParseFailed() { this("", null, null); }
+    ParseFailed(String message, Input.Region region, Input input) {
+        this.region = region;
+        this.location = region.getStart();
+        this.message = message;
+        this.input = input;
+    }
     public Input.Location getLocation() { return location; }
-    public String toString() { return message/* + (location==null ? "" : (" at " + location))*/; }
+    private Input.Region getRegion() { return region; }
+    public String toString() {
+        Input.Location before = getRegion().getStart();
+        for(int i=0; i<10; i++) before = before.prev() == null ? before : before.prev();
+        Input.Location after = getRegion().getEnd();
+        for(int i=0; i<10; i++) after = after.next() == null ? after : after.next();
+        StringBuilder ret = new StringBuilder();
+        ret.append(message);
+        ret.append('\n');
+        ret.append("      at: ");
+        ret.append(getRegion()+"");
+        if (input != null) {
+            ret.append('\n');
+            ret.append("    text: ");
+            String first = input.showRegion(before.createRegion(getRegion().getStart()));
+            ret.append(first);
+            String second = input.showRegion(getRegion());
+            ret.append(ANSI.red(second));
+            ret.append(input.showRegion(getRegion().getEnd().createRegion(after)));
+            ret.append('\n');
+            ret.append("          ");
+            for(int i=0; i<first.length(); i++) ret.append(' ');
+            for(int i=0; i<second.length(); i++) ret.append(ANSI.red("^"));
+        }
+        return ret.toString();
+    }
 
     // FIXME
     private static HashSet<GSS.Phase.Node> touched = new HashSet<GSS.Phase.Node>();