changeset 29:41d23f2762c3 new_gen

Merge, and updated Error class Usage is something like: --- auto e = new Error("No conversion between %0 and %1); e.arg(t1).arg(t2); e.loc(exp.location); --- Multiple locations can be given, to do clang like errors in the future
author Anders Halager <halager@gmail.com>
date Sun, 20 Apr 2008 11:47:34 +0200
parents 69464d465284
children 3147a52d1247
files gen/LLVMGen.d lexer/Lexer.d misc/Error.d misc/Location.d parser/Parser.d sema/Declarations.d
diffstat 6 files changed, 121 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/gen/LLVMGen.d	Sun Apr 20 11:20:28 2008 +0200
+++ b/gen/LLVMGen.d	Sun Apr 20 11:47:34 2008 +0200
@@ -10,6 +10,8 @@
        ast.Stmt,
        ast.Exp;
 
+import misc.Error;
+
 import lexer.Token;
 
 import sema.SymbolTableBuilder,
@@ -175,6 +177,12 @@
         }
     }
 
+    struct PE
+    {
+        static char[] NoImplicitConversion =
+            "Can't find an implicit conversion between %1 and %2";
+    }
+
     void sextSmallerToLarger(ref Value left, ref Value right)
     {
         if (left.type != right.type)
@@ -183,10 +191,9 @@
             IntegerType l = cast(IntegerType) left.type;
             IntegerType r = cast(IntegerType) right.type;
             if (l is null || r is null)
-                throw new Exception(
-                        "Can't find a valid convertion between "
-                        "a " ~ left.type.toString ~ " and a "
-                        ~ right.type.toString);
+                throw error(__LINE__, PE.NoImplicitConversion)
+                    .arg(left.type.toString)
+                    .arg(right.type.toString);
 
             if (l.numBits() < r.numBits())
                 left = b.buildSExt(left, r, ".cast");
@@ -393,8 +400,7 @@
             Stdout(v.type).newline;
             Stdout(t.type).newline;
             if (v_t is null || i_t is null)
-                throw new Exception(
-                        "Inappropriate assignment, types don't match");
+                throw error(__LINE__, "Inappropriate assignment, types don't match");
 
             if (v_t.numBits() < i_t.numBits())
                 v = b.buildSExt(v, t.type, ".cast");
@@ -404,6 +410,11 @@
         return b.buildStore(v, t);
     }
 
+    Error error(uint line, char[] msg)
+    {
+        return new Error(msg);
+    }
+
 private:
 
     // llvm stuff
--- a/lexer/Lexer.d	Sun Apr 20 11:20:28 2008 +0200
+++ b/lexer/Lexer.d	Sun Apr 20 11:47:34 2008 +0200
@@ -127,8 +127,7 @@
                                 if(source.data[position-1] == '/')
                                    return this.next;
                         }
-                        throw new Error("Unexpected end of file. Unclosed comment block", 
-                                Location(position, source));
+                        throw error(__LINE__, "Unexpected end of file. Unclosed comment block");
 
                     case '+':
                         position += 2;
@@ -153,8 +152,7 @@
                             if(nesting == 0)
                                 return this.next;
                         }
-                        throw new Error("Unexpected end of file. Unclosed comment block", 
-                                Location(position, source));
+                        throw error(__LINE__, "Unexpected end of file. Unclosed comment block");
 
                     default:
                         return Token(Tok.Div, Location(position - 1, this.source), 1);
@@ -227,11 +225,16 @@
                 return CharType.Symbol;
 
             default:
-                throw new Error("Read invalid symbol: '" ~ current ~ "'", Location(position, source));
+                throw error(__LINE__, "Read invalid symbol: '%0'").arg(current);
         }
 
     }
 
+    Error error(uint line, char[] msg)
+    {
+        return (new Error(msg)).loc(Location(position, source));
+    }
+
     DataSource source;
     int position;
     Error[] errors;
--- a/misc/Error.d	Sun Apr 20 11:20:28 2008 +0200
+++ b/misc/Error.d	Sun Apr 20 11:47:34 2008 +0200
@@ -1,18 +1,63 @@
 module misc.Error;
 
-import misc.Location;
+import tango.core.Exception,
+       tango.text.Util : layout;
 
-import tango.core.Exception;
+import llvm.type;
+
+import misc.Location,
+       sema.Symbol;
 
 class Error : Exception
 {
-    char[] message;
-    Location errorLocation;
+
+    this(char[] message)
+    {
+        super(message);
+        args ~= message;
+    }
 
-    this(char[] message, Location errorLocation)
+    char[] toString()
+    {
+        char[256] tmp = void;
+        char[] msg = layout(tmp, args);
+        if (locs.length > 0)
+            msg = locs[0].toString ~ ": " ~ msg;
+        else
+            msg = msg.dup;
+        return msg;
+    }
+
+    Error arg(char[] s)
     {
-        super(errorLocation.toString ~ " " ~ message);
-        this.message = message;
-        this.errorLocation = errorLocation;
+        if (args.length == 11)
+            throw new Exception("Sorry, errors only support up to 10 args");
+        args ~= s;
+        return this;
+    }
+
+    Error arg(char c)
+    {
+        return arg([c]);
+    }
+
+    Error arg(DType type)
+    {
+        return arg(type.name());
     }
+
+    Error arg(Symbol sym)
+    {
+        return arg(sym.type.name ~ " " ~ sym.id.get);
+    }
+
+    Error loc(Location loc)
+    {
+        locs ~= loc;
+        return this;
+    }
+
+private:
+    char[][] args;
+    Location[] locs;
 }
