diff options
84 files changed, 677 insertions, 721 deletions
diff --git a/.gitignore b/.gitignore index 20a87aea7..20a87aea7 100644..100755 --- a/.gitignore +++ b/.gitignore diff --git a/doc/astspec.txt b/doc/astspec.txt index 01c1adba3..6b6242614 100755 --- a/doc/astspec.txt +++ b/doc/astspec.txt @@ -43,10 +43,8 @@ To specify the AST for the different Nimrod constructs, the notation ``nodekind(son1, son2, ...)`` or ``nodekind(value)`` or ``nodekind(field=value)`` is used. -Some child may be missing. Then it is ``nil``. A nil child is equivalent to -a node of kind ``nnkEmpty``. This is more or less a (useful) artifact from -the implementation. (In the compiler's implementation ``nil`` is of course -not the same as ``nnkEmpty``!) +Some child may be missing. A missing child is a node of kind ``nnkEmpty``; +a child can never be nil. Leaf nodes/Atoms @@ -364,7 +362,7 @@ When statement -------------- Like the ``if`` statement, but the root has the kind ``nnkWhenStmt``. - + Assignment ---------- diff --git a/doc/lib.txt b/doc/lib.txt index cefb1a1fe..cefb1a1fe 100644..100755 --- a/doc/lib.txt +++ b/doc/lib.txt diff --git a/examples/httpserver2.nim b/examples/httpserver2.nim index 0604e6a83..0604e6a83 100644..100755 --- a/examples/httpserver2.nim +++ b/examples/httpserver2.nim diff --git a/icons/koch.rc b/icons/koch.rc index 2e5d884dc..2e5d884dc 100644..100755 --- a/icons/koch.rc +++ b/icons/koch.rc diff --git a/icons/koch.res b/icons/koch.res index 3b38f7da4..3b38f7da4 100644..100755 --- a/icons/koch.res +++ b/icons/koch.res Binary files differdiff --git a/icons/nimrod.rc b/icons/nimrod.rc index 6f36b8145..6f36b8145 100644..100755 --- a/icons/nimrod.rc +++ b/icons/nimrod.rc diff --git a/icons/nimrod.res b/icons/nimrod.res index 6eddd053b..6eddd053b 100644..100755 --- a/icons/nimrod.res +++ b/icons/nimrod.res Binary files differdiff --git a/koch.nim b/koch.nim index 273f0b79f..273f0b79f 100644..100755 --- a/koch.nim +++ b/koch.nim diff --git a/lib/core/marshal.nim b/lib/core/marshal.nim index 1a06e5c37..1a06e5c37 100644..100755 --- a/lib/core/marshal.nim +++ b/lib/core/marshal.nim diff --git a/lib/core/threads.nim b/lib/core/threads.nim index fc120f1a3..fc120f1a3 100644..100755 --- a/lib/core/threads.nim +++ b/lib/core/threads.nim diff --git a/lib/impure/ssl.nim b/lib/impure/ssl.nim index ab53d0538..ab53d0538 100644..100755 --- a/lib/impure/ssl.nim +++ b/lib/impure/ssl.nim diff --git a/lib/pure/base64.nim b/lib/pure/base64.nim index 8c4883c11..8c4883c11 100644..100755 --- a/lib/pure/base64.nim +++ b/lib/pure/base64.nim diff --git a/lib/pure/cookies.nim b/lib/pure/cookies.nim index eed6c7512..eed6c7512 100644..100755 --- a/lib/pure/cookies.nim +++ b/lib/pure/cookies.nim diff --git a/lib/pure/math.nim b/lib/pure/math.nim index dc6133901..c44d786b1 100755 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -185,11 +185,12 @@ when not defined(ECMAScript): proc random(max: int): int = return int(rand()) mod max proc trunc*(x: float): float {.importc: "trunc", nodecl.} + proc floor*(x: float): float {.importc: "floor", nodecl.} else: proc mathrandom(): float {.importc: "Math.random", nodecl.} - proc mathfloor(x: float): float {.importc: "Math.floor", nodecl.} - proc random*(max: int): int = return mathfloor(mathrandom() * max) + proc floor*(x: float): float {.importc: "Math.floor", nodecl.} + proc random*(max: int): int = return floor(mathrandom() * max) proc randomize*() = nil proc sqrt*(x: float): float {.importc: "Math.sqrt", nodecl.} @@ -208,7 +209,7 @@ else: elif x < 0.0: result = -frexp(-x, exponent) else: - var ex = mathfloor(log2(x)) + var ex = floor(log2(x)) exponent = round(ex) result = x / pow(2.0, ex) @@ -227,7 +228,6 @@ else: var y = exp(2.0*x) return (y-1.0)/(y+1.0) - type TRunningStat* = object ## an accumulator for statistical data n*: int ## number of pushed data diff --git a/lib/pure/scgi.nim b/lib/pure/scgi.nim index 4893cf603..4893cf603 100644..100755 --- a/lib/pure/scgi.nim +++ b/lib/pure/scgi.nim diff --git a/lib/pure/smtp.nim b/lib/pure/smtp.nim index 21afdf953..21afdf953 100644..100755 --- a/lib/pure/smtp.nim +++ b/lib/pure/smtp.nim diff --git a/lib/wrappers/claro.nim b/lib/wrappers/claro.nim index feab2a216..feab2a216 100644..100755 --- a/lib/wrappers/claro.nim +++ b/lib/wrappers/claro.nim diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index 5fc6ddd02..5fc6ddd02 100644..100755 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim diff --git a/lib/wrappers/pcre.nim b/lib/wrappers/pcre.nim index 7e75035da..7e75035da 100644..100755 --- a/lib/wrappers/pcre.nim +++ b/lib/wrappers/pcre.nim diff --git a/rod/astalgo.nim b/rod/astalgo.nim index a4a6ec06e..3167f814b 100755 --- a/rod/astalgo.nim +++ b/rod/astalgo.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -44,9 +44,8 @@ proc TableSearch*(t: TTable, key, closure: PObject, comparator: TCmpProc): PObje # ----------------------- str table ----------------------------------------- proc StrTableContains*(t: TStrTable, n: PSym): bool proc StrTableAdd*(t: var TStrTable, n: PSym) -proc StrTableGet*(t: TStrTable, name: PIdent): PSym -proc StrTableIncl*(t: var TStrTable, n: PSym): bool - # returns true if n is already in the string table +proc StrTableGet*(t: TStrTable, name: PIdent): PSym + # the iterator scheme: type TTabIter*{.final.} = object # consider all fields here private @@ -574,8 +573,10 @@ proc StrTableAdd(t: var TStrTable, n: PSym) = StrTableRawInsert(t.data, n) inc(t.counter) -proc StrTableIncl(t: var TStrTable, n: PSym): bool = +proc StrTableIncl*(t: var TStrTable, n: PSym): bool = # returns true if n is already in the string table: + # It is essential that `n` is written nevertheless! + # This way the newest redefinition is picked by the semantic analyses! var h: THash it: PSym @@ -584,6 +585,7 @@ proc StrTableIncl(t: var TStrTable, n: PSym): bool = it = t.data[h] if it == nil: break if it.name.id == n.name.id: + t.data[h] = n # overwrite it with newer definition! return true # found it h = nextTry(h, high(t.data)) if mustRehash(len(t.data), t.counter): @@ -661,10 +663,9 @@ proc SymTabAdd(tab: var TSymTab, e: PSym) = StrTableAdd(tab.stack[tab.tos - 1], e) proc SymTabAddUniqueAt(tab: var TSymTab, e: PSym, at: Natural): TResult = - if StrTableGet(tab.stack[at], e.name) != nil: + if StrTableIncl(tab.stack[at], e): result = Failure else: - StrTableAdd(tab.stack[at], e) result = Success proc SymTabAddUnique(tab: var TSymTab, e: PSym): TResult = diff --git a/rod/c2nim/clex.nim b/rod/c2nim/clex.nim index 8136ad998..5a67f9475 100755 --- a/rod/c2nim/clex.nim +++ b/rod/c2nim/clex.nim @@ -130,11 +130,11 @@ proc getLineInfo*(L: TLexer): TLineInfo = result = newLineInfo(L.filename, L.linenumber, getColNumber(L, L.bufpos)) proc lexMessage*(L: TLexer, msg: TMsgKind, arg = "") = - msgs.liMessage(getLineInfo(L), msg, arg) + msgs.GenericMessage(getLineInfo(L), msg, arg) proc lexMessagePos(L: var TLexer, msg: TMsgKind, pos: int, arg = "") = var info = newLineInfo(L.filename, L.linenumber, pos - L.lineStart) - msgs.liMessage(info, msg, arg) + msgs.GenericMessage(info, msg, arg) proc TokKindToStr*(k: TTokKind): string = case k diff --git a/rod/ccgexprs.nim b/rod/ccgexprs.nim index 634dea886..36603be61 100755 --- a/rod/ccgexprs.nim +++ b/rod/ccgexprs.nim @@ -1439,7 +1439,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = of mEcho: genEcho(p, e) of mArrToSeq: genArrToSeq(p, e, d) of mNLen..mNError: - liMessage(e.info, errCannotGenerateCodeForX, e.sons[0].sym.name.s) + localError(e.info, errCannotGenerateCodeForX, e.sons[0].sym.name.s) else: internalError(e.info, "genMagicExpr: " & $op) proc genConstExpr(p: BProc, n: PNode): PRope @@ -1605,7 +1605,7 @@ proc expr(p: BProc, e: PNode, d: var TLoc) = var sym = e.sym case sym.Kind of skMethod: - if sym.ast.sons[codePos] == nil: + if sym.ast.sons[codePos].kind == nkEmpty: # we cannot produce code for the dispatcher yet: fillProcLoc(sym) genProcPrototype(p.module, sym) diff --git a/rod/ccgstmts.nim b/rod/ccgstmts.nim index 2ac87824c..2b649a270 100755 --- a/rod/ccgstmts.nim +++ b/rod/ccgstmts.nim @@ -56,22 +56,19 @@ proc genVarTuple(p: BProc, n: PNode) = genObjectInit(p, v.typ, v.loc, true) proc genVarStmt(p: BProc, n: PNode) = - var - v: PSym - a: PNode for i in countup(0, sonsLen(n) - 1): - a = n.sons[i] + var a = n.sons[i] if a.kind == nkCommentStmt: continue if a.kind == nkIdentDefs: assert(a.sons[0].kind == nkSym) - v = a.sons[0].sym + var v = a.sons[0].sym if sfGlobal in v.flags: assignGlobalVar(p, v) else: assignLocalVar(p, v) initVariable(p, v) # XXX: this is not required if a.sons[2] != nil, # unless it is a GC'ed pointer - if a.sons[2] != nil: + if a.sons[2].kind != nkEmpty: genLineDir(p, a) expr(p, a.sons[2], v.loc) genObjectInit(p, v.typ, v.loc, true) # correct position @@ -79,13 +76,11 @@ proc genVarStmt(p: BProc, n: PNode) = genVarTuple(p, a) proc genConstStmt(p: BProc, t: PNode) = - var c: PSym for i in countup(0, sonsLen(t) - 1): if t.sons[i].kind == nkCommentStmt: continue if t.sons[i].kind != nkConstDef: InternalError(t.info, "genConstStmt") - c = t.sons[i].sons[0].sym # This can happen for forward consts: - if (c.ast != nil) and (c.typ.kind in ConstantDataTypes) and - not (lfNoDecl in c.loc.flags): + var c = t.sons[i].sons[0].sym + if c.typ.kind in ConstantDataTypes and not (lfNoDecl in c.loc.flags): # generate the data: fillLoc(c.loc, locData, c.typ, mangleName(c), OnUnknown) if sfImportc in c.flags: @@ -134,7 +129,7 @@ proc genIfStmt(p: BProc, n: PNode) = proc popSafePoints(p: BProc, howMany: int) = var L = p.nestedTryStmts.len - # danger of endless recursion! we workaround this here, by a temp stack + # danger of endless recursion! we workaround this here by a temp stack var stack: seq[PNode] newSeq(stack, howMany) for i in countup(1, howMany): @@ -154,7 +149,7 @@ proc genReturnStmt(p: BProc, t: PNode) = p.beforeRetNeeded = true popSafePoints(p, min(1, p.nestedTryStmts.len)) genLineDir(p, t) - if (t.sons[0] != nil): genStmts(p, t.sons[0]) + if (t.sons[0].kind != nkEmpty): genStmts(p, t.sons[0]) appff(p.s[cpsStmts], "goto BeforeRet;$n", "br label %BeforeRet$n", []) proc genWhileStmt(p: BProc, t: PNode) = @@ -185,7 +180,7 @@ proc genWhileStmt(p: BProc, t: PNode) = proc genBlock(p: BProc, t: PNode, d: var TLoc) = inc(p.labels) var idx = len(p.blocks) - if t.sons[0] != nil: + if t.sons[0].kind != nkEmpty: # named block? assert(t.sons[0].kind == nkSym) var sym = t.sons[0].sym @@ -202,7 +197,7 @@ proc genBlock(p: BProc, t: PNode, d: var TLoc) = proc genBreakStmt(p: BProc, t: PNode) = var idx = len(p.blocks) - 1 - if t.sons[0] != nil: + if t.sons[0].kind != nkEmpty: # named break? assert(t.sons[0].kind == nkSym) var sym = t.sons[0].sym @@ -220,7 +215,7 @@ proc getRaiseFrmt(p: BProc): string = result = "#raiseException((#E_Base*)$1, $2);$n" proc genRaiseStmt(p: BProc, t: PNode) = - if t.sons[0] != nil: + if t.sons[0].kind != nkEmpty: var a: TLoc InitLocExpr(p, t.sons[0], a) var e = rdLoc(a) @@ -668,8 +663,6 @@ proc genStmts(p: BProc, t: PNode) = var a: TLoc prc: PSym - #assert(t <> nil); - if inCheckpoint(t.info): MessageOut(renderTree(t)) case t.kind of nkEmpty: nil @@ -707,7 +700,7 @@ proc genStmts(p: BProc, t: PNode) = nil of nkPragma: genPragma(p, t) of nkProcDef, nkMethodDef, nkConverterDef: - if (t.sons[genericParamsPos] == nil): + if (t.sons[genericParamsPos].kind == nkEmpty): prc = t.sons[namePos].sym if (optDeadCodeElim notin gGlobalOptions and sfDeadCodeElim notin getModule(prc).flags) or @@ -715,7 +708,7 @@ proc genStmts(p: BProc, t: PNode) = (sfExportc in prc.flags and lfExportLib in prc.loc.flags) or (prc.kind == skMethod): # we have not only the header: - if (t.sons[codePos] != nil) or (lfDynamicLib in prc.loc.flags): + if (t.sons[codePos].kind != nkEmpty) or (lfDynamicLib in prc.loc.flags): genProc(p.module, prc) else: internalError(t.info, "genStmts(" & $t.kind & ')') diff --git a/rod/cgen.nim b/rod/cgen.nim index 685d912c4..13b96c19b 100755 --- a/rod/cgen.nim +++ b/rod/cgen.nim @@ -890,12 +890,12 @@ proc myOpen(module: PSym, filename: string): PPassContext = proc myOpenCached(module: PSym, filename: string, rd: PRodReader): PPassContext = if gNimDat == nil: - registerTypeInfoModule() - #MessageOut('cgen.myOpenCached has been called ' + filename); + registerTypeInfoModule() + #MessageOut('cgen.myOpenCached has been called ' + filename) var cfile = changeFileExt(completeCFilePath(filename), cExt) var cfilenoext = changeFileExt(cfile, "") addFileToLink(cfilenoext) - registerModuleToMain(module) + registerModuleToMain(module) # XXX: this cannot be right here, initalization has to be appended during # the ``myClose`` call result = nil @@ -911,7 +911,7 @@ proc shouldRecompile(code: PRope, cfile, cfilenoext: string): bool = proc myProcess(b: PPassContext, n: PNode): PNode = result = n - if b == nil: return + if b == nil or passes.skipCodegen(n): return var m = BModule(b) m.initProc.options = gOptions genStmts(m.initProc, n) @@ -951,7 +951,7 @@ proc writeModule(m: BModule) = proc myClose(b: PPassContext, n: PNode): PNode = result = n - if b == nil: return + if b == nil or passes.skipCodegen(n): return var m = BModule(b) if n != nil: m.initProc.options = gOptions diff --git a/rod/cgmeth.nim b/rod/cgmeth.nim index fe1b581f9..f9b12647f 100755 --- a/rod/cgmeth.nim +++ b/rod/cgmeth.nim @@ -1,22 +1,17 @@ # # # The Nimrod Compiler -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# This module implements code generation for multi methods. +## This module implements code generation for multi methods. import options, ast, astalgo, msgs, idents, rnimsyn, types, magicsys -proc methodDef*(s: PSym) -proc methodCall*(n: PNode): PNode -proc generateMethodDispatchers*(): PNode -# implementation - proc genConv(n: PNode, d: PType, downcast: bool): PNode = var dest, source: PType @@ -40,7 +35,7 @@ proc genConv(n: PNode, d: PType, downcast: bool): PNode = else: result = n -proc methodCall(n: PNode): PNode = +proc methodCall*(n: PNode): PNode = var disp: PSym result = n disp = lastSon(result.sons[0].sym.ast).sym @@ -76,7 +71,7 @@ proc sameMethodBucket(a, b: PSym): bool = return result = true -proc methodDef(s: PSym) = +proc methodDef*(s: PSym) = var L, q: int disp: PSym @@ -86,12 +81,12 @@ proc methodDef(s: PSym) = add(gMethods[i], s) # store a symbol to the dispatcher: addSon(s.ast, lastSon(gMethods[i][0].ast)) return - add(gMethods, @ [s]) # create a new dispatcher: + add(gMethods, @[s]) # create a new dispatcher: disp = copySym(s) disp.typ = copyType(disp.typ, disp.typ.owner, false) if disp.typ.callConv == ccInline: disp.typ.callConv = ccDefault disp.ast = copyTree(s.ast) - disp.ast.sons[codePos] = nil + disp.ast.sons[codePos] = ast.emptyNode if s.typ.sons[0] != nil: disp.ast.sons[resultPos].sym = copySym(s.ast.sons[resultPos].sym) addSon(s.ast, newSymNode(disp)) @@ -188,7 +183,7 @@ proc genDispatcher(methods: TSymSeq, relevantCols: TIntSet): PSym = addSon(disp, a) result.ast.sons[codePos] = disp -proc generateMethodDispatchers(): PNode = +proc generateMethodDispatchers*(): PNode = var relevantCols: TIntSet result = newNode(nkStmtList) for bucket in countup(0, len(gMethods) - 1): diff --git a/rod/commands.nim b/rod/commands.nim index ef7f04eb8..2be58e8c8 100755 --- a/rod/commands.nim +++ b/rod/commands.nim @@ -152,7 +152,7 @@ proc writeCommandLineUsage() = helpWritten = true proc InvalidCmdLineOption(pass: TCmdLinePass, switch: string, info: TLineInfo) = - liMessage(info, errInvalidCmdLineOption, switch) + LocalError(info, errInvalidCmdLineOption, switch) proc splitSwitch(switch: string, cmd, arg: var string, pass: TCmdLinePass, info: TLineInfo) = @@ -174,20 +174,20 @@ proc ProcessOnOffSwitch(op: TOptions, arg: string, pass: TCmdlinePass, case whichKeyword(arg) of wOn: gOptions = gOptions + op of wOff: gOptions = gOptions - op - else: liMessage(info, errOnOrOffExpectedButXFound, arg) + else: LocalError(info, errOnOrOffExpectedButXFound, arg) proc ProcessOnOffSwitchG(op: TGlobalOptions, arg: string, pass: TCmdlinePass, info: TLineInfo) = case whichKeyword(arg) of wOn: gGlobalOptions = gGlobalOptions + op of wOff: gGlobalOptions = gGlobalOptions - op - else: liMessage(info, errOnOrOffExpectedButXFound, arg) + else: LocalError(info, errOnOrOffExpectedButXFound, arg) proc ExpectArg(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) = - if arg == "": liMessage(info, errCmdLineArgExpected, switch) + if arg == "": LocalError(info, errCmdLineArgExpected, switch) proc ExpectNoArg(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) = - if arg != "": liMessage(info, errCmdLineNoArgExpected, switch) + if arg != "": LocalError(info, errCmdLineNoArgExpected, switch) proc ProcessSpecificNote(arg: string, state: TSpecialWord, pass: TCmdlinePass, info: TLineInfo) = @@ -212,7 +212,7 @@ proc ProcessSpecificNote(arg: string, state: TSpecialWord, pass: TCmdlinePass, case whichKeyword(copy(arg, i)) of wOn: incl(gNotes, n) of wOff: excl(gNotes, n) - else: liMessage(info, errOnOrOffExpectedButXFound, arg) + else: LocalError(info, errOnOrOffExpectedButXFound, arg) proc processCompile(filename: string) = var found = findFile(filename) @@ -228,13 +228,13 @@ proc testCompileOptionArg*(switch, arg: string, info: TLineInfo): bool = of wBoehm: result = contains(gGlobalOptions, optBoehmGC) of wRefc: result = contains(gGlobalOptions, optRefcGC) of wNone: result = gGlobalOptions * {optBoehmGC, optRefcGC} == {} - else: liMessage(info, errNoneBoehmRefcExpectedButXFound, arg) + else: LocalError(info, errNoneBoehmRefcExpectedButXFound, arg) of wOpt: case whichKeyword(arg) of wSpeed: result = contains(gOptions, optOptimizeSpeed) of wSize: result = contains(gOptions, optOptimizeSize) of wNone: result = gOptions * {optOptimizeSpeed, optOptimizeSize} == {} - else: liMessage(info, errNoneSpeedOrSizeExpectedButXFound, arg) + else: LocalError(info, errNoneSpeedOrSizeExpectedButXFound, arg) else: InvalidCmdLineOption(passCmd1, switch, info) proc testCompileOption*(switch: string, info: TLineInfo): bool = @@ -285,7 +285,7 @@ proc addPathRec(dir: string, info: TLineInfo) = if k == pcDir and p[pos] != '.': addPathRec(p, info) if not contains(options.searchPaths, p): - liMessage(info, hintPath, p) + Message(info, hintPath, p) lists.PrependStr(options.searchPaths, p) proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = @@ -346,7 +346,7 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = excl(gGlobalOptions, optRefcGC) excl(gGlobalOptions, optBoehmGC) defineSymbol("nogc") - else: liMessage(info, errNoneBoehmRefcExpectedButXFound, arg) + else: LocalError(info, errNoneBoehmRefcExpectedButXFound, arg) of wWarnings, wW: ProcessOnOffSwitch({optWarns}, arg, pass, info) of wWarning: ProcessSpecificNote(arg, wWarning, pass, info) of wHint: ProcessSpecificNote(arg, wHint, pass, info) @@ -388,7 +388,7 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = of wNone: excl(gOptions, optOptimizeSpeed) excl(gOptions, optOptimizeSize) - else: liMessage(info, errNoneSpeedOrSizeExpectedButXFound, arg) + else: LocalError(info, errNoneSpeedOrSizeExpectedButXFound, arg) of wApp: expectArg(switch, arg, pass, info) case whichKeyword(arg) @@ -401,7 +401,7 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = incl(gGlobalOptions, optGenDynLib) excl(gGlobalOptions, optGenGuiApp) defineSymbol("library") - else: liMessage(info, errGuiConsoleOrLibExpectedButXFound, arg) + else: LocalError(info, errGuiConsoleOrLibExpectedButXFound, arg) of wListDef: expectNoArg(switch, arg, pass, info) if pass in {passCmd2, passPP}: condsyms.listSymbols() @@ -427,8 +427,8 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = expectArg(switch, arg, pass, info) if (pass == passCmd1): theOS = platform.NameToOS(arg) - if theOS == osNone: liMessage(info, errUnknownOS, arg) - if theOS != platform.hostOS: + if theOS == osNone: LocalError(info, errUnknownOS, arg) + elif theOS != platform.hostOS: setTarget(theOS, targetCPU) incl(gGlobalOptions, optCompileOnly) condsyms.InitDefines() @@ -436,8 +436,8 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = expectArg(switch, arg, pass, info) if (pass == passCmd1): cpu = platform.NameToCPU(arg) - if cpu == cpuNone: liMessage(info, errUnknownCPU, arg) - if cpu != platform.hostCPU: + if cpu == cpuNone: LocalError(info, errUnknownCPU, arg) + elif cpu != platform.hostCPU: setTarget(targetOS, cpu) incl(gGlobalOptions, optCompileOnly) condsyms.InitDefines() diff --git a/rod/ecmasgen.nim b/rod/ecmasgen.nim index b86b5dd59..6898b01d1 100755 --- a/rod/ecmasgen.nim +++ b/rod/ecmasgen.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -547,7 +547,7 @@ proc genRaiseStmt(p: var TProc, n: PNode, r: var TCompRes) = a: TCompRes typ: PType genLineDir(p, n, r) - if n.sons[0] != nil: + if n.sons[0].kind != nkEmpty: gen(p, n.sons[0], a) if a.com != nil: appf(r.com, "$1;$n", [a.com]) typ = skipTypes(n.sons[0].typ, abstractPtrs) @@ -610,7 +610,7 @@ proc genBlock(p: var TProc, n: PNode, r: var TCompRes) = sym: PSym inc(p.unique) idx = len(p.blocks) - if n.sons[0] != nil: + if n.sons[0].kind != nkEmpty: # named block? if (n.sons[0].kind != nkSym): InternalError(n.info, "genBlock") sym = n.sons[0].sym @@ -633,7 +633,7 @@ proc genBreakStmt(p: var TProc, n: PNode, r: var TCompRes) = sym: PSym genLineDir(p, n, r) idx = len(p.blocks) - 1 - if n.sons[0] != nil: + if n.sons[0].kind != nkEmpty: # named break? assert(n.sons[0].kind == nkSym) sym = n.sons[0].sym @@ -991,7 +991,7 @@ proc genVarInit(p: var TProc, v: PSym, n: PNode, r: var TCompRes) = var a: TCompRes s: PRope - if n == nil: + if n.kind == nkEmpty: appf(r.com, "var $1 = $2;$n", [mangleName(v), createVar(p, v.typ, isIndirect(v))]) else: @@ -1135,7 +1135,7 @@ proc genMagic(p: var TProc, n: PNode, r: var TCompRes) = of mExcl: binaryStmt(p, n, r, "", "delete $1[$2]") of mInSet: binaryExpr(p, n, r, "", "($1[$2] != undefined)") of mNLen..mNError: - liMessage(n.info, errCannotGenerateCodeForX, n.sons[0].sym.name.s) + localError(n.info, errCannotGenerateCodeForX, n.sons[0].sym.name.s) of mNewSeq: binaryStmt(p, n, r, "", "$1 = new Array($2)") of mEcho: genEcho(p, n, r) else: @@ -1231,7 +1231,7 @@ proc genReturnStmt(p: var TProc, n: PNode, r: var TCompRes) = var a: TCompRes if p.procDef == nil: InternalError(n.info, "genReturnStmt") p.BeforeRetNeeded = true - if (n.sons[0] != nil): + if (n.sons[0].kind != nkEmpty): genStmt(p, n.sons[0], a) if a.com != nil: appf(r.com, "$1;$n", mergeStmt(a)) else: @@ -1297,7 +1297,7 @@ proc genStmt(p: var TProc, n: PNode, r: var TCompRes) = r.com = nil r.res = nil case n.kind - of nkNilLit: nil + of nkNilLit, nkEmpty: nil of nkStmtList: for i in countup(0, sonsLen(n) - 1): genStmt(p, n.sons[i], a) @@ -1324,9 +1324,9 @@ proc genStmt(p: var TProc, n: PNode, r: var TCompRes) = nkFromStmt, nkTemplateDef, nkMacroDef, nkPragma: nil of nkProcDef, nkMethodDef, nkConverterDef: - if (n.sons[genericParamsPos] == nil): + if (n.sons[genericParamsPos].kind == nkEmpty): var prc = n.sons[namePos].sym - if (n.sons[codePos] != nil) and not (lfNoDecl in prc.loc.flags): + if (n.sons[codePos].kind != nkEmpty) and not (lfNoDecl in prc.loc.flags): genProc(p, n, r) else: discard mangleName(prc) @@ -1391,6 +1391,7 @@ proc gen(p: var TProc, n: PNode, r: var TCompRes) = of nkCStringToString: convCStrToStr(p, n, r) of nkPassAsOpenArray: gen(p, n.sons[0], r) of nkStmtListExpr: genStmtListExpr(p, n, r) + of nkEmpty: nil else: InternalError(n.info, "gen: unknown node type: " & $n.kind) var globals: PGlobals @@ -1416,6 +1417,7 @@ proc genModule(p: var TProc, n: PNode, r: var TCompRes) = makeCString(toFilename(p.module.module.info)), r.com]) proc myProcess(b: PPassContext, n: PNode): PNode = + if passes.skipCodegen(n): return n var p: TProc r: TCompRes @@ -1428,6 +1430,7 @@ proc myProcess(b: PPassContext, n: PNode): PNode = app(p.globals.code, mergeStmt(r)) proc myClose(b: PPassContext, n: PNode): PNode = + if passes.skipCodegen(n): return n result = myProcess(b, n) var m = BModule(b) if sfMainModule in m.module.flags: diff --git a/rod/evals.nim b/rod/evals.nim index b20c20acf..531ef8fbb 100755 --- a/rod/evals.nim +++ b/rod/evals.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -84,7 +84,7 @@ proc stackTraceAux(x: PStackFrame) = proc stackTrace(c: PEvalContext, n: PNode, msg: TMsgKind, arg: string = "") = messageOut("stack trace: (most recent call last)") stackTraceAux(c.tos) - liMessage(n.info, msg, arg) + Fatal(n.info, msg, arg) proc isSpecial(n: PNode): bool = result = (n.kind == nkExceptBranch) @@ -414,7 +414,7 @@ proc evalEcho(c: PEvalContext, n: PNode): PNode = proc evalExit(c: PEvalContext, n: PNode): PNode = result = evalAux(c, n.sons[1], {}) if isSpecial(result): return - liMessage(n.info, hintQuitCalled) + Message(n.info, hintQuitCalled) quit(int(getOrdValue(result))) proc evalOr(c: PEvalContext, n: PNode): PNode = @@ -915,12 +915,12 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode = of mNHint: result = evalAux(c, n.sons[1], {}) if isSpecial(result): return - liMessage(n.info, hintUser, getStrValue(result)) + Message(n.info, hintUser, getStrValue(result)) result = emptyNode of mNWarning: result = evalAux(c, n.sons[1], {}) if isSpecial(result): return - liMessage(n.info, warnUser, getStrValue(result)) + Message(n.info, warnUser, getStrValue(result)) result = emptyNode of mNError: result = evalAux(c, n.sons[1], {}) diff --git a/rod/extccomp.nim b/rod/extccomp.nim index bb29cea33..bb29cea33 100644..100755 --- a/rod/extccomp.nim +++ b/rod/extccomp.nim diff --git a/rod/filters.nim b/rod/filters.nim index 20db697bf..d1c61749d 100755 --- a/rod/filters.nim +++ b/rod/filters.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -9,7 +9,7 @@ # This module implements Nimrod's simple filters and helpers for filters. -import +import llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options, rnimsyn proc filterReplace*(stdin: PLLStream, filename: string, call: PNode): PLLStream @@ -21,7 +21,7 @@ proc boolArg*(n: PNode, name: string, pos: int, default: bool): bool # implementation proc invalidPragma(n: PNode) = - liMessage(n.info, errXNotAllowedHere, renderTree(n, {renderNoComments})) + LocalError(n.info, errXNotAllowedHere, renderTree(n, {renderNoComments})) proc getArg(n: PNode, name: string, pos: int): PNode = result = nil diff --git a/rod/importer.nim b/rod/importer.nim index 608bad066..06eebcb4e 100755 --- a/rod/importer.nim +++ b/rod/importer.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -22,7 +22,7 @@ proc getModuleFile*(n: PNode): string proc findModule(info: TLineInfo, modulename: string): string = # returns path to module result = options.FindFile(AddFileExt(modulename, nimExt)) - if result == "": liMessage(info, errCannotOpenFile, modulename) + if result == "": Fatal(info, errCannotOpenFile, modulename) proc getModuleFile(n: PNode): string = case n.kind @@ -73,7 +73,7 @@ proc rawImportSymbol(c: PContext, s: PSym) = proc importSymbol(c: PContext, ident: PNode, fromMod: PSym) = if (ident.kind != nkIdent): InternalError(ident.info, "importSymbol") var s = StrTableGet(fromMod.tab, ident.ident) - if s == nil: liMessage(ident.info, errUndeclaredIdentifier, ident.ident.s) + if s == nil: GlobalError(ident.info, errUndeclaredIdentifier, ident.ident.s) if s.kind == skStub: loadStub(s) if not (s.Kind in ExportableSymKinds): InternalError(ident.info, "importSymbol: 2") @@ -106,7 +106,7 @@ proc evalImport(c: PContext, n: PNode): PNode = var f = getModuleFile(n.sons[i]) var m = gImportModule(f) if sfDeprecated in m.flags: - liMessage(n.sons[i].info, warnDeprecated, m.name.s) + Message(n.sons[i].info, warnDeprecated, m.name.s) # ``addDecl`` needs to be done before ``importAllSymbols``! addDecl(c, m) # add symbol to symbol table of module importAllSymbols(c, m) diff --git a/rod/lookups.nim b/rod/lookups.nim index f872224c0..160f9635b 100755 --- a/rod/lookups.nim +++ b/rod/lookups.nim @@ -35,24 +35,24 @@ proc CloseScope*(tab: var TSymTab) = s = InitTabIter(it, tab.stack[tab.tos - 1]) while s != nil: if sfForward in s.flags: - liMessage(s.info, errImplOfXexpected, getSymRepr(s)) + LocalError(s.info, errImplOfXexpected, getSymRepr(s)) elif ({sfUsed, sfInInterface} * s.flags == {}) and (optHints in s.options): # BUGFIX: check options in s! if not (s.kind in {skForVar, skParam, skMethod, skUnknown}): - liMessage(s.info, hintXDeclaredButNotUsed, getSymRepr(s)) + Message(s.info, hintXDeclaredButNotUsed, getSymRepr(s)) s = NextIter(it, tab.stack[tab.tos - 1]) astalgo.rawCloseScope(tab) proc AddSym*(t: var TStrTable, n: PSym) = - if StrTableIncl(t, n): liMessage(n.info, errAttemptToRedefine, n.name.s) + if StrTableIncl(t, n): LocalError(n.info, errAttemptToRedefine, n.name.s) proc addDecl*(c: PContext, sym: PSym) = if SymTabAddUnique(c.tab, sym) == Failure: - liMessage(sym.info, errAttemptToRedefine, sym.Name.s) + LocalError(sym.info, errAttemptToRedefine, sym.Name.s) proc addDeclAt*(c: PContext, sym: PSym, at: Natural) = if SymTabAddUniqueAt(c.tab, sym, at) == Failure: - liMessage(sym.info, errAttemptToRedefine, sym.Name.s) + LocalError(sym.info, errAttemptToRedefine, sym.Name.s) proc AddInterfaceDeclAux(c: PContext, sym: PSym) = if (sfInInterface in sym.flags): @@ -66,12 +66,13 @@ proc addInterfaceDeclAt*(c: PContext, sym: PSym, at: Natural) = AddInterfaceDeclAux(c, sym) proc addOverloadableSymAt*(c: PContext, fn: PSym, at: Natural) = - if not (fn.kind in OverloadableSyms): + if fn.kind notin OverloadableSyms: InternalError(fn.info, "addOverloadableSymAt") var check = StrTableGet(c.tab.stack[at], fn.name) - if (check != nil) and not (check.Kind in OverloadableSyms): - liMessage(fn.info, errAttemptToRedefine, fn.Name.s) - SymTabAddAt(c.tab, fn, at) + if check != nil and check.Kind notin OverloadableSyms: + LocalError(fn.info, errAttemptToRedefine, fn.Name.s) + else: + SymTabAddAt(c.tab, fn, at) proc addInterfaceDecl*(c: PContext, sym: PSym) = # it adds the symbol to the interface if appropriate @@ -89,17 +90,13 @@ proc lookUp*(c: PContext, n: PNode): PSym = of nkAccQuoted: result = lookup(c, n.sons[0]) of nkSym: - # - # result := SymtabGet(c.Tab, n.sym.name); - # if result = nil then - # liMessage(n.info, errUndeclaredIdentifier, n.sym.name.s); result = n.sym of nkIdent: result = SymtabGet(c.Tab, n.ident) - if result == nil: liMessage(n.info, errUndeclaredIdentifier, n.ident.s) + if result == nil: GlobalError(n.info, errUndeclaredIdentifier, n.ident.s) else: InternalError(n.info, "lookUp") if IntSetContains(c.AmbiguousSymbols, result.id): - liMessage(n.info, errUseQualifier, result.name.s) + LocalError(n.info, errUseQualifier, result.name.s) if result.kind == skStub: loadStub(result) type @@ -111,20 +108,15 @@ proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym = of nkIdent: result = SymtabGet(c.Tab, n.ident) if result == nil and checkUndeclared in flags: - liMessage(n.info, errUndeclaredIdentifier, n.ident.s) - elif checkAmbiguity in flags and IntSetContains(c.AmbiguousSymbols, - result.id): - liMessage(n.info, errUseQualifier, n.ident.s) + GlobalError(n.info, errUndeclaredIdentifier, n.ident.s) + elif checkAmbiguity in flags and result != nil and + IntSetContains(c.AmbiguousSymbols, result.id): + LocalError(n.info, errUseQualifier, n.ident.s) of nkSym: - # - # result = SymtabGet(c.Tab, n.sym.name) - # if result == nil: - # liMessage(n.info, errUndeclaredIdentifier, n.sym.name.s) - # else result = n.sym if checkAmbiguity in flags and IntSetContains(c.AmbiguousSymbols, result.id): - liMessage(n.info, errUseQualifier, n.sym.name.s) + LocalError(n.info, errUseQualifier, n.sym.name.s) of nkDotExpr: result = nil var m = qualifiedLookUp(c, n.sons[0], flags*{checkUndeclared}) @@ -141,9 +133,10 @@ proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym = else: result = StrTableGet(m.tab, ident) if result == nil and checkUndeclared in flags: - liMessage(n.sons[1].info, errUndeclaredIdentifier, ident.s) + GlobalError(n.sons[1].info, errUndeclaredIdentifier, ident.s) elif checkUndeclared in flags: - liMessage(n.sons[1].info, errIdentifierExpected, renderTree(n.sons[1])) + GlobalError(n.sons[1].info, errIdentifierExpected, + renderTree(n.sons[1])) of nkAccQuoted: result = QualifiedLookup(c, n.sons[0], flags) else: @@ -151,7 +144,6 @@ proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym = if (result != nil) and (result.kind == skStub): loadStub(result) proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = - var ident: PIdent result = nil case n.kind of nkIdent: @@ -163,18 +155,12 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = result = InitIdentIter(o.it, c.tab.stack[o.stackPtr], n.ident) of nkSym: result = n.sym - o.mode = oimDone - # o.stackPtr = c.tab.tos - # o.mode = oimNoQualifier - # while result == nil: - # dec(o.stackPtr) - # if o.stackPtr < 0: break - # result = InitIdentIter(o.it, c.tab.stack[o.stackPtr], n.sym.name) + o.mode = oimDone of nkDotExpr: o.mode = oimOtherModule o.m = qualifiedLookUp(c, n.sons[0]) if (o.m != nil) and (o.m.kind == skModule): - ident = nil + var ident: PIdent = nil if (n.sons[1].kind == nkIdent): ident = n.sons[1].ident elif (n.sons[1].kind == nkAccQuoted) and @@ -188,7 +174,8 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = else: result = InitIdentIter(o.it, o.m.tab, ident) else: - liMessage(n.sons[1].info, errIdentifierExpected, renderTree(n.sons[1])) + GlobalError(n.sons[1].info, errIdentifierExpected, + renderTree(n.sons[1])) of nkAccQuoted: result = InitOverloadIter(o, c, n.sons[0]) of nkSymChoice: diff --git a/rod/main.nim b/rod/main.nim index 2b391e7dd..5239227ac 100755 --- a/rod/main.nim +++ b/rod/main.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -73,7 +73,7 @@ proc importModule(filename: string): PSym = # compile the module result = compileModule(filename, false, false) elif sfSystemModule in result.flags: - liMessage(result.info, errAttemptToRedefine, result.Name.s) + LocalError(result.info, errAttemptToRedefine, result.Name.s) proc CompileModule(filename: string, isMainFile, isSystemFile: bool): PSym = var rd: PRodReader = nil @@ -177,7 +177,7 @@ proc CommandScan(filename: string) = proc WantFile(filename: string) = if filename == "": - liMessage(newLineInfo("command line", 1, 1), errCommandExpectsFilename) + Fatal(newLineInfo("command line", 1, 1), errCommandExpectsFilename) proc MainCommand(cmd, filename: string) = appendStr(searchPaths, options.libpath) 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) diff --git a/rod/nimrod.ini b/rod/nimrod.ini index d4c6dc3b2..d4c6dc3b2 100644..100755 --- a/rod/nimrod.ini +++ b/rod/nimrod.ini diff --git a/rod/nimrod.nim b/rod/nimrod.nim index 5eac2db43..5eac2db43 100644..100755 --- a/rod/nimrod.nim +++ b/rod/nimrod.nim diff --git a/rod/pas2nim/paslex.nim b/rod/pas2nim/paslex.nim index 193a45001..ed554bdc2 100755 --- a/rod/pas2nim/paslex.nim +++ b/rod/pas2nim/paslex.nim @@ -109,11 +109,11 @@ proc getLineInfo*(L: TLexer): TLineInfo = result = newLineInfo(L.filename, L.linenumber, getColNumber(L, L.bufpos)) proc lexMessage*(L: TLexer, msg: TMsgKind, arg = "") = - msgs.liMessage(getLineInfo(L), msg, arg) + msgs.GenericMessage(getLineInfo(L), msg, arg) proc lexMessagePos(L: var TLexer, msg: TMsgKind, pos: int, arg = "") = var info = newLineInfo(L.filename, L.linenumber, pos - L.lineStart) - msgs.liMessage(info, msg, arg) + msgs.GenericMessage(info, msg, arg) proc TokKindToStr*(k: TTokKind): string = case k diff --git a/rod/passaux.nim b/rod/passaux.nim index d687dba08..5df37c095 100755 --- a/rod/passaux.nim +++ b/rod/passaux.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -12,10 +12,6 @@ import strutils, ast, astalgo, passes, msgs, options -proc verbosePass*(): TPass -proc cleanupPass*(): TPass -# implementation - proc verboseOpen(s: PSym, filename: string): PPassContext = #MessageOut('compiling ' + s.name.s); result = nil # we don't need a context @@ -24,9 +20,9 @@ proc verboseOpen(s: PSym, filename: string): PPassContext = proc verboseProcess(context: PPassContext, n: PNode): PNode = result = n if context != nil: InternalError("logpass: context is not nil") - if gVerbosity == 3: liMessage(n.info, hintProcessing, $(ast.gid)) + if gVerbosity == 3: Message(n.info, hintProcessing, $ast.gid) -proc verbosePass(): TPass = +proc verbosePass*(): TPass = initPass(result) result.open = verboseOpen result.process = verboseProcess @@ -43,11 +39,11 @@ proc cleanUp(c: PPassContext, n: PNode): PNode = if (n.sons[namePos].kind == nkSym): s = n.sons[namePos].sym if not (sfDeadCodeElim in getModule(s).flags) and not astNeeded(s): - s.ast.sons[codePos] = nil # free the memory + s.ast.sons[codePos] = ast.emptyNode # free the memory else: nil -proc cleanupPass(): TPass = +proc cleanupPass*(): TPass = initPass(result) result.process = cleanUp result.close = cleanUp diff --git a/rod/passes.nim b/rod/passes.nim index 40036cb5a..b380cd66f 100755 --- a/rod/passes.nim +++ b/rod/passes.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -25,9 +25,9 @@ type close: proc (p: PPassContext, n: PNode): PNode, process: proc (p: PPassContext, topLevelStmt: PNode): PNode] -# a pass is a tuple of procedure vars ``TPass.close`` may produce additional +# a pass is a tuple of procedure vars ``TPass.close`` may produce additional # nodes. These are passed to the other close procedures. -# This mechanism is needed for the instantiation of generics. +# This mechanism used to be used for the instantiation of generics. proc registerPass*(p: TPass) proc initPass*(p: var TPass) @@ -37,11 +37,6 @@ proc initPass*(p: var TPass) # whole program optimizations. For now, we avoid it to save a lot of memory. proc processModule*(module: PSym, filename: string, stream: PLLStream, rd: PRodReader) -proc astNeeded*(s: PSym): bool - # The ``rodwrite`` module uses this to determine if the body of a proc - # needs to be stored. The passes manager frees s.sons[codePos] when - # appropriate to free the procedure body's memory. This is important - # to keep memory usage down. # the semantic checker needs these: var @@ -50,10 +45,21 @@ var # implementation -proc astNeeded(s: PSym): bool = +proc skipCodegen*(n: PNode): bool {.inline.} = + # can be used by codegen passes to determine whether they should do + # something with `n`. Currently, this ignores `n` and uses the global + # error count instead. + result = msgs.gErrorCounter > 0 + +proc astNeeded*(s: PSym): bool = + # The ``rodwrite`` module uses this to determine if the body of a proc + # needs to be stored. The passes manager frees s.sons[codePos] when + # appropriate to free the procedure body's memory. This is important + # to keep memory usage down. if (s.kind in {skMethod, skProc}) and ({sfCompilerProc, sfCompileTime} * s.flags == {}) and - (s.typ.callConv != ccInline) and (s.ast.sons[genericParamsPos] == nil): + (s.typ.callConv != ccInline) and + (s.ast.sons[genericParamsPos].kind == nkEmpty): result = false else: result = true diff --git a/rod/pnimsyn.nim b/rod/pnimsyn.nim index 7734d7490..fb2b7429e 100755 --- a/rod/pnimsyn.nim +++ b/rod/pnimsyn.nim @@ -117,7 +117,7 @@ proc indAndComment(p: var TParser, n: PNode) = var info = parLineInfo(p) getTok(p) if p.tok.tokType == tkComment: skipComment(p, n) - else: liMessage(info, errInvalidIndentation) + else: LocalError(info, errInvalidIndentation) else: skipComment(p, n) diff --git a/rod/pragmas.nim b/rod/pragmas.nim index d19c8d58e..45543eb74 100755 --- a/rod/pragmas.nim +++ b/rod/pragmas.nim @@ -52,7 +52,7 @@ proc pragmaAsm*(c: PContext, n: PNode): char # implementation proc invalidPragma(n: PNode) = - liMessage(n.info, errInvalidPragmaX, renderTree(n, {renderNoComments})) + LocalError(n.info, errInvalidPragmaX, renderTree(n, {renderNoComments})) proc pragmaAsm(c: PContext, n: PNode): char = result = '\0' @@ -82,27 +82,24 @@ proc MakeExternExport(s: PSym, extname: string) = proc getStrLitNode(c: PContext, n: PNode): PNode = if n.kind != nkExprColonExpr: - liMessage(n.info, errStringLiteralExpected) + GlobalError(n.info, errStringLiteralExpected) else: n.sons[1] = c.semConstExpr(c, n.sons[1]) case n.sons[1].kind of nkStrLit, nkRStrLit, nkTripleStrLit: result = n.sons[1] - else: liMessage(n.info, errStringLiteralExpected) + else: GlobalError(n.info, errStringLiteralExpected) proc expectStrLit(c: PContext, n: PNode): string = result = getStrLitNode(c, n).strVal proc expectIntLit(c: PContext, n: PNode): int = if n.kind != nkExprColonExpr: - liMessage(n.info, errIntLiteralExpected) - result = 0 + LocalError(n.info, errIntLiteralExpected) else: n.sons[1] = c.semConstExpr(c, n.sons[1]) case n.sons[1].kind of nkIntLit..nkInt64Lit: result = int(n.sons[1].intVal) - else: - liMessage(n.info, errIntLiteralExpected) - result = 0 + else: LocalError(n.info, errIntLiteralExpected) proc getOptionalStr(c: PContext, n: PNode, defaultStr: string): string = if n.kind == nkExprColonExpr: result = expectStrLit(c, n) @@ -112,7 +109,9 @@ proc processMagic(c: PContext, n: PNode, s: PSym) = var v: string #if not (sfSystemModule in c.module.flags) then # liMessage(n.info, errMagicOnlyInSystem); - if n.kind != nkExprColonExpr: liMessage(n.info, errStringLiteralExpected) + if n.kind != nkExprColonExpr: + LocalError(n.info, errStringLiteralExpected) + return if n.sons[1].kind == nkIdent: v = n.sons[1].ident.s else: v = expectStrLit(c, n) incl(s.flags, sfImportc) @@ -123,7 +122,7 @@ proc processMagic(c: PContext, n: PNode, s: PSym) = if copy($m, 1) == v: s.magic = m return - liMessage(n.info, warnUnknownMagic, v) + Message(n.info, warnUnknownMagic, v) proc wordToCallConv(sw: TSpecialWord): TCallingConvention = # this assumes that the order of special words and calling conventions is @@ -135,9 +134,9 @@ proc IsTurnedOn(c: PContext, n: PNode): bool = case whichKeyword(n.sons[1].ident) of wOn: result = true of wOff: result = false - else: liMessage(n.info, errOnOrOffExpected) + else: LocalError(n.info, errOnOrOffExpected) else: - liMessage(n.info, errOnOrOffExpected) + LocalError(n.info, errOnOrOffExpected) proc onOff(c: PContext, n: PNode, op: TOptions) = if IsTurnedOn(c, n): gOptions = gOptions + op @@ -153,9 +152,9 @@ proc processCallConv(c: PContext, n: PNode) = case sw of firstCallConv..lastCallConv: POptionEntry(c.optionStack.tail).defaultCC = wordToCallConv(sw) - else: liMessage(n.info, errCallConvExpected) + else: LocalError(n.info, errCallConvExpected) else: - liMessage(n.info, errCallConvExpected) + LocalError(n.info, errCallConvExpected) proc getLib(c: PContext, kind: TLibKind, path: PNode): PLib = var it = PLib(c.libs.head) @@ -168,13 +167,13 @@ proc getLib(c: PContext, kind: TLibKind, path: PNode): PLib = Append(c.libs, result) proc expectDynlibNode(c: PContext, n: PNode): PNode = - if n.kind != nkExprColonExpr: liMessage(n.info, errStringLiteralExpected) + if n.kind != nkExprColonExpr: GlobalError(n.info, errStringLiteralExpected) else: result = c.semExpr(c, n.sons[1]) if result.kind == nkSym and result.sym.kind == skConst: result = result.sym.ast # look it up if result.typ == nil or result.typ.kind != tyString: - liMessage(n.info, errStringLiteralExpected) + GlobalError(n.info, errStringLiteralExpected) proc processDynLib(c: PContext, n: PNode, sym: PSym) = if (sym == nil) or (sym.kind == skModule): @@ -208,7 +207,7 @@ proc processNote(c: PContext, n: PNode) = case whichKeyword(n.sons[1].ident) of wOn: incl(gNotes, nk) of wOff: excl(gNotes, nk) - else: liMessage(n.info, errOnOrOffExpected) + else: LocalError(n.info, errOnOrOffExpected) else: invalidPragma(n) @@ -254,8 +253,8 @@ proc processOption(c: PContext, n: PNode) = of wNone: excl(gOptions, optOptimizeSpeed) excl(gOptions, optOptimizeSize) - else: liMessage(n.info, errNoneSpeedOrSizeExpected) - else: liMessage(n.info, errOptionExpected) + else: LocalError(n.info, errNoneSpeedOrSizeExpected) + else: LocalError(n.info, errOptionExpected) proc processPush(c: PContext, n: PNode, start: int) = var x = newOptionEntry() @@ -271,7 +270,7 @@ proc processPush(c: PContext, n: PNode, start: int) = proc processPop(c: PContext, n: PNode) = if c.optionStack.counter <= 1: - liMessage(n.info, errAtPopWithoutPush) + LocalError(n.info, errAtPopWithoutPush) else: gOptions = POptionEntry(c.optionStack.tail).options #liMessage(n.info, warnUser, ropeToStr(optionsToStr(gOptions))); @@ -281,14 +280,14 @@ proc processPop(c: PContext, n: PNode) = proc processDefine(c: PContext, n: PNode) = if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent): DefineSymbol(n.sons[1].ident.s) - liMessage(n.info, warnDeprecated, "define") + Message(n.info, warnDeprecated, "define") else: invalidPragma(n) proc processUndef(c: PContext, n: PNode) = if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent): UndefSymbol(n.sons[1].ident.s) - liMessage(n.info, warnDeprecated, "undef") + Message(n.info, warnDeprecated, "undef") else: invalidPragma(n) @@ -329,7 +328,7 @@ proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode = of nkStrLit, nkRStrLit, nkTripleStrLit: result = copyNode(n) var str = n.sons[1].strVal - if str == "": liMessage(n.info, errEmptyAsm) + if str == "": GlobalError(n.info, errEmptyAsm) # now parse the string literal and substitute symbols: var a = 0 while true: @@ -392,14 +391,16 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) = of wExtern: setExternName(sym, expectStrLit(c, it)) of wAlign: if sym.typ == nil: invalidPragma(it) - sym.typ.align = expectIntLit(c, it) - if not IsPowerOfTwo(sym.typ.align) and (sym.typ.align != 0): - liMessage(it.info, errPowerOfTwoExpected) + var align = expectIntLit(c, it) + if not IsPowerOfTwo(align) and align != 0: + LocalError(it.info, errPowerOfTwoExpected) + else: + sym.typ.align = align of wSize: if sym.typ == nil: invalidPragma(it) var size = expectIntLit(c, it) if not IsPowerOfTwo(size) or size <= 0 or size > 8: - liMessage(it.info, errPowerOfTwoExpected) + LocalError(it.info, errPowerOfTwoExpected) else: sym.typ.size = size of wNodecl: @@ -477,12 +478,10 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) = of wTypeCheck: noVal(it) incl(sym.flags, sfTypeCheck) - of wHint: liMessage(it.info, hintUser, expectStrLit(c, it)) - of wWarning: liMessage(it.info, warnUser, expectStrLit(c, it)) - of wError: liMessage(it.info, errUser, expectStrLit(c, it)) - of wFatal: - liMessage(it.info, errUser, expectStrLit(c, it)) - quit(1) + of wHint: Message(it.info, hintUser, expectStrLit(c, it)) + of wWarning: Message(it.info, warnUser, expectStrLit(c, it)) + of wError: LocalError(it.info, errUser, expectStrLit(c, it)) + of wFatal: Fatal(it.info, errUser, expectStrLit(c, it)) of wDefine: processDefine(c, it) of wUndef: processUndef(c, it) of wCompile: processCompile(c, it) @@ -515,7 +514,7 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) = else: processNote(c, it) if (sym != nil) and (sym.kind != skModule): if (lfExportLib in sym.loc.flags) and not (sfExportc in sym.flags): - liMessage(n.info, errDynlibRequiresExportc) + LocalError(n.info, errDynlibRequiresExportc) var lib = POptionEntry(c.optionstack.tail).dynlib if ({lfDynamicLib, lfHeader} * sym.loc.flags == {}) and (sfImportc in sym.flags) and (lib != nil): diff --git a/rod/procfind.nim b/rod/procfind.nim index bd5b3841f..2bfa27494 100755 --- a/rod/procfind.nim +++ b/rod/procfind.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -50,7 +50,7 @@ proc SearchForProc(c: PContext, fn: PSym, tos: int): PSym = of paramsEqual: return of paramsIncompatible: - liMessage(fn.info, errNotOverloadable, fn.name.s) + LocalError(fn.info, errNotOverloadable, fn.name.s) return of paramsNotEqual: nil diff --git a/rod/ptmplsyn.nim b/rod/ptmplsyn.nim index 24cce2f0e..f428c6df8 100755 --- a/rod/ptmplsyn.nim +++ b/rod/ptmplsyn.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -94,7 +94,7 @@ proc parseLine(p: var TTmplParser) = dec(p.indent, 2) else: p.info.col = int16(j) - liMessage(p.info, errXNotAllowedHere, "end") + LocalError(p.info, errXNotAllowedHere, "end") LLStreamWrite(p.outp, repeatChar(p.indent)) LLStreamWrite(p.outp, "#end") of wIf, wWhen, wTry, wWhile, wFor, wBlock, wCase, wProc, wIterator, @@ -163,7 +163,8 @@ proc parseLine(p: var TTmplParser) = while true: case p.x[j] of '\0': - liMessage(p.info, errXExpected, "}") + LocalError(p.info, errXExpected, "}") + break of '{': inc(j) inc(curly) @@ -196,7 +197,7 @@ proc parseLine(p: var TTmplParser) = inc(j) else: p.info.col = int16(j) - liMessage(p.info, errInvalidExpression, "$") + LocalError(p.info, errInvalidExpression, "$") else: LLStreamWrite(p.outp, p.x[j]) inc(j) diff --git a/rod/rodutils.nim b/rod/rodutils.nim index dad5d679f..dad5d679f 100644..100755 --- a/rod/rodutils.nim +++ b/rod/rodutils.nim diff --git a/rod/rst.nim b/rod/rst.nim index 207640b2c..efda9bd9a 100755 --- a/rod/rst.nim +++ b/rod/rst.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -288,10 +288,10 @@ proc tokInfo(p: TRstParser, tok: TToken): TLineInfo = result = newLineInfo(p.filename, p.line + tok.line, p.col + tok.col) proc rstMessage(p: TRstParser, msgKind: TMsgKind, arg: string) = - liMessage(tokInfo(p, p.tok[p.idx]), msgKind, arg) + GenericMessage(tokInfo(p, p.tok[p.idx]), msgKind, arg) proc rstMessage(p: TRstParser, msgKind: TMsgKind) = - liMessage(tokInfo(p, p.tok[p.idx]), msgKind, p.tok[p.idx].symbol) + GenericMessage(tokInfo(p, p.tok[p.idx]), msgKind, p.tok[p.idx].symbol) proc currInd(p: TRstParser): int = result = p.indentStack[high(p.indentStack)] diff --git a/rod/scanner.nim b/rod/scanner.nim index 1ef688dd3..2560eb6f9 100755 --- a/rod/scanner.nim +++ b/rod/scanner.nim @@ -223,11 +223,11 @@ proc getLineInfo(L: TLexer): TLineInfo = result = newLineInfo(L.filename, L.linenumber, getColNumber(L, L.bufpos)) proc lexMessage(L: TLexer, msg: TMsgKind, arg = "") = - msgs.liMessage(getLineInfo(L), msg, arg) + msgs.Message(getLineInfo(L), msg, arg) proc lexMessagePos(L: var TLexer, msg: TMsgKind, pos: int, arg = "") = var info = newLineInfo(L.filename, L.linenumber, pos - L.lineStart) - msgs.liMessage(info, msg, arg) + msgs.Message(info, msg, arg) proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: TCharSet) = var pos = L.bufpos # use registers for pos, buf diff --git a/rod/sem.nim b/rod/sem.nim index ac2f21857..1e6ec9080 100755 --- a/rod/sem.nim +++ b/rod/sem.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -25,7 +25,7 @@ proc considerAcc(n: PNode): PIdent = of nkIdent: result = x.ident of nkSym: result = x.sym.name else: - liMessage(n.info, errIdentifierExpected, renderTree(n)) + GlobalError(n.info, errIdentifierExpected, renderTree(n)) result = nil proc isTopLevel(c: PContext): bool = @@ -37,7 +37,7 @@ proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym = proc markUsed(n: PNode, s: PSym) = incl(s.flags, sfUsed) - if sfDeprecated in s.flags: liMessage(n.info, warnDeprecated, s.name.s) + if sfDeprecated in s.flags: Message(n.info, warnDeprecated, s.name.s) proc semIdentVis(c: PContext, kind: TSymKind, n: PNode, allowed: TSymFlags): PSym # identifier with visability @@ -65,22 +65,22 @@ proc instGenericContainer(c: PContext, n: PNode, header: PType): PType proc semConstExpr(c: PContext, n: PNode): PNode = result = semExprWithType(c, n) if result == nil: - liMessage(n.info, errConstExprExpected) + GlobalError(n.info, errConstExprExpected) return result = getConstExpr(c.module, result) - if result == nil: liMessage(n.info, errConstExprExpected) + if result == nil: GlobalError(n.info, errConstExprExpected) proc semAndEvalConstExpr(c: PContext, n: PNode): PNode = var e = semExprWithType(c, n) if e == nil: - liMessage(n.info, errConstExprExpected) + GlobalError(n.info, errConstExprExpected) return nil result = getConstExpr(c.module, e) if result == nil: #writeln(output, renderTree(n)); result = evalConstExpr(c.module, e) if (result == nil) or (result.kind == nkEmpty): - liMessage(n.info, errConstExprExpected) + GlobalError(n.info, errConstExprExpected) proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode = result = n @@ -91,7 +91,7 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode = result = semExpr(c, result) # semExprWithType(c, result) of tyStmt: result = semStmt(c, result) of tyTypeDesc: result.typ = semTypeNode(c, result, nil) - else: liMessage(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0])) + else: GlobalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0])) include "semtempl.nim" @@ -99,7 +99,7 @@ proc semMacroExpr(c: PContext, n: PNode, sym: PSym, semCheck: bool = true): PNode = inc(evalTemplateCounter) if evalTemplateCounter > 100: - liMessage(n.info, errTemplateInstantiationTooNested) + GlobalError(n.info, errTemplateInstantiationTooNested) markUsed(n, sym) var p = newEvalContext(c.module, "", false) var s = newStackFrame() @@ -111,23 +111,23 @@ proc semMacroExpr(c: PContext, n: PNode, sym: PSym, discard eval(p, sym.ast.sons[codePos]) result = s.params[0] popStackFrame(p) - if cyclicTree(result): liMessage(n.info, errCyclicTree) + if cyclicTree(result): GlobalError(n.info, errCyclicTree) if semCheck: result = semAfterMacroCall(c, result, sym) dec(evalTemplateCounter) -include "seminst.nim", "sigmatch.nim" +include seminst, sigmatch proc CheckBool(t: PNode) = if (t.Typ == nil) or (skipTypes(t.Typ, {tyGenericInst, tyVar, tyOrdinal}).kind != tyBool): - liMessage(t.Info, errExprMustBeBool) + LocalError(t.Info, errExprMustBeBool) proc typeMismatch(n: PNode, formal, actual: PType) = - liMessage(n.Info, errGenerated, msgKindToString(errTypeMismatch) & + GlobalError(n.Info, errGenerated, msgKindToString(errTypeMismatch) & typeToString(actual) & ") " & `%`(msgKindToString(errButExpectedX), [typeToString(formal)])) -include "semtypes.nim", "semexprs.nim", "semgnrc.nim", "semstmts.nim" +include semtypes, semexprs, semgnrc, semstmts proc addCodeForGenerics(c: PContext, n: PNode) = for i in countup(c.lastGenericIdx, sonsLen(c.generics) - 1): @@ -166,19 +166,28 @@ proc myOpenCached(module: PSym, filename: string, rd: PRodReader): PPassContext c.fromCache = true result = c -proc myProcess(context: PPassContext, n: PNode): PNode = - result = nil - var c = PContext(context) - result = semStmt(c, n) +proc SemStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = + result = semStmt(c, n) # BUGFIX: process newly generated generics here, not at the end! if sonsLen(c.generics) > 0: var a = newNodeI(nkStmtList, n.info) addCodeForGenerics(c, a) if sonsLen(a) > 0: # a generic has been added to `a`: - addSonIfNotNil(a, result) + if result.kind != nkEmpty: addSon(a, result) result = a +proc myProcess(context: PPassContext, n: PNode): PNode = + var c = PContext(context) + # no need for an expensive 'try' if we stop after the first error anyway: + if msgs.gErrorMax <= 1: + result = SemStmtAndGenerateGenerics(c, n) + else: + try: + result = SemStmtAndGenerateGenerics(c, n) + except ERecoverableError: + result = ast.emptyNode + proc myClose(context: PPassContext, n: PNode): PNode = var c = PContext(context) closeScope(c.tab) # close module's scope diff --git a/rod/semdata.nim b/rod/semdata.nim index ebad21ad8..5b7425a96 100755 --- a/rod/semdata.nim +++ b/rod/semdata.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -69,10 +69,6 @@ proc makeVarType*(c: PContext, baseType: PType): PType proc newTypeS*(kind: TTypeKind, c: PContext): PType proc fillTypeS*(dest: PType, kind: TTypeKind, c: PContext) proc makeRangeType*(c: PContext, first, last: biggestInt, info: TLineInfo): PType -proc illFormedAst*(n: PNode) -proc getSon*(n: PNode, indx: int): PNode -proc checkSonsLen*(n: PNode, length: int) -proc checkMinSonsLen*(n: PNode, length: int) # owner handling: proc getCurrOwner*(): PSym @@ -122,7 +118,7 @@ proc newContext(module: PSym, nimfile: string): PContext = append(result.optionStack, newOptionEntry()) result.module = module result.generics = newNode(nkStmtList) - result.converters = @ [] + result.converters = @[] result.filename = nimfile IntSetInit(result.includedFiles) initStrTable(result.userPragmas) @@ -140,7 +136,7 @@ proc newLib(kind: TLibKind): PLib = proc addToLib(lib: PLib, sym: PSym) = #ObjectSetIncl(lib.syms, sym); - if sym.annex != nil: liMessage(sym.info, errInvalidPragma) + if sym.annex != nil: LocalError(sym.info, errInvalidPragma) sym.annex = lib proc makePtrType(c: PContext, baseType: PType): PType = @@ -170,20 +166,13 @@ proc makeRangeType(c: PContext, first, last: biggestInt, result.n = n addSon(result, getSysType(tyInt)) # basetype of range -proc illFormedAst(n: PNode) = - liMessage(n.info, errIllFormedAstX, renderTree(n, {renderNoComments})) - -proc getSon(n: PNode, indx: int): PNode = - if (n != nil) and (indx < sonsLen(n)): - result = n.sons[indx] - else: - illFormedAst(n) - result = nil - -proc checkSonsLen(n: PNode, length: int) = - if (n == nil) or (sonsLen(n) != length): illFormedAst(n) +proc illFormedAst*(n: PNode) = + GlobalError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments})) + +proc checkSonsLen*(n: PNode, length: int) = + if sonsLen(n) != length: illFormedAst(n) -proc checkMinSonsLen(n: PNode, length: int) = - if (n == nil) or (sonsLen(n) < length): illFormedAst(n) +proc checkMinSonsLen*(n: PNode, length: int) = + if sonsLen(n) < length: illFormedAst(n) initIdTable(gInstTypes) diff --git a/rod/semexprs.nim b/rod/semexprs.nim index cdcf09d3e..0478cff82 100755 --- a/rod/semexprs.nim +++ b/rod/semexprs.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -23,22 +23,24 @@ proc semTemplateExpr(c: PContext, n: PNode, s: PSym, 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 == nil: InternalError("semExprWithType") - if (result.typ == nil): - liMessage(n.info, errExprXHasNoType, renderTree(result, {renderNoComments})) - if result.typ.kind == tyVar: - var d = newNodeIT(nkHiddenDeref, result.info, result.typ.sons[0]) - addSon(d, result) - result = d - + if result.kind == nkEmpty: InternalError("semExprWithType") + if result.typ != nil: + if result.typ.kind == tyVar: + var d = newNodeIT(nkHiddenDeref, result.info, result.typ.sons[0]) + addSon(d, result) + result = d + else: + GlobalError(n.info, errExprXHasNoType, + renderTree(result, {renderNoComments})) + proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = if s.kind == skType and efAllowType notin flags: - liMessage(n.info, errATypeHasNoValue) + GlobalError(n.info, errATypeHasNoValue) case s.kind of skProc, skMethod, skIterator, skConverter: if not (sfProcVar in s.flags) and (s.typ.callConv == ccDefault) and (getModule(s).id != c.module.id): - liMessage(n.info, errXCannotBePassedToProcVar, s.name.s) + LocalError(n.info, errXCannotBePassedToProcVar, s.name.s) result = symChoice(c, n, s) of skConst: # @@ -79,7 +81,7 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = proc checkConversionBetweenObjects(info: TLineInfo, castDest, src: PType) = var diff = inheritanceDiff(castDest, src) if diff == high(int): - liMessage(info, errGenerated, `%`(MsgKindToString(errIllegalConvFromXtoY), [ + GlobalError(info, errGenerated, `%`(MsgKindToString(errIllegalConvFromXtoY), [ typeToString(src), typeToString(castDest)])) proc checkConvertible(info: TLineInfo, castDest, src: PType) = @@ -88,7 +90,7 @@ proc checkConvertible(info: TLineInfo, castDest, src: PType) = if sameType(castDest, src): # don't annoy conversions that may be needed on another processor: if not (castDest.kind in {tyInt..tyFloat128, tyNil}): - liMessage(info, hintConvFromXtoItselfNotNeeded, typeToString(castDest)) + Message(info, hintConvFromXtoItselfNotNeeded, typeToString(castDest)) return var d = skipTypes(castDest, abstractVar) var s = skipTypes(src, abstractVar) @@ -96,9 +98,9 @@ proc checkConvertible(info: TLineInfo, castDest, src: PType) = d = base(d) s = base(s) if d == nil: - liMessage(info, errGenerated, `%`(msgKindToString(errIllegalConvFromXtoY), [ + GlobalError(info, errGenerated, `%`(msgKindToString(errIllegalConvFromXtoY), [ typeToString(src), typeToString(castDest)])) - if (d.Kind == tyObject) and (s.Kind == tyObject): + elif d.Kind == tyObject and s.Kind == tyObject: checkConversionBetweenObjects(info, d, s) elif (skipTypes(castDest, abstractVarRange).Kind in IntegralTypes) and (skipTypes(src, abstractVarRange).Kind in IntegralTypes): @@ -109,7 +111,7 @@ proc checkConvertible(info: TLineInfo, castDest, src: PType) = of isNone, isGeneric: if not equalOrDistinctOf(castDest, src) and not equalOrDistinctOf(src, castDest): - liMessage(info, errGenerated, `%`( + GlobalError(info, errGenerated, `%`( MsgKindToString(errIllegalConvFromXtoY), [typeToString(src), typeToString(castDest)])) else: @@ -134,7 +136,7 @@ proc isCastable(dst, src: PType): bool = (skipTypes(src, abstractInst).kind in {tyInt..tyFloat128}) proc semConv(c: PContext, n: PNode, s: PSym): PNode = - if sonsLen(n) != 2: liMessage(n.info, errConvNeedsOneArg) + if sonsLen(n) != 2: GlobalError(n.info, errConvNeedsOneArg) result = newNodeI(nkConv, n.info) result.typ = semTypeNode(c, n.sons[0], nil) addSon(result, copyTree(n.sons[0])) @@ -147,10 +149,10 @@ proc semConv(c: PContext, n: PNode, s: PSym): PNode = if sameType(result.typ, op.sons[i].typ): markUsed(n, op.sons[i].sym) return op.sons[i] - liMessage(n.info, errUseQualifier, op.sons[0].sym.name.s) + localError(n.info, errUseQualifier, op.sons[0].sym.name.s) proc semCast(c: PContext, n: PNode): PNode = - if optSafeCode in gGlobalOptions: liMessage(n.info, errCastNotInSafeMode) + if optSafeCode in gGlobalOptions: localError(n.info, errCastNotInSafeMode) incl(c.p.owner.flags, sfSideEffect) checkSonsLen(n, 2) result = newNodeI(nkCast, n.info) @@ -158,13 +160,13 @@ proc semCast(c: PContext, n: PNode): PNode = addSon(result, copyTree(n.sons[0])) addSon(result, semExprWithType(c, n.sons[1])) if not isCastable(result.typ, result.sons[1].Typ): - liMessage(result.info, errExprCannotBeCastedToX, typeToString(result.Typ)) + GlobalError(result.info, errExprCannotBeCastedToX, typeToString(result.Typ)) proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode = const opToStr: array[mLow..mHigh, string] = ["low", "high"] if sonsLen(n) != 2: - liMessage(n.info, errXExpectsTypeOrValue, opToStr[m]) + GlobalError(n.info, errXExpectsTypeOrValue, opToStr[m]) else: n.sons[1] = semExprWithType(c, n.sons[1], {efAllowType}) var typ = skipTypes(n.sons[1].typ, abstractVarRange) @@ -175,11 +177,11 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode = n.typ = n.sons[1].typ.sons[0] # indextype of tyInt..tyInt64, tyChar, tyBool, tyEnum: n.typ = n.sons[1].typ - else: liMessage(n.info, errInvalidArgForX, opToStr[m]) + else: GlobalError(n.info, errInvalidArgForX, opToStr[m]) result = n proc semSizeof(c: PContext, n: PNode): PNode = - if sonsLen(n) != 2: liMessage(n.info, errXExpectsTypeOrValue, "sizeof") + if sonsLen(n) != 2: GlobalError(n.info, errXExpectsTypeOrValue, "sizeof") else: n.sons[1] = semExprWithType(c, n.sons[1], {efAllowType}) n.typ = getSysType(tyInt) result = n @@ -190,20 +192,22 @@ proc semIs(c: PContext, n: PNode): PNode = n.sons[2] = semExprWithType(c, n.sons[2], {efAllowType}) var a = n.sons[1].typ var b = n.sons[2].typ - if (b.kind != tyObject) or (a.kind != tyObject): - liMessage(n.info, errIsExpectsObjectTypes) - while (b != nil) and (b.id != a.id): b = b.sons[0] - if b == nil: liMessage(n.info, errXcanNeverBeOfThisSubtype, typeToString(a)) + # a and b can be nil in case of an error: + if a != nil and b != nil: + if (b.kind != tyObject) or (a.kind != tyObject): + GlobalError(n.info, errIsExpectsObjectTypes) + while (b != nil) and (b.id != a.id): b = b.sons[0] + if b == nil: + GlobalError(n.info, errXcanNeverBeOfThisSubtype, typeToString(a)) n.typ = getSysType(tyBool) else: - liMessage(n.info, errIsExpectsTwoArguments) + GlobalError(n.info, errIsExpectsTwoArguments) result = n proc semOpAux(c: PContext, n: PNode) = for i in countup(1, sonsLen(n) - 1): var a = n.sons[i] - if a.kind == nkExprEqExpr: - checkSonsLen(a, 2) + if a.kind == nkExprEqExpr and sonsLen(a) == 2: var info = a.sons[0].info a.sons[0] = newIdentNode(considerAcc(a.sons[0]), info) a.sons[1] = semExprWithType(c, a.sons[1]) @@ -223,9 +227,6 @@ proc overloadedCallOpr(c: PContext, n: PNode): PNode = result = semExpr(c, result) proc changeType(n: PNode, newType: PType) = - var - f: PSym - a, m: PNode case n.kind of nkCurly, nkBracket: for i in countup(0, sonsLen(n) - 1): changeType(n.sons[i], elemType(newType)) @@ -235,22 +236,21 @@ proc changeType(n: PNode, newType: PType) = if newType.n == nil: InternalError(n.info, "changeType: no tuple fields") if (sonsLen(n) > 0) and (n.sons[0].kind == nkExprColonExpr): for i in countup(0, sonsLen(n) - 1): - m = n.sons[i].sons[0] + var m = n.sons[i].sons[0] if m.kind != nkSym: internalError(m.info, "changeType(): invalid tuple constr") - f = getSymFromList(newType.n, m.sym.name) + var f = getSymFromList(newType.n, m.sym.name) if f == nil: internalError(m.info, "changeType(): invalid identifier") changeType(n.sons[i].sons[1], f.typ) else: for i in countup(0, sonsLen(n) - 1): - m = n.sons[i] - a = newNodeIT(nkExprColonExpr, m.info, newType.sons[i]) + var m = n.sons[i] + var a = newNodeIT(nkExprColonExpr, m.info, newType.sons[i]) addSon(a, newSymNode(newType.n.sons[i].sym)) addSon(a, m) changeType(m, newType.sons[i]) n.sons[i] = a - else: - nil + else: nil n.typ = newType proc semArrayConstr(c: PContext, n: PNode): PNode = @@ -263,7 +263,7 @@ proc semArrayConstr(c: PContext, n: PNode): PNode = var x = n.sons[0] var lastIndex: biggestInt = 0 var indexType = getSysType(tyInt) - if x.kind == nkExprColonExpr: + if x.kind == nkExprColonExpr and sonsLen(x) == 2: var idx = semConstExpr(c, x.sons[0]) lastIndex = getOrdValue(idx) indexType = idx.typ @@ -273,11 +273,11 @@ proc semArrayConstr(c: PContext, n: PNode): PNode = var typ = skipTypes(result.sons[0].typ, {tyGenericInst, tyVar, tyOrdinal}) for i in countup(1, sonsLen(n) - 1): x = n.sons[i] - if x.kind == nkExprColonExpr: + if x.kind == nkExprColonExpr and sonsLen(x) == 2: var idx = semConstExpr(c, x.sons[0]) idx = fitNode(c, indexType, idx) if lastIndex+1 != getOrdValue(idx): - liMessage(x.info, errInvalidOrderInArrayConstructor) + localError(x.info, errInvalidOrderInArrayConstructor) x = x.sons[1] n.sons[i] = semExprWithType(c, x) @@ -334,7 +334,6 @@ proc isAssignable(n: PNode): TAssignableResult = of nkSym: if (n.sym.kind in {skVar, skTemp}): result = arLValue of nkDotExpr: - checkMinSonsLen(n, 1) if skipTypes(n.sons[0].typ, abstractInst).kind in {tyVar, tyPtr, tyRef}: result = arLValue else: @@ -342,7 +341,6 @@ proc isAssignable(n: PNode): TAssignableResult = if (result == arLValue) and (sfDiscriminant in n.sons[1].sym.flags): result = arDiscriminant of nkBracketExpr: - checkMinSonsLen(n, 1) if skipTypes(n.sons[0].typ, abstractInst).kind in {tyVar, tyPtr, tyRef}: result = arLValue else: @@ -368,7 +366,7 @@ proc newHiddenAddrTaken(c: PContext, n: PNode): PNode = result = newNodeIT(nkHiddenAddr, n.info, makeVarType(c, n.typ)) addSon(result, n) if isAssignable(n) != arLValue: - liMessage(n.info, errVarForOutParamNeeded) + localError(n.info, errVarForOutParamNeeded) proc analyseIfAddressTaken(c: PContext, n: PNode): PNode = result = n @@ -403,7 +401,7 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) = for i in countup(1, sonsLen(n) - 1): if i < sonsLen(t) and skipTypes(t.sons[i], abstractInst).kind == tyVar: if isAssignable(n.sons[i]) != arLValue: - liMessage(n.sons[i].info, errVarForOutParamNeeded) + LocalError(n.sons[i].info, errVarForOutParamNeeded) return for i in countup(1, sonsLen(n) - 1): if (i < sonsLen(t)) and @@ -421,7 +419,7 @@ proc semDirectCallAnalyseEffects(c: PContext, n: PNode, InternalError("semDirectCallAnalyseEffects") var callee = result.sons[0].sym if (callee.kind == skIterator) and (callee.id == c.p.owner.id): - liMessage(n.info, errRecursiveDependencyX, callee.name.s) + GlobalError(n.info, errRecursiveDependencyX, callee.name.s) if not (sfNoSideEffect in callee.flags): if (sfForward in callee.flags) or ({sfImportc, sfSideEffect} * callee.flags != {}): @@ -456,7 +454,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = add(msg, typeToString(n.sons[i].typ)) add(msg, ")\n" & msgKindToString(errButExpected) & "\n" & typeToString(n.sons[0].typ)) - liMessage(n.Info, errGenerated, msg) + GlobalError(n.Info, errGenerated, msg) result = nil else: result = m.call @@ -471,8 +469,8 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = n.sons[0] = prc result = semDirectCallAnalyseEffects(c, n, flags) if result == nil: - liMessage(n.info, errExprXCannotBeCalled, - renderTree(n, {renderNoComments})) + GlobalError(n.info, errExprXCannotBeCalled, + renderTree(n, {renderNoComments})) fixAbstractType(c, result) analyseIfAddressTakenInCall(c, result) @@ -482,7 +480,7 @@ proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = result = semDirectCallAnalyseEffects(c, n, flags) if result == nil: result = overloadedCallOpr(c, n) - if result == nil: liMessage(n.Info, errGenerated, getNotFoundError(c, n)) + if result == nil: GlobalError(n.Info, errGenerated, getNotFoundError(c, n)) fixAbstractType(c, result) analyseIfAddressTakenInCall(c, result) @@ -517,12 +515,12 @@ proc LookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym = else: result = StrTableGet(m.tab, ident) else: - liMessage(n.sons[1].info, errIdentifierExpected, "") + GlobalError(n.sons[1].info, errIdentifierExpected, "") of nkAccQuoted: checkSonsLen(n, 1) result = lookupForDefined(c, n.sons[0], onlyCurrentScope) else: - liMessage(n.info, errIdentifierExpected, renderTree(n)) + GlobalError(n.info, errIdentifierExpected, renderTree(n)) result = nil proc semDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PNode = @@ -588,7 +586,7 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent, else: if check == nil: check = newNodeI(nkCheckedFieldExpr, n.info) - addSon(check, nil) # make space for access node + addSon(check, ast.emptyNode) # make space for access node s = newNodeI(nkCurly, n.info) for j in countup(0, sonsLen(it) - 2): addSon(s, copyTree(it.sons[j])) inExpr = newNodeI(nkCall, n.info) @@ -602,7 +600,7 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent, if result != nil: if check == nil: check = newNodeI(nkCheckedFieldExpr, n.info) - addSon(check, nil) # make space for access node + addSon(check, ast.emptyNode) # make space for access node inExpr = newNodeI(nkCall, n.info) addSon(inExpr, newIdentNode(getIdent("in"), n.info)) addSon(inExpr, copyTree(r.sons[0])) @@ -653,10 +651,10 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = result.typ = ty markUsed(n, f) else: - liMessage(n.sons[1].info, errEnumHasNoValueX, i.s) + GlobalError(n.sons[1].info, errEnumHasNoValueX, i.s) return elif not (efAllowType in flags) and isTypeExpr(n.sons[0]): - liMessage(n.sons[0].info, errATypeHasNoValue) + GlobalError(n.sons[0].info, errATypeHasNoValue) return ty = skipTypes(ty, {tyGenericInst, tyVar, tyPtr, tyRef}) var check: PNode = nil @@ -705,27 +703,27 @@ proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = addSon(result, newIdentNode(i, n.info)) addSon(result, copyTree(n[0])) else: - liMessage(n.Info, errUndeclaredFieldX, i.s) + GlobalError(n.Info, errUndeclaredFieldX, i.s) proc whichSliceOpr(n: PNode): string = - if (n.sons[0] == nil): - if (n.sons[1] == nil): result = "[..]" + if n.sons[0].kind == nkEmpty: + if n.sons[1].kind == nkEmpty: result = "[..]" else: result = "[..$]" - elif (n.sons[1] == nil): + elif n.sons[1].kind == nkEmpty: result = "[$..]" else: result = "[$..$]" proc addSliceOpr(result: var string, n: PNode) = - if n[0] == nil: - if n[1] == nil: result.add("..") + if n[0].kind == nkEmpty: + if n[1].kind == nkEmpty: result.add("..") else: result.add("..$") - elif n[1] == nil: result.add("$..") + elif n[1].kind == nkEmpty: result.add("$..") else: result.add("$..$") proc buildOverloadedSubscripts(n: PNode, inAsgn: bool): PNode = result = newNodeI(nkCall, n.info) - add(result, nil) # fill with the correct node later + add(result, ast.emptyNode) # fill with the correct node later add(result, n[0]) var opr = "[" for i in 1..n.len-1: @@ -734,8 +732,8 @@ proc buildOverloadedSubscripts(n: PNode, inAsgn: bool): PNode = # we have a slice argument checkSonsLen(n[i], 2) addSliceOpr(opr, n[i]) - addSonIfNotNil(result, n[i][0]) - addSonIfNotNil(result, n[i][1]) + addSon(result, n[i][0]) + addSon(result, n[i][1]) else: add(result, n[i]) if inAsgn: add(opr, "]=") @@ -757,7 +755,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = var indexType = if arr.kind == tyArray: arr.sons[0] else: getSysType(tyInt) var arg = IndexTypesMatch(c, indexType, n.sons[1].typ, n.sons[1]) if arg != nil: n.sons[1] = arg - else: liMessage(n.info, errIndexTypesDoNotMatch) + else: GlobalError(n.info, errIndexTypesDoNotMatch) result = n result.typ = elemType(arr) of tyTuple: @@ -769,9 +767,9 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = {tyInt..tyInt64}: var idx = getOrdValue(n.sons[1]) if (idx >= 0) and (idx < sonsLen(arr)): n.typ = arr.sons[int(idx)] - else: liMessage(n.info, errInvalidIndexValueForTuple) + else: GlobalError(n.info, errInvalidIndexValueForTuple) else: - liMessage(n.info, errIndexTypesDoNotMatch) + GlobalError(n.info, errIndexTypesDoNotMatch) result = n else: nil @@ -779,21 +777,7 @@ proc semArrayAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = result = semSubscript(c, n, flags) if result == nil: # overloaded [] operator: - when false: - result = newNodeI(nkCall, n.info) - if n.sons[1].kind == nkRange: - checkSonsLen(n.sons[1], 2) - addSon(result, newIdentNode(getIdent(whichSliceOpr(n.sons[1])), n.info)) - addSon(result, n.sons[0]) - addSonIfNotNil(result, n.sons[1].sons[0]) - addSonIfNotNil(result, n.sons[1].sons[1]) - else: - addSon(result, newIdentNode(getIdent("[]"), n.info)) - addSon(result, n.sons[0]) - addSon(result, n.sons[1]) - result = semExpr(c, result) - else: - result = semExpr(c, buildOverloadedSubscripts(n, inAsgn=false)) + result = semExpr(c, buildOverloadedSubscripts(n, inAsgn=false)) proc semIfExpr(c: PContext, n: PNode): PNode = result = n @@ -839,7 +823,7 @@ proc semSetConstr(c: PContext, n: PNode): PNode = if typ == nil: typ = skipTypes(n.sons[i].typ, {tyGenericInst, tyVar, tyOrdinal}) if not isOrdinalType(typ): - liMessage(n.info, errOrdinalTypeExpected) + GlobalError(n.info, errOrdinalTypeExpected) return if lengthOrd(typ) > MaxSetElements: typ = makeRangeType(c, 0, MaxSetElements - 1, n.info) @@ -871,11 +855,11 @@ proc checkPar(n: PNode): TParKind = if result == paTupleFields: if (n.sons[i].kind != nkExprColonExpr) or not (n.sons[i].sons[0].kind in {nkSym, nkIdent}): - liMessage(n.sons[i].info, errNamedExprExpected) + GlobalError(n.sons[i].info, errNamedExprExpected) return paNone else: if n.sons[i].kind == nkExprColonExpr: - liMessage(n.sons[i].info, errNamedExprNotAllowed) + GlobalError(n.sons[i].info, errNamedExprNotAllowed) return paNone proc semTupleFieldsConstr(c: PContext, n: PNode): PNode = @@ -892,7 +876,7 @@ proc semTupleFieldsConstr(c: PContext, n: PNode): PNode = if n.sons[i].sons[0].kind == nkIdent: id = n.sons[i].sons[0].ident else: id = n.sons[i].sons[0].sym.name if IntSetContainsOrIncl(ids, id.id): - liMessage(n.sons[i].info, errFieldInitTwice, id.s) + localError(n.sons[i].info, errFieldInitTwice, id.s) n.sons[i].sons[1] = semExprWithType(c, n.sons[i].sons[1]) var f = newSymS(skField, n.sons[i].sons[0], c) f.typ = n.sons[i].sons[1].typ @@ -925,7 +909,7 @@ proc semBlockExpr(c: PContext, n: PNode): PNode = Inc(c.p.nestedBlockCounter) checkSonsLen(n, 2) openScope(c.tab) # BUGFIX: label is in the scope of block! - if n.sons[0] != nil: addDecl(c, newSymS(skLabel, n.sons[0], c)) + if n.sons[0].kind != nkEmpty: addDecl(c, newSymS(skLabel, n.sons[0], c)) n.sons[1] = semStmtListExpr(c, n.sons[1]) n.typ = n.sons[1].typ closeScope(c.tab) @@ -935,7 +919,7 @@ proc isCallExpr(n: PNode): bool = result = n.kind in {nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit} -proc semMacroStmt(c: PContext, n: PNode, semCheck: bool = true): PNode = +proc semMacroStmt(c: PContext, n: PNode, semCheck = true): PNode = checkMinSonsLen(n, 2) var a: PNode if isCallExpr(n.sons[0]): a = n.sons[0].sons[0] @@ -957,23 +941,18 @@ proc semMacroStmt(c: PContext, n: PNode, semCheck: bool = true): PNode = addSon(result, n.sons[0].sons[i]) for i in countup(1, sonsLen(n) - 1): addSon(result, n.sons[i]) result = semTemplateExpr(c, result, s, semCheck) - else: liMessage(n.info, errXisNoMacroOrTemplate, s.name.s) + else: GlobalError(n.info, errXisNoMacroOrTemplate, s.name.s) else: - liMessage(n.info, errInvalidExpressionX, renderTree(a, {renderNoComments})) + GlobalError(n.info, errInvalidExpressionX, renderTree(a, {renderNoComments})) proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = n - if n == nil: return if nfSem in n.flags: return case n.kind # atoms: of nkIdent: var s = lookUp(c, n) result = semSym(c, n, s, flags) of nkSym: - #s := n.sym; - # include(s.flags, sfUsed); - # if (s.kind = skType) and not (efAllowType in flags) then - # liMessage(n.info, errATypeHasNoValue); # because of the changed symbol binding, this does not mean that we # don't have to check the symbol for semantics here again! result = semSym(c, n, n.sym, flags) @@ -982,7 +961,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of nkNilLit: result.typ = getSysType(tyNil) of nkType: - if not (efAllowType in flags): liMessage(n.info, errATypeHasNoValue) + if not (efAllowType in flags): GlobalError(n.info, errATypeHasNoValue) n.typ = semTypeNode(c, n, nil) of nkIntLit: if result.typ == nil: result.typ = getSysType(tyInt) @@ -1020,7 +999,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of skMacro: result = semMacroExpr(c, n, s) of skTemplate: result = semTemplateExpr(c, n, s) of skType: - if n.kind != nkCall: liMessage(n.info, errXisNotCallable, s.name.s) + if n.kind != nkCall: GlobalError(n.info, errXisNotCallable, s.name.s) # XXX does this check make any sense? result = semConv(c, n, s) of skProc, skMethod, skConverter, skIterator: @@ -1062,14 +1041,14 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar}) case t.kind of tyRef, tyPtr: n.typ = t.sons[0] - else: liMessage(n.sons[0].info, errCircumNeedsPointer) + else: GlobalError(n.sons[0].info, errCircumNeedsPointer) result = n of nkAddr: result = n checkSonsLen(n, 1) n.sons[0] = semExprWithType(c, n.sons[0]) if isAssignable(n.sons[0]) != arLValue: - liMessage(n.info, errExprHasNoAddress) + GlobalError(n.info, errExprHasNoAddress) n.typ = makePtrType(c, n.sons[0].typ) of nkHiddenAddr, nkHiddenDeref: checkSonsLen(n, 1) @@ -1091,8 +1070,8 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of nkCheckedFieldExpr: checkMinSonsLen(n, 2) of nkSymChoice: - liMessage(n.info, errExprXAmbiguous, renderTree(n, {renderNoComments})) + GlobalError(n.info, errExprXAmbiguous, renderTree(n, {renderNoComments})) else: #InternalError(n.info, nodeKindToStr[n.kind]); - liMessage(n.info, errInvalidExpressionX, renderTree(n, {renderNoComments})) + GlobalError(n.info, errInvalidExpressionX, renderTree(n, {renderNoComments})) incl(result.flags, nfSem) diff --git a/rod/semfold.nim b/rod/semfold.nim index a61ad0f8e..234d656f3 100755 --- a/rod/semfold.nim +++ b/rod/semfold.nim @@ -334,8 +334,10 @@ proc getConstExpr(m: PSym, n: PNode): PNode = of mSizeOf: var a = n.sons[1] if computeSize(a.typ) < 0: - liMessage(a.info, errCannotEvalXBecauseIncompletelyDefined, "sizeof") - if a.typ.kind in {tyArray, tyObject, tyTuple}: + LocalError(a.info, errCannotEvalXBecauseIncompletelyDefined, + "sizeof") + result = nil + elif a.typ.kind in {tyArray, tyObject, tyTuple}: result = nil # XXX: size computation for complex types is still wrong else: @@ -345,7 +347,8 @@ proc getConstExpr(m: PSym, n: PNode): PNode = of mHigh: if not (skipTypes(n.sons[1].typ, abstractVar).kind in {tyOpenArray, tySequence, tyString}): - result = newIntNodeT(lastOrd(skipTypes(n.sons[1].typ, abstractVar)), n) + result = newIntNodeT(lastOrd(skipTypes(n.sons[1].typ, abstractVar)), + n) of mLengthOpenArray: var a = n.sons[1] if a.kind == nkPassAsOpenArray: a = a.sons[0] @@ -357,9 +360,9 @@ proc getConstExpr(m: PSym, n: PNode): PNode = else: result = magicCall(m, n) except EOverflow: - liMessage(n.info, errOverOrUnderflow) + LocalError(n.info, errOverOrUnderflow) except EDivByZero: - liMessage(n.info, errConstantDivisionByZero) + LocalError(n.info, errConstantDivisionByZero) of nkAddr: var a = getConstExpr(m, n.sons[0]) if a != nil: @@ -408,7 +411,7 @@ proc getConstExpr(m: PSym, n: PNode): PNode = result = a # a <= x and x <= b result.typ = n.typ else: - liMessage(n.info, errGenerated, `%`( + LocalError(n.info, errGenerated, `%`( msgKindToString(errIllegalConvFromXtoY), [typeToString(n.sons[0].typ), typeToString(n.typ)])) of nkStringToCString, nkCStringToString: diff --git a/rod/semgnrc.nim b/rod/semgnrc.nim index 3ccd415f9..77c200120 100755 --- a/rod/semgnrc.nim +++ b/rod/semgnrc.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -55,7 +55,7 @@ proc getIdentNode(n: PNode): PNode = of nkIdent: result = n else: illFormedAst(n) - result = nil + result = n # of nkAccQuoted: # s = lookUp(c, n) @@ -67,21 +67,20 @@ proc semGenericStmt(c: PContext, n: PNode, flags: TSemGenericFlags = {}): PNode L: int a: PNode result = n - if n == nil: return case n.kind of nkIdent: var s = SymtabGet(c.Tab, n.ident) if s == nil: # no error if symbol cannot be bound, unless in ``bind`` context: if withinBind in flags: - liMessage(n.info, errUndeclaredIdentifier, n.ident.s) + localError(n.info, errUndeclaredIdentifier, n.ident.s) else: if withinBind in flags: result = symChoice(c, n, s) else: result = semGenericStmtSymbol(c, n, s) of nkDotExpr: var s = QualifiedLookUp(c, n, {}) if s != nil: result = semGenericStmtSymbol(c, n, s) - of nkSym..nkNilLit: + of nkEmpty, nkSym..nkNilLit: nil of nkBind: result = semGenericStmt(c, n.sons[0], {withinBind}) @@ -138,7 +137,7 @@ proc semGenericStmt(c: PContext, n: PNode, flags: TSemGenericFlags = {}): PNode of nkBlockStmt, nkBlockExpr, nkBlockType: checkSonsLen(n, 2) openScope(c.tab) - if n.sons[0] != nil: addDecl(c, newSymS(skUnknown, n.sons[0], c)) + if n.sons[0].kind != nkEmpty: addDecl(c, newSymS(skUnknown, n.sons[0], c)) n.sons[1] = semGenericStmt(c, n.sons[1]) closeScope(c.tab) of nkTryStmt: @@ -193,7 +192,7 @@ proc semGenericStmt(c: PContext, n: PNode, flags: TSemGenericFlags = {}): PNode if a.kind == nkCommentStmt: continue if (a.kind != nkTypeDef): IllFormedAst(a) checkSonsLen(a, 3) - if a.sons[1] != nil: + if a.sons[1].kind != nkEmpty: openScope(c.tab) a.sons[1] = semGenericStmt(c, a.sons[1]) a.sons[2] = semGenericStmt(c, a.sons[2], {withinTypeDesc}) @@ -202,7 +201,7 @@ proc semGenericStmt(c: PContext, n: PNode, flags: TSemGenericFlags = {}): PNode a.sons[2] = semGenericStmt(c, a.sons[2], {withinTypeDesc}) of nkEnumTy: checkMinSonsLen(n, 1) - if n.sons[0] != nil: + if n.sons[0].kind != nkEmpty: n.sons[0] = semGenericStmt(c, n.sons[0], {withinTypeDesc}) for i in countup(1, sonsLen(n) - 1): case n.sons[i].kind @@ -214,7 +213,7 @@ proc semGenericStmt(c: PContext, n: PNode, flags: TSemGenericFlags = {}): PNode nil of nkFormalParams: checkMinSonsLen(n, 1) - if n.sons[0] != nil: + if n.sons[0].kind != nkEmpty: n.sons[0] = semGenericStmt(c, n.sons[0], {withinTypeDesc}) for i in countup(1, sonsLen(n) - 1): a = n.sons[i] @@ -231,8 +230,8 @@ proc semGenericStmt(c: PContext, n: PNode, flags: TSemGenericFlags = {}): PNode addDecl(c, newSymS(skUnknown, getIdentNode(n.sons[0]), c)) openScope(c.tab) n.sons[genericParamsPos] = semGenericStmt(c, n.sons[genericParamsPos]) - if n.sons[paramsPos] != nil: - if n.sons[paramsPos].sons[0] != nil: + if n.sons[paramsPos].kind != nkEmpty: + if n.sons[paramsPos].sons[0].kind != nkEmpty: addDecl(c, newSym(skUnknown, getIdent("result"), nil)) n.sons[paramsPos] = semGenericStmt(c, n.sons[paramsPos]) n.sons[pragmasPos] = semGenericStmt(c, n.sons[pragmasPos]) diff --git a/rod/seminst.nim b/rod/seminst.nim index 7954d2e8f..f2acdba60 100755 --- a/rod/seminst.nim +++ b/rod/seminst.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -48,7 +48,9 @@ proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable) = if not (q.typ.kind in {tyTypeDesc, tyGenericParam}): continue var s = newSym(skType, q.name, getCurrOwner()) var t = PType(IdTableGet(pt, q.typ)) - if t == nil: liMessage(a.info, errCannotInstantiateX, s.name.s) + if t == nil: + LocalError(a.info, errCannotInstantiateX, s.name.s) + break if (t.kind == tyGenericParam): InternalError(a.info, "instantiateGenericParamList: " & q.name.s) s.typ = t @@ -94,13 +96,14 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, result.ast = n pushOwner(result) openScope(c.tab) - if (n.sons[genericParamsPos] == nil): + if (n.sons[genericParamsPos].kind == nkEmpty): InternalError(n.info, "generateInstance") n.sons[namePos] = newSymNode(result) pushInfoContext(info) instantiateGenericParamList(c, n.sons[genericParamsPos], pt) - n.sons[genericParamsPos] = nil # semantic checking for the parameters: - if n.sons[paramsPos] != nil: + n.sons[genericParamsPos] = ast.emptyNode + # semantic checking for the parameters: + if n.sons[paramsPos].kind != nkEmpty: semParamList(c, n.sons[ParamsPos], nil, result) addParams(c, result.typ.n) else: @@ -112,7 +115,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, # add it here, so that recursive generic procs are possible: GenericCacheAdd(c, fn, result) addDecl(c, result) - if n.sons[codePos] != nil: + if n.sons[codePos].kind != nkEmpty: c.p = newProcCon(result) if result.kind in {skProc, skMethod, skConverter}: addResult(c, result.typ.sons[0], n.info) @@ -129,11 +132,11 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, proc checkConstructedType(info: TLineInfo, t: PType) = if (tfAcyclic in t.flags) and (skipTypes(t, abstractInst).kind != tyObject): - liMessage(info, errInvalidPragmaX, "acyclic") - if computeSize(t) < 0: - liMessage(info, errIllegalRecursionInTypeX, typeToString(t)) - if (t.kind == tyVar) and (t.sons[0].kind == tyVar): - liMessage(info, errVarVarTypeNotAllowed) + LocalError(info, errInvalidPragmaX, "acyclic") + elif computeSize(t) < 0: + LocalError(info, errIllegalRecursionInTypeX, typeToString(t)) + elif (t.kind == tyVar) and (t.sons[0].kind == tyVar): + LocalError(info, errVarVarTypeNotAllowed) type TReplTypeVars{.final.} = object @@ -162,8 +165,7 @@ proc ReplaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode = result.sons[i] = ReplaceTypeVarsN(cl, n.sons[i]) proc ReplaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym = - if s == nil: - return nil + if s == nil: return nil result = PSym(idTableGet(cl.symMap, s)) if result == nil: result = copySym(s, false) @@ -176,7 +178,7 @@ proc ReplaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym = proc lookupTypeVar(cl: TReplTypeVars, t: PType): PType = result = PType(idTableGet(cl.typeMap, t)) if result == nil: - liMessage(t.sym.info, errCannotInstantiateX, typeToString(t)) + GlobalError(t.sym.info, errCannotInstantiateX, typeToString(t)) elif result.kind == tyGenericParam: InternalError(cl.info, "substitution with generic parameter") @@ -210,7 +212,8 @@ proc ReplaceTypeVarsT(cl: var TReplTypeVars, t: PType): PType = idTablePut(gInstTypes, header, result) newbody = ReplaceTypeVarsT(cl, lastSon(body)) newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n) - addSon(result, newbody) #writeln(output, ropeToStr(Typetoyaml(newbody))); + addSon(result, newbody) + #writeln(output, ropeToStr(Typetoyaml(newbody))); checkConstructedType(cl.info, newbody) of tyGenericBody: InternalError(cl.info, "ReplaceTypeVarsT: tyGenericBody") @@ -222,7 +225,7 @@ proc ReplaceTypeVarsT(cl: var TReplTypeVars, t: PType): PType = result.sons[i] = ReplaceTypeVarsT(cl, result.sons[i]) result.n = ReplaceTypeVarsN(cl, result.n) if result.Kind in GenericTypes: - liMessage(cl.info, errCannotInstantiateX, TypeToString(t, preferName)) + LocalError(cl.info, errCannotInstantiateX, TypeToString(t, preferName)) #writeln(output, ropeToStr(Typetoyaml(result))) #checkConstructedType(cl.info, result) diff --git a/rod/semstmts.nim b/rod/semstmts.nim index 0faf3e5fc..d2e7322c2 100755 --- a/rod/semstmts.nim +++ b/rod/semstmts.nim @@ -12,13 +12,12 @@ proc semExprNoType(c: PContext, n: PNode): PNode = result = semExpr(c, n) if result.typ != nil and result.typ.kind != tyStmt: - liMessage(n.info, errDiscardValue) + localError(n.info, errDiscardValue) proc semWhen(c: PContext, n: PNode): PNode = result = nil for i in countup(0, sonsLen(n) - 1): var it = n.sons[i] - if it == nil: illFormedAst(n) case it.kind of nkElifBranch: checkSonsLen(it, 2) @@ -43,7 +42,6 @@ proc semIf(c: PContext, n: PNode): PNode = result = n for i in countup(0, sonsLen(n) - 1): var it = n.sons[i] - if it == nil: illFormedAst(n) case it.kind of nkElifBranch: checkSonsLen(it, 2) @@ -61,12 +59,12 @@ proc semDiscard(c: PContext, n: PNode): PNode = result = n checkSonsLen(n, 1) n.sons[0] = semExprWithType(c, n.sons[0]) - if n.sons[0].typ == nil: liMessage(n.info, errInvalidDiscard) + if n.sons[0].typ == nil: localError(n.info, errInvalidDiscard) proc semBreakOrContinue(c: PContext, n: PNode): PNode = result = n checkSonsLen(n, 1) - if n.sons[0] != nil: + if n.sons[0].kind != nkEmpty: var s: PSym case n.sons[0].kind of nkIdent: s = lookUp(c, n.sons[0]) @@ -78,19 +76,20 @@ proc semBreakOrContinue(c: PContext, n: PNode): PNode = incl(s.flags, sfUsed) n.sons[0] = x else: - liMessage(n.info, errInvalidControlFlowX, s.name.s) + localError(n.info, errInvalidControlFlowX, s.name.s) elif (c.p.nestedLoopCounter <= 0) and (c.p.nestedBlockCounter <= 0): - liMessage(n.info, errInvalidControlFlowX, renderTree(n, {renderNoComments})) + localError(n.info, errInvalidControlFlowX, + renderTree(n, {renderNoComments})) proc semBlock(c: PContext, n: PNode): PNode = result = n Inc(c.p.nestedBlockCounter) checkSonsLen(n, 2) openScope(c.tab) # BUGFIX: label is in the scope of block! - if n.sons[0] != nil: + if n.sons[0].kind != nkEmpty: var labl = newSymS(skLabel, n.sons[0], c) addDecl(c, labl) - n.sons[0] = newSymNode(labl) # BUGFIX + n.sons[0] = newSymNode(labl) n.sons[1] = semStmt(c, n.sons[1]) closeScope(c.tab) Dec(c.p.nestedBlockCounter) @@ -132,7 +131,9 @@ proc semCase(c: PContext, n: PNode): PNode = chckCovered = true of tyFloat..tyFloat128, tyString: nil - else: liMessage(n.info, errSelectorMustBeOfCertainTypes) + else: + LocalError(n.info, errSelectorMustBeOfCertainTypes) + return for i in countup(1, sonsLen(n) - 1): var x = n.sons[i] case x.kind @@ -153,7 +154,7 @@ proc semCase(c: PContext, n: PNode): PNode = x.sons[0] = semStmtScope(c, x.sons[0]) else: illFormedAst(x) if chckCovered and (covered != toCover(n.sons[0].typ)): - liMessage(n.info, errNotAllCasesCovered) + localError(n.info, errNotAllCasesCovered) closeScope(c.tab) proc propertyWriteAccess(c: PContext, n, a: PNode): PNode = @@ -170,7 +171,7 @@ proc propertyWriteAccess(c: PContext, n, a: PNode): PNode = fixAbstractType(c, result) analyseIfAddressTakenInCall(c, result) else: - liMessage(n.Info, errUndeclaredFieldX, id.s) + globalError(n.Info, errUndeclaredFieldX, id.s) proc semAsgn(c: PContext, n: PNode): PNode = checkSonsLen(n, 2) @@ -197,7 +198,8 @@ proc semAsgn(c: PContext, n: PNode): PNode = var le = a.typ if skipTypes(le, {tyGenericInst}).kind != tyVar and IsAssignable(a) == arNone: # Direct assignment to a discriminant is allowed! - liMessage(a.info, errXCannotBeAssignedTo, renderTree(a, {renderNoComments})) + localError(a.info, errXCannotBeAssignedTo, + renderTree(a, {renderNoComments})) else: n.sons[1] = fitNode(c, le, n.sons[1]) fixAbstractType(c, n) @@ -210,83 +212,84 @@ proc SemReturn(c: PContext, n: PNode): PNode = result = n checkSonsLen(n, 1) if not (c.p.owner.kind in {skConverter, skMethod, skProc, skMacro}): - liMessage(n.info, errXNotAllowedHere, "\'return\'") - if (n.sons[0] != nil): + globalError(n.info, errXNotAllowedHere, "\'return\'") + if n.sons[0].kind != nkEmpty: n.sons[0] = SemExprWithType(c, n.sons[0]) # check for type compatibility: restype = c.p.owner.typ.sons[0] - if (restype != nil): + if restype != nil: a = newNodeI(nkAsgn, n.sons[0].info) n.sons[0] = fitNode(c, restype, n.sons[0]) # optimize away ``return result``, because it would be transformed # to ``result = result; return``: if (n.sons[0].kind == nkSym) and (sfResult in n.sons[0].sym.flags): - n.sons[0] = nil + n.sons[0] = ast.emptyNode else: if (c.p.resultSym == nil): InternalError(n.info, "semReturn") addSon(a, semExprWithType(c, newSymNode(c.p.resultSym))) addSon(a, n.sons[0]) n.sons[0] = a else: - liMessage(n.info, errCannotReturnExpr) + localError(n.info, errCannotReturnExpr) proc SemYield(c: PContext, n: PNode): PNode = result = n checkSonsLen(n, 1) if (c.p.owner == nil) or (c.p.owner.kind != skIterator): - liMessage(n.info, errYieldNotAllowedHere) - if (n.sons[0] != nil): + GlobalError(n.info, errYieldNotAllowedHere) + if n.sons[0].kind != nkEmpty: n.sons[0] = SemExprWithType(c, n.sons[0]) # check for type compatibility: var restype = c.p.owner.typ.sons[0] - if (restype != nil): + if restype != nil: n.sons[0] = fitNode(c, restype, n.sons[0]) if (n.sons[0].typ == nil): InternalError(n.info, "semYield") else: - liMessage(n.info, errCannotReturnExpr) + localError(n.info, errCannotReturnExpr) proc fitRemoveHiddenConv(c: PContext, typ: Ptype, n: PNode): PNode = result = fitNode(c, typ, n) - if (result.kind in {nkHiddenStdConv, nkHiddenSubConv}): + if result.kind in {nkHiddenStdConv, nkHiddenSubConv}: changeType(result.sons[1], typ) result = result.sons[1] elif not sameType(result.typ, typ): changeType(result, typ) proc semVar(c: PContext, n: PNode): PNode = - var - length: int - a, b, def: PNode - typ, tup: PType - v: PSym + var b: PNode result = copyNode(n) - for i in countup(0, sonsLen(n) - 1): - a = n.sons[i] + for i in countup(0, sonsLen(n)-1): + var a = n.sons[i] if a.kind == nkCommentStmt: continue if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): IllFormedAst(a) checkMinSonsLen(a, 3) - length = sonsLen(a) - if a.sons[length - 2] != nil: typ = semTypeNode(c, a.sons[length - 2], nil) - else: typ = nil - if a.sons[length - 1] != nil: - def = semExprWithType(c, a.sons[length - 1]) + var length = sonsLen(a) + var typ: PType + if a.sons[length-2].kind != nkEmpty: + typ = semTypeNode(c, a.sons[length-2], nil) + else: + typ = nil + var def: PNode + if a.sons[length-1].kind != nkEmpty: + def = semExprWithType(c, a.sons[length-1]) # BUGFIX: ``fitNode`` is needed here! # check type compability between def.typ and typ: - if (typ != nil): def = fitNode(c, typ, def) + if typ != nil: def = fitNode(c, typ, def) else: typ = def.typ else: - def = nil + def = ast.emptyNode if not typeAllowed(typ, skVar): - liMessage(a.info, errXisNoType, typeToString(typ)) - tup = skipTypes(typ, {tyGenericInst}) + GlobalError(a.info, errXisNoType, typeToString(typ)) + var tup = skipTypes(typ, {tyGenericInst}) if a.kind == nkVarTuple: - if tup.kind != tyTuple: liMessage(a.info, errXExpected, "tuple") + if tup.kind != tyTuple: GlobalError(a.info, errXExpected, "tuple") if length - 2 != sonsLen(tup): - liMessage(a.info, errWrongNumberOfVariables) + GlobalError(a.info, errWrongNumberOfVariables) b = newNodeI(nkVarTuple, a.info) newSons(b, length) - b.sons[length - 2] = nil # no type desc + b.sons[length - 2] = ast.emptyNode # no type desc b.sons[length - 1] = def addSon(result, b) for j in countup(0, length - 3): + var v: PSym if (c.p.owner.kind == skModule): v = semIdentWithPragma(c, skVar, a.sons[j], {sfStar, sfMinus}) incl(v.flags, sfGlobal) @@ -298,7 +301,7 @@ proc semVar(c: PContext, n: PNode): PNode = v.typ = typ b = newNodeI(nkIdentDefs, a.info) addSon(b, newSymNode(v)) - addSon(b, nil) # no type description + addSon(b, ast.emptyNode) # no type description addSon(b, copyTree(def)) addSon(result, b) else: @@ -306,57 +309,53 @@ proc semVar(c: PContext, n: PNode): PNode = b.sons[j] = newSymNode(v) proc semConst(c: PContext, n: PNode): PNode = - var - a, def, b: PNode - v: PSym - typ: PType result = copyNode(n) for i in countup(0, sonsLen(n) - 1): - a = n.sons[i] + var a = n.sons[i] if a.kind == nkCommentStmt: continue if (a.kind != nkConstDef): IllFormedAst(a) checkSonsLen(a, 3) + var v: PSym if (c.p.owner.kind == skModule): v = semIdentWithPragma(c, skConst, a.sons[0], {sfStar, sfMinus}) incl(v.flags, sfGlobal) else: v = semIdentWithPragma(c, skConst, a.sons[0], {}) - if a.sons[1] != nil: typ = semTypeNode(c, a.sons[1], nil) - else: typ = nil - def = semAndEvalConstExpr(c, a.sons[2]) + var typ: PType = nil + if a.sons[1].kind != nkEmpty: typ = semTypeNode(c, a.sons[1], nil) + var def = semAndEvalConstExpr(c, a.sons[2]) # check type compability between def.typ and typ: if (typ != nil): def = fitRemoveHiddenConv(c, typ, def) else: typ = def.typ if not typeAllowed(typ, skConst): - liMessage(a.info, errXisNoType, typeToString(typ)) + GlobalError(a.info, errXisNoType, typeToString(typ)) v.typ = typ v.ast = def # no need to copy if v.flags * {sfStar, sfMinus} != {}: incl(v.flags, sfInInterface) addInterfaceDecl(c, v) - b = newNodeI(nkConstDef, a.info) + var b = newNodeI(nkConstDef, a.info) addSon(b, newSymNode(v)) - addSon(b, nil) # no type description + addSon(b, ast.emptyNode) # no type description addSon(b, copyTree(def)) addSon(result, b) proc semFor(c: PContext, n: PNode): PNode = var - length: int v, countup: PSym iter: PType countupNode, call: PNode result = n checkMinSonsLen(n, 3) - length = sonsLen(n) + var length = sonsLen(n) openScope(c.tab) if n.sons[length - 2].kind == nkRange: checkSonsLen(n.sons[length - 2], 2) # convert ``in 3..5`` to ``in countup(3, 5)`` countupNode = newNodeI(nkCall, n.sons[length - 2].info) countUp = StrTableGet(magicsys.systemModule.Tab, getIdent("countup")) - if (countUp == nil): liMessage(countupNode.info, errSystemNeeds, "countup") + if countUp == nil: GlobalError(countupNode.info, errSystemNeeds, "countup") newSons(countupNode, 3) countupnode.sons[0] = newSymNode(countup) countupNode.sons[1] = n.sons[length - 2].sons[0] @@ -366,16 +365,16 @@ proc semFor(c: PContext, n: PNode): PNode = call = n.sons[length - 2] if (call.kind != nkCall) or (call.sons[0].kind != nkSym) or (call.sons[0].sym.kind != skIterator): - liMessage(n.sons[length - 2].info, errIteratorExpected) + GlobalError(n.sons[length - 2].info, errIteratorExpected) iter = skipTypes(n.sons[length - 2].typ, {tyGenericInst}) if iter.kind != tyTuple: - if length != 3: liMessage(n.info, errWrongNumberOfVariables) + if length != 3: GlobalError(n.info, errWrongNumberOfVariables) v = newSymS(skForVar, n.sons[0], c) v.typ = iter n.sons[0] = newSymNode(v) addDecl(c, v) else: - if length - 2 != sonsLen(iter): liMessage(n.info, errWrongNumberOfVariables) + if length-2 != sonsLen(iter): GlobalError(n.info, errWrongNumberOfVariables) for i in countup(0, length - 3): v = newSymS(skForVar, n.sons[i], c) v.typ = iter.sons[i] @@ -389,11 +388,11 @@ proc semFor(c: PContext, n: PNode): PNode = proc semRaise(c: PContext, n: PNode): PNode = result = n checkSonsLen(n, 1) - if n.sons[0] != nil: + if n.sons[0].kind != nkEmpty: n.sons[0] = semExprWithType(c, n.sons[0]) var typ = n.sons[0].typ if (typ.kind != tyRef) or (typ.sons[0].kind != tyObject): - liMessage(n.info, errExprCannotBeRaised) + localError(n.info, errExprCannotBeRaised) proc semTry(c: PContext, n: PNode): PNode = var check: TIntSet @@ -409,12 +408,12 @@ proc semTry(c: PContext, n: PNode): PNode = for j in countup(0, length - 2): var typ = semTypeNode(c, a.sons[j], nil) if typ.kind == tyRef: typ = typ.sons[0] - if (typ.kind != tyObject): - liMessage(a.sons[j].info, errExprCannotBeRaised) + if typ.kind != tyObject: + GlobalError(a.sons[j].info, errExprCannotBeRaised) a.sons[j] = newNodeI(nkType, a.sons[j].info) a.sons[j].typ = typ if IntSetContainsOrIncl(check, typ.id): - liMessage(a.sons[j].info, errExceptionAlreadyHandled) + localError(a.sons[j].info, errExceptionAlreadyHandled) elif a.kind != nkFinally: illFormedAst(n) # last child of an nkExcept/nkFinally branch is a statement: @@ -423,16 +422,16 @@ proc semTry(c: PContext, n: PNode): PNode = proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = result = copyNode(n) if n.kind != nkGenericParams: InternalError(n.info, "semGenericParamList") - for i in countup(0, sonsLen(n) - 1): + for i in countup(0, sonsLen(n)-1): var a = n.sons[i] if a.kind != nkIdentDefs: illFormedAst(n) var L = sonsLen(a) - var def = a.sons[L - 1] + var def = a.sons[L-1] var typ: PType - if a.sons[L - 2] != nil: typ = semTypeNode(c, a.sons[L - 2], nil) - elif def != nil: typ = newTypeS(tyExpr, c) + if a.sons[L-2].kind != nkEmpty: typ = semTypeNode(c, a.sons[L-2], nil) + elif def.kind != nkEmpty: typ = newTypeS(tyExpr, c) else: typ = nil - for j in countup(0, L - 3): + for j in countup(0, L-3): var s: PSym if (typ == nil) or (typ.kind == tyTypeDesc): s = newSymS(skType, a.sons[j], c) @@ -441,7 +440,7 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = # not a type param, but an expression s = newSymS(skGenericParam, a.sons[j], c) s.typ = typ - s.ast = def + if def.kind != nkEmpty: s.ast = def s.typ.sym = s if father != nil: addSon(father, s.typ) s.position = i @@ -451,7 +450,7 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = proc addGenericParamListToScope(c: PContext, n: PNode) = if n.kind != nkGenericParams: InternalError(n.info, "addGenericParamListToScope") - for i in countup(0, sonsLen(n) - 1): + for i in countup(0, sonsLen(n)-1): var a = n.sons[i] if a.kind != nkSym: internalError(a.info, "addGenericParamListToScope") addDecl(c, a.sym) @@ -466,7 +465,7 @@ proc SemTypeSection(c: PContext, n: PNode): PNode = for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue - if (a.kind != nkTypeDef): IllFormedAst(a) + if a.kind != nkTypeDef: IllFormedAst(a) checkSonsLen(a, 3) if (c.p.owner.kind == skModule): s = semIdentWithPragma(c, skType, a.sons[0], {sfStar, sfMinus}) @@ -488,10 +487,10 @@ proc SemTypeSection(c: PContext, n: PNode): PNode = checkSonsLen(a, 3) if (a.sons[0].kind != nkSym): IllFormedAst(a) s = a.sons[0].sym - if (s.magic == mNone) and (a.sons[2] == nil): - liMessage(a.info, errImplOfXexpected, s.name.s) + if (s.magic == mNone) and (a.sons[2].kind == nkEmpty): + GlobalError(a.info, errImplOfXexpected, s.name.s) if s.magic != mNone: processMagicType(c, s) - if a.sons[1] != nil: + if a.sons[1].kind != nkEmpty: # We have a generic type declaration here. In generic types, # symbol lookup needs to be done here. openScope(c.tab) @@ -508,7 +507,7 @@ proc SemTypeSection(c: PContext, n: PNode): PNode = s.typ.sons[sonsLen(s.typ) - 1] = body #debug(s.typ); popOwner() closeScope(c.tab) - elif a.sons[2] != nil: + elif a.sons[2].kind != nkEmpty: # process the type's body: pushOwner(s) t = semTypeNode(c, a.sons[2], s.typ) @@ -523,9 +522,8 @@ proc SemTypeSection(c: PContext, n: PNode): PNode = if (a.sons[0].kind != nkSym): IllFormedAst(a) s = a.sons[0].sym # compute the type's size and check for illegal recursions: - if a.sons[1] == nil: - if (a.sons[2] != nil) and - (a.sons[2].kind in {nkSym, nkIdent, nkAccQuoted}): + if a.sons[1].kind == nkEmpty: + if (a.sons[2].kind in {nkSym, nkIdent, nkAccQuoted}): # type aliases are hard: #MessageOut('for type ' + typeToString(s.typ)); t = semTypeNode(c, a.sons[2], nil) @@ -538,21 +536,23 @@ proc semParamList(c: PContext, n, genericParams: PNode, s: PSym) = s.typ = semProcTypeNode(c, n, genericParams, nil) proc addParams(c: PContext, n: PNode) = - for i in countup(1, sonsLen(n) - 1): + for i in countup(1, sonsLen(n)-1): if (n.sons[i].kind != nkSym): InternalError(n.info, "addParams") addDecl(c, n.sons[i].sym) proc semBorrow(c: PContext, n: PNode, s: PSym) = # search for the correct alias: var b = SearchForBorrowProc(c, s, c.tab.tos - 2) - if b == nil: - liMessage(n.info, errNoSymbolToBorrowFromFound) # store the alias: - n.sons[codePos] = newSymNode(b) + if b != nil: + # store the alias: + n.sons[codePos] = newSymNode(b) + else: + LocalError(n.info, errNoSymbolToBorrowFromFound) proc sideEffectsCheck(c: PContext, s: PSym) = if {sfNoSideEffect, sfSideEffect} * s.flags == {sfNoSideEffect, sfSideEffect}: - liMessage(s.info, errXhasSideEffects, s.name.s) + LocalError(s.info, errXhasSideEffects, s.name.s) proc addResult(c: PContext, t: PType, info: TLineInfo) = if t != nil: @@ -577,26 +577,27 @@ proc semLambda(c: PContext, n: PNode): PNode = n.sons[namePos] = newSymNode(s) pushOwner(s) openScope(c.tab) - if (n.sons[genericParamsPos] != nil): + if (n.sons[genericParamsPos].kind != nkEmpty): illFormedAst(n) # process parameters: - if n.sons[paramsPos] != nil: + if n.sons[paramsPos].kind != nkEmpty: semParamList(c, n.sons[ParamsPos], nil, s) addParams(c, s.typ.n) else: s.typ = newTypeS(tyProc, c) addSon(s.typ, nil) s.typ.callConv = ccClosure - if n.sons[pragmasPos] != nil: pragma(c, s, n.sons[pragmasPos], lambdaPragmas) + if n.sons[pragmasPos].kind != nkEmpty: + pragma(c, s, n.sons[pragmasPos], lambdaPragmas) s.options = gOptions - if n.sons[codePos] != nil: + if n.sons[codePos].kind != nkEmpty: if sfImportc in s.flags: - liMessage(n.sons[codePos].info, errImplOfXNotAllowed, s.name.s) + LocalError(n.sons[codePos].info, errImplOfXNotAllowed, s.name.s) c.p = newProcCon(s) addResult(c, s.typ.sons[0], n.info) n.sons[codePos] = semStmtScope(c, n.sons[codePos]) addResultNode(c, n) else: - liMessage(n.info, errImplOfXexpected, s.name.s) + LocalError(n.info, errImplOfXexpected, s.name.s) closeScope(c.tab) # close scope for parameters popOwner() c.p = oldP # restore @@ -620,16 +621,16 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, s.ast = n pushOwner(s) openScope(c.tab) - if n.sons[genericParamsPos] != nil: + if n.sons[genericParamsPos].kind != nkEmpty: n.sons[genericParamsPos] = semGenericParamList(c, n.sons[genericParamsPos]) gp = n.sons[genericParamsPos] else: gp = newNodeI(nkGenericParams, n.info) # process parameters: - if n.sons[paramsPos] != nil: + if n.sons[paramsPos].kind != nkEmpty: semParamList(c, n.sons[ParamsPos], gp, s) if sonsLen(gp) > 0: - if n.sons[genericParamsPos] == nil: + if n.sons[genericParamsPos].kind == nkEmpty: # we have a list of implicit type parameters: n.sons[genericParamsPos] = gp # check for semantics again: @@ -651,16 +652,17 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, addInterfaceOverloadableSymAt(c, s, c.tab.tos - 2) else: addInterfaceDeclAt(c, s, c.tab.tos - 2) - if n.sons[pragmasPos] != nil: pragma(c, s, n.sons[pragmasPos], validPragmas) + if n.sons[pragmasPos].kind != nkEmpty: + pragma(c, s, n.sons[pragmasPos], validPragmas) else: - if n.sons[pragmasPos] != nil: - liMessage(n.sons[pragmasPos].info, errPragmaOnlyInHeaderOfProc) + if n.sons[pragmasPos].kind != nkEmpty: + LocalError(n.sons[pragmasPos].info, errPragmaOnlyInHeaderOfProc) if sfForward notin proto.flags: - liMessage(n.info, errAttemptToRedefineX, proto.name.s) + LocalError(n.info, errAttemptToRedefineX, proto.name.s) excl(proto.flags, sfForward) closeScope(c.tab) # close scope with wrong parameter symbols openScope(c.tab) # open scope for old (correct) parameter symbols - if proto.ast.sons[genericParamsPos] != nil: + if proto.ast.sons[genericParamsPos].kind != nkEmpty: addGenericParamListToScope(c, proto.ast.sons[genericParamsPos]) addParams(c, proto.typ.n) proto.info = s.info # more accurate line information @@ -674,27 +676,27 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, popOwner() pushOwner(s) s.options = gOptions - if n.sons[codePos] != nil: - # for DLL generation, it is annoying to check for sfImportc! + if n.sons[codePos].kind != nkEmpty: + # for DLL generation it is annoying to check for sfImportc! if sfBorrow in s.flags: - liMessage(n.sons[codePos].info, errImplOfXNotAllowed, s.name.s) - if (n.sons[genericParamsPos] == nil): + LocalError(n.sons[codePos].info, errImplOfXNotAllowed, s.name.s) + if n.sons[genericParamsPos].kind == nkEmpty: c.p = newProcCon(s) if (s.typ.sons[0] != nil) and (kind != skIterator): addResult(c, s.typ.sons[0], n.info) if sfImportc notin s.flags: # no semantic checking for importc: n.sons[codePos] = semStmtScope(c, n.sons[codePos]) - if (s.typ.sons[0] != nil) and (kind != skIterator): addResultNode(c, n) + if s.typ.sons[0] != nil and kind != skIterator: addResultNode(c, n) else: - if (s.typ.sons[0] != nil) and (kind != skIterator): + if s.typ.sons[0] != nil and kind != skIterator: addDecl(c, newSym(skUnknown, getIdent("result"), nil)) n.sons[codePos] = semGenericStmtScope(c, n.sons[codePos]) if sfImportc in s.flags: # so we just ignore the body after semantic checking for importc: - n.sons[codePos] = nil + n.sons[codePos] = ast.emptyNode else: - if proto != nil: liMessage(n.info, errImplOfXexpected, proto.name.s) + if proto != nil: LocalError(n.info, errImplOfXexpected, proto.name.s) if {sfImportc, sfBorrow} * s.flags == {}: incl(s.flags, sfForward) elif sfBorrow in s.flags: semBorrow(c, n, s) sideEffectsCheck(c, s) @@ -706,14 +708,16 @@ proc semIterator(c: PContext, n: PNode): PNode = result = semProcAux(c, n, skIterator, iteratorPragmas) var s = result.sons[namePos].sym var t = s.typ - if t.sons[0] == nil: liMessage(n.info, errXNeedsReturnType, "iterator") - if n.sons[codePos] == nil: liMessage(n.info, errImplOfXexpected, s.name.s) + if t.sons[0] == nil: + LocalError(n.info, errXNeedsReturnType, "iterator") + if n.sons[codePos].kind == nkEmpty: + LocalError(n.info, errImplOfXexpected, s.name.s) proc semProc(c: PContext, n: PNode): PNode = result = semProcAux(c, n, skProc, procPragmas) proc semMethod(c: PContext, n: PNode): PNode = - if not isTopLevel(c): liMessage(n.info, errXOnlyAtModuleScope, "method") + if not isTopLevel(c): LocalError(n.info, errXOnlyAtModuleScope, "method") result = semProcAux(c, n, skMethod, methodPragmas) var s = result.sons[namePos].sym @@ -728,30 +732,31 @@ proc semMethod(c: PContext, n: PNode): PNode = # XXX this not really correct way to do it: Perhaps it should be done after # generic instantiation. Well it's good enough for now: if not hasObjParam: - liMessage(n.info, errXNeedsParamObjectType, "method") + LocalError(n.info, errXNeedsParamObjectType, "method") proc semConverterDef(c: PContext, n: PNode): PNode = - if not isTopLevel(c): liMessage(n.info, errXOnlyAtModuleScope, "converter") + if not isTopLevel(c): LocalError(n.info, errXOnlyAtModuleScope, "converter") checkSonsLen(n, codePos + 1) - if n.sons[genericParamsPos] != nil: - liMessage(n.info, errNoGenericParamsAllowedForX, "converter") + if n.sons[genericParamsPos].kind != nkEmpty: + LocalError(n.info, errNoGenericParamsAllowedForX, "converter") result = semProcAux(c, n, skConverter, converterPragmas) var s = result.sons[namePos].sym var t = s.typ - if t.sons[0] == nil: liMessage(n.info, errXNeedsReturnType, "converter") - if sonsLen(t) != 2: liMessage(n.info, errXRequiresOneArgument, "converter") + if t.sons[0] == nil: LocalError(n.info, errXNeedsReturnType, "converter") + if sonsLen(t) != 2: LocalError(n.info, errXRequiresOneArgument, "converter") addConverter(c, s) proc semMacroDef(c: PContext, n: PNode): PNode = checkSonsLen(n, codePos + 1) - if n.sons[genericParamsPos] != nil: - liMessage(n.info, errNoGenericParamsAllowedForX, "macro") + if n.sons[genericParamsPos].kind != nkEmpty: + LocalError(n.info, errNoGenericParamsAllowedForX, "macro") result = semProcAux(c, n, skMacro, macroPragmas) var s = result.sons[namePos].sym var t = s.typ - if t.sons[0] == nil: liMessage(n.info, errXNeedsReturnType, "macro") - if sonsLen(t) != 2: liMessage(n.info, errXRequiresOneArgument, "macro") - if n.sons[codePos] == nil: liMessage(n.info, errImplOfXexpected, s.name.s) + if t.sons[0] == nil: LocalError(n.info, errXNeedsReturnType, "macro") + if sonsLen(t) != 2: LocalError(n.info, errXRequiresOneArgument, "macro") + if n.sons[codePos].kind == nkEmpty: + LocalError(n.info, errImplOfXexpected, s.name.s) proc evalInclude(c: PContext, n: PNode): PNode = result = newNodeI(nkStmtList, n.info) @@ -760,7 +765,7 @@ proc evalInclude(c: PContext, n: PNode): PNode = var f = getModuleFile(n.sons[i]) var fileIndex = includeFilename(f) if IntSetContainsOrIncl(c.includedFiles, fileIndex): - liMessage(n.info, errRecursiveDependencyX, f) + GlobalError(n.info, errRecursiveDependencyX, f) addSon(result, semStmt(c, gIncludeFile(f))) IntSetExcl(c.includedFiles, fileIndex) @@ -771,7 +776,6 @@ proc SemStmt(c: PContext, n: PNode): PNode = const # must be last statements in a block: LastBlockStmts = {nkRaiseStmt, nkReturnStmt, nkBreakStmt, nkContinueStmt} result = n - if n == nil: return if nfSem in n.flags: return case n.kind of nkAsgn: result = semAsgn(c, n) @@ -783,12 +787,11 @@ proc SemStmt(c: PContext, n: PNode): PNode = var length = sonsLen(n) for i in countup(0, length - 1): n.sons[i] = semStmt(c, n.sons[i]) - if (n.sons[i].kind in LastBlockStmts): + if n.sons[i].kind in LastBlockStmts: for j in countup(i + 1, length - 1): case n.sons[j].kind - of nkPragma, nkCommentStmt, nkNilLit, nkEmpty: - nil - else: liMessage(n.sons[j].info, errStmtInvalidAfterReturn) + of nkPragma, nkCommentStmt, nkNilLit, nkEmpty: nil + else: localError(n.sons[j].info, errStmtInvalidAfterReturn) of nkRaiseStmt: result = semRaise(c, n) of nkVarSection: result = semVar(c, n) of nkConstSection: result = semConst(c, n) @@ -812,15 +815,15 @@ proc SemStmt(c: PContext, n: PNode): PNode = of nkMacroDef: result = semMacroDef(c, n) of nkTemplateDef: result = semTemplateDef(c, n) of nkImportStmt: - if not isTopLevel(c): liMessage(n.info, errXOnlyAtModuleScope, "import") + if not isTopLevel(c): LocalError(n.info, errXOnlyAtModuleScope, "import") result = evalImport(c, n) of nkFromStmt: - if not isTopLevel(c): liMessage(n.info, errXOnlyAtModuleScope, "from") + if not isTopLevel(c): LocalError(n.info, errXOnlyAtModuleScope, "from") result = evalFrom(c, n) of nkIncludeStmt: - if not isTopLevel(c): liMessage(n.info, errXOnlyAtModuleScope, "include") + if not isTopLevel(c): LocalError(n.info, errXOnlyAtModuleScope, "include") result = evalInclude(c, n) - else: liMessage(n.info, errStmtExpected) + else: LocalError(n.info, errStmtExpected) if result == nil: InternalError(n.info, "SemStmt: result = nil") incl(result.flags, nfSem) diff --git a/rod/semtempl.nim b/rod/semtempl.nim index cb4288a56..1fbcbe227 100755 --- a/rod/semtempl.nim +++ b/rod/semtempl.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -9,8 +9,6 @@ proc isExpr(n: PNode): bool = # returns true if ``n`` looks like an expression - if n == nil: - return false case n.kind of nkIdent..nkNilLit: result = true @@ -23,8 +21,6 @@ proc isExpr(n: PNode): bool = proc isTypeDesc(n: PNode): bool = # returns true if ``n`` looks like a type desc - if n == nil: - return false case n.kind of nkIdent, nkSym, nkType: result = true @@ -38,12 +34,9 @@ proc isTypeDesc(n: PNode): bool = else: result = false proc evalTemplateAux(c: PContext, templ, actual: PNode, sym: PSym): PNode = - var p: PSym - if templ == nil: - return nil case templ.kind of nkSym: - p = templ.sym + var p = templ.sym if (p.kind == skParam) and (p.owner.id == sym.id): result = copyTree(actual.sons[p.position]) else: @@ -63,32 +56,38 @@ proc evalTemplateArgs(c: PContext, n: PNode, s: PSym): PNode = var f, a: int arg: PNode - f = sonsLen(s.typ) # if the template has zero arguments, it can be called without ``()`` - # `n` is then a nkSym or something similar + f = sonsLen(s.typ) + # if the template has zero arguments, it can be called without ``()`` + # `n` is then a nkSym or something similar case n.kind of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit: a = sonsLen(n) else: a = 0 - if a > f: liMessage(n.info, errWrongNumberOfArguments) + if a > f: LocalError(n.info, errWrongNumberOfArguments) result = copyNode(n) for i in countup(1, f - 1): if i < a: arg = n.sons[i] else: arg = copyTree(s.typ.n.sons[i].sym.ast) - if arg == nil: liMessage(n.info, errWrongNumberOfArguments) - if not (s.typ.sons[i].kind in {tyTypeDesc, tyStmt, tyExpr}): + if arg == nil or arg.kind == nkEmpty: + LocalError(n.info, errWrongNumberOfArguments) + elif not (s.typ.sons[i].kind in {tyTypeDesc, tyStmt, tyExpr}): # concrete type means semantic checking for argument: + # XXX This is horrible! Better make semantic checking use some kind + # of fixpoint iteration ... arg = fitNode(c, s.typ.sons[i], semExprWithType(c, arg)) addSon(result, arg) proc evalTemplate(c: PContext, n: PNode, sym: PSym): PNode = var args: PNode inc(evalTemplateCounter) - if evalTemplateCounter > 100: - liMessage(n.info, errTemplateInstantiationTooNested) - # replace each param by the corresponding node: - args = evalTemplateArgs(c, n, sym) - result = evalTemplateAux(c, sym.ast.sons[codePos], args, sym) - dec(evalTemplateCounter) + if evalTemplateCounter <= 100: + # replace each param by the corresponding node: + args = evalTemplateArgs(c, n, sym) + result = evalTemplateAux(c, sym.ast.sons[codePos], args, sym) + dec(evalTemplateCounter) + else: + GlobalError(n.info, errTemplateInstantiationTooNested) + result = n proc symChoice(c: PContext, n: PNode, s: PSym): PNode = var @@ -116,8 +115,6 @@ proc symChoice(c: PContext, n: PNode, s: PSym): PNode = proc resolveTemplateParams(c: PContext, n: PNode, withinBind: bool, toBind: var TIntSet): PNode = var s: PSym - if n == nil: - return nil case n.kind of nkIdent: if not withinBind and not IntSetContains(toBind, n.ident.id): @@ -130,7 +127,7 @@ proc resolveTemplateParams(c: PContext, n: PNode, withinBind: bool, else: IntSetIncl(toBind, n.ident.id) result = symChoice(c, n, lookup(c, n)) - of nkSym..nkNilLit: # atom + of nkEmpty, nkSym..nkNilLit: # atom result = n of nkBind: result = resolveTemplateParams(c, n.sons[0], true, toBind) @@ -155,7 +152,8 @@ proc transformToExpr(n: PNode): PNode = if realStmt >= 0: result = transformToExpr(n.sons[realStmt]) else: n.kind = nkStmtListExpr of nkBlockStmt: - n.kind = nkBlockExpr #nkIfStmt: n.kind := nkIfExpr; // this is not correct! + n.kind = nkBlockExpr + #nkIfStmt: n.kind := nkIfExpr; // this is not correct! else: nil @@ -173,11 +171,12 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = pushOwner(s) openScope(c.tab) n.sons[namePos] = newSymNode(s) # check that no pragmas exist: - if n.sons[pragmasPos] != nil: - liMessage(n.info, errNoPragmasAllowedForX, "template") # check that no generic parameters exist: - if n.sons[genericParamsPos] != nil: - liMessage(n.info, errNoGenericParamsAllowedForX, "template") - if (n.sons[paramsPos] == nil): + if n.sons[pragmasPos].kind != nkEmpty: + LocalError(n.info, errNoPragmasAllowedForX, "template") + # check that no generic parameters exist: + if n.sons[genericParamsPos].kind != nkEmpty: + LocalError(n.info, errNoGenericParamsAllowedForX, "template") + if n.sons[paramsPos].kind == nkEmpty: # use ``stmt`` as implicit result type s.typ = newTypeS(tyProc, c) s.typ.n = newNodeI(nkFormalParams, n.info) @@ -185,7 +184,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = addSon(s.typ.n, newNodeIT(nkType, n.info, s.typ.sons[0])) else: semParamList(c, n.sons[ParamsPos], nil, s) - if n.sons[paramsPos].sons[0] == nil: + if n.sons[paramsPos].sons[0].kind == nkEmpty: # use ``stmt`` as implicit result type s.typ.sons[0] = newTypeS(tyStmt, c) s.typ.n.sons[0] = newNodeIT(nkType, n.info, s.typ.sons[0]) @@ -193,12 +192,13 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = IntSetInit(toBind) n.sons[codePos] = resolveTemplateParams(c, n.sons[codePos], false, toBind) if not (s.typ.sons[0].kind in {tyStmt, tyTypeDesc}): - n.sons[codePos] = transformToExpr(n.sons[codePos]) # only parameters are resolved, no type checking is performed + n.sons[codePos] = transformToExpr(n.sons[codePos]) + # only parameters are resolved, no type checking is performed closeScope(c.tab) popOwner() s.ast = n result = n - if n.sons[codePos] == nil: - liMessage(n.info, errImplOfXexpected, s.name.s) # add identifier of template as a last step to not allow - # recursive templates + if n.sons[codePos].kind == nkEmpty: + LocalError(n.info, errImplOfXexpected, s.name.s) + # add identifier of template as a last step to not allow recursive templates: addInterfaceDecl(c, s) diff --git a/rod/semtypes.nim b/rod/semtypes.nim index 8585c70a4..08c64384e 100755 --- a/rod/semtypes.nim +++ b/rod/semtypes.nim @@ -30,10 +30,10 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = result = newOrPrevType(tyEnum, prev, c) result.n = newNodeI(nkEnumTy, n.info) checkMinSonsLen(n, 1) - if n.sons[0] != nil: + if n.sons[0].kind != nkEmpty: base = semTypeNode(c, n.sons[0].sons[0], nil) if base.kind != tyEnum: - liMessage(n.sons[0].info, errInheritanceOnlyWithEnums) + localError(n.sons[0].info, errInheritanceOnlyWithEnums) counter = lastOrd(base) + 1 addSon(result, base) for i in countup(1, sonsLen(n) - 1): @@ -44,10 +44,10 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = var strVal: PNode = nil case skipTypes(v.typ, abstractInst).kind of tyTuple: - if sonsLen(v) != 2: liMessage(v.info, errWrongNumberOfVariables) + if sonsLen(v) != 2: GlobalError(v.info, errWrongNumberOfVariables) strVal = v.sons[1] # second tuple part is the string value if skipTypes(strVal.typ, abstractInst).kind notin {tyString, tyCstring}: - liMessage(strVal.info, errStringLiteralExpected) + GlobalError(strVal.info, errStringLiteralExpected) x = getOrdValue(v.sons[0]) # first tuple part is the ordinal of tyString, tyCstring: strVal = v @@ -57,7 +57,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = if i != 1: if (x != counter): incl(result.flags, tfEnumHasWholes) if x < counter: - liMessage(n.sons[i].info, errInvalidOrderInEnumX, e.name.s) + GlobalError(n.sons[i].info, errInvalidOrderInEnumX, e.name.s) e.ast = strVal # might be nil counter = x of nkSym: @@ -82,10 +82,10 @@ proc semSet(c: PContext, n: PNode, prev: PType): PType = addSon(result, base) if base.kind == tyGenericInst: base = lastSon(base) if base.kind != tyGenericParam: - if not isOrdinalType(base): liMessage(n.info, errOrdinalTypeExpected) - if lengthOrd(base) > MaxSetElements: liMessage(n.info, errSetTooBig) + if not isOrdinalType(base): GlobalError(n.info, errOrdinalTypeExpected) + if lengthOrd(base) > MaxSetElements: GlobalError(n.info, errSetTooBig) else: - liMessage(n.info, errXExpectsOneTypeParam, "set") + GlobalError(n.info, errXExpectsOneTypeParam, "set") proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string, prev: PType): PType = @@ -94,7 +94,7 @@ proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string, var base = semTypeNode(c, n.sons[1], nil) addSon(result, base) else: - liMessage(n.info, errXExpectsOneTypeParam, kindStr) + GlobalError(n.info, errXExpectsOneTypeParam, kindStr) proc semAnyRef(c: PContext, n: PNode, kind: TTypeKind, kindStr: string, prev: PType): PType = @@ -103,38 +103,38 @@ proc semAnyRef(c: PContext, n: PNode, kind: TTypeKind, kindStr: string, var base = semTypeNode(c, n.sons[0], nil) addSon(result, base) else: - liMessage(n.info, errXExpectsOneTypeParam, kindStr) + GlobalError(n.info, errXExpectsOneTypeParam, kindStr) proc semVarType(c: PContext, n: PNode, prev: PType): PType = result = newOrPrevType(tyVar, prev, c) if sonsLen(n) == 1: var base = semTypeNode(c, n.sons[0], nil) - if base.kind == tyVar: liMessage(n.info, errVarVarTypeNotAllowed) + if base.kind == tyVar: GlobalError(n.info, errVarVarTypeNotAllowed) addSon(result, base) else: - liMessage(n.info, errXExpectsOneTypeParam, "var") + GlobalError(n.info, errXExpectsOneTypeParam, "var") proc semDistinct(c: PContext, n: PNode, prev: PType): PType = result = newOrPrevType(tyDistinct, prev, c) if sonsLen(n) == 1: addSon(result, semTypeNode(c, n.sons[0], nil)) - else: liMessage(n.info, errXExpectsOneTypeParam, "distinct") + else: GlobalError(n.info, errXExpectsOneTypeParam, "distinct") proc semRangeAux(c: PContext, n: PNode, prev: PType): PType = if (n.kind != nkRange): InternalError(n.info, "semRangeAux") checkSonsLen(n, 2) result = newOrPrevType(tyRange, prev, c) result.n = newNodeI(nkRange, n.info) - if (n.sons[0] == nil) or (n.sons[1] == nil): - liMessage(n.Info, errRangeIsEmpty) + if (n.sons[0].kind == nkEmpty) or (n.sons[1].kind == nkEmpty): + GlobalError(n.Info, errRangeIsEmpty) var a = semConstExpr(c, n.sons[0]) var b = semConstExpr(c, n.sons[1]) - if not sameType(a.typ, b.typ): liMessage(n.info, errPureTypeMismatch) + if not sameType(a.typ, b.typ): GlobalError(n.info, errPureTypeMismatch) if not (a.typ.kind in {tyInt..tyInt64, tyEnum, tyBool, tyChar, tyFloat..tyFloat128}): - liMessage(n.info, errOrdinalTypeExpected) + GlobalError(n.info, errOrdinalTypeExpected) if enumHasWholes(a.typ): - liMessage(n.info, errEnumXHasHoles, a.typ.sym.name.s) - if not leValue(a, b): liMessage(n.Info, errRangeIsEmpty) + GlobalError(n.info, errEnumXHasHoles, a.typ.sym.name.s) + if not leValue(a, b): GlobalError(n.Info, errRangeIsEmpty) addSon(result.n, a) addSon(result.n, b) addSon(result, b.typ) @@ -143,9 +143,9 @@ proc semRange(c: PContext, n: PNode, prev: PType): PType = result = nil if sonsLen(n) == 2: if n.sons[1].kind == nkRange: result = semRangeAux(c, n.sons[1], prev) - else: liMessage(n.sons[0].info, errRangeExpected) + else: GlobalError(n.sons[0].info, errRangeExpected) else: - liMessage(n.info, errXExpectsOneTypeParam, "range") + GlobalError(n.info, errXExpectsOneTypeParam, "range") proc semArray(c: PContext, n: PNode, prev: PType): PType = var indx, base: PType @@ -158,13 +158,13 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType = if indx.kind == tyGenericInst: indx = lastSon(indx) if indx.kind != tyGenericParam: if not isOrdinalType(indx): - liMessage(n.sons[1].info, errOrdinalTypeExpected) + GlobalError(n.sons[1].info, errOrdinalTypeExpected) if enumHasWholes(indx): - liMessage(n.sons[1].info, errEnumXHasHoles, indx.sym.name.s) + GlobalError(n.sons[1].info, errEnumXHasHoles, indx.sym.name.s) base = semTypeNode(c, n.sons[2], nil) addSon(result, base) else: - liMessage(n.info, errArrayExpectsTwoTypeParams) + GlobalError(n.info, errArrayExpectsTwoTypeParams) proc semOrdinal(c: PContext, n: PNode, prev: PType): PType = result = newOrPrevType(tyOrdinal, prev, c) @@ -172,46 +172,44 @@ proc semOrdinal(c: PContext, n: PNode, prev: PType): PType = var base = semTypeNode(c, n.sons[1], nil) if base.kind != tyGenericParam: if not isOrdinalType(base): - liMessage(n.sons[1].info, errOrdinalTypeExpected) + GlobalError(n.sons[1].info, errOrdinalTypeExpected) addSon(result, base) else: - liMessage(n.info, errXExpectsOneTypeParam, "ordinal") + GlobalError(n.info, errXExpectsOneTypeParam, "ordinal") proc semTypeIdent(c: PContext, n: PNode): PSym = result = qualifiedLookup(c, n, {checkAmbiguity, checkUndeclared}) if (result != nil): markUsed(n, result) - if result.kind != skType: liMessage(n.info, errTypeExpected) + if result.kind != skType: GlobalError(n.info, errTypeExpected) else: - liMessage(n.info, errIdentifierExpected) + GlobalError(n.info, errIdentifierExpected) proc semTuple(c: PContext, n: PNode, prev: PType): PType = var - length, counter: int typ: PType check: TIntSet - a: PNode - field: PSym result = newOrPrevType(tyTuple, prev, c) result.n = newNodeI(nkRecList, n.info) IntSetInit(check) - counter = 0 + var counter = 0 for i in countup(0, sonsLen(n) - 1): - a = n.sons[i] + var a = n.sons[i] if (a.kind != nkIdentDefs): IllFormedAst(a) checkMinSonsLen(a, 3) - length = sonsLen(a) - if a.sons[length - 2] != nil: typ = semTypeNode(c, a.sons[length - 2], nil) - else: liMessage(a.info, errTypeExpected) - if a.sons[length - 1] != nil: - liMessage(a.sons[length - 1].info, errInitHereNotAllowed) + var length = sonsLen(a) + if a.sons[length - 2].kind != nkEmpty: + typ = semTypeNode(c, a.sons[length - 2], nil) + else: GlobalError(a.info, errTypeExpected) + if a.sons[length - 1].kind != nkEmpty: + GlobalError(a.sons[length - 1].info, errInitHereNotAllowed) for j in countup(0, length - 3): - field = newSymS(skField, a.sons[j], c) + var field = newSymS(skField, a.sons[j], c) field.typ = typ field.position = counter inc(counter) if IntSetContainsOrIncl(check, field.name.id): - liMessage(a.sons[j].info, errAttemptToRedefine, field.name.s) + GlobalError(a.sons[j].info, errAttemptToRedefine, field.name.s) addSon(result.n, newSymNode(field)) addSon(result, typ) @@ -220,10 +218,11 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = elem: PType isConcrete: bool if (s.typ == nil) or (s.typ.kind != tyGenericBody): - liMessage(n.info, errCannotInstantiateX, s.name.s) + GlobalError(n.info, errCannotInstantiateX, s.name.s) result = newOrPrevType(tyGenericInvokation, prev, c) if (s.typ.containerID == 0): InternalError(n.info, "semtypes.semGeneric") - if sonsLen(n) != sonsLen(s.typ): liMessage(n.info, errWrongNumberOfArguments) + if sonsLen(n) != sonsLen(s.typ): + GlobalError(n.info, errWrongNumberOfArguments) addSon(result, s.typ) isConcrete = true # iterate over arguments: for i in countup(1, sonsLen(n) - 1): @@ -231,7 +230,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = if elem.kind == tyGenericParam: isConcrete = false addSon(result, elem) if isConcrete: - if s.ast == nil: liMessage(n.info, errCannotInstantiateX, s.name.s) + if s.ast == nil: GlobalError(n.info, errCannotInstantiateX, s.name.s) result = instGenericContainer(c, n, result) proc semIdentVis(c: PContext, kind: TSymKind, n: PNode, @@ -246,7 +245,7 @@ proc semIdentVis(c: PContext, kind: TSymKind, n: PNode, elif (sfMinus in allowed) and (v.id == ord(wMinus)): incl(result.flags, sfMinus) else: - liMessage(n.sons[0].info, errInvalidVisibilityX, v.s) + GlobalError(n.sons[0].info, errInvalidVisibilityX, v.s) else: illFormedAst(n) else: @@ -271,8 +270,7 @@ proc checkForOverlap(c: PContext, t, ex: PNode, branchIndex: int) = for i in countup(1, branchIndex - 1): for j in countup(0, sonsLen(t.sons[i]) - 2): if overlap(t.sons[i].sons[j], ex): - #MessageOut(renderTree(t)); - liMessage(ex.info, errDuplicateCaseLabel) + LocalError(ex.info, errDuplicateCaseLabel) proc semBranchExpr(c: PContext, t: PNode, ex: var PNode) = ex = semConstExpr(c, ex) @@ -290,7 +288,7 @@ proc SemCaseBranch(c: PContext, t, branch: PNode, branchIndex: int, semBranchExpr(c, t, b.sons[1]) if emptyRange(b.sons[0], b.sons[1]): #MessageOut(renderTree(t)); - liMessage(b.info, errRangeIsEmpty) + GlobalError(b.info, errRangeIsEmpty) covered = covered + getOrdValue(b.sons[1]) - getOrdValue(b.sons[0]) + 1 else: semBranchExpr(c, t, branch.sons[i]) # NOT: `b`, because of var-param! @@ -314,11 +312,11 @@ proc semRecordCase(c: PContext, n: PNode, check: var TIntSet, pos: var int, incl(a.sons[0].sym.flags, sfDiscriminant) covered = 0 typ = skipTypes(a.sons[0].Typ, abstractVar) - if not isOrdinalType(typ): liMessage(n.info, errSelectorMustBeOrdinal) + if not isOrdinalType(typ): GlobalError(n.info, errSelectorMustBeOrdinal) if firstOrd(typ) < 0: - liMessage(n.info, errOrdXMustNotBeNegative, a.sons[0].sym.name.s) + GlobalError(n.info, errOrdXMustNotBeNegative, a.sons[0].sym.name.s) if lengthOrd(typ) > 0x00007FFF: - liMessage(n.info, errLenXinvalid, a.sons[0].sym.name.s) + GlobalError(n.info, errLenXinvalid, a.sons[0].sym.name.s) chckCovered = true for i in countup(1, sonsLen(n) - 1): b = copyTree(n.sons[i]) @@ -334,7 +332,7 @@ proc semRecordCase(c: PContext, n: PNode, check: var TIntSet, pos: var int, semRecordNodeAux(c, lastSon(n.sons[i]), check, pos, b, rectype) addSon(a, b) if chckCovered and (covered != lengthOrd(a.sons[0].typ)): - liMessage(a.info, errNotAllCasesCovered) + localError(a.info, errNotAllCasesCovered) addSon(father, a) proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, pos: var int, @@ -370,8 +368,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, pos: var int, if father.kind != nkRecList: addSon(father, newNodeI(nkRecList, n.info)) of nkRecList: # attempt to keep the nesting at a sane level: - if father.kind == nkRecList: a = father - else: a = copyNode(n) + var a = if father.kind == nkRecList: father else: copyNode(n) for i in countup(0, sonsLen(n) - 1): semRecordNodeAux(c, n.sons[i], check, pos, a, rectype) if a != father: addSon(father, a) @@ -381,11 +378,12 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, pos: var int, if (father.kind != nkRecList) and (length >= 4): a = newNodeI(nkRecList, n.info) else: - a = nil - if n.sons[length - 1] != nil: - liMessage(n.sons[length - 1].info, errInitHereNotAllowed) - if n.sons[length - 2] == nil: liMessage(n.info, errTypeExpected) - typ = semTypeNode(c, n.sons[length - 2], nil) + a = ast.emptyNode + if n.sons[length - 1].kind != nkEmpty: + localError(n.sons[length - 1].info, errInitHereNotAllowed) + if n.sons[length - 2].kind == nkEmpty: + GlobalError(n.info, errTypeExpected) + typ = semTypeNode(c, n.sons[length-2], nil) for i in countup(0, sonsLen(n) - 3): f = semIdentWithPragma(c, skField, n.sons[i], {sfStar, sfMinus}) f.typ = typ @@ -396,10 +394,11 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, pos: var int, f.flags = f.flags + ({sfImportc, sfExportc} * rectype.flags) inc(pos) if IntSetContainsOrIncl(check, f.name.id): - liMessage(n.sons[i].info, errAttemptToRedefine, f.name.s) - if a == nil: addSon(father, newSymNode(f)) + localError(n.sons[i].info, errAttemptToRedefine, f.name.s) + if a.kind == nkEmpty: addSon(father, newSymNode(f)) else: addSon(a, newSymNode(f)) - if a != nil: addSon(father, a) + if a.kind != nkEmpty: addSon(father, a) + of nkEmpty: nil else: illFormedAst(n) proc addInheritedFieldsAux(c: PContext, check: var TIntSet, pos: var int, @@ -435,11 +434,11 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType): PType = IntSetInit(check) pos = 0 # n.sons[0] contains the pragmas (if any). We process these later... checkSonsLen(n, 3) - if n.sons[1] != nil: + if n.sons[1].kind != nkEmpty: base = semTypeNode(c, n.sons[1].sons[0], nil) if base.kind == tyObject: addInheritedFields(c, check, pos, base) - else: liMessage(n.sons[1].info, errInheritanceOnlyWithNonFinalObjects) - else: + else: localError(n.sons[1].info, errInheritanceOnlyWithNonFinalObjects) + else: base = nil if n.kind != nkObjectTy: InternalError(n.info, "semObjectNode") result = newOrPrevType(tyObject, prev, c) @@ -447,7 +446,7 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType): PType = result.n = newNodeI(nkRecList, n.info) semRecordNodeAux(c, n.sons[2], check, pos, result.n, result.sym) if (base != nil) and (tfFinal in base.flags): - liMessage(n.sons[1].info, errInheritanceOnlyWithNonFinalObjects) + localError(n.sons[1].info, errInheritanceOnlyWithNonFinalObjects) proc addTypeVarsOfGenericBody(c: PContext, t: PType, genericParams: PNode, cl: var TIntSet): PType = @@ -509,11 +508,11 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, prev: PType): PType = if a.kind != nkIdentDefs: IllFormedAst(a) checkMinSonsLen(a, 3) var length = sonsLen(a) - if a.sons[length - 2] != nil: + if a.sons[length - 2].kind != nkEmpty: typ = paramType(c, a.sons[length - 2], genericParams, cl) else: typ = nil - if a.sons[length - 1] != nil: + if a.sons[length - 1].kind != nkEmpty: def = semExprWithType(c, a.sons[length - 1]) # check type compability between def.typ and typ: if typ != nil: @@ -523,18 +522,18 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, prev: PType): PType = else: typ = def.typ else: - def = nil + def = ast.emptyNode for j in countup(0, length - 3): var arg = newSymS(skParam, a.sons[j], c) arg.typ = typ arg.position = counter inc(counter) - arg.ast = copyTree(def) + if def.kind != nkEmpty: arg.ast = copyTree(def) if IntSetContainsOrIncl(check, arg.name.id): - liMessage(a.sons[j].info, errAttemptToRedefine, arg.name.s) + LocalError(a.sons[j].info, errAttemptToRedefine, arg.name.s) addSon(result.n, newSymNode(arg)) addSon(result, typ) - if n.sons[0] != nil: + if n.sons[0].kind != nkEmpty: result.sons[0] = paramType(c, n.sons[0], genericParams, cl) res.typ = result.sons[0] @@ -554,7 +553,7 @@ proc semBlockType(c: PContext, n: PNode, prev: PType): PType = Inc(c.p.nestedBlockCounter) checkSonsLen(n, 2) openScope(c.tab) - if n.sons[0] != nil: + if n.sons[0].kind != nkEmpty: addDecl(c, newSymS(skLabel, n.sons[0], c)) result = semStmtListType(c, n.sons[1], prev) n.sons[1].typ = result @@ -567,13 +566,13 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = s: PSym t: PType result = nil - if n == nil: return case n.kind + of nkEmpty: nil of nkTypeOfExpr: result = semExprWithType(c, n, {efAllowType}).typ of nkPar: if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev) - else: liMessage(n.info, errTypeExpected) + else: GlobalError(n.info, errTypeExpected) of nkBracketExpr: checkMinSonsLen(n, 2) s = semTypeIdent(c, n.sons[0]) @@ -587,7 +586,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = else: result = semGeneric(c, n, s, prev) of nkIdent, nkDotExpr, nkAccQuoted: s = semTypeIdent(c, n) - if s.typ == nil: liMessage(n.info, errTypeExpected) + if s.typ == nil: GlobalError(n.info, errTypeExpected) if prev == nil: result = s.typ else: @@ -604,7 +603,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result = prev markUsed(n, n.sym) else: - liMessage(n.info, errTypeExpected) + GlobalError(n.info, errTypeExpected) of nkObjectTy: result = semObjectNode(c, n, prev) of nkTupleTy: result = semTuple(c, n, prev) of nkRefTy: result = semAnyRef(c, n, tyRef, "ref", prev) @@ -627,7 +626,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = of nkBlockType: result = semBlockType(c, n, prev) else: - liMessage(n.info, errTypeExpected) + GlobalError(n.info, errTypeExpected) #internalError(n.info, 'semTypeNode(' +{&} nodeKindToStr[n.kind] +{&} ')'); proc setMagicType(m: PSym, kind: TTypeKind, size: int) = @@ -665,5 +664,5 @@ proc processMagicType(c: PContext, m: PSym) = of mStmt: setMagicType(m, tyStmt, 0) of mTypeDesc: setMagicType(m, tyTypeDesc, 0) of mArray, mOpenArray, mRange, mSet, mSeq, mOrdinal: return - else: liMessage(m.info, errTypeExpected) + else: GlobalError(m.info, errTypeExpected) diff --git a/rod/sigmatch.nim b/rod/sigmatch.nim index bcb9198da..cddfc89cb 100755 --- a/rod/sigmatch.nim +++ b/rod/sigmatch.nim @@ -443,7 +443,7 @@ proc implicitConv(kind: TNodeKind, f: PType, arg: PNode, m: TCandidate, if containsGenericType(f): result.typ = getInstantiatedType(c, arg, m, f) else: result.typ = f if result.typ == nil: InternalError(arg.info, "implicitConv") - addSon(result, nil) + addSon(result, ast.emptyNode) addSon(result, arg) proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType, @@ -578,7 +578,7 @@ proc matches(c: PContext, n: PNode, m: var TCandidate) = # named param # check if m.callee has such a param: if n.sons[a].sons[0].kind != nkIdent: - liMessage(n.sons[a].info, errNamedParamHasToBeIdent) + LocalError(n.sons[a].info, errNamedParamHasToBeIdent) m.state = csNoMatch return formal = getSymFromList(m.callee.n, n.sons[a].sons[0].ident, 1) @@ -588,7 +588,7 @@ proc matches(c: PContext, n: PNode, m: var TCandidate) = return if IntSetContainsOrIncl(marker, formal.position): # already in namedParams: - liMessage(n.sons[a].info, errCannotBindXTwice, formal.name.s) + LocalError(n.sons[a].info, errCannotBindXTwice, formal.name.s) m.state = csNoMatch return m.baseTypeMatch = false @@ -633,7 +633,7 @@ proc matches(c: PContext, n: PNode, m: var TCandidate) = formal = m.callee.n.sons[f].sym if IntSetContainsOrIncl(marker, formal.position): # already in namedParams: - liMessage(n.sons[a].info, errCannotBindXTwice, formal.name.s) + LocalError(n.sons[a].info, errCannotBindXTwice, formal.name.s) m.state = csNoMatch return m.baseTypeMatch = false @@ -683,12 +683,13 @@ proc semDirectCallWithBinding(c: PContext, n, f: PNode, filter: TSymKinds, var o: TOverloadIter x, y, z: TCandidate - #liMessage(n.info, warnUser, renderTree(n)); + #Message(n.info, warnUser, renderTree(n)) var sym = initOverloadIter(o, c, f) result = nil if sym == nil: return initCandidate(x, sym, initialBinding) initCandidate(y, sym, initialBinding) + while sym != nil: if sym.kind in filter: initCandidate(z, sym, initialBinding) @@ -711,7 +712,7 @@ proc semDirectCallWithBinding(c: PContext, n, f: PNode, filter: TSymKinds, not sameMethodDispatcher(x.calleeSym, y.calleeSym): if x.state != csMatch: InternalError(n.info, "x.state is not csMatch") - liMessage(n.Info, errGenerated, msgKindToString(errAmbiguousCallXYZ) % [ + LocalError(n.Info, errGenerated, msgKindToString(errAmbiguousCallXYZ) % [ getProcHeader(x.calleeSym), getProcHeader(y.calleeSym), x.calleeSym.Name.s]) else: @@ -719,7 +720,7 @@ proc semDirectCallWithBinding(c: PContext, n, f: PNode, filter: TSymKinds, markUsed(n, x.calleeSym) if x.calleeSym.ast == nil: internalError(n.info, "calleeSym.ast is nil") # XXX: remove this check! - if x.calleeSym.ast.sons[genericParamsPos] != nil: + if x.calleeSym.ast.sons[genericParamsPos].kind != nkEmpty: # a generic proc! x.calleeSym = generateInstance(c, x.calleeSym, x.bindings, n.info) x.callee = x.calleeSym.typ diff --git a/rod/tccgen.nim b/rod/tccgen.nim index ca7bac193..2fd207aaa 100755 --- a/rod/tccgen.nim +++ b/rod/tccgen.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. diff --git a/rod/transf.nim b/rod/transf.nim index 9eddcbe68..fb9c640cd 100755 --- a/rod/transf.nim +++ b/rod/transf.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -219,12 +219,11 @@ proc transformVarSection(c: PTransf, v: PNode): PTransNode = newVar.owner = getCurrOwner(c) IdNodeTablePut(c.transCon.mapping, it.sons[j].sym, newSymNode(newVar)) defs[j] = newSymNode(newVar).PTransNode - assert(it.sons[L-2] == nil) + assert(it.sons[L-2].kind == nkEmpty) defs[L-1] = transform(c, it.sons[L-1]) result[i] = defs proc hasContinue(n: PNode): bool = - if n == nil: return case n.kind of nkEmpty..nkNilLit, nkForStmt, nkWhileStmt: nil of nkContinueStmt: result = true @@ -271,7 +270,6 @@ proc unpackTuple(c: PTransf, n: PNode, father: PTransNode) = transform(c, newTupleAccess(n, i)))) proc introduceNewLocalVars(c: PTransf, n: PNode): PTransNode = - if n == nil: return case n.kind of nkSym: return transformSym(c, n) @@ -311,8 +309,8 @@ proc transformYield(c: PTransf, n: PNode): PTransNode = proc addVar(father, v: PNode) = var vpart = newNodeI(nkIdentDefs, v.info) addSon(vpart, v) - addSon(vpart, nil) - addSon(vpart, nil) + addSon(vpart, ast.emptyNode) + addSon(vpart, ast.emptyNode) addSon(father, vpart) proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode = @@ -515,7 +513,6 @@ proc getMagicOp(call: PNode): TMagic = proc gatherVars(c: PTransf, n: PNode, marked: var TIntSet, owner: PSym, container: PNode) = # gather used vars for closure generation - if n == nil: return case n.kind of nkSym: var s = n.sym @@ -662,7 +659,6 @@ proc transformCall(c: PTransf, n: PNode): PTransNode = result = transformSons(c, n) proc transform(c: PTransf, n: PNode): PTransNode = - if n == nil: return case n.kind of nkSym: return transformSym(c, n) @@ -678,7 +674,7 @@ proc transform(c: PTransf, n: PNode): PTransNode = of nkCaseStmt: result = transformCase(c, n) of nkProcDef, nkMethodDef, nkIteratorDef, nkMacroDef: - if n.sons[genericParamsPos] == nil: + if n.sons[genericParamsPos].kind == nkEmpty: n.sons[codePos] = PNode(transform(c, n.sons[codePos])) if n.kind == nkMethodDef: methodDef(n.sons[namePos].sym) result = PTransNode(n) @@ -727,6 +723,7 @@ 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 var c = PTransf(context) pushTransCon(c, newTransCon(getCurrOwner(c))) result = PNode(transform(c, n)) diff --git a/rod/types.nim b/rod/types.nim index d26136aa9..dcabbd3ee 100755 --- a/rod/types.nim +++ b/rod/types.nim @@ -119,7 +119,7 @@ proc getOrdValue(n: PNode): biggestInt = of nkCharLit..nkInt64Lit: result = n.intVal of nkNilLit: result = 0 else: - liMessage(n.info, errOrdinalTypeExpected) + LocalError(n.info, errOrdinalTypeExpected) result = 0 proc isCompatibleToCString(a: PType): bool = diff --git a/tests/accept/compile/tgenericvariant.nim b/tests/accept/compile/tgenericvariant.nim index 51d01355a..51d01355a 100644..100755 --- a/tests/accept/compile/tgenericvariant.nim +++ b/tests/accept/compile/tgenericvariant.nim diff --git a/tests/accept/compile/tnamedparams.nim b/tests/accept/compile/tnamedparams.nim index 4b0cd5361..4b0cd5361 100644..100755 --- a/tests/accept/compile/tnamedparams.nim +++ b/tests/accept/compile/tnamedparams.nim diff --git a/tests/accept/compile/toop.nim b/tests/accept/compile/toop.nim index d103c6304..d103c6304 100644..100755 --- a/tests/accept/compile/toop.nim +++ b/tests/accept/compile/toop.nim diff --git a/tests/accept/run/spec.csv b/tests/accept/run/spec.csv index e9c49ea74..5102c85b1 100755 --- a/tests/accept/run/spec.csv +++ b/tests/accept/run/spec.csv @@ -22,7 +22,7 @@ tcopy.nim;TEMP=C:\Programs\xyz\bin tcountup.nim;0123456789 tcurrncy.nim;25 temit.nim;509 -tenumhole;my value A1my value Bconc2valueCabc4abc +tenumhole.nim;my value A1my value Bconc2valueCabc4abc texcsub.nim;caught! texplicitgeneric1.nim;Key: 12 value: 12Key: 13 value: 13 Key: A value: 12 Key: B value: 13 tfinally.nim;came here 3 @@ -47,7 +47,7 @@ tmultim1.nim;7 tmultim2.nim;collide: unit, thing collide: unit, thing collide: thing, unit tmultim3.nim;Hi derived! tmultim4.nim;hello -tnamedenumfields;my value A0my value Bconc1valueCabc3abc +tnamedenumfields.nim;my value A0my value Bconc1valueCabc3abc tnestif.nim;i == 2 tnestprc.nim;10 toop1.nim;34[]o 5 diff --git a/tests/accept/run/tarraycons.nim b/tests/accept/run/tarraycons.nim index 12f13ac33..12f13ac33 100644..100755 --- a/tests/accept/run/tarraycons.nim +++ b/tests/accept/run/tarraycons.nim diff --git a/tests/accept/run/tcountup.nim b/tests/accept/run/tcountup.nim index 4d4c9b304..4d4c9b304 100644..100755 --- a/tests/accept/run/tcountup.nim +++ b/tests/accept/run/tcountup.nim diff --git a/tests/accept/run/temit.nim b/tests/accept/run/temit.nim index 81f9b53ae..81f9b53ae 100644..100755 --- a/tests/accept/run/temit.nim +++ b/tests/accept/run/temit.nim diff --git a/tests/accept/run/tenumhole.nim b/tests/accept/run/tenumhole.nim index 75fb74592..75fb74592 100644..100755 --- a/tests/accept/run/tenumhole.nim +++ b/tests/accept/run/tenumhole.nim diff --git a/tests/accept/run/texcsub.nim b/tests/accept/run/texcsub.nim index b35f0fa3f..b35f0fa3f 100644..100755 --- a/tests/accept/run/texcsub.nim +++ b/tests/accept/run/texcsub.nim diff --git a/tests/accept/run/tfloat3.nim b/tests/accept/run/tfloat3.nim index 72acce958..72acce958 100644..100755 --- a/tests/accept/run/tfloat3.nim +++ b/tests/accept/run/tfloat3.nim diff --git a/tests/accept/run/titer6.nim b/tests/accept/run/titer6.nim index 8a1d9cf1b..8a1d9cf1b 100644..100755 --- a/tests/accept/run/titer6.nim +++ b/tests/accept/run/titer6.nim diff --git a/tests/accept/run/tmultim2.nim b/tests/accept/run/tmultim2.nim index bf3b5fd6e..c43c9b6f0 100755 --- a/tests/accept/run/tmultim2.nim +++ b/tests/accept/run/tmultim2.nim @@ -22,7 +22,7 @@ proc test(a, b: TThing) {.inline.} = var a: TThing b, c: TUnit -collide(b, c) # ambiguous unit, thing or thing, unit? -> prefer unit, thing! +collide(b, c) # ambiguous (unit, thing) or (thing, unit)? -> prefer unit, thing! test(b, c) collide(a, b) #OUT collide: unit, thing collide: unit, thing collide: thing, unit diff --git a/tests/accept/run/tmultim4.nim b/tests/accept/run/tmultim4.nim index fbfaf3175..fbfaf3175 100644..100755 --- a/tests/accept/run/tmultim4.nim +++ b/tests/accept/run/tmultim4.nim diff --git a/tests/accept/run/tnamedenumfields.nim b/tests/accept/run/tnamedenumfields.nim index 6012cf1eb..6012cf1eb 100644..100755 --- a/tests/accept/run/tnamedenumfields.nim +++ b/tests/accept/run/tnamedenumfields.nim diff --git a/tests/accept/run/toprprec.nim b/tests/accept/run/toprprec.nim index 4728b2e68..4728b2e68 100644..100755 --- a/tests/accept/run/toprprec.nim +++ b/tests/accept/run/toprprec.nim diff --git a/tests/gc/tthreads.nim b/tests/gc/tthreads.nim index 2ef599e53..2ef599e53 100644..100755 --- a/tests/gc/tthreads.nim +++ b/tests/gc/tthreads.nim diff --git a/tests/reject/tarraycons.nim b/tests/reject/tarraycons.nim index 1809f8735..1809f8735 100644..100755 --- a/tests/reject/tarraycons.nim +++ b/tests/reject/tarraycons.nim diff --git a/tests/reject/tmethod.nim b/tests/reject/tmethod.nim index 101cabf25..101cabf25 100644..100755 --- a/tests/reject/tmethod.nim +++ b/tests/reject/tmethod.nim diff --git a/tests/reject/tnamedparams.nim b/tests/reject/tnamedparams.nim index 6c59518b3..6c59518b3 100644..100755 --- a/tests/reject/tnamedparams.nim +++ b/tests/reject/tnamedparams.nim diff --git a/tests/reject/twrongtupleaccess.nim b/tests/reject/twrongtupleaccess.nim index f706e267c..f706e267c 100644..100755 --- a/tests/reject/twrongtupleaccess.nim +++ b/tests/reject/twrongtupleaccess.nim diff --git a/tests/testdata/jsontest2.json b/tests/testdata/jsontest2.json index 3a2294474..3a2294474 100644..100755 --- a/tests/testdata/jsontest2.json +++ b/tests/testdata/jsontest2.json diff --git a/todo.txt b/todo.txt index 476eb01e9..92bf541f3 100755 --- a/todo.txt +++ b/todo.txt @@ -1,7 +1,4 @@ -- ban ``nil`` from the AST. This might also fix bugs concerning macros. - TODO: - * semantic checking (keep in mind incremental parsing!) - * code generators +- 'suggest' - thread support: threadvar on Windows seems broken; add --deadlock_prevention:on|off switch diff --git a/web/news.txt b/web/news.txt index 1548fdc0f..68f0fb190 100755 --- a/web/news.txt +++ b/web/news.txt @@ -61,6 +61,7 @@ Additions - Added basic thread support via the ``threads`` core module and the ``--threads:on`` command line switch. - Added unary ``<`` for nice looking excluding upper bounds in ranges. +- Added ``math.floor``. 2010-10-20 Version 0.8.10 released diff --git a/web/nimrod.ini b/web/nimrod.ini index fc11c00d0..fc11c00d0 100644..100755 --- a/web/nimrod.ini +++ b/web/nimrod.ini |