basic continue after error works; interactive mode more useful

This commit is contained in:
Araq
2011-02-13 03:39:11 +01:00
parent 5b28d08203
commit 627e192f64
12 changed files with 58 additions and 40 deletions

View File

@@ -37,7 +37,7 @@ Installation on the Macintosh
Only MacOS X is supported.
Since MacOS X is UNIX based too, it works like the installation on Linux.
However, for unknown reasons the symbolic link method does not work MacOS X.
However, for unknown reasons the symbolic link method does not work on MacOS X.
You need to install Apple's developer's tools for the GNU Compiler Collection.

View File

@@ -747,7 +747,7 @@ proc compileOption*(option, arg: string): bool {.
include "system/inclrtl"
when not defined(ecmascript):
when not defined(ecmascript) and not defined(nimrodVm):
include "system/cgprocs"
proc add *[T](x: var seq[T], y: T) {.magic: "AppendSeqElem", noSideEffect.}
@@ -1334,10 +1334,6 @@ proc quit*(errorcode: int = QuitSuccess) {.
## It does *not* call the garbage collector to free all the memory,
## unless a quit procedure calls ``GC_collect``.
when not defined(EcmaScript) and not defined(NimrodVM):
proc quit*(errormsg: string) {.noReturn.}
## a shorthand for ``echo(errormsg); quit(quitFailure)``.
when not defined(EcmaScript) and not defined(NimrodVM):
proc atomicInc*(memLoc: var int, x: int): int {.inline.}
@@ -1558,10 +1554,6 @@ when not defined(EcmaScript) and not defined(NimrodVM):
## returns the OS file handle of the file ``f``. This is only useful for
## platform specific programming.
proc quit(errormsg: string) =
echo(errormsg)
quit(quitFailure)
proc cstringArrayToSeq*(a: cstringArray, len: int): seq[string] =
## converts a ``cstringArray`` to a ``seq[string]``. `a` is supposed to be
## of length ``len``.
@@ -1669,5 +1661,10 @@ elif defined(ecmaScript) or defined(NimrodVM):
if x < y: return -1
return 1
proc quit*(errormsg: string) {.noReturn.} =
## a shorthand for ``echo(errormsg); quit(quitFailure)``.
echo(errormsg)
quit(quitFailure)
{.pop.} # checks
{.pop.} # hints

View File

@@ -56,7 +56,9 @@ var
gOutOfMem: ref EOutOfMemory
proc raiseOutOfMem() {.noreturn.} =
if gOutOfMem == nil: quit("out of memory; cannot even throw an exception")
if gOutOfMem == nil:
echo("out of memory; cannot even throw an exception")
quit(1)
gOutOfMem.msg = "out of memory"
raise gOutOfMem

View File

@@ -75,11 +75,12 @@ proc popStackFrame(c: PEvalContext) =
proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode
proc stackTraceAux(x: PStackFrame) =
if x != nil:
proc stackTraceAux(x: PStackFrame) =
if x != nil:
stackTraceAux(x.next)
var info = if x.call != nil: x.call.info else: UnknownLineInfo()
messageOut(`%`("file: $1, line: $2",
[toFilename(x.call.info), $(toLineNumber(x.call.info))]))
[toFilename(info), $(toLineNumber(info))]))
proc stackTrace(c: PEvalContext, n: PNode, msg: TMsgKind, arg: string = "") =
messageOut("stack trace: (most recent call last)")

View File

@@ -23,6 +23,7 @@ type
f*: tfile
s*: string
rd*, wr*: int # for string streams
lineOffset*: int # for fake stdin line numbers
PLLStream* = ref TLLStream
@@ -65,6 +66,7 @@ proc LLStreamOpenStdIn(): PLLStream =
new(result)
result.kind = llsStdIn
result.s = ""
result.lineOffset = -1
proc LLStreamClose(s: PLLStream) =
case s.kind
@@ -85,7 +87,8 @@ proc LLreadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int =
L = len(line)
add(s.s, line)
add(s.s, "\n")
if (L > 0) and (line[L - 1 + 0] == '#'): break
if (L > 0) and (line[L - 1 + 0] == '#'): break
inc(s.lineOffset)
result = min(bufLen, len(s.s) - s.rd)
if result > 0:
copyMem(buf, addr(s.s[0 + s.rd]), result)

View File

@@ -139,6 +139,7 @@ proc CommandCompileToEcmaScript(filename: string) =
compileProject(filename)
proc CommandInteractive() =
msgs.gErrorMax = high(int) # do not stop after first error
incl(gGlobalOptions, optSafeCode)
setTarget(osNimrodVM, cpuNimrodVM)
initDefines()

View File

