diff options
76 files changed, 1103 insertions, 1492 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 5a84b2b02..ec727544e 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1095,9 +1095,6 @@ proc newSym*(symKind: TSymKind, name: PIdent, owner: PSym, # writeStacktrace() # MessageOut(name.s & " has id: " & toString(result.id)) -var emptyNode* = newNode(nkEmpty) # XXX global variable here! -# There is a single empty node that is shared! Do not overwrite it! - proc isMetaType*(t: PType): bool = return t.kind in tyMetaTypes or (t.kind == tyStatic and t.n == nil) or @@ -1229,13 +1226,10 @@ proc addSon*(father, son: PNode) = if isNil(father.sons): father.sons = @[] add(father.sons, son) -var emptyParams = newNode(nkFormalParams) -emptyParams.addSon(emptyNode) - proc newProcNode*(kind: TNodeKind, info: TLineInfo, body: PNode, - params = emptyParams, + params, name, pattern, genericParams, - pragmas, exceptions = ast.emptyNode): PNode = + pragmas, exceptions: PNode): PNode = result = newNodeI(kind, info) result.sons = @[name, pattern, genericParams, params, pragmas, exceptions, body] diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index d98a42b34..1b6417964 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -15,13 +15,13 @@ import ast, hashes, intsets, strutils, options, msgs, ropes, idents, rodutils proc hashNode*(p: RootRef): Hash -proc treeToYaml*(n: PNode, indent: int = 0, maxRecDepth: int = - 1): Rope +proc treeToYaml*(conf: ConfigRef; n: PNode, indent: int = 0, maxRecDepth: int = - 1): Rope # Convert a tree into its YAML representation; this is used by the # YAML code generator and it is invaluable for debugging purposes. # If maxRecDepht <> -1 then it won't print the whole graph. -proc typeToYaml*(n: PType, indent: int = 0, maxRecDepth: int = - 1): Rope -proc symToYaml*(n: PSym, indent: int = 0, maxRecDepth: int = - 1): Rope -proc lineInfoToStr*(info: TLineInfo): Rope +proc typeToYaml*(conf: ConfigRef; n: PType, indent: int = 0, maxRecDepth: int = - 1): Rope +proc symToYaml*(conf: ConfigRef; n: PSym, indent: int = 0, maxRecDepth: int = - 1): Rope +proc lineInfoToStr*(conf: ConfigRef; info: TLineInfo): Rope # ----------------------- node sets: --------------------------------------- proc objectSetContains*(t: TObjectSet, obj: RootRef): bool @@ -61,11 +61,12 @@ type proc initIdentIter*(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym proc nextIdentIter*(ti: var TIdentIter, tab: TStrTable): PSym -# these are for debugging only: They are not really deprecated, but I want -# the warning so that release versions do not contain debugging statements: -proc debug*(n: PSym) {.deprecated.} -proc debug*(n: PType) {.deprecated.} -proc debug*(n: PNode) {.deprecated.} +when declared(echo): + # these are for debugging only: They are not really deprecated, but I want + # the warning so that release versions do not contain debugging statements: + proc debug*(conf: ConfigRef; n: PSym) {.deprecated.} + proc debug*(conf: ConfigRef; n: PType) {.deprecated.} + proc debug*(conf: ConfigRef; n: PNode) {.deprecated.} template mdbg*: bool {.dirty.} = when compiles(c.module): @@ -250,16 +251,16 @@ proc flagsToStr[T](flags: set[T]): Rope = add(result, makeYamlString($x)) result = "[" & result & "]" -proc lineInfoToStr(info: TLineInfo): Rope = - result = "[$1, $2, $3]" % [makeYamlString(toFilename(info)), +proc lineInfoToStr(conf: ConfigRef; info: TLineInfo): Rope = + result = "[$1, $2, $3]" % [makeYamlString(toFilename(conf, info)), rope(toLinenumber(info)), rope(toColumn(info))] -proc treeToYamlAux(n: PNode, marker: var IntSet, +proc treeToYamlAux(conf: ConfigRef; n: PNode, marker: var IntSet, indent, maxRecDepth: int): Rope -proc symToYamlAux(n: PSym, marker: var IntSet, +proc symToYamlAux(conf: ConfigRef; n: PSym, marker: var IntSet, indent, maxRecDepth: int): Rope -proc typeToYamlAux(n: PType, marker: var IntSet, +proc typeToYamlAux(conf: ConfigRef; n: PType, marker: var IntSet, indent, maxRecDepth: int): Rope proc ropeConstr(indent: int, c: openArray[Rope]): Rope = @@ -273,7 +274,7 @@ proc ropeConstr(indent: int, c: openArray[Rope]): Rope = inc(i, 2) addf(result, "$N$1}", [rspaces(indent)]) -proc symToYamlAux(n: PSym, marker: var IntSet, indent: int, +proc symToYamlAux(conf: ConfigRef; n: PSym, marker: var IntSet, indent: int, maxRecDepth: int): Rope = if n == nil: result = rope("null") @@ -281,20 +282,20 @@ proc symToYamlAux(n: PSym, marker: var IntSet, indent: int, result = "\"$1 @$2\"" % [rope(n.name.s), rope( strutils.toHex(cast[ByteAddress](n), sizeof(n) * 2))] else: - var ast = treeToYamlAux(n.ast, marker, indent + 2, maxRecDepth - 1) + var ast = treeToYamlAux(conf, n.ast, marker, indent + 2, maxRecDepth - 1) result = ropeConstr(indent, [rope("kind"), makeYamlString($n.kind), rope("name"), makeYamlString(n.name.s), - rope("typ"), typeToYamlAux(n.typ, marker, + rope("typ"), typeToYamlAux(conf, n.typ, marker, indent + 2, maxRecDepth - 1), - rope("info"), lineInfoToStr(n.info), + rope("info"), lineInfoToStr(conf, n.info), rope("flags"), flagsToStr(n.flags), rope("magic"), makeYamlString($n.magic), rope("ast"), ast, rope("options"), flagsToStr(n.options), rope("position"), rope(n.position)]) -proc typeToYamlAux(n: PType, marker: var IntSet, indent: int, +proc typeToYamlAux(conf: ConfigRef; n: PType, marker: var IntSet, indent: int, maxRecDepth: int): Rope = if n == nil: result = rope("null") @@ -306,15 +307,15 @@ proc typeToYamlAux(n: PType, marker: var IntSet, indent: int, result = rope("[") for i in countup(0, sonsLen(n) - 1): if i > 0: add(result, ",") - addf(result, "$N$1$2", [rspaces(indent + 4), typeToYamlAux(n.sons[i], + addf(result, "$N$1$2", [rspaces(indent + 4), typeToYamlAux(conf, n.sons[i], marker, indent + 4, maxRecDepth - 1)]) addf(result, "$N$1]", [rspaces(indent + 2)]) else: result = rope("null") result = ropeConstr(indent, [rope("kind"), makeYamlString($n.kind), - rope("sym"), symToYamlAux(n.sym, marker, - indent + 2, maxRecDepth - 1), rope("n"), treeToYamlAux(n.n, marker, + rope("sym"), symToYamlAux(conf, n.sym, marker, + indent + 2, maxRecDepth - 1), rope("n"), treeToYamlAux(conf, n.n, marker, indent + 2, maxRecDepth - 1), rope("flags"), flagsToStr(n.flags), rope("callconv"), makeYamlString(CallingConvToStr[n.callConv]), @@ -322,7 +323,7 @@ proc typeToYamlAux(n: PType, marker: var IntSet, indent: int, rope("align"), rope(n.align), rope("sons"), result]) -proc treeToYamlAux(n: PNode, marker: var IntSet, indent: int, +proc treeToYamlAux(conf: ConfigRef; n: PNode, marker: var IntSet, indent: int, maxRecDepth: int): Rope = if n == nil: result = rope("null") @@ -330,7 +331,7 @@ proc treeToYamlAux(n: PNode, marker: var IntSet, indent: int, var istr = rspaces(indent + 2) result = "{$N$1\"kind\": $2" % [istr, makeYamlString($n.kind)] if maxRecDepth != 0: - addf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)]) + addf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(conf, n.info)]) case n.kind of nkCharLit..nkInt64Lit: addf(result, ",$N$1\"intVal\": $2", [istr, rope(n.intVal)]) @@ -344,7 +345,7 @@ proc treeToYamlAux(n: PNode, marker: var IntSet, indent: int, addf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)]) of nkSym: addf(result, ",$N$1\"sym\": $2", - [istr, symToYamlAux(n.sym, marker, indent + 2, maxRecDepth)]) + [istr, symToYamlAux(conf, n.sym, marker, indent + 2, maxRecDepth)]) of nkIdent: if n.ident != nil: addf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)]) @@ -355,27 +356,27 @@ proc treeToYamlAux(n: PNode, marker: var IntSet, indent: int, addf(result, ",$N$1\"sons\": [", [istr]) for i in countup(0, sonsLen(n) - 1): if i > 0: add(result, ",") - addf(result, "$N$1$2", [rspaces(indent + 4), treeToYamlAux(n.sons[i], + addf(result, "$N$1$2", [rspaces(indent + 4), treeToYamlAux(conf, n.sons[i], marker, indent + 4, maxRecDepth - 1)]) addf(result, "$N$1]", [istr]) addf(result, ",$N$1\"typ\": $2", - [istr, typeToYamlAux(n.typ, marker, indent + 2, maxRecDepth)]) + [istr, typeToYamlAux(conf, n.typ, marker, indent + 2, maxRecDepth)]) addf(result, "$N$1}", [rspaces(indent)]) -proc treeToYaml(n: PNode, indent: int = 0, maxRecDepth: int = - 1): Rope = +proc treeToYaml(conf: ConfigRef; n: PNode, indent: int = 0, maxRecDepth: int = - 1): Rope = var marker = initIntSet() - result = treeToYamlAux(n, marker, indent, maxRecDepth) + result = treeToYamlAux(conf, n, marker, indent, maxRecDepth) -proc typeToYaml(n: PType, indent: int = 0, maxRecDepth: int = - 1): Rope = +proc typeToYaml(conf: ConfigRef; n: PType, indent: int = 0, maxRecDepth: int = - 1): Rope = var marker = initIntSet() - result = typeToYamlAux(n, marker, indent, maxRecDepth) + result = typeToYamlAux(conf, n, marker, indent, maxRecDepth) -proc symToYaml(n: PSym, indent: int = 0, maxRecDepth: int = - 1): Rope = +proc symToYaml(conf: ConfigRef; n: PSym, indent: int = 0, maxRecDepth: int = - 1): Rope = var marker = initIntSet() - result = symToYamlAux(n, marker, indent, maxRecDepth) + result = symToYamlAux(conf, n, marker, indent, maxRecDepth) -proc debugTree*(n: PNode, indent: int, maxRecDepth: int; renderType=false): Rope -proc debugType(n: PType, maxRecDepth=100): Rope = +proc debugTree*(conf: ConfigRef; n: PNode, indent: int, maxRecDepth: int; renderType=false): Rope +proc debugType(conf: ConfigRef; n: PType, maxRecDepth=100): Rope = if n == nil: result = rope("null") else: @@ -385,7 +386,7 @@ proc debugType(n: PType, maxRecDepth=100): Rope = add(result, n.sym.name.s) if n.kind in IntegralTypes and n.n != nil: add(result, ", node: ") - add(result, debugTree(n.n, 2, maxRecDepth-1, renderType=true)) + add(result, debugTree(conf, n.n, 2, maxRecDepth-1, renderType=true)) if (n.kind != tyString) and (sonsLen(n) > 0) and maxRecDepth != 0: add(result, "(") for i in countup(0, sonsLen(n) - 1): @@ -393,13 +394,13 @@ proc debugType(n: PType, maxRecDepth=100): Rope = if n.sons[i] == nil: add(result, "null") else: - add(result, debugType(n.sons[i], maxRecDepth-1)) + add(result, debugType(conf, n.sons[i], maxRecDepth-1)) if n.kind == tyObject and n.n != nil: add(result, ", node: ") - add(result, debugTree(n.n, 2, maxRecDepth-1, renderType=true)) + add(result, debugTree(conf, n.n, 2, maxRecDepth-1, renderType=true)) add(result, ")") -proc debugTree(n: PNode, indent: int, maxRecDepth: int; +proc debugTree(conf: ConfigRef; n: PNode, indent: int, maxRecDepth: int; renderType=false): Rope = if n == nil: result = rope("null") @@ -409,7 +410,7 @@ proc debugTree(n: PNode, indent: int, maxRecDepth: int; [istr, makeYamlString($n.kind)] when defined(useNodeIds): addf(result, ",$N$1\"id\": $2", [istr, rope(n.id)]) - addf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)]) + addf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(conf, n.info)]) if maxRecDepth != 0: addf(result, ",$N$1\"flags\": $2", [istr, rope($n.flags)]) case n.kind @@ -429,7 +430,7 @@ proc debugTree(n: PNode, indent: int, maxRecDepth: int; # [istr, symToYaml(n.sym, indent, maxRecDepth), # rope(n.sym.id)]) if renderType and n.sym.typ != nil: - addf(result, ",$N$1\"typ\": $2", [istr, debugType(n.sym.typ, 2)]) + addf(result, ",$N$1\"typ\": $2", [istr, debugType(conf, n.sym.typ, 2)]) of nkIdent: if n.ident != nil: addf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)]) @@ -440,27 +441,28 @@ proc debugTree(n: PNode, indent: int, maxRecDepth: int; addf(result, ",$N$1\"sons\": [", [istr]) for i in countup(0, sonsLen(n) - 1): if i > 0: add(result, ",") - addf(result, "$N$1$2", [rspaces(indent + 4), debugTree(n.sons[i], + addf(result, "$N$1$2", [rspaces(indent + 4), debugTree(conf, n.sons[i], indent + 4, maxRecDepth - 1, renderType)]) addf(result, "$N$1]", [istr]) addf(result, "$N$1}", [rspaces(indent)]) -proc debug(n: PSym) = - if n == nil: - echo("null") - elif n.kind == skUnknown: - echo("skUnknown") - else: - #writeLine(stdout, $symToYaml(n, 0, 1)) - echo("$1_$2: $3, $4, $5, $6" % [ - n.name.s, $n.id, $flagsToStr(n.flags), $flagsToStr(n.loc.flags), - $lineInfoToStr(n.info), $n.kind]) +when declared(echo): + proc debug(conf: ConfigRef; n: PSym) = + if n == nil: + echo("null") + elif n.kind == skUnknown: + echo("skUnknown") + else: + #writeLine(stdout, $symToYaml(n, 0, 1)) + echo("$1_$2: $3, $4, $5, $6" % [ + n.name.s, $n.id, $flagsToStr(n.flags), $flagsToStr(n.loc.flags), + $lineInfoToStr(conf, n.info), $n.kind]) -proc debug(n: PType) = - echo($debugType(n)) + proc debug(conf: ConfigRef; n: PType) = + echo($debugType(conf, n)) -proc debug(n: PNode) = - echo($debugTree(n, 0, 100)) + proc debug(conf: ConfigRef; n: PNode) = + echo($debugTree(conf, n, 0, 100)) proc nextTry(h, maxHash: Hash): Hash = result = ((5 * h) + 1) and maxHash diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index 7d355db5f..43a9f570a 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -24,7 +24,7 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc, # getUniqueType() is too expensive here: var typ = skipTypes(ri.sons[0].typ, abstractInst) if typ.sons[0] != nil: - if isInvalidReturnType(typ.sons[0]): + if isInvalidReturnType(p.config, typ.sons[0]): if params != nil: pl.add(~", ") # beware of 'result = p(result)'. We may need to allocate a temporary: if d.k in {locTemp, locNone} or not leftAppearsOnRightSide(le, ri): @@ -33,13 +33,13 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc, elif d.k notin {locTemp} and not hasNoInit(ri): # reset before pass as 'result' var: discard "resetLoc(p, d)" - add(pl, addrLoc(d)) + add(pl, addrLoc(p.config, d)) add(pl, ~");$n") line(p, cpsStmts, pl) else: var tmp: TLoc getTemp(p, typ.sons[0], tmp, needsInit=true) - add(pl, addrLoc(tmp)) + add(pl, addrLoc(p.config, tmp)) add(pl, ~");$n") line(p, cpsStmts, pl) genAssignment(p, d, tmp, {}) # no need for deep copying @@ -102,7 +102,7 @@ proc openArrayLoc(p: BProc, n: PNode): Rope = let ty = skipTypes(a.t, abstractVar+{tyPtr}) case ty.kind of tyArray: - let first = firstOrd(ty) + let first = firstOrd(p.config, ty) if first == 0: result = "($1)+($2), ($3)-($2)+1" % [rdLoc(a), rdLoc(b), rdLoc(c)] else: @@ -129,13 +129,13 @@ proc openArrayLoc(p: BProc, n: PNode): Rope = else: result = "$1->data, ($1 ? $1->$2 : 0)" % [a.rdLoc, lenField(p)] of tyArray: - result = "$1, $2" % [rdLoc(a), rope(lengthOrd(a.t))] + result = "$1, $2" % [rdLoc(a), rope(lengthOrd(p.config, a.t))] of tyPtr, tyRef: case lastSon(a.t).kind of tyString, tySequence: result = "(*$1)->data, (*$1 ? (*$1)->$2 : 0)" % [a.rdLoc, lenField(p)] of tyArray: - result = "$1, $2" % [rdLoc(a), rope(lengthOrd(lastSon(a.t)))] + result = "$1, $2" % [rdLoc(a), rope(lengthOrd(p.config, lastSon(a.t)))] else: internalError(p.config, "openArrayLoc: " & typeToString(a.t)) else: internalError(p.config, "openArrayLoc: " & typeToString(a.t)) @@ -152,9 +152,9 @@ proc genArg(p: BProc, n: PNode, param: PSym; call: PNode): Rope = elif skipTypes(param.typ, abstractVar).kind in {tyOpenArray, tyVarargs}: var n = if n.kind != nkHiddenAddr: n else: n.sons[0] result = openArrayLoc(p, n) - elif ccgIntroducedPtr(param): + elif ccgIntroducedPtr(p.config, param): initLocExpr(p, n, a) - result = addrLoc(a) + result = addrLoc(p.config, a) elif p.module.compileToCpp and param.typ.kind == tyVar and n.kind == nkHiddenAddr: initLocExprSingleUse(p, n.sons[0], a) @@ -164,7 +164,7 @@ proc genArg(p: BProc, n: PNode, param: PSym; call: PNode): Rope = if callee.kind == nkSym and {sfImportC, sfInfixCall, sfCompilerProc} * callee.sym.flags == {sfImportC} and {lfHeader, lfNoDecl} * callee.sym.loc.flags != {}: - result = addrLoc(a) + result = addrLoc(p.config, a) else: result = rdLoc(a) else: @@ -231,7 +231,7 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) = let rawProc = getRawProcType(p, typ) let callPattern = if tfIterator in typ.flags: PatIter else: PatProc if typ.sons[0] != nil: - if isInvalidReturnType(typ.sons[0]): + if isInvalidReturnType(p.config, typ.sons[0]): if sonsLen(ri) > 1: add(pl, ~", ") # beware of 'result = p(result)'. We may need to allocate a temporary: if d.k in {locTemp, locNone} or not leftAppearsOnRightSide(le, ri): @@ -241,12 +241,12 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) = elif d.k notin {locTemp} and not hasNoInit(ri): # reset before pass as 'result' var: discard "resetLoc(p, d)" - add(pl, addrLoc(d)) + add(pl, addrLoc(p.config, d)) genCallPattern() else: var tmp: TLoc getTemp(p, typ.sons[0], tmp, needsInit=true) - add(pl, addrLoc(tmp)) + add(pl, addrLoc(p.config, tmp)) genCallPattern() genAssignment(p, d, tmp, {}) # no need for deep copying else: @@ -509,20 +509,20 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) = add(pl, ~": ") add(pl, genArg(p, ri.sons[i], param, ri)) if typ.sons[0] != nil: - if isInvalidReturnType(typ.sons[0]): + if isInvalidReturnType(p.config, typ.sons[0]): if sonsLen(ri) > 1: add(pl, ~" ") # beware of 'result = p(result)'. We always allocate a temporary: if d.k in {locTemp, locNone}: # We already got a temp. Great, special case it: if d.k == locNone: getTemp(p, typ.sons[0], d, needsInit=true) add(pl, ~"Result: ") - add(pl, addrLoc(d)) + add(pl, addrLoc(p.config, d)) add(pl, ~"];$n") line(p, cpsStmts, pl) else: var tmp: TLoc getTemp(p, typ.sons[0], tmp, needsInit=true) - add(pl, addrLoc(tmp)) + add(pl, addrLoc(p.config, tmp)) add(pl, ~"];$n") line(p, cpsStmts, pl) genAssignment(p, d, tmp, {}) # no need for deep copying diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 335aa2f84..f26526b05 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -114,8 +114,8 @@ proc genRawSetData(cs: TBitSet, size: int): Rope = proc genSetNode(p: BProc, n: PNode): Rope = var cs: TBitSet - var size = int(getSize(n.typ)) - toBitSet(n, cs) + var size = int(getSize(p.config, n.typ)) + toBitSet(p.config, n, cs) if size > 8: let id = nodeTableTestOrSet(p.module.dataCache, n, p.module.labels) result = p.module.tmpBase & rope(id) @@ -185,13 +185,13 @@ proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = # lineF(p, cpsStmts, '$1 = $2;$n', [rdLoc(dest), rdLoc(src)]) if canFormAcycle(dest.t): linefmt(p, cpsStmts, "#asgnRef((void**) $1, $2);$n", - addrLoc(dest), rdLoc(src)) + addrLoc(p.config, dest), rdLoc(src)) else: linefmt(p, cpsStmts, "#asgnRefNoCycle((void**) $1, $2);$n", - addrLoc(dest), rdLoc(src)) + addrLoc(p.config, dest), rdLoc(src)) else: linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n", - addrLoc(dest), rdLoc(src)) + addrLoc(p.config, dest), rdLoc(src)) proc asgnComplexity(n: PNode): int = if n != nil: @@ -260,13 +260,13 @@ proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = useStringh(p.module) linefmt(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n", - addrLoc(dest), addrLoc(src), rdLoc(dest)) + addrLoc(p.config, dest), addrLoc(p.config, src), rdLoc(dest)) else: linefmt(p, cpsStmts, "#genericShallowAssign((void*)$1, (void*)$2, $3);$n", - addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t, dest.lode.info)) + addrLoc(p.config, dest), addrLoc(p.config, src), genTypeInfo(p.module, dest.t, dest.lode.info)) else: linefmt(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);$n", - addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t, dest.lode.info)) + addrLoc(p.config, dest), addrLoc(p.config, src), genTypeInfo(p.module, dest.t, dest.lode.info)) proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = # This function replaces all other methods for generating @@ -284,7 +284,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = genRefAssign(p, dest, src, flags) else: linefmt(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n", - addrLoc(dest), rdLoc(src), + addrLoc(p.config, dest), rdLoc(src), genTypeInfo(p.module, dest.t, dest.lode.info)) of tyString: if (needToCopy notin flags and src.storage != OnStatic) or canMove(src.lode): @@ -301,7 +301,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = linefmt(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", tmp.rdLoc) else: linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, #copyString($2));$n", - addrLoc(dest), rdLoc(src)) + addrLoc(p.config, dest), rdLoc(src)) of tyProc: if needsComplexAssignment(dest.t): # optimize closure assignment: @@ -346,7 +346,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = if needsComplexAssignment(dest.t): linefmt(p, cpsStmts, # XXX: is this correct for arrays? "#genericAssignOpenArray((void*)$1, (void*)$2, $1Len_0, $3);$n", - addrLoc(dest), addrLoc(src), + addrLoc(p.config, dest), addrLoc(p.config, src), genTypeInfo(p.module, dest.t, dest.lode.info)) else: useStringh(p.module) @@ -354,10 +354,10 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1[0])*$1Len_0);$n", rdLoc(dest), rdLoc(src)) of tySet: - if mapType(ty) == ctArray: + if mapType(p.config, ty) == ctArray: useStringh(p.module) linefmt(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, $3);$n", - rdLoc(dest), rdLoc(src), rope(getSize(dest.t))) + rdLoc(dest), rdLoc(src), rope(getSize(p.config, dest.t))) else: linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) of tyPtr, tyPointer, tyChar, tyBool, tyEnum, tyCString, @@ -369,8 +369,8 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = #writeStackTrace() #echo p.currLineInfo, " requesting" linefmt(p, cpsStmts, "#memTrackerWrite((void*)$1, $2, $3, $4);$n", - addrLoc(dest), rope getSize(dest.t), - makeCString(p.currLineInfo.toFullPath), + addrLoc(p.config, dest), rope getSize(p.config, dest.t), + makeCString(toFullPath(p.config, p.currLineInfo)), rope p.currLineInfo.safeLineNm) proc genDeepCopy(p: BProc; dest, src: TLoc) = @@ -379,31 +379,31 @@ proc genDeepCopy(p: BProc; dest, src: TLoc) = var tmp: TLoc getTemp(p, a.t, tmp) genAssignment(p, tmp, a, {}) - addrLoc(tmp) + addrLoc(p.config, tmp) else: - addrLoc(a) + addrLoc(p.config, a) var ty = skipTypes(dest.t, abstractVarRange) case ty.kind of tyPtr, tyRef, tyProc, tyTuple, tyObject, tyArray: # XXX optimize this linefmt(p, cpsStmts, "#genericDeepCopy((void*)$1, (void*)$2, $3);$n", - addrLoc(dest), addrLocOrTemp(src), + addrLoc(p.config, dest), addrLocOrTemp(src), genTypeInfo(p.module, dest.t, dest.lode.info)) of tySequence, tyString: linefmt(p, cpsStmts, "#genericSeqDeepCopy($1, $2, $3);$n", - addrLoc(dest), rdLoc(src), + addrLoc(p.config, dest), rdLoc(src), genTypeInfo(p.module, dest.t, dest.lode.info)) of tyOpenArray, tyVarargs: linefmt(p, cpsStmts, "#genericDeepCopyOpenArray((void*)$1, (void*)$2, $1Len_0, $3);$n", - addrLoc(dest), addrLocOrTemp(src), + addrLoc(p.config, dest), addrLocOrTemp(src), genTypeInfo(p.module, dest.t, dest.lode.info)) of tySet: - if mapType(ty) == ctArray: + if mapType(p.config, ty) == ctArray: useStringh(p.module) linefmt(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, $3);$n", - rdLoc(dest), rdLoc(src), rope(getSize(dest.t))) + rdLoc(dest), rdLoc(src), rope(getSize(p.config, dest.t))) else: linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) of tyPointer, tyChar, tyBool, tyEnum, tyCString, @@ -489,15 +489,15 @@ proc unaryExprChar(p: BProc, e: PNode, d: var TLoc, frmt: string) = proc binaryArithOverflowRaw(p: BProc, t: PType, a, b: TLoc; frmt: string): Rope = - var size = getSize(t) - let storage = if size < platform.intSize: rope("NI") + var size = getSize(p.config, t) + let storage = if size < p.config.target.intSize: rope("NI") else: getTypeDesc(p.module, t) result = getTempName(p.module) linefmt(p, cpsLocals, "$1 $2;$n", storage, result) lineCg(p, cpsStmts, frmt, result, rdCharLoc(a), rdCharLoc(b)) - if size < platform.intSize or t.kind in {tyRange, tyEnum}: + if size < p.config.target.intSize or t.kind in {tyRange, tyEnum}: linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n", - result, intLiteral(firstOrd(t)), intLiteral(lastOrd(t))) + result, intLiteral(firstOrd(p.config, t)), intLiteral(lastOrd(p.config, t))) proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) = const @@ -545,8 +545,8 @@ proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) = t = skipTypes(e.typ, abstractRange) if optOverflowCheck in p.options: linefmt(p, cpsStmts, "if ($1 == $2) #raiseOverflow();$n", - rdLoc(a), intLiteral(firstOrd(t))) - putIntoDest(p, d, e, opr[m] % [rdLoc(a), rope(getSize(t) * 8)]) + rdLoc(a), intLiteral(firstOrd(p.config, t))) + putIntoDest(p, d, e, opr[m] % [rdLoc(a), rope(getSize(p.config, t) * 8)]) proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) = const @@ -602,8 +602,8 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) = initLocExpr(p, e.sons[1], a) initLocExpr(p, e.sons[2], b) # BUGFIX: cannot use result-type here, as it may be a boolean - s = max(getSize(a.t), getSize(b.t)) * 8 - k = getSize(a.t) * 8 + s = max(getSize(p.config, a.t), getSize(p.config, b.t)) * 8 + k = getSize(p.config, a.t) * 8 putIntoDest(p, d, e, binArithTab[op] % [rdLoc(a), rdLoc(b), rope(s), getSimpleTypeDesc(p.module, e.typ), rope(k)]) @@ -656,7 +656,7 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) = initLocExpr(p, e.sons[1], a) t = skipTypes(e.typ, abstractRange) putIntoDest(p, d, e, - unArithTab[op] % [rdLoc(a), rope(getSize(t) * 8), + unArithTab[op] % [rdLoc(a), rope(getSize(p.config, t) * 8), getSimpleTypeDesc(p.module, e.typ)]) proc isCppRef(p: BProc; typ: PType): bool {.inline.} = @@ -665,7 +665,7 @@ proc isCppRef(p: BProc; typ: PType): bool {.inline.} = tfVarIsPtr notin skipTypes(typ, abstractInst).flags proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) = - let mt = mapType(e.sons[0].typ) + let mt = mapType(p.config, e.sons[0].typ) if mt in {ctArray, ctPtrToArray} and not enforceDeref: # XXX the amount of hacks for C's arrays is incredible, maybe we should # simply wrap them in a struct? --> Losing auto vectorization then? @@ -724,12 +724,12 @@ proc genAddr(p: BProc, e: PNode, d: var TLoc) = initLocExpr(p, e.sons[0], a) putIntoDest(p, d, e, "&" & a.r, a.storage) #Message(e.info, warnUser, "HERE NEW &") - elif mapType(e.sons[0].typ) == ctArray or isCppRef(p, e.sons[0].typ): + elif mapType(p.config, e.sons[0].typ) == ctArray or isCppRef(p, e.sons[0].typ): expr(p, e.sons[0], d) else: var a: TLoc initLocExpr(p, e.sons[0], a) - putIntoDest(p, d, e, addrLoc(a), a.storage) + putIntoDest(p, d, e, addrLoc(p.config, a), a.storage) template inheritLocation(d: var TLoc, a: TLoc) = if d.k == locNone: d.storage = a.storage @@ -844,21 +844,21 @@ proc genArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) = initLocExpr(p, x, a) initLocExpr(p, y, b) var ty = skipTypes(a.t, abstractVarRange + abstractPtrs + tyUserTypeClasses) - var first = intLiteral(firstOrd(ty)) + var first = intLiteral(firstOrd(p.config, ty)) # emit range check: if optBoundsCheck in p.options and tfUncheckedArray notin ty.flags: if not isConstExpr(y): # semantic pass has already checked for const index expressions - if firstOrd(ty) == 0: - if (firstOrd(b.t) < firstOrd(ty)) or (lastOrd(b.t) > lastOrd(ty)): + if firstOrd(p.config, ty) == 0: + if (firstOrd(p.config, b.t) < firstOrd(p.config, ty)) or (lastOrd(p.config, b.t) > lastOrd(p.config, ty)): linefmt(p, cpsStmts, "if ((NU)($1) > (NU)($2)) #raiseIndexError();$n", - rdCharLoc(b), intLiteral(lastOrd(ty))) + rdCharLoc(b), intLiteral(lastOrd(p.config, ty))) else: linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseIndexError();$n", - rdCharLoc(b), first, intLiteral(lastOrd(ty))) + rdCharLoc(b), first, intLiteral(lastOrd(p.config, ty))) else: let idx = getOrdValue(y) - if idx < firstOrd(ty) or idx > lastOrd(ty): + if idx < firstOrd(p.config, ty) or idx > lastOrd(p.config, ty): localError(p.config, x.info, "index out of bounds") d.inheritLocation(a) putIntoDest(p, d, n, @@ -880,10 +880,10 @@ proc genIndexCheck(p: BProc; arr, idx: TLoc) = linefmt(p, cpsStmts, "if ((NU)($1) >= (NU)($2Len_0)) #raiseIndexError();$n", rdLoc(idx), rdLoc(arr)) of tyArray: - let first = intLiteral(firstOrd(ty)) + let first = intLiteral(firstOrd(p.config, ty)) if tfUncheckedArray notin ty.flags: linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseIndexError();$n", - rdCharLoc(idx), first, intLiteral(lastOrd(ty))) + rdCharLoc(idx), first, intLiteral(lastOrd(p.config, ty))) of tySequence, tyString: linefmt(p, cpsStmts, "if (!$2 || (NU)($1) >= (NU)($2->$3)) #raiseIndexError();$n", @@ -978,7 +978,7 @@ proc genEcho(p: BProc, n: PNode) = # this unusal way of implementing it ensures that e.g. ``echo("hallo", 45)`` # is threadsafe. internalAssert p.config, n.kind == nkBracket - if platform.targetOS == osGenode: + if p.config.target.targetOS == osGenode: # bypass libc and print directly to the Genode LOG session var args: Rope = nil var a: TLoc @@ -1000,7 +1000,7 @@ proc genEcho(p: BProc, n: PNode) = when false: p.module.includeHeader("<stdio.h>") linefmt(p, cpsStmts, "printf($1$2);$n", - makeCString(repeat("%s", n.len) & tnl), args) + makeCString(repeat("%s", n.len) & "\L"), args) linefmt(p, cpsStmts, "fflush(stdout);$n") proc gcUsage(conf: ConfigRef; n: PNode) = @@ -1114,7 +1114,7 @@ proc genReset(p: BProc, n: PNode) = var a: TLoc initLocExpr(p, n.sons[1], a) linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n", - addrLoc(a), + addrLoc(p.config, a), genTypeInfo(p.module, skipTypes(a.t, {tyVar}), n.info)) proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) = @@ -1299,7 +1299,7 @@ proc genArrToSeq(p: BProc, n: PNode, d: var TLoc) = if d.k == locNone: getTemp(p, n.typ, d) # generate call to newSeq before adding the elements per hand: - let L = int(lengthOrd(n.sons[1].typ)) + let L = int(lengthOrd(p.config, n.sons[1].typ)) genNewSeqAux(p, d, intLiteral(L)) initLocExpr(p, n.sons[1], a) # bug #5007; do not produce excessive C source code: @@ -1413,7 +1413,7 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) = putIntoDest(p, d, e, ropecg(p.module, "#reprStr($1)", [rdLoc(a)]), a.storage) of tySet: putIntoDest(p, d, e, ropecg(p.module, "#reprSet($1, $2)", [ - addrLoc(a), genTypeInfo(p.module, t, e.info)]), a.storage) + addrLoc(p.config, a), genTypeInfo(p.module, t, e.info)]), a.storage) of tyOpenArray, tyVarargs: var b: TLoc case a.t.kind @@ -1424,7 +1424,7 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) = "$1->data, ($1 ? $1->$2 : 0)" % [rdLoc(a), lenField(p)], a.storage) of tyArray: putIntoDest(p, b, e, - "$1, $2" % [rdLoc(a), rope(lengthOrd(a.t))], a.storage) + "$1, $2" % [rdLoc(a), rope(lengthOrd(p.config, a.t))], a.storage) else: internalError(p.config, e.sons[0].info, "genRepr()") putIntoDest(p, d, e, ropecg(p.module, "#reprOpenArray($1, $2)", [rdLoc(b), @@ -1437,7 +1437,7 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) = localError(p.config, e.info, "'repr' doesn't support 'void' type") else: putIntoDest(p, d, e, ropecg(p.module, "#reprAny($1, $2)", - [addrLoc(a), genTypeInfo(p.module, t, e.info)]), + [addrLoc(p.config, a), genTypeInfo(p.module, t, e.info)]), a.storage) gcUsage(p.config, e) @@ -1491,8 +1491,8 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) = putIntoDest(p, d, e, tmp.r) of tyArray: # YYY: length(sideeffect) is optimized away incorrectly? - if op == mHigh: putIntoDest(p, d, e, rope(lastOrd(typ))) - else: putIntoDest(p, d, e, rope(lengthOrd(typ))) + if op == mHigh: putIntoDest(p, d, e, rope(lastOrd(p.config, typ))) + else: putIntoDest(p, d, e, rope(lengthOrd(p.config, typ))) else: internalError(p.config, e.info, "genArrayLen()") proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) = @@ -1530,19 +1530,19 @@ proc genSwap(p: BProc, e: PNode, d: var TLoc) = genAssignment(p, a, b, {}) genAssignment(p, b, tmp, {}) -proc rdSetElemLoc(a: TLoc, setType: PType): Rope = +proc rdSetElemLoc(conf: ConfigRef; a: TLoc, setType: PType): Rope = # read a location of an set element; it may need a subtraction operation # before the set operation result = rdCharLoc(a) assert(setType.kind == tySet) - if firstOrd(setType) != 0: - result = "($1- $2)" % [result, rope(firstOrd(setType))] + if firstOrd(conf, setType) != 0: + result = "($1- $2)" % [result, rope(firstOrd(conf, setType))] -proc fewCmps(s: PNode): bool = +proc fewCmps(conf: ConfigRef; s: PNode): bool = # this function estimates whether it is better to emit code # for constructing the set or generating a bunch of comparisons directly if s.kind != nkCurly: return false - if (getSize(s.typ) <= platform.intSize) and (nfAllConst in s.flags): + if (getSize(conf, s.typ) <= conf.target.intSize) and (nfAllConst in s.flags): result = false # it is better to emit the set generation code elif elemType(s.typ).kind in {tyInt, tyInt16..tyInt64}: result = true # better not emit the set if int is basetype! @@ -1550,10 +1550,10 @@ proc fewCmps(s: PNode): bool = result = sonsLen(s) <= 8 # 8 seems to be a good value proc binaryExprIn(p: BProc, e: PNode, a, b, d: var TLoc, frmt: string) = - putIntoDest(p, d, e, frmt % [rdLoc(a), rdSetElemLoc(b, a.t)]) + putIntoDest(p, d, e, frmt % [rdLoc(a), rdSetElemLoc(p.config, b, a.t)]) proc genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc) = - case int(getSize(skipTypes(e.sons[1].typ, abstractVar))) + case int(getSize(p.config, skipTypes(e.sons[1].typ, abstractVar))) of 1: binaryExprIn(p, e, a, b, d, "(($1 &(1U<<((NU)($2)&7U)))!=0)") of 2: binaryExprIn(p, e, a, b, d, "(($1 &(1U<<((NU)($2)&15U)))!=0)") of 4: binaryExprIn(p, e, a, b, d, "(($1 &(1U<<((NU)($2)&31U)))!=0)") @@ -1565,11 +1565,11 @@ proc binaryStmtInExcl(p: BProc, e: PNode, d: var TLoc, frmt: string) = assert(d.k == locNone) initLocExpr(p, e.sons[1], a) initLocExpr(p, e.sons[2], b) - lineF(p, cpsStmts, frmt, [rdLoc(a), rdSetElemLoc(b, a.t)]) + lineF(p, cpsStmts, frmt, [rdLoc(a), rdSetElemLoc(p.config, b, a.t)]) proc genInOp(p: BProc, e: PNode, d: var TLoc) = var a, b, x, y: TLoc - if (e.sons[1].kind == nkCurly) and fewCmps(e.sons[1]): + if (e.sons[1].kind == nkCurly) and fewCmps(p.config, e.sons[1]): # a set constructor but not a constant set: # do not emit the set, but generate a bunch of comparisons; and if we do # so, we skip the unnecessary range check: This is a semantical extension @@ -1613,7 +1613,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) = "&", "|", "& ~", "^"] var a, b, i: TLoc var setType = skipTypes(e.sons[1].typ, abstractVar) - var size = int(getSize(setType)) + var size = int(getSize(p.config, setType)) case size of 1, 2, 4, 8: case op @@ -1680,7 +1680,7 @@ proc genSomeCast(p: BProc, e: PNode, d: var TLoc) = let etyp = skipTypes(e.typ, abstractRange) if etyp.kind in ValueTypes and lfIndirect notin a.flags: putIntoDest(p, d, e, "(*($1*) ($2))" % - [getTypeDesc(p.module, e.typ), addrLoc(a)], a.storage) + [getTypeDesc(p.module, e.typ), addrLoc(p.config, a)], a.storage) elif etyp.kind == tyProc and etyp.callConv == ccClosure: putIntoDest(p, d, e, "(($1) ($2))" % [getClosureType(p.module, etyp, clHalfWithEnv), rdCharLoc(a)], a.storage) @@ -1917,7 +1917,7 @@ proc genSetConstr(p: BProc, e: PNode, d: var TLoc) = putIntoDest(p, d, e, genSetNode(p, e)) else: if d.k == locNone: getTemp(p, e.typ, d) - if getSize(e.typ) > 8: + if getSize(p.config, e.typ) > 8: # big set: useStringh(p.module) lineF(p, cpsStmts, "memset($1, 0, sizeof($2));$n", @@ -1929,14 +1929,14 @@ proc genSetConstr(p: BProc, e: PNode, d: var TLoc) = initLocExpr(p, it.sons[1], b) lineF(p, cpsStmts, "for ($1 = $3; $1 <= $4; $1++) $n" & "$2[(NU)($1)>>3] |=(1U<<((NU)($1)&7U));$n", [rdLoc(idx), rdLoc(d), - rdSetElemLoc(a, e.typ), rdSetElemLoc(b, e.typ)]) + rdSetElemLoc(p.config, a, e.typ), rdSetElemLoc(p.config, b, e.typ)]) else: initLocExpr(p, it, a) lineF(p, cpsStmts, "$1[(NU)($2)>>3] |=(1U<<((NU)($2)&7U));$n", - [rdLoc(d), rdSetElemLoc(a, e.typ)]) + [rdLoc(d), rdSetElemLoc(p.config, a, e.typ)]) else: # small set - var ts = "NU" & $(getSize(e.typ) * 8) + var ts = "NU" & $(getSize(p.config, e.typ) * 8) lineF(p, cpsStmts, "$1 = 0;$n", [rdLoc(d)]) for it in e.sons: if it.kind == nkRange: @@ -1945,13 +1945,13 @@ proc genSetConstr(p: BProc, e: PNode, d: var TLoc) = initLocExpr(p, it.sons[1], b) lineF(p, cpsStmts, "for ($1 = $3; $1 <= $4; $1++) $n" & "$2 |=((" & ts & ")(1)<<(($1)%(sizeof(" & ts & ")*8)));$n", [ - rdLoc(idx), rdLoc(d), rdSetElemLoc(a, e.typ), - rdSetElemLoc(b, e.typ)]) + rdLoc(idx), rdLoc(d), rdSetElemLoc(p.config, a, e.typ), + rdSetElemLoc(p.config, b, e.typ)]) else: initLocExpr(p, it, a) lineF(p, cpsStmts, "$1 |=((" & ts & ")(1)<<(($2)%(sizeof(" & ts & ")*8)));$n", - [rdLoc(d), rdSetElemLoc(a, e.typ)]) + [rdLoc(d), rdSetElemLoc(p.config, a, e.typ)]) proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) = var rec: TLoc @@ -2069,7 +2069,7 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) = "(($1) ($2))" % [getTypeDesc(p.module, n.typ), rdLoc(a)], a.storage) else: putIntoDest(p, d, n, "(*($1*) ($2))" % - [getTypeDesc(p.module, dest), addrLoc(a)], a.storage) + [getTypeDesc(p.module, dest), addrLoc(p.config, a)], a.storage) proc downConv(p: BProc, n: PNode, d: var TLoc) = if p.module.compileToCpp: @@ -2290,7 +2290,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = incl a.flags, lfSingleUse genCall(p, ex, a) if lfSingleUse notin a.flags: - line(p, cpsStmts, a.r & ";" & tnl) + line(p, cpsStmts, a.r & ";\L") else: initLocExpr(p, ex, a) of nkAsmStmt: genAsmStmt(p, n) @@ -2360,7 +2360,7 @@ proc getDefaultValue(p: BProc; typ: PType; info: TLineInfo): Rope = result.add "}" of tyArray: result = rope"{}" of tySet: - if mapType(t) == ctArray: result = rope"{}" + if mapType(p.config, t) == ctArray: result = rope"{}" else: result = rope"0" else: globalError(p.config, info, "cannot create null element for: " & $t.kind) @@ -2457,8 +2457,8 @@ proc genConstExpr(p: BProc, n: PNode): Rope = result = genConstExpr(p, n.sons[1]) of nkCurly: var cs: TBitSet - toBitSet(n, cs) - result = genRawSetData(cs, int(getSize(n.typ))) + toBitSet(p.config, n, cs) + result = genRawSetData(cs, int(getSize(p.config, n.typ))) of nkBracket, nkPar, nkTupleConstr, nkClosure: var t = skipTypes(n.typ, abstractInst) if t.kind == tySequence: diff --git a/compiler/ccgmerge.nim b/compiler/ccgmerge.nim index 4b4f9c0e6..664f89b73 100644 --- a/compiler/ccgmerge.nim +++ b/compiler/ccgmerge.nim @@ -47,34 +47,32 @@ const proc genSectionStart*(fs: TCFileSection; conf: ConfigRef): Rope = if compilationCachePresent(conf): - result = rope(tnl) - add(result, "/*\t") + result = nil + add(result, "\n/*\t") add(result, CFileSectionNames[fs]) - add(result, ":*/") - add(result, tnl) + add(result, ":*/\n") proc genSectionEnd*(fs: TCFileSection; conf: ConfigRef): Rope = if compilationCachePresent(conf): - result = rope(NimMergeEndMark & tnl) + result = rope(NimMergeEndMark & "\n") proc genSectionStart*(ps: TCProcSection; conf: ConfigRef): Rope = if compilationCachePresent(conf): - result = rope(tnl) - add(result, "/*\t") + result = rope(nil) + add(result, "\n/*\t") add(result, CProcSectionNames[ps]) - add(result, ":*/") - add(result, tnl) + add(result, ":*/\n") proc genSectionEnd*(ps: TCProcSection; conf: ConfigRef): Rope = if compilationCachePresent(conf): - result = rope(NimMergeEndMark & tnl) + result = rope(NimMergeEndMark & "\n") proc writeTypeCache(a: TypeCache, s: var string) = var i = 0 for id, value in pairs(a): if i == 10: i = 0 - s.add(tnl) + s.add('\L') else: s.add(' ') encodeStr($id, s) @@ -88,7 +86,7 @@ proc writeIntSet(a: IntSet, s: var string) = for x in items(a): if i == 10: i = 0 - s.add(tnl) + s.add('\L') else: s.add(' ') encodeVInt(x, s) @@ -97,8 +95,7 @@ proc writeIntSet(a: IntSet, s: var string) = proc genMergeInfo*(m: BModule): Rope = if not compilationCachePresent(m.config): return nil - var s = "/*\tNIM_merge_INFO:" - s.add(tnl) + var s = "/*\tNIM_merge_INFO:\n" s.add("typeCache:{") writeTypeCache(m.typeCache, s) s.add("declared:{") @@ -110,8 +107,7 @@ proc genMergeInfo*(m: BModule): Rope = encodeVInt(m.labels, s) s.add(" flags:") encodeVInt(cast[int](m.flags), s) - s.add(tnl) - s.add("*/") + s.add("\n*/") result = s.rope template `^`(pos: int): untyped = L.buf[pos] @@ -155,11 +151,11 @@ proc readVerbatimSection(L: var TBaseLexer): Rope = of CR: pos = nimlexbase.handleCR(L, pos) buf = L.buf - r.add(tnl) + r.add('\L') of LF: pos = nimlexbase.handleLF(L, pos) buf = L.buf - r.add(tnl) + r.add('\L') of '\0': doAssert(false, "ccgmerge: expected: " & NimMergeEndMark) break diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 1e0a3c818..dd0e80f0e 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -28,9 +28,9 @@ proc registerGcRoot(p: BProc, v: PSym) = appcg(p.module, p.module.initProc.procSec(cpsInit), "#nimRegisterGlobalMarker($1);$n", [prc]) -proc isAssignedImmediately(n: PNode): bool {.inline.} = +proc isAssignedImmediately(conf: ConfigRef; n: PNode): bool {.inline.} = if n.kind == nkEmpty: return false - if isInvalidReturnType(n.typ): + if isInvalidReturnType(conf, n.typ): # var v = f() # is transformed into: var v; f(addr v) # where 'f' **does not** initialize the result! @@ -65,7 +65,7 @@ proc genVarTuple(p: BProc, n: PNode) = registerGcRoot(p, v) else: assignLocalVar(p, vn) - initLocalVar(p, v, immediateAsgn=isAssignedImmediately(n[L-1])) + initLocalVar(p, v, immediateAsgn=isAssignedImmediately(p.config, n[L-1])) initLoc(field, locExpr, vn, tup.storage) if t.kind == tyTuple: field.r = "$1.Field$2" % [rdLoc(tup), rope(i)] @@ -168,7 +168,7 @@ proc genGotoState(p: BProc, n: PNode) = lineF(p, cpsStmts, "switch ($1) {$n", [rdLoc(a)]) p.beforeRetNeeded = true lineF(p, cpsStmts, "case -1: goto BeforeRet_;$n", []) - var statesCounter = lastOrd(n.sons[0].typ) + var statesCounter = lastOrd(p.config, n.sons[0].typ) if n.len >= 2 and n[1].kind == nkIntLit: statesCounter = n[1].intVal let prefix = if n.len == 3 and n[2].kind == nkStrLit: n[2].strVal.rope @@ -227,7 +227,7 @@ proc genSingleVar(p: BProc, a: PNode) = registerGcRoot(p, v) else: let value = a.sons[2] - let imm = isAssignedImmediately(value) + let imm = isAssignedImmediately(p.config, value) if imm and p.module.compileToCpp and p.splitDecls == 0 and not containsHiddenPointer(v.typ): # C++ really doesn't like things like 'Foo f; f = x' as that invokes a @@ -401,12 +401,12 @@ proc genComputedGoto(p: BProc; n: PNode) = localError(p.config, it.info, "case statement must be exhaustive for computed goto"); return casePos = i - let aSize = lengthOrd(it.sons[0].typ) + let aSize = lengthOrd(p.config, it.sons[0].typ) if aSize > 10_000: localError(p.config, it.info, "case statement has too many cases for computed goto"); return arraySize = aSize.int - if firstOrd(it.sons[0].typ) != 0: + if firstOrd(p.config, it.sons[0].typ) != 0: localError(p.config, it.info, "case statement has to start at 0 for computed goto"); return if casePos < 0: @@ -477,7 +477,7 @@ proc genWhileStmt(p: BProc, t: PNode) = lineF(p, cpsStmts, "if (!$1) goto $2;$n", [rdLoc(a), label]) var loopBody = t.sons[1] if loopBody.stmtsContainPragma(wComputedGoto) and - hasComputedGoto in CC[cCompiler].props: + hasComputedGoto in CC[p.config.cCompiler].props: # for closure support weird loop bodies are generated: if loopBody.len == 2 and loopBody.sons[0].kind == nkEmpty: loopBody = loopBody.sons[1] @@ -650,7 +650,7 @@ proc genCaseStringBranch(p: BProc, b: PNode, e: TLoc, labl: TLabel, assert(b.sons[i].kind != nkRange) initLocExpr(p, b.sons[i], x) assert(b.sons[i].kind in {nkStrLit..nkTripleStrLit}) - var j = int(hashString(b.sons[i].strVal) and high(branches)) + var j = int(hashString(p.config, b.sons[i].strVal) and high(branches)) appcg(p.module, branches[j], "if (#eqStrings($1, $2)) goto $3;$n", [rdLoc(e), rdLoc(x), labl]) @@ -703,7 +703,7 @@ proc ifSwitchSplitPoint(p: BProc, n: PNode): int = var stmtBlock = lastSon(branch) if stmtBlock.stmtsContainPragma(wLinearScanEnd): result = i - elif hasSwitchRange notin CC[cCompiler].props: + elif hasSwitchRange notin CC[p.config.cCompiler].props: if branch.kind == nkOfBranch and branchHasTooBigRange(branch): result = i @@ -711,7 +711,7 @@ proc genCaseRange(p: BProc, branch: PNode) = var length = branch.len for j in 0 .. length-2: if branch[j].kind == nkRange: - if hasSwitchRange in CC[cCompiler].props: + if hasSwitchRange in CC[p.config.cCompiler].props: lineF(p, cpsStmts, "case $1 ... $2:$n", [ genLiteral(p, branch[j][0]), genLiteral(p, branch[j][1])]) @@ -751,7 +751,7 @@ proc genOrdinalCase(p: BProc, n: PNode, d: var TLoc) = hasDefault = true exprBlock(p, branch.lastSon, d) lineF(p, cpsStmts, "break;$n", []) - if (hasAssume in CC[cCompiler].props) and not hasDefault: + if (hasAssume in CC[p.config.cCompiler].props) and not hasDefault: lineF(p, cpsStmts, "default: __assume(0);$n", []) lineF(p, cpsStmts, "}$n", []) if lend != nil: fixLabel(p, lend) @@ -967,21 +967,21 @@ proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): Rope = initLocExpr(p, it, a) res.add($a.rdLoc) - if isAsmStmt and hasGnuAsm in CC[cCompiler].props: + if isAsmStmt and hasGnuAsm in CC[p.config.cCompiler].props: for x in splitLines(res): var j = 0 while x[j] in {' ', '\t'}: inc(j) if x[j] in {'"', ':'}: # don't modify the line if already in quotes or # some clobber register list: - add(result, x); add(result, tnl) + add(result, x); add(result, "\L") elif x[j] != '\0': # ignore empty lines add(result, "\"") add(result, x) add(result, "\\n\"\n") else: - res.add(tnl) + res.add("\L") result = res.rope proc genAsmStmt(p: BProc, t: PNode) = @@ -993,9 +993,9 @@ proc genAsmStmt(p: BProc, t: PNode) = # work: if p.prc == nil: # top level asm statement? - addf(p.module.s[cfsProcHeaders], CC[cCompiler].asmStmtFrmt, [s]) + addf(p.module.s[cfsProcHeaders], CC[p.config.cCompiler].asmStmtFrmt, [s]) else: - lineF(p, cpsStmts, CC[cCompiler].asmStmtFrmt, [s]) + lineF(p, cpsStmts, CC[p.config.cCompiler].asmStmtFrmt, [s]) proc determineSection(n: PNode): TCFileSection = result = cfsProcHeaders @@ -1028,7 +1028,7 @@ proc genBreakPoint(p: BProc, t: PNode) = genLineDir(p, t) # BUGFIX appcg(p.module, p.module.g.breakpoints, "#dbgRegisterBreakpoint($1, (NCSTRING)$2, (NCSTRING)$3);$n", [ - rope(toLinenumber(t.info)), makeCString(toFilename(t.info)), + rope(toLinenumber(t.info)), makeCString(toFilename(p.config, t.info)), makeCString(name)]) proc genWatchpoint(p: BProc, n: PNode) = @@ -1037,7 +1037,7 @@ proc genWatchpoint(p: BProc, n: PNode) = initLocExpr(p, n.sons[1], a) let typ = skipTypes(n.sons[1].typ, abstractVarRange) lineCg(p, cpsStmts, "#dbgRegisterWatchpoint($1, (NCSTRING)$2, $3);$n", - [a.addrLoc, makeCString(renderTree(n.sons[1])), + [addrLoc(p.config, a), makeCString(renderTree(n.sons[1])), genTypeInfo(p.module, typ, n.info)]) proc genPragma(p: BProc, n: PNode) = @@ -1068,7 +1068,7 @@ proc genDiscriminantCheck(p: BProc, a, tmp: TLoc, objtype: PType, var t = skipTypes(objtype, abstractVar) assert t.kind == tyObject discard genTypeInfo(p.module, t, a.lode.info) - var L = lengthOrd(field.typ) + var L = lengthOrd(p.config, field.typ) if not containsOrIncl(p.module.declaredThings, field.id): appcg(p.module, cfsVars, "extern $1", discriminatorTableDecl(p.module, t, field)) diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim index c265064a1..4514ce7dc 100644 --- a/compiler/ccgtrav.nim +++ b/compiler/ccgtrav.nim @@ -70,7 +70,7 @@ proc genTraverseProc(c: TTraversalClosure, accessor: Rope, typ: PType) = tySink: genTraverseProc(c, accessor, lastSon(typ)) of tyArray: - let arraySize = lengthOrd(typ.sons[0]) + let arraySize = lengthOrd(c.p.config, typ.sons[0]) var i: TLoc getTemp(p, getSysType(c.p.module.g.graph, unknownLineInfo(), tyInt), i) let oldCode = p.s(cpsStmts) @@ -122,7 +122,6 @@ proc genTraverseProc(m: BModule, origTyp: PType; sig: SigHash): Rope = var p = newProc(nil, m) result = "Marker_" & getTypeName(m, origTyp, sig) var typ = origTyp.skipTypes(abstractInst) - if typ.kind == tyOpt: typ = optLowering(typ) let header = "static N_NIMCALL(void, $1)(void* p, NI op)" % [result] diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 7b44cddad..d0433f9ae 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -50,7 +50,7 @@ proc mangleName(m: BModule; s: PSym): Rope = result = s.name.s.mangle.rope add(result, idOrSig(s, m.module.name.s, m.sigConflicts)) s.loc.r = result - writeMangledName(m.ndi, s) + writeMangledName(m.ndi, s, m.config) proc mangleParamName(m: BModule; s: PSym): Rope = ## we cannot use 'sigConflicts' here since we have a BModule, not a BProc. @@ -63,7 +63,7 @@ proc mangleParamName(m: BModule; s: PSym): Rope = res.add "_0" result = res.rope s.loc.r = result - writeMangledName(m.ndi, s) + writeMangledName(m.ndi, s, m.config) proc mangleLocalName(p: BProc; s: PSym): Rope = assert s.kind in skLocalVars+{skTemp} @@ -81,7 +81,7 @@ proc mangleLocalName(p: BProc; s: PSym): Rope = result.add "_" & rope(counter+1) p.sigConflicts.inc(key) s.loc.r = result - if s.kind != skTemp: writeMangledName(p.module.ndi, s) + if s.kind != skTemp: writeMangledName(p.module.ndi, s, p.config) proc scopeMangledParam(p: BProc; param: PSym) = ## parameter generation only takes BModule, not a BProc, so we have to @@ -124,40 +124,40 @@ proc getTypeName(m: BModule; typ: PType; sig: SigHash): Rope = result = typ.loc.r if result == nil: internalError(m.config, "getTypeName: " & $typ.kind) -proc mapSetType(typ: PType): TCTypeKind = - case int(getSize(typ)) +proc mapSetType(conf: ConfigRef; typ: PType): TCTypeKind = + case int(getSize(conf, typ)) of 1: result = ctInt8 of 2: result = ctInt16 of 4: result = ctInt32 of 8: result = ctInt64 else: result = ctArray -proc mapType(typ: PType): TCTypeKind = +proc mapType(conf: ConfigRef; typ: PType): TCTypeKind = ## Maps a Nim type to a C type case typ.kind of tyNone, tyStmt: result = ctVoid of tyBool: result = ctBool of tyChar: result = ctChar - of tySet: result = mapSetType(typ) + of tySet: result = mapSetType(conf, typ) of tyOpenArray, tyArray, tyVarargs: result = ctArray of tyObject, tyTuple: result = ctStruct of tyUserTypeClasses: doAssert typ.isResolvedUserTypeClass - return mapType(typ.lastSon) + return mapType(conf, typ.lastSon) of tyGenericBody, tyGenericInst, tyGenericParam, tyDistinct, tyOrdinal, tyTypeDesc, tyAlias, tySink, tyInferred: - result = mapType(lastSon(typ)) + result = mapType(conf, lastSon(typ)) of tyEnum: - if firstOrd(typ) < 0: + if firstOrd(conf, typ) < 0: result = ctInt32 else: - case int(getSize(typ)) + case int(getSize(conf, typ)) of 1: result = ctUInt8 of 2: result = ctUInt16 of 4: result = ctInt32 of 8: result = ctInt64 else: result = ctInt32 - of tyRange: result = mapType(typ.sons[0]) + of tyRange: result = mapType(conf, typ.sons[0]) of tyPtr, tyVar, tyLent, tyRef, tyOptAsRef: var base = skipTypes(typ.lastSon, typedescInst) case base.kind @@ -169,27 +169,20 @@ proc mapType(typ: PType): TCTypeKind = else: result = ctPtr of tyPointer: result = ctPtr of tySequence: result = ctNimSeq - of tyOpt: - case optKind(typ) - of oBool: result = ctStruct - of oNil, oPtr: result = ctPtr - of oEnum: - # The 'nil' value is always negative, so we always use a signed integer - result = if getSize(typ.sons[0]) == 8: ctInt64 else: ctInt32 of tyProc: result = if typ.callConv != ccClosure: ctProc else: ctStruct of tyString: result = ctNimStr of tyCString: result = ctCString of tyInt..tyUInt64: result = TCTypeKind(ord(typ.kind) - ord(tyInt) + ord(ctInt)) of tyStatic: - if typ.n != nil: result = mapType(lastSon typ) + if typ.n != nil: result = mapType(conf, lastSon typ) else: doAssert(false, "mapType") else: doAssert(false, "mapType") -proc mapReturnType(typ: PType): TCTypeKind = +proc mapReturnType(conf: ConfigRef; typ: PType): TCTypeKind = #if skipTypes(typ, typedescInst).kind == tyArray: result = ctPtr #else: - result = mapType(typ) + result = mapType(conf, typ) proc isImportedType(t: PType): bool = result = t.sym != nil and sfImportc in t.sym.flags @@ -207,14 +200,14 @@ proc isObjLackingTypeField(typ: PType): bool {.inline.} = result = (typ.kind == tyObject) and ((tfFinal in typ.flags) and (typ.sons[0] == nil) or isPureObject(typ)) -proc isInvalidReturnType(rettype: PType): bool = +proc isInvalidReturnType(conf: ConfigRef; rettype: PType): bool = # Arrays and sets cannot be returned by a C procedure, because C is # such a poor programming language. # We exclude records with refs too. This enhances efficiency and # is necessary for proper code generation of assignments. if rettype == nil: result = true else: - case mapType(rettype) + case mapType(conf, rettype) of ctArray: result = not (skipTypes(rettype, typedescInst).kind in {tyVar, tyLent, tyRef, tyPtr}) @@ -240,9 +233,9 @@ proc cacheGetType(tab: TypeCache; sig: SigHash): Rope = proc addAbiCheck(m: BModule, t: PType, name: Rope) = if isDefined(m.config, "checkabi"): - addf(m.s[cfsTypeInfo], "NIM_CHECK_SIZE($1, $2);$n", [name, rope(getSize(t))]) + addf(m.s[cfsTypeInfo], "NIM_CHECK_SIZE($1, $2);$n", [name, rope(getSize(m.config, t))]) -proc ccgIntroducedPtr(s: PSym): bool = +proc ccgIntroducedPtr(conf: ConfigRef; s: PSym): bool = var pt = skipTypes(s.typ, typedescInst) assert skResult != s.kind if tfByRef in pt.flags: return true @@ -252,7 +245,7 @@ proc ccgIntroducedPtr(s: PSym): bool = if s.typ.sym != nil and sfForward in s.typ.sym.flags: # forwarded objects are *always* passed by pointers for consistency! result = true - elif (optByRef in s.options) or (getSize(pt) > platform.floatSize * 3): + elif (optByRef in s.options) or (getSize(conf, pt) > conf.target.floatSize * 3): result = true # requested anyway elif (tfFinal in pt.flags) and (pt.sons[0] == nil): result = false # no need, because no subtyping possible @@ -260,14 +253,14 @@ proc ccgIntroducedPtr(s: PSym): bool = result = true # ordinary objects are always passed by reference, # otherwise casting doesn't work of tyTuple: - result = (getSize(pt) > platform.floatSize*3) or (optByRef in s.options) + result = (getSize(conf, pt) > conf.target.floatSize*3) or (optByRef in s.options) else: result = false -proc fillResult(param: PNode) = +proc fillResult(conf: ConfigRef; param: PNode) = fillLoc(param.sym.loc, locParam, param, ~"Result", OnStack) let t = param.sym.typ - if mapReturnType(t) != ctArray and isInvalidReturnType(t): + if mapReturnType(conf, t) != ctArray and isInvalidReturnType(conf, t): incl(param.sym.loc.flags, lfIndirect) param.sym.loc.storage = OnUnknown @@ -364,12 +357,6 @@ proc getTypeDescWeak(m: BModule; t: PType; check: var IntSet): Rope = of tySequence: result = getTypeForward(m, t, hashType(t)) & "*" pushType(m, t) - of tyOpt: - if optKind(etB) == oPtr: - result = getTypeForward(m, t, hashType(t)) & "*" - pushType(m, t) - else: - result = getTypeDescAux(m, t, check) else: result = getTypeDescAux(m, t, check) @@ -384,7 +371,7 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var Rope, check: var IntSet, declareEnvironment=true; weakDep=false) = params = nil - if t.sons[0] == nil or isInvalidReturnType(t.sons[0]): + if t.sons[0] == nil or isInvalidReturnType(m.config, t.sons[0]): rettype = ~"void" else: rettype = getTypeDescAux(m, t.sons[0], check) @@ -395,7 +382,7 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var Rope, if params != nil: add(params, ~", ") fillLoc(param.loc, locParam, t.n.sons[i], mangleParamName(m, param), param.paramStorageLoc) - if ccgIntroducedPtr(param): + if ccgIntroducedPtr(m.config, param): add(params, getTypeDescWeak(m, param.typ, check)) add(params, ~"*") incl(param.loc.flags, lfIndirect) @@ -417,10 +404,10 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var Rope, addf(params, ", NI $1Len_$2", [param.loc.r, j.rope]) inc(j) arr = arr.sons[0] - if t.sons[0] != nil and isInvalidReturnType(t.sons[0]): + if t.sons[0] != nil and isInvalidReturnType(m.config, t.sons[0]): var arr = t.sons[0] if params != nil: add(params, ", ") - if mapReturnType(t.sons[0]) != ctArray: + if mapReturnType(m.config, t.sons[0]) != ctArray: add(params, getTypeDescWeak(m, arr, check)) add(params, "*") else: @@ -471,13 +458,13 @@ proc genRecordFieldsAux(m: BModule, n: PNode, if tfPacked notin rectype.flags: add(unionBody, "struct {") else: - if hasAttribute in CC[cCompiler].props: + if hasAttribute in CC[m.config.cCompiler].props: add(unionBody, "struct __attribute__((__packed__)){" ) else: addf(unionBody, "#pragma pack(push, 1)$nstruct{", []) add(unionBody, a) addf(unionBody, "} $1;$n", [sname]) - if tfPacked in rectype.flags and hasAttribute notin CC[cCompiler].props: + if tfPacked in rectype.flags and hasAttribute notin CC[m.config.cCompiler].props: addf(unionBody, "#pragma pack(pop)$n", []) else: add(unionBody, genRecordFieldsAux(m, k, ae, rectype, check)) @@ -526,10 +513,10 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope, var hasField = false if tfPacked in typ.flags: - if hasAttribute in CC[cCompiler].props: + if hasAttribute in CC[m.config.cCompiler].props: result = structOrUnion(typ) & " __attribute__((__packed__))" else: - result = "#pragma pack(push, 1)" & tnl & structOrUnion(typ) + result = "#pragma pack(push, 1)\L" & structOrUnion(typ) else: result = structOrUnion(typ) @@ -556,7 +543,7 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope, # proper request to generate popCurrentExceptionEx not possible for 2 reasons: # generated function will be below declared Exception type and circular dependency # between Exception and popCurrentExceptionEx function - result = genProcHeader(m, magicsys.getCompilerProc(m.g.graph, "popCurrentExceptionEx")) & ";" & rnl & result + result = genProcHeader(m, magicsys.getCompilerProc(m.g.graph, "popCurrentExceptionEx")) & ";" & result hasField = true else: appcg(m, result, " {$n $1 Sup;$n", @@ -570,9 +557,9 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope, addf(result, "char dummy;$n", []) else: add(result, desc) - add(result, "};" & tnl) - if tfPacked in typ.flags and hasAttribute notin CC[cCompiler].props: - result.add "#pragma pack(pop)" & tnl + add(result, "};\L") + if tfPacked in typ.flags and hasAttribute notin CC[m.config.cCompiler].props: + result.add "#pragma pack(pop)\L" proc getTupleDesc(m: BModule, typ: PType, name: Rope, check: var IntSet): Rope = @@ -581,9 +568,9 @@ proc getTupleDesc(m: BModule, typ: PType, name: Rope, for i in countup(0, sonsLen(typ) - 1): addf(desc, "$1 Field$2;$n", [getTypeDescAux(m, typ.sons[i], check), rope(i)]) - if desc == nil: add(result, "char dummy;" & tnl) + if desc == nil: add(result, "char dummy;\L") else: add(result, desc) - add(result, "};" & tnl) + add(result, "};\L") proc scanCppGenericSlot(pat: string, cursor, outIdx, outStars: var int): bool = # A helper proc for handling cppimport patterns, involving numeric @@ -657,21 +644,6 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope = result = name & "*" & star m.typeCache[sig] = result pushType(m, et) - of tyOpt: - if etB.sons[0].kind in {tyObject, tyTuple}: - let name = getTypeForward(m, et, hashType et) - result = name & "*" & star - m.typeCache[sig] = result - pushType(m, et) - elif optKind(etB) == oBool: - let name = getTypeForward(m, et, hashType et) - result = name & "*" - m.typeCache[sig] = result - pushType(m, et) - else: - # else we have a strong dependency :-( - result = getTypeDescAux(m, et, check) & star - m.typeCache[sig] = result else: # else we have a strong dependency :-( result = getTypeDescAux(m, et, check) & star @@ -687,11 +659,11 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope = (sfImportc in t.sym.flags and t.sym.magic == mNone)): m.typeCache[sig] = result var size: int - if firstOrd(t) < 0: + if firstOrd(m.config, t) < 0: addf(m.s[cfsTypes], "typedef NI32 $1;$n", [result]) size = 4 else: - size = int(getSize(t)) + size = int(getSize(m.config, t)) case size of 1: addf(m.s[cfsTypes], "typedef NU8 $1;$n", [result]) of 2: addf(m.s[cfsTypes], "typedef NU16 $1;$n", [result]) @@ -747,40 +719,8 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope = else: result = rope("TGenericSeq") add(result, "*") - of tyOpt: - result = cacheGetType(m.typeCache, sig) - if result == nil: - case optKind(t) - of oBool: - result = cacheGetType(m.forwTypeCache, sig) - if result == nil: - result = getTypeName(m, origTyp, sig) - addf(m.s[cfsForwardTypes], getForwardStructFormat(m), - [structOrUnion(t), result]) - m.forwTypeCache[sig] = result - appcg(m, m.s[cfsSeqTypes], "struct $2 {$n" & - " NIM_BOOL Field0;$n" & - " $1 Field1;$n" & - "};$n", [getTypeDescAux(m, t.sons[0], check), result]) - of oPtr: - let et = t.sons[0] - if et.kind in {tyTuple, tyObject}: - let name = getTypeForward(m, et, hashType et) - result = name & "*" - pushType(m, et) - else: - result = getTypeDescAux(m, t.sons[0], check) & "*" - of oNil: - result = getTypeDescAux(m, t.sons[0], check) - of oEnum: - result = getTypeName(m, origTyp, sig) - if getSize(t.sons[0]) == 8: - addf(m.s[cfsTypes], "typedef NI64 $1;$n", [result]) - else: - addf(m.s[cfsTypes], "typedef NI32 $1;$n", [result]) - m.typeCache[sig] = result of tyArray: - var n: BiggestInt = lengthOrd(t) + var n: BiggestInt = lengthOrd(m.config, t) if n <= 0: n = 1 # make an array of at least one element result = getTypeName(m, origTyp, sig) m.typeCache[sig] = result @@ -866,11 +806,11 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope = result = $t.kind & '_' & getTypeName(m, t.lastSon, hashType t.lastSon) m.typeCache[sig] = result if not isImportedType(t): - let s = int(getSize(t)) + let s = int(getSize(m.config, t)) case s of 1, 2, 4, 8: addf(m.s[cfsTypes], "typedef NU$2 $1;$n", [result, rope(s*8)]) else: addf(m.s[cfsTypes], "typedef NU8 $1[$2];$n", - [result, rope(getSize(t))]) + [result, rope(getSize(m.config, t))]) of tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc, tyAlias, tySink, tyUserTypeClass, tyUserTypeClassInst, tyInferred: result = getTypeDescAux(m, lastSon(t), check) @@ -972,7 +912,7 @@ proc genTypeInfoAuxBase(m: BModule; typ, origType: PType; var typename = typeToString(if origType.typeInst != nil: origType.typeInst else: origType, preferName) if typename == "ref object" and origType.skipTypes(skipPtrs).sym != nil: - typename = "anon ref object from " & $origType.skipTypes(skipPtrs).sym.info + typename = "anon ref object from " & m.config$origType.skipTypes(skipPtrs).sym.info addf(m.s[cfsTypeInit3], "$1.name = $2;$n", [name, makeCstring typename]) discard cgsym(m, "nimTypeRoot") @@ -1006,7 +946,7 @@ proc discriminatorTableName(m: BModule, objtype: PType, d: PSym): Rope = proc discriminatorTableDecl(m: BModule, objtype: PType, d: PSym): Rope = discard cgsym(m, "TNimNode") var tmp = discriminatorTableName(m, objtype, d) - result = "TNimNode* $1[$2];$n" % [tmp, rope(lengthOrd(d.typ)+1)] + result = "TNimNode* $1[$2];$n" % [tmp, rope(lengthOrd(m.config, d.typ)+1)] proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope; info: TLineInfo) = @@ -1030,7 +970,7 @@ proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope; assert(n.sons[0].kind == nkSym) var field = n.sons[0].sym var tmp = discriminatorTableName(m, typ, field) - var L = lengthOrd(field.typ) + var L = lengthOrd(m.config, field.typ) assert L > 0 if field.loc.r == nil: fillObjectFields(m, typ) if field.loc.t == nil: @@ -1140,7 +1080,7 @@ proc genEnumInfo(m: BModule, typ: PType, name: Rope; info: TLineInfo) = add(enumNames, makeCString(field.name.s)) else: add(enumNames, makeCString(field.ast.strVal)) - if i < length - 1: add(enumNames, ", " & tnl) + if i < length - 1: add(enumNames, ", \L") if field.position != i or tfEnumHasHoles in typ.flags: addf(specialCases, "$1.offset = $2;$n", [elemNode, rope(field.position)]) hasHoles = true @@ -1166,7 +1106,7 @@ proc genSetInfo(m: BModule, typ: PType, name: Rope; info: TLineInfo) = genTypeInfoAux(m, typ, typ, name, info) var tmp = getNimNode(m) addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 0;$n" & "$3.node = &$1;$n", - [tmp, rope(firstOrd(typ)), name]) + [tmp, rope(firstOrd(m.config, typ)), name]) proc genArrayInfo(m: BModule, typ: PType, name: Rope; info: TLineInfo) = genTypeInfoAuxBase(m, typ, typ, name, genTypeInfo(m, typ.sons[1], info), info) @@ -1190,8 +1130,6 @@ proc genDeepCopyProc(m: BModule; s: PSym; result: Rope) = proc genTypeInfo(m: BModule, t: PType; info: TLineInfo): Rope = let origType = t var t = skipTypes(origType, irrelevantForBackend + tyUserTypeClasses) - if t.kind == tyOpt: - return genTypeInfo(m, optLowering(t), info) let sig = hashType(origType) result = m.typeInfoMarker.getOrDefault(sig) diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim index a6080a808..f481e4d63 100644 --- a/compiler/ccgutils.nim +++ b/compiler/ccgutils.nim @@ -27,9 +27,9 @@ proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode = proc stmtsContainPragma*(n: PNode, w: TSpecialWord): bool = result = getPragmaStmt(n, w) != nil -proc hashString*(s: string): BiggestInt = +proc hashString*(conf: ConfigRef; s: string): BiggestInt = # has to be the same algorithm as system.hashString! - if CPU[targetCPU].bit == 64: + if CPU[conf.target.targetCPU].bit == 64: # we have to use the same bitwidth # as the target CPU var b = 0'i64 @@ -52,112 +52,7 @@ proc hashString*(s: string): BiggestInt = a = a +% `shl`(a, 15'i32) result = a -var - gTypeTable: array[TTypeKind, TIdTable] # XXX globals here - gCanonicalTypes: array[TTypeKind, PType] - -proc initTypeTables() = - for i in countup(low(TTypeKind), high(TTypeKind)): initIdTable(gTypeTable[i]) - -proc resetCaches* = - ## XXX: fix that more properly - initTypeTables() - for i in low(gCanonicalTypes)..high(gCanonicalTypes): - gCanonicalTypes[i] = nil - -when false: - proc echoStats*() = - for i in countup(low(TTypeKind), high(TTypeKind)): - echo i, " ", gTypeTable[i].counter - -proc slowSearch(key: PType; k: TTypeKind): PType = - # tuples are quite horrible as C does not support them directly and - # tuple[string, string] is a (strange) subtype of - # tuple[nameA, nameB: string]. This bites us here, so we - # use 'sameBackendType' instead of 'sameType'. - if idTableHasObjectAsKey(gTypeTable[k], key): return key - for h in countup(0, high(gTypeTable[k].data)): - var t = PType(gTypeTable[k].data[h].key) - if t != nil and sameBackendType(t, key): - return t - idTablePut(gTypeTable[k], key, key) - result = key - -proc getUniqueType*(key: PType): PType = - # this is a hotspot in the compiler! - result = key - when false: - if key == nil: return - var k = key.kind - case k - of tyBool, tyChar, tyInt..tyUInt64: - # no canonicalization for integral types, so that e.g. ``pid_t`` is - # produced instead of ``NI``. - result = key - of tyEmpty, tyNil, tyExpr, tyStmt, tyPointer, tyString, - tyCString, tyNone, tyVoid: - result = gCanonicalTypes[k] - if result == nil: - gCanonicalTypes[k] = key - result = key - of tyTypeDesc, tyTypeClasses, tyGenericParam, tyFromExpr: - if key.isResolvedUserTypeClass: - return getUniqueType(lastSon(key)) - if key.sym != nil: - internalError(key.sym.info, "metatype not eliminated") - else: - internalError("metatype not eliminated") - of tyDistinct: - if key.deepCopy != nil: result = key - else: result = getUniqueType(lastSon(key)) - of tyGenericInst, tyOrdinal, tyStatic, tyAlias, tySink, tyInferred: - result = getUniqueType(lastSon(key)) - #let obj = lastSon(key) - #if obj.sym != nil and obj.sym.name.s == "TOption": - # echo "for ", typeToString(key), " I returned " - # debug result - of tyPtr, tyRef, tyVar, tyLent: - let elemType = lastSon(key) - if elemType.kind in {tyBool, tyChar, tyInt..tyUInt64}: - # no canonicalization for integral types, so that e.g. ``ptr pid_t`` is - # produced instead of ``ptr NI``. - result = key - else: - result = slowSearch(key, k) - of tyGenericInvocation, tyGenericBody, - tyOpenArray, tyArray, tySet, tyRange, tyTuple, - tySequence, tyForward, tyVarargs, tyProxy, tyOpt: - # we have to do a slow linear search because types may need - # to be compared by their structure: - result = slowSearch(key, k) - of tyObject: - if tfFromGeneric notin key.flags: - # fast case; lookup per id suffices: - result = PType(idTableGet(gTypeTable[k], key)) - if result == nil: - idTablePut(gTypeTable[k], key, key) - result = key - else: - # ugly slow case: need to compare by structure - if idTableHasObjectAsKey(gTypeTable[k], key): return key - for h in countup(0, high(gTypeTable[k].data)): - var t = PType(gTypeTable[k].data[h].key) - if t != nil and sameBackendType(t, key): - return t - idTablePut(gTypeTable[k], key, key) - result = key - of tyEnum: - result = PType(idTableGet(gTypeTable[k], key)) - if result == nil: - idTablePut(gTypeTable[k], key, key) - result = key - of tyProc: - if key.callConv != ccClosure: - result = key - else: - # ugh, we need the canon here: - result = slowSearch(key, k) - of tyUnused, tyOptAsRef, tyUnused1, tyUnused2: internalError("getUniqueType") +template getUniqueType*(key: PType): PType = key proc makeSingleLineCString*(s: string): string = result = "\"" @@ -210,5 +105,3 @@ proc mangle*(name: string): string = requiresUnderscore = true if requiresUnderscore: result.add "_" - -initTypeTables() diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 79bcf0491..1c5544d4d 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -19,7 +19,8 @@ import import strutils except `%` # collides with ropes.`%` from modulegraphs import ModuleGraph -from configuration import warnGcMem, errXMustBeCompileTime, hintDependency, errGenerated +from configuration import + warnGcMem, errXMustBeCompileTime, hintDependency, errGenerated, errCannotOpenFile import dynlib when not declared(dynlib.libCandidates): @@ -120,10 +121,10 @@ proc ropecg(m: BModule, frmt: FormatStr, args: varargs[Rope]): Rope = internalError(m.config, "ropes: invalid format string $" & $j) add(result, args[j-1]) of 'n': - if optLineDir notin m.config.options: add(result, rnl) + if optLineDir notin m.config.options: add(result, "\L") inc(i) of 'N': - add(result, rnl) + add(result, "\L") inc(i) else: internalError(m.config, "ropes: invalid format string $" & frmt[i]) elif frmt[i] == '#' and frmt[i+1] in IdentStartChars: @@ -193,7 +194,7 @@ proc genCLineDir(r: var Rope, filename: string, line: int; conf: ConfigRef) = [rope(makeSingleLineCString(filename)), rope(line)]) proc genCLineDir(r: var Rope, info: TLineInfo; conf: ConfigRef) = - genCLineDir(r, info.toFullPath, info.safeLineNm, conf) + genCLineDir(r, toFullPath(conf, info), info.safeLineNm, conf) proc freshLineInfo(p: BProc; info: TLineInfo): bool = if p.lastLineInfo.line != info.line or @@ -211,13 +212,13 @@ proc genLineDir(p: BProc, t: PNode) = let line = tt.info.safeLineNm if optEmbedOrigSrc in p.config.globalOptions: - add(p.s(cpsStmts), ~"//" & sourceLine(p.config, tt.info) & rnl) - genCLineDir(p.s(cpsStmts), tt.info.toFullPath, line, p.config) + add(p.s(cpsStmts), ~"//" & sourceLine(p.config, tt.info) & "\L") + genCLineDir(p.s(cpsStmts), toFullPath(p.config, tt.info), line, p.config) if ({optStackTrace, optEndb} * p.options == {optStackTrace, optEndb}) and (p.prc == nil or sfPure notin p.prc.flags): if freshLineInfo(p, tt.info): linefmt(p, cpsStmts, "#endb($1, $2);$N", - line.rope, makeCString(toFilename(tt.info))) + line.rope, makeCString(toFilename(p.config, tt.info))) elif ({optLineTrace, optStackTrace} * p.options == {optLineTrace, optStackTrace}) and (p.prc == nil or sfPure notin p.prc.flags) and tt.info.fileIndex != InvalidFileIDX: @@ -249,9 +250,9 @@ proc rdLoc(a: TLoc): Rope = result = a.r if lfIndirect in a.flags: result = "(*$1)" % [result] -proc addrLoc(a: TLoc): Rope = +proc addrLoc(conf: ConfigRef; a: TLoc): Rope = result = a.r - if lfIndirect notin a.flags and mapType(a.t) != ctArray: + if lfIndirect notin a.flags and mapType(conf, a.t) != ctArray: result = "(&" & result & ")" proc rdCharLoc(a: TLoc): Rope = @@ -281,7 +282,7 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc, linefmt(p, section, "$1.m_type = $2;$n", r, genTypeInfo(p.module, t, a.lode.info)) of frEmbedded: # worst case for performance: - var r = if takeAddr: addrLoc(a) else: rdLoc(a) + var r = if takeAddr: addrLoc(p.config, a) else: rdLoc(a) linefmt(p, section, "#objectInit($1, $2);$n", r, genTypeInfo(p.module, t, a.lode.info)) type @@ -310,10 +311,10 @@ proc resetLoc(p: BProc, loc: var TLoc) = linefmt(p, cpsStmts, "$1 = 0;$n", rdLoc(loc)) else: if optNilCheck in p.options: - linefmt(p, cpsStmts, "#chckNil((void*)$1);$n", addrLoc(loc)) + linefmt(p, cpsStmts, "#chckNil((void*)$1);$n", addrLoc(p.config, loc)) if loc.storage != OnStack: linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n", - addrLoc(loc), genTypeInfo(p.module, loc.t, loc.lode.info)) + addrLoc(p.config, loc), genTypeInfo(p.module, loc.t, loc.lode.info)) # XXX: generated reset procs should not touch the m_type # field, so disabling this should be safe: genObjectInit(p, cpsStmts, loc.t, loc, true) @@ -322,7 +323,7 @@ proc resetLoc(p: BProc, loc: var TLoc) = # array passed as argument decayed into pointer, bug #7332 # so we use getTypeDesc here rather than rdLoc(loc) linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n", - addrLoc(loc), getTypeDesc(p.module, loc.t)) + addrLoc(p.config, loc), getTypeDesc(p.module, loc.t)) # XXX: We can be extra clever here and call memset only # on the bytes following the m_type field? genObjectInit(p, cpsStmts, loc.t, loc, true) @@ -339,7 +340,7 @@ proc constructLoc(p: BProc, loc: TLoc, isTemp = false) = if not isImportedCppType(typ): useStringh(p.module) linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n", - addrLoc(loc), getTypeDesc(p.module, typ)) + addrLoc(p.config, loc), getTypeDesc(p.module, typ)) genObjectInit(p, cpsStmts, loc.t, loc, true) proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) = @@ -386,7 +387,7 @@ proc localDebugInfo(p: BProc, s: PSym) = # XXX work around a bug: No type information for open arrays possible: if skipTypes(s.typ, abstractVar).kind in {tyOpenArray, tyVarargs}: return var a = "&" & s.loc.r - if s.kind == skParam and ccgIntroducedPtr(s): a = s.loc.r + if s.kind == skParam and ccgIntroducedPtr(p.config, s): a = s.loc.r lineF(p, cpsInit, "FR_.s[$1].address = (void*)$3; FR_.s[$1].typ = $4; FR_.s[$1].name = $2;$n", [p.maxFrameLen.rope, makeCString(normalize(s.name.s)), a, @@ -414,7 +415,7 @@ proc assignLocalVar(p: BProc, n: PNode) = #assert(s.loc.k == locNone) # not yet assigned # this need not be fulfilled for inline procs; they are regenerated # for each module that uses them! - let nl = if optLineDir in p.config.options: "" else: tnl + let nl = if optLineDir in p.config.options: "" else: "\L" let decl = localVarDecl(p, n) & ";" & nl line(p, cpsLocals, decl) localDebugInfo(p, n.sym) @@ -651,33 +652,33 @@ proc cgsym(m: BModule, name: string): Rope = result = sym.loc.r proc generateHeaders(m: BModule) = - add(m.s[cfsHeaders], tnl & "#include \"nimbase.h\"" & tnl) + add(m.s[cfsHeaders], "\L#include \"nimbase.h\"\L") for it in m.headerFiles: if it[0] == '#': - add(m.s[cfsHeaders], rope(it.replace('`', '"') & tnl)) + add(m.s[cfsHeaders], rope(it.replace('`', '"') & "\L")) elif it[0] notin {'\"', '<'}: addf(m.s[cfsHeaders], "#include \"$1\"$N", [rope(it)]) else: addf(m.s[cfsHeaders], "#include $1$N", [rope(it)]) - add(m.s[cfsHeaders], "#undef LANGUAGE_C" & tnl) - add(m.s[cfsHeaders], "#undef MIPSEB" & tnl) - add(m.s[cfsHeaders], "#undef MIPSEL" & tnl) - add(m.s[cfsHeaders], "#undef PPC" & tnl) - add(m.s[cfsHeaders], "#undef R3000" & tnl) - add(m.s[cfsHeaders], "#undef R4000" & tnl) - add(m.s[cfsHeaders], "#undef i386" & tnl) - add(m.s[cfsHeaders], "#undef linux" & tnl) - add(m.s[cfsHeaders], "#undef mips" & tnl) - add(m.s[cfsHeaders], "#undef near" & tnl) - add(m.s[cfsHeaders], "#undef powerpc" & tnl) - add(m.s[cfsHeaders], "#undef unix" & tnl) + add(m.s[cfsHeaders], "#undef LANGUAGE_C\L") + add(m.s[cfsHeaders], "#undef MIPSEB\L") + add(m.s[cfsHeaders], "#undef MIPSEL\L") + add(m.s[cfsHeaders], "#undef PPC\L") + add(m.s[cfsHeaders], "#undef R3000\L") + add(m.s[cfsHeaders], "#undef R4000\L") + add(m.s[cfsHeaders], "#undef i386\L") + add(m.s[cfsHeaders], "#undef linux\L") + add(m.s[cfsHeaders], "#undef mips\L") + add(m.s[cfsHeaders], "#undef near\L") + add(m.s[cfsHeaders], "#undef powerpc\L") + add(m.s[cfsHeaders], "#undef unix\L") proc openNamespaceNim(): Rope = - result.add("namespace Nim {" & tnl) + result.add("namespace Nim {\L") proc closeNamespaceNim(): Rope = - result.add("}" & tnl) + result.add("}\L") proc closureSetup(p: BProc, prc: PSym) = if tfCapturesEnv notin prc.typ.flags: return @@ -727,7 +728,7 @@ proc genProcAux(m: BModule, prc: PSym) = internalError(m.config, prc.info, "proc has no result symbol") let resNode = prc.ast.sons[resultPos] let res = resNode.sym # get result symbol - if not isInvalidReturnType(prc.typ.sons[0]): + if not isInvalidReturnType(m.config, prc.typ.sons[0]): if sfNoInit in prc.flags: incl(res.flags, sfNoInit) if sfNoInit in prc.flags and p.module.compileToCpp and (let val = easyResultAsgn(prc.getBody); val != nil): var decl = localVarDecl(p, resNode) @@ -741,7 +742,7 @@ proc genProcAux(m: BModule, prc: PSym) = initLocalVar(p, res, immediateAsgn=false) returnStmt = ropecg(p.module, "\treturn $1;$n", rdLoc(res.loc)) else: - fillResult(resNode) + fillResult(p.config, resNode) assignParam(p, res) if sfNoInit notin prc.flags: resetLoc(p, res.loc) if skipTypes(res.typ, abstractInst).kind == tyArray: @@ -756,10 +757,10 @@ proc genProcAux(m: BModule, prc: PSym) = genStmts(p, prc.getBody) # modifies p.locals, p.init, etc. var generatedProc: Rope if sfNoReturn in prc.flags: - if hasDeclspec in extccomp.CC[extccomp.cCompiler].props: + if hasDeclspec in extccomp.CC[p.config.cCompiler].props: header = "__declspec(noreturn) " & header if sfPure in prc.flags: - if hasDeclspec in extccomp.CC[extccomp.cCompiler].props: + if hasDeclspec in extccomp.CC[p.config.cCompiler].props: header = "__declspec(naked) " & header generatedProc = ropecg(p.module, "$N$1 {$n$2$3$4}$N$N", header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts)) @@ -803,13 +804,13 @@ proc genProcPrototype(m: BModule, sym: PSym) = getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym))) elif not containsOrIncl(m.declaredProtos, sym.id): var header = genProcHeader(m, sym) - if sfNoReturn in sym.flags and hasDeclspec in extccomp.CC[cCompiler].props: + if sfNoReturn in sym.flags and hasDeclspec in extccomp.CC[m.config.cCompiler].props: header = "__declspec(noreturn) " & header if sym.typ.callConv != ccInline and requiresExternC(m, sym): header = "extern \"C\" " & header - if sfPure in sym.flags and hasAttribute in CC[cCompiler].props: + if sfPure in sym.flags and hasAttribute in CC[m.config.cCompiler].props: header.add(" __attribute__((naked))") - if sfNoReturn in sym.flags and hasAttribute in CC[cCompiler].props: + if sfNoReturn in sym.flags and hasAttribute in CC[m.config.cCompiler].props: header.add(" __attribute__((noreturn))") add(m.s[cfsProcHeaders], ropecg(m, "$1;$n", header)) @@ -918,10 +919,10 @@ proc genVarPrototype(m: BModule, n: PNode) = addf(m.s[cfsVars], " $1;$n", [sym.loc.r]) proc addIntTypes(result: var Rope; conf: ConfigRef) {.inline.} = - addf(result, "#define NIM_NEW_MANGLING_RULES" & tnl & - "#define NIM_INTBITS $1" & tnl, [ - platform.CPU[targetCPU].intSize.rope]) - if optUseNimNamespace in conf.globalOptions: result.add("#define USE_NIM_NAMESPACE" & tnl) + addf(result, "#define NIM_NEW_MANGLING_RULES\L" & + "#define NIM_INTBITS $1\L", [ + platform.CPU[conf.target.targetCPU].intSize.rope]) + if optUseNimNamespace in conf.globalOptions: result.add("#define USE_NIM_NAMESPACE\L") proc getCopyright(conf: ConfigRef; cfile: Cfile): Rope = if optCompileOnly in conf.globalOptions: @@ -936,9 +937,9 @@ proc getCopyright(conf: ConfigRef; cfile: Cfile): Rope = "/* Compiled for: $2, $3, $4 */$N" & "/* Command for C compiler:$n $5 */$N") % [rope(VersionAsString), - rope(platform.OS[targetOS].name), - rope(platform.CPU[targetCPU].name), - rope(extccomp.CC[extccomp.cCompiler].name), + rope(platform.OS[conf.target.targetOS].name), + rope(platform.CPU[conf.target.targetCPU].name), + rope(extccomp.CC[conf.cCompiler].name), rope(getCompileCFileCmd(conf, cfile))] proc getFileHeader(conf: ConfigRef; cfile: Cfile): Rope = @@ -1047,7 +1048,7 @@ proc genMainProc(m: BModule) = "}$N$N" var nimMain, otherMain: FormatStr - if platform.targetOS == osWindows and + if m.config.target.targetOS == osWindows and m.config.globalOptions * {optGenGuiApp, optGenDynLib} != {}: if optGenGuiApp in m.config.globalOptions: nimMain = WinNimMain @@ -1056,13 +1057,13 @@ proc genMainProc(m: BModule) = nimMain = WinNimDllMain otherMain = WinCDllMain m.includeHeader("<windows.h>") - elif platform.targetOS == osGenode: + elif m.config.target.targetOS == osGenode: nimMain = GenodeNimMain otherMain = ComponentConstruct elif optGenDynLib in m.config.globalOptions: nimMain = PosixNimDllMain otherMain = PosixCDllMain - elif platform.targetOS == osStandalone: + elif m.config.target.targetOS == osStandalone: nimMain = PosixNimMain otherMain = StandaloneCMain else: @@ -1073,12 +1074,12 @@ proc genMainProc(m: BModule) = m.g.breakpoints.add(m.genFilenames) let initStackBottomCall = - if platform.targetOS == osStandalone or m.config.selectedGC == gcNone: "".rope + if m.config.target.targetOS == osStandalone or m.config.selectedGC == gcNone: "".rope else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N") inc(m.labels) appcg(m, m.s[cfsProcs], PreMainBody, [ m.g.mainDatInit, m.g.breakpoints, m.g.otherModsInit, - if emulatedThreadVars(m.config) and platform.targetOS != osStandalone: + if emulatedThreadVars(m.config) and m.config.target.targetOS != osStandalone: ropecg(m, "\t#initThreadVarsEmulation();$N") else: "".rope, @@ -1088,7 +1089,7 @@ proc genMainProc(m: BModule) = [m.g.mainModInit, initStackBottomCall, rope(m.labels)]) if optNoMain notin m.config.globalOptions: if optUseNimNamespace in m.config.globalOptions: - m.s[cfsProcs].add closeNamespaceNim() & "using namespace Nim;" & tnl + m.s[cfsProcs].add closeNamespaceNim() & "using namespace Nim;\L" appcg(m, m.s[cfsProcs], otherMain, []) if optUseNimNamespace in m.config.globalOptions: m.s[cfsProcs].add openNamespaceNim() @@ -1249,7 +1250,7 @@ proc rawNewModule(g: BModuleList; module: PSym, filename: string): BModule = excl(result.postInitProc.options, optStackTrace) let ndiName = if optCDebug in g.config.globalOptions: changeFileExt(completeCFilePath(g.config, filename), "ndi") else: "" - open(result.ndi, ndiName) + open(result.ndi, ndiName, g.config) proc nullify[T](arr: var T) = for i in low(arr)..high(arr): @@ -1299,12 +1300,12 @@ proc resetModule*(m: BModule) = proc resetCgenModules*(g: BModuleList) = for m in cgenModules(g): resetModule(m) -proc rawNewModule(g: BModuleList; module: PSym): BModule = - result = rawNewModule(g, module, module.position.FileIndex.toFullPath) +proc rawNewModule(g: BModuleList; module: PSym; conf: ConfigRef): BModule = + result = rawNewModule(g, module, toFullPath(conf, module.position.FileIndex)) -proc newModule(g: BModuleList; module: PSym): BModule = +proc newModule(g: BModuleList; module: PSym; conf: ConfigRef): BModule = # we should create only one cgen module for each module sym - result = rawNewModule(g, module) + result = rawNewModule(g, module, conf) growCache g.modules, module.position g.modules[module.position] = result @@ -1315,7 +1316,7 @@ template injectG() {.dirty.} = proc myOpen(graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext = injectG() - result = newModule(g, module) + result = newModule(g, module, graph.config) if optGenIndex in graph.config.globalOptions and g.generatedHeader == nil: let f = if graph.config.headerFile.len > 0: graph.config.headerFile else: graph.config.projectFull @@ -1347,7 +1348,8 @@ proc writeHeader(m: BModule) = result.addf("N_CDECL(void, NimMain)(void);$n", []) if optUseNimNamespace in m.config.globalOptions: result.add closeNamespaceNim() result.addf("#endif /* $1 */$n", [guard]) - writeRope(result, m.filename) + if not writeRope(result, m.filename): + rawMessage(m.config, errCannotOpenFile, m.filename) proc getCFile(m: BModule): string = let ext = @@ -1358,7 +1360,7 @@ proc getCFile(m: BModule): string = proc myOpenCached(graph: ModuleGraph; module: PSym, rd: PRodReader): PPassContext = injectG() - var m = newModule(g, module) + var m = newModule(g, module, graph.config) readMergeInfo(getCFile(m), m) result = m @@ -1368,7 +1370,8 @@ proc myProcess(b: PPassContext, n: PNode): PNode = var m = BModule(b) if passes.skipCodegen(m.config, n): return m.initProc.options = initProcOptions(m) - softRnl = if optLineDir in m.config.options: noRnl else: rnl + #softRnl = if optLineDir in m.config.options: noRnl else: rnl + # XXX replicate this logic! genStmts(m.initProc, n) proc finishModule(m: BModule) = @@ -1395,12 +1398,14 @@ proc shouldRecompile(m: BModule; code: Rope, cfile: Cfile): bool = echo "diff ", cfile.cname, ".backup ", cfile.cname else: echo "new file ", cfile.cname - writeRope(code, cfile.cname) + if not writeRope(code, cfile.cname): + rawMessage(m.config, errCannotOpenFile, cfile.cname) return if existsFile(cfile.obj) and os.fileNewer(cfile.obj, cfile.cname): result = false else: - writeRope(code, cfile.cname) + if not writeRope(code, cfile.cname): + rawMessage(m.config, errCannotOpenFile, cfile.cname) # We need 2 different logics here: pending modules (including # 'nim__dat') may require file merging for the combination of dead code @@ -1435,7 +1440,8 @@ proc writeModule(m: BModule, pending: bool) = genInitCode(m) finishTypeDescriptions(m) var code = genModule(m, cf) - writeRope(code, cfile) + if not writeRope(code, cfile): + rawMessage(m.config, errCannotOpenFile, cfile) addFileToCompile(m.config, cf) else: # Consider: first compilation compiles ``system.nim`` and produces @@ -1456,7 +1462,8 @@ proc updateCachedModule(m: BModule) = finishTypeDescriptions(m) var code = genModule(m, cf) - writeRope(code, cfile) + if not writeRope(code, cfile): + rawMessage(m.config, errCannotOpenFile, cfile) else: cf.flags = {CfileFlag.Cached} addFileToCompile(m.config, cf) diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index 1d72952e2..da3ffaa61 100644 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -115,7 +115,7 @@ proc createDispatcher(s: PSym): PSym = # we can't inline the dispatcher itself (for now): if disp.typ.callConv == ccInline: disp.typ.callConv = ccDefault disp.ast = copyTree(s.ast) - disp.ast.sons[bodyPos] = ast.emptyNode + disp.ast.sons[bodyPos] = newNodeI(nkEmpty, s.info) disp.loc.r = nil if s.typ.sons[0] != nil: if disp.ast.sonsLen > resultPos: @@ -124,7 +124,7 @@ proc createDispatcher(s: PSym): PSym = # We've encountered a method prototype without a filled-in # resultPos slot. We put a placeholder in there that will # be updated in fixupDispatcher(). - disp.ast.addSon(ast.emptyNode) + disp.ast.addSon(newNodeI(nkEmpty, s.info)) attachDispatcher(s, newSymNode(disp)) # attach to itself to prevent bugs: attachDispatcher(disp, newSymNode(disp)) @@ -137,7 +137,7 @@ proc fixupDispatcher(meth, disp: PSym; conf: ConfigRef) = # the lock level of the dispatcher needs to be updated/checked # against that of the method. if disp.ast.sonsLen > resultPos and meth.ast.sonsLen > resultPos and - disp.ast.sons[resultPos] == ast.emptyNode: + disp.ast.sons[resultPos].kind == nkEmpty: disp.ast.sons[resultPos] = copyTree(meth.ast.sons[resultPos]) # The following code works only with lock levels, so we disable @@ -184,7 +184,7 @@ proc methodDef*(g: ModuleGraph; s: PSym, fromCache: bool) = # internalError(s.info, "no method dispatcher found") if witness != nil: localError(g.config, s.info, "invalid declaration order; cannot attach '" & s.name.s & - "' to method defined here: " & $witness.info) + "' to method defined here: " & g.config$witness.info) elif sfBase notin s.flags: message(g.config, s.info, warnUseBase) diff --git a/compiler/commands.nim b/compiler/commands.nim index 09f63f0f5..50bc6a770 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -56,21 +56,21 @@ const x AdvancedUsage = slurp"../doc/advopt.txt".replace("//", "") % FeatureDesc -proc getCommandLineDesc(): string = - result = (HelpMessage % [VersionAsString, platform.OS[platform.hostOS].name, - CPU[platform.hostCPU].name, CompileDate]) & +proc getCommandLineDesc(conf: ConfigRef): string = + result = (HelpMessage % [VersionAsString, platform.OS[conf.target.hostOS].name, + CPU[conf.target.hostCPU].name, CompileDate]) & Usage proc helpOnError(conf: ConfigRef; pass: TCmdLinePass) = if pass == passCmd1: - msgWriteln(conf, getCommandLineDesc(), {msgStdout}) + msgWriteln(conf, getCommandLineDesc(conf), {msgStdout}) msgQuit(0) proc writeAdvancedUsage(conf: ConfigRef; pass: TCmdLinePass) = if pass == passCmd1: msgWriteln(conf, (HelpMessage % [VersionAsString, - platform.OS[platform.hostOS].name, - CPU[platform.hostCPU].name, CompileDate]) & + platform.OS[conf.target.hostOS].name, + CPU[conf.target.hostCPU].name, CompileDate]) & AdvancedUsage, {msgStdout}) msgQuit(0) @@ -78,8 +78,8 @@ proc writeAdvancedUsage(conf: ConfigRef; pass: TCmdLinePass) = proc writeFullhelp(conf: ConfigRef; pass: TCmdLinePass) = if pass == passCmd1: msgWriteln(conf, `%`(HelpMessage, [VersionAsString, - platform.OS[platform.hostOS].name, - CPU[platform.hostCPU].name, CompileDate]) & + platform.OS[conf.target.hostOS].name, + CPU[conf.target.hostCPU].name, CompileDate]) & Usage & AdvancedUsage, {msgStdout}) msgQuit(0) @@ -87,8 +87,8 @@ proc writeFullhelp(conf: ConfigRef; pass: TCmdLinePass) = proc writeVersionInfo(conf: ConfigRef; pass: TCmdLinePass) = if pass == passCmd1: msgWriteln(conf, `%`(HelpMessage, [VersionAsString, - platform.OS[platform.hostOS].name, - CPU[platform.hostCPU].name, CompileDate]), + platform.OS[conf.target.hostOS].name, + CPU[conf.target.hostCPU].name, CompileDate]), {msgStdout}) const gitHash = gorge("git log -n 1 --format=%H").strip @@ -103,7 +103,7 @@ proc writeVersionInfo(conf: ConfigRef; pass: TCmdLinePass) = proc writeCommandLineUsage*(conf: ConfigRef; helpWritten: var bool) = if not helpWritten: - msgWriteln(conf, getCommandLineDesc(), {msgStdout}) + msgWriteln(conf, getCommandLineDesc(conf), {msgStdout}) helpWritten = true proc addPrefix(switch: string): string = @@ -289,14 +289,14 @@ proc processPath(conf: ConfigRef; path: string, info: TLineInfo, else: conf.projectPath / path try: - result = pathSubs(conf, p, info.toFullPath().splitFile().dir) + result = pathSubs(conf, p, toFullPath(conf, info).splitFile().dir) except ValueError: localError(conf, info, "invalid path: " & p) result = p proc processCfgPath(conf: ConfigRef; path: string, info: TLineInfo): string = let path = if path[0] == '"': strutils.unescape(path) else: path - let basedir = info.toFullPath().splitFile().dir + let basedir = toFullPath(conf, info).splitFile().dir let p = if os.isAbsolute(path) or '$' in path: path else: @@ -322,7 +322,7 @@ proc trackDirty(conf: ConfigRef; arg: string, info: TLineInfo) = let dirtyOriginalIdx = fileInfoIdx(conf, a[1]) if dirtyOriginalIdx.int32 >= 0: - msgs.setDirtyFile(dirtyOriginalIdx, a[0]) + msgs.setDirtyFile(conf, dirtyOriginalIdx, a[0]) gTrackPos = newLineInfo(dirtyOriginalIdx, line, column) @@ -344,8 +344,6 @@ proc dynlibOverride(conf: ConfigRef; switch, arg: string, pass: TCmdLinePass, in proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; conf: ConfigRef) = var - theOS: TSystemOS - cpu: TSystemCPU key, val: string case switch.normalize of "path", "p": @@ -565,13 +563,13 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; if pass in {passCmd2, passPP}: extccomp.addLinkOptionCmd(conf, arg) of "cincludes": expectArg(conf, switch, arg, pass, info) - if pass in {passCmd2, passPP}: cIncludes.add processPath(conf, arg, info) + if pass in {passCmd2, passPP}: conf.cIncludes.add processPath(conf, arg, info) of "clibdir": expectArg(conf, switch, arg, pass, info) - if pass in {passCmd2, passPP}: cLibs.add processPath(conf, arg, info) + if pass in {passCmd2, passPP}: conf.cLibs.add processPath(conf, arg, info) of "clib": expectArg(conf, switch, arg, pass, info) - if pass in {passCmd2, passPP}: cLinkedLibs.add processPath(conf, arg, info) + if pass in {passCmd2, passPP}: conf.cLinkedLibs.add processPath(conf, arg, info) of "header": if conf != nil: conf.headerFile = arg incl(conf.globalOptions, optGenIndex) @@ -592,17 +590,17 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; of "os": expectArg(conf, switch, arg, pass, info) if pass in {passCmd1, passPP}: - theOS = platform.nameToOS(arg) + let theOS = platform.nameToOS(arg) if theOS == osNone: localError(conf, info, "unknown OS: '$1'" % arg) - elif theOS != platform.hostOS: - setTarget(theOS, targetCPU) + elif theOS != conf.target.hostOS: + setTarget(conf.target, theOS, conf.target.targetCPU) of "cpu": expectArg(conf, switch, arg, pass, info) if pass in {passCmd1, passPP}: - cpu = platform.nameToCPU(arg) + let cpu = platform.nameToCPU(arg) if cpu == cpuNone: localError(conf, info, "unknown CPU: '$1'" % arg) - elif cpu != platform.hostCPU: - setTarget(targetOS, cpu) + elif cpu != conf.target.hostCPU: + setTarget(conf.target, conf.target.targetOS, cpu) of "run", "r": expectNoArg(conf, switch, arg, pass, info) incl(conf.globalOptions, optRun) diff --git a/compiler/configuration.nim b/compiler/configuration.nim index f9f0e623c..bd9651c08 100644 --- a/compiler/configuration.nim +++ b/compiler/configuration.nim @@ -11,8 +11,6 @@ ## needs to be passed around to everything so that the compiler becomes ## more useful as a library. -import tables - const explanationsBaseUrl* = "https://nim-lang.org/docs/manual" @@ -182,179 +180,3 @@ const const errXMustBeCompileTime* = "'$1' can only be used in compile-time context" errArgsNeedRunOption* = "arguments can only be given if the '--run' option is selected" - -#[ -errStringLiteralExpected: "string literal expected", -errIntLiteralExpected: "integer literal expected", -errIdentifierExpected: "identifier expected, but found '$1'", -errNewlineExpected: "newline expected, but found '$1'", -errInvalidModuleName: "invalid module name: '$1'", -errOnOrOffExpected: "'on' or 'off' expected", -errNoneSpeedOrSizeExpected: "'none', 'speed' or 'size' expected", -errInvalidPragma: "invalid pragma", -errUnknownPragma: "unknown pragma: '$1'", -errAtPopWithoutPush: "'pop' without a 'push' pragma", -errEmptyAsm: "empty asm statement", -errInvalidIndentation: "invalid indentation", - -errNoReturnWithReturnTypeNotAllowed: "routines with NoReturn pragma are not allowed to have return type", -errAttemptToRedefine: , -errStmtInvalidAfterReturn: "statement not allowed after 'return', 'break', 'raise', 'continue' or proc call with noreturn pragma", -errStmtExpected: "statement expected", -errInvalidLabel: "'$1' is no label", -errInvalidCmdLineOption: "invalid command line option: '$1'", -errCmdLineArgExpected: "argument for command line option expected: '$1'", -errCmdLineNoArgExpected: "invalid argument for command line option: '$1'", -errInvalidVarSubstitution: "invalid variable substitution in '$1'", -errUnknownVar: "unknown variable: '$1'", -errUnknownCcompiler: "unknown C compiler: '$1'", -errOnOrOffExpectedButXFound: "'on' or 'off' expected, but '$1' found", -errOnOffOrListExpectedButXFound: "'on', 'off' or 'list' expected, but '$1' found", -errGenOutExpectedButXFound: "'c', 'c++' or 'yaml' expected, but '$1' found", -, -errInvalidMultipleAsgn: "multiple assignment is not allowed", -errColonOrEqualsExpected: "':' or '=' expected, but found '$1'", -errUndeclaredField: "undeclared field: '$1'", -errUndeclaredRoutine: "attempting to call undeclared routine: '$1'", -errUseQualifier: "ambiguous identifier: '$1' -- use a qualifier", -errTypeExpected: "type expected", -errSystemNeeds: "system module needs '$1'", -errExecutionOfProgramFailed: "execution of an external program failed: '$1'", -errNotOverloadable: , -errInvalidArgForX: "invalid argument for '$1'", -errStmtHasNoEffect: "statement has no effect", -, -errXExpectsArrayType: "'$1' expects an array type", -errIteratorCannotBeInstantiated: "'$1' cannot be instantiated because its body has not been compiled yet", -errExprXAmbiguous: "expression '$1' ambiguous in this context", -errConstantDivisionByZero: , -errOrdinalOrFloatTypeExpected: "ordinal or float type expected", -errOverOrUnderflow: , -errCannotEvalXBecauseIncompletelyDefined: , -errChrExpectsRange0_255: "'chr' expects an int in the range 0..255", -errDynlibRequiresExportc: "'dynlib' requires 'exportc'", -errNilAccess: "attempt to access a nil address", -errIndexOutOfBounds: "index out of bounds", -errIndexTypesDoNotMatch: "index types do not match", -errBracketsInvalidForType: "'[]' operator invalid for this type", -errValueOutOfSetBounds: "value out of set bounds", -errFieldNotInit: "field '$1' not initialized", -errExprXCannotBeCalled: "expression '$1' cannot be called", -errExprHasNoType: "expression has no type", -errExprXHasNoType:, -errCastNotInSafeMode: "'cast' not allowed in safe mode", -errExprCannotBeCastToX: , -errCommaOrParRiExpected: "',' or ')' expected", -errCurlyLeOrParLeExpected: "'{' or '(' expected", -errSectionExpected: "section ('type', 'proc', etc.) expected", -errRangeExpected: "range expected", -errMagicOnlyInSystem: "'magic' only allowed in system module", -errPowerOfTwoExpected: "power of two expected", -errStringMayNotBeEmpty: "string literal may not be empty", -errCallConvExpected: "calling convention expected", -errProcOnlyOneCallConv: "a proc can only have one calling convention", -errSymbolMustBeImported: "symbol must be imported if 'lib' pragma is used", -errExprMustBeBool: "expression must be of type 'bool'", -errConstExprExpected: "constant expression expected", -errDuplicateCaseLabel: "duplicate case label", -errRangeIsEmpty: "range is empty", -, -errSelectorMustBeOrdinal: "selector must be of an ordinal type", -errOrdXMustNotBeNegative: "ord($1) must not be negative", -errLenXinvalid: "len($1) must be less than 32768", -errTypeXhasUnknownSize: "type '$1' has unknown size", -errConstNeedsConstExpr: "a constant can only be initialized with a constant expression", -errConstNeedsValue: "a constant needs a value", -errResultCannotBeOpenArray: "the result type cannot be on open array", -errSizeTooBig: "computing the type's size produced an overflow", -errInheritanceOnlyWithEnums: "inheritance only works with an enum", -errIllegalRecursionInTypeX:, -errCannotInstantiateX: "cannot instantiate: '$1'", -errTypeMismatch: "type mismatch: got <", -errButExpected: "but expected one of: ", -errButExpectedX: "but expected '$1'", -errAmbiguousCallXYZ: "ambiguous call; both $1 and $2 match for: $3", -errWrongNumberOfArguments: "wrong number of arguments", -errWrongNumberOfArgumentsInCall: "wrong number of arguments in call to '$1'", -errMissingGenericParamsForTemplate: "'$1' has unspecified generic parameters", -errXCannotBePassedToProcVar: , -, -errImplOfXexpected: , - -errIllegalConvFromXtoY: , -errCannotBindXTwice: "cannot bind parameter '$1' twice", -errInvalidOrderInArrayConstructor: , -errInvalidOrderInEnumX: "invalid order in enum '$1'", -errEnumXHasHoles: "enum '$1' has holes", -errExceptExpected: "'except' or 'finally' expected", -errInvalidTry: "after catch all 'except' or 'finally' no section may follow", -errOptionExpected: , -errXisNoLabel: "'$1' is not a label", -errNotAllCasesCovered: "not all cases are covered", -errUnknownSubstitionVar: "unknown substitution variable: '$1'", -errComplexStmtRequiresInd: "complex statement requires indentation", -errXisNotCallable: "'$1' is not callable", -errNoPragmasAllowedForX: "no pragmas allowed for $1", -, -errInvalidParamKindX: "invalid param kind: '$1'", -errDefaultArgumentInvalid: "default argument invalid", -errNamedParamHasToBeIdent: "named parameter has to be an identifier", -errNoReturnTypeForX: "no return type allowed for $1", -errConvNeedsOneArg: "a type conversion needs exactly one argument", -errInvalidPragmaX: , -errXNotAllowedHere: "$1 not allowed here", -errXisNoType: "invalid type: '$1'", -errCircumNeedsPointer: "'[]' needs a pointer or reference type", -errInvalidExpression: "invalid expression", -errInvalidExpressionX: "invalid expression: '$1'", -errEnumHasNoValueX: "enum has no value '$1'", -, -errNoCommand: "no command given", -errInvalidCommandX: "invalid command: '$1'", -errXNeedsParamObjectType: , -errTemplateInstantiationTooNested: "template instantiation too nested, try --evalTemplateLimit:N", -errMacroInstantiationTooNested: "macro instantiation too nested, try --evalMacroLimit:N", -errInstantiationFrom: "template/generic instantiation from here", -errInvalidIndexValueForTuple: "invalid index value for tuple subscript", -errCommandExpectsFilename: "command expects a filename argument", -errMainModuleMustBeSpecified: "please, specify a main module in the project configuration file", -errXExpected: "'$1' expected", -, -errCastToANonConcreteType: "cannot cast to a non concrete type: '$1'", -errInvalidSectionStart: "invalid section start", -errGridTableNotImplemented: "grid table is not implemented", -errGeneralParseError: "general parse error", -errNewSectionExpected: "new section expected", -errWhitespaceExpected: "whitespace expected, got '$1'", -errXisNoValidIndexFile: "'$1' is no valid index file", -errCannotRenderX: "cannot render reStructuredText element '$1'", -errVarVarTypeNotAllowed: , -errInstantiateXExplicitly: "instantiate '$1' explicitly", -errOnlyACallOpCanBeDelegator: , -errUsingNoSymbol: "'$1' is not a variable, constant or a proc name", -errMacroBodyDependsOnGenericTypes: "the macro body cannot be compiled, " & - "because the parameter '$1' has a generic type", -errDestructorNotGenericEnough: "Destructor signature is too specific. " & - "A destructor must be associated will all instantiations of a generic type", -errInlineIteratorsAsProcParams: "inline iterators can be used as parameters only for " & - "templates, macros and other inline iterators", -errXExpectsTwoArguments: "'$1' expects two arguments", -errXExpectsObjectTypes: "'$1' expects object types", -errXcanNeverBeOfThisSubtype: "'$1' can never be of this subtype", -errTooManyIterations: "interpretation requires too many iterations; " & - "if you are sure this is not a bug in your code edit " & - "compiler/vmdef.MaxLoopIterations and rebuild the compiler", -errFieldXNotFound: "field '$1' cannot be found", -errInvalidConversionFromTypeX: "invalid conversion from type '$1'", -errAssertionFailed: "assertion failed", -errCannotGenerateCodeForX: "cannot generate code for '$1'", -errXRequiresOneArgument: "$1 requires one parameter", -errUnhandledExceptionX: "unhandled exception: $1", -errCyclicTree: "macro returned a cyclic abstract syntax tree", -errXisNoMacroOrTemplate: "'$1' is no macro or template", -errXhasSideEffects: "'$1' can have side effects", -errWrongSymbolX:, -errIllegalCaptureX: "illegal capture '$1'", -errXCannotBeClosure: "'$1' cannot have 'closure' calling convention", -, -]# diff --git a/compiler/depends.nim b/compiler/depends.nim index 732404232..38b84aafc 100644 --- a/compiler/depends.nim +++ b/compiler/depends.nim @@ -14,8 +14,6 @@ import from modulegraphs import ModuleGraph -proc generateDot*(project: string) - type TGen = object of TPassContext module*: PSym @@ -44,8 +42,8 @@ proc addDotDependency(c: PPassContext, n: PNode): PNode = else: discard -proc generateDot(project: string) = - writeRope("digraph $1 {$n$2}$n" % [ +proc generateDot*(project: string) = + discard writeRope("digraph $1 {$n$2}$n" % [ rope(changeFileExt(extractFilename(project), "")), gDotGraph], changeFileExt(project, "dot")) diff --git a/compiler/destroyer.nim b/compiler/destroyer.nim index 31c735794..0dc90b552 100644 --- a/compiler/destroyer.nim +++ b/compiler/destroyer.nim @@ -132,6 +132,7 @@ type destroys, topLevelVars: PNode toDropBit: Table[int, PSym] graph: ModuleGraph + emptyNode: PNode proc getTemp(c: var Con; typ: PType; info: TLineInfo): PNode = # XXX why are temps fields in an object here? @@ -243,7 +244,7 @@ proc genDestroy(c: Con; t: PType; dest: PNode): PNode = genOp(t.destructor, "=destroy") proc addTopVar(c: var Con; v: PNode) = - c.topLevelVars.add newTree(nkIdentDefs, v, emptyNode, emptyNode) + c.topLevelVars.add newTree(nkIdentDefs, v, c.emptyNode, c.emptyNode) proc dropBit(c: var Con; s: PSym): PSym = result = c.toDropBit.getOrDefault(s.id) @@ -253,7 +254,7 @@ proc registerDropBit(c: var Con; s: PSym) = let result = newSym(skTemp, getIdent(s.name.s & "_AliveBit"), c.owner, s.info) result.typ = getSysType(c.graph, s.info, tyBool) let trueVal = newIntTypeNode(nkIntLit, 1, result.typ) - c.topLevelVars.add newTree(nkIdentDefs, newSymNode result, emptyNode, trueVal) + c.topLevelVars.add newTree(nkIdentDefs, newSymNode result, c.emptyNode, trueVal) c.toDropBit[s.id] = result # generate: # if not sinkParam_AliveBit: `=destroy`(sinkParam) @@ -328,7 +329,7 @@ proc destructiveMoveVar(n: PNode; c: var Con): PNode = var vpart = newNodeI(nkIdentDefs, tempAsNode.info, 3) vpart.sons[0] = tempAsNode - vpart.sons[1] = ast.emptyNode + vpart.sons[1] = c.emptyNode vpart.sons[2] = n add(v, vpart) @@ -434,6 +435,7 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode = c.topLevelVars = newNodeI(nkVarSection, n.info) c.toDropBit = initTable[int, PSym]() c.graph = g + c.emptyNode = newNodeI(nkEmpty, n.info) let cfg = constructCfg(owner, n) shallowCopy(c.g, cfg) c.jumpTargets = initIntSet() diff --git a/compiler/dfa.nim b/compiler/dfa.nim index 0fd706178..aab1d9b4b 100644 --- a/compiler/dfa.nim +++ b/compiler/dfa.nim @@ -54,7 +54,7 @@ type blocks: seq[TBlock] proc debugInfo(info: TLineInfo): string = - result = info.toFilename & ":" & $info.line + result = $info.line #info.toFilename & ":" & $info.line proc codeListing(c: ControlFlowGraph, result: var string, start=0; last = -1) = # for debugging purposes @@ -87,7 +87,8 @@ proc echoCfg*(c: ControlFlowGraph; start=0; last = -1) {.deprecated.} = ## echos the ControlFlowGraph for debugging purposes. var buf = "" codeListing(c, buf, start, last) - echo buf + when declared(echo): + echo buf proc forkI(c: var Con; n: PNode): TPosition = result = TPosition(c.code.len) diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 7ab2f0eee..c40d524d8 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -190,7 +190,7 @@ proc genComment(d: PDoc, n: PNode): string = result = "" var dummyHasToc: bool if n.comment != nil: - renderRstToOut(d[], parseRst(n.comment, toFilename(n.info), + renderRstToOut(d[], parseRst(n.comment, toFilename(d.conf, n.info), toLinenumber(n.info), toColumn(n.info), dummyHasToc, d.options, d.conf), result) @@ -307,13 +307,13 @@ when false: result = findDocComment(n.sons[i]) if result != nil: return - proc extractDocComment*(s: PSym, d: PDoc = nil): string = + proc extractDocComment*(s: PSym, d: PDoc): string = let n = findDocComment(s.ast) result = "" if not n.isNil: if not d.isNil: var dummyHasToc: bool - renderRstToOut(d[], parseRst(n.comment, toFilename(n.info), + renderRstToOut(d[], parseRst(n.comment, toFilename(d.conf, n.info), toLinenumber(n.info), toColumn(n.info), dummyHasToc, d.options + {roSkipPounds}), result) @@ -502,7 +502,7 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) = let docItemSeeSrc = getConfigVar(d.conf, "doc.item.seesrc") if docItemSeeSrc.len > 0: let cwd = canonicalizePath(d.conf, getCurrentDir()) - var path = n.info.toFullPath + var path = toFullPath(d.conf, n.info) if path.startsWith(cwd): path = path[cwd.len+1 .. ^1].replace('\\', '/') let gitUrl = getConfigVar(d.conf, "git.url") @@ -777,10 +777,16 @@ proc getOutFile2(conf: ConfigRef; filename, ext, dir: string): string = proc writeOutput*(d: PDoc, filename, outExt: string, useWarning = false) = var content = genOutFile(d) + var success = true + var filename: string if optStdout in d.conf.globalOptions: writeRope(stdout, content) + filename = "<stdout>" else: - writeRope(content, getOutFile2(d.conf, filename, outExt, "htmldocs"), useWarning) + filename = getOutFile2(d.conf, filename, outExt, "htmldocs") + success = writeRope(content, filename) + if not success: + rawMessage(d.conf, if useWarning: warnCannotOpenFile else: errCannotOpenFile, filename) proc writeOutputJson*(d: PDoc, filename, outExt: string, useWarning = false) = @@ -861,7 +867,9 @@ proc commandJson*(conf: ConfigRef) = writeRope(stdout, content) else: #echo getOutFile(gProjectFull, JsonExt) - writeRope(content, getOutFile(conf, conf.projectFull, JsonExt), useWarning = false) + let filename = getOutFile(conf, conf.projectFull, JsonExt) + if not writeRope(content, filename): + rawMessage(conf, errCannotOpenFile, filename) proc commandTags*(conf: ConfigRef) = var ast = parseFile(conf.projectMainIdx.FileIndex, newIdentCache(), conf) @@ -876,7 +884,9 @@ proc commandTags*(conf: ConfigRef) = writeRope(stdout, content) else: #echo getOutFile(gProjectFull, TagsExt) - writeRope(content, getOutFile(conf, conf.projectFull, TagsExt), useWarning = false) + let filename = getOutFile(conf, conf.projectFull, TagsExt) + if not writeRope(content, filename): + rawMessage(conf, errCannotOpenFile, filename) proc commandBuildIndex*(conf: ConfigRef) = var content = mergeIndexes(conf.projectFull).rope @@ -887,4 +897,6 @@ proc commandBuildIndex*(conf: ConfigRef) = ["Index".rope, nil, nil, rope(getDateStr()), rope(getClockStr()), content, nil, nil, nil]) # no analytics because context is not available - writeRope(code, getOutFile(conf, "theindex", HtmlExt)) + let filename = getOutFile(conf, "theindex", HtmlExt) + if not writeRope(code, filename): + rawMessage(conf, errCannotOpenFile, filename) diff --git a/compiler/docgen2.nim b/compiler/docgen2.nim index d9a73e1cd..5e36cd356 100644 --- a/compiler/docgen2.nim +++ b/compiler/docgen2.nim @@ -35,11 +35,11 @@ template closeImpl(body: untyped) {.dirty.} = proc close(graph: ModuleGraph; p: PPassContext, n: PNode): PNode = closeImpl: - writeOutput(g.doc, g.module.filename, HtmlExt, useWarning) + writeOutput(g.doc, toFilename(graph.config, FileIndex g.module.position), HtmlExt, useWarning) proc closeJson(graph: ModuleGraph; p: PPassContext, n: PNode): PNode = closeImpl: - writeOutputJson(g.doc, g.module.filename, ".json", useWarning) + writeOutputJson(g.doc, toFilename(graph.config, FileIndex g.module.position), ".json", useWarning) proc processNode(c: PPassContext, n: PNode): PNode = result = n @@ -55,7 +55,7 @@ proc myOpen(graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext = var g: PGen new(g) g.module = module - var d = newDocumentor(module.filename, graph.config) + var d = newDocumentor(toFilename(graph.config, FileIndex module.position), graph.config) d.hasToc = true g.doc = d result = g diff --git a/compiler/evalffi.nim b/compiler/evalffi.nim index 0e3d0609d..e863c8995 100644 --- a/compiler/evalffi.nim +++ b/compiler/evalffi.nim @@ -442,7 +442,7 @@ proc callForeignFunction*(call: PNode): PNode = libffi.call(cif, fn, retVal, args) if retVal.isNil: - result = emptyNode + result = newNode(nkEmpty) else: result = unpack(retVal, typ.sons[0], nil) result.info = call.info @@ -484,7 +484,7 @@ proc callForeignFunction*(fn: PNode, fntyp: PType, libffi.call(cif, fn, retVal, cargs) if retVal.isNil: - result = emptyNode + result = newNode(nkEmpty) else: result = unpack(retVal, fntyp.sons[0], nil) result.info = info diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index 01c56ec9c..a1b5e731c 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -104,7 +104,7 @@ proc evalTemplateArgs(n: PNode, s: PSym; conf: ConfigRef; fromHlo: bool): PNode let default = s.typ.n.sons[i].sym.ast if default.isNil or default.kind == nkEmpty: localError(conf, n.info, errWrongNumberOfArguments) - addSon(result, ast.emptyNode) + addSon(result, newNodeI(nkEmpty, n.info)) else: addSon(result, default.copyTree) diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 3f0e6f611..23db9cbe1 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -16,12 +16,7 @@ import ropes, os, strutils, osproc, platform, condsyms, options, msgs, configuration, std / sha1, streams -#from debuginfo import writeDebugInfo - type - TSystemCC* = enum - ccNone, ccGcc, ccLLVM_Gcc, ccCLang, ccLcc, ccBcc, ccDmc, ccWcc, ccVcc, - ccTcc, ccPcc, ccUcc, ccIcl, ccIcc TInfoCCProp* = enum # properties of the C compiler: hasSwitchRange, # CC allows ranges in switch statements (GNU C) hasComputedGoto, # CC has computed goto (GNU C extension) @@ -336,37 +331,8 @@ const hExt* = ".h" -var - cCompiler* = ccGcc # the used compiler - gMixedMode*: bool # true if some module triggered C++ codegen - cIncludes*: seq[string] = @[] # directories to search for included files - cLibs*: seq[string] = @[] # directories to search for lib files - cLinkedLibs*: seq[string] = @[] # libraries to link - -# implementation - -proc libNameTmpl(): string {.inline.} = - result = if targetOS == osWindows: "$1.lib" else: "lib$1.a" - -type - CfileFlag* {.pure.} = enum - Cached, ## no need to recompile this time - External ## file was introduced via .compile pragma - - Cfile* = object - cname*, obj*: string - flags*: set[CFileFlag] - CfileList = seq[Cfile] - -var - externalToLink: seq[string] = @[] # files to link in addition to the file - # we compiled - linkOptionsCmd: string = "" - compileOptionsCmd: seq[string] = @[] - linkOptions: string = "" - compileOptions: string = "" - ccompilerpath: string = "" - toCompile: CfileList = @[] +proc libNameTmpl(conf: ConfigRef): string {.inline.} = + result = if conf.target.targetOS == osWindows: "$1.lib" else: "lib$1.a" proc nameToCC*(name: string): TSystemCC = ## Returns the kind of compiler referred to by `name`, or ccNone @@ -389,10 +355,10 @@ proc getConfigVar(conf: ConfigRef; c: TSystemCC, suffix: string): string = else: suffix - if (platform.hostOS != targetOS or platform.hostCPU != targetCPU) and + if (conf.target.hostOS != conf.target.targetOS or conf.target.hostCPU != conf.target.targetCPU) and optCompileOnly notin conf.globalOptions: - let fullCCname = platform.CPU[targetCPU].name & '.' & - platform.OS[targetOS].name & '.' & + let fullCCname = platform.CPU[conf.target.targetCPU].name & '.' & + platform.OS[conf.target.targetOS].name & '.' & CC[c].name & fullSuffix result = getConfigVar(conf, fullCCname) if result.len == 0: @@ -402,40 +368,40 @@ proc getConfigVar(conf: ConfigRef; c: TSystemCC, suffix: string): string = result = getConfigVar(conf, CC[c].name & fullSuffix) proc setCC*(conf: ConfigRef; ccname: string; info: TLineInfo) = - cCompiler = nameToCC(ccname) - if cCompiler == ccNone: + conf.cCompiler = nameToCC(ccname) + if conf.cCompiler == ccNone: localError(conf, info, "unknown C compiler: '$1'" % ccname) - compileOptions = getConfigVar(conf, cCompiler, ".options.always") - linkOptions = "" - ccompilerpath = getConfigVar(conf, cCompiler, ".path") + conf.compileOptions = getConfigVar(conf, conf.cCompiler, ".options.always") + conf.linkOptions = "" + conf.ccompilerpath = getConfigVar(conf, conf.cCompiler, ".path") for i in countup(low(CC), high(CC)): undefSymbol(conf.symbols, CC[i].name) - defineSymbol(conf.symbols, CC[cCompiler].name) + defineSymbol(conf.symbols, CC[conf.cCompiler].name) proc addOpt(dest: var string, src: string) = if len(dest) == 0 or dest[len(dest)-1] != ' ': add(dest, " ") add(dest, src) proc addLinkOption*(conf: ConfigRef; option: string) = - addOpt(linkOptions, option) + addOpt(conf.linkOptions, option) proc addCompileOption*(conf: ConfigRef; option: string) = - if strutils.find(compileOptions, option, 0) < 0: - addOpt(compileOptions, option) + if strutils.find(conf.compileOptions, option, 0) < 0: + addOpt(conf.compileOptions, option) proc addLinkOptionCmd*(conf: ConfigRef; option: string) = - addOpt(linkOptionsCmd, option) + addOpt(conf.linkOptionsCmd, option) proc addCompileOptionCmd*(conf: ConfigRef; option: string) = - compileOptionsCmd.add(option) + conf.compileOptionsCmd.add(option) proc initVars*(conf: ConfigRef) = # we need to define the symbol here, because ``CC`` may have never been set! for i in countup(low(CC), high(CC)): undefSymbol(conf.symbols, CC[i].name) - defineSymbol(conf.symbols, CC[cCompiler].name) - addCompileOption(conf, getConfigVar(conf, cCompiler, ".options.always")) + defineSymbol(conf.symbols, CC[conf.cCompiler].name) + addCompileOption(conf, getConfigVar(conf, conf.cCompiler, ".options.always")) #addLinkOption(getConfigVar(cCompiler, ".options.linker")) - if len(ccompilerpath) == 0: - ccompilerpath = getConfigVar(conf, cCompiler, ".path") + if len(conf.ccompilerpath) == 0: + conf.ccompilerpath = getConfigVar(conf, conf.cCompiler, ".path") proc completeCFilePath*(conf: ConfigRef; cfile: string, createSubDir: bool = true): string = result = completeGeneratedFilePath(conf, cfile, createSubDir) @@ -445,21 +411,21 @@ proc toObjFile*(conf: ConfigRef; filename: string): string = #if filename.endsWith(".cpp"): # result = changeFileExt(filename, "cpp." & CC[cCompiler].objExt) #else: - result = changeFileExt(filename, CC[cCompiler].objExt) + result = changeFileExt(filename, CC[conf.cCompiler].objExt) proc addFileToCompile*(conf: ConfigRef; cf: Cfile) = - toCompile.add(cf) + conf.toCompile.add(cf) proc resetCompilationLists*(conf: ConfigRef) = - toCompile.setLen 0 + conf.toCompile.setLen 0 ## XXX: we must associate these with their originating module # when the module is loaded/unloaded it adds/removes its items # That's because we still need to hash check the external files # Maybe we can do that in checkDep on the other hand? - externalToLink.setLen 0 + conf.externalToLink.setLen 0 proc addExternalFileToLink*(conf: ConfigRef; filename: string) = - externalToLink.insert(filename, 0) + conf.externalToLink.insert(filename, 0) proc execWithEcho(conf: ConfigRef; cmd: string, msg = hintExecuting): int = rawMessage(conf, msg, cmd) @@ -472,9 +438,12 @@ proc execExternalProgram*(conf: ConfigRef; cmd: string, msg = hintExecuting) = proc generateScript(conf: ConfigRef; projectFile: string, script: Rope) = let (dir, name, ext) = splitFile(projectFile) - writeRope(script, getNimcacheDir(conf) / addFileExt("compile_" & name, - platform.OS[targetOS].scriptExt)) - copyFile(conf.libpath / "nimbase.h", getNimcacheDir(conf) / "nimbase.h") + let filename = getNimcacheDir(conf) / addFileExt("compile_" & name, + platform.OS[conf.target.targetOS].scriptExt) + if writeRope(script, filename): + copyFile(conf.libpath / "nimbase.h", getNimcacheDir(conf) / "nimbase.h") + else: + rawMessage(conf, errGenerated, "could not write to file: " & filename) proc getOptSpeed(conf: ConfigRef; c: TSystemCC): string = result = getConfigVar(conf, c, ".options.speed") @@ -499,8 +468,8 @@ proc noAbsolutePaths(conf: ConfigRef): bool {.inline.} = result = conf.globalOptions * {optGenScript, optGenMapping} != {} proc cFileSpecificOptions(conf: ConfigRef; cfilename: string): string = - result = compileOptions - for option in compileOptionsCmd: + result = conf.compileOptions + for option in conf.compileOptionsCmd: if strutils.find(result, option, 0) < 0: addOpt(result, option) @@ -508,15 +477,15 @@ proc cFileSpecificOptions(conf: ConfigRef; cfilename: string): string = if optCDebug in conf.globalOptions: let key = trunk & ".debug" if existsConfigVar(conf, key): addOpt(result, getConfigVar(conf, key)) - else: addOpt(result, getDebug(conf, cCompiler)) + else: addOpt(result, getDebug(conf, conf.cCompiler)) if optOptimizeSpeed in conf.options: let key = trunk & ".speed" if existsConfigVar(conf, key): addOpt(result, getConfigVar(conf, key)) - else: addOpt(result, getOptSpeed(conf, cCompiler)) + else: addOpt(result, getOptSpeed(conf, conf.cCompiler)) elif optOptimizeSize in conf.options: let key = trunk & ".size" if existsConfigVar(conf, key): addOpt(result, getConfigVar(conf, key)) - else: addOpt(result, getOptSize(conf, cCompiler)) + else: addOpt(result, getOptSize(conf, conf.cCompiler)) let key = trunk & ".always" if existsConfigVar(conf, key): addOpt(result, getConfigVar(conf, key)) @@ -524,15 +493,15 @@ proc getCompileOptions(conf: ConfigRef): string = result = cFileSpecificOptions(conf, "__dummy__") proc getLinkOptions(conf: ConfigRef): string = - result = linkOptions & " " & linkOptionsCmd & " " - for linkedLib in items(cLinkedLibs): - result.add(CC[cCompiler].linkLibCmd % linkedLib.quoteShell) - for libDir in items(cLibs): - result.add(join([CC[cCompiler].linkDirCmd, libDir.quoteShell])) + result = conf.linkOptions & " " & conf.linkOptionsCmd & " " + for linkedLib in items(conf.cLinkedLibs): + result.add(CC[conf.cCompiler].linkLibCmd % linkedLib.quoteShell) + for libDir in items(conf.cLibs): + result.add(join([CC[conf.cCompiler].linkDirCmd, libDir.quoteShell])) proc needsExeExt(conf: ConfigRef): bool {.inline.} = - result = (optGenScript in conf.globalOptions and targetOS == osWindows) or - (platform.hostOS == osWindows) + result = (optGenScript in conf.globalOptions and conf.target.targetOS == osWindows) or + (conf.target.hostOS == osWindows) proc getCompilerExe(conf: ConfigRef; compiler: TSystemCC; cfile: string): string = result = if conf.cmd == cmdCompileToCpp and not cfile.endsWith(".c"): @@ -546,18 +515,18 @@ proc getCompilerExe(conf: ConfigRef; compiler: TSystemCC; cfile: string): string proc getLinkerExe(conf: ConfigRef; compiler: TSystemCC): string = result = if CC[compiler].linkerExe.len > 0: CC[compiler].linkerExe - elif gMixedMode and conf.cmd != cmdCompileToCpp: CC[compiler].cppCompiler + elif optMixedMode in conf.globalOptions and conf.cmd != cmdCompileToCpp: CC[compiler].cppCompiler else: getCompilerExe(conf, compiler, "") proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile): string = - var c = cCompiler + var c = conf.cCompiler var options = cFileSpecificOptions(conf, cfile.cname) var exe = getConfigVar(conf, c, ".exe") if exe.len == 0: exe = getCompilerExe(conf, c, cfile.cname) if needsExeExt(conf): exe = addFileExt(exe, "exe") if optGenDynLib in conf.globalOptions and - ospNeedsPIC in platform.OS[targetOS].props: + ospNeedsPIC in platform.OS[conf.target.targetOS].props: add(options, ' ' & CC[c].pic) var includeCmd, compilePattern: string @@ -565,10 +534,10 @@ proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile): string = # compute include paths: includeCmd = CC[c].includeCmd & quoteShell(conf.libpath) - for includeDir in items(cIncludes): + for includeDir in items(conf.cIncludes): includeCmd.add(join([CC[c].includeCmd, includeDir.quoteShell])) - compilePattern = joinPath(ccompilerpath, exe) + compilePattern = joinPath(conf.ccompilerpath, exe) else: includeCmd = "" compilePattern = getCompilerExe(conf, c, cfile.cname) @@ -604,9 +573,9 @@ proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile): string = proc footprint(conf: ConfigRef; cfile: Cfile): SecureHash = result = secureHash( $secureHashFile(cfile.cname) & - platform.OS[targetOS].name & - platform.CPU[targetCPU].name & - extccomp.CC[extccomp.cCompiler].name & + platform.OS[conf.target.targetOS].name & + platform.CPU[conf.target.targetCPU].name & + extccomp.CC[conf.cCompiler].name & getCompileCFileCmd(conf, cfile)) proc externalFileChanged(conf: ConfigRef; cfile: Cfile): bool = @@ -630,7 +599,7 @@ proc externalFileChanged(conf: ConfigRef; cfile: Cfile): bool = proc addExternalFileToCompile*(conf: ConfigRef; c: var Cfile) = if optForceFullMake notin conf.globalOptions and not externalFileChanged(conf, c): c.flags.incl CfileFlag.Cached - toCompile.add(c) + conf.toCompile.add(c) proc addExternalFileToCompile*(conf: ConfigRef; filename: string) = var c = Cfile(cname: filename, @@ -650,7 +619,7 @@ proc compileCFile(conf: ConfigRef; list: CFileList, script: var Rope, cmds: var add(prettyCmds, "CC: " & name) if optGenScript in conf.globalOptions: add(script, compileCmd) - add(script, tnl) + add(script, "\n") proc getLinkCmd(conf: ConfigRef; projectfile, objfiles: string): string = if optGenStaticLib in conf.globalOptions: @@ -660,24 +629,24 @@ proc getLinkCmd(conf: ConfigRef; projectfile, objfiles: string): string = if not libname.isAbsolute(): libname = getCurrentDir() / libname else: - libname = (libNameTmpl() % splitFile(conf.projectName).name) - result = CC[cCompiler].buildLib % ["libfile", libname, + libname = (libNameTmpl(conf) % splitFile(conf.projectName).name) + result = CC[conf.cCompiler].buildLib % ["libfile", libname, "objfiles", objfiles] else: - var linkerExe = getConfigVar(conf, cCompiler, ".linkerexe") - if len(linkerExe) == 0: linkerExe = getLinkerExe(conf, cCompiler) + var linkerExe = getConfigVar(conf, conf.cCompiler, ".linkerexe") + if len(linkerExe) == 0: linkerExe = getLinkerExe(conf, conf.cCompiler) # bug #6452: We must not use ``quoteShell`` here for ``linkerExe`` if needsExeExt(conf): linkerExe = addFileExt(linkerExe, "exe") if noAbsolutePaths(conf): result = linkerExe - else: result = joinPath(ccompilerpath, linkerExe) - let buildgui = if optGenGuiApp in conf.globalOptions: CC[cCompiler].buildGui + else: result = joinPath(conf.cCompilerpath, linkerExe) + let buildgui = if optGenGuiApp in conf.globalOptions: CC[conf.cCompiler].buildGui else: "" var exefile, builddll: string if optGenDynLib in conf.globalOptions: - exefile = platform.OS[targetOS].dllFrmt % splitFile(projectfile).name - builddll = CC[cCompiler].buildDll + exefile = platform.OS[conf.target.targetOS].dllFrmt % splitFile(projectfile).name + builddll = CC[conf.cCompiler].buildDll else: - exefile = splitFile(projectfile).name & platform.OS[targetOS].exeExt + exefile = splitFile(projectfile).name & platform.OS[conf.target.targetOS].exeExt builddll = "" if conf.outFile.len > 0: exefile = conf.outFile.expandTilde @@ -691,10 +660,10 @@ proc getLinkCmd(conf: ConfigRef; projectfile, objfiles: string): string = writeDebugInfo(exefile.changeFileExt("ndb")) exefile = quoteShell(exefile) let linkOptions = getLinkOptions(conf) & " " & - getConfigVar(conf, cCompiler, ".options.linker") - var linkTmpl = getConfigVar(conf, cCompiler, ".linkTmpl") + getConfigVar(conf, conf.cCompiler, ".options.linker") + var linkTmpl = getConfigVar(conf, conf.cCompiler, ".linkTmpl") if linkTmpl.len == 0: - linkTmpl = CC[cCompiler].linkTmpl + linkTmpl = CC[conf.cCompiler].linkTmpl result = quoteShell(result % ["builddll", builddll, "buildgui", buildgui, "options", linkOptions, "objfiles", objfiles, "exefile", exefile, "nim", getPrefixDir(conf), "lib", conf.libpath]) @@ -765,19 +734,20 @@ proc callCCompiler*(conf: ConfigRef; projectfile: string) = var cmds: TStringSeq = @[] var prettyCmds: TStringSeq = @[] let prettyCb = proc (idx: int) = - echo prettyCmds[idx] - compileCFile(conf, toCompile, script, cmds, prettyCmds) + when declared(echo): + echo prettyCmds[idx] + compileCFile(conf, conf.toCompile, script, cmds, prettyCmds) if optCompileOnly notin conf.globalOptions: execCmdsInParallel(conf, cmds, prettyCb) if optNoLinking notin conf.globalOptions: # call the linker: var objfiles = "" - for it in externalToLink: + for it in conf.externalToLink: let objFile = if noAbsolutePaths(conf): it.extractFilename else: it add(objfiles, ' ') add(objfiles, quoteShell( - addFileExt(objFile, CC[cCompiler].objExt))) - for x in toCompile: + addFileExt(objFile, CC[conf.cCompiler].objExt))) + for x in conf.toCompile: let objFile = if noAbsolutePaths(conf): x.obj.extractFilename else: x.obj add(objfiles, ' ') add(objfiles, quoteShell(objFile)) @@ -789,7 +759,7 @@ proc callCCompiler*(conf: ConfigRef; projectfile: string) = linkCmd = "" if optGenScript in conf.globalOptions: add(script, linkCmd) - add(script, tnl) + add(script, "\n") generateScript(conf, projectfile, script) #from json import escapeJson @@ -824,7 +794,7 @@ proc writeJsonBuildInstructions*(conf: ConfigRef; projectfile: string) = for it in llist: let objfile = if noAbsolutePaths(conf): it.extractFilename else: it - let objstr = addFileExt(objfile, CC[cCompiler].objExt) + let objstr = addFileExt(objfile, CC[conf.cCompiler].objExt) add(objfiles, ' ') add(objfiles, objstr) if pastStart: lit ",\L" @@ -848,11 +818,11 @@ proc writeJsonBuildInstructions*(conf: ConfigRef; projectfile: string) = var f: File if open(f, jsonFile, fmWrite): lit "{\"compile\":[\L" - cfiles(conf, f, buf, toCompile, false) + cfiles(conf, f, buf, conf.toCompile, false) lit "],\L\"link\":[\L" var objfiles = "" # XXX add every file here that is to link - linkfiles(conf, f, buf, objfiles, toCompile, externalToLink) + linkfiles(conf, f, buf, objfiles, conf.toCompile, conf.externalToLink) lit "],\L\"linkcmd\": " str getLinkCmd(conf, projectfile, objfiles) @@ -877,14 +847,16 @@ proc runJsonBuildInstructions*(conf: ConfigRef; projectfile: string) = add(prettyCmds, "CC: " & name) let prettyCb = proc (idx: int) = - echo prettyCmds[idx] + when declared(echo): + echo prettyCmds[idx] execCmdsInParallel(conf, cmds, prettyCb) let linkCmd = data["linkcmd"] doAssert linkCmd.kind == JString execLinkCmd(conf, linkCmd.getStr) except: - echo getCurrentException().getStackTrace() + when declared(echo): + echo getCurrentException().getStackTrace() quit "error evaluating JSON file: " & jsonFile proc genMappingFiles(conf: ConfigRef; list: CFileList): Rope = @@ -894,16 +866,18 @@ proc genMappingFiles(conf: ConfigRef; list: CFileList): Rope = proc writeMapping*(conf: ConfigRef; symbolMapping: Rope) = if optGenMapping notin conf.globalOptions: return var code = rope("[C_Files]\n") - add(code, genMappingFiles(conf, toCompile)) + add(code, genMappingFiles(conf, conf.toCompile)) add(code, "\n[C_Compiler]\nFlags=") add(code, strutils.escape(getCompileOptions(conf))) add(code, "\n[Linker]\nFlags=") add(code, strutils.escape(getLinkOptions(conf) & " " & - getConfigVar(conf, cCompiler, ".options.linker"))) + getConfigVar(conf, conf.cCompiler, ".options.linker"))) add(code, "\n[Environment]\nlibpath=") add(code, strutils.escape(conf.libpath)) addf(code, "\n[Symbols]$n$1", [symbolMapping]) - writeRope(code, joinPath(conf.projectPath, "mapping.txt")) + let filename = joinPath(conf.projectPath, "mapping.txt") + if not writeRope(code, filename): + rawMessage(conf, errGenerated, "could not write to file: " & filename) diff --git a/compiler/gorgeimpl.nim b/compiler/gorgeimpl.nim index 44c7651bc..b175d23c5 100644 --- a/compiler/gorgeimpl.nim +++ b/compiler/gorgeimpl.nim @@ -22,7 +22,7 @@ proc readOutput(p: Process): (string, int) = result[1] = p.waitForExit proc opGorge*(cmd, input, cache: string, info: TLineInfo; conf: ConfigRef): (string, int) = - let workingDir = parentDir(info.toFullPath) + let workingDir = parentDir(toFullPath(conf, info)) if cache.len > 0:# and optForceFullMake notin gGlobalOptions: let h = secureHash(cmd & "\t" & input & "\t" & cache) let filename = options.toGeneratedFile(conf, "gorge_" & $h, "txt") diff --git a/compiler/guards.nim b/compiler/guards.nim index d39ea799b..1748254d6 100644 --- a/compiler/guards.nim +++ b/compiler/guards.nim @@ -131,8 +131,8 @@ proc neg(n: PNode; o: Operators): PNode = let eAsNode = newIntNode(nkIntLit, e.sym.position) if not inSet(n.sons[1], eAsNode): s.add eAsNode result.sons[1] = s - elif t.kind notin {tyString, tySequence} and lengthOrd(t) < 1000: - result.sons[1] = complement(n.sons[1]) + #elif t.kind notin {tyString, tySequence} and lengthOrd(t) < 1000: + # result.sons[1] = complement(n.sons[1]) else: # not ({2, 3, 4}.contains(x)) x != 2 and x != 3 and x != 4 # XXX todo @@ -208,14 +208,14 @@ proc zero(): PNode = nkIntLit.newIntNode(0) proc one(): PNode = nkIntLit.newIntNode(1) proc minusOne(): PNode = nkIntLit.newIntNode(-1) -proc lowBound*(x: PNode): PNode = - result = nkIntLit.newIntNode(firstOrd(x.typ)) +proc lowBound*(conf: ConfigRef; x: PNode): PNode = + result = nkIntLit.newIntNode(firstOrd(conf, x.typ)) result.info = x.info -proc highBound*(x: PNode; o: Operators): PNode = +proc highBound*(conf: ConfigRef; x: PNode; o: Operators): PNode = let typ = x.typ.skipTypes(abstractInst) result = if typ.kind == tyArray: - nkIntLit.newIntNode(lastOrd(typ)) + nkIntLit.newIntNode(lastOrd(conf, typ)) elif typ.kind == tySequence and x.kind == nkSym and x.sym.kind == skConst: nkIntLit.newIntNode(x.sym.ast.len-1) @@ -503,7 +503,7 @@ proc leImpliesIn(x, c, aSet: PNode): TImplication = # fact: x <= 4; question x in {56}? # --> true if every value <= 4 is in the set {56} # - var value = newIntNode(c.kind, firstOrd(x.typ)) + var value = newIntNode(c.kind, firstOrd(nil, x.typ)) # don't iterate too often: if c.intVal - value.intVal < 1000: var i, pos, neg: int @@ -520,7 +520,7 @@ proc geImpliesIn(x, c, aSet: PNode): TImplication = # --> true iff every value >= 4 is in the set {56} # var value = newIntNode(c.kind, c.intVal) - let max = lastOrd(x.typ) + let max = lastOrd(nil, x.typ) # don't iterate too often: if max - value.intVal < 1000: var i, pos, neg: int @@ -532,8 +532,8 @@ proc geImpliesIn(x, c, aSet: PNode): TImplication = elif neg == i: result = impNo proc compareSets(a, b: PNode): TImplication = - if equalSets(a, b): result = impYes - elif intersectSets(a, b).len == 0: result = impNo + if equalSets(nil, a, b): result = impYes + elif intersectSets(nil, a, b).len == 0: result = impNo proc impliesIn(fact, loc, aSet: PNode): TImplication = case fact.sons[0].sym.magic @@ -799,10 +799,10 @@ proc ple(m: TModel; a, b: PNode): TImplication = # use type information too: x <= 4 iff high(x) <= 4 if b.isValue and a.typ != nil and a.typ.isOrdinalType: - if lastOrd(a.typ) <= b.intVal: return impYes + if lastOrd(nil, a.typ) <= b.intVal: return impYes # 3 <= x iff low(x) <= 3 if a.isValue and b.typ != nil and b.typ.isOrdinalType: - if firstOrd(b.typ) <= a.intVal: return impYes + if firstOrd(nil, b.typ) <= a.intVal: return impYes # x <= x if sameTree(a, b): return impYes diff --git a/compiler/importer.nim b/compiler/importer.nim index 90e774a50..2dec05d66 100644 --- a/compiler/importer.nim +++ b/compiler/importer.nim @@ -143,8 +143,8 @@ proc myImportModule(c: PContext, n: PNode): PSym = var err = "" for i in countup(recursion, L-1): if i > recursion: err.add "\n" - err.add toFullPath(c.graph.importStack[i]) & " imports " & - toFullPath(c.graph.importStack[i+1]) + err.add toFullPath(c.config, c.graph.importStack[i]) & " imports " & + toFullPath(c.config, c.graph.importStack[i+1]) c.recursiveDep = err result = importModuleAs(c, n, gImportModule(c.graph, c.module, f, c.cache)) #echo "set back to ", L diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 25b554f7b..96f35c76b 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -537,7 +537,7 @@ proc genLineDir(p: PProc, n: PNode) = let line = toLinenumber(n.info) if optLineDir in p.options: lineF(p, "// line $2 \"$1\"$n", - [rope(toFilename(n.info)), rope(line)]) + [rope(toFilename(p.config, n.info)), rope(line)]) if {optStackTrace, optEndb} * p.options == {optStackTrace, optEndb} and ((p.prc == nil) or sfPure notin p.prc.flags): useMagic(p, "endb") @@ -606,11 +606,11 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) = var length = sonsLen(n) var catchBranchesExist = length > 1 and n.sons[i].kind == nkExceptBranch if catchBranchesExist: - add(p.body, "++excHandler;" & tnl) + add(p.body, "++excHandler;\L") var tmpFramePtr = rope"F" if optStackTrace notin p.options: tmpFramePtr = p.getTemp(true) - line(p, tmpFramePtr & " = framePtr;" & tnl) + line(p, tmpFramePtr & " = framePtr;\L") lineF(p, "try {$n", []) var a: TCompRes gen(p, n.sons[0], a) @@ -648,15 +648,15 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) = if catchBranchesExist: if not generalCatchBranchExists: useMagic(p, "reraiseException") - line(p, "else {" & tnl) - line(p, "\treraiseException();" & tnl) - line(p, "}" & tnl) + line(p, "else {\L") + line(p, "\treraiseException();\L") + line(p, "}\L") addf(p.body, "$1lastJSError = $1prevJSError;$n", [dollar]) - line(p, "} finally {" & tnl) + line(p, "} finally {\L") line(p, "framePtr = $1;$n" % [tmpFramePtr]) if i < length and n.sons[i].kind == nkFinally: genStmt(p, n.sons[i].sons[0]) - line(p, "}" & tnl) + line(p, "}\L") proc genRaiseStmt(p: PProc, n: PNode) = genLineDir(p, n) @@ -669,7 +669,7 @@ proc genRaiseStmt(p: PProc, n: PNode) = [a.rdLoc, makeJSString(typ.sym.name.s)]) else: useMagic(p, "reraiseException") - line(p, "reraiseException();" & tnl) + line(p, "reraiseException();\L") proc genCaseJS(p: PProc, n: PNode, r: var TCompRes) = var @@ -775,7 +775,7 @@ proc genAsmOrEmitStmt(p: PProc, n: PNode) = var r: TCompRes gen(p, it, r) p.body.add(r.rdLoc) - p.body.add tnl + p.body.add "\L" proc genIf(p: PProc, n: PNode, r: var TCompRes) = var cond, stmt: TCompRes @@ -798,7 +798,7 @@ proc genIf(p: PProc, n: PNode, r: var TCompRes) = p.nested: gen(p, it.sons[0], stmt) moveInto(p, stmt, r) lineF(p, "}$n", []) - line(p, repeat('}', toClose) & tnl) + line(p, repeat('}', toClose) & "\L") proc generateHeader(p: PProc, typ: PType): Rope = result = nil @@ -969,7 +969,7 @@ proc genArrayAddr(p: PProc, n: PNode, r: var TCompRes) = internalAssert p.config, a.typ != etyBaseIndex and b.typ != etyBaseIndex r.address = a.res var typ = skipTypes(m.sons[0].typ, abstractPtrs) - if typ.kind == tyArray: first = firstOrd(typ.sons[0]) + if typ.kind == tyArray: first = firstOrd(p.config, typ.sons[0]) else: first = 0 if optBoundsCheck in p.options: useMagic(p, "chckIndx") @@ -1366,7 +1366,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope = of tyBool: result = putToSeq("false", indirect) of tyArray: - let length = int(lengthOrd(t)) + let length = int(lengthOrd(p.config, t)) let e = elemType(t) let jsTyp = arrayTypeForElemType(e) if not jsTyp.isNil: @@ -1680,7 +1680,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) = of mIsNil: unaryExpr(p, n, r, "", "($1 === null)") of mEnumToStr: genRepr(p, n, r) of mNew, mNewFinalize: genNew(p, n) - of mSizeOf: r.res = rope(getSize(n.sons[1].typ)) + of mSizeOf: r.res = rope(getSize(p.config, n.sons[1].typ)) of mChr, mArrToSeq: gen(p, n.sons[1], r) # nothing to do of mOrd: genOrd(p, n, r) of mLengthStr: @@ -1901,13 +1901,13 @@ proc frameCreate(p: PProc; procname, filename: Rope): Rope = result.add p.indentLine(ropes.`%`("framePtr = F;$n", [])) proc frameDestroy(p: PProc): Rope = - result = p.indentLine rope(("framePtr = F.prev;") & tnl) + result = p.indentLine rope(("framePtr = F.prev;") & "\L") proc genProcBody(p: PProc, prc: PSym): Rope = if hasFrameInfo(p): result = frameCreate(p, makeJSString(prc.owner.name.s & '.' & prc.name.s), - makeJSString(toFilename(prc.info))) + makeJSString(toFilename(p.config, prc.info))) else: result = nil if p.beforeRetNeeded: @@ -1926,7 +1926,7 @@ proc optionaLine(p: Rope): Rope = if p == nil: return nil else: - return p & tnl + return p & "\L" proc genProc(oldProc: PProc, prc: PSym): Rope = var @@ -1968,7 +1968,7 @@ proc genProc(oldProc: PProc, prc: PSym): Rope = optionaLine(genProcBody(p, prc)), optionaLine(p.indentLine(returnStmt))] else: - result = ~tnl + result = ~"\L" if optHotCodeReloading in p.config.options: # Here, we introduce thunks that create the equivalent of a jump table @@ -2200,7 +2200,7 @@ proc genModule(p: PProc, n: PNode) = if optStackTrace in p.options: add(p.body, frameCreate(p, makeJSString("module " & p.module.module.name.s), - makeJSString(toFilename(p.module.module.info)))) + makeJSString(toFilename(p.config, p.module.module.info)))) genStmt(p, n) if optStackTrace in p.options: add(p.body, frameDestroy(p)) @@ -2262,7 +2262,7 @@ proc myClose(graph: ModuleGraph; b: PPassContext, n: PNode): PNode = if passes.skipCodegen(m.config, n): return n if sfMainModule in m.module.flags: let ext = "js" - let f = if globals.classes.len == 0: toFilename(FileIndex m.module.position) + let f = if globals.classes.len == 0: toFilename(m.config, FileIndex m.module.position) else: "nimsystem" let code = wholeCode(graph, m) let outfile = diff --git a/compiler/jstypes.nim b/compiler/jstypes.nim index f9e4246eb..d86b09a03 100644 --- a/compiler/jstypes.nim +++ b/compiler/jstypes.nim @@ -25,7 +25,7 @@ proc genObjectFields(p: PProc, typ: PType, n: PNode): Rope = else: s = nil for i in countup(0, length - 1): - if i > 0: add(s, ", " & tnl) + if i > 0: add(s, ", \L") add(s, genObjectFields(p, typ, n.sons[i])) result = ("{kind: 2, len: $1, offset: 0, " & "typ: null, name: null, sons: [$2]}") % [rope(length), s] @@ -56,15 +56,15 @@ proc genObjectFields(p: PProc, typ: PType, n: PNode): Rope = else: add(u, rope(getOrdValue(b.sons[j]))) of nkElse: - u = rope(lengthOrd(field.typ)) + u = rope(lengthOrd(p.config, field.typ)) else: internalError(p.config, n.info, "genObjectFields(nkRecCase)") - if result != nil: add(result, ", " & tnl) + if result != nil: add(result, ", \L") addf(result, "[setConstr($1), $2]", [u, genObjectFields(p, typ, lastSon(b))]) result = ("{kind: 3, offset: \"$1\", len: $3, " & "typ: $2, name: $4, sons: [$5]}") % [ mangleName(p.module, field), s, - rope(lengthOrd(field.typ)), makeJSString(field.name.s), result] + rope(lengthOrd(p.config, field.typ)), makeJSString(field.name.s), result] else: internalError(p.config, n.info, "genObjectFields") proc objHasTypeField(t: PType): bool {.inline.} = @@ -85,7 +85,7 @@ proc genObjectInfo(p: PProc, typ: PType, name: Rope) = proc genTupleFields(p: PProc, typ: PType): Rope = var s: Rope = nil for i in 0 ..< typ.len: - if i > 0: add(s, ", " & tnl) + if i > 0: add(s, ", \L") s.addf("{kind: 1, offset: \"Field$1\", len: 0, " & "typ: $2, name: \"Field$1\", sons: null}", [i.rope, genTypeInfo(p, typ.sons[i])]) @@ -106,7 +106,7 @@ proc genEnumInfo(p: PProc, typ: PType, name: Rope) = for i in countup(0, length - 1): if (typ.n.sons[i].kind != nkSym): internalError(p.config, typ.n.info, "genEnumInfo") let field = typ.n.sons[i].sym - if i > 0: add(s, ", " & tnl) + if i > 0: add(s, ", \L") let extName = if field.ast == nil: field.name.s else: field.ast.strVal addf(s, "\"$1\": {kind: 1, offset: $1, typ: $2, name: $3, len: 0, sons: null}", [rope(field.position), name, makeJSString(extName)]) diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index 773e5e29c..f9795a766 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -279,7 +279,7 @@ proc markAsClosure(g: ModuleGraph; owner: PSym; n: PNode) = let s = n.sym if illegalCapture(s): localError(g.config, n.info, "illegal capture '$1' of type <$2> which is declared here: $3" % - [s.name.s, typeToString(s.typ), $s.info]) + [s.name.s, typeToString(s.typ), g.config$s.info]) elif owner.typ.callConv notin {ccClosure, ccDefault}: localError(g.config, n.info, "illegal capture '$1' because '$2' has the calling convention: <$3>" % [s.name.s, owner.name.s, CallingConvToStr[owner.typ.callConv]]) @@ -629,7 +629,7 @@ proc transformYield(n: PNode; owner: PSym; d: DetectionPass; addSon(a, retVal) retStmt.add(a) else: - retStmt.add(emptyNode) + retStmt.add(newNodeI(nkEmpty, n.info)) var stateLabelStmt = newNodeI(nkState, n.info) stateLabelStmt.add(newIntTypeNode(nkIntLit, stateNo, @@ -923,7 +923,7 @@ proc liftForLoop*(g: ModuleGraph; body: PNode; owner: PSym): PNode = body[i].sym.kind = skLet addSon(vpart, body[i]) - addSon(vpart, ast.emptyNode) # no explicit type + addSon(vpart, newNodeI(nkEmpty, body.info)) # no explicit type if not env.isNil: call.sons[0] = makeClosure(g, call.sons[0].sym, env.newSymNode, body.info) addSon(vpart, call) diff --git a/compiler/lexer.nim b/compiler/lexer.nim index 591561987..cf23c9479 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -630,14 +630,14 @@ proc getEscapedChar(L: var TLexer, tok: var TToken) = if L.config.oldNewlines: if tok.tokType == tkCharLit: lexMessage(L, errGenerated, "\\n not allowed in character literal") - add(tok.literal, tnl) + add(tok.literal, L.config.target.tnl) else: add(tok.literal, '\L') inc(L.bufpos) of 'p', 'P': if tok.tokType == tkCharLit: lexMessage(L, errGenerated, "\\p not allowed in character literal") - add(tok.literal, tnl) + add(tok.literal, L.config.target.tnl) inc(L.bufpos) of 'r', 'R', 'c', 'C': add(tok.literal, CR) @@ -717,7 +717,7 @@ proc handleCRLF(L: var TLexer, pos: int): int = if optEmbedOrigSrc in L.config.globalOptions: let lineStart = cast[ByteAddress](L.buf) + L.lineStart let line = newString(cast[cstring](lineStart), col) - addSourceLine(L.fileIdx, line) + addSourceLine(L.config, L.fileIdx, line) case L.buf[pos] of CR: diff --git a/compiler/lookups.nim b/compiler/lookups.nim index b6d63d0bd..a67b027cb 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -86,7 +86,7 @@ proc skipAlias*(s: PSym; n: PNode; conf: ConfigRef): PSym = else: result = s.owner if conf.cmd == cmdPretty: - prettybase.replaceDeprecated(n.info, s, result) + prettybase.replaceDeprecated(conf, n.info, s, result) else: message(conf, n.info, warnDeprecated, "use " & result.name.s & " instead; " & s.name.s) @@ -100,15 +100,16 @@ proc searchInScopes*(c: PContext, s: PIdent): PSym = if result != nil: return result = nil -proc debugScopes*(c: PContext; limit=0) {.deprecated.} = - var i = 0 - for scope in walkScopes(c.currentScope): - echo "scope ", i - for h in 0 .. high(scope.symbols.data): - if scope.symbols.data[h] != nil: - echo scope.symbols.data[h].name.s - if i == limit: break - inc i +when declared(echo): + proc debugScopes*(c: PContext; limit=0) {.deprecated.} = + var i = 0 + for scope in walkScopes(c.currentScope): + echo "scope ", i + for h in 0 .. high(scope.symbols.data): + if scope.symbols.data[h] != nil: + echo scope.symbols.data[h].name.s + if i == limit: break + inc i proc searchInScopes*(c: PContext, s: PIdent, filter: TSymKinds): PSym = for scope in walkScopes(c.currentScope): @@ -147,10 +148,10 @@ type scope*: PScope inSymChoice: IntSet -proc getSymRepr*(s: PSym): string = +proc getSymRepr*(conf: ConfigRef; s: PSym): string = case s.kind of skProc, skFunc, skMethod, skConverter, skIterator: - result = getProcHeader(s) + result = getProcHeader(conf, s) else: result = s.name.s @@ -164,7 +165,8 @@ proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope) = # too many 'implementation of X' errors are annoying # and slow 'suggest' down: if missingImpls == 0: - localError(c.config, s.info, "implementation of '$1' expected" % getSymRepr(s)) + localError(c.config, s.info, "implementation of '$1' expected" % + getSymRepr(c.config, s)) inc missingImpls elif {sfUsed, sfExported} * s.flags == {} and optHints in s.options: if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam}: @@ -172,7 +174,7 @@ proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope) = # maybe they can be made skGenericParam as well. if s.typ != nil and tfImplicitTypeParam notin s.typ.flags and s.typ.kind != tyGenericParam: - message(c.config, s.info, hintXDeclaredButNotUsed, getSymRepr(s)) + message(c.config, s.info, hintXDeclaredButNotUsed, getSymRepr(c.config, s)) s = nextIter(it, scope.symbols) proc wrongRedefinition*(c: PContext; info: TLineInfo, s: string) = diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index 13336f00e..38e9800d3 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -30,8 +30,8 @@ proc newTupleAccess*(g: ModuleGraph; tup: PNode, i: int): PNode = proc addVar*(father, v: PNode) = var vpart = newNodeI(nkIdentDefs, v.info, 3) vpart.sons[0] = v - vpart.sons[1] = ast.emptyNode - vpart.sons[2] = ast.emptyNode + vpart.sons[1] = newNodeI(nkEmpty, v.info) + vpart.sons[2] = vpart[1] addSon(father, vpart) proc newAsgnStmt(le, ri: PNode): PNode = @@ -83,7 +83,7 @@ proc lowerTupleUnpackingForAsgn*(n: PNode; owner: PSym): PNode = var vpart = newNodeI(nkIdentDefs, tempAsNode.info, 3) vpart.sons[0] = tempAsNode - vpart.sons[1] = ast.emptyNode + vpart.sons[1] = newNodeI(nkEmpty, value.info) vpart.sons[2] = value addSon(v, vpart) result.add(v) @@ -104,7 +104,7 @@ proc lowerSwap*(n: PNode; owner: PSym): PNode = var vpart = newNodeI(nkIdentDefs, v.info, 3) vpart.sons[0] = tempAsNode - vpart.sons[1] = ast.emptyNode + vpart.sons[1] = newNodeI(nkEmpty, v.info) vpart.sons[2] = n[1] addSon(v, vpart) @@ -120,7 +120,7 @@ proc createObj*(g: ModuleGraph; owner: PSym, info: TLineInfo; final=true): PType else: rawAddSon(result, getCompilerProc(g, "RootObj").typ) result.n = newNodeI(nkRecList, info) - let s = newSym(skType, getIdent("Env_" & info.toFilename), + let s = newSym(skType, getIdent("Env_" & toFilename(g.config, info)), owner, info, owner.options) incl s.flags, sfAnon s.typ = result @@ -344,8 +344,8 @@ proc addLocalVar(g: ModuleGraph; varSection, varInit: PNode; owner: PSym; typ: P var vpart = newNodeI(nkIdentDefs, varSection.info, 3) vpart.sons[0] = newSymNode(result) - vpart.sons[1] = ast.emptyNode - vpart.sons[2] = if varInit.isNil: v else: ast.emptyNode + vpart.sons[1] = newNodeI(nkEmpty, varSection.info) + vpart.sons[2] = if varInit.isNil: v else: vpart[1] varSection.add vpart if varInit != nil: if useShallowCopy and typeNeedsNoDeepCopy(typ): @@ -438,7 +438,7 @@ proc createWrapperProc(g: ModuleGraph; f: PNode; threadParam, argsParam: PSym; body.add callCodegenProc(g, "barrierLeave", threadLocalBarrier.newSymNode) var params = newNodeI(nkFormalParams, f.info) - params.add emptyNode + params.add newNodeI(nkEmpty, f.info) params.add threadParam.newSymNode params.add argsParam.newSymNode @@ -454,12 +454,16 @@ proc createWrapperProc(g: ModuleGraph; f: PNode; threadParam, argsParam: PSym; let name = (if f.kind == nkSym: f.sym.name.s else: genPrefix) & "Wrapper" result = newSym(skProc, getIdent(name), argsParam.owner, f.info, argsParam.options) - result.ast = newProcNode(nkProcDef, f.info, body, params, newSymNode(result)) + let emptyNode = newNodeI(nkEmpty, f.info) + result.ast = newProcNode(nkProcDef, f.info, body = body, + params = params, name = newSymNode(result), pattern = emptyNode, + genericParams = emptyNode, pragmas = emptyNode, + exceptions = emptyNode) result.typ = t proc createCastExpr(argsParam: PSym; objType: PType): PNode = result = newNodeI(nkCast, argsParam.info) - result.add emptyNode + result.add newNodeI(nkEmpty, argsParam.info) result.add newSymNode(argsParam) result.typ = newType(tyPtr, objType.owner) result.typ.rawAddSon(objType) @@ -511,7 +515,7 @@ proc newIntLit*(g: ModuleGraph; info: TLineInfo; value: BiggestInt): PNode = proc genHigh*(g: ModuleGraph; n: PNode): PNode = if skipTypes(n.typ, abstractVar).kind == tyArray: - result = newIntLit(g, n.info, lastOrd(skipTypes(n.typ, abstractVar))) + result = newIntLit(g, n.info, lastOrd(g.config, skipTypes(n.typ, abstractVar))) else: result = newNodeI(nkCall, n.info, 2) result.typ = getSysType(g, n.info, tyInt) @@ -577,7 +581,7 @@ proc setupArgsForParallelism(g: ModuleGraph; n: PNode; objType: PType; scratchOb useShallowCopy=true) slice.sons[3] = threadLocal.newSymNode call.add slice - elif (let size = computeSize(argType); size < 0 or size > 16) and + elif (let size = computeSize(g.config, argType); size < 0 or size > 16) and n.getRoot != nil: # it is more efficient to pass a pointer instead: let a = genAddrOf(n) diff --git a/compiler/magicsys.nim b/compiler/magicsys.nim index b5577d961..2f021743e 100644 --- a/compiler/magicsys.nim +++ b/compiler/magicsys.nim @@ -87,7 +87,7 @@ proc getSysType*(g: ModuleGraph; info: TLineInfo; kind: TTypeKind): PType = of tyString: result = sysTypeFromName("string") of tyCString: result = sysTypeFromName("cstring") of tyPointer: result = sysTypeFromName("pointer") - of tyNil: result = newSysType(g, tyNil, ptrSize) + of tyNil: result = newSysType(g, tyNil, g.config.target.ptrSize) else: internalError(g.config, "request for typekind: " & $kind) g.sysTypes[kind] = result if result.kind != kind: @@ -139,7 +139,7 @@ proc addSonSkipIntLit*(father, son: PType) = proc setIntLitType*(g: ModuleGraph; result: PNode) = let i = result.intVal - case platform.intSize + case g.config.target.intSize of 8: result.typ = getIntLitType(g, result) of 4: if i >= low(int32) and i <= high(int32): @@ -187,7 +187,7 @@ proc registerNimScriptSymbol*(g: ModuleGraph; s: PSym) = strTableAdd(g.exposed, s) else: localError(g.config, s.info, - "symbol conflicts with other .exportNims symbol at: " & $conflict.info) + "symbol conflicts with other .exportNims symbol at: " & g.config$conflict.info) proc getNimScriptSymbol*(g: ModuleGraph; name: string): PSym = strTableGet(g.exposed, getIdent(name)) diff --git a/compiler/main.nim b/compiler/main.nim index e3f00db9e..7e0ac102c 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -35,10 +35,10 @@ proc writeDepsFile(g: ModuleGraph; project: string) = let f = open(changeFileExt(project, "deps"), fmWrite) for m in g.modules: if m != nil: - f.writeLine(toFullPath(m.position.FileIndex)) + f.writeLine(toFullPath(g.config, m.position.FileIndex)) for k in g.inclToMod.keys: if g.getModule(k).isNil: # don't repeat includes which are also modules - f.writeLine(k.toFullPath) + f.writeLine(toFullPath(g.config, k)) f.close() proc commandGenDepend(graph: ModuleGraph; cache: IdentCache) = @@ -91,7 +91,7 @@ proc commandJsonScript(graph: ModuleGraph; cache: IdentCache) = proc commandCompileToJS(graph: ModuleGraph; cache: IdentCache) = #incl(gGlobalOptions, optSafeCode) - setTarget(osJS, cpuJS) + setTarget(graph.config.target, osJS, cpuJS) #initDefines() defineSymbol(graph.config.symbols, "ecmascript") # For backward compatibility defineSymbol(graph.config.symbols, "js") diff --git a/compiler/modulegraphs.nim b/compiler/modulegraphs.nim index 460d0b4a5..d8fa4cedd 100644 --- a/compiler/modulegraphs.nim +++ b/compiler/modulegraphs.nim @@ -50,6 +50,7 @@ type exposed*: TStrTable intTypeCache*: array[-5..64, PType] opContains*, opNot*: PSym + emptyNode*: PNode proc hash*(x: FileIndex): Hash {.borrow.} @@ -79,6 +80,7 @@ proc newModuleGraph*(config: ConfigRef = nil): ModuleGraph = initStrTable(result.exposed) result.opNot = createMagic(result, "not", mNot) result.opContains = createMagic(result, "contains", mInSet) + result.emptyNode = newNode(nkEmpty) proc resetAllModules*(g: ModuleGraph) = initStrTable(packageSyms) diff --git a/compiler/modulepaths.nim b/compiler/modulepaths.nim index daa55c2ba..8d21fa755 100644 --- a/compiler/modulepaths.nim +++ b/compiler/modulepaths.nim @@ -120,7 +120,7 @@ proc getModuleName*(conf: ConfigRef; n: PNode): string = case n.kind of nkStrLit, nkRStrLit, nkTripleStrLit: try: - result = pathSubs(conf, n.strVal, n.info.toFullPath().splitFile().dir) + result = pathSubs(conf, n.strVal, toFullPath(conf, n.info).splitFile().dir) except ValueError: localError(conf, n.info, "invalid path: " & n.strVal) result = n.strVal @@ -177,7 +177,7 @@ proc getModuleName*(conf: ConfigRef; n: PNode): string = proc checkModuleName*(conf: ConfigRef; n: PNode; doLocalError=true): FileIndex = # This returns the full canonical path for a given module import let modulename = getModuleName(conf, n) - let fullPath = findModule(conf, modulename, n.info.toFullPath) + let fullPath = findModule(conf, modulename, toFullPath(conf, n.info)) if fullPath.len == 0: if doLocalError: let m = if modulename.len > 0: modulename else: $n diff --git a/compiler/modules.nim b/compiler/modules.nim index 5d1eba1f2..09d5d60b5 100644 --- a/compiler/modules.nim +++ b/compiler/modules.nim @@ -23,7 +23,7 @@ proc newModule(graph: ModuleGraph; fileIdx: FileIndex): PSym = new(result) result.id = -1 # for better error checking result.kind = skModule - let filename = fileIdx.toFullPath + let filename = toFullPath(graph.config, fileIdx) result.name = getIdent(splitFile(filename).name) if not isNimIdentifier(result.name.s): rawMessage(graph.config, errGenerated, "invalid module name: " & result.name.s) @@ -50,7 +50,9 @@ proc newModule(graph: ModuleGraph; fileIdx: FileIndex): PSym = strTableAdd(result.tab, result) # a module knows itself let existing = strTableGet(packSym.tab, result.name) if existing != nil and existing.info.fileIndex != result.info.fileIndex: - localError(graph.config, result.info, "module names need to be unique per Nimble package; module clashes with " & existing.info.fileIndex.toFullPath) + localError(graph.config, result.info, + "module names need to be unique per Nimble package; module clashes with " & + toFullPath(graph.config, existing.info.fileIndex)) # strTableIncl() for error corrections: discard strTableIncl(packSym.tab, result) @@ -73,7 +75,7 @@ proc compileModule*(graph: ModuleGraph; fileIdx: FileIndex; cache: IdentCache, f return else: discard - result.id = getModuleId(fileIdx, toFullPath(fileIdx)) + result.id = getModuleId(fileIdx, toFullPath(graph.config, fileIdx)) discard processModule(graph, result, if sfMainModule in flags and graph.config.projectIsStdin: stdin.llStreamOpen else: nil, rd, cache) diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 533d3a57f..151291ffb 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -83,7 +83,7 @@ proc makeCString*(s: string): Rope = for i in countup(0, len(s) - 1): if (i + 1) mod MaxLineLength == 0: add(res, '\"') - add(res, tnl) + add(res, '\L') add(res, '\"') add(res, toCChar(s[i])) add(res, '\"') @@ -157,13 +157,6 @@ proc newLineInfo*(fileInfoIdx: FileIndex, line, col: int): TLineInfo = proc newLineInfo*(conf: ConfigRef; filename: string, line, col: int): TLineInfo {.inline.} = result = newLineInfo(fileInfoIdx(conf, filename), line, col) -when false: - fileInfos.add(newFileInfo("", "command line")) - var gCmdLineInfo* = newLineInfo(FileIndex(0), 1, 1) - - fileInfos.add(newFileInfo("", "compilation artifact")) - var gCodegenLineInfo* = newLineInfo(FileIndex(1), 1, 1) - proc raiseRecoverableError*(msg: string) {.noinline, noreturn.} = raise newException(ERecoverableError, msg) @@ -184,7 +177,7 @@ var errorOutputs* = {eStdOut, eStdErr} writelnHook*: proc (output: string) {.closure.} - structuredErrorHook*: proc (info: TLineInfo; msg: string; severity: Severity) {.closure.} + structuredErrorHook*: proc (config: ConfigRef; info: TLineInfo; msg: string; severity: Severity) {.closure.} proc concat(strings: openarray[string]): string = var totalLen = 0 @@ -234,26 +227,26 @@ proc getInfoContext*(index: int): TLineInfo = if i >=% L: result = unknownLineInfo() else: result = msgContext[i] -template toFilename*(fileIdx: FileIndex): string = +template toFilename*(conf: ConfigRef; fileIdx: FileIndex): string = (if fileIdx.int32 < 0: "???" else: fileInfos[fileIdx.int32].projPath) -proc toFullPath*(fileIdx: FileIndex): string = +proc toFullPath*(conf: ConfigRef; fileIdx: FileIndex): string = if fileIdx.int32 < 0: result = "???" else: result = fileInfos[fileIdx.int32].fullPath -proc setDirtyFile*(fileIdx: FileIndex; filename: string) = +proc setDirtyFile*(conf: ConfigRef; fileIdx: FileIndex; filename: string) = assert fileIdx.int32 >= 0 fileInfos[fileIdx.int32].dirtyFile = filename -proc setHash*(fileIdx: FileIndex; hash: string) = +proc setHash*(conf: ConfigRef; fileIdx: FileIndex; hash: string) = assert fileIdx.int32 >= 0 shallowCopy(fileInfos[fileIdx.int32].hash, hash) -proc getHash*(fileIdx: FileIndex): string = +proc getHash*(conf: ConfigRef; fileIdx: FileIndex): string = assert fileIdx.int32 >= 0 shallowCopy(result, fileInfos[fileIdx.int32].hash) -proc toFullPathConsiderDirty*(fileIdx: FileIndex): string = +proc toFullPathConsiderDirty*(conf: ConfigRef; fileIdx: FileIndex): string = if fileIdx.int32 < 0: result = "???" elif not fileInfos[fileIdx.int32].dirtyFile.isNil: @@ -261,11 +254,11 @@ proc toFullPathConsiderDirty*(fileIdx: FileIndex): string = else: result = fileInfos[fileIdx.int32].fullPath -template toFilename*(info: TLineInfo): string = - info.fileIndex.toFilename +template toFilename*(conf: ConfigRef; info: TLineInfo): string = + toFilename(conf, info.fileIndex) -template toFullPath*(info: TLineInfo): string = - info.fileIndex.toFullPath +template toFullPath*(conf: ConfigRef; info: TLineInfo): string = + toFullPath(conf, info.fileIndex) proc toMsgFilename*(conf: ConfigRef; info: TLineInfo): string = if info.fileIndex.int32 < 0: @@ -281,17 +274,19 @@ proc toLinenumber*(info: TLineInfo): int {.inline.} = proc toColumn*(info: TLineInfo): int {.inline.} = result = info.col -proc toFileLine*(info: TLineInfo): string {.inline.} = - result = info.toFilename & ":" & $info.line +proc toFileLine*(conf: ConfigRef; info: TLineInfo): string {.inline.} = + result = toFilename(conf, info) & ":" & $info.line -proc toFileLineCol*(info: TLineInfo): string {.inline.} = - result = info.toFilename & "(" & $info.line & ", " & $info.col & ")" +proc toFileLineCol*(conf: ConfigRef; info: TLineInfo): string {.inline.} = + result = toFilename(conf, info) & "(" & $info.line & ", " & $info.col & ")" -proc `$`*(info: TLineInfo): string = toFileLineCol(info) +proc `$`*(conf: ConfigRef; info: TLineInfo): string = toFileLineCol(conf, info) -proc `??`* (info: TLineInfo, filename: string): bool = +proc `$`*(info: TLineInfo): string {.error.} = discard + +proc `??`* (conf: ConfigRef; info: TLineInfo, filename: string): bool = # only for debugging purposes - result = filename in info.toFilename + result = filename in toFilename(conf, info) const trackPosInvalidFileIdx* = FileIndex(-2) # special marker so that no suggestions # are produced within comments and string literals @@ -428,7 +423,7 @@ proc writeContext(conf: ConfigRef; lastinfo: TLineInfo) = for i in countup(0, len(msgContext) - 1): if msgContext[i] != lastinfo and msgContext[i] != info: if structuredErrorHook != nil: - structuredErrorHook(msgContext[i], instantiationFrom, + structuredErrorHook(conf, msgContext[i], instantiationFrom, Severity.Error) else: styledMsgWriteln(styleBright, @@ -474,7 +469,7 @@ proc rawMessage*(conf: ConfigRef; msg: TMsgKind, args: openArray[string]) = let s = msgKindToString(msg) % args if structuredErrorHook != nil: - structuredErrorHook(unknownLineInfo(), s & (if kind != nil: KindFormat % kind else: ""), sev) + structuredErrorHook(conf, unknownLineInfo(), s & (if kind != nil: KindFormat % kind else: ""), sev) if not ignoreMsgBecauseOfIdeTools(conf, msg): if kind != nil: @@ -548,7 +543,7 @@ proc liMessage(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string, if not ignoreMsg: if structuredErrorHook != nil: - structuredErrorHook(info, s & (if kind != nil: KindFormat % kind else: ""), sev) + structuredErrorHook(conf, info, s & (if kind != nil: KindFormat % kind else: ""), sev) if not ignoreMsgBecauseOfIdeTools(conf, msg): if kind != nil: styledMsgWriteln(styleBright, x, resetStyle, color, title, resetStyle, s, @@ -600,7 +595,7 @@ template assertNotNil*(conf: ConfigRef; e): untyped = template internalAssert*(conf: ConfigRef, e: bool) = if not e: internalError(conf, $instantiationInfo()) -proc addSourceLine*(fileIdx: FileIndex, line: string) = +proc addSourceLine*(conf: ConfigRef; fileIdx: FileIndex, line: string) = fileInfos[fileIdx.int32].lines.add line.rope proc sourceLine*(conf: ConfigRef; i: TLineInfo): Rope = @@ -608,8 +603,8 @@ proc sourceLine*(conf: ConfigRef; i: TLineInfo): Rope = if not optPreserveOrigSource(conf) and fileInfos[i.fileIndex.int32].lines.len == 0: try: - for line in lines(i.toFullPath): - addSourceLine i.fileIndex, line.string + for line in lines(toFullPath(conf, i)): + addSourceLine conf, i.fileIndex, line.string except IOError: discard assert i.fileIndex.int32 < fileInfos.len @@ -625,13 +620,6 @@ proc quotedFilename*(conf: ConfigRef; i: TLineInfo): Rope = else: result = fileInfos[i.fileIndex.int32].quotedName -ropes.errorHandler = proc (err: RopesError, msg: string, useWarning: bool) = - case err - of rInvalidFormatStr: - internalError(newPartialConfigRef(), "ropes: invalid format string: " & msg) - of rCannotOpenFile: - rawMessage(newPartialConfigRef(), if useWarning: warnCannotOpenFile else: errCannotOpenFile, msg) - proc listWarnings*(conf: ConfigRef) = msgWriteln(conf, "Warnings:") for warn in warnMin..warnMax: diff --git a/compiler/ndi.nim b/compiler/ndi.nim index a7ca02193..9708c388d 100644 --- a/compiler/ndi.nim +++ b/compiler/ndi.nim @@ -10,7 +10,7 @@ ## This module implements the generation of ``.ndi`` files for better debugging ## support of Nim code. "ndi" stands for "Nim debug info". -import ast, msgs, ropes +import ast, msgs, ropes, options type NdiFile* = object @@ -18,19 +18,19 @@ type f: File buf: string -proc doWrite(f: var NdiFile; s: PSym) = +proc doWrite(f: var NdiFile; s: PSym; conf: ConfigRef) = f.buf.setLen 0 f.buf.add s.info.line.int f.buf.add "\t" f.buf.add s.info.col.int f.f.write(s.name.s, "\t") f.f.writeRope(s.loc.r) - f.f.writeLine("\t", s.info.toFullPath, "\t", f.buf) + f.f.writeLine("\t", toFullPath(conf, s.info), "\t", f.buf) -template writeMangledName*(f: NdiFile; s: PSym) = - if f.enabled: doWrite(f, s) +template writeMangledName*(f: NdiFile; s: PSym; conf: ConfigRef) = + if f.enabled: doWrite(f, s, conf) -proc open*(f: var NdiFile; filename: string) = +proc open*(f: var NdiFile; filename: string; conf: ConfigRef) = f.enabled = filename.len > 0 if f.enabled: f.f = open(filename, fmWrite, 8000) diff --git a/compiler/nimfix/pretty.nim b/compiler/nimfix/pretty.nim index 96429ad53..2fa2a2c3d 100644 --- a/compiler/nimfix/pretty.nim +++ b/compiler/nimfix/pretty.nim @@ -93,8 +93,8 @@ proc beautifyName(s: string, k: TSymKind): string = result.add s[i] inc i -proc replaceInFile(info: TLineInfo; newName: string) = - loadFile(info) +proc replaceInFile(conf: ConfigRef; info: TLineInfo; newName: string) = + loadFile(conf, info) let line = gSourceFiles[info.fileIndex.int].lines[info.line.int-1] var first = min(info.col.int, line.len) @@ -116,7 +116,7 @@ proc checkStyle(conf: ConfigRef; info: TLineInfo, s: string, k: TSymKind; sym: P if s != beau: if gStyleCheck == StyleCheck.Auto: sym.name = getIdent(beau) - replaceInFile(info, beau) + replaceInFile(conf, info, beau) else: message(conf, info, hintName, beau) @@ -136,7 +136,7 @@ template styleCheckDef*(info: TLineInfo; s: PSym) = template styleCheckDef*(s: PSym) = styleCheckDef(s.info, s, s.kind) -proc styleCheckUseImpl(info: TLineInfo; s: PSym) = +proc styleCheckUseImpl(conf: ConfigRef; info: TLineInfo; s: PSym) = if info.fileIndex.int < 0: return # we simply convert it to what it looks like in the definition # for consistency @@ -147,7 +147,7 @@ proc styleCheckUseImpl(info: TLineInfo; s: PSym) = if s.kind in {skType, skGenericParam} and sfAnon in s.flags: return let newName = s.name.s - replaceInFile(info, newName) + replaceInFile(conf, info, newName) #if newName == "File": writeStackTrace() template styleCheckUse*(info: TLineInfo; s: PSym) = diff --git a/compiler/nimfix/prettybase.nim b/compiler/nimfix/prettybase.nim index c32dbe623..89c48ae6e 100644 --- a/compiler/nimfix/prettybase.nim +++ b/compiler/nimfix/prettybase.nim @@ -8,7 +8,7 @@ # import strutils, lexbase, streams -import ".." / [ast, msgs, idents] +import ".." / [ast, msgs, idents, options] from os import splitFile type @@ -21,14 +21,14 @@ type var gSourceFiles*: seq[TSourceFile] = @[] -proc loadFile*(info: TLineInfo) = +proc loadFile*(conf: ConfigRef; info: TLineInfo) = let i = info.fileIndex.int if i >= gSourceFiles.len: gSourceFiles.setLen(i+1) if gSourceFiles[i].lines.isNil: gSourceFiles[i].fileIdx = info.fileIndex gSourceFiles[i].lines = @[] - let path = info.toFullPath + let path = toFullPath(conf, info) gSourceFiles[i].fullpath = path gSourceFiles[i].isNimfixFile = path.splitFile.ext == ".nimfix" # we want to die here for IOError: @@ -61,8 +61,8 @@ proc differ*(line: string, a, b: int, x: string): bool = let y = line[a..b] result = cmpIgnoreStyle(y, x) == 0 and y != x -proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PIdent) = - loadFile(info) +proc replaceDeprecated*(conf: ConfigRef; info: TLineInfo; oldSym, newSym: PIdent) = + loadFile(conf, info) let line = gSourceFiles[info.fileIndex.int32].lines[info.line.int-1] var first = min(info.col.int, line.len) @@ -79,11 +79,11 @@ proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PIdent) = gSourceFiles[info.fileIndex.int32].dirty = true #if newSym.s == "File": writeStackTrace() -proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PSym) = - replaceDeprecated(info, oldSym.name, newSym.name) +proc replaceDeprecated*(conf: ConfigRef; info: TLineInfo; oldSym, newSym: PSym) = + replaceDeprecated(conf, info, oldSym.name, newSym.name) -proc replaceComment*(info: TLineInfo) = - loadFile(info) +proc replaceComment*(conf: ConfigRef; info: TLineInfo) = + loadFile(conf, info) let line = gSourceFiles[info.fileIndex.int32].lines[info.line.int-1] var first = info.col.int diff --git a/compiler/nimsets.nim b/compiler/nimsets.nim index 6cb675ed8..c7a12433f 100644 --- a/compiler/nimsets.nim +++ b/compiler/nimsets.nim @@ -10,7 +10,8 @@ # this unit handles Nim sets; it implements symbolic sets import - ast, astalgo, trees, nversion, msgs, platform, bitsets, types, renderer + ast, astalgo, trees, nversion, msgs, platform, bitsets, types, renderer, + options proc inSet*(s: PNode, elem: PNode): bool = assert s.kind == nkCurly @@ -58,10 +59,10 @@ proc someInSet*(s: PNode, a, b: PNode): bool = return true result = false -proc toBitSet*(s: PNode, b: var TBitSet) = +proc toBitSet*(conf: ConfigRef; s: PNode, b: var TBitSet) = var first, j: BiggestInt - first = firstOrd(s.typ.sons[0]) - bitSetInit(b, int(getSize(s.typ))) + first = firstOrd(conf, s.typ.sons[0]) + bitSetInit(b, int(getSize(conf, s.typ))) for i in countup(0, sonsLen(s) - 1): if s.sons[i].kind == nkRange: j = getOrdValue(s.sons[i].sons[0]) @@ -71,13 +72,13 @@ proc toBitSet*(s: PNode, b: var TBitSet) = else: bitSetIncl(b, getOrdValue(s.sons[i]) - first) -proc toTreeSet*(s: TBitSet, settype: PType, info: TLineInfo): PNode = +proc toTreeSet*(conf: ConfigRef; s: TBitSet, settype: PType, info: TLineInfo): PNode = var a, b, e, first: BiggestInt # a, b are interval borders elemType: PType n: PNode elemType = settype.sons[0] - first = firstOrd(elemType) + first = firstOrd(conf, elemType) result = newNodeI(nkCurly, info) result.typ = settype result.info = info @@ -107,42 +108,42 @@ proc toTreeSet*(s: TBitSet, settype: PType, info: TLineInfo): PNode = template nodeSetOp(a, b: PNode, op: untyped) {.dirty.} = var x, y: TBitSet - toBitSet(a, x) - toBitSet(b, y) + toBitSet(conf, a, x) + toBitSet(conf, b, y) op(x, y) - result = toTreeSet(x, a.typ, a.info) + result = toTreeSet(conf, x, a.typ, a.info) -proc unionSets*(a, b: PNode): PNode = nodeSetOp(a, b, bitSetUnion) -proc diffSets*(a, b: PNode): PNode = nodeSetOp(a, b, bitSetDiff) -proc intersectSets*(a, b: PNode): PNode = nodeSetOp(a, b, bitSetIntersect) -proc symdiffSets*(a, b: PNode): PNode = nodeSetOp(a, b, bitSetSymDiff) +proc unionSets*(conf: ConfigRef; a, b: PNode): PNode = nodeSetOp(a, b, bitSetUnion) +proc diffSets*(conf: ConfigRef; a, b: PNode): PNode = nodeSetOp(a, b, bitSetDiff) +proc intersectSets*(conf: ConfigRef; a, b: PNode): PNode = nodeSetOp(a, b, bitSetIntersect) +proc symdiffSets*(conf: ConfigRef; a, b: PNode): PNode = nodeSetOp(a, b, bitSetSymDiff) -proc containsSets*(a, b: PNode): bool = +proc containsSets*(conf: ConfigRef; a, b: PNode): bool = var x, y: TBitSet - toBitSet(a, x) - toBitSet(b, y) + toBitSet(conf, a, x) + toBitSet(conf, b, y) result = bitSetContains(x, y) -proc equalSets*(a, b: PNode): bool = +proc equalSets*(conf: ConfigRef; a, b: PNode): bool = var x, y: TBitSet - toBitSet(a, x) - toBitSet(b, y) + toBitSet(conf, a, x) + toBitSet(conf, b, y) result = bitSetEquals(x, y) -proc complement*(a: PNode): PNode = +proc complement*(conf: ConfigRef; a: PNode): PNode = var x: TBitSet - toBitSet(a, x) + toBitSet(conf, a, x) for i in countup(0, high(x)): x[i] = not x[i] - result = toTreeSet(x, a.typ, a.info) + result = toTreeSet(conf, x, a.typ, a.info) -proc deduplicate*(a: PNode): PNode = +proc deduplicate*(conf: ConfigRef; a: PNode): PNode = var x: TBitSet - toBitSet(a, x) - result = toTreeSet(x, a.typ, a.info) + toBitSet(conf, a, x) + result = toTreeSet(conf, x, a.typ, a.info) -proc cardSet*(a: PNode): BiggestInt = +proc cardSet*(conf: ConfigRef; a: PNode): BiggestInt = var x: TBitSet - toBitSet(a, x) + toBitSet(conf, a, x) result = bitSetCard(x) proc setHasRange*(s: PNode): bool = diff --git a/compiler/options.nim b/compiler/options.nim index 2027897fa..d1907b1a5 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -73,6 +73,7 @@ type # please make sure we have under 32 options optNoCppExceptions # use C exception handling even with CPP optExcessiveStackTrace # fully qualified module filenames optWholeProject # for 'doc2': output any dependency + optMixedMode # true if some module triggered C++ codegen optListFullPaths optNoNimblePath optDynlibOverrideAll @@ -121,7 +122,21 @@ type SymbolFilesOption* = enum disabledSf, enabledSf, writeOnlySf, readOnlySf, v2Sf + TSystemCC* = enum + ccNone, ccGcc, ccLLVM_Gcc, ccCLang, ccLcc, ccBcc, ccDmc, ccWcc, ccVcc, + ccTcc, ccPcc, ccUcc, ccIcl, ccIcc + + CfileFlag* {.pure.} = enum + Cached, ## no need to recompile this time + External ## file was introduced via .compile pragma + + Cfile* = object + cname*, obj*: string + flags*: set[CFileFlag] + CfileList* = seq[Cfile] + ConfigRef* = ref object ## eventually all global configuration should be moved here + target*: Target linesCompiled*: int # all lines that have been compiled options*: TOptions globalOptions*: TGlobalOptions @@ -142,6 +157,7 @@ type helpWritten*: bool ideCmd*: IdeCmd oldNewlines*: bool + cCompiler*: TSystemCC enableNotes*: TNoteKinds disableNotes*: TNoteKinds foreignPackageNotes*: TNoteKinds @@ -173,6 +189,20 @@ type docSeeSrcUrl*: string # if empty, no seeSrc will be generated. \ # The string uses the formatting variables `path` and `line`. + # the used compiler + cIncludes*: seq[string] # directories to search for included files + cLibs*: seq[string] # directories to search for lib files + cLinkedLibs*: seq[string] # libraries to link + + externalToLink*: seq[string] # files to link in addition to the file + # we compiled + linkOptionsCmd*: string + compileOptionsCmd*: seq[string] + linkOptions*: string + compileOptions*: string + ccompilerpath*: string + toCompile*: CfileList + const oldExperimentalFeatures* = {implicitDeref, dotOperators, callOperator, parallel} const @@ -195,6 +225,7 @@ template newPackageCache*(): untyped = proc newConfigRef*(): ConfigRef = result = ConfigRef( selectedGC: gcRefc, + cCompiler: ccGcc, verbosity: 1, options: DefaultOptions, globalOptions: DefaultGlobalOptions, @@ -221,8 +252,20 @@ proc newConfigRef*(): ConfigRef = keepComments: true, # whether the parser needs to keep comments implicitImports: @[], # modules that are to be implicitly imported implicitIncludes: @[], # modules that are to be implicitly included - docSeeSrcUrl: "" + docSeeSrcUrl: "", + cIncludes: @[], # directories to search for included files + cLibs: @[], # directories to search for lib files + cLinkedLibs: @[], # libraries to link + + externalToLink: @[], + linkOptionsCmd: "", + compileOptionsCmd: @[], + linkOptions: "", + compileOptions: "", + ccompilerpath: "", + toCompile: @[] ) + setTargetFromSystem(result.target) # enable colors by default on terminals if terminal.isatty(stderr): incl(result.globalOptions, optUseColors) @@ -244,39 +287,39 @@ proc cppDefine*(c: ConfigRef; define: string) = proc isDefined*(conf: ConfigRef; symbol: string): bool = if conf.symbols.hasKey(symbol): result = conf.symbols[symbol] != "false" - elif cmpIgnoreStyle(symbol, CPU[targetCPU].name) == 0: + elif cmpIgnoreStyle(symbol, CPU[conf.target.targetCPU].name) == 0: result = true - elif cmpIgnoreStyle(symbol, platform.OS[targetOS].name) == 0: + elif cmpIgnoreStyle(symbol, platform.OS[conf.target.targetOS].name) == 0: result = true else: case symbol.normalize - of "x86": result = targetCPU == cpuI386 - of "itanium": result = targetCPU == cpuIa64 - of "x8664": result = targetCPU == cpuAmd64 + of "x86": result = conf.target.targetCPU == cpuI386 + of "itanium": result = conf.target.targetCPU == cpuIa64 + of "x8664": result = conf.target.targetCPU == cpuAmd64 of "posix", "unix": - result = targetOS in {osLinux, osMorphos, osSkyos, osIrix, osPalmos, + result = conf.target.targetOS in {osLinux, osMorphos, osSkyos, osIrix, osPalmos, osQnx, osAtari, osAix, osHaiku, osVxWorks, osSolaris, osNetbsd, osFreebsd, osOpenbsd, osDragonfly, osMacosx, osAndroid} of "linux": - result = targetOS in {osLinux, osAndroid} + result = conf.target.targetOS in {osLinux, osAndroid} of "bsd": - result = targetOS in {osNetbsd, osFreebsd, osOpenbsd, osDragonfly} + result = conf.target.targetOS in {osNetbsd, osFreebsd, osOpenbsd, osDragonfly} of "emulatedthreadvars": - result = platform.OS[targetOS].props.contains(ospLacksThreadVars) - of "msdos": result = targetOS == osDos - of "mswindows", "win32": result = targetOS == osWindows - of "macintosh": result = targetOS in {osMacos, osMacosx} - of "sunos": result = targetOS == osSolaris - of "littleendian": result = CPU[targetCPU].endian == platform.littleEndian - of "bigendian": result = CPU[targetCPU].endian == platform.bigEndian - of "cpu8": result = CPU[targetCPU].bit == 8 - of "cpu16": result = CPU[targetCPU].bit == 16 - of "cpu32": result = CPU[targetCPU].bit == 32 - of "cpu64": result = CPU[targetCPU].bit == 64 + result = platform.OS[conf.target.targetOS].props.contains(ospLacksThreadVars) + of "msdos": result = conf.target.targetOS == osDos + of "mswindows", "win32": result = conf.target.targetOS == osWindows + of "macintosh": result = conf.target.targetOS in {osMacos, osMacosx} + of "sunos": result = conf.target.targetOS == osSolaris + of "littleendian": result = CPU[conf.target.targetCPU].endian == platform.littleEndian + of "bigendian": result = CPU[conf.target.targetCPU].endian == platform.bigEndian + of "cpu8": result = CPU[conf.target.targetCPU].bit == 8 + of "cpu16": result = CPU[conf.target.targetCPU].bit == 16 + of "cpu32": result = CPU[conf.target.targetCPU].bit == 32 + of "cpu64": result = CPU[conf.target.targetCPU].bit == 64 of "nimrawsetjmp": - result = targetOS in {osSolaris, osNetbsd, osFreebsd, osOpenbsd, + result = conf.target.targetOS in {osSolaris, osNetbsd, osFreebsd, osOpenbsd, osDragonfly, osMacosx} else: discard diff --git a/compiler/parser.nim b/compiler/parser.nim index fbc57ebb6..82e6549ed 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -40,6 +40,7 @@ type tok*: TToken # The current token inPragma*: int # Pragma level inSemiStmtList*: int + emptyNode: PNode SymbolMode = enum smNormal, smAllowNil, smAfterDot @@ -93,6 +94,7 @@ proc openParser*(p: var TParser, fileIdx: FileIndex, inputStream: PLLStream, getTok(p) # read the first token p.firstTok = true p.strongSpaces = strongSpaces + p.emptyNode = newNode(nkEmpty) proc openParser*(p: var TParser, filename: string, inputStream: PLLStream, cache: IdentCache; config: ConfigRef; @@ -333,7 +335,7 @@ proc parseSymbol(p: var TParser, mode = smNormal): PNode = getTok(p) else: parMessage(p, errIdentifierExpected, p.tok) - result = ast.emptyNode + result = p.emptyNode of tkAccent: result = newNodeP(nkAccQuoted, p) getTok(p) @@ -364,7 +366,7 @@ proc parseSymbol(p: var TParser, mode = smNormal): PNode = # But: this really sucks for idetools and keywords, so we don't do it # if it is a keyword: #if not isKeyword(p.tok.tokType): getTok(p) - result = ast.emptyNode + result = p.emptyNode proc colonOrEquals(p: var TParser, a: PNode): PNode = if p.tok.tokType == tkColon: @@ -703,7 +705,7 @@ proc identOrLiteral(p: var TParser, mode: TPrimaryMode): PNode = else: parMessage(p, errExprExpected, p.tok) getTok(p) # we must consume a token here to prevend endless loops! - result = ast.emptyNode + result = p.emptyNode proc namedParams(p: var TParser, callee: PNode, kind: TNodeKind, endTok: TTokType): PNode = @@ -1015,7 +1017,7 @@ proc parseParamList(p: var TParser, retColon = true): PNode = #| paramListColon = paramList? (':' optInd typeDesc)? var a: PNode result = newNodeP(nkFormalParams, p) - addSon(result, ast.emptyNode) # return type + addSon(result, p.emptyNode) # return type let hasParLe = p.tok.tokType == tkParLe and p.tok.indent < 0 if hasParLe: getTok(p) @@ -1047,13 +1049,13 @@ proc parseParamList(p: var TParser, retColon = true): PNode = result.sons[0] = parseTypeDesc(p) elif not retColon and not hasParle: # Mark as "not there" in order to mark for deprecation in the semantic pass: - result = ast.emptyNode + result = p.emptyNode proc optPragmas(p: var TParser): PNode = if p.tok.tokType == tkCurlyDotLe and (p.tok.indent < 0 or realInd(p)): result = parsePragma(p) else: - result = ast.emptyNode + result = p.emptyNode proc parseDoBlock(p: var TParser; info: TLineInfo): PNode = #| doBlock = 'do' paramListArrow pragmas? colcom stmt @@ -1062,7 +1064,9 @@ proc parseDoBlock(p: var TParser; info: TLineInfo): PNode = colcom(p, result) result = parseStmt(p) if params.kind != nkEmpty: - result = newProcNode(nkDo, info, result, params = params, pragmas = pragmas) + result = newProcNode(nkDo, info, + body = result, params = params, name = p.emptyNode, pattern = p.emptyNode, + genericParams = p.emptyNode, pragmas = pragmas, exceptions = p.emptyNode) proc parseProcExpr(p: var TParser; isExpr: bool; kind: TNodeKind): PNode = #| procExpr = 'proc' paramListColon pragmas? ('=' COMMENT? stmt)? @@ -1075,9 +1079,9 @@ proc parseProcExpr(p: var TParser; isExpr: bool; kind: TNodeKind): PNode = if p.tok.tokType == tkEquals and isExpr: getTok(p) skipComment(p, result) - result = newProcNode(kind, info, parseStmt(p), - params = params, - pragmas = pragmas) + result = newProcNode(kind, info, body = parseStmt(p), + params = params, name = p.emptyNode, pattern = p.emptyNode, + genericParams = p.emptyNode, pragmas = pragmas, exceptions = p.emptyNode) else: result = newNodeI(nkProcTy, info) if hasSignature: @@ -1244,8 +1248,8 @@ proc postExprBlocks(p: var TParser, x: PNode): PNode = if p.tok.indent >= 0: return var - openingParams = emptyNode - openingPragmas = emptyNode + openingParams = p.emptyNode + openingPragmas = p.emptyNode if p.tok.tokType == tkDo: getTok(p) @@ -1264,8 +1268,12 @@ proc postExprBlocks(p: var TParser, x: PNode): PNode = stmtList.flags.incl nfBlockArg if openingParams.kind != nkEmpty: - result.add newProcNode(nkDo, stmtList.info, stmtList, - params = openingParams, pragmas = openingPragmas) + result.add newProcNode(nkDo, stmtList.info, body = stmtList, + params = openingParams, + name = p.emptyNode, pattern = p.emptyNode, + genericParams = p.emptyNode, + pragmas = openingPragmas, + exceptions = p.emptyNode) else: result.add stmtList @@ -1424,10 +1432,10 @@ proc parseReturnOrRaise(p: var TParser, kind: TNodeKind): PNode = getTok(p) if p.tok.tokType == tkComment: skipComment(p, result) - addSon(result, ast.emptyNode) + addSon(result, p.emptyNode) elif p.tok.indent >= 0 and p.tok.indent <= p.currInd or not isExprStart(p): # NL terminates: - addSon(result, ast.emptyNode) + addSon(result, p.emptyNode) else: var e = parseExpr(p) e = postExprBlocks(p, e) @@ -1568,7 +1576,7 @@ proc parseBlock(p: var TParser): PNode = #| blockExpr = 'block' symbol? colcom stmt result = newNodeP(nkBlockStmt, p) getTokNoInd(p) - if p.tok.tokType == tkColon: addSon(result, ast.emptyNode) + if p.tok.tokType == tkColon: addSon(result, p.emptyNode) else: addSon(result, parseSymbol(p)) colcom(p, result) addSon(result, parseStmt(p)) @@ -1586,7 +1594,7 @@ proc parseAsm(p: var TParser): PNode = result = newNodeP(nkAsmStmt, p) getTokNoInd(p) if p.tok.tokType == tkCurlyDotLe: addSon(result, parsePragma(p)) - else: addSon(result, ast.emptyNode) + else: addSon(result, p.emptyNode) case p.tok.tokType of tkStrLit: addSon(result, newStrNodeP(nkStrLit, p.tok.literal, p)) of tkRStrLit: addSon(result, newStrNodeP(nkRStrLit, p.tok.literal, p)) @@ -1594,7 +1602,7 @@ proc parseAsm(p: var TParser): PNode = newStrNodeP(nkTripleStrLit, p.tok.literal, p)) else: parMessage(p, "the 'asm' statement takes a string literal") - addSon(result, ast.emptyNode) + addSon(result, p.emptyNode) return getTok(p) @@ -1625,13 +1633,13 @@ proc parseGenericParam(p: var TParser): PNode = optInd(p, result) addSon(result, parseExpr(p)) else: - addSon(result, ast.emptyNode) + addSon(result, p.emptyNode) if p.tok.tokType == tkEquals: getTok(p) optInd(p, result) addSon(result, parseExpr(p)) else: - addSon(result, ast.emptyNode) + addSon(result, p.emptyNode) proc parseGenericParamList(p: var TParser): PNode = #| genericParamList = '[' optInd @@ -1667,22 +1675,22 @@ proc parseRoutine(p: var TParser, kind: TNodeKind): PNode = optInd(p, result) addSon(result, identVis(p)) if p.tok.tokType == tkCurlyLe and p.validInd: addSon(result, p.parsePattern) - else: addSon(result, ast.emptyNode) + else: addSon(result, p.emptyNode) if p.tok.tokType == tkBracketLe and p.validInd: result.add(p.parseGenericParamList) else: - addSon(result, ast.emptyNode) + addSon(result, p.emptyNode) addSon(result, p.parseParamList) if p.tok.tokType == tkCurlyDotLe and p.validInd: addSon(result, p.parsePragma) - else: addSon(result, ast.emptyNode) + else: addSon(result, p.emptyNode) # empty exception tracking: - addSon(result, ast.emptyNode) + addSon(result, p.emptyNode) if p.tok.tokType == tkEquals and p.validInd: getTok(p) skipComment(p, result) addSon(result, parseStmt(p)) else: - addSon(result, ast.emptyNode) + addSon(result, p.emptyNode) indAndComment(p, result) proc newCommentStmt(p: var TParser): PNode = @@ -1732,7 +1740,7 @@ proc parseConstant(p: var TParser): PNode = optInd(p, result) addSon(result, parseTypeDesc(p)) else: - addSon(result, ast.emptyNode) + addSon(result, p.emptyNode) eat(p, tkEquals) optInd(p, result) addSon(result, parseExpr(p)) @@ -1742,7 +1750,7 @@ proc parseEnum(p: var TParser): PNode = #| enum = 'enum' optInd (symbol optInd ('=' optInd expr COMMENT?)? comma?)+ result = newNodeP(nkEnumTy, p) getTok(p) - addSon(result, ast.emptyNode) + addSon(result, p.emptyNode) optInd(p, result) flexComment(p, result) # progress guaranteed @@ -1813,7 +1821,7 @@ proc parseObjectCase(p: var TParser): PNode = addSon(a, identWithPragma(p)) eat(p, tkColon) addSon(a, parseTypeDesc(p)) - addSon(a, ast.emptyNode) + addSon(a, p.emptyNode) addSon(result, a) if p.tok.tokType == tkColon: getTok(p) flexComment(p, result) @@ -1872,7 +1880,7 @@ proc parseObjectPart(p: var TParser): PNode = result = newNodeP(nkNilLit, p) getTok(p) else: - result = ast.emptyNode + result = p.emptyNode proc parseObject(p: var TParser): PNode = #| object = 'object' pragma? ('of' typeDesc)? COMMENT? objectPart @@ -1881,19 +1889,19 @@ proc parseObject(p: var TParser): PNode = if p.tok.tokType == tkCurlyDotLe and p.validInd: addSon(result, parsePragma(p)) else: - addSon(result, ast.emptyNode) + addSon(result, p.emptyNode) if p.tok.tokType == tkOf and p.tok.indent < 0: var a = newNodeP(nkOfInherit, p) getTok(p) addSon(a, parseTypeDesc(p)) addSon(result, a) else: - addSon(result, ast.emptyNode) + addSon(result, p.emptyNode) if p.tok.tokType == tkComment: skipComment(p, result) # an initial IND{>} HAS to follow: if not realInd(p): - addSon(result, emptyNode) + addSon(result, p.emptyNode) return addSon(result, parseObjectPart(p)) @@ -1928,7 +1936,7 @@ proc parseTypeClass(p: var TParser): PNode = if p.tok.tokType == tkCurlyDotLe and p.validInd: addSon(result, parsePragma(p)) else: - addSon(result, ast.emptyNode) + addSon(result, p.emptyNode) if p.tok.tokType == tkOf and p.tok.indent < 0: var a = newNodeP(nkOfInherit, p) getTok(p) @@ -1939,12 +1947,12 @@ proc parseTypeClass(p: var TParser): PNode = getTok(p) addSon(result, a) else: - addSon(result, ast.emptyNode) + addSon(result, p.emptyNode) if p.tok.tokType == tkComment: skipComment(p, result) # an initial IND{>} HAS to follow: if not realInd(p): - addSon(result, emptyNode) + addSon(result, p.emptyNode) else: addSon(result, parseStmt(p)) @@ -1957,14 +1965,14 @@ proc parseTypeDef(p: var TParser): PNode = if p.tok.tokType == tkBracketLe and p.validInd: addSon(result, parseGenericParamList(p)) else: - addSon(result, ast.emptyNode) + addSon(result, p.emptyNode) if p.tok.tokType == tkEquals: result.info = parLineInfo(p) getTok(p) optInd(p, result) addSon(result, parseTypeDefAux(p)) else: - addSon(result, ast.emptyNode) + addSon(result, p.emptyNode) indAndComment(p, result) # special extension! proc parseVarTuple(p: var TParser): PNode = @@ -1979,7 +1987,7 @@ proc parseVarTuple(p: var TParser): PNode = if p.tok.tokType != tkComma: break getTok(p) skipComment(p, a) - addSon(result, ast.emptyNode) # no type desc + addSon(result, p.emptyNode) # no type desc optPar(p) eat(p, tkParRi) eat(p, tkEquals) @@ -2040,7 +2048,7 @@ proc simpleStmt(p: var TParser): PNode = of tkComment: result = newCommentStmt(p) else: if isExprStart(p): result = parseExprStmt(p) - else: result = ast.emptyNode + else: result = p.emptyNode if result.kind notin {nkEmpty, nkCommentStmt}: skipComment(p, result) proc complexOrSimpleStmt(p: var TParser): PNode = @@ -2136,7 +2144,7 @@ proc parseStmt(p: var TParser): PNode = of tkIf, tkWhile, tkCase, tkTry, tkFor, tkBlock, tkAsm, tkProc, tkFunc, tkIterator, tkMacro, tkType, tkConst, tkWhen, tkVar: parMessage(p, "complex statement requires indentation") - result = ast.emptyNode + result = p.emptyNode else: if p.inSemiStmtList > 0: result = simpleStmt(p) @@ -2173,7 +2181,7 @@ proc parseAll(p: var TParser): PNode = proc parseTopLevelStmt(p: var TParser): PNode = ## Implements an iterator which, when called repeatedly, returns the next ## top-level statement or emptyNode if end of stream. - result = ast.emptyNode + result = p.emptyNode # progress guaranteed while true: if p.tok.indent != 0: diff --git a/compiler/passes.nim b/compiler/passes.nim index 8f9f57f3d..26e33185c 100644 --- a/compiler/passes.nim +++ b/compiler/passes.nim @@ -151,7 +151,7 @@ proc processImplicits(conf: ConfigRef; implicits: seq[string], nodeKind: TNodeKi a: var TPassContextArray; m: PSym) = # XXX fixme this should actually be relative to the config file! let gCmdLineInfo = newLineInfo(FileIndex(0), 1, 1) - let relativeTo = m.info.toFullPath + let relativeTo = toFullPath(conf, m.info) for module in items(implicits): # implicit imports should not lead to a module importing itself if m.position != resolveMod(conf, module, relativeTo).int32: @@ -201,7 +201,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream, elif rd == nil: openPasses(graph, a, module, cache) if stream == nil: - let filename = fileIdx.toFullPathConsiderDirty + let filename = toFullPathConsiderDirty(graph.config, fileIdx) s = llStreamOpen(filename, fmRead) if s == nil: rawMessage(graph.config, errCannotOpenFile, filename) diff --git a/compiler/platform.nim b/compiler/platform.nim index 8b3bf6b74..173cfa8e3 100644 --- a/compiler/platform.nim +++ b/compiler/platform.nim @@ -210,44 +210,40 @@ const (name: "mips64el", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64), (name: "riscv64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64)] -var - targetCPU*, hostCPU*: TSystemCPU - targetOS*, hostOS*: TSystemOS - -proc nameToOS*(name: string): TSystemOS -proc nameToCPU*(name: string): TSystemCPU - -var - intSize*: int - floatSize*: int - ptrSize*: int - tnl*: string # target newline - -proc setTarget*(o: TSystemOS, c: TSystemCPU) = +type + Target* = object + targetCPU*, hostCPU*: TSystemCPU + targetOS*, hostOS*: TSystemOS + intSize*: int + floatSize*: int + ptrSize*: int + tnl*: string # target newline + +proc setTarget*(t: var Target; o: TSystemOS, c: TSystemCPU) = assert(c != cpuNone) assert(o != osNone) #echo "new Target: OS: ", o, " CPU: ", c - targetCPU = c - targetOS = o - intSize = CPU[c].intSize div 8 - floatSize = CPU[c].floatSize div 8 - ptrSize = CPU[c].bit div 8 - tnl = OS[o].newLine - -proc nameToOS(name: string): TSystemOS = + t.targetCPU = c + t.targetOS = o + # assume no cross-compiling + t.hostCPU = c + t.hostOS = o + t.intSize = CPU[c].intSize div 8 + t.floatSize = CPU[c].floatSize div 8 + t.ptrSize = CPU[c].bit div 8 + t.tnl = OS[o].newLine + +proc nameToOS*(name: string): TSystemOS = for i in countup(succ(osNone), high(TSystemOS)): if cmpIgnoreStyle(name, OS[i].name) == 0: return i result = osNone -proc nameToCPU(name: string): TSystemCPU = +proc nameToCPU*(name: string): TSystemCPU = for i in countup(succ(cpuNone), high(TSystemCPU)): if cmpIgnoreStyle(name, CPU[i].name) == 0: return i result = cpuNone -hostCPU = nameToCPU(system.hostCPU) -hostOS = nameToOS(system.hostOS) - -setTarget(hostOS, hostCPU) # assume no cross-compiling - +proc setTargetFromSystem*(t: var Target) = + t.setTarget(nameToOS(system.hostOS), nameToCPU(system.hostCPU)) diff --git a/compiler/plugins/itersgen.nim b/compiler/plugins/itersgen.nim index ebb65dd4a..7af97904e 100644 --- a/compiler/plugins/itersgen.nim +++ b/compiler/plugins/itersgen.nim @@ -40,10 +40,10 @@ proc iterToProcImpl(c: PContext, n: PNode): PNode = prc.typ.rawAddSon t let orig = iter.sym.ast prc.ast = newProcNode(nkProcDef, n.info, - name = newSymNode(prc), - params = orig[paramsPos], - pragmas = orig[pragmasPos], - body = body) + body = body, params = orig[paramsPos], name = newSymNode(prc), + pattern = c.graph.emptyNode, genericParams = c.graph.emptyNode, + pragmas = orig[pragmasPos], exceptions = c.graph.emptyNode) + prc.ast.add iter.sym.ast.sons[resultPos] addInterfaceDecl(c, prc) diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index de98a5e42..19431613c 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -143,7 +143,7 @@ proc processImportCpp(c: PContext; s: PSym, extname: string, info: TLineInfo) = if c.config.cmd == cmdCompileToC: let m = s.getModule() incl(m.flags, sfCompileToCpp) - extccomp.gMixedMode = true + incl c.config.globalOptions, optMixedMode proc processImportObjC(c: PContext; s: PSym, extname: string, info: TLineInfo) = setExternName(c, s, extname, info) @@ -404,7 +404,7 @@ proc relativeFile(c: PContext; n: PNode; ext=""): string = var s = expectStrLit(c, n) if ext.len > 0 and splitFile(s).ext == "": s = addFileExt(s, ext) - result = parentDir(n.info.toFullPath) / s + result = parentDir(toFullPath(c.config, n.info)) / s if not fileExists(result): if isAbsolute(s): result = s else: @@ -426,7 +426,7 @@ proc processCompile(c: PContext, n: PNode) = if it.kind in {nkPar, nkTupleConstr} and it.len == 2: let s = getStrLit(c, it, 0) let dest = getStrLit(c, it, 1) - var found = parentDir(n.info.toFullPath) / s + var found = parentDir(toFullPath(c.config, n.info)) / s for f in os.walkFiles(found): let nameOnly = extractFilename(f) var cf = Cfile(cname: f, @@ -435,7 +435,7 @@ proc processCompile(c: PContext, n: PNode) = extccomp.addExternalFileToCompile(c.config, cf) else: let s = expectStrLit(c, n) - var found = parentDir(n.info.toFullPath) / s + var found = parentDir(toFullPath(c.config, n.info)) / s if not fileExists(found): if isAbsolute(s): found = s else: @@ -444,7 +444,7 @@ proc processCompile(c: PContext, n: PNode) = extccomp.addExternalFileToCompile(c.config, found) proc processCommonLink(c: PContext, n: PNode, feature: TLinkFeature) = - let found = relativeFile(c, n, CC[cCompiler].objExt) + let found = relativeFile(c, n, CC[c.config.cCompiler].objExt) case feature of linkNormal: extccomp.addExternalFileToLink(c.config, found) of linkSys: diff --git a/compiler/procfind.nim b/compiler/procfind.nim index 042947e72..3f47e7e8a 100644 --- a/compiler/procfind.nim +++ b/compiler/procfind.nim @@ -73,7 +73,7 @@ proc searchForProcNew(c: PContext, scope: PScope, fn: PSym): PSym = if (sfExported notin result.flags) and (sfExported in fn.flags): let message = ("public implementation '$1' has non-public " & "forward declaration in $2") % - [getProcHeader(result), $result.info] + [getProcHeader(c.config, result), c.config$result.info] localError(c.config, fn.info, message) return of paramsIncompatible: diff --git a/compiler/reorder.nim b/compiler/reorder.nim index d50be1d99..e4ba221e3 100644 --- a/compiler/reorder.nim +++ b/compiler/reorder.nim @@ -155,7 +155,8 @@ proc expandIncludes(graph: ModuleGraph, module: PSym, n: PNode, var f = checkModuleName(graph.config, a.sons[i]) if f != InvalidFileIDX: if containsOrIncl(includedFiles, f.int): - localError(graph.config, a.info, "recursive dependency: '$1'" % f.toFilename) + localError(graph.config, a.info, "recursive dependency: '$1'" % + toFilename(graph.config, f)) else: let nn = includeModule(graph, module, f, cache) let nnn = expandIncludes(graph, module, nn, modulePath, @@ -430,7 +431,7 @@ proc reorder*(graph: ModuleGraph, n: PNode, module: PSym, cache: IdentCache): PN if n.hasForbiddenPragma: return n var includedFiles = initIntSet() - let mpath = module.fileIdx.toFullPath + let mpath = toFullPath(graph.config, module.fileIdx) let n = expandIncludes(graph, module, n, mpath, includedFiles, cache).splitSections result = newNodeI(nkStmtList, n.info) diff --git a/compiler/rodread.nim b/compiler/rodread.nim index 52e7a924c..9c834a410 100644 --- a/compiler/rodread.nim +++ b/compiler/rodread.nim @@ -658,7 +658,7 @@ proc processRodFile(r: PRodReader, hash: SecureHash) = inc(r.pos, 2) # skip "(\10" inc(r.line) while r.s[r.pos] != ')': - w = r.files[decodeVInt(r.s, r.pos)].toFullPath + w = toFullPath(r.config, r.files[decodeVInt(r.s, r.pos)]) inc(r.pos) # skip ' ' inclHash = parseSecureHash(decodeStr(r.s, r.pos)) if r.reason == rrNone: @@ -792,7 +792,8 @@ proc findSomeWhere(id: int) = if rd != nil: var d = iiTableGet(rd.index.tab, id) if d != InvalidKey: - echo "found id ", id, " in ", gMods[i].filename + when declared(echo): + echo "found id ", id, " in ", gMods[i].filename proc getReader(moduleId: int): PRodReader = # we can't index 'gMods' here as it's indexed by a *file index* which is not @@ -865,11 +866,11 @@ proc loadMethods(r: PRodReader) = r.methods.add(rrGetSym(r, d, unknownLineInfo())) if r.s[r.pos] == ' ': inc(r.pos) -proc getHash*(fileIdx: FileIndex): SecureHash = +proc getHash*(conf: ConfigRef; fileIdx: FileIndex): SecureHash = if fileIdx.int32 <% gMods.len and gMods[fileIdx.int32].hashDone: return gMods[fileIdx.int32].hash - result = secureHashFile(fileIdx.toFullPath) + result = secureHashFile(toFullPath(conf, fileIdx)) if fileIdx.int32 >= gMods.len: setLen(gMods, fileIdx.int32+1) gMods[fileIdx.int32].hash = result @@ -882,8 +883,8 @@ proc checkDep(fileIdx: FileIndex; cache: IdentCache; conf: ConfigRef): TReasonFo if gMods[fileIdx.int32].reason != rrEmpty: # reason has already been computed for this module: return gMods[fileIdx.int32].reason - let filename = fileIdx.toFilename - var hash = getHash(fileIdx) + let filename = toFilename(conf, fileIdx) + var hash = getHash(conf, fileIdx) gMods[fileIdx.int32].reason = rrNone # we need to set it here to avoid cycles result = rrNone var rodfile = toGeneratedFile(conf, conf.withPackageName(filename), RodExt) @@ -966,7 +967,7 @@ proc getBody*(s: PSym): PNode = ## accessor. assert s.kind in routineKinds # prevent crashes due to incorrect macro transformations (bug #2377) - if s.ast.isNil or bodyPos >= s.ast.len: return ast.emptyNode + if s.ast.isNil or bodyPos >= s.ast.len: return newNodeI(nkEmpty, s.info) result = s.ast.sons[bodyPos] if result == nil: assert s.offset != 0 diff --git a/compiler/rodwrite.nim b/compiler/rodwrite.nim index 4686baf2b..a5574fdf0 100644 --- a/compiler/rodwrite.nim +++ b/compiler/rodwrite.nim @@ -56,7 +56,7 @@ proc fileIdx(w: PRodWriter, filename: string): int = w.files[result] = filename template filename*(w: PRodWriter): string = - toFilename(FileIndex w.module.position) + toFilename(w.config, FileIndex w.module.position) proc newRodWriter(hash: SecureHash, module: PSym; cache: IdentCache; config: ConfigRef): PRodWriter = @@ -80,20 +80,20 @@ proc newRodWriter(hash: SecureHash, module: PSym; cache: IdentCache; result.converters = "" result.methods = "" result.init = "" - result.origFile = module.info.toFullPath + result.origFile = toFullPath(config, module.info) result.data = newStringOfCap(12_000) result.cache = cache proc addModDep(w: PRodWriter, dep: string; info: TLineInfo) = if w.modDeps.len != 0: add(w.modDeps, ' ') - let resolved = findModule(w.config, dep, info.toFullPath) + let resolved = findModule(w.config, dep, toFullPath(w.config, info)) encodeVInt(fileIdx(w, resolved), w.modDeps) const rodNL = "\x0A" proc addInclDep(w: PRodWriter, dep: string; info: TLineInfo) = - let resolved = findModule(w.config, dep, info.toFullPath) + let resolved = findModule(w.config, dep, toFullPath(w.config, info)) encodeVInt(fileIdx(w, resolved), w.inclDeps) add(w.inclDeps, " ") encodeStr($secureHashFile(resolved), w.inclDeps) @@ -130,7 +130,7 @@ proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode, result.add(',') encodeVInt(int n.info.line, result) result.add(',') - encodeVInt(fileIdx(w, toFullPath(n.info)), result) + encodeVInt(fileIdx(w, toFullPath(w.config, n.info)), result) elif fInfo.line != n.info.line: result.add('?') encodeVInt(n.info.col, result) @@ -308,7 +308,7 @@ proc encodeSym(w: PRodWriter, s: PSym, result: var string) = result.add(',') if s.info.line != 0'u16: encodeVInt(int s.info.line, result) result.add(',') - encodeVInt(fileIdx(w, toFullPath(s.info)), result) + encodeVInt(fileIdx(w, toFullPath(w.config, s.info)), result) if s.owner != nil: result.add('*') encodeVInt(s.owner.id, result) @@ -645,7 +645,7 @@ proc process(c: PPassContext, n: PNode): PNode = proc myOpen(g: ModuleGraph; module: PSym; cache: IdentCache): PPassContext = if module.id < 0: internalError(g.config, "rodwrite: module ID not set") - var w = newRodWriter(rodread.getHash FileIndex module.position, module, cache, g.config) + var w = newRodWriter(rodread.getHash(g.config, FileIndex module.position), module, cache, g.config) rawAddInterfaceSym(w, module) result = w diff --git a/compiler/ropes.nim b/compiler/ropes.nim index 05d5e840c..297343a39 100644 --- a/compiler/ropes.nim +++ b/compiler/ropes.nim @@ -72,15 +72,6 @@ type RopeSeq* = seq[Rope] - RopesError* = enum - rCannotOpenFile - rInvalidFormatStr - -# implementation - -var errorHandler*: proc(err: RopesError, msg: string, useWarning = false) - # avoid dependency on msgs.nim - proc len*(a: Rope): int = ## the rope's length if a == nil: result = 0 @@ -204,13 +195,14 @@ proc writeRope*(f: File, r: Rope) = ## writes a rope to a file. for s in leaves(r): write(f, s) -proc writeRope*(head: Rope, filename: string, useWarning = false) = +proc writeRope*(head: Rope, filename: string): bool = var f: File if open(f, filename, fmWrite): if head != nil: writeRope(f, head) close(f) + result = true else: - errorHandler(rCannotOpenFile, filename, useWarning) + result = false proc `$`*(r: Rope): string = ## converts a rope back to a string. @@ -225,11 +217,6 @@ proc ropeConcat*(a: varargs[Rope]): Rope = proc prepend*(a: var Rope, b: Rope) = a = b & a proc prepend*(a: var Rope, b: string) = a = b & a -var - rnl* = tnl.newRope - softRnl* = tnl.newRope - noRnl* = "".newRope - proc `%`*(frmt: FormatStr, args: openArray[Rope]): Rope = var i = 0 var length = len(frmt) @@ -254,7 +241,7 @@ proc `%`*(frmt: FormatStr, args: openArray[Rope]): Rope = if i >= frmt.len or frmt[i] notin {'0'..'9'}: break num = j if j > high(args) + 1: - errorHandler(rInvalidFormatStr, $(j)) + doAssert false, "invalid format string: " & frmt else: add(result, args[j-1]) of '{': @@ -265,20 +252,21 @@ proc `%`*(frmt: FormatStr, args: openArray[Rope]): Rope = inc(i) num = j if frmt[i] == '}': inc(i) - else: errorHandler(rInvalidFormatStr, $(frmt[i])) + else: + doAssert false, "invalid format string: " & frmt if j > high(args) + 1: - errorHandler(rInvalidFormatStr, $(j)) + doAssert false, "invalid format string: " & frmt else: add(result, args[j-1]) of 'n': - add(result, softRnl) + add(result, "\n") inc(i) of 'N': - add(result, rnl) + add(result, "\n") inc(i) else: - errorHandler(rInvalidFormatStr, $(frmt[i])) + doAssert false, "invalid format string: " & frmt var start = i while i < length: if frmt[i] != '$': inc(i) @@ -350,7 +338,6 @@ proc equalsFile*(r: Rope, filename: string): bool = proc writeRopeIfNotEqual*(r: Rope, filename: string): bool = # returns true if overwritten if not equalsFile(r, filename): - writeRope(r, filename) - result = true + result = writeRope(r, filename) else: result = false diff --git a/compiler/sem.nim b/compiler/sem.nim index c5c3dd99b..8b616bd84 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -594,12 +594,12 @@ proc myProcess(context: PPassContext, n: PNode): PNode = c.suggestionsMade = true result = nil else: - result = ast.emptyNode + result = newNodeI(nkEmpty, n.info) #if c.config.cmd == cmdIdeTools: findSuggest(c, n) rod.storeNode(c.module, result) proc testExamples(c: PContext) = - let inp = toFullPath(c.module.info) + let inp = toFullPath(c.config, c.module.info) let outp = inp.changeFileExt"" & "_examples.nim" renderModule(c.runnableExamples, inp, outp) let backend = if isDefined(c.config, "js"): "js" diff --git a/compiler/semasgn.nim b/compiler/semasgn.nim index f0fde195c..3577abee8 100644 --- a/compiler/semasgn.nim +++ b/compiler/semasgn.nim @@ -157,7 +157,7 @@ proc defaultOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = proc addVar(father, v, value: PNode) = var vpart = newNodeI(nkIdentDefs, v.info, 3) vpart.sons[0] = v - vpart.sons[1] = ast.emptyNode + vpart.sons[1] = newNodeI(nkEmpty, v.info) vpart.sons[2] = value addSon(father, vpart) @@ -207,7 +207,7 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) = if t.kind == tySequence: # XXX add 'nil' handling here body.add newSeqCall(c.c, x, y) - let i = declareCounter(c, body, firstOrd(t)) + let i = declareCounter(c, body, firstOrd(c.c.config, t)) let whileLoop = genWhileLoop(c, i, x) let elemType = t.lastSon liftBodyAux(c, elemType, whileLoop.sons[1], x.at(i, elemType), @@ -297,7 +297,7 @@ proc liftBody(c: PContext; typ: PType; kind: TTypeAttachedOp; of attachedDestructor: typ.destructor = result var n = newNodeI(nkProcDef, info, bodyPos+1) - for i in 0 ..< n.len: n.sons[i] = emptyNode + for i in 0 ..< n.len: n.sons[i] = newNodeI(nkEmpty, info) n.sons[namePos] = newSymNode(result) n.sons[paramsPos] = result.typ.n n.sons[bodyPos] = body diff --git a/compiler/semcall.nim b/compiler/semcall.nim index e9a31d3d6..1de5a55cc 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -170,7 +170,7 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors): add(candidates, renderTree(err.sym.ast, {renderNoBody, renderNoComments, renderNoPragmas})) else: - add(candidates, err.sym.getProcHeader(prefer)) + add(candidates, getProcHeader(c.config, err.sym, prefer)) add(candidates, "\n") if err.firstMismatch != 0 and n.len > 1: let cond = n.len > 2 @@ -344,7 +344,8 @@ proc resolveOverloads(c: PContext, n, orig: PNode, add(args, ")") localError(c.config, n.info, errAmbiguousCallXYZ % [ - getProcHeader(result.calleeSym), getProcHeader(alt.calleeSym), + getProcHeader(c.config, result.calleeSym), + getProcHeader(c.config, alt.calleeSym), args]) proc instGenericConvertersArg*(c: PContext, a: PNode, x: TCandidate) = diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 12ac19ca3..e88f19768 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -75,6 +75,7 @@ type PContext* = ref TContext TContext* = object of TPassContext # a context represents a module + enforceVoidContext*: PType module*: PSym # the module sym belonging to the context currentScope*: PScope # current scope importTable*: PScope # scope for all imported symbols @@ -148,7 +149,7 @@ proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair = proc filename*(c: PContext): string = # the module's filename - return toFilename(FileIndex c.module.position) + return toFilename(c.config, FileIndex c.module.position) proc scopeDepth*(c: PContext): int {.inline.} = result = if c.currentScope != nil: c.currentScope.depthLevel @@ -212,6 +213,7 @@ proc newOptionEntry*(conf: ConfigRef): POptionEntry = proc newContext*(graph: ModuleGraph; module: PSym; cache: IdentCache): PContext = new(result) + result.enforceVoidContext = PType(kind: tyStmt) result.ambiguousSymbols = initIntSet() result.optionStack = @[] result.libs = @[] diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 6b32fa66c..64a5861e2 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -58,7 +58,7 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # do not produce another redundant error message: #raiseRecoverableError("") result = errorNode(c, n) - if result.typ == nil or result.typ == enforceVoidContext: + if result.typ == nil or result.typ == c.enforceVoidContext: localError(c.config, n.info, errExprXHasNoType % renderTree(result, {renderNoComments})) result.typ = errorType(c) @@ -137,7 +137,7 @@ proc checkConvertible(c: PContext, castDest, src: PType): TConvStatus = else: discard -proc isCastable(dst, src: PType): bool = +proc isCastable(conf: ConfigRef; dst, src: PType): bool = ## Checks whether the source type can be cast to the destination type. ## Casting is very unrestrictive; casts are allowed as long as ## castDest.size >= src.size, and typeAllowed(dst, skParam) @@ -152,8 +152,8 @@ proc isCastable(dst, src: PType): bool = return false var dstSize, srcSize: BiggestInt - dstSize = computeSize(dst) - srcSize = computeSize(src) + dstSize = computeSize(conf, dst) + srcSize = computeSize(conf, src) if dstSize < 0: result = false elif srcSize < 0: @@ -167,7 +167,7 @@ proc isCastable(dst, src: PType): bool = (skipTypes(dst, abstractInst).kind in IntegralTypes) or (skipTypes(src, abstractInst-{tyTypeDesc}).kind in IntegralTypes) if result and src.kind == tyNil: - result = dst.size <= platform.ptrSize + result = dst.size <= conf.target.ptrSize proc isSymChoice(n: PNode): bool {.inline.} = result = n.kind in nkSymChoices @@ -251,7 +251,7 @@ proc semCast(c: PContext, n: PNode): PNode = let castedExpr = semExprWithType(c, n.sons[1]) if tfHasMeta in targetType.flags: localError(c.config, n.sons[0].info, "cannot cast to a non concrete type: '$1'" % $targetType) - if not isCastable(targetType, castedExpr.typ): + if not isCastable(c.config, targetType, castedExpr.typ): let tar = $targetType let alt = typeToString(targetType, preferDesc) let msg = if tar != alt: tar & "=" & alt else: tar @@ -407,7 +407,7 @@ proc changeType(c: PContext; n: PNode, newType: PType, check: bool) = of nkCharLit..nkUInt64Lit: if check and n.kind != nkUInt64Lit: let value = n.intVal - if value < firstOrd(newType) or value > lastOrd(newType): + if value < firstOrd(c.config, newType) or value > lastOrd(c.config, newType): localError(c.config, n.info, "cannot convert " & $value & " to " & typeToString(newType)) else: discard @@ -634,7 +634,7 @@ proc semStaticExpr(c: PContext, n: PNode): PNode = result = evalStaticExpr(c.module, c.cache, c.graph, a, c.p.owner) if result.isNil: localError(c.config, n.info, errCannotInterpretNodeX % renderTree(n)) - result = emptyNode + result = c.graph.emptyNode else: result = fixupTypeAfterEval(c, result, a) @@ -745,7 +745,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = if errorOutputs == {}: # speed up error generation: globalError(c.config, n.info, "type mismatch") - return emptyNode + return c.graph.emptyNode else: var hasErrorType = false var msg = "type mismatch: got <" @@ -866,7 +866,7 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent, else: if check == nil: check = newNodeI(nkCheckedFieldExpr, n.info) - addSon(check, ast.emptyNode) # make space for access node + addSon(check, c.graph.emptyNode) # make space for access node s = newNodeIT(nkCurly, n.info, setType) for j in countup(0, sonsLen(it) - 2): addSon(s, copyTree(it.sons[j])) var inExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool)) @@ -881,7 +881,7 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent, if result != nil: if check == nil: check = newNodeI(nkCheckedFieldExpr, n.info) - addSon(check, ast.emptyNode) # make space for access node + addSon(check, c.graph.emptyNode) # make space for access node var inExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool)) addSon(inExpr, newSymNode(c.graph.opContains, n.info)) addSon(inExpr, s) @@ -938,7 +938,7 @@ proc readTypeParameter(c: PContext, typ: PType, if rawTyp.n != nil: return rawTyp.n else: - return emptyNode + return c.graph.emptyNode else: let foundTyp = makeTypeDesc(c, rawTyp) return newSymNode(copySym(tParam.sym).linkTo(foundTyp), info) @@ -1106,7 +1106,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = case t.kind of tyTypeParamsHolders: result = readTypeParameter(c, t, i, n.info) - if result == emptyNode: + if result == c.graph.emptyNode: result = n n.typ = makeTypeFromExpr(c, n.copyTree) return @@ -1450,7 +1450,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = rhs = semExprWithType(c, n.sons[1], if lhsIsResult: {efAllowDestructor} else: {}) if lhsIsResult: - n.typ = enforceVoidContext + n.typ = c.enforceVoidContext if c.p.owner.kind != skMacro and resultTypeIsInferrable(lhs.sym.typ): var rhsTyp = rhs.typ if rhsTyp.kind in tyUserTypeClasses and rhsTyp.isResolvedUserTypeClass: @@ -1489,7 +1489,7 @@ proc semReturn(c: PContext, n: PNode): PNode = n.sons[0] = semAsgn(c, a) # optimize away ``result = result``: if n[0][1].kind == nkSym and n[0][1].sym == c.p.resultSym: - n.sons[0] = ast.emptyNode + n.sons[0] = c.graph.emptyNode else: localError(c.config, n.info, errNoReturnTypeDeclared) else: @@ -1748,14 +1748,17 @@ proc semQuoteAst(c: PContext, n: PNode): PNode = processQuotations(c, quotedBlock, op, quotes, ids) var dummyTemplate = newProcNode( - nkTemplateDef, quotedBlock.info, quotedBlock, - name = newAnonSym(c, skTemplate, n.info).newSymNode) + nkTemplateDef, quotedBlock.info, body = quotedBlock, + params = c.graph.emptyNode, + name = newAnonSym(c, skTemplate, n.info).newSymNode, + pattern = c.graph.emptyNode, genericParams = c.graph.emptyNode, + pragmas = c.graph.emptyNode, exceptions = c.graph.emptyNode) if ids.len > 0: dummyTemplate.sons[paramsPos] = newNodeI(nkFormalParams, n.info) dummyTemplate[paramsPos].add getSysSym(c.graph, n.info, "typed").newSymNode # return type ids.add getSysSym(c.graph, n.info, "untyped").newSymNode # params type - ids.add emptyNode # no default value + ids.add c.graph.emptyNode # no default value dummyTemplate[paramsPos].add newNode(nkIdentDefs, n.info, ids) var tmpl = semTemplateDef(c, dummyTemplate) @@ -1913,7 +1916,7 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = result.typ = typ result.add instantiateCreateFlowVarCall(c, typ, n.info).newSymNode else: - result.add emptyNode + result.add c.graph.emptyNode of mProcCall: result = setMs(n, s) result.sons[1] = semExpr(c, n.sons[1]) @@ -1937,17 +1940,17 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = of mRunnableExamples: if c.config.cmd == cmdDoc and n.len >= 2 and n.lastSon.kind == nkStmtList: if sfMainModule in c.module.flags: - let inp = toFullPath(c.module.info) + let inp = toFullPath(c.config, c.module.info) if c.runnableExamples == nil: c.runnableExamples = newTree(nkStmtList, newTree(nkImportStmt, newStrNode(nkStrLit, expandFilename(inp)))) let imports = newTree(nkStmtList) extractImports(n.lastSon, imports) for imp in imports: c.runnableExamples.add imp - c.runnableExamples.add newTree(nkBlockStmt, emptyNode, copyTree n.lastSon) + c.runnableExamples.add newTree(nkBlockStmt, c.graph.emptyNode, copyTree n.lastSon) result = setMs(n, s) else: - result = emptyNode + result = c.graph.emptyNode else: result = semDirectOp(c, n, flags) @@ -2040,7 +2043,7 @@ proc semSetConstr(c: PContext, n: PNode): PNode = if not isOrdinalType(typ): localError(c.config, n.info, errOrdinalTypeExpected) typ = makeRangeType(c, 0, MaxSetElements-1, n.info) - elif lengthOrd(typ) > MaxSetElements: + elif lengthOrd(c.config, typ) > MaxSetElements: typ = makeRangeType(c, 0, MaxSetElements-1, n.info) addSonSkipIntLit(result.typ, typ) for i in countup(0, sonsLen(n) - 1): diff --git a/compiler/semfields.nim b/compiler/semfields.nim index 16d79c559..b432ee963 100644 --- a/compiler/semfields.nim +++ b/compiler/semfields.nim @@ -162,7 +162,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode = # we avoid it now if we can: if containsNode(stmts, {nkBreakStmt}): var b = newNodeI(nkBreakStmt, n.info) - b.add(ast.emptyNode) + b.add(newNodeI(nkEmpty, n.info)) stmts.add(b) else: result = stmts diff --git a/compiler/semfold.nim b/compiler/semfold.nim index daf9ce983..b60f6b8bd 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -53,24 +53,24 @@ proc getConstExpr*(m: PSym, n: PNode; g: ModuleGraph): PNode # expression proc evalOp*(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode -proc checkInRange(n: PNode, res: BiggestInt): bool = - if res in firstOrd(n.typ)..lastOrd(n.typ): +proc checkInRange(conf: ConfigRef; n: PNode, res: BiggestInt): bool = + if res in firstOrd(conf, n.typ)..lastOrd(conf, n.typ): result = true proc foldAdd(a, b: BiggestInt, n: PNode; g: ModuleGraph): PNode = let res = a +% b if ((res xor a) >= 0'i64 or (res xor b) >= 0'i64) and - checkInRange(n, res): + checkInRange(g.config, n, res): result = newIntNodeT(res, n, g) proc foldSub*(a, b: BiggestInt, n: PNode; g: ModuleGraph): PNode = let res = a -% b if ((res xor a) >= 0'i64 or (res xor not b) >= 0'i64) and - checkInRange(n, res): + checkInRange(g.config, n, res): result = newIntNodeT(res, n, g) proc foldAbs*(a: BiggestInt, n: PNode; g: ModuleGraph): PNode = - if a != firstOrd(n.typ): + if a != firstOrd(g.config, n.typ): result = newIntNodeT(a, n, g) proc foldMod*(a, b: BiggestInt, n: PNode; g: ModuleGraph): PNode = @@ -82,7 +82,7 @@ proc foldModU*(a, b: BiggestInt, n: PNode; g: ModuleGraph): PNode = result = newIntNodeT(a %% b, n, g) proc foldDiv*(a, b: BiggestInt, n: PNode; g: ModuleGraph): PNode = - if b != 0'i64 and (a != firstOrd(n.typ) or b != -1'i64): + if b != 0'i64 and (a != firstOrd(g.config, n.typ) or b != -1'i64): result = newIntNodeT(a div b, n, g) proc foldDivU*(a, b: BiggestInt, n: PNode; g: ModuleGraph): PNode = @@ -96,7 +96,7 @@ proc foldMul*(a, b: BiggestInt, n: PNode; g: ModuleGraph): PNode = # Fast path for normal case: small multiplicands, and no info # is lost in either method. - if resAsFloat == floatProd and checkInRange(n, res): + if resAsFloat == floatProd and checkInRange(g.config, n, res): return newIntNodeT(res, n, g) # Somebody somewhere lost info. Close enough, or way off? Note @@ -107,7 +107,7 @@ proc foldMul*(a, b: BiggestInt, n: PNode; g: ModuleGraph): PNode = # abs(diff)/abs(prod) <= 1/32 iff # 32 * abs(diff) <= abs(prod) -- 5 good bits is "close enough" if 32.0 * abs(resAsFloat - floatProd) <= abs(floatProd) and - checkInRange(n, res): + checkInRange(g.config, n, res): return newIntNodeT(res, n, g) proc ordinalValToString*(a: PNode; g: ModuleGraph): string = @@ -210,9 +210,9 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode = of mUnaryMinusI, mUnaryMinusI64: result = newIntNodeT(- getInt(a), n, g) of mUnaryMinusF64: result = newFloatNodeT(- getFloat(a), n, g) of mNot: result = newIntNodeT(1 - getInt(a), n, g) - of mCard: result = newIntNodeT(nimsets.cardSet(a), n, g) + of mCard: result = newIntNodeT(nimsets.cardSet(g.config, a), n, g) of mBitnotI: result = newIntNodeT(not getInt(a), n, g) - of mLengthArray: result = newIntNodeT(lengthOrd(a.typ), n, g) + of mLengthArray: result = newIntNodeT(lengthOrd(g.config, a.typ), n, g) of mLengthSeq, mLengthOpenArray, mXLenSeq, mLengthStr, mXLenStr: if a.kind == nkNilLit: result = newIntNodeT(0, n, g) @@ -229,7 +229,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode = of mAbsI: result = foldAbs(getInt(a), n, g) of mZe8ToI, mZe8ToI64, mZe16ToI, mZe16ToI64, mZe32ToI64, mZeIToI64: # byte(-128) = 1...1..1000_0000'64 --> 0...0..1000_0000'64 - result = newIntNodeT(getInt(a) and (`shl`(1, getSize(a.typ) * 8) - 1), n, g) + result = newIntNodeT(getInt(a) and (`shl`(1, getSize(g.config, a.typ) * 8) - 1), n, g) of mToU8: result = newIntNodeT(getInt(a) and 0x000000FF, n, g) of mToU16: result = newIntNodeT(getInt(a) and 0x0000FFFF, n, g) of mToU32: result = newIntNodeT(getInt(a) and 0x00000000FFFFFFFF'i64, n, g) @@ -304,21 +304,21 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode = of mMulU: result = newIntNodeT(`*%`(getInt(a), getInt(b)), n, g) of mModU: result = foldModU(getInt(a), getInt(b), n, g) of mDivU: result = foldDivU(getInt(a), getInt(b), n, g) - of mLeSet: result = newIntNodeT(ord(containsSets(a, b)), n, g) - of mEqSet: result = newIntNodeT(ord(equalSets(a, b)), n, g) + of mLeSet: result = newIntNodeT(ord(containsSets(g.config, a, b)), n, g) + of mEqSet: result = newIntNodeT(ord(equalSets(g.config, a, b)), n, g) of mLtSet: - result = newIntNodeT(ord(containsSets(a, b) and not equalSets(a, b)), n, g) + result = newIntNodeT(ord(containsSets(g.config, a, b) and not equalSets(g.config, a, b)), n, g) of mMulSet: - result = nimsets.intersectSets(a, b) + result = nimsets.intersectSets(g.config, a, b) result.info = n.info of mPlusSet: - result = nimsets.unionSets(a, b) + result = nimsets.unionSets(g.config, a, b) result.info = n.info of mMinusSet: - result = nimsets.diffSets(a, b) + result = nimsets.diffSets(g.config, a, b) result.info = n.info of mSymDiffSet: - result = nimsets.symdiffSets(a, b) + result = nimsets.symdiffSets(g.config, a, b) result.info = n.info of mConStrStr: result = newStrNodeT(getStrOrChar(a) & getStrOrChar(b), n, g) of mInSet: result = newIntNodeT(ord(inSet(a, b)), n, g) @@ -415,9 +415,9 @@ proc getAppType(n: PNode; g: ModuleGraph): PNode = proc rangeCheck(n: PNode, value: BiggestInt; g: ModuleGraph) = var err = false if n.typ.skipTypes({tyRange}).kind in {tyUInt..tyUInt64}: - err = value <% firstOrd(n.typ) or value >% lastOrd(n.typ, fixedUnsigned=true) + err = value <% firstOrd(g.config, n.typ) or value >% lastOrd(g.config, n.typ, fixedUnsigned=true) else: - err = value < firstOrd(n.typ) or value > lastOrd(n.typ) + err = value < firstOrd(g.config, n.typ) or value > lastOrd(g.config, n.typ) if err: localError(g.config, n.info, "cannot convert " & $value & " to " & typeToString(n.typ)) @@ -472,7 +472,7 @@ proc foldArrayAccess(m: PSym, n: PNode; g: ModuleGraph): PNode = else: localError(g.config, n.info, "index out of bounds: " & $n) of nkBracket: - idx = idx - x.typ.firstOrd + idx = idx - firstOrd(g.config, x.typ) if idx >= 0 and idx < x.len: result = x.sons[int(idx)] else: localError(g.config, n.info, "index out of bounds: " & $n) of nkStrLit..nkTripleStrLit: @@ -547,11 +547,11 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode = "yyyy-MM-dd"), n, g) of mCompileTime: result = newStrNodeT(format(getSrcTimestamp(), "HH:mm:ss"), n, g) - of mCpuEndian: result = newIntNodeT(ord(CPU[targetCPU].endian), n, g) - of mHostOS: result = newStrNodeT(toLowerAscii(platform.OS[targetOS].name), n, g) - of mHostCPU: result = newStrNodeT(platform.CPU[targetCPU].name.toLowerAscii, n, g) - of mBuildOS: result = newStrNodeT(toLowerAscii(platform.OS[platform.hostOS].name), n, g) - of mBuildCPU: result = newStrNodeT(platform.CPU[platform.hostCPU].name.toLowerAscii, n, g) + of mCpuEndian: result = newIntNodeT(ord(CPU[g.config.target.targetCPU].endian), n, g) + of mHostOS: result = newStrNodeT(toLowerAscii(platform.OS[g.config.target.targetOS].name), n, g) + of mHostCPU: result = newStrNodeT(platform.CPU[g.config.target.targetCPU].name.toLowerAscii, n, g) + of mBuildOS: result = newStrNodeT(toLowerAscii(platform.OS[g.config.target.hostOS].name), n, g) + of mBuildCPU: result = newStrNodeT(platform.CPU[g.config.target.hostCPU].name.toLowerAscii, n, g) of mAppType: result = getAppType(n, g) of mNaN: result = newFloatNodeT(NaN, n, g) of mInf: result = newFloatNodeT(Inf, n, g) @@ -599,22 +599,22 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode = return of mSizeOf: var a = n.sons[1] - if computeSize(a.typ) < 0: + if computeSize(g.config, a.typ) < 0: localError(g.config, a.info, "cannot evaluate 'sizeof' because its type is not defined completely") result = nil elif skipTypes(a.typ, typedescInst+{tyRange}).kind in IntegralTypes+NilableTypes+{tySet}: #{tyArray,tyObject,tyTuple}: - result = newIntNodeT(getSize(a.typ), n, g) + result = newIntNodeT(getSize(g.config, a.typ), n, g) else: result = nil # XXX: size computation for complex types is still wrong of mLow: - result = newIntNodeT(firstOrd(n.sons[1].typ), n, g) + result = newIntNodeT(firstOrd(g.config, n.sons[1].typ), n, g) of mHigh: if skipTypes(n.sons[1].typ, abstractVar).kind notin {tySequence, tyString, tyCString, tyOpenArray, tyVarargs}: - result = newIntNodeT(lastOrd(skipTypes(n[1].typ, abstractVar)), n, g) + result = newIntNodeT(lastOrd(g.config, skipTypes(n[1].typ, abstractVar)), n, g) else: var a = getArrayConstr(m, n.sons[1], g) if a.kind == nkBracket: @@ -630,7 +630,7 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode = of mLengthArray: # It doesn't matter if the argument is const or not for mLengthArray. # This fixes bug #544. - result = newIntNodeT(lengthOrd(n.sons[1].typ), n, g) + result = newIntNodeT(lengthOrd(g.config, n.sons[1].typ), n, g) of mAstToStr: result = newStrNodeT(renderTree(n[1], {renderNoComments}), n, g) of mConStrStr: diff --git a/compiler/seminst.nim b/compiler/seminst.nim index a5f0ca7d8..e95b94553 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -328,7 +328,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, inc i if tfTriggersCompileTime in result.typ.flags: incl(result.flags, sfCompileTime) - n.sons[genericParamsPos] = ast.emptyNode + n.sons[genericParamsPos] = c.graph.emptyNode var oldPrc = genericCacheGet(fn, entry[], c.compilesContextId) if oldPrc == nil: # we MUST not add potentially wrong instantiations to the caching mechanism. diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 8515e971d..e60d34e82 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -78,7 +78,7 @@ proc semInstantiationInfo(c: PContext, n: PNode): PNode = let useFullPaths = expectIntLit(c, n.sons[2]) let info = getInfoContext(idx) var filename = newNodeIT(nkStrLit, n.info, getSysType(c.graph, n.info, tyString)) - filename.strVal = if useFullPaths != 0: info.toFullPath else: info.toFilename + filename.strVal = if useFullPaths != 0: toFullPath(c.config, info) else: toFilename(c.config, info) var line = newNodeIT(nkIntLit, n.info, getSysType(c.graph, n.info, tyInt)) line.intVal = toLinenumber(info) var column = newNodeIT(nkIntLit, n.info, getSysType(c.graph, n.info, tyInt)) @@ -154,7 +154,7 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym) result = newIntNodeT(ord(not complexObj), traitCall, c.graph) else: localError(c.config, traitCall.info, "unknown trait") - result = emptyNode + result = newNodeI(nkEmpty, traitCall.info) proc semTypeTraits(c: PContext, n: PNode): PNode = checkMinSonsLen(n, 2, c.config) @@ -174,7 +174,7 @@ proc semOrd(c: PContext, n: PNode): PNode = if isOrdinalType(parType): discard elif parType.kind == tySet: - result.typ = makeRangeType(c, firstOrd(parType), lastOrd(parType), n.info) + result.typ = makeRangeType(c, firstOrd(c.config, parType), lastOrd(c.config, parType), n.info) else: localError(c.config, n.info, errOrdinalTypeExpected) result.typ = errorType(c) @@ -209,10 +209,6 @@ proc semBindSym(c: PContext, n: PNode): PNode = proc semShallowCopy(c: PContext, n: PNode, flags: TExprFlags): PNode -proc isStrangeArray(t: PType): bool = - let t = t.skipTypes(abstractInst) - result = t.kind == tyArray and t.firstOrd != 0 - proc semOf(c: PContext, n: PNode): PNode = if sonsLen(n) == 3: n.sons[1] = semExprWithType(c, n.sons[1]) diff --git a/compiler/semparallel.nim b/compiler/semparallel.nim index ea5aab628..33d24a077 100644 --- a/compiler/semparallel.nim +++ b/compiler/semparallel.nim @@ -136,8 +136,8 @@ proc checkLe(c: AnalysisCtx; a, b: PNode) = localError(c.graph.config, a.info, "can prove: " & ?a & " > " & ?b & " (bounds check)") proc checkBounds(c: AnalysisCtx; arr, idx: PNode) = - checkLe(c, arr.lowBound, idx) - checkLe(c, idx, arr.highBound(c.guards.o)) + checkLe(c, lowBound(c.graph.config, arr), idx) + checkLe(c, idx, highBound(c.graph.config, arr, c.guards.o)) proc addLowerBoundAsFacts(c: var AnalysisCtx) = for v in c.locals: @@ -438,7 +438,7 @@ proc transformSpawn(g: ModuleGraph; owner: PSym; n, barrier: PNode): PNode = let t = b[1][0].typ.sons[0] if spawnResult(t, true) == srByVar: result.add wrapProcForSpawn(g, owner, m, b.typ, barrier, it[0]) - it.sons[it.len-1] = emptyNode + it.sons[it.len-1] = newNodeI(nkEmpty, it.info) else: it.sons[it.len-1] = wrapProcForSpawn(g, owner, m, b.typ, barrier, nil) if result.isNil: result = n diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index b66d7d9f2..2ba2a6ace 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -915,8 +915,8 @@ proc initEffects(g: ModuleGraph; effects: PNode; s: PSym; t: var TEffects) = newSeq(effects.sons, effectListLen) effects.sons[exceptionEffects] = newNodeI(nkArgList, s.info) effects.sons[tagEffects] = newNodeI(nkArgList, s.info) - effects.sons[usesEffects] = ast.emptyNode - effects.sons[writeEffects] = ast.emptyNode + effects.sons[usesEffects] = g.emptyNode + effects.sons[writeEffects] = g.emptyNode t.exc = effects.sons[exceptionEffects] t.tags = effects.sons[tagEffects] diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 3687e50e9..055ac3425 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -36,8 +36,6 @@ const errRecursiveDependencyX = "recursive dependency: '$1'" errPragmaOnlyInHeaderOfProcX = "pragmas are only allowed in the header of a proc; redefinition of $1" -var enforceVoidContext = PType(kind: tyStmt) # XXX global variable here - proc semDiscard(c: PContext, n: PNode): PNode = result = n checkSonsLen(n, 1, c.config) @@ -87,15 +85,15 @@ proc semWhile(c: PContext, n: PNode): PNode = n.sons[1] = semStmt(c, n.sons[1]) dec(c.p.nestedLoopCounter) closeScope(c) - if n.sons[1].typ == enforceVoidContext: - result.typ = enforceVoidContext + if n.sons[1].typ == c.enforceVoidContext: + result.typ = c.enforceVoidContext -proc toCover(t: PType): BiggestInt = +proc toCover(c: PContext, t: PType): BiggestInt = var t2 = skipTypes(t, abstractVarRange-{tyTypeDesc}) if t2.kind == tyEnum and enumHasHoles(t2): result = sonsLen(t2.n) else: - result = lengthOrd(skipTypes(t, abstractVar-{tyTypeDesc})) + result = lengthOrd(c.config, skipTypes(t, abstractVar-{tyTypeDesc})) proc semProc(c: PContext, n: PNode): PNode @@ -146,7 +144,7 @@ proc discardCheck(c: PContext, result: PNode) = result.typ.typeToString & "' and has to be discarded" if result.info.line != n.info.line or result.info.fileIndex != n.info.fileIndex: - s.add "; start of expression here: " & $result.info + s.add "; start of expression here: " & c.config$result.info if result.typ.kind == tyProc: s.add "; for a function call use ()" localError(c.config, n.info, s) @@ -173,7 +171,7 @@ proc semIf(c: PContext, n: PNode): PNode = for it in n: discardCheck(c, it.lastSon) result.kind = nkIfStmt # propagate any enforced VoidContext: - if typ == enforceVoidContext: result.typ = enforceVoidContext + if typ == c.enforceVoidContext: result.typ = c.enforceVoidContext else: for it in n: let j = it.len-1 @@ -230,7 +228,7 @@ proc semCase(c: PContext, n: PNode): PNode = else: illFormedAst(x, c.config) if chckCovered: - if covered == toCover(n.sons[0].typ): + if covered == toCover(c, n.sons[0].typ): hasElse = true else: localError(c.config, n.info, "not all cases are covered") @@ -238,8 +236,8 @@ proc semCase(c: PContext, n: PNode): PNode = if isEmptyType(typ) or typ.kind in {tyNil, tyExpr} or not hasElse: for i in 1..n.len-1: discardCheck(c, n.sons[i].lastSon) # propagate any enforced VoidContext: - if typ == enforceVoidContext: - result.typ = enforceVoidContext + if typ == c.enforceVoidContext: + result.typ = c.enforceVoidContext else: for i in 1..n.len-1: var it = n.sons[i] @@ -318,8 +316,8 @@ proc semTry(c: PContext, n: PNode): PNode = if isEmptyType(typ) or typ.kind in {tyNil, tyExpr}: discardCheck(c, n.sons[0]) for i in 1..n.len-1: discardCheck(c, n.sons[i].lastSon) - if typ == enforceVoidContext: - result.typ = enforceVoidContext + if typ == c.enforceVoidContext: + result.typ = c.enforceVoidContext else: if n.lastSon.kind == nkFinally: discardCheck(c, n.lastSon.lastSon) n.sons[0] = fitNode(c, typ, n.sons[0], n.sons[0].info) @@ -394,7 +392,7 @@ proc isDiscardUnderscore(v: PSym): bool = result = true proc semUsing(c: PContext; n: PNode): PNode = - result = ast.emptyNode + result = c.graph.emptyNode if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "using") for i in countup(0, sonsLen(n)-1): var a = n.sons[i] @@ -481,7 +479,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = typ = semTypeNode(c, a.sons[length-2], nil) else: typ = nil - var def: PNode = ast.emptyNode + var def: PNode = c.graph.emptyNode if a.sons[length-1].kind != nkEmpty: def = semExprWithType(c, a.sons[length-1], {efAllowDestructor}) if def.typ.kind == tyTypeDesc and c.p.owner.kind != skMacro: @@ -698,7 +696,8 @@ proc handleForLoopMacro(c: PContext; n: PNode): PNode = match = symx else: localError(c.config, n.info, errAmbiguousCallXYZ % [ - getProcHeader(match), getProcHeader(symx), $iterExpr]) + getProcHeader(c.config, match), + getProcHeader(c.config, symx), $iterExpr]) symx = nextOverloadIter(o, c, headSymbol) if match == nil: return @@ -746,8 +745,8 @@ proc semFor(c: PContext, n: PNode): PNode = else: result = semForVars(c, n) # propagate any enforced VoidContext: - if n.sons[length-1].typ == enforceVoidContext: - result.typ = enforceVoidContext + if n.sons[length-1].typ == c.enforceVoidContext: + result.typ = c.enforceVoidContext closeScope(c) proc semRaise(c: PContext, n: PNode): PNode = @@ -834,7 +833,7 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) = typsym.info = s.info else: localError(c.config, name.info, "cannot complete type '" & s.name.s & "' twice; " & - "previous type completion was here: " & $typsym.info) + "previous type completion was here: " & c.config$typsym.info) s = typsym # add it here, so that recursive types are possible: if sfGenSym notin s.flags: addInterfaceDecl(c, s) @@ -1056,7 +1055,7 @@ proc semAllTypeSections(c: PContext; n: PNode): PNode = var f = checkModuleName(c.config, n.sons[i]) if f != InvalidFileIDX: if containsOrIncl(c.includedFiles, f.int): - localError(c.config, n.info, errRecursiveDependencyX % f.toFilename) + localError(c.config, n.info, errRecursiveDependencyX % toFilename(c.config, f)) else: let code = gIncludeFile(c.graph, c.module, f, c.cache) gatherStmts c, code, result @@ -1176,7 +1175,7 @@ proc semProcAnnotation(c: PContext, prc: PNode; x.add(newSymNode(m)) prc.sons[pragmasPos] = copyExcept(n, i) if prc[pragmasPos].kind != nkEmpty and prc[pragmasPos].len == 0: - prc.sons[pragmasPos] = emptyNode + prc.sons[pragmasPos] = c.graph.emptyNode if it.kind in nkPragmaCallKinds and it.len > 1: # pass pragma arguments to the macro too: @@ -1199,7 +1198,7 @@ proc setGenericParamsMisc(c: PContext; n: PNode): PNode = # issue https://github.com/nim-lang/Nim/issues/1713 result = semGenericParamList(c, orig) if n.sons[miscPos].kind == nkEmpty: - n.sons[miscPos] = newTree(nkBracket, ast.emptyNode, orig) + n.sons[miscPos] = newTree(nkBracket, c.graph.emptyNode, orig) else: n.sons[miscPos].sons[1] = orig n.sons[genericParamsPos] = result @@ -1270,7 +1269,7 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode = result = n s.ast = result n.sons[namePos].sym = s - n.sons[genericParamsPos] = emptyNode + n.sons[genericParamsPos] = c.graph.emptyNode # for LL we need to avoid wrong aliasing let params = copyTree n.typ.n n.sons[paramsPos] = params @@ -1543,7 +1542,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, # linking names do agree: if proto.typ.callConv != s.typ.callConv or proto.typ.flags < s.typ.flags: localError(c.config, n.sons[pragmasPos].info, errPragmaOnlyInHeaderOfProcX % - ("'" & proto.name.s & "' from " & $proto.info)) + ("'" & proto.name.s & "' from " & c.config$proto.info)) if sfForward notin proto.flags: wrongRedefinition(c, n.info, proto.name.s) excl(proto.flags, sfForward) @@ -1613,7 +1612,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, if s.kind == skMethod: semMethodPrototype(c, s, n) if sfImportc in s.flags: # so we just ignore the body after semantic checking for importc: - n.sons[bodyPos] = ast.emptyNode + n.sons[bodyPos] = c.graph.emptyNode popProcCon(c) else: if s.kind == skMethod: semMethodPrototype(c, s, n) @@ -1692,7 +1691,7 @@ proc semMethod(c: PContext, n: PNode): PNode = let ret = s.typ.sons[0] disp.typ.sons[0] = ret if disp.ast[resultPos].kind == nkSym: - if isEmptyType(ret): disp.ast.sons[resultPos] = emptyNode + if isEmptyType(ret): disp.ast.sons[resultPos] = c.graph.emptyNode else: disp.ast[resultPos].sym.typ = ret proc semConverterDef(c: PContext, n: PNode): PNode = @@ -1738,7 +1737,7 @@ proc evalInclude(c: PContext, n: PNode): PNode = var f = checkModuleName(c.config, n.sons[i]) if f != InvalidFileIDX: if containsOrIncl(c.includedFiles, f.int): - localError(c.config, n.info, errRecursiveDependencyX % f.toFilename) + localError(c.config, n.info, errRecursiveDependencyX % toFilename(c.config, f)) else: addSon(result, semStmt(c, gIncludeFile(c.graph, c.module, f, c.cache))) excl(c.includedFiles, f.int) @@ -1771,7 +1770,7 @@ proc semStaticStmt(c: PContext, n: PNode): PNode = n.sons[0] = a evalStaticStmt(c.module, c.cache, c.graph, a, c.p.owner) result = newNodeI(nkDiscardStmt, n.info, 1) - result.sons[0] = emptyNode + result.sons[0] = c.graph.emptyNode proc usesResult(n: PNode): bool = # nkStmtList(expr) properly propagates the void context, @@ -1834,9 +1833,9 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = localError(c.config, result.info, "concept predicate failed") of tyUnknown: continue else: discard - if n.sons[i].typ == enforceVoidContext: #or usesResult(n.sons[i]): + if n.sons[i].typ == c.enforceVoidContext: #or usesResult(n.sons[i]): voidContext = true - n.typ = enforceVoidContext + n.typ = c.enforceVoidContext if i == last and (length == 1 or efWantValue in flags): n.typ = n.sons[i].typ if not isEmptyType(n.typ): n.kind = nkStmtListExpr diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 8b5c26f99..17566548d 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -66,7 +66,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = base = semTypeNode(c, n.sons[0].sons[0], nil) if base.kind != tyEnum: localError(c.config, n.sons[0].info, "inheritance only works with an enum") - counter = lastOrd(base) + 1 + counter = lastOrd(c.config, base) + 1 rawAddSon(result, base) let isPure = result.sym != nil and sfPure in result.sym.flags var symbols: TStrTable @@ -133,7 +133,7 @@ proc semSet(c: PContext, n: PNode, prev: PType): PType = if base.kind != tyGenericParam: if not isOrdinalType(base): localError(c.config, n.info, errOrdinalTypeExpected) - elif lengthOrd(base) > MaxSetElements: + elif lengthOrd(c.config, base) > MaxSetElements: localError(c.config, n.info, errSetTooBig) else: localError(c.config, n.info, errXExpectsOneTypeParam % "set") @@ -553,7 +553,7 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int, inc(covered) else: if r.kind == nkCurly: - r = r.deduplicate + r = deduplicate(c.config, r) # first element is special and will overwrite: branch.sons[i]: branch.sons[i] = semCaseBranchSetElem(c, t, r[0], covered) @@ -584,10 +584,10 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int, var typ = skipTypes(a.sons[0].typ, abstractVar-{tyTypeDesc}) if not isOrdinalType(typ): localError(c.config, n.info, "selector must be of an ordinal type") - elif firstOrd(typ) != 0: + elif firstOrd(c.config, typ) != 0: localError(c.config, n.info, "low(" & $a.sons[0].sym.name.s & ") must be 0 for discriminant") - elif lengthOrd(typ) > 0x00007FFF: + elif lengthOrd(c.config, typ) > 0x00007FFF: localError(c.config, n.info, "len($1) must be less than 32768" % a.sons[0].sym.name.s) var chckCovered = true for i in countup(1, sonsLen(n) - 1): @@ -603,7 +603,7 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int, else: illFormedAst(n, c.config) delSon(b, sonsLen(b) - 1) semRecordNodeAux(c, lastSon(n.sons[i]), check, pos, b, rectype) - if chckCovered and covered != lengthOrd(a.sons[0].typ): + if chckCovered and covered != lengthOrd(c.config, a.sons[0].typ): localError(c.config, a.info, "not all cases are covered") addSon(father, a) @@ -658,7 +658,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, var length = sonsLen(n) var a: PNode if father.kind != nkRecList and length>=4: a = newNodeI(nkRecList, n.info) - else: a = ast.emptyNode + else: a = newNodeI(nkEmpty, n.info) if n.sons[length-1].kind != nkEmpty: localError(c.config, n.sons[length-1].info, errInitHereNotAllowed) var typ: PType @@ -1585,7 +1585,7 @@ when false: result = semTypeNodeInner(c, n, prev) instAllTypeBoundOp(c, n.info) -proc setMagicType(m: PSym, kind: TTypeKind, size: int) = +proc setMagicType(conf: ConfigRef; m: PSym, kind: TTypeKind, size: int) = # source : https://en.wikipedia.org/wiki/Data_structure_alignment#x86 m.typ.kind = kind m.typ.size = size @@ -1596,10 +1596,10 @@ proc setMagicType(m: PSym, kind: TTypeKind, size: int) = # FIXME: proper support for clongdouble should be added. # long double size can be 8, 10, 12, 16 bytes depending on platform & compiler - if targetCPU == cpuI386 and size == 8: + if conf.target.targetCPU == cpuI386 and size == 8: #on Linux/BSD i386, double are aligned to 4bytes (except with -malign-double) if kind in {tyFloat64, tyFloat} and - targetOS in {osLinux, osAndroid, osNetbsd, osFreebsd, osOpenbsd, osDragonfly}: + conf.target.targetOS in {osLinux, osAndroid, osNetbsd, osFreebsd, osOpenbsd, osDragonfly}: m.typ.align = 4 # on i386, all known compiler, 64bits ints are aligned to 4bytes (except with -malign-double) elif kind in {tyInt, tyUInt, tyInt64, tyUInt64}: @@ -1609,73 +1609,73 @@ proc setMagicType(m: PSym, kind: TTypeKind, size: int) = proc processMagicType(c: PContext, m: PSym) = case m.magic - of mInt: setMagicType(m, tyInt, intSize) - of mInt8: setMagicType(m, tyInt8, 1) - of mInt16: setMagicType(m, tyInt16, 2) - of mInt32: setMagicType(m, tyInt32, 4) - of mInt64: setMagicType(m, tyInt64, 8) - of mUInt: setMagicType(m, tyUInt, intSize) - of mUInt8: setMagicType(m, tyUInt8, 1) - of mUInt16: setMagicType(m, tyUInt16, 2) - of mUInt32: setMagicType(m, tyUInt32, 4) - of mUInt64: setMagicType(m, tyUInt64, 8) - of mFloat: setMagicType(m, tyFloat, floatSize) - of mFloat32: setMagicType(m, tyFloat32, 4) - of mFloat64: setMagicType(m, tyFloat64, 8) - of mFloat128: setMagicType(m, tyFloat128, 16) - of mBool: setMagicType(m, tyBool, 1) - of mChar: setMagicType(m, tyChar, 1) + of mInt: setMagicType(c.config, m, tyInt, c.config.target.intSize) + of mInt8: setMagicType(c.config, m, tyInt8, 1) + of mInt16: setMagicType(c.config, m, tyInt16, 2) + of mInt32: setMagicType(c.config, m, tyInt32, 4) + of mInt64: setMagicType(c.config, m, tyInt64, 8) + of mUInt: setMagicType(c.config, m, tyUInt, c.config.target.intSize) + of mUInt8: setMagicType(c.config, m, tyUInt8, 1) + of mUInt16: setMagicType(c.config, m, tyUInt16, 2) + of mUInt32: setMagicType(c.config, m, tyUInt32, 4) + of mUInt64: setMagicType(c.config, m, tyUInt64, 8) + of mFloat: setMagicType(c.config, m, tyFloat, c.config.target.floatSize) + of mFloat32: setMagicType(c.config, m, tyFloat32, 4) + of mFloat64: setMagicType(c.config, m, tyFloat64, 8) + of mFloat128: setMagicType(c.config, m, tyFloat128, 16) + of mBool: setMagicType(c.config, m, tyBool, 1) + of mChar: setMagicType(c.config, m, tyChar, 1) of mString: - setMagicType(m, tyString, ptrSize) + setMagicType(c.config, m, tyString, c.config.target.ptrSize) rawAddSon(m.typ, getSysType(c.graph, m.info, tyChar)) of mCstring: - setMagicType(m, tyCString, ptrSize) + setMagicType(c.config, m, tyCString, c.config.target.ptrSize) rawAddSon(m.typ, getSysType(c.graph, m.info, tyChar)) - of mPointer: setMagicType(m, tyPointer, ptrSize) + of mPointer: setMagicType(c.config, m, tyPointer, c.config.target.ptrSize) of mEmptySet: - setMagicType(m, tySet, 1) + setMagicType(c.config, m, tySet, 1) rawAddSon(m.typ, newTypeS(tyEmpty, c)) - of mIntSetBaseType: setMagicType(m, tyRange, intSize) - of mNil: setMagicType(m, tyNil, ptrSize) + of mIntSetBaseType: setMagicType(c.config, m, tyRange, c.config.target.intSize) + of mNil: setMagicType(c.config, m, tyNil, c.config.target.ptrSize) of mExpr: if m.name.s == "auto": - setMagicType(m, tyAnything, 0) + setMagicType(c.config, m, tyAnything, 0) else: - setMagicType(m, tyExpr, 0) + setMagicType(c.config, m, tyExpr, 0) if m.name.s == "expr": m.typ.flags.incl tfOldSchoolExprStmt of mStmt: - setMagicType(m, tyStmt, 0) + setMagicType(c.config, m, tyStmt, 0) if m.name.s == "stmt": m.typ.flags.incl tfOldSchoolExprStmt of mTypeDesc: - setMagicType(m, tyTypeDesc, 0) + setMagicType(c.config, m, tyTypeDesc, 0) rawAddSon(m.typ, newTypeS(tyNone, c)) of mVoidType: - setMagicType(m, tyVoid, 0) + setMagicType(c.config, m, tyVoid, 0) of mArray: - setMagicType(m, tyArray, 0) + setMagicType(c.config, m, tyArray, 0) of mOpenArray: - setMagicType(m, tyOpenArray, 0) + setMagicType(c.config, m, tyOpenArray, 0) of mVarargs: - setMagicType(m, tyVarargs, 0) + setMagicType(c.config, m, tyVarargs, 0) of mRange: - setMagicType(m, tyRange, 0) + setMagicType(c.config, m, tyRange, 0) rawAddSon(m.typ, newTypeS(tyNone, c)) of mSet: - setMagicType(m, tySet, 0) + setMagicType(c.config, m, tySet, 0) of mSeq: - setMagicType(m, tySequence, 0) + setMagicType(c.config, m, tySequence, 0) of mOpt: - setMagicType(m, tyOpt, 0) + setMagicType(c.config, m, tyOpt, 0) of mOrdinal: - setMagicType(m, tyOrdinal, 0) + setMagicType(c.config, m, tyOrdinal, 0) rawAddSon(m.typ, newTypeS(tyNone, c)) of mPNimrodNode: incl m.typ.flags, tfTriggersCompileTime of mException: discard of mBuiltinType: case m.name.s - of "lent": setMagicType(m, tyLent, ptrSize) - of "sink": setMagicType(m, tySink, 0) + of "lent": setMagicType(c.config, m, tyLent, c.config.target.ptrSize) + of "sink": setMagicType(c.config, m, tySink, 0) else: localError(c.config, m.info, errTypeExpected) else: localError(c.config, m.info, errTypeExpected) diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 61d92bb19..993cacb5e 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -27,7 +27,7 @@ proc checkConstructedType*(conf: ConfigRef; info: TLineInfo, typ: PType) = localError(conf, info, "invalid pragma: acyclic") elif t.kind in {tyVar, tyLent} and t.sons[0].kind in {tyVar, tyLent}: localError(conf, info, "type 'var var' is not allowed") - elif computeSize(t) == szIllegalRecursion: + elif computeSize(conf, t) == szIllegalRecursion: localError(conf, info, "illegal recursion in type '" & typeToString(t) & "'") when false: if t.kind == tyObject and t.sons[0] != nil: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 41cac2a4a..8fdf10afb 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -253,7 +253,7 @@ proc complexDisambiguation(a, b: PType): int = result = x - y proc writeMatches*(c: TCandidate) = - echo "Candidate '", c.calleeSym.name.s, "' at ", c.calleeSym.info + echo "Candidate '", c.calleeSym.name.s, "' at ", c.c.config $ c.calleeSym.info echo " exact matches: ", c.exactMatches echo " generic matches: ", c.genericMatches echo " subtype matches: ", c.subtypeMatches @@ -376,8 +376,10 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation = if k == f.kind: result = isSubrange elif k == tyInt and f.kind in {tyRange, tyInt8..tyInt64, tyUInt..tyUInt64} and - isIntLit(ab) and ab.n.intVal >= firstOrd(f) and - ab.n.intVal <= lastOrd(f): + isIntLit(ab) and ab.n.intVal >= firstOrd(nil, f) and + ab.n.intVal <= lastOrd(nil, f): + # passing 'nil' to firstOrd/lastOrd here as type checking rules should + # not depent on the target integer size configurations! # integer literal in the proper range; we want ``i16 + 4`` to stay an # ``int16`` operation so we declare the ``4`` pseudo-equal to int16 result = isFromIntLit @@ -387,8 +389,10 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation = result = isConvertible elif a.kind == tyRange and a.sons[0].kind in {tyInt..tyInt64, tyUInt8..tyUInt32} and - a.n[0].intVal >= firstOrd(f) and - a.n[1].intVal <= lastOrd(f): + a.n[0].intVal >= firstOrd(nil, f) and + a.n[1].intVal <= lastOrd(nil, f): + # passing 'nil' to firstOrd/lastOrd here as type checking rules should + # not depent on the target integer size configurations! result = isConvertible else: result = isNone #elif f.kind == tyInt and k in {tyInt..tyInt32}: result = isIntConv @@ -634,10 +638,10 @@ proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation = proc typeRangeRel(f, a: PType): TTypeRelation {.noinline.} = let - a0 = firstOrd(a) - a1 = lastOrd(a) - f0 = firstOrd(f) - f1 = lastOrd(f) + a0 = firstOrd(nil, a) + a1 = lastOrd(nil, a) + f0 = firstOrd(nil, f) + f1 = lastOrd(nil, f) if a0 == f0 and a1 == f1: result = isEqual elif a0 >= f0 and a1 <= f1: @@ -887,17 +891,17 @@ proc inferStaticsInRange(c: var TCandidate, if inferStaticParam(c, exp, rhs): return isGeneric else: - failureToInferStaticParam(c.c.graph.config, exp) + failureToInferStaticParam(c.c.config, exp) if lowerBound.kind == nkIntLit: if upperBound.kind == nkIntLit: - if lengthOrd(concrete) == upperBound.intVal - lowerBound.intVal + 1: + if lengthOrd(c.c.config, concrete) == upperBound.intVal - lowerBound.intVal + 1: return isGeneric else: return isNone - doInferStatic(upperBound, lengthOrd(concrete) + lowerBound.intVal - 1) + doInferStatic(upperBound, lengthOrd(c.c.config, concrete) + lowerBound.intVal - 1) elif upperBound.kind == nkIntLit: - doInferStatic(lowerBound, upperBound.intVal + 1 - lengthOrd(concrete)) + doInferStatic(lowerBound, upperBound.intVal + 1 - lengthOrd(c.c.config, concrete)) template subtypeCheck() = if result <= isSubrange and f.lastSon.skipTypes(abstractInst).kind in {tyRef, tyPtr, tyVar, tyLent}: @@ -1176,7 +1180,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType, elif c.c.matchedConcept != nil and aRange.rangeHasUnresolvedStatic: return inferStaticsInRange(c, aRange, f) else: - if lengthOrd(fRange) != lengthOrd(aRange): + if lengthOrd(c.c.config, fRange) != lengthOrd(c.c.config, aRange): result = isNone else: discard of tyOpenArray, tyVarargs: @@ -1342,7 +1346,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType, if a.len == 1: let pointsTo = a.sons[0].skipTypes(abstractInst) if pointsTo.kind == tyChar: result = isConvertible - elif pointsTo.kind == tyArray and firstOrd(pointsTo.sons[0]) == 0 and + elif pointsTo.kind == tyArray and firstOrd(nil, pointsTo.sons[0]) == 0 and skipTypes(pointsTo.sons[0], {tyRange}).kind in {tyInt..tyInt64} and pointsTo.sons[1].kind == tyChar: result = isConvertible @@ -1774,7 +1778,7 @@ proc implicitConv(kind: TNodeKind, f: PType, arg: PNode, m: TCandidate, else: result.typ = f if result.typ == nil: internalError(c.graph.config, arg.info, "implicitConv") - addSon(result, ast.emptyNode) + addSon(result, c.graph.emptyNode) addSon(result, arg) proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType, @@ -1993,7 +1997,10 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType, return arg elif a.kind == tyVoid and f.matchesVoidProc and argOrig.kind == nkStmtList: # lift do blocks without params to lambdas - let lifted = c.semExpr(c, newProcNode(nkDo, argOrig.info, argOrig), {}) + let p = c.graph + let lifted = c.semExpr(c, newProcNode(nkDo, argOrig.info, body = argOrig, + params = p.emptyNode, name = p.emptyNode, pattern = p.emptyNode, + genericParams = p.emptyNode, pragmas = p.emptyNode, exceptions = p.emptyNode), {}) if f.kind == tyBuiltInTypeClass: inc m.genericMatches put(m, f, lifted.typ) @@ -2354,7 +2361,7 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) = proc argtypeMatches*(c: PContext, f, a: PType): bool = var m: TCandidate initCandidate(c, m, f) - let res = paramTypesMatch(m, f, a, ast.emptyNode, nil) + let res = paramTypesMatch(m, f, a, c.graph.emptyNode, nil) #instantiateGenericConverters(c, res, m) # XXX this is used by patterns.nim too; I think it's better to not # instantiate generic converters for that diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 23aecfa71..0700b4140 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -143,7 +143,7 @@ proc symToSuggest(conf: ConfigRef; s: PSym, isLocal: bool, section: IdeCmd, info when not defined(noDocgen): result.doc = s.extractDocComment let infox = if section in {ideUse, ideHighlight, ideOutline}: info else: s.info - result.filePath = toFullPath(infox) + result.filePath = toFullPath(conf, infox) result.line = toLinenumber(infox) result.column = toColumn(infox) @@ -342,7 +342,7 @@ proc suggestFieldAccess(c: PContext, n, field: PNode, outputs: var Suggestions) when defined(nimsuggest): if n.kind == nkSym and n.sym.kind == skError and suggestVersion == 0: # consider 'foo.|' where 'foo' is some not imported module. - let fullPath = findModule(c.config, n.sym.name.s, n.info.toFullPath) + let fullPath = findModule(c.config, n.sym.name.s, toFullPath(c.config, n.info)) if fullPath.len == 0: # error: no known module name: typ = nil @@ -510,7 +510,7 @@ proc safeSemExpr*(c: PContext, n: PNode): PNode = try: result = c.semExpr(c, n) except ERecoverableError: - result = ast.emptyNode + result = c.graph.emptyNode proc sugExpr(c: PContext, n: PNode, outputs: var Suggestions) = if n.kind == nkDotExpr: diff --git a/compiler/syntaxes.nim b/compiler/syntaxes.nim index 4bc153e46..cb12629b4 100644 --- a/compiler/syntaxes.nim +++ b/compiler/syntaxes.nim @@ -38,7 +38,6 @@ proc parseAll*(p: var TParsers): PNode = result = parser.parseAll(p.parser) of skinEndX: internalError(p.config, "parser to implement") - result = ast.emptyNode proc parseTopLevelStmt*(p: var TParsers): PNode = case p.skin @@ -46,7 +45,6 @@ proc parseTopLevelStmt*(p: var TParsers): PNode = result = parser.parseTopLevelStmt(p.parser) of skinEndX: internalError(p.config, "parser to implement") - result = ast.emptyNode proc utf8Bom(s: string): int = if s.len >= 3 and s[0] == '\xEF' and s[1] == '\xBB' and s[2] == '\xBF': @@ -62,7 +60,7 @@ proc containsShebang(s: string, i: int): bool = proc parsePipe(filename: string, inputStream: PLLStream; cache: IdentCache; config: ConfigRef): PNode = - result = ast.emptyNode + result = newNode(nkEmpty) var s = llStreamOpen(filename, fmRead) if s != nil: var line = newStringOfCap(80) @@ -144,7 +142,7 @@ proc openParsers*(p: var TParsers, fileIdx: FileIndex, inputstream: PLLStream; assert config != nil var s: PLLStream p.skin = skinStandard - let filename = fileIdx.toFullPathConsiderDirty + let filename = toFullPathConsiderDirty(config, fileIdx) var pipe = parsePipe(filename, inputstream, cache, config) p.config() = config if pipe != nil: s = evalPipe(p, pipe, filename, inputstream) @@ -162,7 +160,7 @@ proc parseFile*(fileIdx: FileIndex; cache: IdentCache; config: ConfigRef): PNode var p: TParsers f: File - let filename = fileIdx.toFullPathConsiderDirty + let filename = toFullPathConsiderDirty(config, fileIdx) if not open(f, filename): rawMessage(config, errGenerated, "cannot open file: " & filename) return diff --git a/compiler/transf.nim b/compiler/transf.nim index a10e8a1e5..4bd57d9d3 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -194,7 +194,7 @@ proc transformVarSection(c: PTransf, v: PNode): PTransNode = idNodeTablePut(c.transCon.mapping, it.sons[j].sym, x) defs[j] = x.PTransNode assert(it.sons[L-2].kind == nkEmpty) - defs[L-2] = ast.emptyNode.PTransNode + defs[L-2] = newNodeI(nkEmpty, it.info).PTransNode defs[L-1] = transform(c, it.sons[L-1]) result[i] = defs @@ -393,7 +393,7 @@ proc generateThunk(c: PTransf; prc: PNode, dest: PType): PNode = if c.graph.config.cmd == cmdCompileToJS: return prc result = newNodeIT(nkClosure, prc.info, dest) var conv = newNodeIT(nkHiddenSubConv, prc.info, dest) - conv.add(emptyNode) + conv.add(newNodeI(nkEmpty, prc.info)) conv.add(prc) if prc.kind == nkClosure: internalError(c.graph.config, prc.info, "closure to closure created") @@ -410,8 +410,8 @@ proc transformConv(c: PTransf, n: PNode): PTransNode = if not isOrdinalType(source): # float -> int conversions. ugh. result = transformSons(c, n) - elif firstOrd(n.typ) <= firstOrd(n.sons[1].typ) and - lastOrd(n.sons[1].typ) <= lastOrd(n.typ): + elif firstOrd(c.graph.config, n.typ) <= firstOrd(c.graph.config, n.sons[1].typ) and + lastOrd(c.graph.config, n.sons[1].typ) <= lastOrd(c.graph.config, n.typ): # BUGFIX: simply leave n as it is; we need a nkConv node, # but no range check: result = transformSons(c, n) @@ -423,8 +423,8 @@ proc transformConv(c: PTransf, n: PNode): PTransNode = result = newTransNode(nkChckRange, n, 3) dest = skipTypes(n.typ, abstractVar) result[0] = transform(c, n.sons[1]) - result[1] = newIntTypeNode(nkIntLit, firstOrd(dest), dest).PTransNode - result[2] = newIntTypeNode(nkIntLit, lastOrd(dest), dest).PTransNode + result[1] = newIntTypeNode(nkIntLit, firstOrd(c.graph.config, dest), dest).PTransNode + result[2] = newIntTypeNode(nkIntLit, lastOrd(c.graph.config, dest), dest).PTransNode of tyFloat..tyFloat128: # XXX int64 -> float conversion? if skipTypes(n.typ, abstractVar).kind == tyRange: @@ -721,16 +721,16 @@ proc transformExceptBranch(c: PTransf, n: PNode): PTransNode = let actions = newTransNode(nkStmtListExpr, n[1], 2) # Generating `let exc = (excType)(getCurrentException())` # -> getCurrentException() - let excCall = PTransNode(callCodegenProc(c.graph, "getCurrentException", ast.emptyNode)) + let excCall = PTransNode(callCodegenProc(c.graph, "getCurrentException", newNodeI(nkEmpty, n.info))) # -> (excType) let convNode = newTransNode(nkHiddenSubConv, n[1].info, 2) - convNode[0] = PTransNode(ast.emptyNode) + convNode[0] = PTransNode(newNodeI(nkEmpty, n.info)) convNode[1] = excCall PNode(convNode).typ = excTypeNode.typ.toRef() # -> let exc = ... let identDefs = newTransNode(nkIdentDefs, n[1].info, 3) identDefs[0] = PTransNode(n[0][2]) - identDefs[1] = PTransNode(ast.emptyNode) + identDefs[1] = PTransNode(newNodeI(nkEmpty, n.info)) identDefs[2] = convNode let letSection = newTransNode(nkLetSection, n[1].info, 1) diff --git a/compiler/types.nim b/compiler/types.nim index b5f4fbf54..4b6cb105c 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -102,7 +102,7 @@ proc isIntLit*(t: PType): bool {.inline.} = proc isFloatLit*(t: PType): bool {.inline.} = result = t.kind == tyFloat and t.n != nil and t.n.kind == nkFloatLit -proc getProcHeader*(sym: PSym; prefer: TPreferedDesc = preferName): string = +proc getProcHeader*(conf: ConfigRef; sym: PSym; prefer: TPreferedDesc = preferName): string = result = sym.owner.name.s & '.' & sym.name.s & '(' var n = sym.typ.n for i in countup(1, sonsLen(n) - 1): @@ -118,7 +118,7 @@ proc getProcHeader*(sym: PSym; prefer: TPreferedDesc = preferName): string = if n.sons[0].typ != nil: result.add(": " & typeToString(n.sons[0].typ, prefer)) result.add "[declared in " - result.add($sym.info) + result.add(conf$sym.info) result.add "]" proc elemType*(t: PType): PType = @@ -589,18 +589,18 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = result = typeToStr[t.kind] result.addTypeFlags(t) -proc firstOrd*(t: PType): BiggestInt = +proc firstOrd*(conf: ConfigRef; t: PType): BiggestInt = case t.kind of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs, tyProxy: result = 0 - of tySet, tyVar: result = firstOrd(t.sons[0]) - of tyArray: result = firstOrd(t.sons[0]) + of tySet, tyVar: result = firstOrd(conf, t.sons[0]) + of tyArray: result = firstOrd(conf, t.sons[0]) of tyRange: assert(t.n != nil) # range directly given: assert(t.n.kind == nkRange) result = getOrdValue(t.n.sons[0]) of tyInt: - if platform.intSize == 4: result = - (2147483646) - 2 + if conf != nil and conf.target.intSize == 4: result = - (2147483646) - 2 else: result = 0x8000000000000000'i64 of tyInt8: result = - 128 of tyInt16: result = - 32768 @@ -610,38 +610,38 @@ proc firstOrd*(t: PType): BiggestInt = of tyEnum: # if basetype <> nil then return firstOrd of basetype if sonsLen(t) > 0 and t.sons[0] != nil: - result = firstOrd(t.sons[0]) + result = firstOrd(conf, t.sons[0]) else: assert(t.n.sons[0].kind == nkSym) result = t.n.sons[0].sym.position of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tyStatic, tyInferred: - result = firstOrd(lastSon(t)) + result = firstOrd(conf, lastSon(t)) of tyOrdinal: - if t.len > 0: result = firstOrd(lastSon(t)) - else: internalError(newPartialConfigRef(), "invalid kind for firstOrd(" & $t.kind & ')') + if t.len > 0: result = firstOrd(conf, lastSon(t)) + else: internalError(conf, "invalid kind for firstOrd(" & $t.kind & ')') else: - internalError(newPartialConfigRef(), "invalid kind for firstOrd(" & $t.kind & ')') + internalError(conf, "invalid kind for firstOrd(" & $t.kind & ')') result = 0 -proc lastOrd*(t: PType; fixedUnsigned = false): BiggestInt = +proc lastOrd*(conf: ConfigRef; t: PType; fixedUnsigned = false): BiggestInt = case t.kind of tyBool: result = 1 of tyChar: result = 255 - of tySet, tyVar: result = lastOrd(t.sons[0]) - of tyArray: result = lastOrd(t.sons[0]) + of tySet, tyVar: result = lastOrd(conf, t.sons[0]) + of tyArray: result = lastOrd(conf, t.sons[0]) of tyRange: assert(t.n != nil) # range directly given: assert(t.n.kind == nkRange) result = getOrdValue(t.n.sons[1]) of tyInt: - if platform.intSize == 4: result = 0x7FFFFFFF + if conf != nil and conf.target.intSize == 4: result = 0x7FFFFFFF else: result = 0x7FFFFFFFFFFFFFFF'i64 of tyInt8: result = 0x0000007F of tyInt16: result = 0x00007FFF of tyInt32: result = 0x7FFFFFFF of tyInt64: result = 0x7FFFFFFFFFFFFFFF'i64 of tyUInt: - if platform.intSize == 4: result = 0xFFFFFFFF + if conf != nil and conf.target.intSize == 4: result = 0xFFFFFFFF elif fixedUnsigned: result = 0xFFFFFFFFFFFFFFFF'i64 else: result = 0x7FFFFFFFFFFFFFFF'i64 of tyUInt8: result = 0xFF @@ -654,27 +654,27 @@ proc lastOrd*(t: PType; fixedUnsigned = false): BiggestInt = assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym) result = t.n.sons[sonsLen(t.n) - 1].sym.position of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tyStatic, tyInferred: - result = lastOrd(lastSon(t)) + result = lastOrd(conf, lastSon(t)) of tyProxy: result = 0 of tyOrdinal: - if t.len > 0: result = lastOrd(lastSon(t)) - else: internalError(newPartialConfigRef(), "invalid kind for lastOrd(" & $t.kind & ')') + if t.len > 0: result = lastOrd(conf, lastSon(t)) + else: internalError(conf, "invalid kind for lastOrd(" & $t.kind & ')') else: - internalError(newPartialConfigRef(), "invalid kind for lastOrd(" & $t.kind & ')') + internalError(conf, "invalid kind for lastOrd(" & $t.kind & ')') result = 0 -proc lengthOrd*(t: PType): BiggestInt = +proc lengthOrd*(conf: ConfigRef; t: PType): BiggestInt = case t.kind - of tyInt64, tyInt32, tyInt: result = lastOrd(t) - of tyDistinct: result = lengthOrd(t.sons[0]) + of tyInt64, tyInt32, tyInt: result = lastOrd(conf, t) + of tyDistinct: result = lengthOrd(conf, t.sons[0]) else: - let last = lastOrd t - let first = firstOrd t + let last = lastOrd(conf, t) + let first = firstOrd(conf, t) # XXX use a better overflow check here: if last == high(BiggestInt) and first <= 0: result = last else: - result = lastOrd(t) - firstOrd(t) + 1 + result = lastOrd(conf, t) - firstOrd(conf, t) + 1 # -------------- type equality ----------------------------------------------- @@ -1205,81 +1205,24 @@ proc typeAllowed*(t: PType, kind: TSymKind; flags: TTypeAllowedFlags = {}): PTyp proc align(address, alignment: BiggestInt): BiggestInt = result = (address + (alignment - 1)) and not (alignment - 1) -type - OptKind* = enum ## What to map 'opt T' to internally. - oBool ## opt[T] requires an additional 'bool' field - oNil ## opt[T] has no overhead since 'nil' - ## is available - oEnum ## We can use some enum value that is not yet - ## used for opt[T] - oPtr ## opt[T] actually introduces a hidden pointer - ## in order for the type recursion to work - -proc optKind*(typ: PType): OptKind = - ## return true iff 'opt[T]' can be mapped to 'T' internally - ## because we have a 'nil' value available: - assert typ.kind == tyOpt - case typ.sons[0].skipTypes(abstractInst).kind - of tyRef, tyPtr, tyProc: - result = oNil - of tyArray, tyObject, tyTuple: - result = oPtr - of tyBool: result = oEnum - of tyEnum: - assert(typ.n.sons[0].kind == nkSym) - if typ.n.sons[0].sym.position != low(int): - result = oEnum - else: - result = oBool - else: - result = oBool - -proc optLowering*(typ: PType): PType = - case optKind(typ) - of oNil: result = typ.sons[0] - of oPtr: - result = newType(tyOptAsRef, typ.owner) - result.rawAddSon typ.sons[0] - of oBool: - result = newType(tyTuple, typ.owner) - result.rawAddSon newType(tyBool, typ.owner) - result.rawAddSon typ.sons[0] - of oEnum: - if lastOrd(typ) + 1 < `shl`(BiggestInt(1), 32): - result = newType(tyInt32, typ.owner) - else: - result = newType(tyInt64, typ.owner) - -proc optEnumValue*(typ: PType): BiggestInt = - assert typ.kind == tyOpt - assert optKind(typ) == oEnum - let elem = typ.sons[0].skipTypes(abstractInst).kind - if elem == tyBool: - result = 2 - else: - assert elem == tyEnum - assert typ.n.sons[0].sym.position != low(int) - result = typ.n.sons[0].sym.position - 1 - - const szNonConcreteType* = -3 szIllegalRecursion* = -2 szUnknownSize* = -1 -proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt -proc computeRecSizeAux(n: PNode, a, currOffset: var BiggestInt): BiggestInt = +proc computeSizeAux(conf: ConfigRef; typ: PType, a: var BiggestInt): BiggestInt +proc computeRecSizeAux(conf: ConfigRef; n: PNode, a, currOffset: var BiggestInt): BiggestInt = var maxAlign, maxSize, b, res: BiggestInt case n.kind of nkRecCase: assert(n.sons[0].kind == nkSym) - result = computeRecSizeAux(n.sons[0], a, currOffset) + result = computeRecSizeAux(conf, n.sons[0], a, currOffset) maxSize = 0 maxAlign = 1 for i in countup(1, sonsLen(n) - 1): case n.sons[i].kind of nkOfBranch, nkElse: - res = computeRecSizeAux(lastSon(n.sons[i]), b, currOffset) + res = computeRecSizeAux(conf, lastSon(n.sons[i]), b, currOffset) if res < 0: return res maxSize = max(maxSize, res) maxAlign = max(maxAlign, b) @@ -1292,20 +1235,20 @@ proc computeRecSizeAux(n: PNode, a, currOffset: var BiggestInt): BiggestInt = result = 0 maxAlign = 1 for i in countup(0, sonsLen(n) - 1): - res = computeRecSizeAux(n.sons[i], b, currOffset) + res = computeRecSizeAux(conf, n.sons[i], b, currOffset) if res < 0: return res currOffset = align(currOffset, b) + res result = align(result, b) + res if b > maxAlign: maxAlign = b a = maxAlign of nkSym: - result = computeSizeAux(n.sym.typ, a) + result = computeSizeAux(conf, n.sym.typ, a) n.sym.offset = int(currOffset) else: a = 1 result = szNonConcreteType -proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt = +proc computeSizeAux(conf: ConfigRef; typ: PType, a: var BiggestInt): BiggestInt = var res, maxAlign, length, currOffset: BiggestInt if typ.size == szIllegalRecursion: # we are already computing the size of the type @@ -1319,7 +1262,7 @@ proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt = typ.size = szIllegalRecursion # mark as being computed case typ.kind of tyInt, tyUInt: - result = intSize + result = conf.target.intSize a = result of tyInt8, tyUInt8, tyBool, tyChar: result = 1 @@ -1337,30 +1280,30 @@ proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt = result = 16 a = result of tyFloat: - result = floatSize + result = conf.target.floatSize a = result of tyProc: - if typ.callConv == ccClosure: result = 2 * ptrSize - else: result = ptrSize - a = ptrSize + if typ.callConv == ccClosure: result = 2 * conf.target.ptrSize + else: result = conf.target.ptrSize + a = conf.target.ptrSize of tyString, tyNil: - result = ptrSize + result = conf.target.ptrSize a = result of tyCString, tySequence, tyPtr, tyRef, tyVar, tyLent, tyOpenArray: let base = typ.lastSon if base == typ or (base.kind == tyTuple and base.size==szIllegalRecursion): result = szIllegalRecursion - else: result = ptrSize + else: result = conf.target.ptrSize a = result of tyArray: - let elemSize = computeSizeAux(typ.sons[1], a) + let elemSize = computeSizeAux(conf, typ.sons[1], a) if elemSize < 0: return elemSize - result = lengthOrd(typ.sons[0]) * elemSize + result = lengthOrd(conf, typ.sons[0]) * elemSize of tyEnum: - if firstOrd(typ) < 0: + if firstOrd(conf, typ) < 0: result = 4 # use signed int32 else: - length = lastOrd(typ) # BUGFIX: use lastOrd! + length = lastOrd(conf, typ) # BUGFIX: use lastOrd! if length + 1 < `shl`(1, 8): result = 1 elif length + 1 < `shl`(1, 16): result = 2 elif length + 1 < `shl`(BiggestInt(1), 32): result = 4 @@ -1370,7 +1313,7 @@ proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt = if typ.sons[0].kind == tyGenericParam: result = szUnknownSize else: - length = lengthOrd(typ.sons[0]) + length = lengthOrd(conf, typ.sons[0]) if length <= 8: result = 1 elif length <= 16: result = 2 elif length <= 32: result = 4 @@ -1379,12 +1322,12 @@ proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt = else: result = align(length, 8) div 8 + 1 a = result of tyRange: - result = computeSizeAux(typ.sons[0], a) + result = computeSizeAux(conf, typ.sons[0], a) of tyTuple: result = 0 maxAlign = 1 for i in countup(0, sonsLen(typ) - 1): - res = computeSizeAux(typ.sons[i], a) + res = computeSizeAux(conf, typ.sons[i], a) if res < 0: return res maxAlign = max(maxAlign, a) result = align(result, a) + res @@ -1392,61 +1335,52 @@ proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt = a = maxAlign of tyObject: if typ.sons[0] != nil: - result = computeSizeAux(typ.sons[0].skipTypes(skipPtrs), a) + result = computeSizeAux(conf, typ.sons[0].skipTypes(skipPtrs), a) if result < 0: return maxAlign = a elif isObjectWithTypeFieldPredicate(typ): - result = intSize + result = conf.target.intSize maxAlign = result else: result = 0 maxAlign = 1 currOffset = result - result = computeRecSizeAux(typ.n, a, currOffset) + result = computeRecSizeAux(conf, typ.n, a, currOffset) if result < 0: return if a < maxAlign: a = maxAlign result = align(result, a) of tyInferred: if typ.len > 1: - result = computeSizeAux(typ.lastSon, a) + result = computeSizeAux(conf, typ.lastSon, a) of tyGenericInst, tyDistinct, tyGenericBody, tyAlias: - result = computeSizeAux(lastSon(typ), a) + result = computeSizeAux(conf, lastSon(typ), a) of tyTypeClasses: - result = if typ.isResolvedUserTypeClass: computeSizeAux(typ.lastSon, a) + result = if typ.isResolvedUserTypeClass: computeSizeAux(conf, typ.lastSon, a) else: szUnknownSize of tyTypeDesc: - result = computeSizeAux(typ.base, a) + result = computeSizeAux(conf, typ.base, a) of tyForward: return szIllegalRecursion of tyStatic: - result = if typ.n != nil: computeSizeAux(typ.lastSon, a) + result = if typ.n != nil: computeSizeAux(conf, typ.lastSon, a) else: szUnknownSize - of tyOpt: - case optKind(typ) - of oBool: result = computeSizeAux(lastSon(typ), a) + 1 - of oEnum: - if lastOrd(typ) + 1 < `shl`(BiggestInt(1), 32): result = 4 - else: result = 8 - of oNil: result = computeSizeAux(lastSon(typ), a) - of oPtr: result = ptrSize else: #internalError("computeSizeAux()") result = szUnknownSize typ.size = result typ.align = int16(a) -proc computeSize*(typ: PType): BiggestInt = +proc computeSize*(conf: ConfigRef; typ: PType): BiggestInt = var a: BiggestInt = 1 - result = computeSizeAux(typ, a) + result = computeSizeAux(conf, typ, a) proc getReturnType*(s: PSym): PType = # Obtains the return type of a iterator/proc/macro/template assert s.kind in skProcKinds result = s.typ.sons[0] -proc getSize*(typ: PType): BiggestInt = - result = computeSize(typ) - #if result < 0: internalError("getSize: " & $typ.kind) - # XXX review all usages of 'getSize' +proc getSize*(conf: ConfigRef; typ: PType): BiggestInt = + result = computeSize(conf, typ) + if result < 0: internalError(conf, "getSize: " & $typ.kind) proc containsGenericTypeIter(t: PType, closure: RootRef): bool = case t.kind diff --git a/compiler/vm.nim b/compiler/vm.nim index cbd304caa..ecee319d0 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -66,7 +66,7 @@ proc stackTraceAux(c: PCtx; x: PStackFrame; pc: int; recursionLimit=100) = stackTraceAux(c, x.next, x.comesFrom, recursionLimit-1) var info = c.debug[pc] # we now use the same format as in system/except.nim - var s = substr(toFilename(info), 0) + var s = substr(toFilename(c.config, info), 0) # this 'substr' prevents a strange corruption. XXX This needs to be # investigated eventually but first attempts to fix it broke everything # see the araq-wip-fixed-writebarrier branch. @@ -213,7 +213,7 @@ proc putIntoNode(n: var PNode; x: TFullReg) = if nfIsRef in x.node.flags: n = x.node else: - let destIsRef = nfIsRef in n.flags + let destIsRef = nfIsRef in n.flags n[] = x.node[] # Ref-ness must be kept for the destination if destIsRef: @@ -370,7 +370,7 @@ proc opConv(c: PCtx; dest: var TFullReg, src: TFullReg, desttyp, srctyp: PType): dest.intVal = int(src.floatVal) else: dest.intVal = src.intVal - if dest.intVal < firstOrd(desttyp) or dest.intVal > lastOrd(desttyp): + if dest.intVal < firstOrd(c.config, desttyp) or dest.intVal > lastOrd(c.config, desttyp): return true of tyUInt..tyUInt64: if dest.kind != rkInt: @@ -700,12 +700,12 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = decodeB(rkNode) var b = newNodeIT(nkCurly, regs[ra].node.info, regs[ra].node.typ) addSon(b, regs[rb].regToNode) - var r = diffSets(regs[ra].node, b) + var r = diffSets(c.config, regs[ra].node, b) discardSons(regs[ra].node) for i in countup(0, sonsLen(r) - 1): addSon(regs[ra].node, r.sons[i]) of opcCard: decodeB(rkInt) - regs[ra].intVal = nimsets.cardSet(regs[rb].node) + regs[ra].intVal = nimsets.cardSet(c.config, regs[rb].node) of opcMulInt: decodeBC(rkInt) let @@ -853,35 +853,35 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = regs[ra].intVal = ord(regs[rb].node.strVal < regs[rc].node.strVal) of opcLeSet: decodeBC(rkInt) - regs[ra].intVal = ord(containsSets(regs[rb].node, regs[rc].node)) + regs[ra].intVal = ord(containsSets(c.config, regs[rb].node, regs[rc].node)) of opcEqSet: decodeBC(rkInt) - regs[ra].intVal = ord(equalSets(regs[rb].node, regs[rc].node)) + regs[ra].intVal = ord(equalSets(c.config, regs[rb].node, regs[rc].node)) of opcLtSet: decodeBC(rkInt) let a = regs[rb].node let b = regs[rc].node - regs[ra].intVal = ord(containsSets(a, b) and not equalSets(a, b)) + regs[ra].intVal = ord(containsSets(c.config, a, b) and not equalSets(c.config, a, b)) of opcMulSet: decodeBC(rkNode) createSet(regs[ra]) move(regs[ra].node.sons, - nimsets.intersectSets(regs[rb].node, regs[rc].node).sons) + nimsets.intersectSets(c.config, regs[rb].node, regs[rc].node).sons) of opcPlusSet: decodeBC(rkNode) createSet(regs[ra]) move(regs[ra].node.sons, - nimsets.unionSets(regs[rb].node, regs[rc].node).sons) + nimsets.unionSets(c.config, regs[rb].node, regs[rc].node).sons) of opcMinusSet: decodeBC(rkNode) createSet(regs[ra]) move(regs[ra].node.sons, - nimsets.diffSets(regs[rb].node, regs[rc].node).sons) + nimsets.diffSets(c.config, regs[rb].node, regs[rc].node).sons) of opcSymdiffSet: decodeBC(rkNode) createSet(regs[ra]) move(regs[ra].node.sons, - nimsets.symdiffSets(regs[rb].node, regs[rc].node).sons) + nimsets.symdiffSets(c.config, regs[rb].node, regs[rc].node).sons) of opcConcatStr: decodeBC(rkNode) createStr regs[ra] @@ -1358,7 +1358,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = # c.debug[pc].line.int - countLines(regs[rb].strVal) ? var error: string let ast = parseString(regs[rb].node.strVal, c.cache, c.config, - c.debug[pc].toFullPath, c.debug[pc].line.int, + toFullPath(c.config, c.debug[pc]), c.debug[pc].line.int, proc (conf: ConfigRef; info: TLineInfo; msg: TMsgKind; arg: string) = if error.isNil and msg <= errMax: error = formatMsg(conf, info, msg, arg)) @@ -1373,7 +1373,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = decodeB(rkNode) var error: string let ast = parseString(regs[rb].node.strVal, c.cache, c.config, - c.debug[pc].toFullPath, c.debug[pc].line.int, + toFullPath(c.config, c.debug[pc]), c.debug[pc].line.int, proc (conf: ConfigRef; info: TLineInfo; msg: TMsgKind; arg: string) = if error.isNil and msg <= errMax: error = formatMsg(conf, info, msg, arg)) @@ -1392,7 +1392,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcNGetFile: decodeB(rkNode) let n = regs[rb].node - regs[ra].node = newStrNode(nkStrLit, n.info.toFilename) + regs[ra].node = newStrNode(nkStrLit, toFilename(c.config, n.info)) regs[ra].node.info = n.info regs[ra].node.typ = n.typ of opcNGetLine: @@ -1683,7 +1683,7 @@ proc myProcess(c: PPassContext, n: PNode): PNode = # don't eval errornous code: if c.oldErrorCount == c.config.errorCounter: evalStmt(c, n) - result = emptyNode + result = newNodeI(nkEmpty, n.info) else: result = n c.oldErrorCount = c.config.errorCounter @@ -1703,7 +1703,7 @@ proc evalConstExprAux(module: PSym; cache: IdentCache; defer: c.mode = oldMode c.mode = mode let start = genExpr(c, n, requiresValue = mode!=emStaticStmt) - if c.code[start].opcode == opcEof: return emptyNode + if c.code[start].opcode == opcEof: return newNodeI(nkEmpty, n.info) assert c.code[start].opcode != opcEof when debugEchoCode: c.echoCode start var tos = PStackFrame(prc: prc, comesFrom: 0, next: nil) diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index 2c92348a6..45d6b81c3 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -11,7 +11,7 @@ import ast, types, msgs, os, streams, options, idents proc opSlurp*(file: string, info: TLineInfo, module: PSym; conf: ConfigRef): string = try: - var filename = parentDir(info.toFullPath) / file + var filename = parentDir(toFullPath(conf, info)) / file if not fileExists(filename): filename = findFile(conf, file) result = readFile(filename) @@ -54,7 +54,7 @@ proc objectNode(n: PNode): PNode = result = newNodeI(nkIdentDefs, n.info) result.add n # name result.add mapTypeToAstX(n.sym.typ, n.info, true, false) # type - result.add ast.emptyNode # no assigned value + result.add newNodeI(nkEmpty, n.info) # no assigned value else: result = copyNode(n) for i in 0 ..< n.safeLen: @@ -69,7 +69,7 @@ proc mapTypeToAstX(t: PType; info: TLineInfo; template mapTypeToAstR(t,info): untyped = mapTypeToAstX(t, info, inst, true) template mapTypeToAst(t,i,info): untyped = if i<t.len and t.sons[i]!=nil: mapTypeToAstX(t.sons[i], info, inst) - else: ast.emptyNode + else: newNodeI(nkEmpty, info) template mapTypeToBracket(name, m, t, info): untyped = mapTypeToBracketX(name, m, t, info, inst) template newNodeX(kind): untyped = @@ -78,7 +78,7 @@ proc mapTypeToAstX(t: PType; info: TLineInfo; var id = newNodeX(nkIdentDefs) id.add n # name id.add mapTypeToAst(t, info) # type - id.add ast.emptyNode # no assigned value + id.add newNodeI(nkEmpty, info) # no assigned value id template newIdentDefs(s): untyped = newIdentDefs(s, s.typ) @@ -156,8 +156,8 @@ proc mapTypeToAstX(t: PType; info: TLineInfo; of tyObject: if inst: result = newNodeX(nkObjectTy) - result.add ast.emptyNode # pragmas not reconstructed yet - if t.sons[0] == nil: result.add ast.emptyNode # handle parent object + result.add newNodeI(nkEmpty, info) # pragmas not reconstructed yet + if t.sons[0] == nil: result.add newNodeI(nkEmpty, info) # handle parent object else: var nn = newNodeX(nkOfInherit) nn.add mapTypeToAst(t.sons[0], info) @@ -165,13 +165,13 @@ proc mapTypeToAstX(t: PType; info: TLineInfo; if t.n.len > 0: result.add objectNode(t.n) else: - result.add ast.emptyNode + result.add newNodeI(nkEmpty, info) else: if allowRecursion or t.sym == nil: result = newNodeIT(nkObjectTy, if t.n.isNil: info else: t.n.info, t) - result.add ast.emptyNode + result.add newNodeI(nkEmpty, info) if t.sons[0] == nil: - result.add ast.emptyNode + result.add newNodeI(nkEmpty, info) else: result.add mapTypeToAst(t.sons[0], info) result.add copyTree(t.n) @@ -179,7 +179,7 @@ proc mapTypeToAstX(t: PType; info: TLineInfo; result = atomicType(t.sym) of tyEnum: result = newNodeIT(nkEnumTy, if t.n.isNil: info else: t.n.info, t) - result.add ast.emptyNode # pragma node, currently always empty for enum + result.add newNodeI(nkEmpty, info) # pragma node, currently always empty for enum for c in t.n.sons: result.add copyTree(c) of tyTuple: @@ -223,13 +223,13 @@ proc mapTypeToAstX(t: PType; info: TLineInfo; result = newNodeX(nkProcTy) var fp = newNodeX(nkFormalParams) if t.sons[0] == nil: - fp.add ast.emptyNode + fp.add newNodeI(nkEmpty, info) else: fp.add mapTypeToAst(t.sons[0], t.n[0].info) for i in 1..<t.sons.len: fp.add newIdentDefs(t.n[i], t.sons[i]) result.add fp - result.add ast.emptyNode # pragmas aren't reconstructed yet + result.add newNodeI(nkEmpty, info) # pragmas aren't reconstructed yet else: result = mapTypeToBracket("proc", mNone, t, info) of tyOpenArray: result = mapTypeToBracket("openArray", mOpenArray, t, info) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 7ac3b5cf7..282530d27 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -40,8 +40,8 @@ type TGenFlag = enum gfAddrOf, gfFieldAccess TGenFlags = set[TGenFlag] -proc debugInfo(info: TLineInfo): string = - result = info.toFilename.splitFile.name & ":" & $info.line +proc debugInfo(c: PCtx; info: TLineInfo): string = + result = toFilename(c.config, info).splitFile.name & ":" & $info.line proc codeListing(c: PCtx, result: var string, start=0; last = -1) = # first iteration: compute all necessary labels: @@ -85,7 +85,7 @@ proc codeListing(c: PCtx, result: var string, start=0; last = -1) = else: result.addf("\t$#\tr$#, $#", ($opc).substr(3), x.regA, x.regBx-wordExcess) result.add("\t#") - result.add(debugInfo(c.debug[i])) + result.add(debugInfo(c, c.debug[i])) result.add("\n") inc i @@ -550,7 +550,7 @@ proc genField(c: PCtx; n: PNode): TRegister = result = s.position proc genIndex(c: PCtx; n: PNode; arr: PType): TRegister = - if arr.skipTypes(abstractInst).kind == tyArray and (let x = firstOrd(arr); + if arr.skipTypes(abstractInst).kind == tyArray and (let x = firstOrd(c.config, arr); x != 0): let tmp = c.genx(n) # freeing the temporary here means we can produce: regA = regA - Imm @@ -767,12 +767,12 @@ proc genIntCast(c: PCtx; n: PNode; dest: var TDest) = var unsignedIntegers = {tyUInt8..tyUInt32, tyChar} let src = n.sons[1].typ.skipTypes(abstractRange)#.kind let dst = n.sons[0].typ.skipTypes(abstractRange)#.kind - let src_size = src.getSize + let src_size = getSize(c.config, src) - if platform.intSize < 8: + if c.config.target.intSize < 8: signedIntegers.incl(tyInt) unsignedIntegers.incl(tyUInt) - if src_size == dst.getSize and src.kind in allowedIntegers and + if src_size == getSize(c.config, dst) and src.kind in allowedIntegers and dst.kind in allowedIntegers: let tmp = c.genx(n.sons[1]) var tmp2 = c.getTemp(n.sons[1].typ) @@ -1543,7 +1543,6 @@ proc getNullValueAux(obj: PNode, result: PNode; conf: ConfigRef) = proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode = var t = skipTypes(typ, abstractRange-{tyTypeDesc}) - result = emptyNode case t.kind of tyBool, tyEnum, tyChar, tyInt..tyInt64: result = newNodeIT(nkIntLit, info, t) @@ -1575,7 +1574,7 @@ proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode = getNullValueAux(t.n, result, conf) of tyArray: result = newNodeIT(nkBracket, info, t) - for i in countup(0, int(lengthOrd(t)) - 1): + for i in countup(0, int(lengthOrd(conf, t)) - 1): addSon(result, getNullValue(elemType(t), info, conf)) of tyTuple: result = newNodeIT(nkTupleConstr, info, t) @@ -1589,6 +1588,7 @@ proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode = result = newNodeIT(nkBracket, info, t) else: globalError(conf, info, "cannot create null element for: " & $t.kind) + result = newNodeI(nkEmpty, info) proc ldNullOpcode(t: PType): TOpcode = assert t != nil @@ -2008,7 +2008,7 @@ proc genProc(c: PCtx; s: PSym): int = #c.removeLastEof result = c.code.len+1 # skip the jump instruction if x.kind == nkEmpty: - x = newTree(nkBracket, newIntNode(nkIntLit, result), ast.emptyNode) + x = newTree(nkBracket, newIntNode(nkIntLit, result), x) else: x.sons[0] = newIntNode(nkIntLit, result) s.ast.sons[miscPos] = x diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 370420d37..0d6690ebd 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -909,7 +909,7 @@ proc rawCreateDir(dir: string): bool = elif errno == EEXIST: result = false else: - echo res + #echo res raiseOSError(osLastError()) else: when useWinUnicode: diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 664446d54..e8bca4bdd 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -832,7 +832,7 @@ elif not defined(useNimRtl): # Parent process. Copy process information. if poEchoCmd in options: - echo(command, " ", join(args, " ")) + when declared(echo): echo(command, " ", join(args, " ")) result.id = pid result.exitFlag = false diff --git a/nimsuggest/nimsuggest.nim b/nimsuggest/nimsuggest.nim index 5c505ddf7..bea33684a 100644 --- a/nimsuggest/nimsuggest.nim +++ b/nimsuggest/nimsuggest.nim @@ -74,8 +74,8 @@ proc writelnToChannel(line: string) = proc sugResultHook(s: Suggest) = results.send(s) -proc errorHook(info: TLineInfo; msg: string; sev: Severity) = - results.send(Suggest(section: ideChk, filePath: toFullPath(info), +proc errorHook(conf: ConfigRef; info: TLineInfo; msg: string; sev: Severity) = + results.send(Suggest(section: ideChk, filePath: toFullPath(conf, info), line: toLinenumber(info), column: toColumn(info), doc: msg, forth: $sev)) @@ -173,8 +173,8 @@ proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int; var isKnownFile = true let dirtyIdx = fileInfoIdx(conf, file, isKnownFile) - if dirtyfile.len != 0: msgs.setDirtyFile(dirtyIdx, dirtyfile) - else: msgs.setDirtyFile(dirtyIdx, nil) + if dirtyfile.len != 0: msgs.setDirtyFile(conf, dirtyIdx, dirtyfile) + else: msgs.setDirtyFile(conf, dirtyIdx, nil) gTrackPos = newLineInfo(dirtyIdx, line, col) gTrackPosAttached = false @@ -432,7 +432,7 @@ proc execCmd(cmd: string; graph: ModuleGraph; cache: IdentCache; cachedMsgs: Cac results.send(Suggest(section: ideKnown, quality: ord(fileInfoKnown(conf, orig)))) else: if conf.ideCmd == ideChk: - for cm in cachedMsgs: errorHook(cm.info, cm.msg, cm.sev) + for cm in cachedMsgs: errorHook(conf, cm.info, cm.msg, cm.sev) execute(conf.ideCmd, orig, dirtyfile, line, col, graph, cache) sentinel() @@ -477,7 +477,7 @@ proc mainThread(graph: ModuleGraph; cache: IdentCache) = conf.ideCmd = ideChk msgs.writelnHook = proc (s: string) = discard cachedMsgs.setLen 0 - msgs.structuredErrorHook = proc (info: TLineInfo; msg: string; sev: Severity) = + msgs.structuredErrorHook = proc (conf: ConfigRef; info: TLineInfo; msg: string; sev: Severity) = cachedMsgs.add(CachedMsg(info: info, msg: msg, sev: sev)) suggestionResultHook = proc (s: Suggest) = discard recompileFullProject(graph, cache) |