changeset 33:084c2c147c4f new_gen

Improvements to the Error class. * Now takes tokens instead of locations (a single loc can still be given) * Some of the arg functions take arrays now * Output is much better. Will print the line with all tokens given marked
author Anders Halager <halager@gmail.com>
date Sun, 20 Apr 2008 13:59:20 +0200
parents 7f4de5b5166c
children 371e8cfec764
files gen/LLVMGen.d misc/Error.d parser/Parser.d
diffstat 3 files changed, 114 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/gen/LLVMGen.d	Sun Apr 20 12:19:11 2008 +0200
+++ b/gen/LLVMGen.d	Sun Apr 20 13:59:20 2008 +0200
@@ -180,7 +180,7 @@
     struct PE
     {
         static char[] NoImplicitConversion =
-            "Can't find an implicit conversion between %1 and %2";
+            "Can't find an implicit conversion between %0 and %1";
     }
 
     void sextSmallerToLarger(ref Value left, ref Value right)
@@ -262,9 +262,9 @@
                     IntegerType v_t = cast(IntegerType) v.type;
                     IntegerType i_t = cast(IntegerType) t;
                     if (v_t is null || i_t is null)
-                        throw new Exception(
-                                "Inappropriate assignment"
-                                ", types dont match");
+                        throw error(__LINE__, PE.NoImplicitConversion)
+                            .arg(v.type.toString)
+                            .arg(t.toString);
                     if (v_t.numBits() < i_t.numBits())
                         v = b.buildSExt(v, t, ".cast");
                     else
@@ -404,7 +404,9 @@
             Stdout(v.type).newline;
             Stdout(t.type).newline;
             if (v_t is null || i_t is null)
-                throw error(__LINE__, "Inappropriate assignment, types don't match");
+                throw error(__LINE__, PE.NoImplicitConversion)
+                    .arg(a.elementType.toString)
+                    .arg(v.type.toString);
 
             if (v_t.numBits() < i_t.numBits())
                 v = b.buildSExt(v, t.type, ".cast");
--- a/misc/Error.d	Sun Apr 20 12:19:11 2008 +0200
+++ b/misc/Error.d	Sun Apr 20 13:59:20 2008 +0200
@@ -1,11 +1,12 @@
 module misc.Error;
 
 import tango.core.Exception,
-       tango.text.Util : layout;
+       Array = tango.core.Array,
+       tango.text.Util;
 
 import llvm.type;
 
-import misc.Location,
+import lexer.Token,
        sema.Symbol;
 
 class Error : Exception
@@ -21,10 +22,41 @@
     {
         char[256] tmp = void;
         char[] msg = layout(tmp, args);
-        if (locs.length > 0)
-            msg = locs[0].toString ~ ": " ~ msg;
+        if (location.source.name.length > 0)
+            msg = location.toString ~ ": " ~ msg;
         else
             msg = msg.dup;
+
+        if (toks.length > 0)
+        {
+            Array.sort(toks,
+                    (Token a, Token b)
+                    {
+                        return a.location.position - b.location.position;
+                    });
+            char[] data = toks[0].location.source.data;
+            size_t low    = toks[0].location.position;
+            size_t high   = toks[$ - 1].location.position;
+
+            size_t line_start = Array.rfind(data[0 .. low], '\n');
+            size_t line_end = high + Array.find(data[high .. $], '\n');
+            char[] line = trim(data[line_start + 1 .. line_end]);
+            char[] marks = line.dup;
+            marks[] = ' ';
+            foreach (tok; toks[0 .. $])
+            {
+                size_t p = tok.location.position - (line.ptr - data.ptr);
+                marks[p .. p + tok.length] = '~';
+            }
+            size_t p = main_tok.location.position - (line.ptr - data.ptr);
+            marks[p .. p + main_tok.length] = '^';
+
+            msg ~= "\n    ";
+            msg ~= line;
+            msg ~= "\n    ";
+            msg ~= marks;
+        }
+
         return msg;
     }
 
@@ -36,14 +68,33 @@
         return this;
     }
 
+    Error arg(char[][] s)
+    {
+        char[] res = s[0 .. $ - 1].join(", ");
+        res ~= " and ";
+        res ~= s[$ - 1];
+        return arg(res);
+    }
+
     Error arg(char c)
     {
         return arg([c]);
     }
 
-    Error arg(DType type)
+    Error arg(DType[] types)
     {
-        return arg(type.name());
+        char[][] res;
+        foreach (type; types)
+            res ~= type.name();
+        return arg(res);
+    }
+
+    Error arg(Tok[] toks...)
+    {
+        char[][] res;
+        foreach (t; toks)
+            res ~= typeToString[t];
+        return arg(res);
     }
 
     Error arg(Symbol sym)
