diff options
33 files changed, 297 insertions, 180 deletions
diff --git a/build_tools.sh b/build_tools.sh deleted file mode 100644 index 4d867b0ad..000000000 --- a/build_tools.sh +++ /dev/null @@ -1,3 +0,0 @@ -./bin/nim c --noNimblePath -p:compiler -o:./bin/nimble dist/nimble/src/nimble.nim -./bin/nim c --noNimblePath -p:compiler -o:./bin/nimsuggest dist/nimsuggest/nimsuggest.nim -./bin/nim c -o:./bin/nimgrep tools/nimgrep.nim diff --git a/compiler/ast.nim b/compiler/ast.nim index d8939fc60..2426dcc02 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -347,7 +347,7 @@ type tyUInt, tyUInt8, tyUInt16, tyUInt32, tyUInt64, tyBigNum, tyConst, tyMutable, tyVarargs, - tyIter, # unused + tyUnused # kept for enum ordinal compatibility tyProxy # used as errornous type (for idetools) tyBuiltInTypeClass #\ diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index eac734b3d..6dcf80f2f 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -122,7 +122,7 @@ proc mapType(typ: PType): TCTypeKind = of tyOpenArray, tyArrayConstr, tyArray, tyVarargs: result = ctArray of tyObject, tyTuple: result = ctStruct of tyGenericBody, tyGenericInst, tyGenericParam, tyDistinct, tyOrdinal, - tyConst, tyMutable, tyIter, tyTypeDesc: + tyConst, tyMutable, tyTypeDesc: result = mapType(lastSon(typ)) of tyEnum: if firstOrd(typ) < 0: @@ -711,8 +711,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): Rope = of 1, 2, 4, 8: addf(m.s[cfsTypes], "typedef NU$2 $1;$n", [result, rope(s*8)]) else: addf(m.s[cfsTypes], "typedef NU8 $1[$2];$n", [result, rope(getSize(t))]) - of tyGenericInst, tyDistinct, tyOrdinal, tyConst, tyMutable, - tyIter, tyTypeDesc: + of tyGenericInst, tyDistinct, tyOrdinal, tyConst, tyMutable, tyTypeDesc: result = getTypeDescAux(m, lastSon(t), check) else: internalError("getTypeDescAux(" & $t.kind & ')') diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim index ecd98a2bf..898c00f73 100644 --- a/compiler/ccgutils.nim +++ b/compiler/ccgutils.nim @@ -106,7 +106,7 @@ proc getUniqueType*(key: PType): PType = of tyDistinct: if key.deepCopy != nil: result = key else: result = getUniqueType(lastSon(key)) - of tyGenericInst, tyOrdinal, tyMutable, tyConst, tyIter, tyStatic: + of tyGenericInst, tyOrdinal, tyMutable, tyConst, tyStatic: result = getUniqueType(lastSon(key)) #let obj = lastSon(key) #if obj.sym != nil and obj.sym.name.s == "TOption": @@ -153,6 +153,7 @@ proc getUniqueType*(key: PType): PType = else: # ugh, we need the canon here: result = slowSearch(key, k) + of tyUnused: internalError("getUniqueType") proc tableGetType*(tab: TIdTable, key: PType): RootRef = # returns nil if we need to declare this type diff --git a/compiler/installer.ini b/compiler/installer.ini index 40050a2f7..5e4b3ddbc 100644 --- a/compiler/installer.ini +++ b/compiler/installer.ini @@ -41,8 +41,8 @@ Files: "config/nimdoc.tex.cfg" ; Files: "doc/*.cfg" ; Files: "doc/*.pdf" ; Files: "doc/*.ini" -Files: "doc/overview.html" -Start: "doc/overview.html" +Files: "doc/html/overview.html" +Start: "doc/html/overview.html" [Other] @@ -63,6 +63,7 @@ Files: "icons/koch_icon.o" Files: "compiler" Files: "doc" +Files: "doc/html" Files: "tools" Files: "web/website.ini" Files: "web/ticker.html" @@ -93,7 +94,7 @@ Files: "bin/nimble.exe" Files: "koch.exe" Files: "finish.exe" ; Files: "dist/mingw" -Files: "start.bat" +Files: r"tools\start.bat" BinPath: r"bin;dist\mingw\bin;dist" ; Section | dir | zipFile | size hint (in KB) | url | exe start menu entry diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index e7fe8cc27..6b95014f1 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -151,7 +151,7 @@ proc mapType(typ: PType): TJSTypeKind = of tyPointer: # treat a tyPointer like a typed pointer to an array of bytes result = etyBaseIndex - of tyRange, tyDistinct, tyOrdinal, tyConst, tyMutable, tyIter, tyProxy: + of tyRange, tyDistinct, tyOrdinal, tyConst, tyMutable, tyProxy: result = mapType(t.sons[0]) of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyChar: result = etyInt of tyBool: result = etyBool @@ -171,6 +171,7 @@ proc mapType(typ: PType): TJSTypeKind = else: result = etyNone of tyProc: result = etyProc of tyCString: result = etyString + of tyUnused: internalError("mapType") proc mapType(p: PProc; typ: PType): TJSTypeKind = if p.target == targetPHP: result = etyObject diff --git a/compiler/semasgn.nim b/compiler/semasgn.nim index 2e925e386..64a501e25 100644 --- a/compiler/semasgn.nim +++ b/compiler/semasgn.nim @@ -221,7 +221,7 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) = body.add newAsgnStmt(x, call) of tyVarargs, tyOpenArray: localError(c.info, errGenerated, "cannot copy openArray") - of tyFromExpr, tyIter, tyProxy, tyBuiltInTypeClass, tyUserTypeClass, + of tyFromExpr, tyProxy, tyBuiltInTypeClass, tyUserTypeClass, tyUserTypeClassInst, tyCompositeTypeClass, tyAnd, tyOr, tyNot, tyAnything, tyMutable, tyGenericParam, tyGenericBody, tyNil, tyExpr, tyStmt, tyTypeDesc, tyGenericInvocation, tyBigNum, tyConst, tyForward: @@ -229,6 +229,7 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) = of tyOrdinal, tyRange, tyGenericInst, tyFieldAccessor, tyStatic, tyVar: liftBodyAux(c, lastSon(t), body, x, y) + of tyUnused: internalError("liftBodyAux") proc newProcType(info: TLineInfo; owner: PSym): PType = result = newType(tyProc, owner) diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 338b254df..e1a65da74 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -58,7 +58,7 @@ iterator instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable): PSym for i, a in n.pairs: internalAssert a.kind == nkSym var q = a.sym - if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyStatic, tyIter}+tyTypeClasses: + if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyStatic}+tyTypeClasses: continue let symKind = if q.typ.kind == tyStatic: skConst else: skType var s = newSym(symKind, q.name, getCurrOwner(), q.info) diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 806b00db6..cd90782d1 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -24,7 +24,7 @@ proc semTypeOf(c: PContext; n: PNode): PNode = result = newNodeI(nkTypeOfExpr, n.info) let typExpr = semExprWithType(c, n, {efInTypeof}) result.add typExpr - result.typ = makeTypeDesc(c, typExpr.typ.skipTypes({tyTypeDesc, tyIter})) + result.typ = makeTypeDesc(c, typExpr.typ.skipTypes({tyTypeDesc})) type SemAsgnMode = enum asgnNormal, noOverloadedSubscript, noOverloadedAsgn diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 44807dae2..15171874f 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -549,8 +549,6 @@ proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation = of tyNil: result = f.allowsNil - of tyIter: - if tfIterator in f.flags: result = typeRel(c, f.base, a.base) else: discard proc typeRangeRel(f, a: PType): TTypeRelation {.noinline.} = @@ -1223,13 +1221,6 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = else: result = isNone - of tyIter: - if a.kind == tyIter or - (a.kind == tyProc and tfIterator in a.flags): - result = typeRel(c, f.base, a.base) - else: - result = isNone - of tyStmt: if aOrig != nil and tfOldSchoolExprStmt notin f.flags: put(c, f, aOrig) @@ -1587,8 +1578,9 @@ proc prepareOperand(c: PContext; formal: PType; a: PNode): PNode = elif a.typ.isNil: # XXX This is unsound! 'formal' can differ from overloaded routine to # overloaded routine! - let flags = if formal.kind == tyIter: {efDetermineType, efWantIterator} - else: {efDetermineType, efAllowStmt} + let flags = {efDetermineType, efAllowStmt} + #if formal.kind == tyIter: {efDetermineType, efWantIterator} + #else: {efDetermineType, efAllowStmt} #elif formal.kind == tyStmt: {efDetermineType, efWantStmt} #else: {efDetermineType} result = c.semOperand(c, a, flags) diff --git a/compiler/types.nim b/compiler/types.nim index 4e60e0121..d7651aad2 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -572,7 +572,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = addSep(prag) add(prag, "locks: " & $t.lockLevel) if len(prag) != 0: add(result, "{." & prag & ".}") - of tyVarargs, tyIter: + of tyVarargs: result = typeToStr[t.kind] % typeToString(t.sons[0]) else: result = typeToStr[t.kind] @@ -965,7 +965,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = result = a.sym.position == b.sym.position of tyGenericInvocation, tyGenericBody, tySequence, tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, - tyArray, tyProc, tyConst, tyMutable, tyVarargs, tyIter, + tyArray, tyProc, tyConst, tyMutable, tyVarargs, tyOrdinal, tyTypeClasses, tyFieldAccessor: cycleCheck() if a.kind == tyUserTypeClass and a.n != nil: return a.n == b.n @@ -980,6 +980,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = sameValue(a.n.sons[1], b.n.sons[1]) of tyGenericInst: discard of tyNone: result = false + of tyUnused: internalError("sameFlags") proc sameBackendType*(x, y: PType): bool = var c = initSameTypeClosure() @@ -1143,7 +1144,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, else: result = typeAllowedAux(marker, t.lastSon, skVar, flags+{taHeap}) of tyPtr: result = typeAllowedAux(marker, t.lastSon, skVar, flags+{taHeap}) - of tyArrayConstr, tySet, tyConst, tyMutable, tyIter: + of tyArrayConstr, tySet, tyConst, tyMutable: for i in countup(0, sonsLen(t) - 1): result = typeAllowedAux(marker, t.sons[i], kind, flags) if result != nil: break @@ -1160,6 +1161,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, # for now same as error node; we say it's a valid type as it should # prevent cascading errors: result = nil + of tyUnused: internalError("typeAllowedAux") proc typeAllowed*(t: PType, kind: TSymKind): PType = # returns 'nil' on success and otherwise the part of the type that is @@ -1311,7 +1313,7 @@ proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt = if result < 0: return if a < maxAlign: a = maxAlign result = align(result, a) - of tyGenericInst, tyDistinct, tyGenericBody, tyMutable, tyConst, tyIter: + of tyGenericInst, tyDistinct, tyGenericBody, tyMutable, tyConst: result = computeSizeAux(lastSon(typ), a) of tyTypeDesc: result = computeSizeAux(typ.base, a) diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index b40ca1058..61f56092c 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -270,7 +270,6 @@ proc mapTypeToAstX(t: PType; info: TLineInfo; of tyConst: result = mapTypeToBracket("const", mNone, t, info) of tyMutable: result = mapTypeToBracket("mutable", mNone, t, info) of tyVarargs: result = mapTypeToBracket("varargs", mVarargs, t, info) - of tyIter: result = mapTypeToBracket("iter", mNone, t, info) of tyProxy: result = atomicType("error", mNone) of tyBuiltInTypeClass: result = mapTypeToBracket("builtinTypeClass", mNone, t, info) @@ -292,6 +291,7 @@ proc mapTypeToAstX(t: PType; info: TLineInfo; result.add atomicType("static", mNone) if t.n != nil: result.add t.n.copyTree + of tyUnused: internalError("mapTypeToAstX") proc opMapTypeToAst*(t: PType; info: TLineInfo): PNode = result = mapTypeToAstX(t, info, false, true) diff --git a/contributors.txt b/contributors.txt deleted file mode 100644 index d54ec844a..000000000 --- a/contributors.txt +++ /dev/null @@ -1,12 +0,0 @@ -Comex -Eric Doughty-Papassideris -Simon Hafner -Keita Haga -Grzegorz Adam Hankiewicz -Philippe Lhoste -Zahary Karadjov -Mario Ray Mahardhika -Alexander Mitchell-Robinson (Amrykid) -Dominik Picheta -Jonathan Plona -Alexander Rødseth diff --git a/contributing.rst b/doc/contributing.rst index 31f04a5e0..31f04a5e0 100644 --- a/contributing.rst +++ b/doc/contributing.rst diff --git a/doc/docs.txt b/doc/docs.rst index 4484784ae..4484784ae 100644 --- a/doc/docs.txt +++ b/doc/docs.rst diff --git a/docstyle.rst b/doc/docstyle.rst index d789b1df9..d789b1df9 100644 --- a/docstyle.rst +++ b/doc/docstyle.rst diff --git a/doc/gc.rst b/doc/gc.rst index 1c8cb9122..bb0088617 100644 --- a/doc/gc.rst +++ b/doc/gc.rst @@ -19,8 +19,10 @@ This document describes how the GC works and how to tune it for The basic algorithm is *Deferred Reference Counting* with cycle detection. References on the stack are not counted for better performance (and easier C -code generation). The GC **never** scans the whole heap but it may scan the -delta-subgraph of the heap that changed since its last run. +code generation). Cycle detection is currently done by a simple mark&sweep +GC that has to scan the full (thread local heap). ``--gc:v2`` replaces this +with an incremental mark and sweep. That it is not production ready yet, +however. The GC is only triggered in a memory allocation operation. It is not triggered @@ -34,17 +36,7 @@ Cycle collector =============== The cycle collector can be en-/disabled independently from the other parts of -the GC with ``GC_enableMarkAndSweep`` and ``GC_disableMarkAndSweep``. The -compiler analyses the types for their possibility to build cycles, but often -it is necessary to help this analysis with the ``acyclic`` pragma (see -`acyclic <manual.html#acyclic-pragma>`_ for further information). - -You can also use the ``acyclic`` pragma for data that is cyclic in reality and -then break up the cycles explicitly with ``GC_addCycleRoot``. This can be a -very valuable optimization; the Nim compiler itself relies on this -optimization trick to improve performance. Note that ``GC_addCycleRoot`` is -a quick operation; the root is only registered for the next run of the -cycle collector. +the GC with ``GC_enableMarkAndSweep`` and ``GC_disableMarkAndSweep``. Realtime support @@ -55,19 +47,19 @@ defined via ``--define:useRealtimeGC`` (you can put this into your config file as well). With this switch the GC supports the following operations: .. code-block:: nim - proc GC_setMaxPause*(MaxPauseInUs: int) + proc GC_setMaxPause*(maxPauseInUs: int) proc GC_step*(us: int, strongAdvice = false, stackSize = -1) -The unit of the parameters ``MaxPauseInUs`` and ``us`` is microseconds. +The unit of the parameters ``maxPauseInUs`` and ``us`` is microseconds. These two procs are the two modus operandi of the realtime GC: (1) GC_SetMaxPause Mode You can call ``GC_SetMaxPause`` at program startup and then each triggered - GC run tries to not take longer than ``MaxPause`` time. However, it is + GC run tries to not take longer than ``maxPause`` time. However, it is possible (and common) that the work is nevertheless not evenly distributed - as each call to ``new`` can trigger the GC and thus take ``MaxPause`` + as each call to ``new`` can trigger the GC and thus take ``maxPause`` time. (2) GC_step Mode @@ -86,8 +78,8 @@ These two procs are the two modus operandi of the realtime GC: These procs provide a "best effort" realtime guarantee; in particular the cycle collector is not aware of deadlines yet. Deactivate it to get more predictable realtime behaviour. Tests show that a 2ms max pause -time will be met in almost all cases on modern CPUs unless the cycle collector -is triggered. +time will be met in almost all cases on modern CPUs (with the cycle collector +disabled). Time measurement diff --git a/doc/overview.txt b/doc/overview.rst index 5b41752ae..e01520d7c 100644 --- a/doc/overview.txt +++ b/doc/overview.rst @@ -5,5 +5,5 @@ Nim Documentation Overview :Author: Andreas Rumpf :Version: |nimversion| -.. include:: ../doc/docs.txt +.. include:: docs.rst diff --git a/install_nimble.nims b/install_nimble.nims index 05024c046..6e929f499 100644 --- a/install_nimble.nims +++ b/install_nimble.nims @@ -3,6 +3,8 @@ import ospaths mode = ScriptMode.Verbose +echo "This script is deprecated. Use 'koch nimble' instead." + var id = 0 while dirExists("nimble" & $id): inc id @@ -20,4 +22,4 @@ try: mvFile "nimble" & $id & "/src/nimble".toExe, "bin/nimble".toExe except OSError: cpFile "nimble" & $id & "/src/nimble".toExe, "bin/nimble".toExe - + diff --git a/install_tools.nims b/install_tools.nims index e211ff491..f5f320f78 100644 --- a/install_tools.nims +++ b/install_tools.nims @@ -3,6 +3,8 @@ import ospaths mode = ScriptMode.Verbose +echo "This script is deprecated. Use 'koch tools' instead." + if not dirExists"dist/nimble": echo "[Error] This script only works for the tarball." else: @@ -11,8 +13,8 @@ else: " dist/nimble/src/nimble.nim" let nimsugExe = "./bin/nimsuggest".toExe - selfExec "c --noNimblePath -p:compiler -o:" & nimsugExe & + selfExec "c --noNimblePath -d:release -p:compiler -o:" & nimsugExe & " dist/nimsuggest/nimsuggest.nim" let nimgrepExe = "./bin/nimgrep".toExe - selfExec "c -o:./bin/nimgrep tools/nimgrep.nim" + selfExec "c -d:release -o:" & nimgrepExe & " tools/nimgrep.nim" diff --git a/koch.nim b/koch.nim index 74855a6b9..b50691d0d 100644 --- a/koch.nim +++ b/koch.nim @@ -49,6 +49,8 @@ Possible Commands: tests [options] run the testsuite temp options creates a temporary compiler for testing winrelease creates a release (for coredevs only) + nimble builds the Nimble tool + tools builds Nim related tools Boot options: -d:release produce a release version of the compiler -d:tinyc include the Tiny C backend (not supported on Windows) @@ -88,6 +90,9 @@ proc exec(cmd: string, errorcode: int = QuitFailure, additionalPath = "") = if execShellCmd(cmd) != 0: quit("FAILURE", errorcode) putEnv("PATH", prevPath) +proc nimexec(cmd: string) = + exec findNim() & " " & cmd + proc execCleanPath(cmd: string, additionalPath = ""; errorcode: int = QuitFailure) = # simulate a poor man's virtual environment @@ -144,10 +149,13 @@ const compileNimInst = "tools/niminst/niminst" proc csource(args: string) = - exec("$4 cc $1 -r $3 --var:version=$2 --var:mingw=none csource --main:compiler/nim.nim compiler/installer.ini $1" % - [args, VersionAsString, compileNimInst, findNim()]) + nimexec(("cc $1 -r $3 --var:version=$2 --var:mingw=none csource " & + "--main:compiler/nim.nim compiler/installer.ini $1") % + [args, VersionAsString, compileNimInst]) proc bundleNimbleSrc() = + ## bunldeNimbleSrc() bundles a specific Nimble commit with the tarball. We + ## always bundle the latest official release. if dirExists("dist/nimble/.git"): exec("git --git-dir dist/nimble/.git pull") else: @@ -160,42 +168,77 @@ proc bundleNimbleExe() = bundleNimbleSrc() # now compile Nimble and copy it to $nim/bin for the installer.ini # to pick it up: - exec(findNim() & " c dist/nimble/src/nimble.nim") + nimexec("c dist/nimble/src/nimble.nim") copyExe("dist/nimble/src/nimble".exe, "bin/nimble".exe) +proc buildNimble() = + ## buildNimble() builds Nimble for the building via "github". As such, we + ## choose the most recent commit of Nimble too. + var installDir = "dist/nimble" + if dirExists("dist/nimble/.git"): + exec("git --git-dir dist/nimble/.git pull") + else: + # if dist/nimble exist, but is not a git repo, don't mess with it: + if dirExists(installDir): + var id = 0 + while dirExists("dist/nimble" & $id): + inc id + installDir = "dist/nimble" & $id + exec("git clone https://github.com/nim-lang/nimble.git " & installDir) + nimexec("c " & installDir / "src/nimble.nim") + copyExe(installDir / "src/nimble".exe, "bin/nimble".exe) + proc bundleNimsuggest(buildExe: bool) = if dirExists("dist/nimsuggest/.git"): exec("git --git-dir dist/nimsuggest/.git pull") else: exec("git clone https://github.com/nim-lang/nimsuggest.git dist/nimsuggest") if buildExe: - exec(findNim() & " c --noNimblePath -p:compiler dist/nimsuggest/nimsuggest.nim") + nimexec("c --noNimblePath -d:release -p:compiler dist/nimsuggest/nimsuggest.nim") copyExe("dist/nimsuggest/nimsuggest".exe, "bin/nimsuggest".exe) + removeFile("dist/nimsuggest/nimsuggest".exe) proc bundleFinishExe() = - exec(findNim() & " c finish.nim") + nimexec("c tools/finish.nim") + copyExe("tools/finish".exe, "finish".exe) + removeFile("tools/finish".exe) proc zip(args: string) = bundleNimbleSrc() bundleNimsuggest(false) bundleFinishExe() - exec("$3 cc -r $2 --var:version=$1 --var:mingw=none --main:compiler/nim.nim scripts compiler/installer.ini" % - [VersionAsString, compileNimInst, findNim()]) + nimexec("cc -r $2 --var:version=$1 --var:mingw=none --main:compiler/nim.nim scripts compiler/installer.ini" % + [VersionAsString, compileNimInst]) exec("$# --var:version=$# --var:mingw=none --main:compiler/nim.nim zip compiler/installer.ini" % ["tools/niminst/niminst".exe, VersionAsString]) proc xz(args: string) = bundleNimbleSrc() bundleNimsuggest(false) - exec("$3 cc -r $2 --var:version=$1 --var:mingw=none --main:compiler/nim.nim scripts compiler/installer.ini" % - [VersionAsString, compileNimInst, findNim()]) + nimexec("cc -r $2 --var:version=$1 --var:mingw=none --main:compiler/nim.nim scripts compiler/installer.ini" % + [VersionAsString, compileNimInst]) exec("$# --var:version=$# --var:mingw=none --main:compiler/nim.nim xz compiler/installer.ini" % ["tools" / "niminst" / "niminst".exe, VersionAsString]) proc buildTool(toolname, args: string) = - exec("$# cc $# $#" % [findNim(), args, toolname]) + nimexec("cc $# $#" % [args, toolname]) copyFile(dest="bin"/ splitFile(toolname).name.exe, source=toolname.exe) +proc buildTools() = + if not dirExists"dist/nimble": + echo "[Error] 'koch tools' only works for the tarball." + else: + let nimbleExe = "bin/nimble".exe + nimexec "c --noNimblePath -p:compiler -o:" & nimbleExe & + " dist/nimble/src/nimble.nim" + + let nimsugExe = "bin/nimsuggest".exe + nimexec "c --noNimblePath -p:compiler -d:release -o:" & nimsugExe & + " dist/nimsuggest/nimsuggest.nim" + + let nimgrepExe = "bin/nimgrep".exe + nimexec "c -o:" & nimgrepExe & " tools/nimgrep.nim" + proc nsis(args: string) = bundleNimbleExe() bundleNimsuggest(true) @@ -210,21 +253,21 @@ proc nsis(args: string) = " nsis compiler/installer.ini") % [VersionAsString, $(sizeof(pointer)*8)]) proc geninstall(args="") = - exec("$# cc -r $# --var:version=$# --var:mingw=none --main:compiler/nim.nim scripts compiler/installer.ini $#" % - [findNim(), compileNimInst, VersionAsString, args]) + nimexec("cc -r $# --var:version=$# --var:mingw=none --main:compiler/nim.nim scripts compiler/installer.ini $#" % + [compileNimInst, VersionAsString, args]) proc install(args: string) = geninstall() exec("sh ./install.sh $#" % args) proc web(args: string) = - exec("$# js tools/dochack/dochack.nim" % findNim()) - exec("$# cc -r tools/nimweb.nim $# web/website.ini --putenv:nimversion=$#" % - [findNim(), args, VersionAsString]) + nimexec("js tools/dochack/dochack.nim") + nimexec("cc -r tools/nimweb.nim $# web/website.ini --putenv:nimversion=$#" % + [args, VersionAsString]) proc website(args: string) = - exec("$# cc -r tools/nimweb.nim $# --website web/website.ini --putenv:nimversion=$#" % - [findNim(), args, VersionAsString]) + nimexec("cc -r tools/nimweb.nim $# --website web/website.ini --putenv:nimversion=$#" % + [args, VersionAsString]) proc pdf(args="") = exec("$# cc -r tools/nimweb.nim $# --pdf web/website.ini --putenv:nimversion=$#" % @@ -314,7 +357,6 @@ proc removePattern(pattern: string) = removeFile(f) proc clean(args: string) = - if existsFile("koch.dat"): removeFile("koch.dat") removePattern("web/*.html") removePattern("doc/*.html") cleanAux(getCurrentDir()) @@ -335,11 +377,10 @@ template `|`(a, b): string = (if a.len > 0: a else: b) proc tests(args: string) = # we compile the tester with taintMode:on to have a basic # taint mode test :-) - let nimexe = findNim() - exec nimexe & " cc --taintMode:on tests/testament/tester" + nimexec "cc --taintMode:on tests/testament/tester" # Since tests take a long time (on my machine), and we want to defy Murhpys # law - lets make sure the compiler really is freshly compiled! - exec nimexe & " c --lib:lib -d:release --opt:speed compiler/nim.nim" + nimexec "c --lib:lib -d:release --opt:speed compiler/nim.nim" let tester = quoteShell(getCurrentDir() / "tests/testament/tester".exe) let success = tryExec tester & " " & (args|"all") if not existsEnv("TRAVIS") and not existsEnv("APPVEYOR"): @@ -369,6 +410,7 @@ of cmdArgument: of "boot": boot(op.cmdLineRest) of "clean": clean(op.cmdLineRest) of "web": web(op.cmdLineRest) + of "doc", "docs": web("--onlyDocs " & op.cmdLineRest) of "json2": web("--json2 " & op.cmdLineRest) of "website": website(op.cmdLineRest & " --googleAnalytics:UA-48159761-1") of "web0": @@ -386,5 +428,7 @@ of cmdArgument: of "test", "tests": tests(op.cmdLineRest) of "temp": temp(op.cmdLineRest) of "winrelease": winRelease() + of "nimble": buildNimble() + of "tools": buildTools() else: showHelp() of cmdEnd: showHelp() diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 19452b4a8..292e8dd3c 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -92,7 +92,7 @@ type ntyUInt, ntyUInt8, ntyUInt16, ntyUInt32, ntyUInt64, ntyBigNum, ntyConst, ntyMutable, ntyVarargs, - ntyIter, + ntyUnused, ntyError, ntyBuiltinTypeClass, ntyConcept, ntyConceptInst, ntyComposite, ntyAnd, ntyOr, ntyNot diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim index f458b7636..45a148fbf 100644 --- a/lib/pure/collections/sequtils.nim +++ b/lib/pure/collections/sequtils.nim @@ -228,7 +228,7 @@ proc apply*[T](data: var seq[T], op: proc (x: var T) {.closure.}) ## var a = @["1", "2", "3", "4"] ## echo repr(a) ## # --> ["1", "2", "3", "4"] - ## map(a, proc(x: var string) = x &= "42") + ## apply(a, proc(x: var string) = x &= "42") ## echo repr(a) ## # --> ["142", "242", "342", "442"] ## @@ -247,7 +247,7 @@ proc apply*[T](data: var seq[T], op: proc (x: T): T {.closure.}) ## var a = @["1", "2", "3", "4"] ## echo repr(a) ## # --> ["1", "2", "3", "4"] - ## map(a, proc(x: string): string = x & "42") + ## apply(a, proc(x: string): string = x & "42") ## echo repr(a) ## # --> ["142", "242", "342", "442"] ## diff --git a/lib/pure/os.nim b/lib/pure/os.nim index cdbe170cc..001d3d250 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -50,6 +50,8 @@ proc c_getenv(env: cstring): cstring {. importc: "getenv", header: "<stdlib.h>".} proc c_putenv(env: cstring): cint {. importc: "putenv", header: "<stdlib.h>".} +proc c_free(p: pointer) {. + importc: "free", header: "<stdlib.h>".} var errno {.importc, header: "<errno.h>".}: cint @@ -303,24 +305,47 @@ proc fileNewer*(a, b: string): bool {.rtl, extern: "nos$1".} = proc getCurrentDir*(): string {.rtl, extern: "nos$1", tags: [].} = ## Returns the `current working directory`:idx:. - const bufsize = 512 # should be enough when defined(windows): + var bufsize = MAX_PATH.int32 when useWinUnicode: var res = newWideCString("", bufsize) - var L = getCurrentDirectoryW(bufsize, res) - if L == 0'i32: raiseOSError(osLastError()) - result = res$L + while true: + var L = getCurrentDirectoryW(bufsize, res) + if L == 0'i32: + raiseOSError(osLastError()) + elif L > bufsize: + res = newWideCString("", L) + bufsize = L + else: + result = res$L + break else: result = newString(bufsize) - var L = getCurrentDirectoryA(bufsize, result) - if L == 0'i32: raiseOSError(osLastError()) - setLen(result, L) + while true: + var L = getCurrentDirectoryA(bufsize, result) + if L == 0'i32: + raiseOSError(osLastError()) + elif L > bufsize: + result = newString(L) + bufsize = L + else: + setLen(result, L) + break else: + var bufsize = 1024 # should be enough result = newString(bufsize) - if getcwd(result, bufsize) != nil: - setLen(result, c_strlen(result)) - else: - raiseOSError(osLastError()) + while true: + if getcwd(result, bufsize) != nil: + setLen(result, c_strlen(result)) + break + else: + let err = osLastError() + if err.int32 == ERANGE: + bufsize = bufsize shl 1 + doAssert(bufsize >= 0) + result = newString(bufsize) + else: + raiseOSError(osLastError()) proc setCurrentDir*(newDir: string) {.inline, tags: [].} = ## Sets the `current working directory`:idx:; `OSError` is raised if @@ -336,28 +361,45 @@ proc setCurrentDir*(newDir: string) {.inline, tags: [].} = proc expandFilename*(filename: string): string {.rtl, extern: "nos$1", tags: [ReadDirEffect].} = - ## Returns the full (`absolute`:idx:) path of the file `filename`, raises OSError in case of an error. + ## Returns the full (`absolute`:idx:) path of the file `filename`, + ## raises OSError in case of an error. when defined(windows): - const bufsize = 3072'i32 + var bufsize = MAX_PATH.int32 when useWinUnicode: - var unused: WideCString - var res = newWideCString("", bufsize div 2) - var L = getFullPathNameW(newWideCString(filename), bufsize, res, unused) - if L <= 0'i32 or L >= bufsize: - raiseOSError(osLastError()) - result = res$L + var unused: WideCString = nil + var res = newWideCString("", bufsize) + while true: + var L = getFullPathNameW(newWideCString(filename), bufsize, res, unused) + if L == 0'i32: + raiseOSError(osLastError()) + elif L > bufsize: + res = newWideCString("", L) + bufsize = L + else: + result = res$L + break else: - var unused: cstring + var unused: cstring = nil result = newString(bufsize) - var L = getFullPathNameA(filename, bufsize, result, unused) - if L <= 0'i32 or L >= bufsize: raiseOSError(osLastError()) - setLen(result, L) + while true: + var L = getFullPathNameA(filename, bufsize, result, unused) + if L == 0'i32: + raiseOSError(osLastError()) + elif L > bufsize: + result = newString(L) + bufsize = L + else: + setLen(result, L) + break else: - # careful, realpath needs to take an allocated buffer according to Posix: - result = newString(pathMax) - var r = realpath(filename, result) - if r.isNil: raiseOSError(osLastError()) - setLen(result, c_strlen(result)) + # according to Posix we don't need to allocate space for result pathname. + # But we need to free return value with free(3). + var r = realpath(filename, nil) + if r.isNil: + raiseOSError(osLastError()) + else: + result = $r + c_free(cast[pointer](r)) when defined(Windows): proc openHandle(path: string, followSymlink=true): Handle = @@ -1382,6 +1424,35 @@ when declared(paramCount) or defined(nimdoc): for i in 1..paramCount(): result.add(paramStr(i)) +when defined(freebsd): + proc sysctl(name: ptr cint, namelen: cuint, oldp: pointer, oldplen: ptr csize, + newp: pointer, newplen: csize): cint + {.importc: "sysctl",header: """#include <sys/types.h> + #include <sys/sysctl.h>"""} + const + CTL_KERN = 1 + KERN_PROC = 14 + KERN_PROC_PATHNAME = 12 + MAX_PATH = 1024 + + proc getApplFreebsd(): string = + var pathLength = csize(MAX_PATH) + result = newString(pathLength) + var req = [CTL_KERN.cint, KERN_PROC.cint, KERN_PROC_PATHNAME.cint, -1.cint] + while true: + let res = sysctl(addr req[0], 4, cast[pointer](addr result[0]), + addr pathLength, nil, 0) + if res < 0: + let err = osLastError() + if err.int32 == ENOMEM: + result = newString(pathLength) + else: + result.setLen(0) # error! + break + else: + result.setLen(pathLength) + break + when defined(linux) or defined(solaris) or defined(bsd) or defined(aix): proc getApplAux(procPath: string): string = result = newString(256) @@ -1426,16 +1497,34 @@ proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect].} = # Solaris: # /proc/<pid>/object/a.out (filename only) # /proc/<pid>/path/a.out (complete pathname) - # FreeBSD: /proc/<pid>/file when defined(windows): + var bufsize = int32(MAX_PATH) when useWinUnicode: - var buf = newWideCString("", 256) - var len = getModuleFileNameW(0, buf, 256) - result = buf$len + var buf = newWideCString("", bufsize) + while true: + var L = getModuleFileNameW(0, buf, bufsize) + if L == 0'i32: + result = "" # error! + break + elif L > bufsize: + buf = newWideCString("", L) + bufsize = L + else: + result = buf$L + break else: - result = newString(256) - var len = getModuleFileNameA(0, result, 256) - setlen(result, int(len)) + result = newString(bufsize) + while true: + var L = getModuleFileNameA(0, result, bufsize) + if L == 0'i32: + result = "" # error! + break + elif L > bufsize: + result = newString(L) + bufsize = L + else: + setLen(result, L) + break elif defined(macosx): var size: cuint32 getExecPath1(nil, size) @@ -1450,7 +1539,7 @@ proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect].} = elif defined(solaris): result = getApplAux("/proc/" & $getpid() & "/path/a.out") elif defined(freebsd): - result = getApplAux("/proc/" & $getpid() & "/file") + result = getApplFreebsd() # little heuristic that may work on other POSIX-like systems: if result.len == 0: result = getApplHeuristic() diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index 0fc2e441e..12553e3da 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -11,11 +11,21 @@ ## ## This module implements boilerplate to make unit testing easy. ## +## The test status and name is printed after any output or traceback. +## ## Example: ## ## .. code:: nim ## ## suite "description for this stuff": +## echo "suite setup: run once before the tests" +## +## setup: +## echo "run before each test" +## +## teardown: +## echo "run after each test": +## ## test "essential truths": ## # give up and stop if this fails ## require(true) @@ -30,6 +40,13 @@ ## let v = @[1, 2, 3] # you can do initialization here ## expect(IndexError): ## discard v[4] +## +## echo "suite teardown: run once after the tests" +## +## +## Tests can be nested, however failure of a nested test will not mark the +## parent test as failed. Setup and teardown are inherited. Setup can be +## overridden locally. import macros @@ -226,10 +243,11 @@ template fail* = checkpoints = @[] template skip* = - ## Makes test to be skipped. Should be used directly + ## Mark the test as skipped. Should be used directly ## in case when it is not possible to perform test ## for reasons depending on outer environment, ## or certain application logic conditions or configurations. + ## The test code is still executed. ## ## .. code-block:: nim ## @@ -250,12 +268,12 @@ macro check*(conditions: untyped): untyped = ## ## import strutils ## - ## check("AKB48".toLower() == "akb48") + ## check("AKB48".toLowerAscii() == "akb48") ## ## let teams = {'A', 'K', 'B', '4', '8'} ## ## check: - ## "AKB48".toLower() == "akb48" + ## "AKB48".toLowerAscii() == "akb48" ## 'C' in teams let checked = callsite()[1] var diff --git a/finish.nim b/tools/finish.nim index 18216cfb2..8b9acfc56 100644 --- a/finish.nim +++ b/tools/finish.nim @@ -69,10 +69,10 @@ when defined(windows): if askBool("Would like to add Nim-" & NimVersion & " to your start menu? (y/n) "): createDir(dest) - createShortcut(getCurrentDir() / "start.bat", dest / "Nim", + createShortcut(getCurrentDir() / "tools" / "start.bat", dest / "Nim", getCurrentDir() / r"icons\nim.ico") if fileExists("doc/overview.html"): - createShortcut(getCurrentDir() / "doc" / "overview.html", + createShortcut(getCurrentDir() / "doc" / "html" / "overview.html", dest / "Overview") if dirExists(r"dist\aporia-0.4.0"): createShortcut(getCurrentDir() / r"dist\aporia-0.4.0\bin\aporia.exe", diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim index 66ea52447..e0b8ad9b3 100644 --- a/tools/niminst/niminst.nim +++ b/tools/niminst/niminst.nim @@ -313,7 +313,7 @@ proc parseIniFile(c: var ConfigData) = of cfgSectionStart: section = normalize(k.section) of cfgKeyValuePair: - var v = `%`(k.value, c.vars, {useEnvironment}) + var v = `%`(k.value, c.vars, {useEnvironment, useEmpty}) c.vars[k.key] = v case section diff --git a/tools/nimweb.nim b/tools/nimweb.nim index c3bba3f0a..9a21a0fb5 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -29,7 +29,7 @@ type TRssItem = object year, month, day, title, url, content: string TAction = enum - actAll, actOnlyWebsite, actPdf, actJson2 + actAll, actOnlyWebsite, actPdf, actJson2, actOnlyDocs Sponsor = object logo: string @@ -72,7 +72,7 @@ include "website.tmpl" # ------------------------- configuration file ------------------------------- const - version = "0.7" + version = "0.8" usage = "nimweb - Nim Website Generator Version " & version & """ (c) 2015 Andreas Rumpf @@ -85,6 +85,8 @@ Options: -v, --version shows the version --website only build the website, not the full documentation --pdf build the PDF version of the documentation + --json2 build JSON of the documentation + --onlyDocs build only the documentation Compile_options: will be passed to the Nim compiler """ @@ -157,6 +159,7 @@ proc parseCmdLine(c: var TConfigData) = of "website": action = actOnlyWebsite of "pdf": action = actPdf of "json2": action = actJson2 + of "onlydocs": action = actOnlyDocs of "googleanalytics": c.gaId = val c.nimArgs.add("--doc.googleAnalytics:" & val & " ") @@ -315,6 +318,7 @@ proc buildDoc(c: var TConfigData, destPath: string) = exec(findNim() & " buildIndex -o:$1/theindex.html $1" % [destPath]) proc buildPdfDoc(c: var TConfigData, destPath: string) = + createDir(destPath) if os.execShellCmd("pdflatex -version") != 0: echo "pdflatex not found; no PDF documentation generated" else: @@ -507,8 +511,14 @@ proc main(c: var TConfigData) = buildAddDoc(c, docup) buildDocSamples(c, docup) buildDoc(c, docup) - buildDocSamples(c, "doc") - buildDoc(c, "doc") + createDir("doc/html") + buildDocSamples(c, "doc/html") + buildDoc(c, "doc/html") + +proc onlyDocs(c: var TConfigData) = + createDir("doc/html") + buildDocSamples(c, "doc/html") + buildDoc(c, "doc/html") proc json2(c: var TConfigData) = const destPath = "web/json2" @@ -529,6 +539,7 @@ parseCmdLine(c) parseIniFile(c) case action of actOnlyWebsite: buildWebsite(c) -of actPdf: buildPdfDoc(c, "doc") +of actPdf: buildPdfDoc(c, "doc/pdf") +of actOnlyDocs: onlyDocs(c) of actAll: main(c) of actJson2: json2(c) diff --git a/tools/noprefix.nim b/tools/noprefix.nim deleted file mode 100644 index d16c2b520..000000000 --- a/tools/noprefix.nim +++ /dev/null @@ -1,32 +0,0 @@ -# strip those silly GTK/ATK prefixes... - -import - expandimportc, os - -const - filelist = [ - ("sdl/sdl", "sdl"), - ("sdl/sdl_net", "sdl"), - ("sdl/sdl_gfx", "sdl"), - ("sdl/sdl_image", "sdl"), - ("sdl/sdl_mixer_nosmpeg", "sdl"), - ("sdl/sdl_mixer", "sdl"), - ("sdl/sdl_ttf", "sdl"), - ("sdl/smpeg", "sdl"), - - ("libcurl", "curl"), - ("mysql", "mysql"), - ("postgres", ""), - ("sqlite3", "sqlite3"), - - ("pcre/pcre", "pcre") - ] - -proc createDirs = - createDir("lib/newwrap/sdl") - createDir("lib/newwrap/pcre") - -for filename, prefix in items(filelist): - var f = addFileExt(filename, "nim") - main("lib/wrappers" / f, "lib/newwrap" / f, prefix) - diff --git a/start.bat b/tools/start.bat index 685932c47..a4475fac7 100644 --- a/start.bat +++ b/tools/start.bat @@ -1,6 +1,8 @@ @echo off REM COLOR 0A -SET NIMPATH=%~dp0 +SET NIMPATH=%~dp0\.. SET PATH=%NIMPATH%\bin;%NIMPATH%\dist\mingw\bin;%PATH% -cmd +cd %NIMPATH% +cmd + diff --git a/web/download.rst b/web/download.rst index c9aaea9fc..b9874f1b1 100644 --- a/web/download.rst +++ b/web/download.rst @@ -12,9 +12,9 @@ Zips We now encourage you to install via the provided zipfiles: * | 32 bit: `nim-0.15.2_x32.zip <download/nim-0.15.2_x32.zip>`_ - | SHA-256 + | SHA-256 0f1bfb74751f55e090140a361c08e9f39f1dd03f1f0c070c061f2d5049ab9f96 * | 64 bit: `nim-0.15.2_x64.zip <download/nim-0.15.2_x64.zip>`_ - | SHA-256 + | SHA-256 ceea42de6ebcd41032ee51f04526dc4cf2cbb0958ca6ad2321cf21944e05f553 Unzip these where you want and optionally run ``finish.exe`` to detect your MingW environment. @@ -28,9 +28,9 @@ so will unlikely to be provided further in the future. These installers have everything you need to use Nim, including a C compiler. * | 32 bit: `nim-0.15.2_x32.exe <download/nim-0.15.2_x32.exe>`_ - | SHA-256 + | SHA-256 8d648295dbd59cb315c98926a1da9f1f68773a1a2ef3d9d4c91c59387167efa3 * | 64 bit: `nim-0.15.2_x64.exe <download/nim-0.15.2_x64.exe>`_ - | SHA-256 + | SHA-256 8c7efc6571921c2d2e5e995f801d4229ea1de19fbdabdcba1628307bd4612392 These installers also include Aporia, Nimble and other useful Nim tools to get you started with Nim development! @@ -49,7 +49,7 @@ like systems. Firstly, download this archive: * | `nim-0.15.2.tar.xz (4.5MB) <download/nim-0.15.2.tar.xz>`_ - | SHA-256 + | SHA-256 905df2316262aa2cbacae067acf45fc05c2a71c8c6fde1f2a70c927ebafcfe8a Extract the archive. Then copy the extracted files into your chosen installation directory, ideally somewhere in your home directory. diff --git a/web/news/e028_version_0_15_2.rst b/web/news/e028_version_0_15_2.rst index 376fb4dde..601a26646 100644 --- a/web/news/e028_version_0_15_2.rst +++ b/web/news/e028_version_0_15_2.rst @@ -16,10 +16,17 @@ regressions of 0.15.0. For Windows we now provide zipfiles in addition to the NSIS based installer which proves to be hard to maintain and after all these months still has serious issues. So we encourage you download the .zip file instead of the .exe file! Unzip it somewhere, run ``finish.exe`` to -detect your MingW installation, done. +detect your MingW installation, done. ``finish.exe`` can also set your PATH +environment variable. -To see a full list of changes, take a look at the -detailed changelog `below <#changelog>`_. + +Bugfixes +-------- + +The list below has been generated based on the commits in Nim's git +repository. As such it lists only the issues which have been closed +via a commit, for a full list see +`this link on Github <https://github.com/nim-lang/Nim/issues?utf8=%E2%9C%93&q=is%3Aissue+closed%3A%222016-09-30+..+2016-10-23%22+>`_. - Fixed "`NimMain` not exported in DLL, but `NimMainInner` is" diff --git a/web/website.ini b/web/website.ini index 833122ecb..0d1be4b63 100644 --- a/web/website.ini +++ b/web/website.ini @@ -31,7 +31,7 @@ file: ticker.html [Documentation] doc: "endb;intern;apis;lib;manual.rst;tut1.rst;tut2.rst;nimc;overview;filters" doc: "tools;niminst;nimgrep;gc;estp;idetools;docgen;koch;backends.rst" -doc: "nimfix.rst;nimsuggest.rst;nep1.rst;nims.rst" +doc: "nimfix.rst;nimsuggest.rst;nep1.rst;nims.rst;contributing.rst" pdf: "manual.rst;lib.rst;tut1.rst;tut2.rst;nimc.rst;niminst.rst;gc.rst" srcdoc2: "system.nim;system/nimscript;pure/ospaths" srcdoc2: "core/macros;pure/marshal;core/typeinfo" |