diff options
40 files changed, 465 insertions, 378 deletions
diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index 8d132ab26..c53e53b88 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -203,9 +203,9 @@ proc mustRehash(length, counter: int): bool = assert(length > counter) result = (length * 2 < counter * 3) or (length - counter < 4) -proc spaces(x: int): PRope = +proc rspaces(x: int): PRope = # returns x spaces - result = toRope(repeatChar(x)) + result = toRope(spaces(x)) proc toYamlChar(c: char): string = case c @@ -253,7 +253,7 @@ proc typeToYamlAux(n: PType, marker: var IntSet, indent, maxRecDepth: int): PRope proc strTableToYaml(n: TStrTable, marker: var IntSet, indent: int, maxRecDepth: int): PRope = - var istr = spaces(indent + 2) + var istr = rspaces(indent + 2) result = toRope("[") var mycount = 0 for i in countup(0, high(n.data)): @@ -262,20 +262,20 @@ proc strTableToYaml(n: TStrTable, marker: var IntSet, indent: int, appf(result, "$N$1$2", [istr, symToYamlAux(n.data[i], marker, indent + 2, maxRecDepth - 1)]) inc(mycount) - if mycount > 0: appf(result, "$N$1", [spaces(indent)]) + if mycount > 0: appf(result, "$N$1", [rspaces(indent)]) app(result, "]") assert(mycount == n.counter) proc ropeConstr(indent: int, c: openArray[PRope]): PRope = # array of (name, value) pairs - var istr = spaces(indent + 2) + var istr = rspaces(indent + 2) result = toRope("{") var i = 0 while i <= high(c): if i > 0: app(result, ",") appf(result, "$N$1\"$2\": $3", [istr, c[i], c[i + 1]]) inc(i, 2) - appf(result, "$N$1}", [spaces(indent)]) + appf(result, "$N$1}", [rspaces(indent)]) proc symToYamlAux(n: PSym, marker: var IntSet, indent: int, maxRecDepth: int): PRope = @@ -310,9 +310,9 @@ proc typeToYamlAux(n: PType, marker: var IntSet, indent: int, result = toRope("[") for i in countup(0, sonsLen(n) - 1): if i > 0: app(result, ",") - appf(result, "$N$1$2", [spaces(indent + 4), typeToYamlAux(n.sons[i], + appf(result, "$N$1$2", [rspaces(indent + 4), typeToYamlAux(n.sons[i], marker, indent + 4, maxRecDepth - 1)]) - appf(result, "$N$1]", [spaces(indent + 2)]) + appf(result, "$N$1]", [rspaces(indent + 2)]) else: result = toRope("null") result = ropeConstr(indent, [toRope("kind"), @@ -331,7 +331,7 @@ proc treeToYamlAux(n: PNode, marker: var IntSet, indent: int, if n == nil: result = toRope("null") else: - var istr = spaces(indent + 2) + var istr = rspaces(indent + 2) result = ropef("{$N$1\"kind\": $2", [istr, makeYamlString($n.kind)]) if maxRecDepth != 0: appf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)]) @@ -359,12 +359,12 @@ proc treeToYamlAux(n: PNode, marker: var IntSet, indent: int, appf(result, ",$N$1\"sons\": [", [istr]) for i in countup(0, sonsLen(n) - 1): if i > 0: app(result, ",") - appf(result, "$N$1$2", [spaces(indent + 4), treeToYamlAux(n.sons[i], + appf(result, "$N$1$2", [rspaces(indent + 4), treeToYamlAux(n.sons[i], marker, indent + 4, maxRecDepth - 1)]) appf(result, "$N$1]", [istr]) appf(result, ",$N$1\"typ\": $2", [istr, typeToYamlAux(n.typ, marker, indent + 2, maxRecDepth)]) - appf(result, "$N$1}", [spaces(indent)]) + appf(result, "$N$1}", [rspaces(indent)]) proc treeToYaml(n: PNode, indent: int = 0, maxRecDepth: int = - 1): PRope = var marker = initIntSet() @@ -408,7 +408,7 @@ proc debugTree(n: PNode, indent: int, maxRecDepth: int; if n == nil: result = toRope("null") else: - var istr = spaces(indent + 2) + var istr = rspaces(indent + 2) result = ropef("{$N$1\"kind\": $2", [istr, makeYamlString($n.kind)]) if maxRecDepth != 0: @@ -440,11 +440,11 @@ proc debugTree(n: PNode, indent: int, maxRecDepth: int; appf(result, ",$N$1\"sons\": [", [istr]) for i in countup(0, sonsLen(n) - 1): if i > 0: app(result, ",") - appf(result, "$N$1$2", [spaces(indent + 4), debugTree(n.sons[i], + appf(result, "$N$1$2", [rspaces(indent + 4), debugTree(n.sons[i], indent + 4, maxRecDepth - 1, renderType)]) appf(result, "$N$1]", [istr]) appf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)]) - appf(result, "$N$1}", [spaces(indent)]) + appf(result, "$N$1}", [rspaces(indent)]) proc debug(n: PSym) = if n == nil: diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 3bc0d8afb..564d1fd36 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -56,11 +56,6 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): PRope = case skipTypes(ty, abstractVarRange).kind of tyChar, tyNil: result = intLiteral(n.intVal) - of tyInt: - if n.intVal >= low(int32) and n.intVal <= high(int32): - result = int32Literal(int32(n.intVal)) - else: - result = intLiteral(n.intVal) of tyBool: if n.intVal != 0: result = ~"NIM_TRUE" else: result = ~"NIM_FALSE" @@ -89,7 +84,7 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): PRope = var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId) if id == gBackendId: # string literal not found in the cache: - result = ropecg(p.module, "((#NimStringDesc*) &$1)", + result = ropecg(p.module, "((#NimStringDesc*) &$1)", [getStrLit(p.module, n.strVal)]) else: result = ropecg(p.module, "((#NimStringDesc*) &TMP$1)", [toRope(id)]) @@ -158,7 +153,7 @@ proc getStorageLoc(n: PNode): TStorageLoc = of skVar, skForVar, skResult, skLet: if sfGlobal in n.sym.flags: result = OnHeap else: result = OnStack - of skConst: + of skConst: if sfGlobal in n.sym.flags: result = OnHeap else: result = OnUnknown else: result = OnUnknown @@ -236,7 +231,7 @@ proc genOptAsgnTuple(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = for i in 0 .. <t.len: let t = t.sons[i] let field = ropef("Field$1", i.toRope) - genAssignment(p, optAsgnLoc(dest, t, field), + genAssignment(p, optAsgnLoc(dest, t, field), optAsgnLoc(src, t, field), newflags) proc genOptAsgnObject(p: BProc, dest, src: TLoc, flags: TAssignmentFlags, @@ -252,20 +247,20 @@ proc genOptAsgnObject(p: BProc, dest, src: TLoc, flags: TAssignmentFlags, case t.kind of nkSym: let field = t.sym - genAssignment(p, optAsgnLoc(dest, field.typ, field.loc.r), + genAssignment(p, optAsgnLoc(dest, field.typ, field.loc.r), optAsgnLoc(src, field.typ, field.loc.r), newflags) of nkRecList: for child in items(t): genOptAsgnObject(p, dest, src, newflags, child) else: discard proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = - # Consider: + # Consider: # type TMyFastString {.shallow.} = string # Due to the implementation of pragmas this would end up to set the # tfShallow flag for the built-in string type too! So we check only # here for this flag, where it is reasonably safe to do so # (for objects, etc.): - if needToCopy notin flags or + if needToCopy notin flags or tfShallow in skipTypes(dest.t, abstractVarRange).flags: if dest.s == OnStack or not usesNativeGC(): useStringh(p.module) @@ -510,7 +505,7 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) = var storage: PRope var size = getSize(t) if size < platform.intSize: - storage = toRope("NI") + storage = toRope("NI") else: storage = getTypeDesc(p.module, t) var tmp = getTempName() @@ -547,7 +542,7 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) = "(($4)($1) - ($4)($2))", # SubF64 "(($4)($1) * ($4)($2))", # MulF64 "(($4)($1) / ($4)($2))", # DivF64 - + "($4)((NU$3)($1) >> (NU$3)($2))", # ShrI "($4)((NU$3)($1) << (NU$3)($2))", # ShlI "($4)($1 & $2)", # BitandI @@ -617,7 +612,7 @@ proc genEqProc(p: BProc, e: PNode, d: var TLoc) = initLocExpr(p, e.sons[1], a) initLocExpr(p, e.sons[2], b) if a.t.callConv == ccClosure: - putIntoDest(p, d, e.typ, + putIntoDest(p, d, e.typ, ropef("($1.ClPrc == $2.ClPrc && $1.ClEnv == $2.ClEnv)", [ rdLoc(a), rdLoc(b)])) else: @@ -721,7 +716,7 @@ template inheritLocation(d: var TLoc, a: TLoc) = if d.k == locNone: d.s = a.s if d.heapRoot == nil: d.heapRoot = if a.heapRoot != nil: a.heapRoot else: a.r - + proc genRecordFieldAux(p: BProc, e: PNode, d, a: var TLoc): PType = initLocExpr(p, e.sons[0], a) if e.sons[1].kind != nkSym: internalError(e.info, "genRecordFieldAux") @@ -954,7 +949,7 @@ proc genEcho(p: BProc, n: PNode) = initLocExpr(p, n.sons[i], a) appf(args, ", $1? ($1)->data:\"nil\"", [rdLoc(a)]) linefmt(p, cpsStmts, "printf($1$2);$n", - makeCString(repeatStr(n.len, "%s") & tnl), args) + makeCString(repeat("%s", n.len) & tnl), args) proc gcUsage(n: PNode) = if gSelectedGC == gcNone: message(n.info, warnGcMem, n.renderTree) @@ -1061,7 +1056,7 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) = genAssignment(p, dest, b, {needToCopy, afDestIsNil}) gcUsage(e) -proc genReset(p: BProc, n: PNode) = +proc genReset(p: BProc, n: PNode) = var a: TLoc initLocExpr(p, n.sons[1], a) linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n", @@ -1120,14 +1115,14 @@ proc genNewSeqAux(p: BProc, dest: TLoc, length: PRope) = else: call.r = ropecg(p.module, "($1) #newSeq($2, $3)", args) genAssignment(p, dest, call, {needToKeepAlive}) - + proc genNewSeq(p: BProc, e: PNode) = var a, b: TLoc initLocExpr(p, e.sons[1], a) initLocExpr(p, e.sons[2], b) genNewSeqAux(p, a, b.rdLoc) gcUsage(e) - + proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = var tmp: TLoc var t = e.typ.skipTypes(abstractInst) @@ -1168,7 +1163,7 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = d = tmp else: genAssignment(p, d, tmp, {}) - + proc genSeqConstr(p: BProc, t: PNode, d: var TLoc) = var arr: TLoc if d.k == locNone: @@ -1192,7 +1187,7 @@ proc genArrToSeq(p: BProc, t: PNode, d: var TLoc) = getTemp(p, t.typ, d) # generate call to newSeq before adding the elements per hand: var L = int(lengthOrd(t.sons[1].typ)) - + genNewSeqAux(p, d, intLiteral(L)) initLocExpr(p, t.sons[1], a) for i in countup(0, L - 1): @@ -1202,7 +1197,7 @@ proc genArrToSeq(p: BProc, t: PNode, d: var TLoc) = initLoc(arr, locExpr, elemType(skipTypes(t.sons[1].typ, abstractInst)), a.s) arr.r = rfmt(nil, "$1[$2]", rdLoc(a), intLiteral(i)) genAssignment(p, elem, arr, {afDestIsNil, needToCopy}) - + proc genNewFinalize(p: BProc, e: PNode) = var a, b, f: TLoc @@ -1258,7 +1253,7 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) = app(r, ~".Sup") t = skipTypes(t.sons[0], typedescInst) if isObjLackingTypeField(t): - globalError(x.info, errGenerated, + globalError(x.info, errGenerated, "no 'of' operator available for pure objects") if nilCheck != nil: r = rfmt(p.module, "(($1) && ($2))", nilCheck, genOfHelper(p, dest, r)) @@ -1275,7 +1270,7 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) = var t = skipTypes(e.sons[1].typ, abstractVarRange) case t.kind of tyInt..tyInt64, tyUInt..tyUInt64: - putIntoDest(p, d, e.typ, + putIntoDest(p, d, e.typ, ropecg(p.module, "#reprInt((NI64)$1)", [rdLoc(a)])) of tyFloat..tyFloat128: putIntoDest(p, d, e.typ, ropecg(p.module, "#reprFloat($1)", [rdLoc(a)])) @@ -1298,13 +1293,13 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) = of tyOpenArray, tyVarargs: putIntoDest(p, b, e.typ, ropef("$1, $1Len0", [rdLoc(a)])) of tyString, tySequence: - putIntoDest(p, b, e.typ, + putIntoDest(p, b, e.typ, ropef("$1->data, $1->$2", [rdLoc(a), lenField(p)])) of tyArray, tyArrayConstr: putIntoDest(p, b, e.typ, ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))])) else: internalError(e.sons[0].info, "genRepr()") - putIntoDest(p, d, e.typ, + putIntoDest(p, d, e.typ, ropecg(p.module, "#reprOpenArray($1, $2)", [rdLoc(b), genTypeInfo(p.module, elemType(t))])) of tyCString, tyArray, tyArrayConstr, tyRef, tyPtr, tyPointer, tyNil, @@ -1433,7 +1428,7 @@ proc genInOp(p: BProc, e: PNode, d: var TLoc) = # 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 # that code now relies on. :-/ XXX - let ea = if e.sons[2].kind in {nkChckRange, nkChckRange64}: + let ea = if e.sons[2].kind in {nkChckRange, nkChckRange64}: e.sons[2].sons[0] else: e.sons[2] @@ -1518,7 +1513,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) = initLocExpr(p, e.sons[2], b) if d.k == locNone: getTemp(p, a.t, d) lineF(p, cpsStmts, - "for ($1 = 0; $1 < $2; $1++) $n" & + "for ($1 = 0; $1 < $2; $1++) $n" & " $3[$1] = $4[$1] $6 $5[$1];$n", [ rdLoc(i), toRope(size), rdLoc(d), rdLoc(a), rdLoc(b), toRope(lookupOpr[op])]) @@ -1549,7 +1544,7 @@ proc genSomeCast(p: BProc, e: PNode, d: var TLoc) = proc genCast(p: BProc, e: PNode, d: var TLoc) = const floatTypes = {tyFloat..tyFloat128} - let + let destt = skipTypes(e.typ, abstractRange) srct = skipTypes(e.sons[1].typ, abstractRange) if destt.kind in floatTypes or srct.kind in floatTypes: @@ -1656,7 +1651,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = of mRepr: genRepr(p, e, d) of mGetTypeInfo: genGetTypeInfo(p, e, d) of mSwap: genSwap(p, e, d) - of mUnaryLt: + of mUnaryLt: if optOverflowCheck notin p.options: unaryExpr(p, e, d, "($1 - 1)") else: unaryExpr(p, e, d, "#subInt($1, 1)") of mPred: @@ -1830,10 +1825,10 @@ proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) = proc isConstClosure(n: PNode): bool {.inline.} = result = n.sons[0].kind == nkSym and isRoutine(n.sons[0].sym) and n.sons[1].kind == nkNilLit - + proc genClosure(p: BProc, n: PNode, d: var TLoc) = assert n.kind == nkClosure - + if isConstClosure(n): inc(p.labels) var tmp = con("LOC", toRope(p.labels)) @@ -1920,7 +1915,7 @@ proc downConv(p: BProc, n: PNode, d: var TLoc) = if isRef: # it can happen that we end up generating '&&x->Sup' here, so we pack # the '&x->Sup' into a temporary and then those address is taken - # (see bug #837). However sometimes using a temporary is not correct: + # (see bug #837). However sometimes using a temporary is not correct: # init(TFigure(my)) # where it is passed to a 'var TFigure'. We test # this by ensuring the destination is also a pointer: if d.k == locNone and skipTypes(n.typ, abstractInst).kind in {tyRef, tyPtr, tyVar}: @@ -1937,13 +1932,13 @@ proc exprComplexConst(p: BProc, n: PNode, d: var TLoc) = discard getTypeDesc(p.module, t) # so that any fields are initialized var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId) var tmp = con("TMP", toRope(id)) - + if id == gBackendId: # expression not found in the cache: inc(gBackendId) appf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n", [getTypeDesc(p.module, t), tmp, genConstExpr(p, n)]) - + if d.k == locNone: fillLoc(d, locData, t, tmp, OnHeap) else: @@ -1984,7 +1979,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = internalError n.info, "expr: var not init " & sym.name.s & "_" & $sym.id if sfThread in sym.flags: accessThreadLocalVar(p, sym) - if emulatedThreadVars(): + if emulatedThreadVars(): putIntoDest(p, d, sym.loc.t, con("NimTV->", sym.loc.r)) else: putLocIntoDest(p, d, sym.loc) @@ -2001,7 +1996,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = #echo "FAILED FOR PRCO ", p.prc.name.s #debug p.prc.typ.n #echo renderTree(p.prc.ast, {renderIds}) - internalError(n.info, "expr: param not init " & sym.name.s & "_" & $sym.id) + internalError(n.info, "expr: param not init " & sym.name.s & "_" & $sym.id) putLocIntoDest(p, d, sym.loc) else: internalError(n.info, "expr(" & $sym.kind & "); unknown symbol") of nkNilLit: @@ -2101,9 +2096,9 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = # we have to emit the type information for object types here to support # separate compilation: genTypeSection(p.module, n) - of nkCommentStmt, nkIteratorDef, nkIncludeStmt, - nkImportStmt, nkImportExceptStmt, nkExportStmt, nkExportExceptStmt, - nkFromStmt, nkTemplateDef, nkMacroDef: + of nkCommentStmt, nkIteratorDef, nkIncludeStmt, + nkImportStmt, nkImportExceptStmt, nkExportStmt, nkExportExceptStmt, + nkFromStmt, nkTemplateDef, nkMacroDef: discard of nkPragma: genPragma(p, n) of nkPragmaBlock: expr(p, n.lastSon, d) @@ -2118,8 +2113,8 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = sfDeadCodeElim notin getModule(prc).flags) or ({sfExportc, sfCompilerProc} * prc.flags == {sfExportc}) or (sfExportc in prc.flags and lfExportLib in prc.loc.flags) or - (prc.kind == skMethod): - # we have not only the header: + (prc.kind == skMethod): + # we have not only the header: if prc.getBody.kind != nkEmpty or lfDynamicLib in prc.loc.flags: genProc(p.module, prc) of nkParForStmt: genParForStmt(p, n) @@ -2142,7 +2137,7 @@ proc genConstSimpleList(p: BProc, n: PNode): PRope = proc genConstSeq(p: BProc, n: PNode, t: PType): PRope = var data = ropef("{{$1, $1}", n.len.toRope) - if n.len > 0: + if n.len > 0: # array part needs extra curlies: data.app(", {") for i in countup(0, n.len - 1): @@ -2150,14 +2145,14 @@ proc genConstSeq(p: BProc, n: PNode, t: PType): PRope = data.app genConstExpr(p, n.sons[i]) data.app("}") data.app("}") - + inc(gBackendId) result = con("CNSTSEQ", gBackendId.toRope) - + appcg(p.module, cfsData, - "NIM_CONST struct {$n" & + "NIM_CONST struct {$n" & " #TGenericSeq Sup;$n" & - " $1 data[$2];$n" & + " $1 data[$2];$n" & "} $3 = $4;$n", [ getTypeDesc(p.module, t.sons[0]), n.len.toRope, result, data]) diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim index 59b9611fc..25c1a12e5 100644 --- a/compiler/ccgutils.nim +++ b/compiler/ccgutils.nim @@ -9,31 +9,31 @@ # This module declares some helpers for the C code generator. -import - ast, astalgo, ropes, lists, hashes, strutils, types, msgs, wordrecg, +import + ast, astalgo, ropes, lists, hashes, strutils, types, msgs, wordrecg, platform, trees proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode = case n.kind - of nkStmtList: - for i in 0 .. < n.len: + of nkStmtList: + for i in 0 .. < n.len: result = getPragmaStmt(n[i], w) if result != nil: break of nkPragma: - for i in 0 .. < n.len: + for i in 0 .. < n.len: if whichPragma(n[i]) == w: return n[i] else: discard proc stmtsContainPragma*(n: PNode, w: TSpecialWord): bool = result = getPragmaStmt(n, w) != nil -proc hashString*(s: string): BiggestInt = +proc hashString*(s: string): BiggestInt = # has to be the same algorithm as system.hashString! - if CPU[targetCPU].bit == 64: + if CPU[targetCPU].bit == 64: # we have to use the same bitwidth # as the target CPU var b = 0'i64 - for i in countup(0, len(s) - 1): + for i in countup(0, len(s) - 1): b = b +% ord(s[i]) b = b +% `shl`(b, 10) b = b xor `shr`(b, 6) @@ -41,9 +41,9 @@ proc hashString*(s: string): BiggestInt = b = b xor `shr`(b, 11) b = b +% `shl`(b, 15) result = b - else: + else: var a = 0'i32 - for i in countup(0, len(s) - 1): + for i in countup(0, len(s) - 1): a = a +% ord(s[i]).int32 a = a +% `shl`(a, 10'i32) a = a xor `shr`(a, 6'i32) @@ -52,11 +52,11 @@ proc hashString*(s: string): BiggestInt = a = a +% `shl`(a, 15'i32) result = a -var +var gTypeTable: array[TTypeKind, TIdTable] gCanonicalTypes: array[TTypeKind, PType] -proc initTypeTables() = +proc initTypeTables() = for i in countup(low(TTypeKind), high(TTypeKind)): initIdTable(gTypeTable[i]) proc resetCaches* = @@ -67,7 +67,7 @@ proc resetCaches* = when false: proc echoStats*() = - for i in countup(low(TTypeKind), high(TTypeKind)): + for i in countup(low(TTypeKind), high(TTypeKind)): echo i, " ", gTypeTable[i].counter proc slowSearch(key: PType; k: TTypeKind): PType = @@ -78,21 +78,21 @@ proc slowSearch(key: PType; k: TTypeKind): PType = 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): + if t != nil and sameBackendType(t, key): return t idTablePut(gTypeTable[k], key, key) result = key -proc getUniqueType*(key: PType): PType = +proc getUniqueType*(key: PType): PType = # this is a hotspot in the compiler! - if key == nil: return + 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, + of tyEmpty, tyNil, tyExpr, tyStmt, tyPointer, tyString, tyCString, tyNone, tyBigNum: result = gCanonicalTypes[k] if result == nil: @@ -127,7 +127,7 @@ proc getUniqueType*(key: PType): PType = if tfFromGeneric notin key.flags: # fast case; lookup per id suffices: result = PType(idTableGet(gTypeTable[k], key)) - if result == nil: + if result == nil: idTablePut(gTypeTable[k], key, key) result = key else: @@ -138,10 +138,10 @@ proc getUniqueType*(key: PType): PType = if t != nil and sameBackendType(t, key): return t idTablePut(gTypeTable[k], key, key) - result = key + result = key of tyEnum: result = PType(idTableGet(gTypeTable[k], key)) - if result == nil: + if result == nil: idTablePut(gTypeTable[k], key, key) result = key of tyProc: @@ -151,16 +151,16 @@ proc getUniqueType*(key: PType): PType = # ugh, we need the canon here: result = slowSearch(key, k) -proc tableGetType*(tab: TIdTable, key: PType): RootRef = +proc tableGetType*(tab: TIdTable, key: PType): RootRef = # returns nil if we need to declare this type result = idTableGet(tab, key) - if (result == nil) and (tab.counter > 0): + if (result == nil) and (tab.counter > 0): # we have to do a slow linear search because types may need # to be compared by their structure: - for h in countup(0, high(tab.data)): + for h in countup(0, high(tab.data)): var t = PType(tab.data[h].key) - if t != nil: - if sameType(t, key): + if t != nil: + if sameType(t, key): return tab.data[h].val proc makeSingleLineCString*(s: string): string = @@ -193,16 +193,16 @@ proc mangle*(name: string): string = else: add(result, "HEX" & toHex(ord(c), 2)) -proc makeLLVMString*(s: string): PRope = +proc makeLLVMString*(s: string): PRope = const MaxLineLength = 64 result = nil var res = "c\"" - for i in countup(0, len(s) - 1): - if (i + 1) mod MaxLineLength == 0: + for i in countup(0, len(s) - 1): + if (i + 1) mod MaxLineLength == 0: app(result, toRope(res)) setLen(res, 0) case s[i] - of '\0'..'\x1F', '\x80'..'\xFF', '\"', '\\': + of '\0'..'\x1F', '\x80'..'\xFF', '\"', '\\': add(res, '\\') add(res, toHex(ord(s[i]), 2)) else: add(res, s[i]) diff --git a/compiler/filter_tmpl.nim b/compiler/filter_tmpl.nim index 7b975dbaa..5d1f73be4 100644 --- a/compiler/filter_tmpl.nim +++ b/compiler/filter_tmpl.nim @@ -37,11 +37,11 @@ const PatternChars = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '.', '_'} proc newLine(p: var TTmplParser) = - llStreamWrite(p.outp, repeatChar(p.emitPar, ')')) + llStreamWrite(p.outp, repeat(')', p.emitPar)) p.emitPar = 0 if p.info.line > int16(1): llStreamWrite(p.outp, "\n") if p.pendingExprLine: - llStreamWrite(p.outp, repeatChar(2)) + llStreamWrite(p.outp, spaces(2)) p.pendingExprLine = false proc scanPar(p: var TTmplParser, d: int) = @@ -88,24 +88,24 @@ proc parseLine(p: var TTmplParser) = else: p.info.col = int16(j) localError(p.info, errXNotAllowedHere, "end") - llStreamWrite(p.outp, repeatChar(p.indent)) + llStreamWrite(p.outp, spaces(p.indent)) llStreamWrite(p.outp, "#end") of wIf, wWhen, wTry, wWhile, wFor, wBlock, wCase, wProc, wIterator, wConverter, wMacro, wTemplate, wMethod: - llStreamWrite(p.outp, repeatChar(p.indent)) + llStreamWrite(p.outp, spaces(p.indent)) llStreamWrite(p.outp, substr(p.x, d)) inc(p.indent, 2) of wElif, wOf, wElse, wExcept, wFinally: - llStreamWrite(p.outp, repeatChar(p.indent - 2)) + llStreamWrite(p.outp, spaces(p.indent - 2)) llStreamWrite(p.outp, substr(p.x, d)) of wLet, wVar, wConst, wType: - llStreamWrite(p.outp, repeatChar(p.indent)) + llStreamWrite(p.outp, spaces(p.indent)) llStreamWrite(p.outp, substr(p.x, d)) if not p.x.contains({':', '='}): # no inline element --> treat as block: inc(p.indent, 2) else: - llStreamWrite(p.outp, repeatChar(p.indent)) + llStreamWrite(p.outp, spaces(p.indent)) llStreamWrite(p.outp, substr(p.x, d)) p.state = psDirective else: @@ -120,11 +120,11 @@ proc parseLine(p: var TTmplParser) = # next line of string literal: llStreamWrite(p.outp, p.conc) llStreamWrite(p.outp, "\n") - llStreamWrite(p.outp, repeatChar(p.indent + 2)) + llStreamWrite(p.outp, spaces(p.indent + 2)) llStreamWrite(p.outp, "\"") of psDirective: newLine(p) - llStreamWrite(p.outp, repeatChar(p.indent)) + llStreamWrite(p.outp, spaces(p.indent)) llStreamWrite(p.outp, p.emit) llStreamWrite(p.outp, "(\"") inc(p.emitPar) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 34f842d4a..87847204f 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -780,7 +780,7 @@ proc genIf(p: PProc, n: PNode, r: var TCompRes) = moveInto(p, stmt, r) appf(p.body, "}$n" | "end$n") if p.target == targetJS: - app(p.body, repeatChar(toClose, '}') & tnl) + app(p.body, repeat('}', toClose) & tnl) else: for i in 1..toClose: appf(p.body, "end$n") diff --git a/compiler/msgs.nim b/compiler/msgs.nim index a72dedf57..e15cdc86d 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -784,7 +784,7 @@ proc rawMessage*(msg: TMsgKind, arg: string) = proc writeSurroundingSrc(info: TLineInfo) = const indent = " " msgWriteln(indent & info.sourceLine.ropeToStr) - msgWriteln(indent & repeatChar(info.col, ' ') & '^') + msgWriteln(indent & spaces(info.col) & '^') proc formatMsg*(info: TLineInfo, msg: TMsgKind, arg: string): string = let frmt = case msg diff --git a/compiler/nimlexbase.nim b/compiler/nimlexbase.nim index e18e1c22a..f5db5ca4f 100644 --- a/compiler/nimlexbase.nim +++ b/compiler/nimlexbase.nim @@ -166,4 +166,4 @@ proc getCurrentLine(L: TBaseLexer, marker: bool = true): string = inc(i) result.add("\n") if marker: - result.add(repeatChar(getColNumber(L, L.bufpos)) & '^' & "\n") + result.add(spaces(getColNumber(L, L.bufpos)) & '^' & "\n") diff --git a/compiler/renderer.nim b/compiler/renderer.nim index 204bfbf94..f5cabb4bc 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -92,7 +92,7 @@ proc addTok(g: var TSrcGen, kind: TTokType, s: string) = proc addPendingNL(g: var TSrcGen) = if g.pendingNL >= 0: - addTok(g, tkSpaces, "\n" & repeatChar(g.pendingNL)) + addTok(g, tkSpaces, "\n" & spaces(g.pendingNL)) g.lineLen = g.pendingNL g.pendingNL = - 1 @@ -190,7 +190,7 @@ proc putComment(g: var TSrcGen, s: string) = if not isCode and (g.lineLen + (j - i) > MaxLineLen): put(g, tkComment, com) optNL(g, ind) - com = '#' & repeatChar(comIndent) + com = '#' & spaces(comIndent) while s[i] > ' ': add(com, s[i]) inc(i) @@ -280,7 +280,7 @@ proc gcom(g: var TSrcGen, n: PNode) = (g.lineLen < LineCommentColumn): var ml = maxLineLength(n.comment) if ml + LineCommentColumn <= MaxLineLen: - put(g, tkSpaces, repeatChar(LineCommentColumn - g.lineLen)) + put(g, tkSpaces, spaces(LineCommentColumn - g.lineLen)) putComment(g, n.comment) #assert(g.comStack[high(g.comStack)] = n); proc gcoms(g: var TSrcGen) = diff --git a/compiler/sem.nim b/compiler/sem.nim index a90948245..36c0342cd 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -65,8 +65,8 @@ template semIdeForTemplateOrGeneric(c: PContext; n: PNode; echo "passing to safeSemExpr: ", renderTree(n) discard safeSemExpr(c, n) -proc typeMismatch(n: PNode, formal, actual: PType) = - if formal.kind != tyError and actual.kind != tyError: +proc typeMismatch(n: PNode, formal, actual: PType) = + if formal.kind != tyError and actual.kind != tyError: localError(n.info, errGenerated, msgKindToString(errTypeMismatch) & typeToString(actual) & ") " & `%`(msgKindToString(errButExpectedX), [typeToString(formal)])) @@ -113,7 +113,7 @@ proc commonType*(x, y: PType): PType = else: result = newType(tyTypeDesc, a.owner) rawAddSon(result, newType(tyNone, a.owner)) - elif b.kind in {tyArray, tyArrayConstr, tySet, tySequence} and + elif b.kind in {tyArray, tyArrayConstr, tySet, tySequence} and a.kind == b.kind: # check for seq[empty] vs. seq[int] let idx = ord(b.kind in {tyArray, tyArrayConstr}) @@ -163,7 +163,7 @@ proc commonType*(x, y: PType): PType = result = newType(k, r.owner) result.addSonSkipIntLit(r) -proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym = +proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym = result = newSym(kind, considerQuotedIdent(n), getCurrOwner(), n.info) proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym = @@ -182,7 +182,7 @@ proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym = proc semIdentVis(c: PContext, kind: TSymKind, n: PNode, allowed: TSymFlags): PSym # identifier with visability -proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode, +proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode, allowed: TSymFlags): PSym proc semStmtScope(c: PContext, n: PNode): PNode @@ -190,7 +190,7 @@ proc typeAllowedCheck(info: TLineInfo; typ: PType; kind: TSymKind) = let t = typeAllowed(typ, kind) if t != nil: if t == typ: localError(info, "invalid type: '" & typeToString(typ) & "'") - else: localError(info, "invalid type: '" & typeToString(t) & + else: localError(info, "invalid type: '" & typeToString(t) & "' in this context: '" & typeToString(typ) & "'") proc paramsTypeCheck(c: PContext, typ: PType) {.inline.} = @@ -226,7 +226,7 @@ when false: result = newSymNode(getSysSym"void") else: result.typ = makeTypeDesc(c, result.typ) - + result.handleIsOperator = proc (n: PNode): PNode = result = isOpImpl(c, n) @@ -248,7 +248,7 @@ proc fixupTypeAfterEval(c: PContext, evaluated, eOrig: PNode): PNode = if result == nil: result = arg # for 'tcnstseq' we support [] to become 'seq' - if eOrig.typ.skipTypes(abstractInst).kind == tySequence and + if eOrig.typ.skipTypes(abstractInst).kind == tySequence and arg.typ.skipTypes(abstractInst).kind == tyArrayConstr: arg.typ = eOrig.typ @@ -320,7 +320,7 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym, else: case s.typ.sons[0].kind of tyExpr: - # BUGFIX: we cannot expect a type here, because module aliases would not + # BUGFIX: we cannot expect a type here, because module aliases would not # work then (see the ``tmodulealias`` test) # semExprWithType(c, result) result = semExpr(c, result, flags) @@ -355,18 +355,18 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, result = semAfterMacroCall(c, result, sym, flags) popInfoContext() -proc forceBool(c: PContext, n: PNode): PNode = +proc forceBool(c: PContext, n: PNode): PNode = result = fitNode(c, getSysType(tyBool), n) if result == nil: result = n -proc semConstBoolExpr(c: PContext, n: PNode): PNode = +proc semConstBoolExpr(c: PContext, n: PNode): PNode = let nn = semExprWithType(c, n) result = fitNode(c, getSysType(tyBool), nn) if result == nil: localError(n.info, errConstExprExpected) return nn result = getConstExpr(c.module, result) - if result == nil: + if result == nil: localError(n.info, errConstExprExpected) result = nn @@ -403,9 +403,9 @@ proc myOpen(module: PSym): PPassContext = pushOwner(c.module) c.importTable = openScope(c) c.importTable.addSym(module) # a module knows itself - if sfSystemModule in module.flags: + if sfSystemModule in module.flags: magicsys.systemModule = module # set global variable! - else: + else: c.importTable.addSym magicsys.systemModule # import the "System" identifier importAllSymbols(c, magicsys.systemModule) c.topLevelScope = openScope(c) @@ -415,13 +415,13 @@ proc myOpenCached(module: PSym, rd: PRodReader): PPassContext = result = myOpen(module) for m in items(rd.methods): methodDef(m, true) -proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = +proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = result = semStmt(c, n) # BUGFIX: process newly generated generics here, not at the end! if c.lastGenericIdx < c.generics.len: var a = newNodeI(nkStmtList, n.info) addCodeForGenerics(c, a) - if sonsLen(a) > 0: + if sonsLen(a) > 0: # a generic has been added to `a`: if result.kind != nkEmpty: addSon(a, result) result = a @@ -429,17 +429,17 @@ proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = if gCmd == cmdInteractive and not isEmptyType(result.typ): result = buildEchoStmt(c, result) result = transformStmt(c.module, result) - -proc recoverContext(c: PContext) = + +proc recoverContext(c: PContext) = # clean up in case of a semantic error: We clean up the stacks, etc. This is - # faster than wrapping every stack operation in a 'try finally' block and + # faster than wrapping every stack operation in a 'try finally' block and # requires far less code. c.currentScope = c.topLevelScope while getCurrOwner().kind != skModule: popOwner() while c.p != nil and c.p.owner.kind != skModule: c.p = c.p.next -proc myProcess(context: PPassContext, n: PNode): PNode = - var c = PContext(context) +proc myProcess(context: PPassContext, n: PNode): PNode = + var c = PContext(context) # no need for an expensive 'try' if we stop after the first error anyway: if msgs.gErrorMax <= 1: result = semStmtAndGenerateGenerics(c, n) @@ -455,8 +455,8 @@ proc myProcess(context: PPassContext, n: PNode): PNode = if getCurrentException() of ESuggestDone: result = nil else: result = ast.emptyNode #if gCmd == cmdIdeTools: findSuggest(c, n) - -proc myClose(context: PPassContext, n: PNode): PNode = + +proc myClose(context: PPassContext, n: PNode): PNode = var c = PContext(context) closeScope(c) # close module's scope rawCloseScope(c) # imported symbols; don't check for unused ones! diff --git a/compiler/semcall.nim b/compiler/semcall.nim index d92e1ab20..718a87232 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -7,16 +7,16 @@ # distribution, for details about the copyright. # -## This module implements semantic checking for calls. +## This module implements semantic checking for calls. # included from sem.nim proc sameMethodDispatcher(a, b: PSym): bool = result = false - if a.kind == skMethod and b.kind == skMethod: + if a.kind == skMethod and b.kind == skMethod: var aa = lastSon(a.ast) var bb = lastSon(b.ast) if aa.kind == nkSym and bb.kind == nkSym: - if aa.sym == bb.sym: + if aa.sym == bb.sym: result = true else: discard @@ -31,7 +31,7 @@ proc sameMethodDispatcher(a, b: PSym): bool = # to avoid subtle problems, the call remains ambiguous and needs to # be disambiguated by the programmer; this way the right generic is # instantiated. - + proc determineType(c: PContext, s: PSym) proc pickBestCandidate(c: PContext, headSymbol: PNode, @@ -45,12 +45,12 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode, let symScope = o.lastOverloadScope var z: TCandidate - + if sym == nil: return initCandidate(c, best, sym, initialBinding, symScope) initCandidate(c, alt, sym, initialBinding, symScope) best.state = csNoMatch - + while sym != nil: if sym.kind in filter: determineType(c, sym) @@ -88,26 +88,26 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) = # Gives a detailed error message; this is separated from semOverloadedCall, # as semOverlodedCall is already pretty slow (and we need this information # only in case of an error). - if c.inCompilesContext > 0: + if c.inCompilesContext > 0: # fail fast: globalError(n.info, errTypeMismatch, "") if errors.isNil or errors.len == 0: localError(n.info, errExprXCannotBeCalled, n[0].renderTree) return - # to avoid confusing errors like: + # to avoid confusing errors like: # got (SslPtr, SocketHandle) - # but expected one of: + # but expected one of: # openssl.SSL_set_fd(ssl: SslPtr, fd: SocketHandle): cint # we do a pre-analysis. If all types produce the same string, we will add # module information. let proto = describeArgs(c, n, 1, preferName) - + var prefer = preferName for err in errors: var errProto = "" let n = err.typ.n - for i in countup(1, n.len - 1): + for i in countup(1, n.len - 1): var p = n.sons[i] if p.kind == nkSym: add(errProto, typeToString(p.sym.typ, preferName)) @@ -159,9 +159,9 @@ proc resolveOverloads(c: PContext, n, orig: PNode, n.sons.insert(hiddenArg, 1) orig.sons.insert(hiddenArg, 1) - + pickBest(f) - + if result.state != csMatch: n.sons.delete(1) orig.sons.delete(1) @@ -179,7 +179,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode, # we are going to try multiple variants n.sons[0..1] = [nil, n[1], calleeName] orig.sons[0..1] = [nil, orig[1], calleeName] - + template tryOp(x) = let op = newIdentNode(getIdent(x), n.info) n.sons[0] = op @@ -188,7 +188,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode, if nfExplicitCall in n.flags: tryOp ".()" - + if result.state in {csEmpty, csNoMatch}: tryOp "." @@ -199,7 +199,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode, n.sons[0..1] = [callOp, n[1], calleeName] orig.sons[0..1] = [callOp, orig[1], calleeName] pickBest(callOp) - + if overloadsState == csEmpty and result.state == csEmpty: localError(n.info, errUndeclaredIdentifier, considerQuotedIdent(f).s) return @@ -224,7 +224,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode, internalAssert result.state == csMatch #writeMatches(result) #writeMatches(alt) - if c.inCompilesContext > 0: + if c.inCompilesContext > 0: # quick error message for performance of 'compiles' built-in: globalError(n.info, errGenerated, "ambiguous call") elif gErrorCounter == 0: @@ -254,7 +254,7 @@ proc instGenericConvertersSons*(c: PContext, n: PNode, x: TCandidate) = for i in 1 .. <n.len: instGenericConvertersArg(c, n.sons[i], x) -proc indexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode = +proc indexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode = var m: TCandidate initCandidate(c, m, f) result = paramTypesMatch(m, f, a, arg, nil) @@ -325,7 +325,7 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode, # get rid of the deref again for a better error message: n.sons[1] = n.sons[1].sons[0] notFoundError(c, n, errors) - else: + else: notFoundError(c, n, errors) # else: result = errorNode(c, n) @@ -341,7 +341,7 @@ proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode = styleCheckUse(n.info, s) result = newSymNode(newInst, n.info) -proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = +proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = assert n.kind == nkBracketExpr for i in 1..sonsLen(n)-1: n.sons[i].typ = semTypeNode(c, n.sons[i], nil) @@ -361,11 +361,11 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = # XXX I think this could be improved by reusing sigmatch.paramTypesMatch. # It's good enough for now. result = newNodeI(a.kind, n.info) - for i in countup(0, len(a)-1): + for i in countup(0, len(a)-1): var candidate = a.sons[i].sym if candidate.kind in {skProc, skMethod, skConverter, skIterator, skClosureIterator}: - # it suffices that the candidate has the proper number of generic + # it suffices that the candidate has the proper number of generic # type parameters: if safeLen(candidate.ast.sons[genericParamsPos]) == n.len-1: result.add(explicitGenericSym(c, n, candidate)) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 9f2f755a0..0735b76ce 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -10,14 +10,14 @@ # this module does the semantic checking of type declarations # included from sem.nim -proc newOrPrevType(kind: TTypeKind, prev: PType, c: PContext): PType = - if prev == nil: +proc newOrPrevType(kind: TTypeKind, prev: PType, c: PContext): PType = + if prev == nil: result = newTypeS(kind, c) - else: + else: result = prev if result.kind == tyForward: result.kind = kind -proc newConstraint(c: PContext, k: TTypeKind): PType = +proc newConstraint(c: PContext, k: TTypeKind): PType = result = newTypeS(tyBuiltInTypeClass, c) result.addSonSkipIntLit(newTypeS(k, c)) @@ -32,22 +32,22 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = result = newOrPrevType(tyEnum, prev, c) result.n = newNodeI(nkEnumTy, n.info) checkMinSonsLen(n, 1) - if n.sons[0].kind != nkEmpty: + if n.sons[0].kind != nkEmpty: base = semTypeNode(c, n.sons[0].sons[0], nil) - if base.kind != tyEnum: + if base.kind != tyEnum: localError(n.sons[0].info, errInheritanceOnlyWithEnums) counter = lastOrd(base) + 1 rawAddSon(result, base) let isPure = result.sym != nil and sfPure in result.sym.flags var hasNull = false - for i in countup(1, sonsLen(n) - 1): + for i in countup(1, sonsLen(n) - 1): case n.sons[i].kind - of nkEnumFieldDef: + of nkEnumFieldDef: e = newSymS(skEnumField, n.sons[i].sons[0], c) var v = semConstExpr(c, n.sons[i].sons[1]) var strVal: PNode = nil - case skipTypes(v.typ, abstractInst-{tyTypeDesc}).kind - of tyTuple: + case skipTypes(v.typ, abstractInst-{tyTypeDesc}).kind + of tyTuple: if sonsLen(v) == 2: strVal = v.sons[1] # second tuple part is the string value if skipTypes(strVal.typ, abstractInst).kind in {tyString, tyCString}: @@ -63,14 +63,14 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = x = getOrdValue(v) if i != 1: if x != counter: incl(result.flags, tfEnumHasHoles) - if x < counter: + if x < counter: localError(n.sons[i].info, errInvalidOrderInEnumX, e.name.s) x = counter e.ast = strVal # might be nil counter = x - of nkSym: + of nkSym: e = n.sons[i].sym - of nkIdent, nkAccQuoted: + of nkIdent, nkAccQuoted: e = newSymS(skEnumField, n.sons[i], c) else: illFormedAst(n[i]) @@ -87,28 +87,28 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = inc(counter) if not hasNull: incl(result.flags, tfNeedsInit) -proc semSet(c: PContext, n: PNode, prev: PType): PType = +proc semSet(c: PContext, n: PNode, prev: PType): PType = result = newOrPrevType(tySet, prev, c) - if sonsLen(n) == 2: + if sonsLen(n) == 2: var base = semTypeNode(c, n.sons[1], nil) addSonSkipIntLit(result, base) if base.kind == tyGenericInst: base = lastSon(base) if base.kind != tyGenericParam: - if not isOrdinalType(base): + if not isOrdinalType(base): localError(n.info, errOrdinalTypeExpected) - elif lengthOrd(base) > MaxSetElements: + elif lengthOrd(base) > MaxSetElements: localError(n.info, errSetTooBig) else: localError(n.info, errXExpectsOneTypeParam, "set") addSonSkipIntLit(result, errorType(c)) - -proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string, - prev: PType): PType = + +proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string, + prev: PType): PType = result = newOrPrevType(kind, prev, c) - if sonsLen(n) == 2: + if sonsLen(n) == 2: var base = semTypeNode(c, n.sons[1], nil) addSonSkipIntLit(result, base) - else: + else: localError(n.info, errXExpectsOneTypeParam, kindStr) addSonSkipIntLit(result, errorType(c)) @@ -140,23 +140,23 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType = var base = semTypeNode(c, n.lastSon, nil) addSonSkipIntLit(result, base) -proc semVarType(c: PContext, n: PNode, prev: PType): PType = - if sonsLen(n) == 1: +proc semVarType(c: PContext, n: PNode, prev: PType): PType = + if sonsLen(n) == 1: result = newOrPrevType(tyVar, prev, c) var base = semTypeNode(c, n.sons[0], nil) - if base.kind == tyVar: + if base.kind == tyVar: localError(n.info, errVarVarTypeNotAllowed) base = base.sons[0] addSonSkipIntLit(result, base) else: result = newConstraint(c, tyVar) -proc semDistinct(c: PContext, n: PNode, prev: PType): PType = +proc semDistinct(c: PContext, n: PNode, prev: PType): PType = if n.len == 0: return newConstraint(c, tyDistinct) result = newOrPrevType(tyDistinct, prev, c) addSonSkipIntLit(result, semTypeNode(c, n.sons[0], nil)) if n.len > 1: result.n = n[1] - + proc semRangeAux(c: PContext, n: PNode, prev: PType): PType = assert isRange(n) checkSonsLen(n, 3) @@ -164,11 +164,11 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType = result.n = newNodeI(nkRange, n.info) if (n[1].kind == nkEmpty) or (n[2].kind == nkEmpty): localError(n.info, errRangeIsEmpty) - + var range: array[2, PNode] range[0] = semExprWithType(c, n[1], {efDetermineType}) range[1] = semExprWithType(c, n[2], {efDetermineType}) - + var rangeT: array[2, PType] for i in 0..1: rangeT[i] = range[i].typ.skipTypes({tyStatic}).skipIntLit @@ -179,13 +179,13 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType = localError(n.info, errOrdinalTypeExpected) elif enumHasHoles(rangeT[0]): localError(n.info, errEnumXHasHoles, rangeT[0].sym.name.s) - + for i in 0..1: if hasGenericArguments(range[i]): result.n.addSon makeStaticExpr(c, range[i]) else: result.n.addSon semConstExpr(c, range[i]) - + if weakLeValue(result.n[0], result.n[1]) == impNo: localError(n.info, errRangeIsEmpty) @@ -201,10 +201,10 @@ proc semRange(c: PContext, n: PNode, prev: PType): PType = incl(result.flags, tfNeedsInit) elif n.sons[1].kind in {nkCharLit..nkUInt64Lit} and n.sons[1].intVal < 0: incl(result.flags, tfNeedsInit) - elif n.sons[0].kind in {nkFloatLit..nkFloat64Lit} and + elif n.sons[0].kind in {nkFloatLit..nkFloat64Lit} and n.sons[0].floatVal > 0.0: incl(result.flags, tfNeedsInit) - elif n.sons[1].kind in {nkFloatLit..nkFloat64Lit} and + elif n.sons[1].kind in {nkFloatLit..nkFloat64Lit} and n.sons[1].floatVal < 0.0: incl(result.flags, tfNeedsInit) else: @@ -243,13 +243,13 @@ proc semArrayIndex(c: PContext, n: PNode): PType = else: let x = semConstExpr(c, e) if x.kind in {nkIntLit..nkUInt64Lit}: - result = makeRangeType(c, 0, x.intVal-1, n.info, + result = makeRangeType(c, 0, x.intVal-1, n.info, x.typ.skipTypes({tyTypeDesc})) else: result = x.typ.skipTypes({tyTypeDesc}) #localError(n[1].info, errConstExprExpected) -proc semArray(c: PContext, n: PNode, prev: PType): PType = +proc semArray(c: PContext, n: PNode, prev: PType): PType = var base: PType result = newOrPrevType(tyArray, prev, c) if sonsLen(n) == 3: @@ -260,20 +260,20 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType = if indx.kind notin {tyGenericParam, tyStatic, tyFromExpr}: if not isOrdinalType(indx): localError(n.sons[1].info, errOrdinalTypeExpected) - elif enumHasHoles(indx): + elif enumHasHoles(indx): localError(n.sons[1].info, errEnumXHasHoles, indx.sym.name.s) base = semTypeNode(c, n.sons[2], nil) addSonSkipIntLit(result, base) - else: + else: localError(n.info, errArrayExpectsTwoTypeParams) result = newOrPrevType(tyError, prev, c) - -proc semOrdinal(c: PContext, n: PNode, prev: PType): PType = + +proc semOrdinal(c: PContext, n: PNode, prev: PType): PType = result = newOrPrevType(tyOrdinal, prev, c) - if sonsLen(n) == 2: + if sonsLen(n) == 2: var base = semTypeNode(c, n.sons[1], nil) - if base.kind != tyGenericParam: - if not isOrdinalType(base): + if base.kind != tyGenericParam: + if not isOrdinalType(base): localError(n.sons[1].info, errOrdinalTypeExpected) addSonSkipIntLit(result, base) else: @@ -281,7 +281,7 @@ proc semOrdinal(c: PContext, n: PNode, prev: PType): PType = result = newOrPrevType(tyError, prev, c) proc semTypeIdent(c: PContext, n: PNode): PSym = - if n.kind == nkSym: + if n.kind == nkSym: result = n.sym else: when defined(nimfix): @@ -307,7 +307,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = result = result.typ.sym.copySym result.typ = copyType(result.typ, result.typ.owner, true) result.typ.flags.incl tfUnresolved - + if result.kind == skGenericParam: if result.typ.kind == tyGenericParam and result.typ.len == 0 and tfWildcard in result.typ.flags: @@ -319,7 +319,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = localError(n.info, errTypeExpected) return errorSym(c, n) - if result.kind != skType: + if result.kind != skType: # this implements the wanted ``var v: V, x: V`` feature ... var ov: TOverloadIter var amb = initOverloadIter(ov, c, n) @@ -344,48 +344,48 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = else: localError(n.info, errIdentifierExpected) result = errorSym(c, n) - -proc semTuple(c: PContext, n: PNode, prev: PType): PType = + +proc semTuple(c: PContext, n: PNode, prev: PType): PType = if n.sonsLen == 0: return newConstraint(c, tyTuple) var typ: PType result = newOrPrevType(tyTuple, prev, c) result.n = newNodeI(nkRecList, n.info) var check = initIntSet() var counter = 0 - for i in countup(0, sonsLen(n) - 1): + for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if (a.kind != nkIdentDefs): illFormedAst(a) checkMinSonsLen(a, 3) var length = sonsLen(a) - if a.sons[length - 2].kind != nkEmpty: + if a.sons[length - 2].kind != nkEmpty: typ = semTypeNode(c, a.sons[length - 2], nil) else: localError(a.info, errTypeExpected) typ = errorType(c) - if a.sons[length - 1].kind != nkEmpty: + if a.sons[length - 1].kind != nkEmpty: localError(a.sons[length - 1].info, errInitHereNotAllowed) - for j in countup(0, length - 3): + for j in countup(0, length - 3): var field = newSymG(skField, a.sons[j], c) field.typ = typ field.position = counter inc(counter) - if containsOrIncl(check, field.name.id): + if containsOrIncl(check, field.name.id): localError(a.sons[j].info, errAttemptToRedefine, field.name.s) else: addSon(result.n, newSymNode(field)) addSonSkipIntLit(result, typ) if gCmd == cmdPretty: styleCheckDef(a.sons[j].info, field) -proc semIdentVis(c: PContext, kind: TSymKind, n: PNode, - allowed: TSymFlags): PSym = +proc semIdentVis(c: PContext, kind: TSymKind, n: PNode, + allowed: TSymFlags): PSym = # identifier with visibility - if n.kind == nkPostfix: - if sonsLen(n) == 2 and n.sons[0].kind == nkIdent: + if n.kind == nkPostfix: + if sonsLen(n) == 2 and n.sons[0].kind == nkIdent: # for gensym'ed identifiers the identifier may already have been # transformed to a symbol and we need to use that here: result = newSymG(kind, n.sons[1], c) var v = n.sons[0].ident - if sfExported in allowed and v.id == ord(wStar): + if sfExported in allowed and v.id == ord(wStar): incl(result.flags, sfExported) else: localError(n.sons[0].info, errInvalidVisibilityX, v.s) @@ -393,7 +393,7 @@ proc semIdentVis(c: PContext, kind: TSymKind, n: PNode, illFormedAst(n) else: result = newSymG(kind, n, c) - + proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode, allowed: TSymFlags): PSym = if n.kind == nkPragmaExpr: @@ -415,31 +415,31 @@ proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode, proc checkForOverlap(c: PContext, t: PNode, currentEx, branchIndex: int) = let ex = t[branchIndex][currentEx].skipConv for i in countup(1, branchIndex): - for j in countup(0, sonsLen(t.sons[i]) - 2): + for j in countup(0, sonsLen(t.sons[i]) - 2): if i == branchIndex and j == currentEx: break if overlap(t.sons[i].sons[j].skipConv, ex): localError(ex.info, errDuplicateCaseLabel) - + proc semBranchRange(c: PContext, t, a, b: PNode, covered: var BiggestInt): PNode = checkMinSonsLen(t, 1) let ac = semConstExpr(c, a) let bc = semConstExpr(c, b) let at = fitNode(c, t.sons[0].typ, ac).skipConvTakeType let bt = fitNode(c, t.sons[0].typ, bc).skipConvTakeType - + result = newNodeI(nkRange, a.info) result.add(at) result.add(bt) if emptyRange(ac, bc): localError(b.info, errRangeIsEmpty) else: covered = covered + getOrdValue(bc) - getOrdValue(ac) + 1 -proc semCaseBranchRange(c: PContext, t, b: PNode, - covered: var BiggestInt): PNode = +proc semCaseBranchRange(c: PContext, t, b: PNode, + covered: var BiggestInt): PNode = checkSonsLen(b, 3) result = semBranchRange(c, t, b.sons[1], b.sons[2], covered) -proc semCaseBranchSetElem(c: PContext, t, b: PNode, - covered: var BiggestInt): PNode = +proc semCaseBranchSetElem(c: PContext, t, b: PNode, + covered: var BiggestInt): PNode = if isRange(b): checkSonsLen(b, 3) result = semBranchRange(c, t, b.sons[1], b.sons[2], covered) @@ -450,10 +450,10 @@ proc semCaseBranchSetElem(c: PContext, t, b: PNode, result = fitNode(c, t.sons[0].typ, b) inc(covered) -proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int, - covered: var BiggestInt) = - - for i in countup(0, sonsLen(branch) - 2): +proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int, + covered: var BiggestInt) = + + for i in countup(0, sonsLen(branch) - 2): var b = branch.sons[i] if b.kind == nkRange: branch.sons[i] = b @@ -480,7 +480,7 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int, var L = branch.len swap(branch.sons[L-2], branch.sons[L-1]) checkForOverlap(c, t, i, branchIndex) - + proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, father: PNode, rectype: PType) proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int, @@ -514,11 +514,11 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int, else: illFormedAst(n) 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(a.sons[0].typ)): localError(a.info, errNotAllCasesCovered) addSon(father, a) -proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, +proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, father: PNode, rectype: PType) = if n == nil: return case n.kind @@ -556,12 +556,12 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, semRecordNodeAux(c, branch, check, pos, father, rectype) of nkRecCase: semRecordCase(c, n, check, pos, father, rectype) - of nkNilLit: + of nkNilLit: if father.kind != nkRecList: addSon(father, newNodeI(nkRecList, n.info)) of nkRecList: # attempt to keep the nesting at a sane level: var a = if father.kind == nkRecList: father else: copyNode(n) - for i in countup(0, sonsLen(n) - 1): + for i in countup(0, sonsLen(n) - 1): semRecordNodeAux(c, n.sons[i], check, pos, a, rectype) if a != father: addSon(father, a) of nkIdentDefs: @@ -570,10 +570,10 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, var a: PNode if father.kind != nkRecList and length>=4: a = newNodeI(nkRecList, n.info) else: a = ast.emptyNode - if n.sons[length-1].kind != nkEmpty: + if n.sons[length-1].kind != nkEmpty: localError(n.sons[length-1].info, errInitHereNotAllowed) var typ: PType - if n.sons[length-2].kind == nkEmpty: + if n.sons[length-2].kind == nkEmpty: localError(n.info, errTypeExpected) typ = errorType(c) else: @@ -586,7 +586,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, f.typ = typ f.position = pos if (rec != nil) and ({sfImportc, sfExportc} * rec.flags != {}) and - (f.loc.r == nil): + (f.loc.r == nil): f.loc.r = toRope(f.name.s) f.flags = f.flags + ({sfImportc, sfExportc} * rec.flags) inc(pos) @@ -598,8 +598,8 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, if a.kind != nkEmpty: addSon(father, a) of nkEmpty: discard else: illFormedAst(n) - -proc addInheritedFieldsAux(c: PContext, check: var IntSet, pos: var int, + +proc addInheritedFieldsAux(c: PContext, check: var IntSet, pos: var int, n: PNode) = case n.kind of nkRecCase: @@ -618,31 +618,31 @@ proc addInheritedFieldsAux(c: PContext, check: var IntSet, pos: var int, inc(pos) else: internalError(n.info, "addInheritedFieldsAux()") -proc skipGenericInvocation(t: PType): PType {.inline.} = +proc skipGenericInvocation(t: PType): PType {.inline.} = result = t if result.kind == tyGenericInvocation: result = result.sons[0] if result.kind == tyGenericBody: result = lastSon(result) -proc addInheritedFields(c: PContext, check: var IntSet, pos: var int, +proc addInheritedFields(c: PContext, check: var IntSet, pos: var int, obj: PType) = assert obj.kind == tyObject - if (sonsLen(obj) > 0) and (obj.sons[0] != nil): + if (sonsLen(obj) > 0) and (obj.sons[0] != nil): addInheritedFields(c, check, pos, obj.sons[0].skipGenericInvocation) addInheritedFieldsAux(c, check, pos, obj.n) proc semObjectNode(c: PContext, n: PNode, prev: PType): PType = if n.sonsLen == 0: return newConstraint(c, tyObject) var check = initIntSet() - var pos = 0 + var pos = 0 var base: PType = nil # n.sons[0] contains the pragmas (if any). We process these later... checkSonsLen(n, 3) - if n.sons[1].kind != nkEmpty: + if n.sons[1].kind != nkEmpty: base = skipTypes(semTypeNode(c, n.sons[1].sons[0], nil), skipPtrs) var concreteBase = skipGenericInvocation(base).skipTypes(skipPtrs) - if concreteBase.kind == tyObject and tfFinal notin concreteBase.flags: + if concreteBase.kind == tyObject and tfFinal notin concreteBase.flags: addInheritedFields(c, check, pos, concreteBase) else: if concreteBase.kind != tyError: @@ -723,7 +723,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, genericParams.addSon(newSymNode(s)) result = typeClass addDecl(c, s) - + # XXX: There are codegen errors if this is turned into a nested proc template liftingWalk(typ: PType, anonFlag = false): expr = liftParamType(c, procKind, genericParams, typ, paramName, info, anonFlag) @@ -742,7 +742,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, case paramType.kind: of tyAnything: result = addImplicitGeneric(newTypeS(tyGenericParam, c)) - + of tyStatic: # proc(a: expr{string}, b: expr{nkLambda}) # overload on compile time values and AST trees @@ -753,7 +753,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, localError(info, errMacroBodyDependsOnGenericTypes, paramName) result = addImplicitGeneric(c.newTypeWithSons(tyStatic, @[base])) result.flags.incl({tfHasStatic, tfUnresolved}) - + of tyTypeDesc: if tfUnresolved notin paramType.flags: # naked typedescs are not bindOnce types @@ -761,12 +761,12 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, paramTypId.id == typedescId.id: paramTypId = nil result = addImplicitGeneric( c.newTypeWithSons(tyTypeDesc, @[paramType.base])) - + of tyDistinct: if paramType.sonsLen == 1: # disable the bindOnce behavior for the type class result = liftingWalk(paramType.sons[0], true) - + of tySequence, tySet, tyArray, tyOpenArray, tyVar, tyPtr, tyRef, tyProc: # XXX: this is a bit strange, but proc(s: seq) @@ -785,22 +785,22 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, if lifted != nil: paramType.sons[i] = lifted result = paramType - + of tyGenericBody: result = newTypeS(tyGenericInvocation, c) result.rawAddSon(paramType) - + for i in 0 .. paramType.sonsLen - 2: if paramType.sons[i].kind == tyStatic: result.rawAddSon makeTypeFromExpr(c, ast.emptyNode) # aka 'tyUnknown' else: result.rawAddSon newTypeS(tyAnything, c) - + if paramType.lastSon.kind == tyUserTypeClass: result.kind = tyUserTypeClassInst result.rawAddSon paramType.lastSon return addImplicitGeneric(result) - + result = instGenericContainer(c, paramType.sym.info, result, allowMetaTypes = true) result = newTypeWithSons(c, tyCompositeTypeClass, @[paramType, result]) @@ -832,7 +832,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, if liftBody != nil: result = liftBody result.shouldHaveMeta - + of tyGenericInvocation: for i in 1 .. <paramType.sonsLen: let lifted = liftingWalk(paramType.sons[i]) @@ -844,18 +844,18 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, of tyUserTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot: result = addImplicitGeneric(copyType(paramType, getCurrOwner(), true)) - + of tyExpr: if procKind notin {skMacro, skTemplate}: result = addImplicitGeneric(newTypeS(tyAnything, c)) - + of tyGenericParam: markUsed(info, paramType.sym) styleCheckUse(info, paramType.sym) if tfWildcard in paramType.flags: paramType.flags.excl tfWildcard paramType.sym.kind = skType - + else: discard # result = liftingWalk(paramType) @@ -872,7 +872,7 @@ proc newProcType(c: PContext; info: TLineInfo; prev: PType = nil): PType = result.callConv = lastOptionEntry(c).defaultCC result.n = newNodeI(nkFormalParams, info) rawAddSon(result, nil) # return type - # result.n[0] used to be `nkType`, but now it's `nkEffectList` because + # result.n[0] used to be `nkType`, but now it's `nkEffectList` because # the effects are now stored in there too ... this is a bit hacky, but as # usual we desperately try to save memory: addSon(result.n, newNodeI(nkEffectList, info)) @@ -909,7 +909,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, typ = semParamType(c, a.sons[length-2], constraint) if hasDefault: - def = semExprWithType(c, a.sons[length-1]) + def = semExprWithType(c, a.sons[length-1]) # check type compatibility between def.typ and typ: if typ == nil: typ = def.typ @@ -927,7 +927,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, typ = newTypeS(tdef, c) if skipTypes(typ, {tyGenericInst}).kind == tyEmpty: continue - for j in countup(0, length-3): + for j in countup(0, length-3): var arg = newSymG(skParam, a.sons[j], c) let lifted = liftParamType(c, kind, genericParams, typ, arg.name.s, arg.info) @@ -937,7 +937,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, arg.constraint = constraint inc(counter) if def != nil and def.kind != nkEmpty: arg.ast = copyTree(def) - if containsOrIncl(check, arg.name.id): + if containsOrIncl(check, arg.name.id): localError(a.sons[j].info, errAttemptToRedefine, arg.name.s) addSon(result.n, newSymNode(arg)) rawAddSon(result, finalType) @@ -950,9 +950,9 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, elif kind == skIterator: # XXX This is special magic we should likely get rid of r = newTypeS(tyExpr, c) - + if r != nil: - # turn explicit 'void' return type into 'nil' because the rest of the + # turn explicit 'void' return type into 'nil' because the rest of the # compiler only checks for 'nil': if skipTypes(r, {tyGenericInst}).kind != tyEmpty: # 'auto' as a return type does not imply a generic: @@ -988,8 +988,8 @@ proc semStmtListType(c: PContext, n: PNode, prev: PType): PType = n.sons[length - 1].typ = result else: result = nil - -proc semBlockType(c: PContext, n: PNode, prev: PType): PType = + +proc semBlockType(c: PContext, n: PNode, prev: PType): PType = inc(c.p.nestedBlockCounter) checkSonsLen(n, 2) openScope(c) @@ -1009,7 +1009,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = localError(n.info, "cannot instantiate the '$1' $2" % [s.name.s, ($s.kind).substr(2).toLower]) return newOrPrevType(tyError, prev, c) - + var t = s.typ if t.kind == tyCompositeTypeClass and t.base.kind == tyGenericBody: t = t.base @@ -1036,7 +1036,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = else: var m = newCandidate(c, t) matches(c, n, copyTree(n), m) - + if m.state != csMatch: var err = "cannot instantiate " & typeToString(t) & "\n" & "got: (" & describeArgs(c, n) & ")\n" & @@ -1045,12 +1045,12 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = return newOrPrevType(tyError, prev, c) var isConcrete = true - + for i in 1 .. <m.call.len: let typ = m.call[i].typ.skipTypes({tyTypeDesc}) if containsGenericType(typ): isConcrete = false addToResult(typ) - + if isConcrete: if s.ast == nil and s.typ.kind != tyCompositeTypeClass: # XXX: What kind of error is this? is it still relevant? @@ -1081,7 +1081,7 @@ proc semTypeClass(c: PContext, n: PNode, prev: PType): PType = let pragmas = n[1] inherited = n[2] - + if inherited.kind != nkEmpty: for n in inherited.sons: let typ = semTypeNode(c, n, nil) @@ -1114,7 +1114,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = checkSonsLen(n, 1) let typExpr = semExprWithType(c, n.sons[0], {efInTypeof}) result = typExpr.typ.skipTypes({tyIter}) - of nkPar: + of nkPar: if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev) else: # XXX support anon tuple here @@ -1197,7 +1197,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result = makeTypeFromExpr(c, preprocessed.copyTree) of nkIdent, nkAccQuoted: var s = semTypeIdent(c, n) - if s.typ == nil: + if s.typ == nil: if s.kind != skError: localError(n.info, errTypeExpected) result = newOrPrevType(tyError, prev, c) elif s.kind == skParam and s.typ.kind == tyTypeDesc: @@ -1205,19 +1205,19 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result = s.typ.base elif prev == nil: result = s.typ - else: + else: assignType(prev, s.typ) # bugfix: keep the fresh id for aliases to integral types: if s.typ.kind notin {tyBool, tyChar, tyInt..tyInt64, tyFloat..tyFloat128, - tyUInt..tyUInt64}: + tyUInt..tyUInt64}: prev.id = s.typ.id result = prev of nkSym: if n.sym.kind == skType and n.sym.typ != nil: var t = n.sym.typ - if prev == nil: + if prev == nil: result = t - else: + else: assignType(prev, t) result = prev markUsed(n.info, n.sym) @@ -1267,12 +1267,12 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result = newOrPrevType(tyError, prev, c) n.typ = result -proc setMagicType(m: PSym, kind: TTypeKind, size: int) = +proc setMagicType(m: PSym, kind: TTypeKind, size: int) = m.typ.kind = kind m.typ.align = size.int16 m.typ.size = size - -proc processMagicType(c: PContext, m: PSym) = + +proc processMagicType(c: PContext, m: PSym) = case m.magic of mInt: setMagicType(m, tyInt, intSize) of mInt8: setMagicType(m, tyInt8, 1) @@ -1290,21 +1290,21 @@ proc processMagicType(c: PContext, m: PSym) = of mFloat128: setMagicType(m, tyFloat128, 16) of mBool: setMagicType(m, tyBool, 1) of mChar: setMagicType(m, tyChar, 1) - of mString: + of mString: setMagicType(m, tyString, ptrSize) rawAddSon(m.typ, getSysType(tyChar)) - of mCstring: + of mCstring: setMagicType(m, tyCString, ptrSize) rawAddSon(m.typ, getSysType(tyChar)) of mPointer: setMagicType(m, tyPointer, ptrSize) - of mEmptySet: + of mEmptySet: setMagicType(m, tySet, 1) rawAddSon(m.typ, newTypeS(tyEmpty, c)) of mIntSetBaseType: setMagicType(m, tyRange, intSize) of mNil: setMagicType(m, tyNil, ptrSize) of mExpr: setMagicType(m, tyExpr, 0) of mStmt: setMagicType(m, tyStmt, 0) - of mTypeDesc: + of mTypeDesc: setMagicType(m, tyTypeDesc, 0) rawAddSon(m.typ, newTypeS(tyNone, c)) of mVoidType: setMagicType(m, tyEmpty, 0) @@ -1318,8 +1318,8 @@ proc processMagicType(c: PContext, m: PSym) = setMagicType(m, tyRange, 0) rawAddSon(m.typ, newTypeS(tyNone, c)) of mSet: - setMagicType(m, tySet, 0) - of mSeq: + setMagicType(m, tySet, 0) + of mSeq: setMagicType(m, tySequence, 0) of mOrdinal: setMagicType(m, tyOrdinal, 0) @@ -1335,13 +1335,13 @@ proc processMagicType(c: PContext, m: PSym) = incl m.typ.flags, tfShared rawAddSon(m.typ, sysTypeFromName"shared") else: localError(m.info, errTypeExpected) - + proc semGenericConstraints(c: PContext, x: PType): PType = result = newTypeWithSons(c, tyGenericParam, @[x]) -proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = +proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = result = copyNode(n) - if n.kind != nkGenericParams: + if n.kind != nkGenericParams: illFormedAst(n) return for i in countup(0, sonsLen(n)-1): @@ -1351,7 +1351,7 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = var def = a{-1} let constraint = a{-2} var typ: PType - + if constraint.kind != nkEmpty: typ = semTypeNode(c, constraint, nil) if typ.kind != tyStatic or typ.len == 0: @@ -1360,7 +1360,7 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = typ = newTypeWithSons(c, tyTypeDesc, @[newTypeS(tyNone, c)]) else: typ = semGenericConstraints(c, typ) - + if def.kind != nkEmpty: def = semConstExpr(c, def) if typ == nil: @@ -1372,7 +1372,7 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = def.typ = def.typ.skipTypes({tyTypeDesc}) if not containsGenericType(def.typ): def = fitNode(c, typ, def) - + if typ == nil: typ = newTypeS(tyGenericParam, c) if father == nil: typ.flags.incl tfWildcard diff --git a/compiler/vm.nim b/compiler/vm.nim index a36de1c20..f0a0135e8 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -239,7 +239,7 @@ proc pushSafePoint(f: PStackFrame; pc: int) = proc popSafePoint(f: PStackFrame) = discard f.safePoints.pop() -proc cleanUpOnException(c: PCtx; tos: PStackFrame): +proc cleanUpOnException(c: PCtx; tos: PStackFrame): tuple[pc: int, f: PStackFrame] = let raisedType = c.currentExceptionA.typ.skipTypes(abstractPtrs) var f = tos @@ -257,7 +257,7 @@ proc cleanUpOnException(c: PCtx; tos: PStackFrame): let exceptType = c.types[c.code[pc2].regBx-wordExcess].skipTypes( abstractPtrs) if inheritanceDiff(exceptType, raisedType) <= 0: - # mark exception as handled but keep it in B for + # mark exception as handled but keep it in B for # the getCurrentException() builtin: c.currentExceptionB = c.currentExceptionA c.currentExceptionA = nil @@ -349,14 +349,14 @@ proc opConv*(dest: var TFullReg, src: TFullReg, desttyp, srctyp: PType): bool = if dest.kind != rkFloat: myreset(dest); dest.kind = rkFloat case skipTypes(srctyp, abstractRange).kind - of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyBool, tyChar: + of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyBool, tyChar: dest.floatVal = toFloat(src.intVal.int) else: dest.floatVal = src.floatVal else: asgnComplex(dest, src) -proc compile(c: PCtx, s: PSym): int = +proc compile(c: PCtx, s: PSym): int = result = vmgen.genProc(c, s) when debugEchoCode: c.echoCode result #c.echoCode @@ -396,10 +396,10 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = pc = tos.comesFrom tos = tos.next let retVal = regs[0] - if tos.isNil: + if tos.isNil: #echo "RET ", retVal.rendertree return retVal - + move(regs, tos.slots) assert c.code[pc].opcode in {opcIndCall, opcIndCallAsgn} if c.code[pc].opcode == opcIndCallAsgn: @@ -653,7 +653,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcSubu: decodeBC(rkInt) regs[ra].intVal = regs[rb].intVal -% regs[rc].intVal - of opcMulu: + of opcMulu: decodeBC(rkInt) regs[ra].intVal = regs[rb].intVal *% regs[rc].intVal of opcDivu: @@ -726,7 +726,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcLeSet: decodeBC(rkInt) regs[ra].intVal = ord(containsSets(regs[rb].node, regs[rc].node)) - of opcEqSet: + of opcEqSet: decodeBC(rkInt) regs[ra].intVal = ord(equalSets(regs[rb].node, regs[rc].node)) of opcLtSet: @@ -737,9 +737,9 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcMulSet: decodeBC(rkNode) createSet(regs[ra]) - move(regs[ra].node.sons, + move(regs[ra].node.sons, nimsets.intersectSets(regs[rb].node, regs[rc].node).sons) - of opcPlusSet: + of opcPlusSet: decodeBC(rkNode) createSet(regs[ra]) move(regs[ra].node.sons, @@ -753,7 +753,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = decodeBC(rkNode) createSet(regs[ra]) move(regs[ra].node.sons, - nimsets.symdiffSets(regs[rb].node, regs[rc].node).sons) + nimsets.symdiffSets(regs[rb].node, regs[rc].node).sons) of opcConcatStr: decodeBC(rkNode) createStr regs[ra] @@ -793,7 +793,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = assert c.code[pc].opcode == opcSubStr let rd = c.code[pc].regA createStr regs[ra] - regs[ra].node.strVal = substr(regs[rb].node.strVal, + regs[ra].node.strVal = substr(regs[rb].node.strVal, regs[rc].intVal.int, regs[rd].intVal.int) of opcParseFloat: decodeBC(rkInt) @@ -896,12 +896,12 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = # we know the next instruction is a 'fjmp': let branch = c.constants[instr.regBx-wordExcess] var cond = false - for j in countup(0, sonsLen(branch) - 2): - if overlap(regs[ra].regToNode, branch.sons[j]): + for j in countup(0, sonsLen(branch) - 2): + if overlap(regs[ra].regToNode, branch.sons[j]): cond = true break assert c.code[pc+1].opcode == opcFJmp - inc pc + inc pc # we skip this instruction so that the final 'inc(pc)' skips # the following jump if not cond: @@ -1273,7 +1273,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcNSetIntVal: decodeB(rkNode) var dest = regs[ra].node - if dest.kind in {nkCharLit..nkInt64Lit} and + if dest.kind in {nkCharLit..nkInt64Lit} and regs[rb].kind in {rkInt}: dest.intVal = regs[rb].intVal else: @@ -1281,24 +1281,24 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcNSetFloatVal: decodeB(rkNode) var dest = regs[ra].node - if dest.kind in {nkFloatLit..nkFloat64Lit} and + if dest.kind in {nkFloatLit..nkFloat64Lit} and regs[rb].kind in {rkFloat}: dest.floatVal = regs[rb].floatVal - else: + else: stackTrace(c, tos, pc, errFieldXNotFound, "floatVal") of opcNSetSymbol: decodeB(rkNode) var dest = regs[ra].node if dest.kind == nkSym and regs[rb].node.kind == nkSym: dest.sym = regs[rb].node.sym - else: + else: stackTrace(c, tos, pc, errFieldXNotFound, "symbol") of opcNSetIdent: decodeB(rkNode) var dest = regs[ra].node if dest.kind == nkIdent and regs[rb].node.kind == nkIdent: dest.ident = regs[rb].node.ident - else: + else: stackTrace(c, tos, pc, errFieldXNotFound, "ident") of opcNSetType: decodeB(rkNode) @@ -1309,7 +1309,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcNSetStrVal: decodeB(rkNode) var dest = regs[ra].node - if dest.kind in {nkStrLit..nkTripleStrLit} and + if dest.kind in {nkStrLit..nkTripleStrLit} and regs[rb].kind in {rkNode}: dest.strVal = regs[rb].node.strVal else: @@ -1435,8 +1435,9 @@ proc evalConstExprAux(module, prc: PSym, n: PNode, mode: TEvalMode): PNode = newSeq(tos.slots, c.prc.maxSlots) #for i in 0 .. <c.prc.maxSlots: tos.slots[i] = newNode(nkEmpty) result = rawExecute(c, start, tos).regToNode + if result.info.line < 0: result.info = n.info -proc evalConstExpr*(module: PSym, e: PNode): PNode = +proc evalConstExpr*(module: PSym, e: PNode): PNode = result = evalConstExprAux(module, nil, e, emConst) proc evalStaticExpr*(module: PSym, e: PNode, prc: PSym): PNode = @@ -1496,6 +1497,7 @@ proc evalMacroCall*(module: PSym, n, nOrig: PNode, sym: PSym): PNode = # temporary storage: #for i in L .. <maxSlots: tos.slots[i] = newNode(nkEmpty) result = rawExecute(c, start, tos).regToNode + if result.info.line < 0: result.info = n.info if cyclicTree(result): globalError(n.info, errCyclicTree) dec(evalMacroCounter) c.callsite = nil diff --git a/koch.nim b/koch.nim index d365262c1..34cb1317d 100644 --- a/koch.nim +++ b/koch.nim @@ -347,7 +347,7 @@ proc temp(args: string) = if args.len > 0: exec(finalDest & " " & args) proc showHelp() = - quit(HelpText % [VersionAsString & repeatChar(44-len(VersionAsString)), + quit(HelpText % [VersionAsString & spaces(44-len(VersionAsString)), CompileDate, CompileTime], QuitSuccess) var op = initOptParser() diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 4758dc0c1..0888a8767 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -343,7 +343,7 @@ proc expectKind*(n: PNimrodNode, k: TNimrodNodeKind) {.compileTime.} = ## checks that `n` is of kind `k`. If this is not the case, ## compilation aborts with an error message. This is useful for writing ## macros that check the AST that is passed to them. - if n.kind != k: error("macro expects a node of kind: " & $k) + if n.kind != k: error("Expected a node of kind " & $k & ", got " & $n.kind) proc expectMinLen*(n: PNimrodNode, min: int) {.compileTime.} = ## checks that `n` has at least `min` children. If this is not the case, @@ -581,10 +581,8 @@ const CallNodes* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand, nnkCallStrLit, nnkHiddenCallConv} -from strutils import cmpIgnoreStyle, format - proc expectKind*(n: PNimrodNode; k: set[TNimrodNodeKind]) {.compileTime.} = - assert n.kind in k, "Expected one of $1, got $2".format(k, n.kind) + assert n.kind in k, "Expected one of " & $k & ", got " & $n.kind proc newProc*(name = newEmptyNode(); params: openArray[PNimrodNode] = [newEmptyNode()]; body: PNimrodNode = newStmtList(), procType = nnkProcDef): PNimrodNode {.compileTime.} = @@ -654,7 +652,7 @@ proc `pragma=`*(someProc: PNimrodNode; val: PNimrodNode){.compileTime.}= template badNodeKind(k; f): stmt{.immediate.} = - assert false, "Invalid node kind $# for macros.`$2`".format(k, f) + assert false, "Invalid node kind " & $k & " for macros.`" & $f & "`" proc body*(someProc: PNimrodNode): PNimrodNode {.compileTime.} = case someProc.kind: @@ -776,6 +774,22 @@ proc copy*(node: PNimrodNode): PNimrodNode {.compileTime.} = ## An alias for copyNimTree(). return node.copyNimTree() +proc cmpIgnoreStyle(a, b: cstring): int {.noSideEffect.} = + proc toLower(c: char): char {.inline.} = + if c in {'A'..'Z'}: result = chr(ord(c) + (ord('a') - ord('A'))) + else: result = c + var i = 0 + var j = 0 + while true: + while a[i] == '_': inc(i) + while b[j] == '_': inc(j) # BUGFIX: typo + var aa = toLower(a[i]) + var bb = toLower(b[j]) + result = ord(aa) - ord(bb) + if result != 0 or aa == '\0': break + inc(i) + inc(j) + proc eqIdent* (a, b: string): bool = cmpIgnoreStyle(a, b) == 0 ## Check if two idents are identical. diff --git a/lib/impure/re.nim b/lib/impure/re.nim index 7d5ff8948..921a24fd1 100644 --- a/lib/impure/re.nim +++ b/lib/impure/re.nim @@ -66,7 +66,7 @@ proc rawCompile(pattern: string, flags: cint): PPcre = offset: cint result = pcre.compile(pattern, flags, addr(msg), addr(offset), nil) if result == nil: - raiseInvalidRegex($msg & "\n" & pattern & "\n" & repeatChar(offset) & "^\n") + raiseInvalidRegex($msg & "\n" & pattern & "\n" & spaces(offset) & "^\n") proc finalizeRegEx(x: Regex) = # XXX This is a hack, but PCRE does not export its "free" function properly. @@ -291,7 +291,7 @@ proc replace*(s: string, sub: Regex, by = ""): string = ## accessed in `by`. Examples: ## ## .. code-block:: nim - ## "var1=key; var2=key2".replace(re"(\w+)'='(\w+)") + ## "var1=key; var2=key2".replace(re"(\w+)=(\w+)") ## ## Results in: ## @@ -313,7 +313,7 @@ proc replacef*(s: string, sub: Regex, by: string): string = ## with the notation ``$i`` and ``$#`` (see strutils.`%`). Examples: ## ## .. code-block:: nim - ## "var1=key; var2=key2".replacef(re"(\w+)'='(\w+)", "$1<-$2$2") + ## "var1=key; var2=key2".replacef(re"(\w+)=(\w+)", "$1<-$2$2") ## ## Results in: ## diff --git a/lib/nimbase.h b/lib/nimbase.h index 50c7968ac..a1d4d1e27 100644 --- a/lib/nimbase.h +++ b/lib/nimbase.h @@ -67,7 +67,7 @@ __clang__ #endif #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) -# define NIM_THREADVAR __declspec(thread) +# define NIM_THREADVAR __declspec(thread) #else # define NIM_THREADVAR __thread #endif @@ -103,7 +103,11 @@ __clang__ # define N_FASTCALL_PTR(rettype, name) rettype (__fastcall *name) # define N_SAFECALL_PTR(rettype, name) rettype (__safecall *name) -# define N_LIB_EXPORT extern __declspec(dllexport) +# ifdef __cplusplus +# define N_LIB_EXPORT extern "C" __declspec(dllexport) +# else +# define N_LIB_EXPORT extern __declspec(dllexport) +# endif # define N_LIB_IMPORT extern __declspec(dllimport) #else # define N_CDECL(rettype, name) rettype name @@ -118,7 +122,11 @@ __clang__ # define N_FASTCALL_PTR(rettype, name) rettype (*name) # define N_SAFECALL_PTR(rettype, name) rettype (*name) -# define N_LIB_EXPORT extern +# ifdef __cplusplus +# define N_LIB_EXPORT extern "C" +# else +# define N_LIB_EXPORT extern +# endif # define N_LIB_IMPORT extern #endif @@ -345,7 +353,7 @@ struct TFrame { #define nimln(n, file) \ F.line = n; F.filename = file; -#define NIM_POSIX_INIT __attribute__((constructor)) +#define NIM_POSIX_INIT __attribute__((constructor)) #if defined(_MSCVER) && defined(__i386__) __declspec(naked) int __fastcall NimXadd(volatile int* pNum, int val) { @@ -380,7 +388,7 @@ static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); } #endif /* Test to see if Nim and the C compiler agree on the size of a pointer. - On disagreement, your C compiler will say something like: + On disagreement, your C compiler will say something like: "error: 'assert_numbits' declared as an array with a negative size" */ typedef int assert_numbits[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1]; #endif diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim index 95d49bad7..97784898e 100644 --- a/lib/packages/docutils/rst.nim +++ b/lib/packages/docutils/rst.nim @@ -189,7 +189,7 @@ proc getIndent(L: var TLexer, tok: var TToken) = tok.line = L.line L.col = tok.ival tok.ival = max(tok.ival - L.baseIndent, 0) - tok.symbol = "\n" & repeatChar(tok.ival) + tok.symbol = "\n" & spaces(tok.ival) proc rawGetTok(L: var TLexer, tok: var TToken) = tok.symbol = "" @@ -963,7 +963,7 @@ proc parseLiteralBlock(p: var TRstParser): PRstNode = break else: add(n.text, "\n") - add(n.text, repeatChar(p.tok[p.idx].ival - indent)) + add(n.text, spaces(p.tok[p.idx].ival - indent)) inc(p.idx) else: add(n.text, p.tok[p.idx].symbol) diff --git a/lib/packages/docutils/rstast.nim b/lib/packages/docutils/rstast.nim index 52af672df..614001d76 100644 --- a/lib/packages/docutils/rstast.nim +++ b/lib/packages/docutils/rstast.nim @@ -110,7 +110,7 @@ proc renderRstToRst(d: var TRenderContext, n: PRstNode, result: var string) = const lvlToChar: array[0..8, char] = ['!', '=', '-', '~', '`', '<', '*', '|', '+'] if n == nil: return - var ind = repeatChar(d.indent) + var ind = spaces(d.indent) case n.kind of rnInner: renderRstSons(d, n, result) @@ -124,7 +124,7 @@ proc renderRstToRst(d: var TRenderContext, n: PRstNode, result: var string) = result.add("\n") result.add(ind) - result.add repeatChar(headlineLen, lvlToChar[n.level]) + result.add repeat(lvlToChar[n.level], headlineLen) of rnOverline: result.add("\n") result.add(ind) @@ -132,7 +132,7 @@ proc renderRstToRst(d: var TRenderContext, n: PRstNode, result: var string) = var headline = "" renderRstSons(d, n, headline) - let lvl = repeatChar(headline.len - d.indent, lvlToChar[n.level]) + let lvl = repeat(lvlToChar[n.level], headline.len - d.indent) result.add(lvl) result.add("\n") result.add(headline) @@ -143,7 +143,7 @@ proc renderRstToRst(d: var TRenderContext, n: PRstNode, result: var string) = of rnTransition: result.add("\n\n") result.add(ind) - result.add repeatChar(78-d.indent, '-') + result.add repeat('-', 78-d.indent) result.add("\n\n") of rnParagraph: result.add("\n\n") @@ -196,7 +196,7 @@ proc renderRstToRst(d: var TRenderContext, n: PRstNode, result: var string) = result.add ':' result.add tmp result.add ':' - result.add repeatChar(L - tmp.len - 2) + result.add spaces(L - tmp.len - 2) renderRstToRst(d, n.sons[1], result) dec(d.indent, L) diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index e1e590877..a385336d6 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -461,9 +461,9 @@ proc indentToLevel(level: var int, newLevel: int): string = if level == newLevel: return if newLevel > level: - result = repeatStr(newLevel - level, "<ul>") + result = repeat("<ul>", newLevel - level) else: - result = repeatStr(level - newLevel, "</ul>") + result = repeat("</ul>", level - newLevel) level = newLevel proc generateDocumentationTOC(entries: seq[TIndexEntry]): string = @@ -701,7 +701,7 @@ proc renderHeadline(d: PDoc, n: PRstNode, result: var string) = # Generate index entry using spaces to indicate TOC level for the output HTML. assert n.level >= 0 setIndexTerm(d, refname, tmp.stripTOCHTML, - repeatChar(max(0, n.level), ' ') & tmp) + spaces(max(0, n.level)) & tmp) proc renderOverline(d: PDoc, n: PRstNode, result: var string) = if d.meta[metaTitle].len == 0: diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim index 20bfc5c7c..20976e788 100644 --- a/lib/pure/algorithm.nim +++ b/lib/pure/algorithm.nim @@ -187,6 +187,34 @@ proc sort*[T](a: var openArray[T], dec(m, s*2) s = s*2 +proc sorted*[T](a: openArray[T], cmp: proc(x, y: T): int {.closure.}, order = SortOrder.Ascending): seq[T] = + ## returns `a` sorted by `cmp` in the specified `order`. + result = newSeq[T](a.len) + for i in 0 .. a.high: + result[i] = a[i] + sort(result, cmp, order) + +template sortByIt*(seq1, op: expr): expr = + ## Convenience template around the ``sorted`` proc to reduce typing. + ## + ## The template injects the ``it`` variable which you can use directly in an + ## expression. Example: + ## + ## .. code-block:: nim + ## + ## var users: seq[tuple[id: int, name: string]] = + ## @[(0, "Smith"), (1, "Pratt"), (2, "Sparrow")] + ## + ## echo users.sortByIt(it.name) + ## + var result {.gensym.} = sorted(seq1, proc(x, y: type(seq1[0])): int = + var it {.inject.} = x + let a = op + it = y + let b = op + result = cmp(a, b)) + result + proc product*[T](x: openArray[seq[T]]): seq[seq[T]] = ## produces the Cartesian product of the array. Warning: complexity ## may explode. diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 2038b246d..5041fe2f6 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -816,7 +816,7 @@ proc copy*(p: JsonNode): JsonNode = # ------------- pretty printing ---------------------------------------------- proc indent(s: var string, i: int) = - s.add(repeatChar(i)) + s.add(spaces(i)) proc newIndent(curr, indent: int, ml: bool): int = if ml: return curr + indent diff --git a/lib/pure/lexbase.nim b/lib/pure/lexbase.nim index a3a3d7b5c..23a87d9f8 100644 --- a/lib/pure/lexbase.nim +++ b/lib/pure/lexbase.nim @@ -165,5 +165,5 @@ proc getCurrentLine(L: BaseLexer, marker: bool = true): string = inc(i) add(result, "\n") if marker: - add(result, repeatChar(getColNumber(L, L.bufpos)) & "^\n") + add(result, spaces(getColNumber(L, L.bufpos)) & "^\n") diff --git a/lib/pure/parseopt.nim b/lib/pure/parseopt.nim index b1e2444c3..4c92a7cdf 100644 --- a/lib/pure/parseopt.nim +++ b/lib/pure/parseopt.nim @@ -11,9 +11,12 @@ ## It supports one convenience iterator over all command line options and some ## lower-level features. ## -## **Deprecated since version 0.9.3:** Use the `parseopt2 <parseopt2.html>`_ -## module instead as this version has issues with spaces in arguments. -{.deprecated.} +## Supported syntax: +## +## 1. short options - ``-abcd``, where a, b, c, d are names +## 2. long option - ``--foo:bar``, ``--foo=bar`` or ``--foo`` +## 3. argument - everything else + {.push debugger: off.} include "system/inclrtl" diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index 67c80e592..e706f2016 100644 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.nim @@ -224,10 +224,12 @@ proc ssReadData(s: Stream, buffer: pointer, bufLen: int): int = proc ssWriteData(s: Stream, buffer: pointer, bufLen: int) = var s = StringStream(s) - if bufLen > 0: - setLen(s.data, s.data.len + bufLen) - copyMem(addr(s.data[s.pos]), buffer, bufLen) - inc(s.pos, bufLen) + if bufLen <= 0: + return + if s.pos + bufLen > s.data.len: + setLen(s.data, s.pos + bufLen) + copyMem(addr(s.data[s.pos]), buffer, bufLen) + inc(s.pos, bufLen) proc ssClose(s: Stream) = var s = StringStream(s) diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 39f468ee3..655203cda 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -499,26 +499,47 @@ proc parseEnum*[T: enum](s: string, default: T): T = return e result = default -proc repeatChar*(count: int, c: char = ' '): string {.noSideEffect, +proc repeat*(c: char, count: int): string {.noSideEffect, rtl, extern: "nsuRepeatChar".} = ## Returns a string of length `count` consisting only of ## the character `c`. You can use this proc to left align strings. Example: ## ## .. code-block:: nim + ## proc tabexpand(indent: int, text: string, tabsize: int = 4) = + ## echo '\t'.repeat(indent div tabsize), ' '.repeat(indent mod tabsize), text + ## + ## tabexpand(4, "At four") + ## tabexpand(5, "At five") + ## tabexpand(6, "At six") + result = newString(count) + for i in 0..count-1: result[i] = c + +proc repeat*(s: string, n: int): string {.noSideEffect, + rtl, extern: "nsuRepeatStr".} = + ## Returns String `s` concatenated `n` times. Example: + ## + ## .. code-block:: nim + ## echo "+++ STOP ".repeat(4), "+++" + result = newStringOfCap(n * s.len) + for i in 1..n: result.add(s) + +template spaces*(n: int): string = repeat(' ',n) + ## Returns a String with `n` space characters. You can use this proc + ## to left align strings. Example: + ## + ## .. code-block:: nim ## let ## width = 15 ## text1 = "Hello user!" ## text2 = "This is a very long string" - ## echo text1 & repeatChar(max(0, width - text1.len)) & "|" - ## echo text2 & repeatChar(max(0, width - text2.len)) & "|" - result = newString(count) - for i in 0..count-1: result[i] = c + ## echo text1 & spaces(max(0, width - text1.len)) & "|" + ## echo text2 & spaces(max(0, width - text2.len)) & "|" -proc repeatStr*(count: int, s: string): string {.noSideEffect, - rtl, extern: "nsuRepeatStr".} = - ## Returns `s` concatenated `count` times. - result = newStringOfCap(count*s.len) - for i in 0..count-1: result.add(s) +proc repeatChar*(count: int, c: char = ' '): string {.deprecated.} = repeat(c, count) + ## deprecated: use repeat() or spaces() + +proc repeatStr*(count: int, s: string): string {.deprecated.} = repeat(s, count) + ## deprecated: use repeat(string, count) or string.repeat(count) proc align*(s: string, count: int, padding = ' '): string {. noSideEffect, rtl, extern: "nsuAlignString".} = diff --git a/lib/pure/times.nim b/lib/pure/times.nim index e32ea786a..c39667611 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -628,25 +628,25 @@ proc formatToken(info: TimeInfo, token: string, buf: var string) = var fr = ($info.year).len()-2 if fr < 0: fr = 0 var fyear = ($info.year)[fr .. ($info.year).len()-1] - if fyear.len != 2: fyear = repeatChar(2-fyear.len(), '0') & fyear + if fyear.len != 2: fyear = repeat('0', 2-fyear.len()) & fyear buf.add(fyear) of "yyy": var fr = ($info.year).len()-3 if fr < 0: fr = 0 var fyear = ($info.year)[fr .. ($info.year).len()-1] - if fyear.len != 3: fyear = repeatChar(3-fyear.len(), '0') & fyear + if fyear.len != 3: fyear = repeat('0', 3-fyear.len()) & fyear buf.add(fyear) of "yyyy": var fr = ($info.year).len()-4 if fr < 0: fr = 0 var fyear = ($info.year)[fr .. ($info.year).len()-1] - if fyear.len != 4: fyear = repeatChar(4-fyear.len(), '0') & fyear + if fyear.len != 4: fyear = repeat('0', 4-fyear.len()) & fyear buf.add(fyear) of "yyyyy": var fr = ($info.year).len()-5 if fr < 0: fr = 0 var fyear = ($info.year)[fr .. ($info.year).len()-1] - if fyear.len != 5: fyear = repeatChar(5-fyear.len(), '0') & fyear + if fyear.len != 5: fyear = repeat('0', 5-fyear.len()) & fyear buf.add(fyear) of "z": let hrs = (info.timezone div 60) div 60 diff --git a/lib/pure/xmldom.nim b/lib/pure/xmldom.nim index 2e55ff182..6242e589e 100644 --- a/lib/pure/xmldom.nim +++ b/lib/pure/xmldom.nim @@ -1083,7 +1083,7 @@ proc addEscaped(s: string): string = else: result.add(c) proc nodeToXml(n: PNode, indent: int = 0): string = - result = repeatChar(indent, ' ') & "<" & n.nodeName + result = spaces(indent) & "<" & n.nodeName if not isNil(n.attributes): for i in items(n.attributes): result.add(" " & i.name & "=\"" & addEscaped(i.value) & "\"") @@ -1098,23 +1098,23 @@ proc nodeToXml(n: PNode, indent: int = 0): string = of ElementNode: result.add(nodeToXml(i, indent + 2)) of TextNode: - result.add(repeatChar(indent * 2, ' ')) + result.add(spaces(indent * 2)) result.add(addEscaped(i.nodeValue)) of CDataSectionNode: - result.add(repeatChar(indent * 2, ' ')) + result.add(spaces(indent * 2)) result.add("<![CDATA[" & i.nodeValue & "]]>") of ProcessingInstructionNode: - result.add(repeatChar(indent * 2, ' ')) + result.add(spaces(indent * 2)) result.add("<?" & PProcessingInstruction(i).target & " " & PProcessingInstruction(i).data & " ?>") of CommentNode: - result.add(repeatChar(indent * 2, ' ')) + result.add(spaces(indent * 2)) result.add("<!-- " & i.nodeValue & " -->") else: continue result.add("\n") # Add the ending tag - </tag> - result.add(repeatChar(indent, ' ') & "</" & n.nodeName & ">") + result.add(spaces(indent) & "</" & n.nodeName & ">") proc `$`*(doc: PDocument): string = ## Converts a PDocument object into a string representation of it's XML diff --git a/tests/clearmsg/tconsttypemismatch.nim b/tests/clearmsg/tconsttypemismatch.nim new file mode 100644 index 000000000..edf480348 --- /dev/null +++ b/tests/clearmsg/tconsttypemismatch.nim @@ -0,0 +1,8 @@ +discard """ + file: "tconsttypemismatch.nim" + line: 7 + errormsg: "type mismatch" +""" +# bug #2252 +const foo: int = 1000 / 30 + diff --git a/tests/generics/tgeneric3.nim b/tests/generics/tgeneric3.nim index 6fb929efb..289bf1fd5 100644 --- a/tests/generics/tgeneric3.nim +++ b/tests/generics/tgeneric3.nim @@ -188,7 +188,7 @@ proc traceTree[T,D](root: PNode[T,D]) = write stdout, space proc doTrace(n: PNode[T,D], level: int) = - var space = repeatChar(2 * level) + var space = spaces(2 * level) traceln(space) write stdout, "node: " if n == nil: diff --git a/tests/manyloc/argument_parser/argument_parser.nim b/tests/manyloc/argument_parser/argument_parser.nim index a507a08e4..060610ae0 100644 --- a/tests/manyloc/argument_parser/argument_parser.nim +++ b/tests/manyloc/argument_parser/argument_parser.nim @@ -471,7 +471,7 @@ proc build_help*(expected: seq[Tparameter_specification] = @[], let width = prefixes.map(proc (x: string): int = 3 + len(x)).max for line in zip(prefixes, helps): - result.add(line.a & repeatChar(width - line.a.len) & line.b) + result.add(line.a & spaces(width - line.a.len) & line.b) proc echo_help*(expected: seq[Tparameter_specification] = @[], diff --git a/tests/manyloc/keineschweine/dependencies/genpacket/streams_enh.nim b/tests/manyloc/keineschweine/dependencies/genpacket/streams_enh.nim index a9759687f..3c5a7835c 100644 --- a/tests/manyloc/keineschweine/dependencies/genpacket/streams_enh.nim +++ b/tests/manyloc/keineschweine/dependencies/genpacket/streams_enh.nim @@ -1,5 +1,5 @@ import streams -from strutils import repeatChar +from strutils import repeat proc readPaddedStr*(s: PStream, length: int, padChar = '\0'): TaintedString = var lastChr = length @@ -10,7 +10,7 @@ proc readPaddedStr*(s: PStream, length: int, padChar = '\0'): TaintedString = proc writePaddedStr*(s: PStream, str: string, length: int, padChar = '\0') = if str.len < length: s.write(str) - s.write(repeatChar(length - str.len, padChar)) + s.write(repeat(padChar, length - str.len)) elif str.len > length: s.write(str.substr(0, length - 1)) else: @@ -37,7 +37,7 @@ when isMainModule: testStream.setPosition 0 testStream.writePaddedStr("Sup", 10) echo(repr(testStream), testStream.data.len) - doAssert testStream.data == "Sup"&repeatChar(7, '\0') + doAssert testStream.data == "Sup"&repeat('\0', 7) testStream.setPosition 0 res = testStream.readPaddedStr(10) diff --git a/tests/manyloc/keineschweine/enet_server/enet_server.nim b/tests/manyloc/keineschweine/enet_server/enet_server.nim index 6dd1a6a7f..c2e893273 100644 --- a/tests/manyloc/keineschweine/enet_server/enet_server.nim +++ b/tests/manyloc/keineschweine/enet_server/enet_server.nim @@ -144,7 +144,7 @@ when isMainModule: discard """block: var TestFile: FileChallengePair - contents = repeatStr(2, "abcdefghijklmnopqrstuvwxyz") + contents = repeat("abcdefghijklmnopqrstuvwxyz", 2) testFile.challenge = newScFileChallenge("foobar.test", FZoneCfg, contents.len.int32) testFile.file = checksumStr(contents) myAssets.add testFile""" diff --git a/tests/manyloc/keineschweine/keineschweine.nim b/tests/manyloc/keineschweine/keineschweine.nim index 0a5dc1efc..525d8a054 100644 --- a/tests/manyloc/keineschweine/keineschweine.nim +++ b/tests/manyloc/keineschweine/keineschweine.nim @@ -113,7 +113,7 @@ when defined(recordMode): isRecording = false proc zeroPad*(s: string; minLen: int): string = if s.len < minLen: - result = repeatChar(minLen - s.len, '0') + result = repeat(0, minLen - s.len) result.add s else: result = s diff --git a/tests/manyloc/keineschweine/lib/map_filter.nim b/tests/manyloc/keineschweine/lib/map_filter.nim index 966b84b6a..5776c9225 100644 --- a/tests/manyloc/keineschweine/lib/map_filter.nim +++ b/tests/manyloc/keineschweine/lib/map_filter.nim @@ -27,9 +27,9 @@ when isMainModule: var res = t.map(proc(z: int): int = result = z * 10) dumpSeq res - from strutils import toHex, repeatStr + from strutils import toHex var foocakes = t.map(proc(z: int): string = - result = toHex((z * 23).biggestInt, 4)) + result = toHex((z * 23).BiggestInt, 4)) dumpSeq foocakes t.mapInPlace(proc(z: int): int = result = z * 30) diff --git a/tests/manyloc/keineschweine/lib/zlib_helpers.nim b/tests/manyloc/keineschweine/lib/zlib_helpers.nim index 9a6542d75..fcd0e8d24 100644 --- a/tests/manyloc/keineschweine/lib/zlib_helpers.nim +++ b/tests/manyloc/keineschweine/lib/zlib_helpers.nim @@ -24,17 +24,17 @@ when isMainModule: import strutils var r = compress("Hello") echo repr(r) - var l = "Hello".len - var rr = uncompress(r, l) + var ln = "Hello".len + var rr = uncompress(r, ln) echo repr(rr) assert rr == "Hello" - proc `*`(a: string; b: int): string {.inline.} = result = repeatStr(b, a) + proc `*`(a: string; b: int): string {.inline.} = result = repeat(a, b) var s = "yo dude sup bruh homie" * 50 r = compress(s) echo s.len, " -> ", r.len - l = s.len - rr = uncompress(r, l) + ln = s.len + rr = uncompress(r, ln) echo r.len, " -> ", rr.len assert rr == s \ No newline at end of file diff --git a/tests/manyloc/keineschweine/server/old_sg_server.nim b/tests/manyloc/keineschweine/server/old_sg_server.nim index ac85cbf62..1e57c12a1 100644 --- a/tests/manyloc/keineschweine/server/old_sg_server.nim +++ b/tests/manyloc/keineschweine/server/old_sg_server.nim @@ -174,7 +174,7 @@ when isMainModule: block: var TestFile: FileChallengePair - contents = repeatStr(2, "abcdefghijklmnopqrstuvwxyz") + contents = repeat("abcdefghijklmnopqrstuvwxyz", 2) testFile.challenge = newScFileChallenge("foobar.test", FZoneCfg, contents.len.int32) testFile.file = checksumStr(contents) myAssets.add testFile diff --git a/tests/stdlib/tstrutil.nim b/tests/stdlib/tstrutil.nim index ce9094bc0..3db484faa 100644 --- a/tests/stdlib/tstrutil.nim +++ b/tests/stdlib/tstrutil.nim @@ -46,7 +46,13 @@ assert "/1/2/3".rfind('0') == -1 assert(toHex(100i16, 32) == "00000000000000000000000000000064") assert(toHex(-100i16, 32) == "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C") -main() -#OUT ha/home/a1xyz/usr/bin +assert(' '.repeat(8)== " ") +assert(" ".repeat(8) == " ") +assert(spaces(8) == " ") +assert(' '.repeat(0) == "") +assert(" ".repeat(0) == "") +assert(spaces(0) == "") +main() +#OUT ha/home/a1xyz/usr/bin diff --git a/tests/vm/tconsteval.nim b/tests/vm/tconsteval.nim index 96a1bafe8..4459931c5 100644 --- a/tests/vm/tconsteval.nim +++ b/tests/vm/tconsteval.nim @@ -24,7 +24,7 @@ Possible Commands: csource [options] builds the C sources for installation zip builds the installation ZIP package inno builds the Inno Setup installer -""" % [NimVersion & repeatChar(44-len(NimVersion)), +""" % [NimVersion & spaces(44-len(NimVersion)), CompileDate, CompileTime] echo HelpText diff --git a/tools/nimgrep.nim b/tools/nimgrep.nim index aeae86300..72e4adc07 100644 --- a/tools/nimgrep.nim +++ b/tools/nimgrep.nim @@ -109,7 +109,7 @@ proc highlight(s, match, repl: string, t: tuple[first, last: int], for i in t.last+1 .. y: stdout.write(s[i]) stdout.write("\n") if showRepl: - stdout.write(repeatChar(alignment-1), "-> ") + stdout.write(spaces(alignment-1), "-> ") for i in x .. t.first-1: stdout.write(s[i]) writeColored(repl) for i in t.last+1 .. y: stdout.write(s[i]) diff --git a/tools/nimweb.nim b/tools/nimweb.nim index 8213cf418..a7301195e 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -99,8 +99,8 @@ macro updated(e: expr): expr {.immediate.} = proc updatedDate(year, month, day: string): string = ## wrapper around the update macro with easy input. result = updated("$1-$2-$3T00:00:00Z" % [year, - repeatStr(2 - len(month), "0") & month, - repeatStr(2 - len(day), "0") & day]) + repeat("0", 2 - len(month)) & month, + repeat("0", 2 - len(day)) & day]) macro entry(e: expr): expr {.immediate.} = ## generates the rss xml ``entry`` element. |