Mercurial > projects > dil
diff trunk/src/dil/Information.d @ 422:ad7977fe315a
Added support for column numbers in error messages.
Moved class Location to module Information.
In class Lexer:
Renamed p_newl to beginLine.
Added member errorLoc.
Renamed fileName to filePath.
Tidied up the code and reordered some methods.
Renamed set_p_newl() to setLineBegin().
All other modifications are pretty much self-explanatory.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Sun, 30 Sep 2007 15:20:35 +0200 |
parents | 33b566df6af4 |
children | bb3cb00feeb2 |
line wrap: on
line diff
--- a/trunk/src/dil/Information.d Sat Sep 29 14:26:14 2007 +0200 +++ b/trunk/src/dil/Information.d Sun Sep 30 15:20:35 2007 +0200 @@ -17,14 +17,16 @@ { MID id; InfoType type; - uint loc; + Location location; + uint column; string message; - this(InfoType type, MID id, uint loc, string message) + this(InfoType type, MID id, Location location, string message) { + assert(location !is null); this.id = id; this.type = type; - this.loc = loc; + this.location = location; this.message = message; } @@ -32,4 +34,104 @@ { return this.message; } + + size_t loc() + { + return location.lineNum; + } + + size_t col() + { + if (column == 0) + column = location.calculateColumn(); + return column; + } + + string filePath() + { + return location.filePath; + } } + +final class Location +{ + char[] filePath; + size_t lineNum; + char* lineBegin, to; // Used to calculate column. + + this(char[] filePath, size_t lineNum) + { + set(filePath, lineNum); + } + + this(char[] filePath, size_t lineNum, char* lineBegin, char* to) + { + set(filePath, lineNum, lineBegin, to); + } + + Location clone() + { + return new Location(filePath, lineNum, lineBegin, to); + } + + void set(char[] filePath, size_t lineNum) + { + set(filePath, lineNum, null, null); + } + + void set(char[] filePath, size_t lineNum, char* lineBegin, char* to) + { + this.filePath = filePath; + set(lineNum, lineBegin, to); + } + + void set(size_t lineNum, char* lineBegin, char* to) + { + assert(lineBegin <= to); + this.lineNum = lineNum; + this.lineBegin = lineBegin; + this.to = to; + } + + void setFilePath(char[] filePath) + { + this.filePath = filePath; + } + + /+ + This is a primitive method to count the number of characters in a string. + Unicode compound characters and other special characters are not + taken into account. + +/ + uint calculateColumn() + { + uint col; + auto p = lineBegin; + for (; p <= to; ++p) + { + assert(delegate () + { + const char[3] LS = \u2028; + const char[3] PS = \u2029; + // Check that there is no newline between p and to. + // But 'to' may point to a newline. + if (p != to && (*p == '\n' || *p == '\r')) + return false; + if (to-p >= 2) + { + if (*p == LS[0] && p[1] == LS[1] && (p[2] == LS[2] || p[2] == PS[2])) + return false; + } + return true; + }() == true + ); + + // Skip this byte if it is a trail byte of a UTF-8 sequence. + if (*p & 0x80 && !(*p & 0x40)) + continue; // *p == 0b10xx_xxxx + // Only count ASCII characters and the first byte of a UTF-8 sequence. + ++col; + } + return col; + } +}