--- a/misc/Location.d	Sun Apr 20 11:20:28 2008 +0200
+++ b/misc/Location.d	Sun Apr 20 11:47:34 2008 +0200
@@ -2,7 +2,7 @@
 
 import misc.DataSource;
 
-import Integer = tango.text.convert.Integer,
+import tango.text.convert.Integer,
        tango.text.Util;
 
 struct Location
@@ -12,8 +12,16 @@
 
     char[] toString ()
     {
-        int lineNumber = split(source.get(0, position), "\n").length;
-        return source.name ~ ":" ~ Integer.toString(lineNumber);
+        int lineNumber = 0;
+        char[] end_line;
+        foreach (line; lines(source.get(0, position)))
+        {
+            ++lineNumber;
+            end_line = line;
+        }
+        return source.name
+            ~ "(" ~ .toString(lineNumber)
+            ~ ":" ~ .toString(end_line.length) ~ ")";
     }
 
     char[] get(uint length)
--- a/parser/Parser.d	Sun Apr 20 11:20:28 2008 +0200
+++ b/parser/Parser.d	Sun Apr 20 11:47:34 2008 +0200
@@ -70,12 +70,12 @@
                                 return new VarDecl(type, identifier, exp);
                             default:
                                 char[] c = t.getType;
-                                error("Unexpexted token "~c~" at line "~Integer.toString(__LINE__));
+                                error(__LINE__, "Unexpexted token %0").arg(c);
                         }
                         break;
                     default:
                         char[] c = t.getType;
-                        error("Unexpexted token "~c~" at line "~Integer.toString(__LINE__));
+                        error(__LINE__, "Unexpexted token %0", &iden).arg(c);
                 }
                 break;
             case Tok.Struct:
@@ -87,14 +87,13 @@
                         Identifier identifier = new Identifier(iden);
                         return new StructDecl (identifier, parseStruct());
                     default:
-                        throw new Error("Expected struct identifier, but got "~iden.getType, 
-                            iden.location);
+                        throw error(__LINE__, "Expected struct identifier, but got %0").arg(iden.getType);
                 }
             case Tok.EOF:
                 return null;
             default:
                 char[] c = t.getType;
-                error("Unexpexted token "~c~" at line "~Integer.toString(__LINE__));
+                throw error(__LINE__, "Unexpexted token %0", &t).arg(c);
         }
     }
 
@@ -292,7 +291,9 @@
                 return new Identifier(identifier);
                 break;
             default:
-                throw new Error("Unexpexted token in Identifier parsing. Got "~identifier.getType, identifier.location);
+                throw error(__LINE__, "Unexpexted token in Identifier parsing. Got %0")
+                    .arg(identifier.getType)
+                    .loc(identifier.location);
         }
     }
 
@@ -313,7 +314,7 @@
                 break;
             default:
                 char[] c = type.getType;
-                error("Unexpexted token in Type parsing. Got "~c);
+                error(__LINE__, "Unexpexted token in Type parsing. Got %0").arg(c);
         }
     }
 
@@ -464,13 +465,23 @@
     void require(Tok t)
     {
         if (lexer.peek().type != t)
-            error("Unexpexted token: Got '"~lexer.peek.getType~"' Expected '"~typeToString[t]~"'");
+            error(__LINE__, "Unexpexted token: Got '%0' Expected '%1'")
+                .arg(lexer.peek.getType)
+                .arg(typeToString[t]);
         lexer.next();
     }
 
-    void error(char[] errMsg)
+    Error error(uint line, char[] errMsg, Token* tok = null)
     {
-        throw new Exception("Parser error: " ~errMsg);
+        Location loc;
+        if (tok is null)
+            loc = lexer.peek.location;
+        else
+            loc = tok.location;
+        return
+            (new Error
+             ("Parser.d(" ~ Integer.toString(line) ~ "): " ~errMsg))
+            .loc(loc);
     }
 
     Lexer lexer;
--- a/sema/Declarations.d	Sun Apr 20 11:20:28 2008 +0200
+++ b/sema/Declarations.d	Sun Apr 20 11:47:34 2008 +0200
@@ -11,19 +11,27 @@
 {
     int[char[]] types;
 
+    private Error error(uint line, char[] msg)
+    {
+        return new Error(msg);
+    }
+
     override void visitIdentifier(Identifier i)
     {
         auto symbol = i.env.find(i);
 
         if(symbol is null)
-            throw new Error("Undefined identifier: '"~i.get~"'",i.token.location);
-
+            throw error(__LINE__, "Undefined identifier: '%0'")
+                .arg(i.get)
+                .loc(i.token.location);
     }
 
     override void visitVarDecl(VarDecl d)
     {
         if(!d.env.findType(d.type))
-            throw new Error("Undefined type: '"~d.type.get~"'",d.type.token.location);
+            throw error(__LINE__, "Undefined type: '%0'")
+                .arg(d.type.get)
+                .loc(d.type.token.location);
 
         visitExp(d.identifier);
         if (d.init)