Mercurial > projects > dang
view misc/Error.d @ 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 | 41d23f2762c3 |
children | ce17bea8e9bd |
line wrap: on
line source
module misc.Error; import tango.core.Exception, Array = tango.core.Array, tango.text.Util; import llvm.type; import lexer.Token, sema.Symbol; class Error : Exception { this(char[] message) { super(message); args ~= message; } char[] toString() { char[256] tmp = void; char[] msg = layout(tmp, args); 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; } Error arg(char[] s) { if (args.length == 11) throw new Exception("Sorry, errors only support up to 10 args"); args ~= s; 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[] types) { 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) { return arg(sym.type.name ~ " " ~ sym.id.get); } Error loc(Location 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 location; Token[] toks; Token main_tok; }