view 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 source

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;
}