diff src/basic/Message.d @ 206:d3c148ca429b

Major moving of files. all src now goes into src, all docs in docs.
author Anders Johnsen <skabet@gmail.com>
date Tue, 12 Aug 2008 18:14:56 +0200
parents
children e0551773a005
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/basic/Message.d	Tue Aug 12 18:14:56 2008 +0200
@@ -0,0 +1,163 @@
+module basic.Message;
+
+import tango.core.Exception,
+       Array = tango.core.Array,
+       tango.io.Stdout,
+       tango.text.Util;
+
+import tango.stdc.stdlib;
+
+import llvm.type;
+
+import lexer.Token,
+       lexer.Lexer;
+
+import basic.SourceLocation,
+       basic.SourceManager;
+
+public import basic.Messages;
+
+enum ExitLevel
+{
+    Normal = 1,
+    Lexer = 2,
+    Parser = 3,
+    Semantic = 3,
+}
+
+class MessageHandler
+{
+public:
+
+    this(SourceManager src_mgr)
+    {
+        this.src_mgr = src_mgr;
+    }
+
+    Message report(uint opcode, SLoc location)
+    {
+        Message m = new Message(opcode, location, src_mgr, this);
+        messages ~= m;
+        return m;
+    }
+
+    void checkErrors(ExitLevel exitlevel = ExitLevel.Normal)
+    {
+        if(messages.length == 0)
+            return;
+
+        if(warnings)
+            checkWarnings;
+        foreach(m ; messages)
+            if(m.type == MessageType.Error)
+            {
+                Stdout(m).newline;
+            }
+
+        exit(exitlevel);
+    }
+
+    void checkWarnings()
+    {
+        foreach(m ; messages)
+            if(m.type == MessageType.Warning)
+            {
+                Stdout(m).newline;
+            }
+    }
+
+    void showWarnings(bool value)
+    {
+        warnings = value;
+    }
+
+private:
+    Message[] messages;
+    SourceManager src_mgr;
+    bool warnings;
+}
+
+class Message
+{
+
+    this(int opcode, SLoc location, SourceManager src_mgr, MessageHandler msg_handler)
+    {
+        this.src_mgr = src_mgr;
+        this.location = location;
+        args ~= Messages[opcode].message;
+        this.type = Messages[opcode].type;
+        this.msg_handler = msg_handler;
+    }
+
+    char[] toString()
+    {
+        char[256] tmp = void;
+        char[] msg = layout(tmp, args);
+
+        Lexer l = new Lexer(location, src_mgr, new MessageHandler(src_mgr));
+
+        Token t = l.next;
+        
+        if (src_mgr.getRawData(location).length > 0)
+            msg = src_mgr.getLocationAsString(location) ~ ": " ~ msg;
+        else
+            msg = msg.dup;
+
+
+        char[] line = src_mgr.getLine(location);
+        char[] marks = line.dup;
+        marks[] = ' ';
+        size_t p = src_mgr.getColumn(location);
+        marks[p .. p + t.length] = '^';
+
+        msg ~= "\n    ";
+        msg ~= line;
+        msg ~= "\n    ";
+        msg ~= marks;
+
+        return msg;
+    }
+
+    Message arg(char[] s)
+    {
+        if (args.length == 11)
+            throw new Exception("Sorry, errors only support up to 10 args");
+        args ~= s;
+        return this;
+    }
+
+    Message arg(char[][] s)
+    {
+        char[] res = s[0 .. $ - 1].join(", ");
+        if (s.length > 1)
+            res ~= " and ";
+        res ~= s[$ - 1];
+        return arg(res);
+    }
+
+    Message arg(char c)
+    {
+        return arg([c]);
+    }
+
+    Message fatal(ExitLevel exitlevel = ExitLevel.Normal)
+    {
+        msg_handler.checkErrors(exitlevel);
+        return this;
+    }
+
+    /*
+    Message loc(SLoc loc)
+    {
+        location = loc;
+        return this;
+    }
+    */
+
+    MessageType type;
+private:
+    char[][] args;
+    SLoc location;
+    SourceManager src_mgr;
+    MessageHandler msg_handler;
+}