@@ -53,11 +104,27 @@
 
     Error loc(Location loc)
     {
-        locs ~= loc;
+        location = loc;
+        return this;
+    }
+
+    Error tok(Token tok)
+    {
+        if (toks.length > 0)
+            assert(tok.location.source == toks[0].location.source,
+                    "Tokens must come from the same source");
+        else
+        {
+            main_tok = tok;
+            loc = tok.location;
+        }
+        toks ~= tok;
         return this;
     }
 
 private:
     char[][] args;
-    Location[] locs;
+    Location location;
+    Token[] toks;
+    Token main_tok;
 }
--- a/parser/Parser.d	Sun Apr 20 12:19:11 2008 +0200
+++ b/parser/Parser.d	Sun Apr 20 13:59:20 2008 +0200
@@ -69,13 +69,16 @@
                                 require(Tok.Seperator);
                                 return new VarDecl(type, identifier, exp);
                             default:
-                                char[] c = t.getType;
-                                throw error(__LINE__, "Unexpexted token %0").arg(c);
+                                char[] c = p.getType;
+                                throw error(__LINE__, UnexpextedTokMulti)
+                                    .tok(p)
+                                    .arg(c)
+                                    .arg(Tok.OpenParentheses, Tok.Seperator, Tok.Assign);
                         }
                         break;
                     default:
                         char[] c = t.getType;
-                        throw error(__LINE__, "Unexpexted token %0", &iden).arg(c);
+                        throw error(__LINE__, UnexpextedTok).tok(iden).arg(c);
                 }
                 break;
             case Tok.Struct:
@@ -93,7 +96,7 @@
                 return null;
             default:
                 char[] c = t.getType;
-                throw error(__LINE__, "Unexpexted token %0", &t).arg(c);
+                throw error(__LINE__, UnexpextedTok).tok(t).arg(c);
         }
     }
 
@@ -135,20 +138,26 @@
                                 require(Tok.Seperator);
                                 return new VarDecl(type, identifier, exp);
                             default:
-                                char[] c = t.getType;
-                                throw error(__LINE__, "Unexpexted token %0").arg(c);
+                                char[] c = p.getType;
+                                throw error(__LINE__, UnexpextedTokMulti)
+                                    .tok(p)
+                                    .arg(c)
+                                    .arg(Tok.OpenParentheses, Tok.Seperator, Tok.Assign);
                         }
                         break;
                     default:
-                        char[] c = t.getType;
-                        throw error(__LINE__, "Unexpexted token %0").arg(c);
+                        char[] c = iden.getType;
+                        throw error(__LINE__, UnexpextedTokSingle)
+                            .tok(iden)
+                            .arg(c)
+                            .arg(Tok.Identifier);
                 }
                 break;
             case Tok.EOF:
                 return null;
             default:
                 char[] c = t.getType;
-                throw error(__LINE__, "Unexpexted token %0").arg(c);
+                throw error(__LINE__, UnexpextedTok).arg(c);
         }
     }
 
@@ -293,7 +302,7 @@
             default:
                 throw error(__LINE__, "Unexpexted token in Identifier parsing. Got %0")
                     .arg(identifier.getType)
-                    .loc(identifier.location);
+                    .tok(identifier);
         }
     }
 
@@ -466,9 +475,9 @@
     void require(Tok t)
     {
         if (lexer.peek().type != t)
-            error(__LINE__, "Unexpexted token: Got '%0' Expected '%1'")
+            error(__LINE__, UnexpextedTokSingle)
                 .arg(lexer.peek.getType)
-                .arg(typeToString[t]);
+                .arg(t);
         lexer.next();
     }
 
@@ -479,11 +488,18 @@
             loc = lexer.peek.location;
         else
             loc = tok.location;
-        return
-            (new Error
-             ("Parser.d(" ~ Integer.toString(line) ~ "): " ~errMsg))
-            .loc(loc);
+        auto e =
+            new Error("Parser.d(" ~ Integer.toString(line) ~ "): " ~errMsg);
+            e.loc(loc);
+            if (tok !is null)
+                e.tok(*tok);
+            return e;
     }
 
+    static char[]
+        UnexpextedTokMulti = "Unexpexted token, got %0 expected one of %1",
+        UnexpextedTokSingle = "Unexpexted token, got %0 expected %1",
+        UnexpextedTok = "Unexpexted token %0";
+
     Lexer lexer;
 }