@@ -373,6 +373,8 @@ type
ERecoverableError* = object of EInvalidValue
proc raiseRecoverableError*() {.noinline, noreturn.} =
raise newException(ERecoverableError, "")
var
gNotes*: TNoteKinds = {low(TNoteKind)..high(TNoteKind)}
@@ -485,7 +487,7 @@ proc handleError(msg: TMsgKind, eh: TErrorHandling) =
if gVerbosity >= 3: assert(false)
quit(1) # one error stops the compiler
elif eh == doRaise:
raise newException(ERecoverableError, "")
raiseRecoverableError()
proc sameLineInfo(a, b: TLineInfo): bool =
result = (a.line == b.line) and (a.fileIndex == b.fileIndex)
@@ -518,36 +520,39 @@ proc rawMessage*(msg: TMsgKind, args: openarray[string]) =
if not (msg in gNotes): return
frmt = rawHintFormat
inc(gHintCounter)
else:
assert(false) # cannot happen
MessageOut(`%`(frmt, `%`(msgKindToString(msg), args)))
handleError(msg, doAbort)
proc rawMessage*(msg: TMsgKind, arg: string) =
rawMessage(msg, [arg])
var
lastError = UnknownLineInfo()
proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string,
eh: TErrorHandling) =
var frmt: string
var ignoreMsg = false
case msg
of errMin..errMax:
writeContext(info)
frmt = posErrorFormat
# we try to filter error messages so that not two error message
# in the same file and line are produced:
ignoreMsg = sameLineInfo(lastError, info)
lastError = info
of warnMin..warnMax:
if not (optWarns in gOptions): return
if not (msg in gNotes): return
ignoreMsg = optWarns notin gOptions or msg notin gNotes
frmt = posWarningFormat
inc(gWarnCounter)
of hintMin..hintMax:
if not (optHints in gOptions): return
if not (msg in gNotes): return
ignoreMsg = optHints notin gOptions or msg notin gNotes
frmt = posHintFormat
inc(gHintCounter)
else:
assert(false) # cannot happen
MessageOut(`%`(frmt, [toFilename(info), coordToStr(info.line),
coordToStr(info.col), getMessageStr(msg, arg)]))
handleError(msg, doAbort)
if not ignoreMsg:
MessageOut(frmt % [toFilename(info), coordToStr(info.line),
coordToStr(info.col), getMessageStr(msg, arg)])
handleError(msg, eh)
proc Fatal*(info: TLineInfo, msg: TMsgKind, arg = "") =
liMessage(info, msg, arg, doAbort)

View File

@@ -68,17 +68,18 @@ proc HandleCmdLine() =
ProcessCmdLine(passCmd2, command, filename)
MainCommand(command, filename)
if gVerbosity >= 2: echo(GC_getStatistics())
when hasTinyCBackend:
if gCmd == cmdRun:
tccgen.run()
if gCmd notin {cmdInterpret, cmdRun} and msgs.gErrorCounter == 0:
rawMessage(hintSuccessX, [$gLinesCompiled, $(getTime() - start)])
if optRun in gGlobalOptions:
when defined(unix):
var prog = "./" & quoteIfContainsWhite(changeFileExt(filename, ""))
else:
var prog = quoteIfContainsWhite(changeFileExt(filename, ""))
execExternalProgram(prog & ' ' & arguments)
if msgs.gErrorCounter == 0:
when hasTinyCBackend:
if gCmd == cmdRun:
tccgen.run()
if gCmd notin {cmdInterpret, cmdRun}:
rawMessage(hintSuccessX, [$gLinesCompiled, $(getTime() - start)])
if optRun in gGlobalOptions:
when defined(unix):
var prog = "./" & quoteIfContainsWhite(changeFileExt(filename, ""))
else:
var prog = quoteIfContainsWhite(changeFileExt(filename, ""))
execExternalProgram(prog & ' ' & arguments)
cmdLineInfo = newLineInfo("command line", - 1, - 1)
condsyms.InitDefines()

View File

@@ -211,6 +211,7 @@ proc openLexer(lex: var TLexer, filename: string, inputstream: PLLStream) =
lex.indentStack = @[0]
lex.filename = filename
lex.indentAhead = - 1
inc(lex.Linenumber, inputstream.lineOffset)
proc closeLexer(lex: var TLexer) =
inc(gLinesCompiled, lex.LineNumber)

View File

@@ -21,9 +21,12 @@ proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
popInfoContext()
proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
result = semExpr(c, n, flags)
if result.kind == nkEmpty: InternalError("semExprWithType")
if result.kind == nkEmpty:
# do not produce another redundant error message:
raiseRecoverableError()
if result.typ != nil:
if result.typ.kind == tyVar:
var d = newNodeIT(nkHiddenDeref, result.info, result.typ.sons[0])

View File

@@ -276,6 +276,8 @@ proc semVar(c: PContext, n: PNode): PNode =
else: typ = def.typ
else:
def = ast.emptyNode
# this can only happen for errornous var statements:
if typ == nil: continue
if not typeAllowed(typ, skVar):
GlobalError(a.info, errXisNoType, typeToString(typ))
var tup = skipTypes(typ, {tyGenericInst})

View File

@@ -723,7 +723,9 @@ proc transform(c: PTransf, n: PNode): PTransNode =
result = PTransNode(cnst) # do not miss an optimization
proc processTransf(context: PPassContext, n: PNode): PNode =
if passes.skipCodegen(n): return n
# Note: For interactive mode we cannot call 'passes.skipCodegen' and skip
# this step! We have to rely that the semantic pass transforms too errornous
# nodes into an empty node.
var c = PTransf(context)
pushTransCon(c, newTransCon(getCurrOwner(c)))
result = PNode(transform(c, n))