diff options
author | Araq <rumpf_a@web.de> | 2011-02-12 19:24:20 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2011-02-12 19:24:20 +0100 |
commit | 5b28d08203ba36e84c8e381761db182c0393d07f (patch) | |
tree | 9f1fdcb65d8617b65672305327a208bb030405c7 /rod/msgs.nim | |
parent | 27dc54cbda0beffe8bca36d9cc59cccaf0b2d30f (diff) | |
download | Nim-5b28d08203ba36e84c8e381761db182c0393d07f.tar.gz |
non-nil AST; continue after errors for IDE support
Diffstat (limited to 'rod/msgs.nim')
-rwxr-xr-x | rod/msgs.nim | 147 |
1 files changed, 72 insertions, 75 deletions
diff --git a/rod/msgs.nim b/rod/msgs.nim index a3e9c1211..dd7fea4cc 100755 --- a/rod/msgs.nim +++ b/rod/msgs.nim @@ -343,7 +343,6 @@ const "RedefinitionOfLabel", "UnknownSubstitutionX", "LanguageXNotSupported", "CommentXIgnored", "XisPassedToProcVar", "User"] -const HintsToStr*: array[0..13, string] = ["Success", "SuccessX", "LineTooLong", "XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded", "ExprAlwaysX", "QuitCalled", "Processing", "CodeBegin", "CodeEnd", "Conf", @@ -371,19 +370,20 @@ type # only 8 bytes. line*, col*: int16 fileIndex*: int32 + + ERecoverableError* = object of EInvalidValue -proc UnknownLineInfo*(): TLineInfo - -var +var gNotes*: TNoteKinds = {low(TNoteKind)..high(TNoteKind)} gErrorCounter*: int = 0 # counts the number of errors gHintCounter*: int = 0 gWarnCounter*: int = 0 gErrorMax*: int = 1 # stop after gErrorMax errors -const # this format is understood by many text editors: it is the same that - # Borland and Freepascal use +# this format is understood by many text editors: it is the same that +# Borland and Freepascal use +const PosErrorFormat* = "$1($2, $3) Error: $4" PosWarningFormat* = "$1($2, $3) Warning: $4" PosHintFormat* = "$1($2, $3) Hint: $4" @@ -391,47 +391,22 @@ const # this format is understood by many text editors: it is the same that RawWarningFormat* = "Warning: $1" RawHintFormat* = "Hint: $1" -proc MessageOut*(s: string) -proc rawMessage*(msg: TMsgKind, arg: string) -proc rawMessage*(msg: TMsgKind, args: openarray[string]) -proc liMessage*(info: TLineInfo, msg: TMsgKind, arg: string = "") -proc InternalError*(info: TLineInfo, errMsg: string) -proc InternalError*(errMsg: string) -proc newLineInfo*(filename: string, line, col: int): TLineInfo -proc ToFilename*(info: TLineInfo): string -proc toColumn*(info: TLineInfo): int -proc ToLinenumber*(info: TLineInfo): int -proc MsgKindToString*(kind: TMsgKind): string - # checkpoints are used for debugging: -proc checkpoint*(info: TLineInfo, filename: string, line: int): bool -proc addCheckpoint*(info: TLineInfo) -proc addCheckpoint*(filename: string, line: int) -proc inCheckpoint*(current: TLineInfo): bool - # prints the line information if in checkpoint -proc pushInfoContext*(info: TLineInfo) -proc popInfoContext*() -proc includeFilename*(f: string): int -# implementation - -proc UnknownLineInfo(): TLineInfo = - result.line = int16(- 1) - result.col = int16(- 1) - result.fileIndex = - 1 +proc UnknownLineInfo*(): TLineInfo = + result.line = int16(-1) + result.col = int16(-1) + result.fileIndex = -1 var filenames: seq[string] = @ [] msgContext: seq[TLineInfo] = @ [] -proc pushInfoContext(info: TLineInfo) = - var length: int - length = len(msgContext) - setlen(msgContext, length + 1) - msgContext[length] = info - -proc popInfoContext() = +proc pushInfoContext*(info: TLineInfo) = + msgContext.add(info) + +proc popInfoContext*() = setlen(msgContext, len(msgContext) - 1) -proc includeFilename(f: string): int = +proc includeFilename*(f: string): int = for i in countdown(high(filenames), low(filenames)): if filenames[i] == f: return i @@ -439,53 +414,51 @@ proc includeFilename(f: string): int = setlen(filenames, result + 1) filenames[result] = f -proc checkpoint(info: TLineInfo, filename: string, line: int): bool = - result = (int(info.line) == line) and - (ChangeFileExt(extractFilename(filenames[info.fileIndex]), "") == - filename) - -var checkPoints: seq[TLineInfo] = @[] - -proc addCheckpoint(info: TLineInfo) = - var length: int - length = len(checkPoints) - setlen(checkPoints, length + 1) - checkPoints[length] = info - -proc addCheckpoint(filename: string, line: int) = - addCheckpoint(newLineInfo(filename, line, - 1)) - -proc newLineInfo(filename: string, line, col: int): TLineInfo = +proc newLineInfo*(filename: string, line, col: int): TLineInfo = result.fileIndex = includeFilename(filename) result.line = int16(line) result.col = int16(col) -proc ToFilename(info: TLineInfo): string = +proc ToFilename*(info: TLineInfo): string = if info.fileIndex == - 1: result = "???" else: result = filenames[info.fileIndex] -proc ToLinenumber(info: TLineInfo): int = +proc ToLinenumber*(info: TLineInfo): int = result = info.line -proc toColumn(info: TLineInfo): int = +proc toColumn*(info: TLineInfo): int = result = info.col -proc MessageOut(s: string) = +proc checkpoint*(info: TLineInfo, filename: string, line: int): bool = + result = (int(info.line) == line) and + (ChangeFileExt(extractFilename(filenames[info.fileIndex]), "") == + filename) + +var checkPoints: seq[TLineInfo] = @[] + +proc addCheckpoint*(info: TLineInfo) = + checkPoints.add(info) + +proc addCheckpoint*(filename: string, line: int) = + addCheckpoint(newLineInfo(filename, line, - 1)) + +proc MessageOut*(s: string) = # change only this proc to put it elsewhere Writeln(stdout, s) proc coordToStr(coord: int): string = - if coord == - 1: result = "???" - else: result = $(coord) + if coord == -1: result = "???" + else: result = $coord -proc MsgKindToString(kind: TMsgKind): string = +proc MsgKindToString*(kind: TMsgKind): string = # later versions may provide translated error messages result = msgKindToStr[kind] proc getMessageStr(msg: TMsgKind, arg: string): string = result = `%`(msgKindToString(msg), [arg]) -proc inCheckpoint(current: TLineInfo): bool = +proc inCheckpoint*(current: TLineInfo): bool = + ## prints the line information if in checkpoint result = false if not (optCheckpoints in gOptions): return # ignore all checkpoints @@ -496,7 +469,10 @@ proc inCheckpoint(current: TLineInfo): bool = coordToStr(current.line), coordToStr(current.col)])) return true -proc handleError(msg: TMsgKind) = +type + TErrorHandling = enum doNothing, doAbort, doRaise + +proc handleError(msg: TMsgKind, eh: TErrorHandling) = if msg == errInternal: assert(false) # we want a stack trace here if (msg >= fatalMin) and (msg <= fatalMax): @@ -504,9 +480,12 @@ proc handleError(msg: TMsgKind) = quit(1) if (msg >= errMin) and (msg <= errMax): inc(gErrorCounter) - if gErrorCounter >= gErrorMax: + options.gExitcode = 1'i8 + if gErrorCounter >= gErrorMax or eh == doAbort: if gVerbosity >= 3: assert(false) quit(1) # one error stops the compiler + elif eh == doRaise: + raise newException(ERecoverableError, "") proc sameLineInfo(a, b: TLineInfo): bool = result = (a.line == b.line) and (a.fileIndex == b.fileIndex) @@ -523,7 +502,7 @@ proc writeContext(lastinfo: TLineInfo) = getMessageStr(errInstantiationFrom, "")])) info = msgContext[i] -proc rawMessage(msg: TMsgKind, args: openarray[string]) = +proc rawMessage*(msg: TMsgKind, args: openarray[string]) = var frmt: string case msg of errMin..errMax: @@ -542,12 +521,13 @@ proc rawMessage(msg: TMsgKind, args: openarray[string]) = else: assert(false) # cannot happen MessageOut(`%`(frmt, `%`(msgKindToString(msg), args))) - handleError(msg) + handleError(msg, doAbort) -proc rawMessage(msg: TMsgKind, arg: string) = +proc rawMessage*(msg: TMsgKind, arg: string) = rawMessage(msg, [arg]) -proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string = "") = +proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string, + eh: TErrorHandling) = var frmt: string case msg of errMin..errMax: @@ -567,12 +547,29 @@ proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string = "") = assert(false) # cannot happen MessageOut(`%`(frmt, [toFilename(info), coordToStr(info.line), coordToStr(info.col), getMessageStr(msg, arg)])) - handleError(msg) + handleError(msg, doAbort) + +proc Fatal*(info: TLineInfo, msg: TMsgKind, arg = "") = + liMessage(info, msg, arg, doAbort) + +proc GlobalError*(info: TLineInfo, msg: TMsgKind, arg = "") = + liMessage(info, msg, arg, doRaise) + +proc LocalError*(info: TLineInfo, msg: TMsgKind, arg = "") = + liMessage(info, msg, arg, doNothing) + +proc Message*(info: TLineInfo, msg: TMsgKind, arg = "") = + liMessage(info, msg, arg, doNothing) + +proc GenericMessage*(info: TLineInfo, msg: TMsgKind, arg = "") = + ## does the right thing for old code that is written with "abort on first + ## error" in mind. + liMessage(info, msg, arg, doAbort) -proc InternalError(info: TLineInfo, errMsg: string) = +proc InternalError*(info: TLineInfo, errMsg: string) = writeContext(info) - liMessage(info, errInternal, errMsg) + liMessage(info, errInternal, errMsg, doAbort) -proc InternalError(errMsg: string) = +proc InternalError*(errMsg: string) = writeContext(UnknownLineInfo()) rawMessage(errInternal, errMsg) |