From 8818b15d8d1388e0d739eb23db1cfa0cb4f1ba51 Mon Sep 17 00:00:00 2001 From: Flaviu Tamas Date: Wed, 12 Nov 2014 08:01:56 -0500 Subject: [PATCH 001/850] Add csources to gitignore This will keep the git status output cleaner. The .gitignore will not cause already tracked files to be deleted --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 462df4efc7..d804fb8f54 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,4 @@ xcuserdata/ /testresults.html /testresults.json testament.db +/csources/ From f9c93d23bc5cd50d0063dbeed105c4be9c674eac Mon Sep 17 00:00:00 2001 From: Flaviu Tamas Date: Thu, 25 Dec 2014 20:53:37 -0500 Subject: [PATCH 002/850] Mostly get analytics working for docs --- compiler/docgen.nim | 23 +++++++++++++++++++++-- config/nimdoc.cfg | 2 ++ tools/nimweb.nim | 8 +++++++- tools/website.tmpl | 4 +++- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 35acf1379f..ab513d2cc8 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -23,6 +23,7 @@ type id: int # for generating IDs toc, section: TSections indexValFilename: string + gaId: string # Google Analytics ID, null if doesn't exist seenSymbols: StringTableRef # avoids duplicate symbol generation for HTML. PDoc* = ref TDocumentor ## Alias to type less. @@ -61,6 +62,8 @@ proc newDocumentor*(filename: string, config: StringTableRef): PDoc = initRstGenerator(result[], (if gCmd != cmdRst2tex: outHtml else: outLatex), options.gConfigVars, filename, {roSupportRawDirective}, docgenFindFile, compilerMsgHandler) + if config.hasKey("doc.googleAnalytics"): + result.gaId = config["doc.googleAnalytics"] result.seenSymbols = newStringTable(modeCaseInsensitive) result.id = 100 @@ -534,6 +537,7 @@ proc genOutFile(d: PDoc): PRope = var code, content: PRope title = "" + analytics = "" var j = 0 var tmp = "" renderTocEntries(d[], j, 1, tmp) @@ -553,6 +557,21 @@ proc genOutFile(d: PDoc): PRope = # Modules get an automatic title for the HTML, but no entry in the index. title = "Module " & extractFilename(changeFileExt(d.filename, "")) + # if there exists an analytics id, use it + if d.gaId != nil: + analytics = """ + + """ % [d.gaId] + let bodyname = if d.hasToc: "doc.body_toc" else: "doc.body_no_toc" content = ropeFormatNamedVars(getConfigVar(bodyname), ["title", "tableofcontents", "moduledesc", "date", "time", "content"], @@ -562,10 +581,10 @@ proc genOutFile(d: PDoc): PRope = # XXX what is this hack doing here? 'optCompileOnly' means raw output!? code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title", "tableofcontents", "moduledesc", "date", "time", - "content", "author", "version"], + "content", "author", "version", "analytics"], [title.toRope, toc, d.modDesc, toRope(getDateStr()), toRope(getClockStr()), content, d.meta[metaAuthor].toRope, - d.meta[metaVersion].toRope]) + d.meta[metaVersion].toRope, analytics.toRope]) else: code = content result = code diff --git a/config/nimdoc.cfg b/config/nimdoc.cfg index 3abae73885..3375460ccc 100644 --- a/config/nimdoc.cfg +++ b/config/nimdoc.cfg @@ -86,6 +86,7 @@ $moduledesc $content """ +# * $analytics: Google analytics location, includes + """ % [config["doc.googleAnalytics"]] + else: + result.analytics = "" + result.seenSymbols = newStringTable(modeCaseInsensitive) result.id = 100 @@ -537,7 +552,6 @@ proc genOutFile(d: PDoc): PRope = var code, content: PRope title = "" - analytics = "" var j = 0 var tmp = "" renderTocEntries(d[], j, 1, tmp) @@ -557,21 +571,6 @@ proc genOutFile(d: PDoc): PRope = # Modules get an automatic title for the HTML, but no entry in the index. title = "Module " & extractFilename(changeFileExt(d.filename, "")) - # if there exists an analytics id, use it - if d.gaId != nil: - analytics = """ - - """ % [d.gaId] - let bodyname = if d.hasToc: "doc.body_toc" else: "doc.body_no_toc" content = ropeFormatNamedVars(getConfigVar(bodyname), ["title", "tableofcontents", "moduledesc", "date", "time", "content"], @@ -584,7 +583,7 @@ proc genOutFile(d: PDoc): PRope = "content", "author", "version", "analytics"], [title.toRope, toc, d.modDesc, toRope(getDateStr()), toRope(getClockStr()), content, d.meta[metaAuthor].toRope, - d.meta[metaVersion].toRope, analytics.toRope]) + d.meta[metaVersion].toRope, d.analytics.toRope]) else: code = content result = code @@ -649,7 +648,8 @@ proc commandBuildIndex*() = let code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title", "tableofcontents", "moduledesc", "date", "time", - "content", "author", "version"], + "content", "author", "version", "analytics"], ["Index".toRope, nil, nil, toRope(getDateStr()), - toRope(getClockStr()), content, nil, nil]) + toRope(getClockStr()), content, nil, nil, nil]) + # no analytics because context is not available writeRope(code, getOutFile("theindex", HtmlExt)) From 3f113f946d3a8569f420e1465445ec162bfcaf99 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 29 Dec 2014 12:12:05 +0100 Subject: [PATCH 004/850] niminst: use project-version for the zip file --- tools/niminst/niminst.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim index 9ee3eb9b96..fe1b9a192b 100644 --- a/tools/niminst/niminst.nim +++ b/tools/niminst/niminst.nim @@ -522,8 +522,8 @@ proc setupDist2(c: var TConfigData) = # ------------------ generate ZIP file --------------------------------------- when haveZipLib: proc zipDist(c: var TConfigData) = - var proj = toLower(c.name) - var n = "$#_$#.zip" % [proj, c.version] + var proj = toLower(c.name) & "-" & c.version + var n = "$#.zip" % proj if c.outdir.len == 0: n = "build" / n else: n = c.outdir / n var z: TZipArchive From 6d749aed291dbe27a42fef25550460cbd2fe6990 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Mon, 29 Dec 2014 18:00:50 +0000 Subject: [PATCH 005/850] Fix typo in news. --- web/news.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web/news.txt b/web/news.txt index ddeab0f9b3..cca2aaeeea 100644 --- a/web/news.txt +++ b/web/news.txt @@ -28,7 +28,7 @@ for lightweight threading through the use of ``spawn``. The unpopular "T" and "P" prefixes on types have been deprecated. Nim also became more expressive by weakening the distinction between statements and -epxressions. We also added a new and searchable forum, a new website, and our +expressions. We also added a new and searchable forum, a new website, and our documentation generator ``docgen`` has seen major improvements. What's left to be done @@ -194,7 +194,6 @@ Bugfixes - Fixed queue exhaustion bug. - Many, many more. - 2014-12-09 New website design! ============================== From 2d20feb8f1c2f44ba492989f1d05cee915c76edd Mon Sep 17 00:00:00 2001 From: def Date: Mon, 29 Dec 2014 22:27:31 +0100 Subject: [PATCH 006/850] Add imports to asynchttpserver example --- lib/pure/asynchttpserver.nim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim index 0b18e6bcc6..4c48350aa0 100644 --- a/lib/pure/asynchttpserver.nim +++ b/lib/pure/asynchttpserver.nim @@ -17,6 +17,8 @@ ## as the response body. ## ## .. code-block::nim +## import asynchttpserver, asyncdispatch +## ## var server = newAsyncHttpServer() ## proc cb(req: Request) {.async.} = ## await req.respond(Http200, "Hello World") From 32af9f878b1a8f54ff919f7282ddcbd7aa698f36 Mon Sep 17 00:00:00 2001 From: astrolantique Date: Mon, 29 Dec 2014 19:44:44 -0600 Subject: [PATCH 007/850] getSystemVersion updated to include 10.7 to 10.10 --- lib/impure/osinfo_posix.nim | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/impure/osinfo_posix.nim b/lib/impure/osinfo_posix.nim index 1baff8c558..0ed4289c47 100644 --- a/lib/impure/osinfo_posix.nim +++ b/lib/impure/osinfo_posix.nim @@ -35,7 +35,15 @@ proc getSystemVersion*(): string = elif $unix_info.sysname == "Darwin": # Darwin result.add("Mac OS X ") - if "10" in $unix_info.release: + if "14" in $unix_info.release: + result.add("v10.10 Yosemite") + elif "13" in $unix_info.release: + result.add("v10.9 Mavericks") + elif "12" in $unix_info.release: + result.add("v10.8 Mountian Lion") + elif "11" in $unix_info.release: + result.add("v10.7 Lion") + elif "10" in $unix_info.release: result.add("v10.6 Snow Leopard") elif "9" in $unix_info.release: result.add("v10.5 Leopard") From 334097a03a13f4e4e42a25d896be7d9b2cd113d4 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 30 Dec 2014 02:52:51 +0100 Subject: [PATCH 008/850] website: better formating --- web/news.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/news.txt b/web/news.txt index cca2aaeeea..75c5744054 100644 --- a/web/news.txt +++ b/web/news.txt @@ -137,9 +137,9 @@ Compiler Additions - The following procs are now available at compile-time:: math.sqrt, math.ln, math.log10, math.log2, math.exp, math.round, - math.arccos, math.arcsin, math.arctan, math.arctan2, math.cos, math.cosh, - math.hypot, math.sinh, math.sin, math.tan, math.tanh, math.pow, - math.trunc, math.floor, math.ceil, math.fmod, + math.arccos, math.arcsin, math.arctan, math.arctan2, math.cos, + math.cosh, math.hypot, math.sinh, math.sin, math.tan, math.tanh, + math.pow, math.trunc, math.floor, math.ceil, math.fmod, os.getEnv, os.existsEnv, os.dirExists, os.fileExists, system.writeFile From f30a1617caaecdc2578aea608b5173d782d1a1ae Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 30 Dec 2014 02:53:16 +0100 Subject: [PATCH 009/850] license file knows about the language renaming --- copying.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copying.txt b/copying.txt index 254b91c774..908625e181 100644 --- a/copying.txt +++ b/copying.txt @@ -1,5 +1,5 @@ ===================================================== -Nimrod -- a Compiler for Nimrod. http://nimrod-lang.org/ +Nim -- a Compiler for Nim. http://nim-lang.org/ Copyright (C) 2006-2014 Andreas Rumpf. All rights reserved. From 7f415b5b116883d96d514864f2796b479d554d7e Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 30 Dec 2014 03:05:29 +0100 Subject: [PATCH 010/850] fixes #1788 --- compiler/ast.nim | 4 ++-- tests/misc/tvarious.nim | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 565bb43535..d85dbf42c4 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1517,8 +1517,8 @@ proc getStr*(a: PNode): string = proc getStrOrChar*(a: PNode): string = case a.kind of nkStrLit..nkTripleStrLit: result = a.strVal - of nkCharLit: result = $chr(int(a.intVal)) - else: + of nkCharLit..nkUInt64Lit: result = $chr(int(a.intVal)) + else: internalError(a.info, "getStrOrChar") result = "" diff --git a/tests/misc/tvarious.nim b/tests/misc/tvarious.nim index ed2964cf9b..434d25e483 100644 --- a/tests/misc/tvarious.nim +++ b/tests/misc/tvarious.nim @@ -62,3 +62,7 @@ when false: block: var a, b: Bar[int, 0..2] discard foo(a, b) + +# bug #1788 + +echo "hello" & char(ord(' ')) & "world" From d01eb14a3997b53fca5ed6628d0ebbf6f91d8b43 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 30 Dec 2014 03:06:25 +0100 Subject: [PATCH 011/850] development version is 0.10.3 --- lib/system.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/system.nim b/lib/system.nim index ca85bf1ad5..b7c77e2766 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1516,7 +1516,7 @@ const NimMinor*: int = 10 ## is the minor number of Nim's version. - NimPatch*: int = 2 + NimPatch*: int = 3 ## is the patch number of Nim's version. NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch From c77176e0c7cd1d0f5f2d7ccf4fe0281b02e7c079 Mon Sep 17 00:00:00 2001 From: astrolantique Date: Tue, 30 Dec 2014 00:24:32 -0600 Subject: [PATCH 012/850] Added NT 6.2 and NT 6.3 (8/8.1) --- lib/impure/osinfo_win.nim | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/impure/osinfo_win.nim b/lib/impure/osinfo_win.nim index f423a34a32..becec928e7 100644 --- a/lib/impure/osinfo_win.nim +++ b/lib/impure/osinfo_win.nim @@ -245,6 +245,14 @@ proc `$`*(osvi: TVersionInfo): string = if osvi.ProductType == VER_NT_WORKSTATION: result.add("Windows 7 ") else: result.add("Windows Server 2008 R2 ") + elif osvi.minorVersion == 2: + if osvi.ProductType == VER_NT_WORKSTATION: + result.add("Windows 8 ") + else: result.add("Windows Server 2012 ") + elif osvi.minorVersion == 3: + if osvi.ProductType == VER_NT_WORKSTATION: + result.add("Windows 8.1 ") + else: result.add("Windows Server 2012 R2 ") var dwType = getProductInfo(osvi.majorVersion, osvi.minorVersion, 0, 0) case dwType From b2140be31f3b19f17adc141b7e3bc00f1b08649d Mon Sep 17 00:00:00 2001 From: Flaviu Tamas Date: Tue, 30 Dec 2014 15:42:18 -0500 Subject: [PATCH 013/850] Fix cross to windows compilation on linux `Winsock2.h` should be all lowercase --- lib/windows/winlean.nim | 42 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 76d17bc4a2..51a12141b1 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -368,32 +368,32 @@ type {.deprecated: [TSocketHandle: SocketHandle].} type - WSAData* {.importc: "WSADATA", header: "Winsock2.h".} = object + WSAData* {.importc: "WSADATA", header: "winsock2.h".} = object wVersion, wHighVersion: int16 szDescription: array[0..WSADESCRIPTION_LEN, char] szSystemStatus: array[0..WSASYS_STATUS_LEN, char] iMaxSockets, iMaxUdpDg: int16 lpVendorInfo: cstring - SockAddr* {.importc: "SOCKADDR", header: "Winsock2.h".} = object + SockAddr* {.importc: "SOCKADDR", header: "winsock2.h".} = object sa_family*: int16 # unsigned sa_data: array[0..13, char] - InAddr* {.importc: "IN_ADDR", header: "Winsock2.h".} = object + InAddr* {.importc: "IN_ADDR", header: "winsock2.h".} = object s_addr*: int32 # IP address Sockaddr_in* {.importc: "SOCKADDR_IN", - header: "Winsock2.h".} = object + header: "winsock2.h".} = object sin_family*: int16 sin_port*: int16 # unsigned sin_addr*: InAddr sin_zero*: array[0..7, char] - In6_addr* {.importc: "IN6_ADDR", header: "Winsock2.h".} = object + In6_addr* {.importc: "IN6_ADDR", header: "winsock2.h".} = object bytes*: array[0..15, char] Sockaddr_in6* {.importc: "SOCKADDR_IN6", - header: "Winsock2.h".} = object + header: "winsock2.h".} = object sin6_family*: int16 sin6_port*: int16 # unsigned sin6_flowinfo*: int32 # unsigned @@ -450,22 +450,22 @@ type var - SOMAXCONN* {.importc, header: "Winsock2.h".}: cint - INVALID_SOCKET* {.importc, header: "Winsock2.h".}: SocketHandle - SOL_SOCKET* {.importc, header: "Winsock2.h".}: cint - SO_DEBUG* {.importc, header: "Winsock2.h".}: cint ## turn on debugging info recording - SO_ACCEPTCONN* {.importc, header: "Winsock2.h".}: cint # socket has had listen() - SO_REUSEADDR* {.importc, header: "Winsock2.h".}: cint # allow local address reuse - SO_KEEPALIVE* {.importc, header: "Winsock2.h".}: cint # keep connections alive - SO_DONTROUTE* {.importc, header: "Winsock2.h".}: cint # just use interface addresses - SO_BROADCAST* {.importc, header: "Winsock2.h".}: cint # permit sending of broadcast msgs - SO_USELOOPBACK* {.importc, header: "Winsock2.h".}: cint # bypass hardware when possible - SO_LINGER* {.importc, header: "Winsock2.h".}: cint # linger on close if data present - SO_OOBINLINE* {.importc, header: "Winsock2.h".}: cint # leave received OOB data in line + SOMAXCONN* {.importc, header: "winsock2.h".}: cint + INVALID_SOCKET* {.importc, header: "winsock2.h".}: SocketHandle + SOL_SOCKET* {.importc, header: "winsock2.h".}: cint + SO_DEBUG* {.importc, header: "winsock2.h".}: cint ## turn on debugging info recording + SO_ACCEPTCONN* {.importc, header: "winsock2.h".}: cint # socket has had listen() + SO_REUSEADDR* {.importc, header: "winsock2.h".}: cint # allow local address reuse + SO_KEEPALIVE* {.importc, header: "winsock2.h".}: cint # keep connections alive + SO_DONTROUTE* {.importc, header: "winsock2.h".}: cint # just use interface addresses + SO_BROADCAST* {.importc, header: "winsock2.h".}: cint # permit sending of broadcast msgs + SO_USELOOPBACK* {.importc, header: "winsock2.h".}: cint # bypass hardware when possible + SO_LINGER* {.importc, header: "winsock2.h".}: cint # linger on close if data present + SO_OOBINLINE* {.importc, header: "winsock2.h".}: cint # leave received OOB data in line - SO_DONTLINGER* {.importc, header: "Winsock2.h".}: cint - SO_EXCLUSIVEADDRUSE* {.importc, header: "Winsock2.h".}: cint # disallow local address reuse - SO_ERROR* {.importc, header: "Winsock2.h".}: cint + SO_DONTLINGER* {.importc, header: "winsock2.h".}: cint + SO_EXCLUSIVEADDRUSE* {.importc, header: "winsock2.h".}: cint # disallow local address reuse + SO_ERROR* {.importc, header: "winsock2.h".}: cint proc `==`*(x, y: SocketHandle): bool {.borrow.} From 1b56334c4624ddb1c45282a6071354b8ab9282da Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 30 Dec 2014 23:20:40 +0100 Subject: [PATCH 014/850] website updates; Source links now work --- tools/nimweb.nim | 20 +++++++++++--------- web/download.txt | 9 +++------ web/news.txt | 7 +++++-- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/tools/nimweb.nim b/tools/nimweb.nim index bbd3776d76..0596076b3b 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -47,7 +47,7 @@ proc initConfigData(c: var TConfigData) = c.logo = "" c.ticker = "" c.vars = newStringTable(modeStyleInsensitive) - c.gitRepo = "https://github.com/Araq/Nimrod/tree" + c.gitRepo = "https://github.com/Araq/Nim/tree" c.gitCommit = "master" c.numProcessors = countProcessors() # Attempts to obtain the git current commit. @@ -262,24 +262,26 @@ proc buildDocSamples(c: var TConfigData, destPath: string) = exec("nim doc2 $# -o:$# $#" % [c.nimArgs, destPath / "docgen_sample2.html", src]) +proc pathPart(d: string): string = splitFile(d).dir.replace('\\', '/') + proc buildDoc(c: var TConfigData, destPath: string) = # call nim for the documentation: var commands = newSeq[string](len(c.doc) + len(c.srcdoc) + len(c.srcdoc2)) i = 0 for d in items(c.doc): - commands[i] = "nim rst2html $# --docSeeSrcUrl:$#/$# -o:$# --index:on $#" % - [c.nimArgs, c.gitRepo, c.gitCommit, + commands[i] = "nim rst2html $# --docSeeSrcUrl:$#/$#/$# -o:$# --index:on $#" % + [c.nimArgs, c.gitRepo, c.gitCommit, d.pathPart, destPath / changeFileExt(splitFile(d).name, "html"), d] i.inc for d in items(c.srcdoc): - commands[i] = "nim doc $# --docSeeSrcUrl:$#/$# -o:$# --index:on $#" % - [c.nimArgs, c.gitRepo, c.gitCommit, + commands[i] = "nim doc $# --docSeeSrcUrl:$#/$#/$# -o:$# --index:on $#" % + [c.nimArgs, c.gitRepo, c.gitCommit, d.pathPart, destPath / changeFileExt(splitFile(d).name, "html"), d] i.inc for d in items(c.srcdoc2): - commands[i] = "nim doc2 $# --docSeeSrcUrl:$#/$# -o:$# --index:on $#" % - [c.nimArgs, c.gitRepo, c.gitCommit, + commands[i] = "nim doc2 $# --docSeeSrcUrl:$#/$#/$# -o:$# --index:on $#" % + [c.nimArgs, c.gitRepo, c.gitCommit, d.pathPart, destPath / changeFileExt(splitFile(d).name, "html"), d] i.inc @@ -311,8 +313,8 @@ proc buildAddDoc(c: var TConfigData, destPath: string) = # build additional documentation (without the index): var commands = newSeq[string](c.webdoc.len) for i, doc in pairs(c.webdoc): - commands[i] = "nim doc $# --docSeeSrcUrl:$#/$# -o:$# $#" % - [c.nimArgs, c.gitRepo, c.gitCommit, + commands[i] = "nim doc $# --docSeeSrcUrl:$#/$#/$# -o:$# $#" % + [c.nimArgs, c.gitRepo, c.gitCommit, doc.pathPart, destPath / changeFileExt(splitFile(doc).name, "html"), doc] mexec(commands, c.numProcessors) diff --git a/web/download.txt b/web/download.txt index 1ba1ad5f75..497781ad64 100644 --- a/web/download.txt +++ b/web/download.txt @@ -9,12 +9,9 @@ and clang on Mac OS X. Binaries ======== -Unfortunately for now we provide no binary builds. - -.. - Unfortunately for now we only provide builds for Windows. - * 32 bit: `nim_0.10.2.exe `_ - * 64 bit: `nim_0.10.2_x64.exe `_ +Unfortunately for now we only provide builds for Windows. +* 32 bit: `nim-0.10.2_x32.exe `_ +* 64 bit: `nim-0.10.2_x64.exe `_ Installation based on generated C code diff --git a/web/news.txt b/web/news.txt index 75c5744054..ee9ad8837a 100644 --- a/web/news.txt +++ b/web/news.txt @@ -29,7 +29,10 @@ for lightweight threading through the use of ``spawn``. The unpopular "T" and "P" prefixes on types have been deprecated. Nim also became more expressive by weakening the distinction between statements and expressions. We also added a new and searchable forum, a new website, and our -documentation generator ``docgen`` has seen major improvements. +documentation generator ``docgen`` has seen major improvements. Many thanks to +Nick Greenfield for the much more beautiful documentation! + + What's left to be done ~~~~~~~~~~~~~~~~~~~~~~ @@ -120,7 +123,7 @@ Language Additions - The builtin ``procCall`` can be used to get ``super``-like functionality for multi methods. - There is a new pragma ``{.experimental.}`` that enables experimental - language features per module, or you can enable this features on a global + language features per module, or you can enable these features on a global level with the ``--experimental`` command line option. From 85c22f334832cc7cf5e2b01a23eb1c1b63189cfe Mon Sep 17 00:00:00 2001 From: Andre Date: Tue, 30 Dec 2014 23:39:43 +0100 Subject: [PATCH 015/850] ignore signal SIGPIPE on Darwin --- lib/posix/posix.nim | 4 ++-- lib/pure/rawsockets.nim | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index deb120372c..0498a0e709 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -1570,9 +1570,9 @@ else: when defined(macosx): + # We can't use the NOSIGNAL flag in the ``send`` function, it has no effect var - MSG_HAVEMORE* {.importc, header: "".}: cint - MSG_NOSIGNAL* = MSG_HAVEMORE + MSG_NOSIGNAL* = 0'i32 else: var MSG_NOSIGNAL* {.importc, header: "".}: cint diff --git a/lib/pure/rawsockets.nim b/lib/pure/rawsockets.nim index 62a011999b..e23deea5bd 100644 --- a/lib/pure/rawsockets.nim +++ b/lib/pure/rawsockets.nim @@ -428,6 +428,10 @@ proc selectWrite*(writefds: var seq[SocketHandle], pruneSocketSet(writefds, (wr)) +# We ignore signal SIGPIPE on Darwin +when defined(macosx): + signal(SIGPIPE, SIG_IGN) + when defined(Windows): var wsa: WSAData if wsaStartup(0x0101'i16, addr wsa) != 0: raiseOSError(osLastError()) From 98d956b77e53cce2f2a2b0624623be3abbf5aee3 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 30 Dec 2014 23:46:14 +0100 Subject: [PATCH 016/850] removed outdated documentation --- doc/nimc.txt | 52 ---------------------------------------------------- 1 file changed, 52 deletions(-) diff --git a/doc/nimc.txt b/doc/nimc.txt index 92acd3979d..a2274febd2 100644 --- a/doc/nimc.txt +++ b/doc/nimc.txt @@ -550,58 +550,6 @@ in C/C++). **Note**: This pragma will not exist for the LLVM backend. -Source code style -================= - -Nim allows you to `mix freely case and underscores as identifier separators -`_, so variables named ``MyPrecioussInt`` and -``my_preciouss_int`` are equivalent: - -.. code-block:: Nim - var MyPrecioussInt = 3 - # Following line compiles fine! - echo my_preciouss_int - -Since this can lead to many variants of the same source code (you can use -`nimgrep `_ instead of your typical ``grep`` to ignore style -problems) the compiler provides the command ``pretty`` to help unifying the -style of source code. Running ``nim pretty ugly_test.nim`` with this -example will generate a secondary file named ``ugly_test.pretty.nim`` with the -following content: - -.. code-block:: Nim - var MyPrecioussInt = 3 - # Following line compiles fine! - echo MyPrecioussInt - -During execution the ``pretty`` command will also run on Nim's standard -library, since it doesn't differentiate the standard library as something -special, and hence will warn of many *errors* which are out of your hand to -fix, creating respective ``.pretty.nim`` files all the way. You can ignore -these errors if they don't belong to your source and simply compare your -original version to the new pretty one. In fact, running ``pretty`` on our test -file will show the following:: - - Hint: ugly_test [Processing] - ugly_test.nim(1, 4) Error: name should be: myPrecioussInt - ugly_test.nim(1, 4) Error: name should be: myPrecioussInt - -At the moment ``pretty`` will homogenize the style of symbols but will leave -important changes for you to review. In this case the command is warning that a -variable name should not start with a capital letter, which is usually reserved -to `object types `_. To learn about the accepted `camel case -style `_ read `Coding Guidelines in -the Internals of Nim Compiler `_ or `Coding -Guidelines `_ and `NEP 1 -: Style Guide for Nim Code -`_ -from the Nim `GitHub wiki`_. - -This command is safe to run because it will never attempt to overwrite your -existing sources, but the respective ``.pretty.nim`` files **will** be -overwritten without notice. - - DynlibOverride ============== From bf8f6a3000804a1beb3488ab3a19d5676fe8c9cd Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 31 Dec 2014 00:44:07 +0100 Subject: [PATCH 017/850] minor doc update --- doc/backends.txt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/doc/backends.txt b/doc/backends.txt index eb16217cd6..ffe2d5e88f 100644 --- a/doc/backends.txt +++ b/doc/backends.txt @@ -456,11 +456,7 @@ can then attach a GC to this thread via .. code-block:: nim - setStackBottom(addr(someLocal)) - initGC() - -At the moment this support is still experimental so you need to expose these -functions yourself or submit patches to request a public API. + system.setupForeignThreadGc() It is **not** safe to disable the garbage collector and enable it after the call from your background thread even if the code you are calling is short From da36a847a74e9edf36f734015d4a41cdb0193e38 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Tue, 30 Dec 2014 11:27:54 +0200 Subject: [PATCH 018/850] fix #1789 (binding to static params during generic proc sigmatch) --- compiler/semexprs.nim | 2 +- compiler/semgnrc.nim | 8 ++++- compiler/seminst.nim | 4 ++- compiler/semtypes.nim | 76 +++++++++++++++++++++------------------- compiler/sigmatch.nim | 28 +++++++++++---- tests/generics/t1789.nim | 44 +++++++++++++++++++++++ 6 files changed, 116 insertions(+), 46 deletions(-) create mode 100644 tests/generics/t1789.nim diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index ee3391e3ee..b2f623fb80 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -219,7 +219,7 @@ proc maybeLiftType(t: var PType, c: PContext, info: TLineInfo) = # gnrc. params, then it won't be necessary to open a new scope here openScope(c) var lifted = liftParamType(c, skType, newNodeI(nkArgList, info), - t, ":anon", info) + t, ":anon", info) closeScope(c) if lifted != nil: t = lifted diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 7c32b00519..06959b8d16 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -60,7 +60,13 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym, else: result = symChoice(c, n, s, scOpen) of skGenericParam: - result = newSymNodeTypeDesc(s, n.info) + if s.typ != nil and s.typ.kind == tyStatic: + if s.typ.n != nil: + result = s.typ.n + else: + result = n + else: + result = newSymNodeTypeDesc(s, n.info) styleCheckUse(n.info, s) of skParam: result = n diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 2decb5d0b2..81a4465c59 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -21,7 +21,8 @@ proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable, var q = a.sym if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyStatic, tyIter}+tyTypeClasses: continue - var s = newSym(skType, q.name, getCurrOwner(), q.info) + let symKind = if q.typ.kind == tyStatic: skConst else: skType + var s = newSym(symKind, q.name, getCurrOwner(), q.info) s.flags = s.flags + {sfUsed, sfFromGeneric} var t = PType(idTableGet(pt, q.typ)) if t == nil: @@ -40,6 +41,7 @@ proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable, t = generateTypeInstance(c, pt, a, t) #t = ReplaceTypeVarsT(cl, t) s.typ = t + if t.kind == tyStatic: s.ast = t.n addDecl(c, s) entry.concreteTypes[i] = t diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 4305a48e1a..eb15c3809c 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -214,44 +214,48 @@ proc semRange(c: PContext, n: PNode, prev: PType): PType = localError(n.info, errXExpectsOneTypeParam, "range") result = newOrPrevType(tyError, prev, c) -proc semArray(c: PContext, n: PNode, prev: PType): PType = - var indx, base: PType - result = newOrPrevType(tyArray, prev, c) - if sonsLen(n) == 3: - # 3 = length(array indx base) - if isRange(n[1]): indx = semRangeAux(c, n[1], nil) +proc semArrayIndex(c: PContext, n: PNode): PType = + if isRange(n): result = semRangeAux(c, n, nil) + else: + let e = semExprWithType(c, n, {efDetermineType}) + if e.typ.kind == tyFromExpr: + result = makeRangeWithStaticExpr(c, e.typ.n) + elif e.kind in {nkIntLit..nkUInt64Lit}: + result = makeRangeType(c, 0, e.intVal-1, n.info, e.typ) + elif e.kind == nkSym and e.typ.kind == tyStatic: + if e.sym.ast != nil: + return semArrayIndex(c, e.sym.ast) + internalAssert c.inGenericContext > 0 + if not isOrdinalType(e.typ.lastSon): + localError(n[1].info, errOrdinalTypeExpected) + result = makeRangeWithStaticExpr(c, e) + result.flags.incl tfUnresolved + elif e.kind in nkCallKinds and hasGenericArguments(e): + if not isOrdinalType(e.typ): + localError(n[1].info, errOrdinalTypeExpected) + # This is an int returning call, depending on an + # yet unknown generic param (see tgenericshardcases). + # We are going to construct a range type that will be + # properly filled-out in semtypinst (see how tyStaticExpr + # is handled there). + result = makeRangeWithStaticExpr(c, e) + elif e.kind == nkIdent: + result = e.typ.skipTypes({tyTypeDesc}) else: - let e = semExprWithType(c, n.sons[1], {efDetermineType}) - if e.typ.kind == tyFromExpr: - indx = makeRangeWithStaticExpr(c, e.typ.n) - elif e.kind in {nkIntLit..nkUInt64Lit}: - indx = makeRangeType(c, 0, e.intVal-1, n.info, e.typ) - elif e.kind == nkSym and e.typ.kind == tyStatic: - if e.sym.ast != nil: return semArray(c, e.sym.ast, nil) - internalAssert c.inGenericContext > 0 - if not isOrdinalType(e.typ.lastSon): - localError(n[1].info, errOrdinalTypeExpected) - indx = makeRangeWithStaticExpr(c, e) - indx.flags.incl tfUnresolved - elif e.kind in nkCallKinds and hasGenericArguments(e): - if not isOrdinalType(e.typ): - localError(n[1].info, errOrdinalTypeExpected) - # This is an int returning call, depending on an - # yet unknown generic param (see tgenericshardcases). - # We are going to construct a range type that will be - # properly filled-out in semtypinst (see how tyStaticExpr - # is handled there). - indx = makeRangeWithStaticExpr(c, e) - elif e.kind == nkIdent: - indx = e.typ.skipTypes({tyTypeDesc}) + let x = semConstExpr(c, e) + if x.kind in {nkIntLit..nkUInt64Lit}: + result = makeRangeType(c, 0, x.intVal-1, n.info, + x.typ.skipTypes({tyTypeDesc})) else: - let x = semConstExpr(c, e) - if x.kind in {nkIntLit..nkUInt64Lit}: - indx = makeRangeType(c, 0, x.intVal-1, n.info, - x.typ.skipTypes({tyTypeDesc})) - else: - indx = x.typ.skipTypes({tyTypeDesc}) - #localError(n[1].info, errConstExprExpected) + result = x.typ.skipTypes({tyTypeDesc}) + #localError(n[1].info, errConstExprExpected) + +proc semArray(c: PContext, n: PNode, prev: PType): PType = + var base: PType + result = newOrPrevType(tyArray, prev, c) + if sonsLen(n) == 3: + # 3 = length(array indx base) + var indx = semArrayIndex(c, n[1]) addSonSkipIntLit(result, indx) if indx.kind == tyGenericInst: indx = lastSon(indx) if indx.kind notin {tyGenericParam, tyStatic, tyFromExpr}: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 06f9d58b7a..d7bf4fee96 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -517,6 +517,16 @@ proc maybeSkipDistinct(t: PType, callee: PSym): PType = else: result = t +proc tryResolvingStaticExpr(c: var TCandidate, n: PNode): PNode = + # Consider this example: + # type Value[N: static[int]] = object + # proc foo[N](a: Value[N], r: range[0..(N-1)]) + # Here, N-1 will be initially nkStaticExpr that can be evaluated only after + # N is bound to a concrete value during the matching of the first param. + # This proc is used to evaluate such static expressions. + let instantiated = replaceTypesInBody(c.c, c.bindings, n) + result = c.c.semExpr(c.c, instantiated) + proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = # typeRel can be used to establish various relationships between types: # @@ -620,6 +630,11 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = # bugfix: accept integer conversions here #if result < isGeneric: result = isNone if result notin {isNone, isGeneric}: + # resolve any late-bound static expressions + # that may appear in the range: + for i in 0..1: + if f.n[i].kind == nkStaticExpr: + f.n.sons[i] = tryResolvingStaticExpr(c, f.n[i]) result = typeRangeRel(f, a) else: if skipTypes(f, {tyRange}).kind == a.kind: @@ -1006,15 +1021,14 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = of tyFromExpr: # fix the expression, so it contains the already instantiated types - let instantiated = replaceTypesInBody(c.c, c.bindings, f.n) - let reevaluted = c.c.semExpr(c.c, instantiated) - case reevaluted.typ.kind + let reevaluated = tryResolvingStaticExpr(c, f.n) + case reevaluated.typ.kind of tyTypeDesc: - result = typeRel(c, a, reevaluted.typ.base) + result = typeRel(c, a, reevaluated.typ.base) of tyStatic: - result = typeRel(c, a, reevaluted.typ.base) - if result != isNone and reevaluted.typ.n != nil: - if not exprStructuralEquivalent(aOrig.n, reevaluted.typ.n): + result = typeRel(c, a, reevaluated.typ.base) + if result != isNone and reevaluated.typ.n != nil: + if not exprStructuralEquivalent(aOrig.n, reevaluated.typ.n): result = isNone else: localError(f.n.info, errTypeExpected) diff --git a/tests/generics/t1789.nim b/tests/generics/t1789.nim new file mode 100644 index 0000000000..188db88f6b --- /dev/null +++ b/tests/generics/t1789.nim @@ -0,0 +1,44 @@ +discard """ + output: "3\n0" +""" + +# https://github.com/Araq/Nim/issues/1789 + +type + Foo[N: static[int]] = object + +proc bindStaticN[N](foo: Foo[N]) = + var ar0: array[3, int] + var ar1: array[N, int] + var ar2: array[1..N, int] + var ar3: array[0..(N+10), float] + echo N + +var f: Foo[3] +f.bindStaticN + +# case 2 + +type + ObjectWithStatic[X, Y: static[int], T] = object + bar: array[X * Y, T] # this one works + + AliasWithStatic[X, Y: static[int], T] = array[X * Y, T] + +var + x: ObjectWithStatic[1, 2, int] + y: AliasWithStatic[2, 3, int] + +# case 3 + +type + Bar[N: static[int], T] = object + bar: array[N, T] + +proc `[]`*[N, T](f: Bar[N, T], n: range[0..(N - 1)]): T = + assert high(n) == N-1 + result = f.bar[n] + +var b: Bar[3, int] +echo b[2] + From 595a8b628f48dfd29facf4d329d32ea5e7c6d9e7 Mon Sep 17 00:00:00 2001 From: Varriount Date: Tue, 30 Dec 2014 19:45:06 -0500 Subject: [PATCH 019/850] Update nim.ini Fix documentation location --- compiler/nim.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/nim.ini b/compiler/nim.ini index 576b6d2bb3..1f14eb21b2 100644 --- a/compiler/nim.ini +++ b/compiler/nim.ini @@ -125,7 +125,7 @@ Files: "start.bat" BinPath: r"bin;dist\mingw\bin;dist" ; Section | dir | zipFile | size hint (in KB) | url | exe start menu entry -Download: r"Documentation|doc|docs.zip|13824|http://nim-lang.org/download/docs-${version}.zip|doc\overview.html" +Download: r"Documentation|doc|docs.zip|13824|http://nim-lang.org/download/docs-${version}.zip|overview.html" Download: r"C Compiler (MingW)|dist|mingw.zip|82944|http://nim-lang.org/download/${mingw}.zip" Download: r"Aporia IDE|dist|aporia.zip|97997|http://nim-lang.org/download/aporia-0.1.3.zip|aporia\bin\aporia.exe" ; for now only NSIS supports optional downloads From 13b72ed0c025f540ac676dd229b781eb4ddee713 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 31 Dec 2014 01:55:02 +0100 Subject: [PATCH 020/850] attempt to make koch smarter about windows installers --- koch.nim | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/koch.nim b/koch.nim index 79228c1a45..e3831617c6 100644 --- a/koch.nim +++ b/koch.nim @@ -94,16 +94,16 @@ const compileNimInst = "-d:useLibzipSrc tools/niminst/niminst" proc csource(args: string) = - exec("$4 cc $1 -r $3 --var:version=$2 --var:mingw=mingw32 csource compiler/nim.ini $1" % + exec("$4 cc $1 -r $3 --var:version=$2 --var:mingw=none csource compiler/nim.ini $1" % [args, VersionAsString, compileNimInst, findNim()]) proc zip(args: string) = - exec("$3 cc -r $2 --var:version=$1 --var:mingw=mingw32 scripts compiler/nim.ini" % + exec("$3 cc -r $2 --var:version=$1 --var:mingw=none scripts compiler/nim.ini" % [VersionAsString, compileNimInst, findNim()]) - exec("$# --var:version=$# --var:mingw=mingw32 zip compiler/nim.ini" % + exec("$# --var:version=$# --var:mingw=none zip compiler/nim.ini" % ["tools/niminst/niminst".exe, VersionAsString]) - -proc buildTool(toolname, args: string) = + +proc buildTool(toolname, args: string) = exec("$# cc $# $#" % [findNim(), args, toolname]) copyFile(dest="bin"/ splitFile(toolname).name.exe, source=toolname.exe) @@ -114,11 +114,11 @@ proc nsis(args: string) = # produce 'nimrod_debug.exe': exec "nim c compiler" / "nim.nim" copyExe("compiler/nim".exe, "bin/nim_debug".exe) - exec(("tools" / "niminst" / "niminst --var:version=$# --var:mingw=mingw32" & - " nsis compiler/nim") % VersionAsString) + exec(("tools" / "niminst" / "niminst --var:version=$# --var:mingw=mingw$#" & + " nsis compiler/nim") % [VersionAsString, $(sizeof(pointer)*8)]) proc install(args: string) = - exec("$# cc -r $# --var:version=$# --var:mingw=mingw32 scripts compiler/nim.ini" % + exec("$# cc -r $# --var:version=$# --var:mingw=none scripts compiler/nim.ini" % [findNim(), compileNimInst, VersionAsString]) exec("sh ./install.sh $#" % args) From 1b54c55b7b41f638b47a1222036ece208b99cbd3 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Wed, 31 Dec 2014 03:46:53 +0200 Subject: [PATCH 021/850] prettier type name printing for generic types featuring static parameters --- compiler/types.nim | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/compiler/types.nim b/compiler/types.nim index f67cd239e9..4a77773e6f 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -17,7 +17,7 @@ proc lastOrd*(t: PType): BiggestInt proc lengthOrd*(t: PType): BiggestInt type TPreferedDesc* = enum - preferName, preferDesc, preferExported, preferModuleInfo + preferName, preferDesc, preferExported, preferModuleInfo, preferGenericArg proc typeToString*(typ: PType; prefer: TPreferedDesc = preferName): string proc base*(t: PType): PType @@ -411,11 +411,13 @@ const "UserTypeClassInst", "CompositeTypeClass", "and", "or", "not", "any", "static", "TypeFromExpr", "FieldAccessor"] +const preferToResolveSymbols = {preferName, preferModuleInfo, preferGenericArg} + proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = var t = typ result = "" if t == nil: return - if prefer in {preferName, preferModuleInfo} and t.sym != nil and + if prefer in preferToResolveSymbols and t.sym != nil and sfAnon notin t.sym.flags: if t.kind == tyInt and isIntLit(t): return t.sym.name.s & " literal(" & $t.n.intVal & ")" @@ -428,20 +430,26 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = if not isIntLit(t) or prefer == preferExported: result = typeToStr[t.kind] else: - result = "int literal(" & $t.n.intVal & ")" + if prefer == preferGenericArg: + result = $t.n.intVal + else: + result = "int literal(" & $t.n.intVal & ")" of tyGenericBody, tyGenericInst, tyGenericInvokation: result = typeToString(t.sons[0]) & '[' for i in countup(1, sonsLen(t) -1 -ord(t.kind != tyGenericInvokation)): if i > 1: add(result, ", ") - add(result, typeToString(t.sons[i])) + add(result, typeToString(t.sons[i], preferGenericArg)) add(result, ']') of tyTypeDesc: if t.base.kind == tyNone: result = "typedesc" else: result = "typedesc[" & typeToString(t.base) & "]" of tyStatic: internalAssert t.len > 0 - result = "static[" & typeToString(t.sons[0]) & "]" - if t.n != nil: result.add "(" & renderTree(t.n) & ")" + if prefer == preferGenericArg and t.n != nil: + result = t.n.renderTree + else: + result = "static[" & typeToString(t.sons[0]) & "]" + if t.n != nil: result.add "(" & renderTree(t.n) & ")" of tyUserTypeClass: internalAssert t.sym != nil and t.sym.owner != nil return t.sym.owner.name.s From b83b1383fb7dc423a812b9a6de64b9155f36d407 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Wed, 31 Dec 2014 03:50:43 +0200 Subject: [PATCH 022/850] fix #1056 --- compiler/semexprs.nim | 4 +++- compiler/semgnrc.nim | 3 ++- tests/generics/t1056.nim | 26 ++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 tests/generics/t1056.nim diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index b2f623fb80..60240e6eb2 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -926,7 +926,8 @@ const proc readTypeParameter(c: PContext, typ: PType, paramName: PIdent, info: TLineInfo): PNode = let ty = if typ.kind == tyGenericInst: typ.skipGenericAlias - else: (internalAssert(typ.kind == tyCompositeTypeClass); typ.sons[1]) + else: (internalAssert(typ.kind == tyCompositeTypeClass); + typ.sons[1].skipGenericAlias) #debug ty let tbody = ty.sons[0] for s in countup(0, tbody.len-2): @@ -965,6 +966,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = var ty = n.sons[0].typ var f: PSym = nil result = nil + if isTypeExpr(n.sons[0]) or (ty.kind == tyTypeDesc and ty.base.kind != tyNone): if ty.kind == tyTypeDesc: ty = ty.base ty = ty.skipTypes(tyDotOpTransparent) diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 06959b8d16..1ab4f5989f 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -72,7 +72,8 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym, result = n styleCheckUse(n.info, s) of skType: - if (s.typ != nil) and (s.typ.kind != tyGenericParam): + if (s.typ != nil) and + (s.typ.flags * {tfGenericTypeParam, tfImplicitTypeParam} == {}): result = newSymNodeTypeDesc(s, n.info) else: result = n diff --git a/tests/generics/t1056.nim b/tests/generics/t1056.nim new file mode 100644 index 0000000000..73a24a76aa --- /dev/null +++ b/tests/generics/t1056.nim @@ -0,0 +1,26 @@ +discard """ + output: '''TMatrix[3, 3, system.int] +3 +3''' +""" + +import typetraits + +type + TMatrix*[N,M: static[int], T] = object + data*: array[0..N*M-1, T] + + TMat2[T] = TMatrix[2,2,T] + +proc echoMatrix(a: TMatrix) = + echo a.type.name + echo TMatrix.N + +proc echoMat2(a: TMat2) = + echo TMat2.M + +var m = TMatrix[3,3,int](data: [1,2,3,4,5,6,7,8,9]) + +echoMatrix m +echoMat2 m + From 13e07f5d667c569355470a56e8a730ca8a1862e5 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Wed, 31 Dec 2014 04:20:32 +0200 Subject: [PATCH 023/850] bugfix: don't treat generic types with different static params as the same type --- compiler/sigmatch.nim | 3 +++ tests/types/tisopr.nim | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index d7bf4fee96..b58818a298 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -979,6 +979,9 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = of tyStatic: if aOrig.kind == tyStatic: result = typeRel(c, f.lastSon, a) + if result != isNone and f.n != nil: + if not exprStructuralEquivalent(f.n, a.n): + result = isNone if result != isNone: put(c.bindings, f, aOrig) else: result = isNone diff --git a/tests/types/tisopr.nim b/tests/types/tisopr.nim index 3c2b9ee5ec..8b7fe4e46c 100644 --- a/tests/types/tisopr.nim +++ b/tests/types/tisopr.nim @@ -34,3 +34,20 @@ type yes s.items is Iter[TNumber] no s.items is Iter[float] +type + Foo[N: static[int], T] = object + field: array[1..N, T] + + Bar[T] = Foo[4, T] + Baz[N: static[int]] = Foo[N, float] + +no Foo[2, float] is Foo[3, float] +no Foo[2, float] is Foo[2, int] + +yes Foo[4, string] is Foo[4, string] +yes Bar[int] is Foo[4, int] +yes Foo[4, int] is Bar[int] + +no Foo[4, int] is Baz[4] +yes Foo[4, float] is Baz[4] + From 2ee24013360649d9ec3749e5dcdce37716900854 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 31 Dec 2014 16:07:56 +0100 Subject: [PATCH 024/850] fixes #1774 --- compiler/nim.nimrod.cfg | 2 -- compiler/semexprs.nim | 2 +- compiler/semstmts.nim | 3 ++- compiler/suggest.nim | 3 --- tests/typerel/typedescs.nim | 7 +++++++ 5 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 tests/typerel/typedescs.nim diff --git a/compiler/nim.nimrod.cfg b/compiler/nim.nimrod.cfg index ba7697c4ce..f4d8b9dcbc 100644 --- a/compiler/nim.nimrod.cfg +++ b/compiler/nim.nimrod.cfg @@ -1,7 +1,5 @@ # Special configuration file for the Nim project -# gc:markAndSweep - hint[XDeclaredButNotUsed]:off path:"llvm" path:"$projectPath/.." diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index b2f623fb80..f718479461 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -985,7 +985,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = of tyTypeParamsHolders: return readTypeParameter(c, ty, i, n.info) of tyObject, tyTuple: - if ty.n.kind == nkRecList: + if ty.n != nil and ty.n.kind == nkRecList: for field in ty.n: if field.sym.name == i: n.typ = newTypeWithSons(c, tyFieldAccessor, @[ty, field.sym.typ]) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index a7603147c5..3b03329396 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -653,7 +653,8 @@ proc checkForMetaFields(n: PNode) = template checkMeta(t) = if t != nil and t.isMetaType and tfGenericTypeParam notin t.flags: localError(n.info, errTIsNotAConcreteType, t.typeToString) - + + if n.isNil: return case n.kind of nkRecList, nkRecCase: for s in n: checkForMetaFields(s) diff --git a/compiler/suggest.nim b/compiler/suggest.nim index c700db323e..f7b00c8f8d 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -74,9 +74,6 @@ proc suggestField(c: PContext, s: PSym, outputs: var int) = suggestWriteln(symToStr(s, isLocal=true, sectionSuggest)) inc outputs -when not defined(nimhygiene): - {.pragma: inject.} - template wholeSymTab(cond, section: expr) {.immediate.} = var isLocal = true for scope in walkScopes(c.currentScope): diff --git a/tests/typerel/typedescs.nim b/tests/typerel/typedescs.nim new file mode 100644 index 0000000000..23b9ce64f6 --- /dev/null +++ b/tests/typerel/typedescs.nim @@ -0,0 +1,7 @@ +# bug #1774 +proc p(T: typedesc) = discard + +p(type((5, 6))) # Compiles +(type((5, 6))).p # Doesn't compile (SIGSEGV: Illegal storage access.) +type T = type((5, 6)) # Doesn't compile (SIGSEGV: Illegal storage access.) + From 99a1530c6c4a2501f0f8305f012e616241545d44 Mon Sep 17 00:00:00 2001 From: Adel Qalieh Date: Wed, 31 Dec 2014 21:41:07 -0500 Subject: [PATCH 025/850] Update tutorial to use RootObj TObject has been deprecated --- doc/tut2.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/tut2.txt b/doc/tut2.txt index 6e239d6816..9d34091647 100644 --- a/doc/tut2.txt +++ b/doc/tut2.txt @@ -56,7 +56,7 @@ Objects have access to their type at runtime. There is an .. code-block:: nim type - TPerson = object of TObject + TPerson = object of RootObj name*: string # the * means that `name` is accessible from other modules age: int # no * means that the field is hidden from other modules @@ -76,10 +76,10 @@ never *equivalent*. New object types can only be defined within a type section. Inheritance is done with the ``object of`` syntax. Multiple inheritance is -currently not supported. If an object type has no suitable ancestor, ``TObject`` +currently not supported. If an object type has no suitable ancestor, ``RootObj`` can be used as its ancestor, but this is only a convention. Objects that have no ancestor are implicitly ``final``. You can use the ``inheritable`` pragma -to introduce new object roots apart from ``system.TObject``. (This is used +to introduce new object roots apart from ``system.RootObj``. (This is used in the GTK wrapper for instance.) @@ -228,7 +228,7 @@ is needed: .. code-block:: nim type - TSocket* = object of TObject + TSocket* = object of RootObj FHost: int # cannot be accessed from the outside of the module # the `F` prefix is a convention to avoid clashes since # the accessors are named `host` @@ -284,7 +284,7 @@ Procedures always use static dispatch. For dynamic dispatch replace the .. code-block:: nim type - PExpr = ref object of TObject ## abstract base class for an expression + PExpr = ref object of RootObj ## abstract base class for an expression PLiteral = ref object of PExpr x: int PPlusExpr = ref object of PExpr @@ -313,7 +313,7 @@ dispatching: .. code-block:: nim type - TThing = object of TObject + TThing = object of RootObj TUnit = object of TThing x: int From d68237177113c6dea7058d5dbdeb94d1eda4824f Mon Sep 17 00:00:00 2001 From: cremno Date: Thu, 1 Jan 2015 15:23:13 +0100 Subject: [PATCH 026/850] fix NSIS uninstaller filename (fix #1804) --- tools/niminst/nsis.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/niminst/nsis.tmpl b/tools/niminst/nsis.tmpl index 40e171d416..23bbf3ac90 100644 --- a/tools/niminst/nsis.tmpl +++ b/tools/niminst/nsis.tmpl @@ -128,7 +128,7 @@ ; Write application registry keys WriteRegStr HKCU "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\bin\?{c.name}.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" - WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninstaller.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\bin\?{c.name}.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" From e2d2203779ed17174542e2ae4b64132cc8a5c7f0 Mon Sep 17 00:00:00 2001 From: Konstantin Molchanov Date: Thu, 1 Jan 2015 21:43:14 +0300 Subject: [PATCH 027/850] Docs: Tutorial 1: Typo fixed. --- doc/tut1.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tut1.txt b/doc/tut1.txt index 46eda7ae37..472017563f 100644 --- a/doc/tut1.txt +++ b/doc/tut1.txt @@ -169,7 +169,7 @@ Numbers Numerical literals are written as in most other languages. As a special twist, underscores are allowed for better readability: ``1_000_000`` (one million). A number that contains a dot (or 'e' or 'E') is a floating point literal: -``1.0e9`` (one million). Hexadecimal literals are prefixed with ``0x``, +``1.0e9`` (one billion). Hexadecimal literals are prefixed with ``0x``, binary literals with ``0b`` and octal literals with ``0o``. A leading zero alone does not produce an octal. From b7187dc4950c244c831711c1cb34593bbc83e869 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 2 Jan 2015 03:21:46 +0100 Subject: [PATCH 028/850] fixed wrong code snippet --- tools/website.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/website.tmpl b/tools/website.tmpl index 6f7a216a56..fed52ac150 100644 --- a/tools/website.tmpl +++ b/tools/website.tmpl @@ -63,7 +63,7 @@ count += 1 echo("Average line length: ", - if count: sum / count else: 0) + if count > 0: sum / count else: 0)
From 194b14a1827e5c812e5a149070ddebc27a2966f2 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 2 Jan 2015 03:32:45 +0100 Subject: [PATCH 029/850] fixes #1816 --- lib/system/channels.nim | 7 ++++--- tests/threads/ttryrecv.nim | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 tests/threads/ttryrecv.nim diff --git a/lib/system/channels.nim b/lib/system/channels.nim index 3e5ca07952..d07d6eae17 100644 --- a/lib/system/channels.nim +++ b/lib/system/channels.nim @@ -232,9 +232,10 @@ proc tryRecv*[TMsg](c: var TChannel[TMsg]): tuple[dataAvailable: bool, ## it returns ``(false, default(msg))``. var q = cast[PRawChannel](addr(c)) if q.mask != ChannelDeadMask: - if tryAcquireSys(q.lock): - llRecv(q, addr(result.msg), cast[PNimType](getTypeInfo(result.msg))) - result.dataAvailable = true + if tryAcquireSys(q.lock): + if q.count > 0: + llRecv(q, addr(result.msg), cast[PNimType](getTypeInfo(result.msg))) + result.dataAvailable = true releaseSys(q.lock) proc peek*[TMsg](c: var TChannel[TMsg]): int = diff --git a/tests/threads/ttryrecv.nim b/tests/threads/ttryrecv.nim new file mode 100644 index 0000000000..acccf182c5 --- /dev/null +++ b/tests/threads/ttryrecv.nim @@ -0,0 +1,35 @@ +discard """ + outputsub: "channel is empty" +""" + +# bug #1816 + +from math import random +from os import sleep + +type PComm = ptr TChannel[int] + +proc doAction(outC: PComm) {.thread.} = + for i in 0.. <5: + sleep(random(100)) + send(outC[], i) + +var + thr: TThread[PComm] + chan: TChannel[int] + +open(chan) +createThread[PComm](thr, doAction, addr(chan)) + +while true: + let (flag, x) = tryRecv(chan) + if flag: + echo("received from chan: " & $x) + else: + echo "channel is empty" + break + +echo "Finished listening" + +joinThread(thr) +close(chan) From d15d9f41110a245b2b5a13bd8a882eeb79311acd Mon Sep 17 00:00:00 2001 From: Joseph Poirier Date: Fri, 2 Jan 2015 03:36:40 -0600 Subject: [PATCH 030/850] clarify single letter option requirements --- doc/basicopt.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/basicopt.txt b/doc/basicopt.txt index ffb374f188..e366b2718e 100644 --- a/doc/basicopt.txt +++ b/doc/basicopt.txt @@ -37,4 +37,4 @@ Options: --advanced show advanced command line switches -h, --help show this help -Note: Even single letter options require the colon: -p:PATH. +Note, single letter options that take an argument require a colon. E.g. -p:PATH. From c9fc300f2df14d2db236689176d11d66b4368242 Mon Sep 17 00:00:00 2001 From: Arthur Liao Date: Fri, 2 Jan 2015 20:20:55 +0800 Subject: [PATCH 031/850] Fix typo --- doc/tut1.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tut1.txt b/doc/tut1.txt index 4c32fa0ae1..324a38b0a3 100644 --- a/doc/tut1.txt +++ b/doc/tut1.txt @@ -1070,7 +1070,7 @@ Operation Comment ``dec(x, n)`` decrements `x` by `n`; `n` is an integer ``succ(x)`` returns the successor of `x` ``succ(x, n)`` returns the `n`'th successor of `x` -``prec(x)`` returns the predecessor of `x` +``pred(x)`` returns the predecessor of `x` ``pred(x, n)`` returns the `n`'th predecessor of `x` ----------------- -------------------------------------------------------- From 66c05e56d8a7d6dfadd8baa85c6d882bb2d670da Mon Sep 17 00:00:00 2001 From: Jochen Kupperschmidt Date: Fri, 2 Jan 2015 13:47:33 +0100 Subject: [PATCH 032/850] Tutorial: Fixed slices example code. This is likely a remainder of the name change from "Nimrod" to "Nim". --- doc/tut1.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tut1.txt b/doc/tut1.txt index 4c32fa0ae1..e961ea11b7 100644 --- a/doc/tut1.txt +++ b/doc/tut1.txt @@ -1323,7 +1323,7 @@ define operators which accept TSlice objects to define ranges. a = "Nim is a progamming language" b = "Slices are useless." - echo a[10..15] # --> 'a prog' + echo a[7..12] # --> 'a prog' b[11.. -2] = "useful" echo b # --> 'Slices are useful.' From 4fff14591481393f6e1cd23b6b730d33d2358774 Mon Sep 17 00:00:00 2001 From: def Date: Fri, 2 Jan 2015 15:16:03 +0100 Subject: [PATCH 033/850] Allow higher versions of libmysqlclient --- lib/wrappers/mysql.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/wrappers/mysql.nim b/lib/wrappers/mysql.nim index 945e09ecf1..5deceb6e2e 100644 --- a/lib/wrappers/mysql.nim +++ b/lib/wrappers/mysql.nim @@ -12,7 +12,7 @@ when defined(Unix): const - lib = "libmysqlclient.so.15" + lib = "libmysqlclient.so.(15|16|17|18)" when defined(Windows): const lib = "libmysql.dll" From e5bfb7d55017a0f205682f34c01ac709dcf82940 Mon Sep 17 00:00:00 2001 From: Audun Wilhelmsen Date: Fri, 2 Jan 2015 22:10:49 +0100 Subject: [PATCH 034/850] Added support for big 'u64 literals Removed duplicate "SomeUInt' typedef from unsigned.nim --- compiler/lexer.nim | 19 +++++++++++++++++++ lib/core/unsigned.nim | 32 +++++++++++++++----------------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/compiler/lexer.nim b/compiler/lexer.nim index a6b85d7f39..459532d12f 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -264,6 +264,19 @@ proc isFloatLiteral(s: string): bool = return true result = false +{.push overflowChecks: off.} +# We need to parse the largest uint literal without overflow checks +proc unsafeParseUInt(s: string, b: var BiggestInt, start = 0): int = + var i = start + if s[i] in {'0'..'9'}: + b = 0 + while s[i] in {'0'..'9'}: + b = b * 10 + (ord(s[i]) - ord('0')) + inc(i) + while s[i] == '_': inc(i) # underscores are allowed and ignored + result = i - start +{.pop.} # overflowChecks + proc getNumber(L: var TLexer): TToken = var pos, endpos: int @@ -425,6 +438,12 @@ proc getNumber(L: var TLexer): TToken = (result.tokType == tkFloat64Lit): result.fNumber = parseFloat(result.literal) if result.tokType == tkIntLit: result.tokType = tkFloatLit + elif result.tokType == tkUint64Lit: + xi = 0 + let len = unsafeParseUInt(result.literal, xi) + if len != result.literal.len or len == 0: + raise newException(ValueError, "invalid integer: " & $xi) + result.iNumber = xi else: result.iNumber = parseBiggestInt(result.literal) if (result.iNumber < low(int32)) or (result.iNumber > high(int32)): diff --git a/lib/core/unsigned.nim b/lib/core/unsigned.nim index 7acdf1439d..20fcd03aa5 100644 --- a/lib/core/unsigned.nim +++ b/lib/core/unsigned.nim @@ -11,49 +11,47 @@ ## To discourage users from using ``unsigned``, it's not part of ``system``, ## but an extra import. -type - SomeUInt = uint|uint8|uint16|uint32|uint64 - -proc `not`*[T: SomeUInt](x: T): T {.magic: "BitnotI", noSideEffect.} +proc `not`*[T: SomeUnsignedInt](x: T): T {.magic: "BitnotI", noSideEffect.} ## computes the `bitwise complement` of the integer `x`. -proc `shr`*[T: SomeUInt](x, y: T): T {.magic: "ShrI", noSideEffect.} +proc `shr`*[T: SomeUnsignedInt](x, y: T): T {.magic: "ShrI", noSideEffect.} ## computes the `shift right` operation of `x` and `y`. -proc `shl`*[T: SomeUInt](x, y: T): T {.magic: "ShlI", noSideEffect.} +proc `shl`*[T: SomeUnsignedInt](x, y: T): T {.magic: "ShlI", noSideEffect.} ## computes the `shift left` operation of `x` and `y`. -proc `and`*[T: SomeUInt](x, y: T): T {.magic: "BitandI", noSideEffect.} +proc `and`*[T: SomeUnsignedInt](x, y: T): T {.magic: "BitandI", noSideEffect.} ## computes the `bitwise and` of numbers `x` and `y`. -proc `or`*[T: SomeUInt](x, y: T): T {.magic: "BitorI", noSideEffect.} +proc `or`*[T: SomeUnsignedInt](x, y: T): T {.magic: "BitorI", noSideEffect.} ## computes the `bitwise or` of numbers `x` and `y`. -proc `xor`*[T: SomeUInt](x, y: T): T {.magic: "BitxorI", noSideEffect.} +proc `xor`*[T: SomeUnsignedInt](x, y: T): T {.magic: "BitxorI", noSideEffect.} ## computes the `bitwise xor` of numbers `x` and `y`. -proc `==`*[T: SomeUInt](x, y: T): bool {.magic: "EqI", noSideEffect.} +proc `==`*[T: SomeUnsignedInt](x, y: T): bool {.magic: "EqI", noSideEffect.} ## Compares two unsigned integers for equality. -proc `+`*[T: SomeUInt](x, y: T): T {.magic: "AddU", noSideEffect.} +proc `+`*[T: SomeUnsignedInt](x, y: T): T {.magic: "AddU", noSideEffect.} ## Binary `+` operator for unsigned integers. -proc `-`*[T: SomeUInt](x, y: T): T {.magic: "SubU", noSideEffect.} +proc `-`*[T: SomeUnsignedInt](x, y: T): T {.magic: "SubU", noSideEffect.} ## Binary `-` operator for unsigned integers. -proc `*`*[T: SomeUInt](x, y: T): T {.magic: "MulU", noSideEffect.} +proc `*`*[T: SomeUnsignedInt](x, y: T): T {.magic: "MulU", noSideEffect.} ## Binary `*` operator for unsigned integers. -proc `div`*[T: SomeUInt](x, y: T): T {.magic: "DivU", noSideEffect.} +proc `div`*[T: SomeUnsignedInt](x, y: T): T {.magic: "DivU", noSideEffect.} ## computes the integer division. This is roughly the same as ## ``floor(x/y)``. -proc `mod`*[T: SomeUInt](x, y: T): T {.magic: "ModU", noSideEffect.} +proc `mod`*[T: SomeUnsignedInt](x, y: T): T {.magic: "ModU", noSideEffect.} ## computes the integer modulo operation. This is the same as ## ``x - (x div y) * y``. -proc `<=`*[T: SomeUInt](x, y: T): bool {.magic: "LeU", noSideEffect.} +proc `<=`*[T: SomeUnsignedInt](x, y: T): bool {.magic: "LeU", noSideEffect.} ## Returns true iff ``x <= y``. -proc `<`*[T: SomeUInt](x, y: T): bool {.magic: "LtU", noSideEffect.} +proc `<`*[T: SomeUnsignedInt](x, y: T): bool {.magic: "LtU", noSideEffect.} ## Returns true iff ``unsigned(x) < unsigned(y)``. + From ad65a2039177b706d6dc5d3c0c7657da9e202a23 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Wed, 31 Dec 2014 12:31:02 +0200 Subject: [PATCH 035/850] fix #419 --- compiler/sigmatch.nim | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index b58818a298..6d6e26b2d6 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -109,9 +109,12 @@ proc initCandidate*(ctx: PContext, c: var TCandidate, callee: PSym, for i in 1..min(sonsLen(typeParams), sonsLen(binding)-1): var formalTypeParam = typeParams.sons[i-1].typ var bound = binding[i].typ - if bound != nil and formalTypeParam.kind != tyTypeDesc: + internalAssert bound != nil + if formalTypeParam.kind == tyTypeDesc: + if bound.kind != tyTypeDesc: + bound = makeTypeDesc(ctx, bound) + else: bound = bound.skipTypes({tyTypeDesc}) - assert bound != nil put(c.bindings, formalTypeParam, bound) proc newCandidate*(ctx: PContext, callee: PSym, From 1d55fd8d1249acacb07ffcf85e307cb80d5d4e5d Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Wed, 31 Dec 2014 12:56:55 +0200 Subject: [PATCH 036/850] use unix line endings --- tests/misc/tvarious.nim | 86 ++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/tests/misc/tvarious.nim b/tests/misc/tvarious.nim index 434d25e483..0daa019a9c 100644 --- a/tests/misc/tvarious.nim +++ b/tests/misc/tvarious.nim @@ -1,54 +1,54 @@ -# Test various aspects +# Test various aspects # bug #572 var a=12345678901'u64 - + var x = (x: 42, y: (a: 8, z: 10)) echo x.y - -import - mvarious - -type - PA = ref TA - PB = ref TB - - TB = object - a: PA - - TA = object - b: TB - x: int - -proc getPA(): PA = - var - b: bool - b = not false - return nil + +import + mvarious + +type + PA = ref TA + PB = ref TB + + TB = object + a: PA + + TA = object + b: TB + x: int + +proc getPA(): PA = + var + b: bool + b = not false + return nil # bug #501 proc f(): int = 54 - -var - global: int - -var - s: string - i: int - r: TA - -r.b.a.x = 0 -global = global + 1 -exportme() -write(stdout, "Hallo wie heißt du? ") -write(stdout, getPA().x) -s = readLine(stdin) -i = 0 -while i < s.len: - if s[i] == 'c': write(stdout, "'c' in deinem Namen gefunden\n") - i = i + 1 - -write(stdout, "Du heißt " & s) + +var + global: int + +var + s: string + i: int + r: TA + +r.b.a.x = 0 +global = global + 1 +exportme() +write(stdout, "Hallo wie heißt du? ") +write(stdout, getPA().x) +s = readLine(stdin) +i = 0 +while i < s.len: + if s[i] == 'c': write(stdout, "'c' in deinem Namen gefunden\n") + i = i + 1 + +write(stdout, "Du heißt " & s) # bug #544 when false: From 70b5efa98de87bd7684b7258cb95fb2b9892b6df Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Wed, 31 Dec 2014 12:58:22 +0200 Subject: [PATCH 037/850] fix #544 --- compiler/sigmatch.nim | 3 ++- tests/misc/tvarious.nim | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 6d6e26b2d6..8fea81bee6 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -629,6 +629,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = elif skipTypes(a, {tyRange}).kind == f.kind: result = isSubtype of tyRange: if a.kind == f.kind: + if f.base.kind == tyNone: return isGeneric result = typeRel(c, base(f), base(a)) # bugfix: accept integer conversions here #if result < isGeneric: result = isNone @@ -948,7 +949,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = else: internalAssert a.sons != nil and a.sons.len > 0 c.typedescMatched = true - result = typeRel(c, f.base, a.base) + result = typeRel(c, f.base, a.skipTypes({tyGenericParam, tyTypeDesc})) else: result = isNone else: diff --git a/tests/misc/tvarious.nim b/tests/misc/tvarious.nim index 0daa019a9c..8124b3fc70 100644 --- a/tests/misc/tvarious.nim +++ b/tests/misc/tvarious.nim @@ -51,17 +51,17 @@ while i < s.len: write(stdout, "Du heißt " & s) # bug #544 -when false: - # yay, fails again - type Bar [T; I:range] = array[I, T] - proc foo*[T; I:range](a, b: Bar[T, I]): Bar[T, I] = - when len(a) != 3: - # Error: constant expression expected - {.fatal:"Dimensions have to be 3".} - #... - block: - var a, b: Bar[int, 0..2] - discard foo(a, b) + +# yay, fails again +type Bar [T; I:range] = array[I, T] +proc foo*[T; I:range](a, b: Bar[T, I]): Bar[T, I] = + when len(a) != 3: + # Error: constant expression expected + {.fatal:"Dimensions have to be 3".} + #... +block: + var a, b: Bar[int, range[0..2]] + discard foo(a, b) # bug #1788 From b21b72dc14e389cb2d31646dc25a5ae0808a43a1 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Fri, 2 Jan 2015 17:51:08 +0200 Subject: [PATCH 038/850] fix #1049 --- compiler/semdata.nim | 2 +- compiler/sigmatch.nim | 47 ++++++++++++++++++-------------- tests/metatype/tstaticparams.nim | 18 ++++++++++++ 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/compiler/semdata.nim b/compiler/semdata.nim index f876770c09..623f9b6339 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -268,7 +268,7 @@ proc makeRangeWithStaticExpr*(c: PContext, n: PNode): PType = template rangeHasStaticIf*(t: PType): bool = # this accepts the ranges's node - t.n[1].kind == nkStaticExpr + t.n != nil and t.n.len > 1 and t.n[1].kind == nkStaticExpr template getStaticTypeFromRange*(t: PType): PType = t.n[1][0][1].typ diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 8fea81bee6..ff90bde697 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -676,22 +676,27 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = else: fRange = prev result = typeRel(c, f.sons[1], a.sons[1]) - if result < isGeneric: - result = isNone - elif tfUnresolved in fRange.flags and - rangeHasStaticIf(fRange): - # This is a range from an array instantiated with a generic - # static param. We must extract the static param here and bind - # it to the size of the currently supplied array. - var - rangeStaticT = fRange.getStaticTypeFromRange - replacementT = newTypeWithSons(c.c, tyStatic, @[tyInt.getSysType]) - inputUpperBound = a.sons[0].n[1].intVal - # we must correct for the off-by-one discrepancy between - # ranges and static params: - replacementT.n = newIntNode(nkIntLit, inputUpperBound + 1) - put(c.bindings, rangeStaticT, replacementT) - result = isGeneric + if result < isGeneric: return isNone + if rangeHasStaticIf(fRange): + if tfUnresolved in fRange.flags: + # This is a range from an array instantiated with a generic + # static param. We must extract the static param here and bind + # it to the size of the currently supplied array. + var + rangeStaticT = fRange.getStaticTypeFromRange + replacementT = newTypeWithSons(c.c, tyStatic, @[tyInt.getSysType]) + inputUpperBound = a.sons[0].n[1].intVal + # we must correct for the off-by-one discrepancy between + # ranges and static params: + replacementT.n = newIntNode(nkIntLit, inputUpperBound + 1) + put(c.bindings, rangeStaticT, replacementT) + return isGeneric + + let len = tryResolvingStaticExpr(c, fRange.n[1]) + if len.kind == nkIntLit and len.intVal+1 == lengthOrd(a): + return # if we get this far, the result is already good + else: + return isNone elif lengthOrd(fRange) != lengthOrd(a): result = isNone else: discard @@ -1049,10 +1054,10 @@ proc cmpTypes*(c: PContext, f, a: PType): TTypeRelation = initCandidate(c, m, f) result = typeRel(m, f, a) -proc getInstantiatedType(c: PContext, arg: PNode, m: TCandidate, - f: PType): PType = +proc getInstantiatedType(c: PContext, arg: PNode, m: TCandidate, + f: PType): PType = result = PType(idTableGet(m.bindings, f)) - if result == nil: + if result == nil: result = generateTypeInstance(c, m.bindings, arg, f) if result == nil: internalError(arg.info, "getInstantiatedType") @@ -1134,7 +1139,7 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType, arg = argSemantized argType = argType c = m.c - + if tfHasStatic in fMaybeStatic.flags: # XXX: When implicit statics are the default # this will be done earlier - we just have to @@ -1148,7 +1153,7 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType, return argSemantized if argType.kind == tyStatic: - if m.callee.kind == tyGenericBody: + if m.callee.kind == tyGenericBody and tfGenericTypeParam notin argType.flags: result = newNodeI(nkType, argOrig.info) result.typ = makeTypeFromExpr(c, arg) return diff --git a/tests/metatype/tstaticparams.nim b/tests/metatype/tstaticparams.nim index 6d7c569e06..b34eaa2112 100644 --- a/tests/metatype/tstaticparams.nim +++ b/tests/metatype/tstaticparams.nim @@ -56,3 +56,21 @@ type TTestSub[N: static[int]] = TTest[1, N] var z: TTestSub[2] echo z.high + +# issue 1049 +proc matrix_1*[M, N, T](mat: Matrix[M,N,T], a: array[N, int]) = discard +proc matrix_2*[M, N, T](mat: Matrix[M,N,T], a: array[N+1, int]) = discard + +proc matrix_3*[M, N: static[int]; T](mat: Matrix[M,N,T], a: array[N, int]) = discard +proc matrix_4*[M, N: static[int]; T](mat: Matrix[M,N,T], a: array[N+1, int]) = discard + +var + tmat: TMatrix[4,4,int] + ar1: array[4, int] + ar2: array[5, int] + +matrix_1(tmat, ar1) +matrix_2(tmat, ar2) +matrix_3(tmat, ar1) +matrix_4(tmat, ar2) + From 5b32fb1791899a86afbb19a0c4e8d0ded0c362eb Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Fri, 2 Jan 2015 17:51:52 +0200 Subject: [PATCH 039/850] re-enable semistatic[T] as a test case --- tests/metatype/tsemistatic.nim | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/metatype/tsemistatic.nim b/tests/metatype/tsemistatic.nim index 0a003be03f..a13175ba88 100644 --- a/tests/metatype/tsemistatic.nim +++ b/tests/metatype/tsemistatic.nim @@ -1,9 +1,15 @@ discard """ msg: "static 10\ndynamic\nstatic 20\n" output: "s\nd\nd\ns" - disabled: "true" """ +type + semistatic[T] = + static[T] or T + +template isStatic*(x): expr = + compiles(static(x)) + proc foo(x: semistatic[int]) = when isStatic(x): static: echo "static ", x From aa69a8a09f990f485e4ae7058b15067c70e70e28 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Fri, 2 Jan 2015 19:00:08 +0200 Subject: [PATCH 040/850] expand the test case for bug 1049 --- compiler/semtypes.nim | 3 +-- tests/metatype/tstaticparams.nim | 11 ++++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index eb15c3809c..14ab7e6ba7 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -225,11 +225,10 @@ proc semArrayIndex(c: PContext, n: PNode): PType = elif e.kind == nkSym and e.typ.kind == tyStatic: if e.sym.ast != nil: return semArrayIndex(c, e.sym.ast) - internalAssert c.inGenericContext > 0 if not isOrdinalType(e.typ.lastSon): localError(n[1].info, errOrdinalTypeExpected) result = makeRangeWithStaticExpr(c, e) - result.flags.incl tfUnresolved + if c.inGenericContext >0: result.flags.incl tfUnresolved elif e.kind in nkCallKinds and hasGenericArguments(e): if not isOrdinalType(e.typ): localError(n[1].info, errOrdinalTypeExpected) diff --git a/tests/metatype/tstaticparams.nim b/tests/metatype/tstaticparams.nim index b34eaa2112..e53e478f0a 100644 --- a/tests/metatype/tstaticparams.nim +++ b/tests/metatype/tstaticparams.nim @@ -65,7 +65,7 @@ proc matrix_3*[M, N: static[int]; T](mat: Matrix[M,N,T], a: array[N, int]) = dis proc matrix_4*[M, N: static[int]; T](mat: Matrix[M,N,T], a: array[N+1, int]) = discard var - tmat: TMatrix[4,4,int] + tmat: Matrix[4,4,int] ar1: array[4, int] ar2: array[5, int] @@ -74,3 +74,12 @@ matrix_2(tmat, ar2) matrix_3(tmat, ar1) matrix_4(tmat, ar2) +template reject(x): stmt = + static: assert(not compiles(x)) + +# test with arrays of wrong size +reject matrix_1(tmat, ar2) +reject matrix_2(tmat, ar1) +reject matrix_3(tmat, ar2) +reject matrix_4(tmat, ar1) + From 1d5ecc0deac508e7ebb3bf9df01aa34d5025d83d Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Fri, 2 Jan 2015 19:19:18 +0200 Subject: [PATCH 041/850] fix #1050 --- compiler/semexprs.nim | 4 +--- tests/generics/t1050.nim | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 tests/generics/t1050.nim diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 89110a4791..68921a15ad 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -229,7 +229,7 @@ proc semConv(c: PContext, n: PNode): PNode = return n result = newNodeI(nkConv, n.info) - var targetType = semTypeNode(c, n.sons[0], nil) + var targetType = semTypeNode(c, n.sons[0], nil).skipTypes({tyTypeDesc}) maybeLiftType(targetType, c, n[0].info) result.addSon copyTree(n.sons[0]) var op = semExprWithType(c, n.sons[1]) @@ -780,7 +780,6 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = if tfNoSideEffect notin t.flags: incl(c.p.owner.flags, sfSideEffect) elif t != nil and t.kind == tyTypeDesc: if n.len == 1: return semObjConstr(c, n, flags) - let destType = t.skipTypes({tyTypeDesc, tyGenericInst}) return semConv(c, n) else: result = overloadedCallOpr(c, n) @@ -928,7 +927,6 @@ proc readTypeParameter(c: PContext, typ: PType, let ty = if typ.kind == tyGenericInst: typ.skipGenericAlias else: (internalAssert(typ.kind == tyCompositeTypeClass); typ.sons[1].skipGenericAlias) - #debug ty let tbody = ty.sons[0] for s in countup(0, tbody.len-2): let tParam = tbody.sons[s] diff --git a/tests/generics/t1050.nim b/tests/generics/t1050.nim new file mode 100644 index 0000000000..a6f9a2482d --- /dev/null +++ b/tests/generics/t1050.nim @@ -0,0 +1,16 @@ +discard """ + msg: "int" + output: "4" +""" + +import typetraits + +type ArrayType[T] = distinct T + +proc arrayItem(a: ArrayType): auto = + static: echo(name(type(a).T)) + result = (type(a).T)(4) + +var arr: ArrayType[int] +echo arrayItem(arr) + From 2f90be13e2be9224c2760b98f6949bdfafc7992a Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Fri, 2 Jan 2015 21:25:16 +0200 Subject: [PATCH 042/850] fix #1820 --- compiler/sigmatch.nim | 2 +- tests/metatype/tstaticparams.nim | 38 +++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index ff90bde697..ce7af1dabe 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -989,7 +989,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = if aOrig.kind == tyStatic: result = typeRel(c, f.lastSon, a) if result != isNone and f.n != nil: - if not exprStructuralEquivalent(f.n, a.n): + if not exprStructuralEquivalent(f.n, aOrig.n): result = isNone if result != isNone: put(c.bindings, f, aOrig) else: diff --git a/tests/metatype/tstaticparams.nim b/tests/metatype/tstaticparams.nim index e53e478f0a..e98a2871f5 100644 --- a/tests/metatype/tstaticparams.nim +++ b/tests/metatype/tstaticparams.nim @@ -1,6 +1,6 @@ discard """ file: "tstaticparams.nim" - output: "abracadabra\ntest\n3\n15\n4\n2" + output: "abracadabra\ntest\n3\n15\n4\n2\nfloat\n3\nfloat\nyin\nyang" """ type @@ -83,3 +83,39 @@ reject matrix_2(tmat, ar1) reject matrix_3(tmat, ar2) reject matrix_4(tmat, ar1) +# bug 1820 + +type + T1820_1[T; Y: static[int]] = object + bar: T + +proc intOrFloat*[Y](f: T1820_1[int, Y]) = echo "int" +proc intOrFloat*[Y](f: T1820_1[float, Y]) = echo "float" +proc threeOrFour*[T](f: T1820_1[T, 3]) = echo "3" +proc threeOrFour*[T](f: T1820_1[T, 4]) = echo "4" + +var foo_1: T1820_1[float, 3] + +foo_1.intOrFloat +foo_1.threeOrFour + +type + YinAndYang = enum + Yin, + Yang + + T1820_2[T; Y: static[YinAndYang]] = object + bar: T + +proc intOrFloat*[Y](f: T1820_2[int, Y]) = echo "int" +proc intOrFloat*[Y](f: T1820_2[float, Y]) = echo "float" +proc yinOrYang*[T](f: T1820_2[T, YinAndYang.Yin]) = echo "yin" +proc yinOrYang*[T](f: T1820_2[T, Yang]) = echo "yang" + +var foo_2: T1820_2[float, Yin] +var foo_3: T1820_2[float, YinAndYang.Yang] + +foo_2.intOrFloat +foo_2.yinOrYang +foo_3.yinOrYang + From 05cbbac4e56b07b902b21f1e9a3f270f450b5d04 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Fri, 2 Jan 2015 23:57:55 +0200 Subject: [PATCH 043/850] support for static params in the user defined type classes --- compiler/ast.nim | 1 + compiler/semcall.nim | 16 ++++++-------- compiler/semstmts.nim | 12 ++++++---- compiler/semtypes.nim | 8 ++++--- compiler/sigmatch.nim | 34 ++++++++++++++++++++++------- tests/metatype/tusertypeclasses.nim | 27 ++++++++++++++++++++++- 6 files changed, 73 insertions(+), 25 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index d85dbf42c4..883b68d71d 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -399,6 +399,7 @@ const tyPureObject* = tyTuple GcTypeKinds* = {tyRef, tySequence, tyString} tyError* = tyProxy # as an errornous node should match everything + tyUnknown* = tyFromExpr tyUnknownTypes* = {tyError, tyFromExpr} diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 3971b8ff59..a712cc195e 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -277,16 +277,14 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode = styleCheckUse(n.sons[0].info, finalCallee) if finalCallee.ast == nil: internalError(n.info, "calleeSym.ast is nil") # XXX: remove this check! + if x.hasFauxMatch: + result = x.call + result.sons[0] = newSymNode(finalCallee, result.sons[0].info) + if containsGenericType(result.typ) or x.fauxMatch == tyUnknown: + result.typ = newTypeS(x.fauxMatch, c) + return if finalCallee.ast.sons[genericParamsPos].kind != nkEmpty: - # a generic proc! - if not x.proxyMatch: - finalCallee = generateInstance(c, x.calleeSym, x.bindings, n.info) - else: - result = x.call - result.sons[0] = newSymNode(finalCallee, result.sons[0].info) - result.typ = finalCallee.typ.sons[0] - if containsGenericType(result.typ): result.typ = errorType(c) - return + finalCallee = generateInstance(c, x.calleeSym, x.bindings, n.info) result = x.call instGenericConvertersSons(c, result, x) result.sons[0] = newSymNode(finalCallee, result.sons[0].info) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 3b03329396..1396ef3747 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1262,10 +1262,14 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = return else: n.sons[i] = semExpr(c, n.sons[i]) - if c.inTypeClass > 0 and n[i].typ != nil and n[i].typ.kind == tyBool: - let verdict = semConstExpr(c, n[i]) - if verdict.intVal == 0: - localError(result.info, "type class predicate failed") + if c.inTypeClass > 0 and n[i].typ != nil: + case n[i].typ.kind + of tyBool: + let verdict = semConstExpr(c, n[i]) + if verdict.intVal == 0: + localError(result.info, "type class predicate failed") + of tyUnknown: continue + else: discard if n.sons[i].typ == enforceVoidContext or usesResult(n.sons[i]): voidContext = true n.typ = enforceVoidContext diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 14ab7e6ba7..deb4b12887 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -781,10 +781,12 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, of tyGenericBody: result = newTypeS(tyGenericInvokation, c) result.rawAddSon(paramType) + for i in 0 .. paramType.sonsLen - 2: - result.rawAddSon newTypeS(tyAnything, c) - # result.rawAddSon(copyType(paramType.sons[i], getCurrOwner(), true)) - + let dummyType = if paramType.sons[i].kind == tyStatic: tyUnknown + else: tyAnything + result.rawAddSon newTypeS(dummyType, c) + if paramType.lastSon.kind == tyUserTypeClass: result.kind = tyUserTypeClassInst result.rawAddSon paramType.lastSon diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index ce7af1dabe..0182cb5554 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -39,7 +39,9 @@ type bindings*: TIdTable # maps types to types baseTypeMatch: bool # needed for conversions from T to openarray[T] # for example - proxyMatch*: bool # to prevent instantiations + fauxMatch*: TTypeKind # the match was successful only due to the use + # of error or wildcard (unknown) types. + # this is used to prevent instantiations. genericConverter*: bool # true if a generic converter needs to # be instantiated coerceDistincts*: bool # this is an explicit coercion that can strip away @@ -66,6 +68,8 @@ const proc markUsed*(info: TLineInfo, s: PSym) +template hasFauxMatch*(c: TCandidate): bool = c.fauxMatch != tyNone + proc initCandidateAux(ctx: PContext, c: var TCandidate, callee: PType) {.inline.} = c.c = ctx @@ -465,9 +469,23 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate, var typeParamName = ff.base.sons[i-1].sym.name typ = ff.sons[i] - param = newSym(skType, typeParamName, body.sym, body.sym.info) - - param.typ = makeTypeDesc(c, typ) + param: PSym + + template paramSym(kind): expr = + newSym(kind, typeParamName, body.sym, body.sym.info) + + case typ.kind + of tyStatic: + param = paramSym skConst + param.typ = typ.base + param.ast = typ.n + of tyUnknown: + param = paramSym skVar + param.typ = typ + else: + param = paramSym skType + param.typ = makeTypeDesc(c, typ) + addDecl(c, param) for param in body.n[0]: @@ -1067,7 +1085,7 @@ proc implicitConv(kind: TNodeKind, f: PType, arg: PNode, m: TCandidate, c: PContext): PNode = result = newNodeI(kind, arg.info) if containsGenericType(f): - if not m.proxyMatch: + if not m.hasFauxMatch: result.typ = getInstantiatedType(c, arg, m, f) else: result.typ = errorType(c) @@ -1139,7 +1157,7 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType, arg = argSemantized argType = argType c = m.c - + if tfHasStatic in fMaybeStatic.flags: # XXX: When implicit statics are the default # this will be done earlier - we just have to @@ -1246,9 +1264,9 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType, result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c) of isNone: # do not do this in ``typeRel`` as it then can't infere T in ``ref T``: - if a.kind == tyProxy: + if a.kind in {tyProxy, tyUnknown}: inc(m.genericMatches) - m.proxyMatch = true + m.fauxMatch = a.kind return copyTree(arg) result = userConvMatch(c, m, f, a, arg) # check for a base type match, which supports varargs[T] without [] diff --git a/tests/metatype/tusertypeclasses.nim b/tests/metatype/tusertypeclasses.nim index 6e9e4934bb..4e5e6221c9 100644 --- a/tests/metatype/tusertypeclasses.nim +++ b/tests/metatype/tusertypeclasses.nim @@ -1,5 +1,13 @@ discard """ - output: "Sortable\nSortable\nContainer" + output: '''Sortable +Sortable +Container +true +true +false +false +false +''' """ import typetraits @@ -41,3 +49,20 @@ proc y(x: TObj): int = 10 proc testFoo(x: TFoo) = discard testFoo(TObj(x: 10)) +type + Matrix[Rows, Cols: static[int]; T] = generic M + M.M == Rows + M.N == Cols + M.T is T + + MyMatrix[M, N: static[int]; T] = object + data: array[M*N, T] + +var x: MyMatrix[3, 3, int] + +echo x is Matrix +echo x is Matrix[3, 3, int] +echo x is Matrix[3, 3, float] +echo x is Matrix[4, 3, int] +echo x is Matrix[3, 4, int] + From 0a82b6eb628a5ec4dc4aadc1fb120067845f8443 Mon Sep 17 00:00:00 2001 From: def Date: Fri, 2 Jan 2015 23:52:46 +0100 Subject: [PATCH 044/850] Add reversed proc to unicode module --- lib/pure/unicode.nim | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim index c2eb001f6a..306509d26e 100644 --- a/lib/pure/unicode.nim +++ b/lib/pure/unicode.nim @@ -1102,6 +1102,13 @@ const 0x01f1, 501, # 0x01f3, 499] # + combiningRanges = [ + 0x0300, 0x036f, + 0x1ab0, 0x1aff, + 0x1dc0, 0x1dff, + 0x20d0, 0x20ff, + 0xfe20, 0xfe2f] + proc binarySearch(c: RuneImpl, tab: openArray[RuneImpl], len, stride: int): int = var n = len var t = 0 @@ -1194,6 +1201,13 @@ proc isWhiteSpace*(c: Rune): bool {.rtl, extern: "nuc$1", procvar.} = if p >= 0 and c >= spaceRanges[p] and c <= spaceRanges[p+1]: return true +proc isCombining*(c: Rune): bool {.rtl, extern: "nuc$1", procvar.} = + ## returns true iff `c` is a Unicode combining character + var c = RuneImpl(c) + var p = binarySearch(c, combiningRanges, len(combiningRanges) div 2, 2) + if p >= 0 and c >= combiningRanges[p] and c <= combiningRanges[p+1]: + return true + iterator runes*(s: string): Rune = ## iterates over any unicode character of the string `s`. var @@ -1220,9 +1234,33 @@ proc cmpRunesIgnoreCase*(a, b: string): int {.rtl, extern: "nuc$1", procvar.} = if result != 0: return result = a.len - b.len +proc reversed*(s: string): string = + ## returns the reverse of `s`, interpreting it as unicode characters. Unicode + ## combining characters are correctly interpreted as well: + ## + ## .. code-block: + ## assert reversed("Reverse this!") == "!siht esreveR" + ## assert reversed("先秦兩漢") == "漢兩秦先" + ## assert reversed("as⃝df̅") == "f̅ds⃝a" + ## assert reversed("a⃞b⃞c⃞") == "c⃞b⃞a⃞" + result = newStringOfCap(len(s)) + var tmp: seq[Rune] = @[] + for r in runes(s): + if isCombining(r): + tmp.insert(r, high(tmp)) + else: + tmp.add(r) + for i in countdown(high(tmp), 0): + result.add(toUTF8(tmp[i])) + when isMainModule: let someString = "öÑ" someRunes = @[runeAt(someString, 0), runeAt(someString, 2)] compared = (someString == $someRunes) assert compared == true + + assert reversed("Reverse this!") == "!siht esreveR" + assert reversed("先秦兩漢") == "漢兩秦先" + assert reversed("as⃝df̅") == "f̅ds⃝a" + assert reversed("a⃞b⃞c⃞") == "c⃞b⃞a⃞" From 7592c9cf22524332ef4b60bf050c046254685e9f Mon Sep 17 00:00:00 2001 From: Audun Wilhelmsen Date: Sat, 3 Jan 2015 00:10:07 +0100 Subject: [PATCH 045/850] Added safe implicit conversion of uint8 to int16..int64, uint16 to int32..int64 etc. Added two new tests for unsigned conversions and comparisons between signed numbers. --- compiler/sigmatch.nim | 26 +++---- tests/misc/tunsignedcomp.nim | 134 +++++++++++++++++++++++++++++++++++ tests/misc/tunsignedconv.nim | 52 ++++++++++++++ 3 files changed, 199 insertions(+), 13 deletions(-) create mode 100644 tests/misc/tunsignedcomp.nim create mode 100644 tests/misc/tunsignedconv.nim diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index b58818a298..e0c11ee3c8 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -260,7 +260,7 @@ proc concreteType(c: TCandidate, t: PType): PType = else: result = t # Note: empty is valid here -proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation = +proc handleRange(f, a: PType, validconv: set[TTypeKind]): TTypeRelation = if a.kind == f.kind: result = isEqual else: @@ -274,9 +274,9 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation = # integer literal in the proper range; we want ``i16 + 4`` to stay an # ``int16`` operation so we declare the ``4`` pseudo-equal to int16 result = isFromIntLit - elif f.kind == tyInt and k in {tyInt8..tyInt32}: + elif f.kind == tyInt and k in {tyInt8..tyInt32, tyUint8..tyUInt16}: result = isIntConv - elif k >= min and k <= max: + elif k in validconv: result = isConvertible elif a.kind == tyRange and a.sons[0].kind in {tyInt..tyInt64, tyUInt8..tyUInt32} and @@ -641,16 +641,16 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = result = isIntConv elif isConvertibleToRange(skipTypes(f, {tyRange}), a): result = isConvertible # a convertible to f - of tyInt: result = handleRange(f, a, tyInt8, tyInt32) - of tyInt8: result = handleRange(f, a, tyInt8, tyInt8) - of tyInt16: result = handleRange(f, a, tyInt8, tyInt16) - of tyInt32: result = handleRange(f, a, tyInt8, tyInt32) - of tyInt64: result = handleRange(f, a, tyInt, tyInt64) - of tyUInt: result = handleRange(f, a, tyUInt8, tyUInt32) - of tyUInt8: result = handleRange(f, a, tyUInt8, tyUInt8) - of tyUInt16: result = handleRange(f, a, tyUInt8, tyUInt16) - of tyUInt32: result = handleRange(f, a, tyUInt8, tyUInt32) - of tyUInt64: result = handleRange(f, a, tyUInt, tyUInt64) + of tyInt: result = handleRange(f, a, {tyInt8..tyInt32,tyUInt8..tyUInt16}) + of tyInt8: result = handleRange(f, a, {tyInt8}) + of tyInt16: result = handleRange(f, a, {tyInt8..tyInt16,tyUInt8}) + of tyInt32: result = handleRange(f, a, {tyInt8..tyInt32,tyUInt8..tyUInt16}) + of tyInt64: result = handleRange(f, a, {tyInt..tyInt64,tyUInt8..tyUInt32}) + of tyUInt: result = handleRange(f, a, {tyUInt8..tyUInt32}) + of tyUInt8: result = handleRange(f, a, {tyUInt8}) + of tyUInt16: result = handleRange(f, a, {tyUInt8..tyUInt16}) + of tyUInt32: result = handleRange(f, a, {tyUInt8..tyUInt32}) + of tyUInt64: result = handleRange(f, a, {tyUInt..tyUInt64}) of tyFloat: result = handleFloatRange(f, a) of tyFloat32: result = handleFloatRange(f, a) of tyFloat64: result = handleFloatRange(f, a) diff --git a/tests/misc/tunsignedcomp.nim b/tests/misc/tunsignedcomp.nim new file mode 100644 index 0000000000..03c841b2f1 --- /dev/null +++ b/tests/misc/tunsignedcomp.nim @@ -0,0 +1,134 @@ +discard """ + output: '''''' +""" + +# All operations involving uint64 are commented out +# as they're not yet supported. +# All other operations are handled by implicit conversions from uints to ints +# uint64 could be supported but would need special implementation of the operators + +# unsigned < signed +assert 10'u8 < 20'i8 +assert 10'u8 < 20'i16 +assert 10'u8 < 20'i32 +assert 10'u8 < 20'i64 + +assert 10'u16 < 20'i8 +assert 10'u16 < 20'i16 +assert 10'u16 < 20'i32 +assert 10'u16 < 20'i64 + +assert 10'u32 < 20'i8 +assert 10'u32 < 20'i16 +assert 10'u32 < 20'i32 +assert 10'u32 < 20'i64 + +# assert 10'u64 < 20'i8 +# assert 10'u64 < 20'i16 +# assert 10'u64 < 20'i32 +# assert 10'u64 < 20'i64 + +# signed < unsigned +assert 10'i8 < 20'u8 +assert 10'i8 < 20'u16 +assert 10'i8 < 20'u32 +# assert 10'i8 < 20'u64 + +assert 10'i16 < 20'u8 +assert 10'i16 < 20'u16 +assert 10'i16 < 20'u32 +# assert 10'i16 < 20'u64 + +assert 10'i32 < 20'u8 +assert 10'i32 < 20'u16 +assert 10'i32 < 20'u32 +# assert 10'i32 < 20'u64 + +assert 10'i64 < 20'u8 +assert 10'i64 < 20'u16 +assert 10'i64 < 20'u32 +# assert 10'i64 < 20'u64 + +# unsigned <= signed +assert 10'u8 <= 20'i8 +assert 10'u8 <= 20'i16 +assert 10'u8 <= 20'i32 +assert 10'u8 <= 20'i64 + +assert 10'u16 <= 20'i8 +assert 10'u16 <= 20'i16 +assert 10'u16 <= 20'i32 +assert 10'u16 <= 20'i64 + +assert 10'u32 <= 20'i8 +assert 10'u32 <= 20'i16 +assert 10'u32 <= 20'i32 +assert 10'u32 <= 20'i64 + +# assert 10'u64 <= 20'i8 +# assert 10'u64 <= 20'i16 +# assert 10'u64 <= 20'i32 +# assert 10'u64 <= 20'i64 + +# signed <= unsigned +assert 10'i8 <= 20'u8 +assert 10'i8 <= 20'u16 +assert 10'i8 <= 20'u32 +# assert 10'i8 <= 20'u64 + +assert 10'i16 <= 20'u8 +assert 10'i16 <= 20'u16 +assert 10'i16 <= 20'u32 +# assert 10'i16 <= 20'u64 + +assert 10'i32 <= 20'u8 +assert 10'i32 <= 20'u16 +assert 10'i32 <= 20'u32 +# assert 10'i32 <= 20'u64 + +assert 10'i64 <= 20'u8 +assert 10'i64 <= 20'u16 +assert 10'i64 <= 20'u32 +# assert 10'i64 <= 20'u64 + +# signed == unsigned +assert 10'i8 == 10'u8 +assert 10'i8 == 10'u16 +assert 10'i8 == 10'u32 +# assert 10'i8 == 10'u64 + +assert 10'i16 == 10'u8 +assert 10'i16 == 10'u16 +assert 10'i16 == 10'u32 +# assert 10'i16 == 10'u64 + +assert 10'i32 == 10'u8 +assert 10'i32 == 10'u16 +assert 10'i32 == 10'u32 +# assert 10'i32 == 10'u64 + +assert 10'i64 == 10'u8 +assert 10'i64 == 10'u16 +assert 10'i64 == 10'u32 +# assert 10'i64 == 10'u64 + +# unsigned == signed +assert 10'u8 == 10'i8 +assert 10'u8 == 10'i16 +assert 10'u8 == 10'i32 +# assert 10'u8 == 10'i64 + +assert 10'u16 == 10'i8 +assert 10'u16 == 10'i16 +assert 10'u16 == 10'i32 +# assert 10'u16 == 10'i64 + +assert 10'u32 == 10'i8 +assert 10'u32 == 10'i16 +assert 10'u32 == 10'i32 +# assert 10'u32 == 10'i64 + +# assert 10'u64 == 10'i8 +# assert 10'u64 == 10'i16 +# assert 10'u64 == 10'i32 +# assert 10'u64 == 10'i64 diff --git a/tests/misc/tunsignedconv.nim b/tests/misc/tunsignedconv.nim new file mode 100644 index 0000000000..547bc92ca1 --- /dev/null +++ b/tests/misc/tunsignedconv.nim @@ -0,0 +1,52 @@ +discard """ + output: '''''' +""" + +import unsigned + +# Tests unsigned literals and implicit conversion between uints and ints +# Passes if it compiles + +var h8:uint8 = 128 +var h16:uint16 = 32768 +var h32:uint32 = 2147483648'u32 +var h64:uint64 = 9223372036854775808'u64 +var foobar:uint64 = 9223372036854775813'u64 # Issue 728 + +var v8:uint8 = 10 +var v16:uint16 = 10 +var v32:uint32 = 10 +var v64:uint64 = 10 + +var a8:int = v8 + 10 +var a16:int = v16 + 10 +# var a32:int = v32 + 10 +# var a64:int = v64 + 10 + +var d8 = v8 + 10'i8 +var d16 = v8 + 10'i16 +var d32 = v8 + 10'i32 +# var d64 = v8 + 10'i64 + +var f8 = v16 + 10'i8 +var f16 = v16 + 10'i16 +var f32 = v16 + 10'i32 +# var f64 = v16 + 10'i64 + +var g8 = v32 + 10'i8 +var g16 = v32 + 10'i16 +var g32 = v32 + 10'i32 +# var g64 = v32 + 10'i64 + +# var n8 = v64 + 10'i8 +# var n16 = v64 + 10'i16 +# var n32 = v64 + 10'i32 +# var n64 = v64 + 10'i64 + +var ar: array[0..20, int] +var n8 = ar[v8] +var n16 = ar[v16] +var n32 = ar[v32] +var n64 = ar[v64] + + From 7343aa0e9dd9aa7602ac504c601affe8d18c5fd1 Mon Sep 17 00:00:00 2001 From: def Date: Sat, 3 Jan 2015 14:21:26 +0100 Subject: [PATCH 046/850] Translate md5 module to unsigned numbers Fixes the bug that files > 256 MB get wrong md5 sum calculated --- lib/pure/md5.nim | 270 +++++++++++++++++++++++------------------------ 1 file changed, 135 insertions(+), 135 deletions(-) diff --git a/lib/pure/md5.nim b/lib/pure/md5.nim index 3b5453957c..c6228af503 100644 --- a/lib/pure/md5.nim +++ b/lib/pure/md5.nim @@ -9,18 +9,20 @@ ## Module for computing MD5 checksums. -type - MD5State = array[0..3, int32] - MD5Block = array[0..15, int32] - MD5CBits = array[0..7, int8] - MD5Digest* = array[0..15, int8] - MD5Buffer = array[0..63, int8] - MD5Context* {.final.} = object +import unsigned + +type + MD5State = array[0..3, uint32] + MD5Block = array[0..15, uint32] + MD5CBits = array[0..7, uint8] + MD5Digest* = array[0..15, uint8] + MD5Buffer = array[0..63, uint8] + MD5Context* {.final.} = object state: MD5State - count: array[0..1, int32] + count: array[0..1, uint32] buffer: MD5Buffer -const +const padding: cstring = "\x80\0\0\0" & "\0\0\0\0\0\0\0\0" & "\0\0\0\0\0\0\0\0" & @@ -31,60 +33,60 @@ const "\0\0\0\0\0\0\0\0" & "\0\0\0\0" -proc F(x, y, z: int32): int32 {.inline.} = +proc F(x, y, z: uint32): uint32 {.inline.} = result = (x and y) or ((not x) and z) -proc G(x, y, z: int32): int32 {.inline.} = +proc G(x, y, z: uint32): uint32 {.inline.} = result = (x and z) or (y and (not z)) -proc H(x, y, z: int32): int32 {.inline.} = +proc H(x, y, z: uint32): uint32 {.inline.} = result = x xor y xor z -proc I(x, y, z: int32): int32 {.inline.} = +proc I(x, y, z: uint32): uint32 {.inline.} = result = y xor (x or (not z)) -proc rot(x: var int32, n: int8) {.inline.} = - x = toU32(x shl ze(n)) or (x shr toU32(32 -% ze(n))) +proc rot(x: var uint32, n: uint8) {.inline.} = + x = (x shl n) or (x shr (32'u32 - n)) -proc FF(a: var int32, b, c, d, x: int32, s: int8, ac: int32) = - a = a +% F(b, c, d) +% x +% ac +proc FF(a: var uint32, b, c, d, x: uint32, s: uint8, ac: uint32) = + a = a + F(b, c, d) + x + ac rot(a, s) - a = a +% b + a = a + b -proc GG(a: var int32, b, c, d, x: int32, s: int8, ac: int32) = - a = a +% G(b, c, d) +% x +% ac +proc GG(a: var uint32, b, c, d, x: uint32, s: uint8, ac: uint32) = + a = a + G(b, c, d) + x + ac rot(a, s) - a = a +% b + a = a + b -proc HH(a: var int32, b, c, d, x: int32, s: int8, ac: int32) = - a = a +% H(b, c, d) +% x +% ac +proc HH(a: var uint32, b, c, d, x: uint32, s: uint8, ac: uint32) = + a = a + H(b, c, d) + x + ac rot(a, s) - a = a +% b + a = a + b -proc II(a: var int32, b, c, d, x: int32, s: int8, ac: int32) = - a = a +% I(b, c, d) +% x +% ac +proc II(a: var uint32, b, c, d, x: uint32, s: uint8, ac: uint32) = + a = a + I(b, c, d) + x + ac rot(a, s) - a = a +% b + a = a + b -proc encode(dest: var MD5Block, src: cstring) = +proc encode(dest: var MD5Block, src: cstring) = var j = 0 for i in 0..high(dest): - dest[i] = toU32(ord(src[j]) or - ord(src[j+1]) shl 8 or - ord(src[j+2]) shl 16 or - ord(src[j+3]) shl 24) + dest[i] = uint32(ord(src[j])) or + uint32(ord(src[j+1])) shl 8 or + uint32(ord(src[j+2])) shl 16 or + uint32(ord(src[j+3])) shl 24 inc(j, 4) -proc decode(dest: var openArray[int8], src: openArray[int32]) = +proc decode(dest: var openArray[uint8], src: openArray[uint32]) = var i = 0 for j in 0..high(src): - dest[i] = toU8(src[j] and 0xff'i32) - dest[i+1] = toU8(src[j] shr 8'i32 and 0xff'i32) - dest[i+2] = toU8(src[j] shr 16'i32 and 0xff'i32) - dest[i+3] = toU8(src[j] shr 24'i32 and 0xff'i32) + dest[i] = src[j] and 0xff'u32 + dest[i+1] = src[j] shr 8 and 0xff'u32 + dest[i+2] = src[j] shr 16 and 0xff'u32 + dest[i+3] = src[j] shr 24 and 0xff'u32 inc(i, 4) -proc transform(buffer: pointer, state: var MD5State) = +proc transform(buffer: pointer, state: var MD5State) = var myBlock: MD5Block encode(myBlock, cast[cstring](buffer)) @@ -92,111 +94,111 @@ proc transform(buffer: pointer, state: var MD5State) = var b = state[1] var c = state[2] var d = state[3] - FF(a, b, c, d, myBlock[0], 7'i8, 0xD76AA478'i32) - FF(d, a, b, c, myBlock[1], 12'i8, 0xE8C7B756'i32) - FF(c, d, a, b, myBlock[2], 17'i8, 0x242070DB'i32) - FF(b, c, d, a, myBlock[3], 22'i8, 0xC1BDCEEE'i32) - FF(a, b, c, d, myBlock[4], 7'i8, 0xF57C0FAF'i32) - FF(d, a, b, c, myBlock[5], 12'i8, 0x4787C62A'i32) - FF(c, d, a, b, myBlock[6], 17'i8, 0xA8304613'i32) - FF(b, c, d, a, myBlock[7], 22'i8, 0xFD469501'i32) - FF(a, b, c, d, myBlock[8], 7'i8, 0x698098D8'i32) - FF(d, a, b, c, myBlock[9], 12'i8, 0x8B44F7AF'i32) - FF(c, d, a, b, myBlock[10], 17'i8, 0xFFFF5BB1'i32) - FF(b, c, d, a, myBlock[11], 22'i8, 0x895CD7BE'i32) - FF(a, b, c, d, myBlock[12], 7'i8, 0x6B901122'i32) - FF(d, a, b, c, myBlock[13], 12'i8, 0xFD987193'i32) - FF(c, d, a, b, myBlock[14], 17'i8, 0xA679438E'i32) - FF(b, c, d, a, myBlock[15], 22'i8, 0x49B40821'i32) - GG(a, b, c, d, myBlock[1], 5'i8, 0xF61E2562'i32) - GG(d, a, b, c, myBlock[6], 9'i8, 0xC040B340'i32) - GG(c, d, a, b, myBlock[11], 14'i8, 0x265E5A51'i32) - GG(b, c, d, a, myBlock[0], 20'i8, 0xE9B6C7AA'i32) - GG(a, b, c, d, myBlock[5], 5'i8, 0xD62F105D'i32) - GG(d, a, b, c, myBlock[10], 9'i8, 0x02441453'i32) - GG(c, d, a, b, myBlock[15], 14'i8, 0xD8A1E681'i32) - GG(b, c, d, a, myBlock[4], 20'i8, 0xE7D3FBC8'i32) - GG(a, b, c, d, myBlock[9], 5'i8, 0x21E1CDE6'i32) - GG(d, a, b, c, myBlock[14], 9'i8, 0xC33707D6'i32) - GG(c, d, a, b, myBlock[3], 14'i8, 0xF4D50D87'i32) - GG(b, c, d, a, myBlock[8], 20'i8, 0x455A14ED'i32) - GG(a, b, c, d, myBlock[13], 5'i8, 0xA9E3E905'i32) - GG(d, a, b, c, myBlock[2], 9'i8, 0xFCEFA3F8'i32) - GG(c, d, a, b, myBlock[7], 14'i8, 0x676F02D9'i32) - GG(b, c, d, a, myBlock[12], 20'i8, 0x8D2A4C8A'i32) - HH(a, b, c, d, myBlock[5], 4'i8, 0xFFFA3942'i32) - HH(d, a, b, c, myBlock[8], 11'i8, 0x8771F681'i32) - HH(c, d, a, b, myBlock[11], 16'i8, 0x6D9D6122'i32) - HH(b, c, d, a, myBlock[14], 23'i8, 0xFDE5380C'i32) - HH(a, b, c, d, myBlock[1], 4'i8, 0xA4BEEA44'i32) - HH(d, a, b, c, myBlock[4], 11'i8, 0x4BDECFA9'i32) - HH(c, d, a, b, myBlock[7], 16'i8, 0xF6BB4B60'i32) - HH(b, c, d, a, myBlock[10], 23'i8, 0xBEBFBC70'i32) - HH(a, b, c, d, myBlock[13], 4'i8, 0x289B7EC6'i32) - HH(d, a, b, c, myBlock[0], 11'i8, 0xEAA127FA'i32) - HH(c, d, a, b, myBlock[3], 16'i8, 0xD4EF3085'i32) - HH(b, c, d, a, myBlock[6], 23'i8, 0x04881D05'i32) - HH(a, b, c, d, myBlock[9], 4'i8, 0xD9D4D039'i32) - HH(d, a, b, c, myBlock[12], 11'i8, 0xE6DB99E5'i32) - HH(c, d, a, b, myBlock[15], 16'i8, 0x1FA27CF8'i32) - HH(b, c, d, a, myBlock[2], 23'i8, 0xC4AC5665'i32) - II(a, b, c, d, myBlock[0], 6'i8, 0xF4292244'i32) - II(d, a, b, c, myBlock[7], 10'i8, 0x432AFF97'i32) - II(c, d, a, b, myBlock[14], 15'i8, 0xAB9423A7'i32) - II(b, c, d, a, myBlock[5], 21'i8, 0xFC93A039'i32) - II(a, b, c, d, myBlock[12], 6'i8, 0x655B59C3'i32) - II(d, a, b, c, myBlock[3], 10'i8, 0x8F0CCC92'i32) - II(c, d, a, b, myBlock[10], 15'i8, 0xFFEFF47D'i32) - II(b, c, d, a, myBlock[1], 21'i8, 0x85845DD1'i32) - II(a, b, c, d, myBlock[8], 6'i8, 0x6FA87E4F'i32) - II(d, a, b, c, myBlock[15], 10'i8, 0xFE2CE6E0'i32) - II(c, d, a, b, myBlock[6], 15'i8, 0xA3014314'i32) - II(b, c, d, a, myBlock[13], 21'i8, 0x4E0811A1'i32) - II(a, b, c, d, myBlock[4], 6'i8, 0xF7537E82'i32) - II(d, a, b, c, myBlock[11], 10'i8, 0xBD3AF235'i32) - II(c, d, a, b, myBlock[2], 15'i8, 0x2AD7D2BB'i32) - II(b, c, d, a, myBlock[9], 21'i8, 0xEB86D391'i32) - state[0] = state[0] +% a - state[1] = state[1] +% b - state[2] = state[2] +% c - state[3] = state[3] +% d - -proc md5Init*(c: var MD5Context) = - ## initializes a MD5Context - c.state[0] = 0x67452301'i32 - c.state[1] = 0xEFCDAB89'i32 - c.state[2] = 0x98BADCFE'i32 - c.state[3] = 0x10325476'i32 - c.count[0] = 0'i32 - c.count[1] = 0'i32 + FF(a, b, c, d, myBlock[0], 7'u8, 0xD76AA478'u32) + FF(d, a, b, c, myBlock[1], 12'u8, 0xE8C7B756'u32) + FF(c, d, a, b, myBlock[2], 17'u8, 0x242070DB'u32) + FF(b, c, d, a, myBlock[3], 22'u8, 0xC1BDCEEE'u32) + FF(a, b, c, d, myBlock[4], 7'u8, 0xF57C0FAF'u32) + FF(d, a, b, c, myBlock[5], 12'u8, 0x4787C62A'u32) + FF(c, d, a, b, myBlock[6], 17'u8, 0xA8304613'u32) + FF(b, c, d, a, myBlock[7], 22'u8, 0xFD469501'u32) + FF(a, b, c, d, myBlock[8], 7'u8, 0x698098D8'u32) + FF(d, a, b, c, myBlock[9], 12'u8, 0x8B44F7AF'u32) + FF(c, d, a, b, myBlock[10], 17'u8, 0xFFFF5BB1'u32) + FF(b, c, d, a, myBlock[11], 22'u8, 0x895CD7BE'u32) + FF(a, b, c, d, myBlock[12], 7'u8, 0x6B901122'u32) + FF(d, a, b, c, myBlock[13], 12'u8, 0xFD987193'u32) + FF(c, d, a, b, myBlock[14], 17'u8, 0xA679438E'u32) + FF(b, c, d, a, myBlock[15], 22'u8, 0x49B40821'u32) + GG(a, b, c, d, myBlock[1], 5'u8, 0xF61E2562'u32) + GG(d, a, b, c, myBlock[6], 9'u8, 0xC040B340'u32) + GG(c, d, a, b, myBlock[11], 14'u8, 0x265E5A51'u32) + GG(b, c, d, a, myBlock[0], 20'u8, 0xE9B6C7AA'u32) + GG(a, b, c, d, myBlock[5], 5'u8, 0xD62F105D'u32) + GG(d, a, b, c, myBlock[10], 9'u8, 0x02441453'u32) + GG(c, d, a, b, myBlock[15], 14'u8, 0xD8A1E681'u32) + GG(b, c, d, a, myBlock[4], 20'u8, 0xE7D3FBC8'u32) + GG(a, b, c, d, myBlock[9], 5'u8, 0x21E1CDE6'u32) + GG(d, a, b, c, myBlock[14], 9'u8, 0xC33707D6'u32) + GG(c, d, a, b, myBlock[3], 14'u8, 0xF4D50D87'u32) + GG(b, c, d, a, myBlock[8], 20'u8, 0x455A14ED'u32) + GG(a, b, c, d, myBlock[13], 5'u8, 0xA9E3E905'u32) + GG(d, a, b, c, myBlock[2], 9'u8, 0xFCEFA3F8'u32) + GG(c, d, a, b, myBlock[7], 14'u8, 0x676F02D9'u32) + GG(b, c, d, a, myBlock[12], 20'u8, 0x8D2A4C8A'u32) + HH(a, b, c, d, myBlock[5], 4'u8, 0xFFFA3942'u32) + HH(d, a, b, c, myBlock[8], 11'u8, 0x8771F681'u32) + HH(c, d, a, b, myBlock[11], 16'u8, 0x6D9D6122'u32) + HH(b, c, d, a, myBlock[14], 23'u8, 0xFDE5380C'u32) + HH(a, b, c, d, myBlock[1], 4'u8, 0xA4BEEA44'u32) + HH(d, a, b, c, myBlock[4], 11'u8, 0x4BDECFA9'u32) + HH(c, d, a, b, myBlock[7], 16'u8, 0xF6BB4B60'u32) + HH(b, c, d, a, myBlock[10], 23'u8, 0xBEBFBC70'u32) + HH(a, b, c, d, myBlock[13], 4'u8, 0x289B7EC6'u32) + HH(d, a, b, c, myBlock[0], 11'u8, 0xEAA127FA'u32) + HH(c, d, a, b, myBlock[3], 16'u8, 0xD4EF3085'u32) + HH(b, c, d, a, myBlock[6], 23'u8, 0x04881D05'u32) + HH(a, b, c, d, myBlock[9], 4'u8, 0xD9D4D039'u32) + HH(d, a, b, c, myBlock[12], 11'u8, 0xE6DB99E5'u32) + HH(c, d, a, b, myBlock[15], 16'u8, 0x1FA27CF8'u32) + HH(b, c, d, a, myBlock[2], 23'u8, 0xC4AC5665'u32) + II(a, b, c, d, myBlock[0], 6'u8, 0xF4292244'u32) + II(d, a, b, c, myBlock[7], 10'u8, 0x432AFF97'u32) + II(c, d, a, b, myBlock[14], 15'u8, 0xAB9423A7'u32) + II(b, c, d, a, myBlock[5], 21'u8, 0xFC93A039'u32) + II(a, b, c, d, myBlock[12], 6'u8, 0x655B59C3'u32) + II(d, a, b, c, myBlock[3], 10'u8, 0x8F0CCC92'u32) + II(c, d, a, b, myBlock[10], 15'u8, 0xFFEFF47D'u32) + II(b, c, d, a, myBlock[1], 21'u8, 0x85845DD1'u32) + II(a, b, c, d, myBlock[8], 6'u8, 0x6FA87E4F'u32) + II(d, a, b, c, myBlock[15], 10'u8, 0xFE2CE6E0'u32) + II(c, d, a, b, myBlock[6], 15'u8, 0xA3014314'u32) + II(b, c, d, a, myBlock[13], 21'u8, 0x4E0811A1'u32) + II(a, b, c, d, myBlock[4], 6'u8, 0xF7537E82'u32) + II(d, a, b, c, myBlock[11], 10'u8, 0xBD3AF235'u32) + II(c, d, a, b, myBlock[2], 15'u8, 0x2AD7D2BB'u32) + II(b, c, d, a, myBlock[9], 21'u8, 0xEB86D391'u32) + state[0] = state[0] + a + state[1] = state[1] + b + state[2] = state[2] + c + state[3] = state[3] + d + +proc md5Init*(c: var MD5Context) = + ## initializes a MD5Context + c.state[0] = 0x67452301'u32 + c.state[1] = 0xEFCDAB89'u32 + c.state[2] = 0x98BADCFE'u32 + c.state[3] = 0x10325476'u32 + c.count[0] = 0'u32 + c.count[1] = 0'u32 zeroMem(addr(c.buffer), sizeof(MD5buffer)) -proc md5Update*(c: var MD5Context, input: cstring, len: int) = +proc md5Update*(c: var MD5Context, input: cstring, len: int) = ## updates the MD5Context with the `input` data of length `len` var input = input - var Index = (c.count[0] shr 3) and 0x3F - c.count[0] = c.count[0] +% toU32(len shl 3) - if c.count[0] < (len shl 3): c.count[1] = c.count[1] +% 1'i32 - c.count[1] = c.count[1] +% toU32(len shr 29) + var Index = int((c.count[0] shr 3) and 0x3F) + c.count[0] = c.count[0] + (uint32(len) shl 3) + if c.count[0] < (uint32(len) shl 3): c.count[1] = c.count[1] + 1'u32 + c.count[1] = c.count[1] + (uint32(len) shr 29) var PartLen = 64 - Index - if len >= PartLen: + if len >= PartLen: copyMem(addr(c.buffer[Index]), input, PartLen) transform(addr(c.buffer), c.state) var i = PartLen - while i + 63 < len: + while i + 63 < len: transform(addr(input[i]), c.state) inc(i, 64) copyMem(addr(c.buffer[0]), addr(input[i]), len-i) else: copyMem(addr(c.buffer[Index]), addr(input[0]), len) -proc md5Final*(c: var MD5Context, digest: var MD5Digest) = +proc md5Final*(c: var MD5Context, digest: var MD5Digest) = ## finishes the MD5Context and stores the result in `digest` var Bits: MD5CBits PadLen: int decode(Bits, c.count) - var Index = (c.count[0] shr 3) and 0x3F + var Index = int((c.count[0] shr 3) and 0x3F) if Index < 56: PadLen = 56 - Index else: PadLen = 120 - Index md5Update(c, padding, PadLen) @@ -204,34 +206,34 @@ proc md5Final*(c: var MD5Context, digest: var MD5Digest) = decode(digest, c.state) zeroMem(addr(c), sizeof(MD5Context)) -proc toMD5*(s: string): MD5Digest = +proc toMD5*(s: string): MD5Digest = ## computes the MD5Digest value for a string `s` var c: MD5Context md5Init(c) md5Update(c, cstring(s), len(s)) md5Final(c, result) - -proc `$`*(D: MD5Digest): string = + +proc `$`*(D: MD5Digest): string = ## converts a MD5Digest value into its string representation const digits = "0123456789abcdef" result = "" - for i in 0..15: + for i in 0..15: add(result, digits[(D[i] shr 4) and 0xF]) add(result, digits[D[i] and 0xF]) -proc getMD5*(s: string): string = +proc getMD5*(s: string): string = ## computes an MD5 value of `s` and returns its string representation - var + var c: MD5Context d: MD5Digest md5Init(c) md5Update(c, cstring(s), len(s)) md5Final(c, d) result = $d - -proc `==`*(D1, D2: MD5Digest): bool = + +proc `==`*(D1, D2: MD5Digest): bool = ## checks if two MD5Digest values are identical - for i in 0..15: + for i in 0..15: if D1[i] != D2[i]: return false return true @@ -241,5 +243,3 @@ when isMainModule: assert(getMD5("Frank jagt im komplett verwahrlosten Taxi quer durch Bayern") == "7e716d0e702df0505fc72e2b89467910") assert($toMD5("") == "d41d8cd98f00b204e9800998ecf8427e") - - From dd82f0c8298666e2de779c518e6fab14e4d13ab4 Mon Sep 17 00:00:00 2001 From: def Date: Sat, 3 Jan 2015 17:21:54 +0100 Subject: [PATCH 047/850] Fix httpclient to properly encode queries (path?queries) --- lib/pure/httpclient.nim | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 3afb625eec..479d9a54de 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -294,7 +294,10 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "", var r = if proxy == nil: parseUri(url) else: proxy.url var headers = substr($httpMethod, len("http")) if proxy == nil: - headers.add(" /" & r.path & r.query) + var pathQuery = " /" & r.path + if r.query.len > 0: + pathQuery.add("?" & r.query) + headers.add(pathQuery) else: headers.add(" " & url) @@ -442,7 +445,9 @@ proc generateHeaders(r: Uri, httpMethod: HttpMethod, headers: StringTableRef): string = result = substr($httpMethod, len("http")) # TODO: Proxies - result.add(" /" & r.path & r.query) + result.add(" /" & r.path) + if r.query.len > 0: + result.add("?" & r.query) result.add(" HTTP/1.1\c\L") add(result, "Host: " & r.hostname & "\c\L") From 76dbce275a2c009a8a93bff9b7a3e44029f215b8 Mon Sep 17 00:00:00 2001 From: def Date: Sat, 3 Jan 2015 17:23:13 +0100 Subject: [PATCH 048/850] Fix (u: Uri), add test cases and make it work for opaque URIs --- lib/pure/uri.nim | 49 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim index 368802dc2d..edc690aecc 100644 --- a/lib/pure/uri.nim +++ b/lib/pure/uri.nim @@ -16,6 +16,7 @@ type Uri* = object scheme*, username*, password*: string hostname*, port*, path*, query*, anchor*: string + opaque*: bool {.deprecated: [TUrl: Url, TUri: Uri].} @@ -115,6 +116,8 @@ proc parseUri*(uri: string): Uri = if authority == "": raise newException(ValueError, "Expected authority got nothing.") parseAuthority(authority, result) + else: + result.opaque = true # Path parsePath(uri, i, result) @@ -256,7 +259,10 @@ proc `$`*(u: Uri): string = result = "" if u.scheme.len > 0: result.add(u.scheme) - result.add("://") + if u.opaque: + result.add(":") + else: + result.add("://") if u.username.len > 0: result.add(u.username) if u.password.len > 0: @@ -268,22 +274,28 @@ proc `$`*(u: Uri): string = result.add(":") result.add(u.port) if u.path.len > 0: - if u.path[0] != '/': result.add("/") result.add(u.path) - result.add(u.query) - result.add(u.anchor) + if u.query.len > 0: + result.add("?") + result.add(u.query) + if u.anchor.len > 0: + result.add("#") + result.add(u.anchor) when isMainModule: block: - let test = parseUri("http://localhost:8080/test") + let str = "http://localhost:8080/test" + let test = parseUri(str) doAssert test.scheme == "http" doAssert test.port == "8080" doAssert test.path == "/test" doAssert test.hostname == "localhost" + doAssert($test == str) block: - let test = parseUri("foo://username:password@example.com:8042/over/there" & - "/index.dtb?type=animal&name=narwhal#nose") + let str = "foo://username:password@example.com:8042/over/there" & + "/index.dtb?type=animal&name=narwhal#nose" + let test = parseUri(str) doAssert test.scheme == "foo" doAssert test.username == "username" doAssert test.password == "password" @@ -292,34 +304,45 @@ when isMainModule: doAssert test.path == "/over/there/index.dtb" doAssert test.query == "type=animal&name=narwhal" doAssert test.anchor == "nose" + doAssert($test == str) block: - let test = parseUri("urn:example:animal:ferret:nose") + let str = "urn:example:animal:ferret:nose" + let test = parseUri(str) doAssert test.scheme == "urn" doAssert test.path == "example:animal:ferret:nose" + doAssert($test == str) block: - let test = parseUri("mailto:username@example.com?subject=Topic") + let str = "mailto:username@example.com?subject=Topic" + let test = parseUri(str) doAssert test.scheme == "mailto" doAssert test.username == "username" doAssert test.hostname == "example.com" doAssert test.query == "subject=Topic" + doAssert($test == str) block: - let test = parseUri("magnet:?xt=urn:sha1:72hsga62ba515sbd62&dn=foobar") + let str = "magnet:?xt=urn:sha1:72hsga62ba515sbd62&dn=foobar" + let test = parseUri(str) doAssert test.scheme == "magnet" doAssert test.query == "xt=urn:sha1:72hsga62ba515sbd62&dn=foobar" + doAssert($test == str) block: - let test = parseUri("/test/foo/bar?q=2#asdf") + let str = "/test/foo/bar?q=2#asdf" + let test = parseUri(str) doAssert test.scheme == "" doAssert test.path == "/test/foo/bar" doAssert test.query == "q=2" doAssert test.anchor == "asdf" + doAssert($test == str) block: - let test = parseUri("test/no/slash") + let str = "test/no/slash" + let test = parseUri(str) doAssert test.path == "test/no/slash" + doAssert($test == str) # Remove dot segments tests block: @@ -371,5 +394,3 @@ when isMainModule: block: let test = parseUri("http://example.com/foo/") / "/bar/asd" doAssert test.path == "/foo/bar/asd" - - From 387d598cfb95aa8c62f2186ed6a25ef142a5c27e Mon Sep 17 00:00:00 2001 From: def Date: Sat, 3 Jan 2015 17:40:33 +0100 Subject: [PATCH 049/850] Minor cleanup --- lib/pure/httpclient.nim | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 479d9a54de..f77be0231c 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -294,10 +294,9 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "", var r = if proxy == nil: parseUri(url) else: proxy.url var headers = substr($httpMethod, len("http")) if proxy == nil: - var pathQuery = " /" & r.path + headers.add(" /" & r.path) if r.query.len > 0: - pathQuery.add("?" & r.query) - headers.add(pathQuery) + headers.add("?" & r.query) else: headers.add(" " & url) From ee62d56cadb9b05d65b01cd8489de2975604c9c9 Mon Sep 17 00:00:00 2001 From: def Date: Sat, 3 Jan 2015 17:44:30 +0100 Subject: [PATCH 050/850] Apply #1824 to fix #1823 --- lib/pure/httpclient.nim | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index f77be0231c..acc80cfdb4 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -294,9 +294,11 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "", var r = if proxy == nil: parseUri(url) else: proxy.url var headers = substr($httpMethod, len("http")) if proxy == nil: - headers.add(" /" & r.path) + echo url + headers.add(" " & r.path) if r.query.len > 0: headers.add("?" & r.query) + echo headers else: headers.add(" " & url) @@ -444,7 +446,7 @@ proc generateHeaders(r: Uri, httpMethod: HttpMethod, headers: StringTableRef): string = result = substr($httpMethod, len("http")) # TODO: Proxies - result.add(" /" & r.path) + result.add(" " & r.path) if r.query.len > 0: result.add("?" & r.query) result.add(" HTTP/1.1\c\L") From ad1945f102a1f2c7e5213e01911649dab6338346 Mon Sep 17 00:00:00 2001 From: Robert Gieseke Date: Sat, 3 Jan 2015 18:06:57 +0100 Subject: [PATCH 051/850] Fix typo --- doc/idetools.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/idetools.txt b/doc/idetools.txt index 5429d0c074..e04f530f48 100644 --- a/doc/idetools.txt +++ b/doc/idetools.txt @@ -145,7 +145,7 @@ The ``--usages`` idetools switch lists all usages of the symbol at a position. IDEs can use this to find all the places in the file where the symbol is used and offer the user to rename it in all places at the same time. Again, a pure string based search and -replace may catch symbols out of the scope of a funcion/loop. +replace may catch symbols out of the scope of a function/loop. For this kind of query the IDE will most likely ignore all the type/signature info provided by idetools and concentrate on the From cd73b3b12bd4fe05e342fe9c9e1dba2413ca6485 Mon Sep 17 00:00:00 2001 From: Joseph Poirier Date: Sat, 3 Jan 2015 14:24:02 -0600 Subject: [PATCH 052/850] fix a couple of typos, grammar, and removal of whitespace --- doc/manual/types.txt | 130 +++++++++++++++++++++---------------------- doc/tut2.txt | 42 +++++++------- web/index.txt | 34 +++++------ 3 files changed, 103 insertions(+), 103 deletions(-) diff --git a/doc/manual/types.txt b/doc/manual/types.txt index b028752e8f..94611bbbb6 100644 --- a/doc/manual/types.txt +++ b/doc/manual/types.txt @@ -40,7 +40,7 @@ These integer types are pre-defined: ``int`` the generic signed integer type; its size is platform dependent and has the - same size as a pointer. This type should be used in general. An integer + same size as a pointer. This type should be used in general. An integer literal that has no type suffix is of this type. intXX @@ -51,7 +51,7 @@ intXX ``uint`` the generic `unsigned integer`:idx: type; its size is platform dependent and - has the same size as a pointer. An integer literal with the type + has the same size as a pointer. An integer literal with the type suffix ``'u`` is of this type. uintXX @@ -59,15 +59,15 @@ uintXX (example: uint16 is a 16 bit wide unsigned integer). The current implementation supports ``uint8``, ``uint16``, ``uint32``, ``uint64``. Literals of these types have the suffix 'uXX. - Unsigned operations all wrap around; they cannot lead to over- or + Unsigned operations all wrap around; they cannot lead to over- or underflow errors. In addition to the usual arithmetic operators for signed and unsigned integers -(``+ - *`` etc.) there are also operators that formally work on *signed* -integers but treat their arguments as *unsigned*: They are mostly provided -for backwards compatibility with older versions of the language that lacked -unsigned integer types. These unsigned operations for signed integers use +(``+ - *`` etc.) there are also operators that formally work on *signed* +integers but treat their arguments as *unsigned*: They are mostly provided +for backwards compatibility with older versions of the language that lacked +unsigned integer types. These unsigned operations for signed integers use the ``%`` suffix as convention: @@ -98,7 +98,7 @@ operation meaning kinds of integer types are used: the smaller type is converted to the larger. A `narrowing type conversion`:idx: converts a larger to a smaller type (for -example ``int32 -> int16``. A `widening type conversion`:idx: converts a +example ``int32 -> int16``. A `widening type conversion`:idx: converts a smaller type to a larger type (for example ``int16 -> int32``). In Nim only widening type conversions are *implicit*: @@ -111,7 +111,7 @@ widening type conversions are *implicit*: However, ``int`` literals are implicitly convertible to a smaller integer type if the literal's value fits this smaller type and such a conversion is less -expensive than other implicit conversions, so ``myInt16 + 34`` produces +expensive than other implicit conversions, so ``myInt16 + 34`` produces an ``int16`` result. For further details, see `Convertible relation`_. @@ -137,12 +137,12 @@ determined). Assignments from the base type to one of its subrange types A subrange type has the same size as its base type (``int`` in the example). Nim requires `interval arithmetic`:idx: for subrange types over a set -of built-in operators that involve constants: ``x %% 3`` is of -type ``range[0..2]``. The following built-in operators for integers are +of built-in operators that involve constants: ``x %% 3`` is of +type ``range[0..2]``. The following built-in operators for integers are affected by this rule: ``-``, ``+``, ``*``, ``min``, ``max``, ``succ``, ``pred``, ``mod``, ``div``, ``%%``, ``and`` (bitwise ``and``). -Bitwise ``and`` only produces a ``range`` if one of its operands is a +Bitwise ``and`` only produces a ``range`` if one of its operands is a constant *x* so that (x+1) is a number of two. (Bitwise ``and`` is then a ``%%`` operation.) @@ -155,7 +155,7 @@ This means that the following code is accepted: of 9: echo "C" of 10: echo "D" # note: no ``else`` required as (x and 3) + 7 has the type: range[7..10] - + Pre-defined floating point types -------------------------------- @@ -186,17 +186,17 @@ The IEEE standard defines five types of floating-point exceptions: for example 0.0/0.0, sqrt(-1.0), and log(-37.8). * Division by zero: divisor is zero and dividend is a finite nonzero number, for example 1.0/0.0. -* Overflow: operation produces a result that exceeds the range of the exponent, +* Overflow: operation produces a result that exceeds the range of the exponent, for example MAXDOUBLE+0.0000000000001e308. -* Underflow: operation produces a result that is too small to be represented +* Underflow: operation produces a result that is too small to be represented as a normal number, for example, MINDOUBLE * MINDOUBLE. -* Inexact: operation produces a result that cannot be represented with infinite +* Inexact: operation produces a result that cannot be represented with infinite precision, for example, 2.0 / 3.0, log(1.1) and 0.1 in input. -The IEEE exceptions are either ignored at runtime or mapped to the +The IEEE exceptions are either ignored at runtime or mapped to the Nim exceptions: `FloatInvalidOpError`:idx:, `FloatDivByZeroError`:idx:, `FloatOverflowError`:idx:, `FloatUnderflowError`:idx:, -and `FloatInexactError`:idx:. +and `FloatInexactError`:idx:. These exceptions inherit from the `FloatingPointError`:idx: base class. Nim provides the pragmas `NaNChecks`:idx: and `InfChecks`:idx: to control @@ -212,7 +212,7 @@ whether the IEEE exceptions are ignored or trap a Nim exception: In the current implementation ``FloatDivByZeroError`` and ``FloatInexactError`` are never raised. ``FloatOverflowError`` is raised instead of ``FloatDivByZeroError``. -There is also a `floatChecks`:idx: pragma that is a short-cut for the +There is also a `floatChecks`:idx: pragma that is a short-cut for the combination of ``NaNChecks`` and ``InfChecks`` pragmas. ``floatChecks`` are turned off as default. @@ -303,7 +303,7 @@ and ``pred`` are not available for them either. The compiler supports the built-in stringify operator ``$`` for enumerations. -The stringify's result can be controlled by explicitly giving the string +The stringify's result can be controlled by explicitly giving the string values to use: .. code-block:: nim @@ -315,12 +315,12 @@ values to use: valueC = 2, valueD = (3, "abc") -As can be seen from the example, it is possible to both specify a field's +As can be seen from the example, it is possible to both specify a field's ordinal value and its string value by using a tuple. It is also possible to only specify one of them. An enum can be marked with the ``pure`` pragma so that it's fields are not -added to the current scope, so they always need to be accessed +added to the current scope, so they always need to be accessed via ``MyEnum.value``: .. code-block:: nim @@ -328,7 +328,7 @@ via ``MyEnum.value``: type MyEnum {.pure.} = enum valueA, valueB, valueC, valueD - + echo valueA # error: Unknown identifier echo MyEnum.valueA # works @@ -364,22 +364,22 @@ cstring type ------------ The ``cstring`` type represents a pointer to a zero-terminated char array compatible to the type ``char*`` in Ansi C. Its primary purpose lies in easy -interfacing with C. The index operation ``s[i]`` means the i-th *char* of +interfacing with C. The index operation ``s[i]`` means the i-th *char* of ``s``; however no bounds checking for ``cstring`` is performed making the index operation unsafe. -A Nim ``string`` is implicitly convertible +A Nim ``string`` is implicitly convertible to ``cstring`` for convenience. If a Nim string is passed to a C-style variadic proc, it is implicitly converted to ``cstring`` too: .. code-block:: nim - proc printf(formatstr: cstring) {.importc: "printf", varargs, + proc printf(formatstr: cstring) {.importc: "printf", varargs, header: "".} - + printf("This works %s", "as expected") Even though the conversion is implicit, it is not *safe*: The garbage collector -does not consider a ``cstring`` to be a root and may collect the underlying +does not consider a ``cstring`` to be a root and may collect the underlying memory. However in practice this almost never happens as the GC considers stack roots conservatively. One can use the builtin procs ``GC_ref`` and ``GC_unref`` to keep the string data alive for the rare cases where it does @@ -390,7 +390,7 @@ string from a cstring: .. code-block:: nim var str: string = "Hello!" - var cstr: cstring = s + var cstr: cstring = str var newstr: string = $cstr @@ -410,9 +410,9 @@ integers from 0 to ``len(A)-1``. An array expression may be constructed by the array constructor ``[]``. Sequences are similar to arrays but of dynamic length which may change -during runtime (like strings). Sequences are implemented as growable arrays, +during runtime (like strings). Sequences are implemented as growable arrays, allocating pieces of memory as items are added. A sequence ``S`` is always -indexed by integers from 0 to ``len(S)-1`` and its bounds are checked. +indexed by integers from 0 to ``len(S)-1`` and its bounds are checked. Sequences can be constructed by the array constructor ``[]`` in conjunction with the array to sequence operator ``@``. Another way to allocate space for a sequence is to call the built-in ``newSeq`` procedure. @@ -452,11 +452,11 @@ Open arrays Often fixed size arrays turn out to be too inflexible; procedures should be able to deal with arrays of different sizes. The `openarray`:idx: type -allows this; it can only be used for parameters. Openarrays are always -indexed with an ``int`` starting at position 0. The ``len``, ``low`` -and ``high`` operations are available for open arrays too. Any array with -a compatible base type can be passed to an openarray parameter, the index -type does not matter. In addition to arrays sequences can also be passed +allows this; it can only be used for parameters. Openarrays are always +indexed with an ``int`` starting at position 0. The ``len``, ``low`` +and ``high`` operations are available for open arrays too. Any array with +a compatible base type can be passed to an openarray parameter, the index +type does not matter. In addition to arrays sequences can also be passed to an open array parameter. The openarray type cannot be nested: multidimensional openarrays are not @@ -467,7 +467,7 @@ Varargs ------- A ``varargs`` parameter is an openarray parameter that additionally -allows to pass a variable number of arguments to a procedure. The compiler +allows to pass a variable number of arguments to a procedure. The compiler converts the list of arguments to an array implicitly: .. code-block:: nim @@ -494,7 +494,7 @@ type conversions in this context: # is transformed to: myWriteln(stdout, [$123, $"def", $4.0]) -In this example ``$`` is applied to any argument that is passed to the +In this example ``$`` is applied to any argument that is passed to the parameter ``a``. (Note that ``$`` applied to strings is a nop.) @@ -531,7 +531,7 @@ in future versions of the compiler. person = (creditCard: "Peter", id: 20) The implementation aligns the fields for best access performance. The alignment -is compatible with the way the C compiler does it. +is compatible with the way the C compiler does it. For consistency with ``object`` declarations, tuples in a ``type`` section can also be defined with indentation instead of ``[]``: @@ -571,7 +571,7 @@ Object construction ------------------- Objects can also be created with an `object construction expression`:idx: that -has the syntax ``T(fieldA: valueA, fieldB: valueB, ...)`` where ``T`` is +has the syntax ``T(fieldA: valueA, fieldB: valueB, ...)`` where ``T`` is an ``object`` type or a ``ref object`` type: .. code-block:: nim @@ -617,10 +617,10 @@ An example: # the following statement raises an `EInvalidField` exception, because # n.kind's value does not fit and the ``nkString`` branch is not active: n.strVal = "" - + # invalid: would change the active object branch: n.kind = nkInt - + var x = PNode(kind: nkAdd, leftOp: PNode(kind: nkInt, intVal: 4), rightOp: PNode(kind: nkInt, intVal: 2)) # valid: does not change the active object branch: @@ -660,8 +660,8 @@ untraced references are *unsafe*. However for certain low-level operations Traced references are declared with the **ref** keyword, untraced references are declared with the **ptr** keyword. -An empty subscript ``[]`` notation can be used to derefer a reference, -the ``addr`` procedure returns the address of an item. An address is always +An empty subscript ``[]`` notation can be used to derefer a reference, +the ``addr`` procedure returns the address of an item. An address is always an untraced reference. Thus the usage of ``addr`` is an *unsafe* feature. @@ -680,7 +680,7 @@ dereferencing operations for reference types: var n: PNode new(n) - n.data = 9 + n.data = 9 # no need to write n[].data; in fact n[].data is highly discouraged! In order to simplify structural type checking, recursive tuples are not valid: @@ -751,20 +751,20 @@ details like this when mixing garbage collected data with unmanaged memory. Not nil annotation ------------------ -All types for that ``nil`` is a valid value can be annotated to +All types for that ``nil`` is a valid value can be annotated to exclude ``nil`` as a valid value with the ``not nil`` annotation: .. code-block:: nim type PObject = ref TObj not nil TProc = (proc (x, y: int)) not nil - + proc p(x: PObject) = echo "not nil" - + # compiler catches this: p(nil) - + # and also this: var x: PObject p(x) @@ -851,22 +851,22 @@ Examples: forEach(printItem) # this will NOT compile because calling conventions differ - + .. code-block:: nim type TOnMouseMove = proc (x, y: int) {.closure.} - + proc onMouseMove(mouseX, mouseY: int) = # has default calling convention echo "x: ", mouseX, " y: ", mouseY - + proc setOnMouseMove(mouseMoveEvent: TOnMouseMove) = discard - + # ok, 'onMouseMove' has the default calling convention, which is compatible # to 'closure': setOnMouseMove(onMouseMove) - + A subtle issue with procedural types is that the calling convention of the procedure influences the type compatibility: procedural types are only @@ -932,7 +932,7 @@ of the following conditions hold: 3) The procedure has a calling convention that differs from ``nimcall``. 4) The procedure is anonymous. -The rules' purpose is to prevent the case that extending a non-``procvar`` +The rules' purpose is to prevent the case that extending a non-``procvar`` procedure with default parameters breaks client code. The default calling convention is ``nimcall``, unless it is an inner proc (a @@ -964,7 +964,7 @@ types are a perfect tool to model different currencies: type TDollar = distinct int TEuro = distinct int - + var d: TDollar e: TEuro @@ -989,7 +989,7 @@ number without unit; and the same holds for division: proc `*` (x: int, y: TDollar): TDollar = result = TDollar(x * int(y)) - + proc `div` ... This quickly gets tedious. The implementations are trivial and the compiler @@ -1014,7 +1014,7 @@ currency. This can be solved with templates_. template additive(typ: typedesc): stmt = proc `+` *(x, y: typ): typ {.borrow.} proc `-` *(x, y: typ): typ {.borrow.} - + # unary operators: proc `+` *(x: typ): typ {.borrow.} proc `-` *(x: typ): typ {.borrow.} @@ -1036,7 +1036,7 @@ currency. This can be solved with templates_. additive(typ) multiplicative(typ, base) comparable(typ) - + defineCurrency(TDollar, int) defineCurrency(TEuro, int) @@ -1127,21 +1127,21 @@ modules like `db_sqlite `_. Void type --------- -The ``void`` type denotes the absense of any type. Parameters of +The ``void`` type denotes the absense of any type. Parameters of type ``void`` are treated as non-existent, ``void`` as a return type means that the procedure does not return a value: .. code-block:: nim proc nothing(x, y: void): void = echo "ha" - + nothing() # writes "ha" to stdout The ``void`` type is particularly useful for generic code: .. code-block:: nim proc callProc[T](p: proc (x: T), x: T) = - when T is void: + when T is void: p() else: p(x) @@ -1151,13 +1151,13 @@ The ``void`` type is particularly useful for generic code: callProc[int](intProc, 12) callProc[void](emptyProc) - + However, a ``void`` type cannot be inferred in generic code: .. code-block:: nim - callProc(emptyProc) + callProc(emptyProc) # Error: type mismatch: got (proc ()) - # but expected one of: + # but expected one of: # callProc(p: proc (T), x: T) The ``void`` type is only valid for parameters and return types; other symbols diff --git a/doc/tut2.txt b/doc/tut2.txt index 9d34091647..2ae0f18f6e 100644 --- a/doc/tut2.txt +++ b/doc/tut2.txt @@ -35,7 +35,7 @@ Object Oriented Programming =========================== While Nim's support for object oriented programming (OOP) is minimalistic, -powerful OOP technics can be used. OOP is seen as *one* way to design a +powerful OOP techniques can be used. OOP is seen as *one* way to design a program, not *the only* way. Often a procedural approach leads to simpler and more efficient code. In particular, prefering composition over inheritance is often the better design. @@ -77,8 +77,8 @@ section. Inheritance is done with the ``object of`` syntax. Multiple inheritance is currently not supported. If an object type has no suitable ancestor, ``RootObj`` -can be used as its ancestor, but this is only a convention. Objects that have -no ancestor are implicitly ``final``. You can use the ``inheritable`` pragma +can be used as its ancestor, but this is only a convention. Objects that have +no ancestor are implicitly ``final``. You can use the ``inheritable`` pragma to introduce new object roots apart from ``system.RootObj``. (This is used in the GTK wrapper for instance.) @@ -199,7 +199,7 @@ This method call syntax is not restricted to objects, it can be used for any type: .. code-block:: nim - + echo("abc".len) # is the same as echo(len("abc")) echo("abc".toUpper()) echo({'a', 'b', 'c'}.card) @@ -212,7 +212,7 @@ So "pure object oriented" code is easy to write: .. code-block:: nim import strutils - + stdout.writeln("Give a list of numbers (separated by spaces): ") stdout.write(stdin.readLine.split.map(parseInt).max.`$`) stdout.writeln(" is the maximum!") @@ -226,7 +226,7 @@ the same. But setting a value is different; for this a special setter syntax is needed: .. code-block:: nim - + type TSocket* = object of RootObj FHost: int # cannot be accessed from the outside of the module @@ -236,7 +236,7 @@ is needed: proc `host=`*(s: var TSocket, value: int) {.inline.} = ## setter of hostAddr s.FHost = value - + proc host*(s: TSocket): int {.inline.} = ## getter of hostAddr s.FHost @@ -294,15 +294,15 @@ Procedures always use static dispatch. For dynamic dispatch replace the method eval(e: PExpr): int = # override this base method quit "to override!" - + method eval(e: PLiteral): int = e.x method eval(e: PPlusExpr): int = eval(e.a) + eval(e.b) - + proc newLit(x: int): PLiteral = PLiteral(x: x) proc newPlus(a, b: PExpr): PPlusExpr = PPlusExpr(a: a, b: b) - + echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4))) - + Note that in the example the constructors ``newLit`` and ``newPlus`` are procs because they should use static binding, but ``eval`` is a method because it requires dynamic binding. @@ -316,16 +316,16 @@ dispatching: TThing = object of RootObj TUnit = object of TThing x: int - + method collide(a, b: TThing) {.inline.} = quit "to override!" - + method collide(a: TThing, b: TUnit) {.inline.} = echo "1" - + method collide(a: TUnit, b: TThing) {.inline.} = echo "2" - + var a, b: TUnit collide(a, b) # output: 2 @@ -526,7 +526,7 @@ containers: yield n.data add(stack, n.ri) # push right subtree onto the stack n = n.le # and follow the left pointer - + var root: PBinaryTree[string] # instantiate a PBinaryTree with ``string`` add(root, newNode("hello")) # instantiates ``newNode`` and ``add`` @@ -578,7 +578,7 @@ simple proc for logging: proc log(msg: string) {.inline.} = if debug: stdout.writeln(msg) - + var x = 4 log("x has the value: " & $x) @@ -595,7 +595,7 @@ Turning the ``log`` proc into a template solves this problem: template log(msg: string) = if debug: stdout.writeln(msg) - + var x = 4 log("x has the value: " & $x) @@ -622,11 +622,11 @@ via a special ``:`` syntax: close(f) else: quit("cannot open: " & fn) - + withFile(txt, "ttempl3.txt", fmWrite): txt.writeln("line 1") txt.writeln("line 2") - + In the example the two ``writeln`` statements are bound to the ``body`` parameter. The ``withFile`` template contains boilerplate code and helps to avoid a common bug: to forget to close the file. Note how the @@ -739,7 +739,7 @@ Term rewriting macros --------------------- Term rewriting macros can be used to enhance the compilation process -with user defined optimizations; see this `document `_ for +with user defined optimizations; see this `document `_ for further information. diff --git a/web/index.txt b/web/index.txt index b6d4f8e8f4..95cac9316f 100644 --- a/web/index.txt +++ b/web/index.txt @@ -5,16 +5,16 @@ Home Welcome to Nim -------------- -**Nim** (formerly known as "Nimrod") is a statically typed, imperative -programming language that tries to give the programmer ultimate power without +**Nim** (formerly known as "Nimrod") is a statically typed, imperative +programming language that tries to give the programmer ultimate power without compromises on runtime efficiency. This means it focuses on compile-time mechanisms in all their various forms. -Beneath a nice infix/indentation based syntax with a -powerful (AST based, hygienic) macro system lies a semantic model that supports -a soft realtime GC on thread local heaps. Asynchronous message passing is used -between threads, so no "stop the world" mechanism is necessary. An unsafe -shared memory heap is also provided for the increased efficiency that results +Beneath a nice infix/indentation based syntax with a +powerful (AST based, hygienic) macro system lies a semantic model that supports +a soft realtime GC on thread local heaps. Asynchronous message passing is used +between threads, so no "stop the world" mechanism is necessary. An unsafe +shared memory heap is also provided for the increased efficiency that results from that model. @@ -24,7 +24,7 @@ Nim is efficient * Native code generation (currently via compilation to C), not dependent on a virtual machine: **Nim produces small executables without dependencies for easy redistribution.** -* A fast **non-tracing** garbage collector that supports soft +* A fast **non-tracing** garbage collector that supports soft real-time systems (like games). * System programming features: Ability to manage your own memory and access the hardware directly. Pointers to garbage collected memory are distinguished @@ -33,22 +33,22 @@ Nim is efficient * Cross-module inlining. * Dynamic method binding with inlining and without virtual method table. * Compile time evaluation of user-defined functions. -* Whole program dead code elimination: Only *used functions* are included in +* Whole program dead code elimination: Only *used functions* are included in the executable. -* Value-based datatypes: For instance, objects and arrays can be allocated on +* Value-based datatypes: For instance, objects and arrays can be allocated on the stack. Nim is expressive ================= -* **The Nim compiler and all of the standard library are implemented in +* **The Nim compiler and all of the standard libraries are implemented in Nim.** * Built-in high level datatypes: strings, sets, sequences, etc. -* Modern type system with local type inference, tuples, variants, +* Modern type system with local type inference, tuples, variants, generics, etc. * User-defineable operators; code with new operators is often easier to read - than code which overloads built-in operators. For example, a + than code which overloads built-in operators. For example, a ``=~`` operator is defined in the ``re`` module. * Macros can modify the abstract syntax tree at compile time. @@ -58,7 +58,7 @@ Nim is elegant * Macros can use the imperative paradigm to construct parse trees. Nim does not require a different coding style for meta programming. -* Macros cannot change Nim's syntax because there is no need for it. +* Macros cannot change Nim's syntax because there is no need for it. Nim's syntax is flexible enough. * Statements are grouped by indentation but can span multiple lines. Indentation must not contain tabulators so the compiler always sees @@ -72,12 +72,12 @@ Nim plays nice with others Porting to other platforms is easy. * **The Nim Compiler can also generate C++ or Objective C for easier interfacing.** -* There are lots of bindings: for example, bindings to GTK2, the Windows API, - the POSIX API, OpenGL, SDL, Cairo, Python, Lua, TCL, X11, libzip, PCRE, +* There are lots of bindings: for example, bindings to GTK2, the Windows API, + the POSIX API, OpenGL, SDL, Cairo, Python, Lua, TCL, X11, libzip, PCRE, libcurl, mySQL and SQLite are included in the standard distribution or can easily be obtained via the `Nimble package manager `_. -* A C to Nim conversion utility: New bindings to C libraries are easily +* A C to Nim conversion utility: New bindings to C libraries are easily generated by ``c2nim``. From c7fac03abed7c4bf6c438635c4b353fff0af051d Mon Sep 17 00:00:00 2001 From: def Date: Sat, 3 Jan 2015 21:53:40 +0100 Subject: [PATCH 053/850] Remove debug messages --- lib/pure/httpclient.nim | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index acc80cfdb4..a4b8bbedb4 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -294,11 +294,9 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "", var r = if proxy == nil: parseUri(url) else: proxy.url var headers = substr($httpMethod, len("http")) if proxy == nil: - echo url headers.add(" " & r.path) if r.query.len > 0: headers.add("?" & r.query) - echo headers else: headers.add(" " & url) From d60d0072813046dae7a00874fca601c7fce71e29 Mon Sep 17 00:00:00 2001 From: def Date: Sun, 4 Jan 2015 22:59:41 +0100 Subject: [PATCH 054/850] Close async socket on error (instead of looping on epoll_wait with 100% CPU) --- lib/pure/asyncdispatch.nim | 4 ++++ lib/pure/selectors.nim | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 4bdce9cfb8..c4abdf9f31 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -878,6 +878,10 @@ else: let data = PData(info.key.data) assert data.fd == info.key.fd.TAsyncFD #echo("In poll ", data.fd.cint) + if EvError in info.events: + closeSocket(data.fd) + continue + if EvRead in info.events: # Callback may add items to ``data.readCBs`` which causes issues if # we are iterating over ``data.readCBs`` at the same time. We therefore diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim index 1c988c6091..b796dca7a9 100644 --- a/lib/pure/selectors.nim +++ b/lib/pure/selectors.nim @@ -23,7 +23,7 @@ proc `$`*(x: SocketHandle): string {.borrow.} type Event* = enum - EvRead, EvWrite + EvRead, EvWrite, EvError SelectorKey* = ref object fd*: SocketHandle @@ -152,6 +152,9 @@ elif defined(linux): let fd = s.events[i].data.fd.SocketHandle var evSet: set[Event] = {} + if (s.events[i].events and EPOLLERR) != 0: evSet = evSet + {EvError} + if (s.events[i].events and EPOLLHUP) != 0: evSet = evSet + {EvError} + if (s.events[i].events and EPOLLRDHUP) != 0: evSet = evSet + {EvError} if (s.events[i].events and EPOLLIN) != 0: evSet = evSet + {EvRead} if (s.events[i].events and EPOLLOUT) != 0: evSet = evSet + {EvWrite} let selectorKey = s.fds[fd] From f56dcd1505ea90947cd3cece1ac3ef3dcf418e21 Mon Sep 17 00:00:00 2001 From: def Date: Sun, 4 Jan 2015 23:06:48 +0100 Subject: [PATCH 055/850] Handle interrupt on epoll_wait graciously (allows strace to work) --- lib/pure/selectors.nim | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim index b796dca7a9..f17c6d3174 100644 --- a/lib/pure/selectors.nim +++ b/lib/pure/selectors.nim @@ -146,7 +146,11 @@ elif defined(linux): ## on the ``fd``. result = @[] let evNum = epoll_wait(s.epollFD, addr s.events[0], 64.cint, timeout.cint) - if evNum < 0: raiseOSError(osLastError()) + if evNum < 0: + let err = osLastError() + if err.cint == EINTR: + return @[] + raiseOSError(osLastError()) if evNum == 0: return @[] for i in 0 .. Date: Sun, 4 Jan 2015 05:36:43 +0100 Subject: [PATCH 056/850] Add multipart parameter to httpclient's post and postContent --- lib/pure/httpclient.nim | 161 +++++++++++++++++++++++++++++++--------- 1 file changed, 127 insertions(+), 34 deletions(-) diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index a4b8bbedb4..b6ff62bdcc 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -32,21 +32,12 @@ ## the server. ## ## .. code-block:: Nim -## var headers: string = "Content-Type: multipart/form-data; boundary=xyz\c\L" -## var body: string = "--xyz\c\L" -## # soap 1.2 output -## body.add("Content-Disposition: form-data; name=\"output\"\c\L") -## body.add("\c\Lsoap12\c\L") +## var data = newData() +## data["output"] = "soap12" +## data["uploaded_file"] = ("test.html", "text/html", +## "

test

") ## -## # html -## body.add("--xyz\c\L") -## body.add("Content-Disposition: form-data; name=\"uploaded_file\";" & -## " filename=\"test.html\"\c\L") -## body.add("Content-Type: text/html\c\L") -## body.add("\c\L

test

\c\L") -## body.add("--xyz--") -## -## echo(postContent("http://validator.w3.org/check", headers, body)) +## echo postContent("http://validator.w3.org/check", multipart=data) ## ## Asynchronous HTTP requests ## ========================== @@ -88,7 +79,7 @@ ## constructor should be used for this purpose. However, ## currently only basic authentication is supported. -import net, strutils, uri, parseutils, strtabs, base64, os +import net, strutils, uri, parseutils, strtabs, base64, os, mimetypes, math import asyncnet, asyncdispatch import rawsockets @@ -103,6 +94,10 @@ type url*: Uri auth*: string + MultipartEntries* = openarray[tuple[name, content: string]] + MultipartData* = ref object + content: seq[string] + ProtocolError* = object of IOError ## exception that is raised when server ## does not conform to the implemented ## protocol @@ -282,6 +277,104 @@ proc newProxy*(url: string, auth = ""): Proxy = ## Constructs a new ``TProxy`` object. result = Proxy(url: parseUri(url), auth: auth) +proc newData*: MultipartData = + ## Constructs a new ``MultipartData`` object. + MultipartData(content: @[]) + +proc add*(p: var MultipartData, name, content: string, filename: string = nil, contentType: string = nil) = + ## Add a value to the multipart data. Raises a `ValueError` exception if + ## `name`, `filename` or `contentType` contain newline characters. + + if {'\c','\L'} in name: + raise newException(ValueError, "name contains a newline character") + if filename != nil and {'\c','\L'} in filename: + raise newException(ValueError, "filename contains a newline character") + if contentType != nil and {'\c','\L'} in contentType: + raise newException(ValueError, "contentType contains a newline character") + + var str = "Content-Disposition: form-data; name=\"" & name & "\"" + if filename != nil: + str.add("; filename=\"" & filename & "\"") + str.add("\c\L") + if contentType != nil: + str.add("Content-Type: " & contentType & "\c\L") + str.add("\c\L" & content & "\c\L") + + p.content.add(str) + +proc add*(p: var MultipartData, xs: MultipartEntries): MultipartData {.discardable.} = + ## Add a list of multipart entries to the multipart data `p`. All values are + ## added without a filename and without a content type. + ## + ## .. code-block:: Nim + ## data.add({"action": "login", "format": "json"}) + for name, content in xs.items: + p.add(name, content) + result = p + +proc newData*(xs: MultipartEntries): MultipartData = + ## Create a new multipart data object and fill it with the entries `xs` + ## directly. + ## + ## .. code-block:: Nim + ## var data = newData({"action": "login", "format": "json"}) + result = MultipartData(content: @[]) + result.add(xs) + +proc addFiles*(p: var MultipartData, xs: openarray[tuple[name, file: string]]) {.discardable.} = + ## Add files to a multipart data object. The file will be opened from your + ## disk, read and sent with the automatically determined MIME type. Raises an + ## `IOError` if the file cannot be opened or reading fails. To manually + ## specify file content, filename and MIME type, use `[]=` instead. + ## + ## .. code-block:: Nim + ## data.addFiles({"uploaded_file": "public/test.html"}) + var m = newMimetypes() + for name, file in xs.items: + var contentType: string + let (dir, fName, ext) = splitFile(file) + if ext.len > 0: + contentType = m.getMimetype(ext[1..ext.high], nil) + p.add(name, readFile(file), fName & ext, contentType) + +proc `[]=`*(p: var MultipartData, name, content: string) = + ## Add a multipart entry to the multipart data `p`. The value is added + ## without a filename and without a content type. + ## + ## .. code-block:: Nim + ## data["username"] = "NimUser" + p.add(name, content) + +proc `[]=`*(p: var MultipartData, name: string, file: tuple[name, contentType, content: string]) = + ## Add a file to the multipart data `p`, specifying filename, contentType and + ## content manually. + ## + ## .. code-block:: Nim + ## data["uploaded_file"] = ("test.html", "text/html", + ## "

test

") + p.add(name, file.content, file.name, file.contentType) + +proc format(p: MultipartData): tuple[header, body: string] = + if p.content == nil or p.content.len == 0: + return ("", "") + + # Create boundary that is not in the data to be formatted + var bound: string + while true: + bound = $random(int.high) + var found = false + for s in p.content: + if bound in s: + found = true + if not found: + break + + result.header = "Content-Type: multipart/form-data; boundary=" & bound & "\c\L" + result.body = "" + for s in p.content: + result.body.add("--" & bound & "\c\L" & s) + result.body.add("--" & bound & "--\c\L") + proc request*(url: string, httpMethod = httpGET, extraHeaders = "", body = "", sslContext: SSLContext = defaultSSLContext, @@ -389,15 +482,21 @@ proc post*(url: string, extraHeaders = "", body = "", maxRedirects = 5, sslContext: SSLContext = defaultSSLContext, timeout = -1, userAgent = defUserAgent, - proxy: Proxy = nil): Response = + proxy: Proxy = nil, + multipart: MultipartData = nil): Response = ## | POSTs ``body`` to the ``url`` and returns a ``Response`` object. ## | This proc adds the necessary Content-Length header. ## | This proc also handles redirection. ## | Extra headers can be specified and must be separated by ``\c\L``. ## | An optional timeout can be specified in miliseconds, if reading from the ## server takes longer than specified an ETimeout exception will be raised. - var xh = extraHeaders & "Content-Length: " & $len(body) & "\c\L" - result = request(url, httpPOST, xh, body, sslContext, timeout, userAgent, + ## | The optional ``multipart`` parameter can be used to create + ## ``multipart/form-data`` POSTs comfortably. + let (mpHeaders, mpBody) = format(multipart) + + var xb = mpBody & body + var xh = extraHeaders & mpHeaders & "Content-Length: " & $len(xb) & "\c\L" + result = request(url, httpPOST, xh, xb, sslContext, timeout, userAgent, proxy) var lastUrl = "" for i in 1..maxRedirects: @@ -412,14 +511,17 @@ proc postContent*(url: string, extraHeaders = "", body = "", maxRedirects = 5, sslContext: SSLContext = defaultSSLContext, timeout = -1, userAgent = defUserAgent, - proxy: Proxy = nil): string = + proxy: Proxy = nil, + multipart: MultipartData = nil): string = ## | POSTs ``body`` to ``url`` and returns the response's body as a string ## | Raises exceptions for the status codes ``4xx`` and ``5xx`` ## | Extra headers can be specified and must be separated by ``\c\L``. ## | An optional timeout can be specified in miliseconds, if reading from the ## server takes longer than specified an ETimeout exception will be raised. + ## | The optional ``multipart`` parameter can be used to create + ## ``multipart/form-data`` POSTs comfortably. var r = post(url, extraHeaders, body, maxRedirects, sslContext, timeout, - userAgent, proxy) + userAgent, proxy, multipart) if r.status[0] in {'4','5'}: raise newException(HttpRequestError, r.status) else: @@ -710,18 +812,9 @@ when isMainModule: #var r = get("http://validator.w3.org/check?uri=http%3A%2F%2Fgoogle.com& # charset=%28detect+automatically%29&doctype=Inline&group=0") - var headers: string = "Content-Type: multipart/form-data; boundary=xyz\c\L" - var body: string = "--xyz\c\L" - # soap 1.2 output - body.add("Content-Disposition: form-data; name=\"output\"\c\L") - body.add("\c\Lsoap12\c\L") + var data = newData() + data["output"] = "soap12" + data["uploaded_file"] = ("test.html", "text/html", + "

test

") - # html - body.add("--xyz\c\L") - body.add("Content-Disposition: form-data; name=\"uploaded_file\";" & - " filename=\"test.html\"\c\L") - body.add("Content-Type: text/html\c\L") - body.add("\c\L

test

\c\L") - body.add("--xyz--") - - echo(postContent("http://validator.w3.org/check", headers, body)) + echo postContent("http://validator.w3.org/check", multipart=data) From 06ad80cc4555ec1cb80d46baac2d93525137314c Mon Sep 17 00:00:00 2001 From: def Date: Mon, 5 Jan 2015 01:30:03 +0100 Subject: [PATCH 057/850] indent = 0 looks better for `$`(node: JsonNode) --- lib/pure/json.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 385787d6c4..c5510a50e2 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -864,7 +864,7 @@ proc pretty*(node: JsonNode, indent = 2): string = proc `$`*(node: JsonNode): string = ## Converts `node` to its JSON Representation on one line. result = "" - toPretty(result, node, 1, false) + toPretty(result, node, 0, false) iterator items*(node: JsonNode): JsonNode = ## Iterator for the items of `node`. `node` has to be a JArray. From f223e94ccd98448e245e5a7bd7e7da396b9ae9c8 Mon Sep 17 00:00:00 2001 From: def Date: Mon, 5 Jan 2015 01:30:30 +0100 Subject: [PATCH 058/850] Add operator `%*` to JSON --- lib/pure/json.nim | 77 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/lib/pure/json.nim b/lib/pure/json.nim index c5510a50e2..eed01e3761 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -30,9 +30,28 @@ ## ## 1.3000000000000000e+00 ## true +## +## This module can also be used to comfortably create JSON using the `%*` +## operator: +## +## .. code-block:: nim +## +## var hisName = "John" +## let herAge = 31 +## var j = %* +## [ +## { +## "name": hisName, +## "age": 30 +## }, +## { +## "name": "Susan", +## "age": herAge +## } +## ] import - hashes, strutils, lexbase, streams, unicode + hashes, strutils, lexbase, streams, unicode, macros type JsonEventKind* = enum ## enumeration of all events that may occur when parsing @@ -625,6 +644,31 @@ proc `%`*(elements: openArray[JsonNode]): JsonNode = newSeq(result.elems, elements.len) for i, p in pairs(elements): result.elems[i] = p +proc toJson(x: expr): expr {.compiletime.} = + case x.kind + of nnkBracket: + result = newNimNode(nnkBracket) + for i in 0 .. Date: Mon, 5 Jan 2015 01:40:47 +0100 Subject: [PATCH 059/850] Check that p is not nil in format --- lib/pure/httpclient.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index b6ff62bdcc..3ab56cddf2 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -355,7 +355,7 @@ proc `[]=`*(p: var MultipartData, name: string, file: tuple[name, contentType, c p.add(name, file.content, file.name, file.contentType) proc format(p: MultipartData): tuple[header, body: string] = - if p.content == nil or p.content.len == 0: + if p == nil or p.content == nil or p.content.len == 0: return ("", "") # Create boundary that is not in the data to be formatted From d4955090ae4b18780e5b7b5333eba619622d0e1b Mon Sep 17 00:00:00 2001 From: def Date: Mon, 5 Jan 2015 01:55:52 +0100 Subject: [PATCH 060/850] post should work when extra headers don't have trailing newline --- lib/pure/httpclient.nim | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 3ab56cddf2..f95242a32a 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -494,8 +494,17 @@ proc post*(url: string, extraHeaders = "", body = "", ## ``multipart/form-data`` POSTs comfortably. let (mpHeaders, mpBody) = format(multipart) - var xb = mpBody & body - var xh = extraHeaders & mpHeaders & "Content-Length: " & $len(xb) & "\c\L" + template withNewLine(x): expr = + if x.len > 0 and not x.endsWith("\c\L"): + x & "\c\L" + else: + x + + var xb = mpBody.withNewLine() & body.withNewLine() + + var xh = extraHeaders.withNewLine() & mpHeaders.withNewLine() & + withNewLine("Content-Length: " & $len(xb)) + result = request(url, httpPOST, xh, xb, sslContext, timeout, userAgent, proxy) var lastUrl = "" From e77eec02f3c9bd81367247a9b0842ab67c979f92 Mon Sep 17 00:00:00 2001 From: def Date: Mon, 5 Jan 2015 01:58:39 +0100 Subject: [PATCH 061/850] A few more fixes to httpclient multipart --- lib/pure/httpclient.nim | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index f95242a32a..4096467938 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -281,7 +281,8 @@ proc newData*: MultipartData = ## Constructs a new ``MultipartData`` object. MultipartData(content: @[]) -proc add*(p: var MultipartData, name, content: string, filename: string = nil, contentType: string = nil) = +proc add*(p: var MultipartData, name, content: string, filename: string = nil, + contentType: string = nil) = ## Add a value to the multipart data. Raises a `ValueError` exception if ## `name`, `filename` or `contentType` contain newline characters. @@ -302,7 +303,8 @@ proc add*(p: var MultipartData, name, content: string, filename: string = nil, c p.content.add(str) -proc add*(p: var MultipartData, xs: MultipartEntries): MultipartData {.discardable.} = +proc add*(p: var MultipartData, xs: MultipartEntries): MultipartData + {.discardable.} = ## Add a list of multipart entries to the multipart data `p`. All values are ## added without a filename and without a content type. ## @@ -321,7 +323,8 @@ proc newData*(xs: MultipartEntries): MultipartData = result = MultipartData(content: @[]) result.add(xs) -proc addFiles*(p: var MultipartData, xs: openarray[tuple[name, file: string]]) {.discardable.} = +proc addFiles*(p: var MultipartData, xs: openarray[tuple[name, file: string]]): + MultipartData {.discardable.} = ## Add files to a multipart data object. The file will be opened from your ## disk, read and sent with the automatically determined MIME type. Raises an ## `IOError` if the file cannot be opened or reading fails. To manually @@ -336,6 +339,7 @@ proc addFiles*(p: var MultipartData, xs: openarray[tuple[name, file: string]]) { if ext.len > 0: contentType = m.getMimetype(ext[1..ext.high], nil) p.add(name, readFile(file), fName & ext, contentType) + result = p proc `[]=`*(p: var MultipartData, name, content: string) = ## Add a multipart entry to the multipart data `p`. The value is added @@ -345,7 +349,8 @@ proc `[]=`*(p: var MultipartData, name, content: string) = ## data["username"] = "NimUser" p.add(name, content) -proc `[]=`*(p: var MultipartData, name: string, file: tuple[name, contentType, content: string]) = +proc `[]=`*(p: var MultipartData, name: string, + file: tuple[name, contentType, content: string]) = ## Add a file to the multipart data `p`, specifying filename, contentType and ## content manually. ## From 7524610b310203c423f0fd593a05baca603e3a6c Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 5 Jan 2015 02:27:24 +0100 Subject: [PATCH 062/850] fixes #1796 --- lib/system/gc.nim | 36 ++++++++++++++++++++++++++++++---- tests/gc/closureleak.nim | 4 ++-- tests/gc/cyclecollector.nim | 21 ++++++++++++++++++++ tests/gc/gctest.nim | 3 ++- tests/testament/categories.nim | 13 ++++++++---- 5 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 tests/gc/cyclecollector.nim diff --git a/lib/system/gc.nim b/lib/system/gc.nim index e0db3fba43..58587cf7f7 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -49,7 +49,7 @@ type waMarkGlobal, # part of the backup/debug mark&sweep waMarkPrecise, # part of the backup/debug mark&sweep waZctDecRef, waPush, waCycleDecRef, waMarkGray, waScan, waScanBlack, - waCollectWhite, + waCollectWhite #, waDebug TFinalizer {.compilerproc.} = proc (self: pointer) {.nimcall, benign.} # A ref type can have a finalizer that is called before the object's @@ -595,9 +595,15 @@ proc scan(s: PCell) = else: s.setColor(rcWhite) forAllChildren(s, waScan) - + proc collectWhite(s: PCell) = - if s.color == rcWhite and s notin gch.cycleRoots: + # This is a hacky way to deal with the following problem (bug #1796) + # Consider this content in cycleRoots: + # x -> a; y -> a where 'a' is an acyclic object so not included in + # cycleRoots itself. Then 'collectWhite' used to free 'a' twice. The + # 'isAllocatedPtr' check prevents this. This also means we do not need + # to query 's notin gch.cycleRoots' at all. + if isAllocatedPtr(gch.region, s) and s.color == rcWhite: s.setColor(rcBlack) forAllChildren(s, waCollectWhite) freeCyclicCell(gch, s) @@ -648,6 +654,28 @@ when useMarkForDebug or useBackupGc: if objStart != nil: markS(gch, objStart) +when logGC: + var + cycleCheckA: array[100, PCell] + cycleCheckALen = 0 + + proc alreadySeen(c: PCell): bool = + for i in 0 .. Date: Sun, 4 Jan 2015 19:48:00 +0200 Subject: [PATCH 063/850] fix #1859 --- compiler/sigmatch.nim | 21 +++++++++++++-------- tests/metatype/tstaticparams.nim | 21 +++++++++++++++++++++ 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 0182cb5554..721f7e3187 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1004,15 +1004,19 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = result = typeRel(c, x, a) # check if it fits of tyStatic: - if aOrig.kind == tyStatic: - result = typeRel(c, f.lastSon, a) - if result != isNone and f.n != nil: - if not exprStructuralEquivalent(f.n, aOrig.n): - result = isNone - if result != isNone: put(c.bindings, f, aOrig) + let prev = PType(idTableGet(c.bindings, f)) + if prev == nil: + if aOrig.kind == tyStatic: + result = typeRel(c, f.lastSon, a) + if result != isNone and f.n != nil: + if not exprStructuralEquivalent(f.n, aOrig.n): + result = isNone + if result != isNone: put(c.bindings, f, aOrig) + else: + result = isNone else: - result = isNone - + result = typeRel(c, prev, aOrig) + of tyTypeDesc: var prev = PType(idTableGet(c.bindings, f)) if prev == nil: @@ -1051,6 +1055,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = of tyFromExpr: # fix the expression, so it contains the already instantiated types + if f.n == nil: return isGeneric let reevaluated = tryResolvingStaticExpr(c, f.n) case reevaluated.typ.kind of tyTypeDesc: diff --git a/tests/metatype/tstaticparams.nim b/tests/metatype/tstaticparams.nim index e98a2871f5..7fc5f479bc 100644 --- a/tests/metatype/tstaticparams.nim +++ b/tests/metatype/tstaticparams.nim @@ -119,3 +119,24 @@ foo_2.intOrFloat foo_2.yinOrYang foo_3.yinOrYang +# bug 1859 + +type + TypeWith2Params[N, M: static[int]] = object + +proc bindBothParams[N](x: TypeWith2Params[N, N]) = discard +proc dontBind1[N,M](x: TypeWith2Params[N, M]) = discard +proc dontBind2(x: TypeWith2Params) = discard + +var bb_1: TypeWith2Params[2, 2] +var bb_2: TypeWith2Params[2, 3] + +bindBothParams(bb_1) +reject bindBothParams(bb_2) + +dontBind1 bb_1 +dontBind1 bb_2 + +dontBind2 bb_1 +dontBind2 bb_2 + From 5e4ae8dbb4f5e3ca8cf8c1fb356ca0f500f32746 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Mon, 5 Jan 2015 03:51:18 +0200 Subject: [PATCH 064/850] fix #1858; Add support for generic templates and macros Implementation notes: Just after overload resolution, the resolved generic params will be added to the call expression to be later processed in evalTemplate and evalMacroCall. These procs have been modified to handle the increased number of parameters, but one remaining issue is that immediate templates and macros don't go through the same process. The next commit will outlaw the use of generic parameters with such macros. --- compiler/ast.nim | 4 ++++ compiler/evaltempl.nim | 52 +++++++++++++++++++++++++++--------------- compiler/semcall.nim | 17 ++++++++++++-- compiler/seminst.nim | 25 ++++++++++---------- compiler/vm.nim | 32 ++++++++++++++++++-------- compiler/vmgen.nim | 23 ++++++++++++++++--- 6 files changed, 109 insertions(+), 44 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 883b68d71d..a071060d40 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1341,6 +1341,10 @@ proc skipTypes*(t: PType, kinds: TTypeKinds): PType = result = t while result.kind in kinds: result = lastSon(result) +proc safeSkipTypes*(t: PType, kinds: TTypeKinds): PType = + result = if t != nil: t.skipTypes(kinds) + else: nil + proc isGCedMem*(t: PType): bool {.inline.} = result = t.kind in {tyString, tyRef, tySequence} or t.kind == tyProc and t.callConv == ccClosure diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index 78cc691c06..ecb898d8ac 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -25,16 +25,22 @@ proc copyNode(ctx: TemplCtx, a, b: PNode): PNode = if ctx.instLines: result.info = b.info proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) = + template handleParam(param) = + let x = param + if x.kind == nkArgList: + for y in items(x): result.add(y) + else: + result.add copyTree(x) + case templ.kind of nkSym: var s = templ.sym if s.owner.id == c.owner.id: - if s.kind == skParam: - let x = actual.sons[s.position] - if x.kind == nkArgList: - for y in items(x): result.add(y) - else: - result.add copyTree(x) + case s.kind + of skParam: + handleParam actual.sons[s.position] + of skGenericParam: + handleParam actual.sons[s.owner.typ.len + s.position - 1] else: internalAssert sfGenSym in s.flags var x = PSym(idTableGet(c.mapping, s)) @@ -56,21 +62,31 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) = proc evalTemplateArgs(n: PNode, s: PSym): PNode = # if the template has zero arguments, it can be called without ``()`` # `n` is then a nkSym or something similar - var a: int - case n.kind - of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit: - a = sonsLen(n) - else: a = 0 - var f = s.typ.sonsLen - if a > f: globalError(n.info, errWrongNumberOfArguments) + var totalParams = case n.kind + of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit: expectedRegularParams + genericParams: + globalError(n.info, errWrongNumberOfArguments) result = newNodeI(nkArgList, n.info) - for i in countup(1, f - 1): - var arg = if i < a: n.sons[i] else: copyTree(s.typ.n.sons[i].sym.ast) - if arg == nil or arg.kind == nkEmpty: - localError(n.info, errWrongNumberOfArguments) - addSon(result, arg) + for i in 1 .. givenRegularParams: + result.addSon n.sons[i] + for i in givenRegularParams+1 .. expectedRegularParams: + let default = s.typ.n.sons[i].sym.ast + if default.kind == nkEmpty: + localError(n.info, errWrongNumberOfArguments) + result.addSon default.copyTree + + for i in 1 .. genericParams: + result.addSon n.sons[givenRegularParams + i] + var evalTemplateCounter* = 0 # to prevent endless recursion in templates instantiation diff --git a/compiler/semcall.nim b/compiler/semcall.nim index a712cc195e..961c61c57a 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -283,8 +283,21 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode = if containsGenericType(result.typ) or x.fauxMatch == tyUnknown: result.typ = newTypeS(x.fauxMatch, c) return - if finalCallee.ast.sons[genericParamsPos].kind != nkEmpty: - finalCallee = generateInstance(c, x.calleeSym, x.bindings, n.info) + let gp = finalCallee.ast.sons[genericParamsPos] + if gp.kind != nkEmpty: + if x.calleeSym.kind notin {skMacro, skTemplate}: + finalCallee = generateInstance(c, x.calleeSym, x.bindings, n.info) + else: + # For macros and templates, the resolved generic params + # are added as normal params. + for s in instantiateGenericParamList(c, gp, x.bindings): + case s.kind + of skConst: + x.call.add s.ast + of skType: + x.call.add newSymNode(s, n.info) + else: + internalAssert false result = x.call instGenericConvertersSons(c, result, x) result.sons[0] = newSymNode(finalCallee, result.sons[0].info) diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 81a4465c59..dd60e08810 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -10,14 +10,10 @@ # This module implements the instantiation of generic procs. # included from sem.nim -proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable, - entry: var TInstantiation) = - if n.kind != nkGenericParams: - internalError(n.info, "instantiateGenericParamList; no generic params") - newSeq(entry.concreteTypes, n.len) +iterator instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable): PSym = + internalAssert n.kind == nkGenericParams for i, a in n.pairs: - if a.kind != nkSym: - internalError(a.info, "instantiateGenericParamList; no symbol") + internalAssert a.kind == nkSym var q = a.sym if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyStatic, tyIter}+tyTypeClasses: continue @@ -42,8 +38,7 @@ proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable, #t = ReplaceTypeVarsT(cl, t) s.typ = t if t.kind == tyStatic: s.ast = t.n - addDecl(c, s) - entry.concreteTypes[i] = t + yield s proc sameInstantiation(a, b: TInstantiation): bool = if a.concreteTypes.len == b.concreteTypes.len: @@ -196,7 +191,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, ## The `pt` parameter is a type-unsafe mapping table used to link generic ## parameters to their concrete types within the generic instance. # no need to instantiate generic templates/macros: - if fn.kind in {skTemplate, skMacro}: return fn + internalAssert fn.kind notin {skMacro, skTemplate} # generates an instantiated proc if c.instCounter > 1000: internalError(fn.ast.info, "nesting too deep") inc(c.instCounter) @@ -213,12 +208,18 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, result.ast = n pushOwner(result) openScope(c) - internalAssert n.sons[genericParamsPos].kind != nkEmpty + let gp = n.sons[genericParamsPos] + internalAssert gp.kind != nkEmpty n.sons[namePos] = newSymNode(result) pushInfoContext(info) var entry = TInstantiation.new entry.sym = result - instantiateGenericParamList(c, n.sons[genericParamsPos], pt, entry[]) + newSeq(entry.concreteTypes, gp.len) + var i = 0 + for s in instantiateGenericParamList(c, gp, pt): + addDecl(c, s) + entry.concreteTypes[i] = s.typ + inc i pushProcCon(c, result) instantiateProcType(c, pt, result, info) n.sons[genericParamsPos] = ast.emptyNode diff --git a/compiler/vm.nim b/compiler/vm.nim index ad0d3b0a17..4072ed7659 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1417,12 +1417,20 @@ proc evalStaticStmt*(module: PSym, e: PNode, prc: PSym) = proc setupCompileTimeVar*(module: PSym, n: PNode) = discard evalConstExprAux(module, nil, n, emStaticStmt) -proc setupMacroParam(x: PNode): PNode = - result = x - if result.kind in {nkHiddenSubConv, nkHiddenStdConv}: result = result.sons[1] - result = canonValue(result) - result.flags.incl nfIsRef - result.typ = x.typ +proc setupMacroParam(x: PNode, typ: PType): TFullReg = + case typ.kind + of tyStatic: + putIntoReg(result, x) + of tyTypeDesc: + putIntoReg(result, x) + else: + result.kind = rkNode + var n = x + if n.kind in {nkHiddenSubConv, nkHiddenStdConv}: n = n.sons[1] + n = n.canonValue + n.flags.incl nfIsRef + n.typ = x.typ + result.node = n var evalMacroCounter: int @@ -1442,6 +1450,7 @@ proc evalMacroCall*(module: PSym, n, nOrig: PNode, sym: PSym): PNode = c.callsite = nOrig let start = genProc(c, sym) + # c.echoCode start var tos = PStackFrame(prc: sym, comesFrom: 0, next: nil) let maxSlots = sym.offset @@ -1457,9 +1466,14 @@ proc evalMacroCall*(module: PSym, n, nOrig: PNode, sym: PSym): PNode = tos.slots[0].kind = rkNode tos.slots[0].node = newNodeIT(nkEmpty, n.info, sym.typ.sons[0]) # setup parameters: - for i in 1 .. < min(tos.slots.len, L): - tos.slots[i].kind = rkNode - tos.slots[i].node = setupMacroParam(n.sons[i]) + for i in 1.. Date: Mon, 5 Jan 2015 03:56:05 +0200 Subject: [PATCH 065/850] unstaged file --- compiler/vmgen.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 7b574bccc2..8444af7ba3 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -165,7 +165,7 @@ const HighRegisterPressure = 40 proc getTemp(c: PCtx; tt: PType): TRegister = - let typ = tt.skipTypes({tyStatic}) + let typ = tt.safeSkipTypes({tyStatic}) let c = c.prc # we prefer the same slot kind here for efficiency. Unfortunately for # discardable return types we may not know the desired type. This can happen From f2fdac531dc73695018ceb38d4c9f017f8c34b2a Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Mon, 5 Jan 2015 03:57:09 +0200 Subject: [PATCH 066/850] test cases for generic macros --- tests/static/tstaticparammacro.nim | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/static/tstaticparammacro.nim b/tests/static/tstaticparammacro.nim index 7fb9e20142..ebd6caa470 100644 --- a/tests/static/tstaticparammacro.nim +++ b/tests/static/tstaticparammacro.nim @@ -10,6 +10,9 @@ AST a AST b (e: [55, 66], f: [77, 88]) 55 +10 +20Test +20 ''' """ @@ -50,3 +53,22 @@ macro mB(data: static[Tb]): stmt = mA(a) mB(b) +type + Foo[N: static[int], Z: static[string]] = object + +macro staticIntMacro(f: static[int]): stmt = echo f +staticIntMacro 10 + +var + x: Foo[20, "Test"] + +macro genericMacro[N; Z: static[string]](f: Foo[N, Z], ll = 3, zz = 12): stmt = + echo N, Z + +genericMacro x + +template genericTemplate[N, Z](f: Foo[N, Z], ll = 3, zz = 12): int = N + +static: + echo genericTemplate(x) # Error: internal error: (filename: compiler/evaltempl.nim, line: 39) + From e26846d0acd57e14be952cee9ad7ef2193d349d2 Mon Sep 17 00:00:00 2001 From: Michael Sheets Date: Sun, 4 Jan 2015 22:01:50 -0600 Subject: [PATCH 067/850] Add TextMate bundle link --- web/question.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/web/question.txt b/web/question.txt index d3a2dd5c08..c271558589 100644 --- a/web/question.txt +++ b/web/question.txt @@ -110,6 +110,7 @@ General - Scite: Included - Gedit: The `Aporia .lang file `_ - jEdit: https://github.com/exhu/nimrod-misc/tree/master/jedit + - TextMate: Available in bundle installer (`Repository `_) .. container:: standout From 41cf963848e577d9722cd5a0816c1435865b45ea Mon Sep 17 00:00:00 2001 From: def Date: Mon, 5 Jan 2015 13:19:10 +0100 Subject: [PATCH 068/850] Remove debugging echos again --- lib/pure/json.nim | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/pure/json.nim b/lib/pure/json.nim index eed01e3761..1b4b135b63 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -665,9 +665,7 @@ proc toJson(x: expr): expr {.compiletime.} = macro `%*`*(x: expr): expr = ## Convert an expression to a JsonParser directly, without having to specify ## `%` for every element. - echo x.treeRepr result = toJson(x) - echo result.treeRepr proc `==`* (a,b: JsonNode): bool = ## Check two nodes for equality From 9cf948e0c808494d663825402960ed09006d3b25 Mon Sep 17 00:00:00 2001 From: def Date: Mon, 5 Jan 2015 18:29:17 +0100 Subject: [PATCH 069/850] Rename newData() to newMultipartData() --- lib/pure/httpclient.nim | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 4096467938..bfdfed72c2 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -32,7 +32,7 @@ ## the server. ## ## .. code-block:: Nim -## var data = newData() +## var data = newMultipartData() ## data["output"] = "soap12" ## data["uploaded_file"] = ("test.html", "text/html", ## "

test

") @@ -277,7 +277,7 @@ proc newProxy*(url: string, auth = ""): Proxy = ## Constructs a new ``TProxy`` object. result = Proxy(url: parseUri(url), auth: auth) -proc newData*: MultipartData = +proc newMultipartData*: MultipartData = ## Constructs a new ``MultipartData`` object. MultipartData(content: @[]) @@ -314,12 +314,12 @@ proc add*(p: var MultipartData, xs: MultipartEntries): MultipartData p.add(name, content) result = p -proc newData*(xs: MultipartEntries): MultipartData = +proc newMultipartData*(xs: MultipartEntries): MultipartData = ## Create a new multipart data object and fill it with the entries `xs` ## directly. ## ## .. code-block:: Nim - ## var data = newData({"action": "login", "format": "json"}) + ## var data = newMultipartData({"action": "login", "format": "json"}) result = MultipartData(content: @[]) result.add(xs) @@ -826,7 +826,7 @@ when isMainModule: #var r = get("http://validator.w3.org/check?uri=http%3A%2F%2Fgoogle.com& # charset=%28detect+automatically%29&doctype=Inline&group=0") - var data = newData() + var data = newMultipartData() data["output"] = "soap12" data["uploaded_file"] = ("test.html", "text/html", "

test

") From 076f99315010da250ea69f67dea6fabe7cabdec3 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Mon, 5 Jan 2015 18:15:18 +0000 Subject: [PATCH 070/850] Fixes nim-lang/nimble#84 --- lib/wrappers/openssl.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index f091d8f46b..29fe3a9210 100644 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -50,7 +50,7 @@ when useWinVersion: from winlean import SocketHandle else: const - versions = "(|.1.0.0|.0.9.9|.0.9.8|.0.9.7|.0.9.6|.0.9.5|.0.9.4)" + versions = "(.10|.1.0.1|.1.0.0|.0.9.9|.0.9.8|.0.9.7|.0.9.6|.0.9.5|.0.9.4)" when defined(macosx): const DLLSSLName = "libssl" & versions & ".dylib" From d99454314cdaf9bf971b00443940775f5bcfc3e7 Mon Sep 17 00:00:00 2001 From: Flaviu Tamas Date: Mon, 5 Jan 2015 18:52:26 -0500 Subject: [PATCH 071/850] Make unittest.nim print stack trace --- lib/pure/unittest.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index 21efea3bc5..4e243b8f47 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -84,6 +84,7 @@ template test*(name: expr, body: stmt): stmt {.immediate, dirty.} = except: checkpoint("Unhandled exception: " & getCurrentExceptionMsg()) + echo getCurrentException().getStackTrace() fail() finally: From 2399f3b03d6953dea57b214eb16e3ce9bb90f85e Mon Sep 17 00:00:00 2001 From: def Date: Tue, 6 Jan 2015 01:28:18 +0100 Subject: [PATCH 072/850] Some GC renames to get rid of deprecation warnings --- lib/system/gc2.nim | 2 +- lib/system/mmdisp.nim | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/system/gc2.nim b/lib/system/gc2.nim index ee52b54f56..b0173b78f3 100644 --- a/lib/system/gc2.nim +++ b/lib/system/gc2.nim @@ -1344,7 +1344,7 @@ when not defined(useNimRtl): else: dec(gch.recGcLock) - proc GC_setStrategy(strategy: TGC_Strategy) = + proc GC_setStrategy(strategy: GC_Strategy) = case strategy of gcThroughput: nil of gcResponsiveness: nil diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim index e091c08897..a1a0353cac 100644 --- a/lib/system/mmdisp.nim +++ b/lib/system/mmdisp.nim @@ -144,7 +144,7 @@ when defined(boehmgc): proc GC_disable() = boehmGC_disable() proc GC_enable() = boehmGC_enable() proc GC_fullCollect() = boehmGCfullCollect() - proc GC_setStrategy(strategy: TGC_Strategy) = discard + proc GC_setStrategy(strategy: GC_Strategy) = discard proc GC_enableMarkAndSweep() = discard proc GC_disableMarkAndSweep() = discard proc GC_getStatistics(): string = return "" @@ -221,7 +221,7 @@ elif defined(nogc) and defined(useMalloc): proc GC_disable() = discard proc GC_enable() = discard proc GC_fullCollect() = discard - proc GC_setStrategy(strategy: TGC_Strategy) = discard + proc GC_setStrategy(strategy: GC_Strategy) = discard proc GC_enableMarkAndSweep() = discard proc GC_disableMarkAndSweep() = discard proc GC_getStatistics(): string = return "" @@ -281,7 +281,7 @@ elif defined(nogc): proc GC_disable() = discard proc GC_enable() = discard proc GC_fullCollect() = discard - proc GC_setStrategy(strategy: TGC_Strategy) = discard + proc GC_setStrategy(strategy: GC_Strategy) = discard proc GC_enableMarkAndSweep() = discard proc GC_disableMarkAndSweep() = discard proc GC_getStatistics(): string = return "" From 6a8d38f35837d1b6b1a87bd2fa8f113e1a306866 Mon Sep 17 00:00:00 2001 From: Flaviu Tamas Date: Mon, 5 Jan 2015 21:33:02 -0500 Subject: [PATCH 073/850] Add an example and remove future claims The future claims haven't been addressed for 3 years, they are unlikely to be fixed soon. --- lib/pure/unittest.nim | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index 21efea3bc5..814626cfa7 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -1,7 +1,7 @@ # # # Nim's Runtime Library -# (c) Copyright 2012 Nim Contributors +# (c) Copyright 2015 Nim Contributors # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -9,12 +9,27 @@ ## :Author: Zahary Karadjov ## -## This module implements the standard unit testing facilities such as -## suites, fixtures and test cases as well as facilities for combinatorial -## and randomzied test case generation (not yet available) -## and object mocking (not yet available) +## This module implements boilerplate to make testing easy. ## -## It is loosely based on C++'s boost.test and Haskell's QuickTest +## Example: +## +## .. code:: nim +## +## suite "description for this stuff": +## test "essential truths": +## # give up and stop if this fails +## require(true) +## +## test "slightly less obvious stuff": +## # print a nasty message and move on, skipping +## # the remainder of this block +## check(1 != 1) +## check("asd"[2] == 'd') +## +## test "out of bounds error is thrown on bad access": +## let v = @[1, 2, 3] # you can do initialization here +## expect(IndexError): +## discard v[4] import macros From 9a36c17c05e458d596e4ecc60322f0bf9d6d3ae6 Mon Sep 17 00:00:00 2001 From: def Date: Tue, 6 Jan 2015 03:53:21 +0100 Subject: [PATCH 074/850] Add workaround for TCC to make POSIX_SPAWN_USEVFORK available --- lib/posix/posix.nim | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index 0498a0e709..d56adf7f50 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -1739,7 +1739,12 @@ when hasSpawnH: when defined(linux): # better be safe than sorry; Linux has this flag, macosx doesn't, don't # know about the other OSes - var POSIX_SPAWN_USEVFORK* {.importc, header: "".}: cint + when defined(tcc): + # TCC doesn't define __USE_GNU, so we can't get the magic number from + # spawn.h + const POSIX_SPAWN_USEVFORK* = cint(0x40) + else: + var POSIX_SPAWN_USEVFORK* {.importc, header: "".}: cint else: # macosx lacks this, so we define the constant to be 0 to not affect # OR'ing of flags: From 8f446eb5413cc318f0f6dcaa233d5bced84827a0 Mon Sep 17 00:00:00 2001 From: Flaviu Tamas Date: Mon, 5 Jan 2015 21:54:06 -0500 Subject: [PATCH 075/850] Properly use the terminal module The documentation for terminal says > Changing the style is permanent even after program termination! Use the code > `system.addQuitProc(resetAttributes)` to restore the defaults. --- lib/pure/unittest.nim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index 21efea3bc5..77b23b067b 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -209,3 +209,5 @@ if envOutLvl.len > 0: if $opt == envOutLvl: outputLevel = opt break + +system.addQuitProc(resetAttributes) From 2f9fd32770a283a9d763ab993979be3152401a49 Mon Sep 17 00:00:00 2001 From: Guillaume Gelin Date: Tue, 6 Jan 2015 15:09:12 +0100 Subject: [PATCH 076/850] Make website.tmpl line endings consistant (using Unix style) --- tools/website.tmpl | 192 ++++++++++++++++++++++----------------------- 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/tools/website.tmpl b/tools/website.tmpl index 0c059fb871..ff29c160b2 100644 --- a/tools/website.tmpl +++ b/tools/website.tmpl @@ -1,23 +1,23 @@ #! stdtmpl | standard #proc generateHTMLPage(c: var TConfigData, currentTab, content, rss: string): string = # result = "" - + - - - $c.projectTitle + + + $c.projectTitle - + #if len(rss) > 0: #end if - - - # if currentTab == "index":
# else:
-# end -
+# end +
-# if currentTab == "index": -
+# if currentTab == "index": +
-
-
-

Nim looks like this..

-
# compute average line length
-var
-  sum = 0
-  count = 0
-
-for line in stdin.lines:
-  sum += line.len
-  count += 1
-
-echo("Average line length: ",
-  if count > 0: sum / count else: 0)
-
-
-
-

..and this...

-
# create and greet someone
-type Person = object
-  name: string
-  age: int
-
-proc greet(p: Person) =
-  echo "Hi, I'm ", p.name, "."
-  echo "I am ", p.age, " years old."
-
-var p = Person(name:"Jon", age:18)
-p.greet() # or greet(p)
-
-
+
+
+

Nim looks like this..

+
# compute average line length
+var
+  sum = 0
+  count = 0
+
+for line in stdin.lines:
+  sum += line.len
+  count += 1
+
+echo("Average line length: ",
+  if count > 0: sum / count else: 0)
+
+
+
+

..and this...

+
# create and greet someone
+type Person = object
+  name: string
+  age: int
+
+proc greet(p: Person) =
+  echo "Hi, I'm ", p.name, "."
+  echo "I am ", p.age, " years old."
+
+var p = Person(name:"Jon", age:18)
+p.greet() # or greet(p)
+
+

Why should I be excited?

@@ -129,14 +129,14 @@ View at: localhost:5000

-
-
-
-
-
-# end -
# end if -

Latest News

+

Latest News

- -
-
+# end if +
+ + + -
-
-
-
+
+
+
+
- $content -
-
-
- - - - + $content + +
+
+ + + + +# end if # if c.gaId != nil: + +# end if diff --git a/web/assets/images/docs-articles.png b/web/assets/images/docs-articles.png new file mode 100644 index 0000000000000000000000000000000000000000..7f800ea33ea7ee8b218cfcf10d2acd6a9b925f67 GIT binary patch literal 381 zcmeAS@N?(olHy`uVBq!ia0vp@3=9l>9Bd2>3}5P}U1DHhU@3O;4B_D5;Hcq9>0n@B z;4JWnEM{Qfy$-^RP8zc-7#J8NOI#yLg7ec#$`gxH8OqDc^)mCai<1)zQuXqS(r3T3 zkz!zA_~q&17@{$8>I7TA!vO*<`z!x(a(ra!YO!#VvS4IYf533z5!0nWl*|Gu1`*L_$w?UaMkye--{$8i;5MKtfxPYJ^fZTBmDW*CC3UDe5n^&dQRh) h!?l2klCJ-yjhnpk_suSsXJBAp@O1TaS?83{1OQG}mSO+^ literal 0 HcmV?d00001 diff --git a/web/assets/images/docs-examples.png b/web/assets/images/docs-examples.png new file mode 100644 index 0000000000000000000000000000000000000000..e6d27e03487084dc6330115681992e011910fb59 GIT binary patch literal 596 zcmeAS@N?(olHy`uVBq!ia0y~yU=UznVBq0kV_;y&es0^yz`(##?Bp53!NI{%!;#X# zz`(#+;1OBOz`%PQgc+SQW>+vUFi4iTMwA5SrTG%ULc({UdJ}zM#Z)3 zFSPW<_k3Q=;3##*B#nL1yUwf`f2>3p)eXeVV{78l+}=IQn%V zX1-b5Uwe){S&fbLZ-ej}iLlQ_#`fCHTmAm?PfNT!>ERDPV+IBW22WQ%mvv4FO#sbx B{+$2- literal 0 HcmV?d00001 diff --git a/web/assets/images/docs-internals.png b/web/assets/images/docs-internals.png new file mode 100644 index 0000000000000000000000000000000000000000..e03a952d59a9f49e1191d53f2e0f6d77c14dce4b GIT binary patch literal 621 zcmeAS@N?(olHy`uVBq!ia0y~yVBiN~4mJh`2J356y%-o6Sc;uILpV4%IBGajIv5xj zI14-?iy0VruY)k7lg8`{1_lPn64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xh zq!<_&UwOJXhGEuaAuOJ;Q(=ACyqSl&cdN1&N_xgg1Z~cpz`-GZk-d{4LXt66h=+5PpHx_zSQgnq#{EKCtP z(Kd}Y@-NvgD4)DfDVgQt+F9PV_nD6Ci*_}otd19uGCsaf@a9y>{ZlUgbsUt8i#_`09ywI#cyw+1$pz0d zOvCi{nY@|dbA9f9<86)&3iEY33&aDASFqY1T;;~uIA7s@in!IB?b`OyGDaUcDpVs( zEcjclzKFW=Tb*;p8u1WzHlA6B)EwIvAAI+se(v|wd&l>c?|faiwoLl+Jukh|wQK(} ZNlZR_cCxxxF#`hwgQu&X%Q~loCIHyA3D5ul literal 0 HcmV?d00001 diff --git a/web/assets/images/docs-libraries.png b/web/assets/images/docs-libraries.png new file mode 100644 index 0000000000000000000000000000000000000000..b14952f7dbc2c4e8ed562afad4b5635cf2ba4984 GIT binary patch literal 335 zcmeAS@N?(olHy`uVBq!ia0vp@3=9nX9Bd2>4ED;d^e0|SF(iEBhjaDG}zd16s2LwR|*US?i)adKios$PCk`s{Z$ zQVa|XXFOdTLo_Cyy2UWnA+|Fw(2G38y{)Bk{<)?YU$%X#L@4BA< zYG?92v}&c%x@GSpMK~A)K8m;Ro7a3tg?&}}!dQ2WyuEkTBLAs0&2joYmnXNQir?dr zNj$sa!T107ls6sce!E}kXhJzhdeetsr)OzaL54~T3bwBc)!KZif7^{vS(lefI@boAR0vUQ-l#Us;p|=8c9nFKW83%k-~YYe z-sa&0Cy#U?`?V!?`xPE*RR!Kj;9OiMm7;%2ou{@}dd`Xz;rkifhr28^ZE5mSyH#UR}}m zJdW+ovmBls$+dCyOIg_+=4%--yA76 zdSP?Z69$(K3%=J3cNR>{Y+8Tib6M9b#RVKW?n^XQz0&Vp_L<+YPs7HsQqf5)g3qEY zcHXOarVW=qTeIY^kdn9f$9|{y**gSg^|MzuY z?yzm!BJ;!hp-cR$+D+PbDtu+LL`7}cj4sa#{IZVY5~F+D=R(I#`yGw0{w~vda6%#= z`xJkaI=8#^g9*yY7b>_~j>fH=&#vMBRloDW@6d;C>@hbj4Awbu{m>}*aXMwwwXCp1 n6Qeou8#6B(eE-Y)pGj5d;Dq~)cHbEo7#KWV{an^LB{Ts5IXeo9 literal 0 HcmV?d00001 diff --git a/web/assets/images/docs-tutorials.png b/web/assets/images/docs-tutorials.png new file mode 100644 index 0000000000000000000000000000000000000000..926a4b58b153684218d931fb700b6f5fe9581a74 GIT binary patch literal 560 zcmeAS@N?(olHy`uVBq!ia0y~yVBlw9VBq6mV_;zT(B<}?fq{Xg*vT`5gM)*kh9jke zfq{Xuz$3Dlfr0lr2s1iq%&uTyV2~_vjVKAuPb(=;EJ|f4FE7{2%*!rLPAo{(%P&fw z{mw>;fq`+Yr;B5V#>CP|wi&^R60P%#Cwp{f=5_Nam2S1VGtEQLg}pV;RaQiOp~9>e zO0S;rA89zcwpk&gEpL~GM`3}$l3>>y0qKAO;VzC>6Vw(sO@4gg&;4KL&VMev_qlG< z*#|F<-F~=X-o7kL_0=K1*X1i7o_H^DU3>M8IXu_PV>iSweEU{#KSgx)7W;0h zduyBtJ$Gv#`Pi%U3OZv9nh+E^7A1T6sfThCC@dPPJtJ8KIu$%uLdm35EN& ziR4aETW(N%;QYVTOraZd=eieXr|Ud36h07sVQQ9U73+kP)5}kldS+q(rgSEu&K=F*%9czR- zgLBm~?F0AC={hMH)ZUwG-J-0Eo#Jl%TNC-&a|@BVM{$#A|DH}$ZF3l*kn*W1eMSf*{8 z=$=x~z{l*ZyKd^X_xZv-Yr_4w;@xCezA@Z4oZl;V_1NO+dKYp&|7TE)S@&bnx~0n* Q7#J8lUHx3vIVCg!0CfTGQvd(} literal 0 HcmV?d00001 diff --git a/web/assets/index.js b/web/assets/index.js new file mode 100644 index 0000000000..f10dc603d0 --- /dev/null +++ b/web/assets/index.js @@ -0,0 +1,34 @@ +"use strict"; + +var timer; +var prevIndex = 0; +var slideCount = 2; + +function setSlideShow(index, short) { + if (index >= slideCount) index = 0; + document.getElementById("slide"+prevIndex).className = ""; + document.getElementById("slide"+index).className = "active"; + document.getElementById("slideControl"+prevIndex).className = ""; + document.getElementById("slideControl"+index).className = "active"; + prevIndex = index; + startTimer(short ? 8000 : 32000); +} + +function nextSlide() { setSlideShow(prevIndex + 1, true); } +function startTimer(t) { timer = setTimeout(nextSlide, t); } + +function slideshow_enter() { clearTimeout(timer); } +function slideshow_exit () { startTimer(16000); } + +function slideshow_click(index) { + clearTimeout(timer); + setSlideShow(index, false); +} + +window.onload = function() { + var slideshow = document.getElementById("slideshow"); + slideshow.onmouseenter = slideshow_enter; + slideshow.onmouseleave = slideshow_exit; + slideCount = slideshow.children.length; + startTimer(8000); +}; \ No newline at end of file diff --git a/web/assets/style.css b/web/assets/style.css index da4cff05c1..5e2115ef13 100644 --- a/web/assets/style.css +++ b/web/assets/style.css @@ -8,10 +8,18 @@ body { min-width:1030px; margin:0; font:13pt "arial"; - background:#152534 url("images/bg.jpg") no-repeat fixed center top; + background:#152534 url("images/bg.jpg") no-repeat center top; color:rgba(0,0,0,.8); } -pre { color:#fff;} +pre { + color:#fff; + margin:0; + padding:15px 10px; + font:10pt monospace; + line-height:14pt; + background:rgba(0,0,0,.4); + border-left:8px solid rgba(0,0,0,.3); + box-shadow:1px 2px 16px rgba(28,180,236,.4); } pre, pre * { cursor:text; } pre .cmt { color:rgb(255,229,106); } pre .kwd { color:#43A8CF; font-weight:bold; } @@ -23,8 +31,14 @@ pre .val { color:#8AB647; } pre .tab { border-left:1px dotted rgba(67,168,207,0.4); } pre .end { background:url("images/tabEnd.png") no-repeat left bottom; } +.page pre { background:rgba(0,0,0,.8); } +.page pre > .Comment { color:rgb(255,229,106); } +.page pre > .Keyword { color:#43A8CF; font-weight:bold; } +.page pre > .StringLit, +.page pre > .DecNumber { color:#8AB647; } + .tall { height:100%; } -.pre { padding:0 5px; font:11pt monospace; background:rgba(255,255,255,.15); border-radius:3px; } +.pre { padding:1px 5px; font:11pt monospace; background:#96A9B7; border-radius:3px; } .page-layout { margin:0 auto; width:1000px; } .docs-layout { margin:0 40px; } @@ -90,7 +104,7 @@ pre .end { background:url("images/tabEnd.png") no-repeat left bottom; } right:-16px; height:48px; background:url("images/glow-arrow.png") no-repeat right; } - glow-arrow.docs { left:280px; } + #glow-arrow.docs { left:280px; } #glow-line-vert { position:fixed; @@ -102,55 +116,35 @@ pre .end { background:url("images/tabEnd.png") no-repeat left bottom; } #slideshow { position:absolute; top:10px; left:10px; width:700px; height: 1000px; } #slideshow > div { - visibility:hidden; opacity:0; position:absolute; transition:visibility 0s linear 1s, opacity 1s ease-in-out; } + position:absolute; + margin:30px 0 0 10px; + visibility:hidden; + opacity:0; + transition: + visibility 0s linear 1s, + opacity 1s ease-in-out; } #slideshow > div.active { visibility:visible; opacity:1; transition-delay:0s; } #slideshow > div.init { transition-delay:0s; } #slideshow-nav { z-index:3; position:absolute; top:110px;; right:-12px; } #slideshow-nav > div { margin:5px 0; width:23px; height:23px; background:url("images/slideshow-nav.png") no-repeat; } #slideshow-nav > div:hover { background-image:url("images/slideshow-nav_active.png"); opacity:0.5; } #slideshow-nav > div.active { background-image:url("images/slideshow-nav_active.png"); opacity:1; } - - #slide0 { margin:30px 0 0 10px; } - #slide0 > div { float:left; width:320px; font:10pt monospace; } + + #slide0 { float:left; width:680px; font:10pt monospace; } #slide0 > div:first-child { margin:0 40px 0 0; } #slide0 h2 { margin:0 0 5px 0; color:rgba(162,198,223,.78); } - #slide0 > div > pre { - margin:0; - padding:15px 10px; - line-height:14pt; - background:rgba(0,0,0,.4); - border-left:8px solid rgba(0,0,0,.3); - box-shadow:1px 2px 16px rgba(28,180,236,.4); } - - #slide1 { margin:30px 0 0 10px; } - #slide1 { float:left; width:680px; font:10pt monospace; } + #slide0 .desc { margin:0 0 5px 0; color:rgba(162,198,223,.78); font:13pt "arial"; } + + #slide1 > div { float:left; width:320px; font:10pt monospace; } #slide1 > div:first-child { margin:0 40px 0 0; } #slide1 h2 { margin:0 0 5px 0; color:rgba(162,198,223,.78); } - #slide1 .desc { margin:0 0 5px 0; color:rgba(162,198,223,.78); - font:13pt "arial"; } - #slide1 pre { - padding:7px 10px; - line-height:14pt; - background:rgba(0,0,0,.4); - border-left:8px solid rgba(0,0,0,.3); - box-shadow:1px 2px 16px rgba(28,180,236,.4); } - - - #slide2 { margin:30px 0 0 10px; } + #slide2 > div { float:left; width:320px; font:10pt monospace; } #slide2 > div:first-child { margin:0 40px 0 0; } #slide2 h2 { margin:0 0 5px 0; color:rgba(162,198,223,.78); } - #slide2 > div > pre { - margin:0; - padding:15px 10px; - line-height:14pt; - background:rgba(0,0,0,.4); - border-left:8px solid rgba(0,0,0,.3); - box-shadow:1px 2px 16px rgba(28,180,236,.4); } - - #slide2 .desc { margin:0 0 5px 0; color:rgba(162,198,223,.78); - font:13pt "arial"; } - + + #slide2 .desc { margin:0 0 5px 0; color:rgba(162,198,223,.78); font:13pt "arial"; } + /* back when slide1 was the quote: #slide1 { margin-top:50px; } #slide1 > p { @@ -166,7 +160,7 @@ pre .end { background:url("images/tabEnd.png") no-repeat left bottom; } font-style:italic; font-weight:bold; color:rgba(93,155,199,.44); } - */ + */ #sidebar { z-index:2; position:absolute; @@ -524,11 +518,12 @@ pre .end { background:url("images/tabEnd.png") no-repeat left bottom; } .standout h2 { margin-bottom:10px; padding-bottom:10px; border-bottom:1px dashed rgba(0,0,0,.8); } .standout li { margin:0 !important; padding-top:10px; border-top:1px dashed rgba(0,0,0,.2); } .standout ul { padding-bottom:5px; } - .standout ul.tools { list-style:url("images/docs-tools.png"); } - .standout ul.library { list-style:url("images/docs-library.png"); } - .standout ul.internal { list-style:url("images/docs-internal.png"); } - .standout ul.tutorial { list-style:url("images/docs-tutorial.png"); } - .standout ul.example { list-style:url("images/docs-example.png"); } + .standout ul.tools { list-style:url("images/docs-tools.png"); } + .standout ul.libraries { list-style:url("images/docs-libraries.png"); } + .standout ul.internals { list-style:url("images/docs-internals.png"); } + .standout ul.tutorials { list-style:url("images/docs-tutorials.png"); } + .standout ul.examples { list-style:url("images/docs-examples.png"); } + .standout ul.articles { list-style:url("images/docs-articles.png"); } .standout li:first-child { padding-top:0; border-top:none; } .standout li p { margin:0 0 10px 0 !important; line-height:130%; } .standout li > a { font-weight:bold; } @@ -551,48 +546,13 @@ pre .end { background:url("images/tabEnd.png") no-repeat left bottom; } #foot-legal { float:right; font-size:10pt; color:rgba(255,255,255,.3); line-height:150%; text-align:right; } #foot-legal a { color:inherit; text-decoration:none; } #foot-legal > h4 > a { color:inherit; } - - #mascot { - z-index:2; - position:absolute; - top:-340px; - right:25px; - width:202px; - height:319px; - background:url("images/mascot.png") no-repeat; } -#body pre { - padding:20px; - border-left:10px solid #8f9698; - background:#f3f6f8; - font-size:15px; - font-family:courier, monospace; - letter-spacing:0; - line-height:17px; - color: #343739; -} - -#body span.pre { - background-color: #96A9B7; - padding: 1pt 3pt; - border-radius: 2pt; - -moz-border-radius: 2pt; - -webkit-border-radius: 2pt; -} - -#body pre > .Comment { color:#858686; font-style:italic; } -#body pre > .Keyword { color:#1cb4ec; font-weight:bold; } -#body pre > .Operator { color:#777; } -#body pre > .StringLit, #page pre > .DecNumber { color:#ff7302; } - #body .docutils th { border-bottom: 2px solid #1A1A1A; font-weight: normal; - padding: 8px; -} + padding: 8px; } #body table.docutils { border-collapse: collapse; text-align: left; - border-spacing: 0px; -} + border-spacing: 0px; } \ No newline at end of file diff --git a/web/documentation.txt b/web/documentation.txt index 0bb2b8a0fb..c32fd35bab 100644 --- a/web/documentation.txt +++ b/web/documentation.txt @@ -6,16 +6,22 @@ Nim's Documentation Standards & Guides ------------------ + .. raw:: html - - | `Standard Library `_ - | This document describes Nim's standard library. - - - | `Language Manual `_ - | The Nim manual is a draft that will evolve into a proper specification. - - - | `Compiler user guide `_ - | The user guide lists command line arguments, special features of the - compiler, etc. +
    +
  • + Standard Library
    +

    This document describes Nim's standard library.

    +
  • +
  • + Language Manual
    +

    The Nim manual is a draft that will evolve into a proper specification.

    +
  • +
  • + Compiler User-Guide
    +

    The user guide lists command line arguments, special features of the compiler, etc.

    +
  • +
.. container:: standout @@ -23,12 +29,18 @@ Nim's Documentation Tools & Features ---------------- - - | `Source code filters `_ - | The Nim compiler supports source code filters as a simple yet powerful - builtin templating system. + .. raw:: html - - | `Tools documentation `_ - | Description of some tools that come with the standard distribution. +
    +
  • + Source-Code Filters
    +

    The Nim compiler supports source code filters as a simple yet powerful builtin templating system.

    +
  • +
  • + Tools Documentation
    +

    Description of some tools that come with the standard distribution.

    +
  • +
.. container:: standout @@ -36,13 +48,18 @@ Nim's Documentation Internal Details ---------------- - - | `Garbage Collector `_ - | Additional documentation about Nim's GC and how to operate it in a - | realtime setting. + .. raw:: html - - | `Internal documentation `_ - | The internal documentation describes how the compiler is implemented. Read - this if you want to hack the compiler. +
    +
  • + Garbage Collector
    +

    Additional documentation about Nim's GC and how to operate it in a realtime setting.

    +
  • +
  • + Internal Documentation
    +

    The internal documentation describes how the compiler is implemented. Read this if you want to hack the compiler.

    +
  • +
Search Options diff --git a/web/learn.txt b/web/learn.txt index 854b316684..4ff4dcafb4 100644 --- a/web/learn.txt +++ b/web/learn.txt @@ -6,11 +6,18 @@ Learning Nim Tutorials --------- - - | `Tutorial (part I) `_ - | Learn the basics of Nim's types, variables, procedures, control flow, etc... + .. raw:: html - - | `Tutorial (part II) `_ - | Learn Nim's more advanced features such as OOP, generics, macros, etc... +
    +
  • + Tutorial (part I)
    +

    Learn the basics of Nim's types, variables, procedures, control flow, etc...

    +
  • +
  • + Tutorial (part II)
    +

    Learn Nim's more advanced features such as OOP, generics, macros, etc...

    +
  • +
.. container:: standout @@ -18,14 +25,22 @@ Learning Nim Examples -------- - - | `Nim by Example `_ - | Nim by Example is an excellent starting place for beginners. + .. raw:: html - - | `Nim on Rosetta Code `_ - | Many different Nim code examples comparable to other languages for reference. - - - | `Nim for C/C++ Programmers `_ - | A useful cheat-sheet for those most familiar with C/C++ languages. +
    +
  • + Nim by Example
    +

    Nim by Example is an excellent starting place for beginners.

    +
  • +
  • + Nim on Rosetta Code
    +

    Many different Nim code examples comparable to other languages for reference.

    +
  • +
  • + Nim for C/C++ Programmers
    +

    A useful cheat-sheet for those most familiar with C/C++ languages.

    +
  • +
.. container:: standout @@ -33,8 +48,21 @@ Learning Nim Articles -------- - - `Dr Dobbs Nimrod Publication `_ - - `Bootstrapping Nim `_ + .. raw:: html + + Documentation From f7f87a7709e40953be74ddd8924a8a77be7a2fa7 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 7 Feb 2015 19:14:14 +0100 Subject: [PATCH 276/850] merged #2083 manually --- compiler/platform.nim | 2 +- config/nim.cfg | 14 ++++++++++++++ lib/nimbase.h | 11 ++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/compiler/platform.nim b/compiler/platform.nim index 8360a9dcc1..a21e732482 100644 --- a/compiler/platform.nim +++ b/compiler/platform.nim @@ -138,7 +138,7 @@ const props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}), (name: "VxWorks", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", objExt: ".o", newLine: "\x0A", pathSep: ";", dirSep: "\\", - scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", + scriptExt: ".sh", curDir: ".", exeExt: ".vxe", extSep: ".", props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}), (name: "JS", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", diff --git a/config/nim.cfg b/config/nim.cfg index e4ea43a599..8f5d7e8e7a 100644 --- a/config/nim.cfg +++ b/config/nim.cfg @@ -112,6 +112,20 @@ hint[LineTooLong]=off gcc.cpp.options.always = "-w -fpermissive" @end +# Configuration for the VxWorks +# This has been tested with VxWorks 6.9 only +@if vxworks: + # For now we only support compiling RTPs applications (i.e. no DKMs) + gcc.options.always = "-mrtp -fno-strict-aliasing -D_C99 -D_HAS_C9X -std=c99 -fasm -Wall -Wno-write-strings" + # The linker config must add the VxWorks common library for the selected + # processor which is usually found in: + # "$WIND_BASE/target/lib/usr/lib/PROCESSOR_FAMILY/PROCESSOR_TYPE/common", + # where PROCESSOR_FAMILY and PROCESSOR_TYPE are those supported by the VxWorks + # compiler (e.g. ppc/PPC32 or mips/MIPSI64, etc) + # For now we only support the PowerPC CPU + gcc.options.linker %= "-L $WIND_BASE/target/lib/usr/lib/ppc/PPC32/common -mrtp -fno-strict-aliasing -D_C99 -D_HAS_C9X -std=c99 -fasm -Wall -Wno-write-strings" +@end + gcc.options.speed = "-O3 -fno-strict-aliasing" gcc.options.size = "-Os" gcc.options.debug = "-g3 -O0" diff --git a/lib/nimbase.h b/lib/nimbase.h index b72e60ac24..50c7968acb 100644 --- a/lib/nimbase.h +++ b/lib/nimbase.h @@ -379,7 +379,7 @@ static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); } # define GC_GUARD #endif -/* Test to see if nimrod and the C compiler agree on the size of a pointer. +/* 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: "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]; @@ -390,3 +390,12 @@ typedef int assert_numbits[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof( #else # define NIM_EXTERNC #endif + +/* ---------------- platform specific includes ----------------------- */ + +/* VxWorks related includes */ +#if defined(__VXWORKS__) +# include +# include +# include +#endif From 736a04c66b679c210551ba2921b43155a57db527 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 8 Feb 2015 12:10:13 +0100 Subject: [PATCH 277/850] better error message --- compiler/vm.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/vm.nim b/compiler/vm.nim index b682b4e253..090498f109 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1438,7 +1438,9 @@ proc evalMacroCall*(module: PSym, n, nOrig: PNode, sym: PSym): PNode = # immediate macros can bypass any type and arity checking so we check the # arity here too: if sym.typ.len > n.safeLen and sym.typ.len > 1: - globalError(n.info, "got $#, but expected $# argument(s)" % [$ Date: Sun, 8 Feb 2015 13:23:47 +0100 Subject: [PATCH 278/850] fixes #1956 --- compiler/msgs.nim | 6 +++--- compiler/semtypes.nim | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 923c351703..be69f1ea5f 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -113,7 +113,7 @@ type warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel, warnUnknownSubstitutionX, warnLanguageXNotSupported, warnFieldXNotSupported, warnCommentXIgnored, - warnNilStatement, warnAnalysisLoophole, + warnNilStatement, warnTypelessParam, warnDifferentHeaps, warnWriteToForeignHeap, warnUnsafeCode, warnEachIdentIsTuple, warnShadowIdent, warnProveInit, warnProveField, warnProveIndex, warnGcUnsafe, warnGcUnsafe2, @@ -376,7 +376,7 @@ const warnFieldXNotSupported: "field \'$1\' not supported [FieldXNotSupported]", warnCommentXIgnored: "comment \'$1\' ignored [CommentXIgnored]", warnNilStatement: "'nil' statement is deprecated; use an empty 'discard' statement instead [NilStmt]", - warnAnalysisLoophole: "thread analysis incomplete due to unknown call '$1' [AnalysisLoophole]", + warnTypelessParam: "'$1' has no type. Typeless parameters are deprecated; only allowed for 'template' [TypelessParam]", warnDifferentHeaps: "possible inconsistency of thread local heaps [DifferentHeaps]", warnWriteToForeignHeap: "write to foreign heap [WriteToForeignHeap]", warnUnsafeCode: "unsafe code: '$1' [UnsafeCode]", @@ -418,7 +418,7 @@ const "RedefinitionOfLabel", "UnknownSubstitutionX", "LanguageXNotSupported", "FieldXNotSupported", "CommentXIgnored", "NilStmt", - "AnalysisLoophole", "DifferentHeaps", "WriteToForeignHeap", + "TypelessParam", "DifferentHeaps", "WriteToForeignHeap", "UnsafeCode", "EachIdentIsTuple", "ShadowIdent", "ProveInit", "ProveField", "ProveIndex", "GcUnsafe", "GcUnsafe2", "Uninit", "GcMem", "Destructor", "LockLevel", "User"] diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 7908742dbe..d052700b20 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -911,6 +911,8 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, if not hasType and not hasDefault: if isType: localError(a.info, "':' expected") let tdef = if kind in {skTemplate, skMacro}: tyExpr else: tyAnything + if tdef == tyAnything: + message(a.info, warnTypelessParam, renderTree(n)) typ = newTypeS(tdef, c) if skipTypes(typ, {tyGenericInst}).kind == tyEmpty: continue From c91ca82a43917163f00cf86e59d80a8909dca80a Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 8 Feb 2015 13:37:22 +0100 Subject: [PATCH 279/850] fixes #2073; language spec change: arrow like operators are not right associative anymore --- compiler/parser.nim | 4 ++-- doc/manual/syntax.txt | 6 ++---- web/news.txt | 1 + 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/compiler/parser.nim b/compiler/parser.nim index aae0ce7f95..f249b37c84 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -198,8 +198,8 @@ proc isSigilLike(tok: TToken): bool {.inline.} = proc isRightAssociative(tok: TToken): bool {.inline.} = ## Determines whether the token is right assocative. - result = tok.tokType == tkOpr and (tok.ident.s[0] == '^' or - (let L = tok.ident.s.len; L > 1 and tok.ident.s[L-1] == '>')) + result = tok.tokType == tkOpr and tok.ident.s[0] == '^' + # or (let L = tok.ident.s.len; L > 1 and tok.ident.s[L-1] == '>')) proc getPrecedence(tok: TToken, strongSpaces: bool): int = ## Calculates the precedence of the given token. diff --git a/doc/manual/syntax.txt b/doc/manual/syntax.txt index c975e7f480..b40a8ce91c 100644 --- a/doc/manual/syntax.txt +++ b/doc/manual/syntax.txt @@ -12,10 +12,8 @@ Binary operators have 11 different levels of precedence. Associativity ------------- -Binary operators whose first character is ``^`` or its last character -is ``>`` are right-associative, all other binary operators are left-associative. - -Exception: The single "greater than" ``>`` operator is left-associative too. +Binary operators whose first character is ``^`` are right-associative, all +other binary operators are left-associative. Operators ending in ``>`` but longer than a single character are called `arrow like`:idx:. diff --git a/web/news.txt b/web/news.txt index ac7971f208..f765479a29 100644 --- a/web/news.txt +++ b/web/news.txt @@ -20,6 +20,7 @@ News ``addHandler``, ``getHandlers``, ``setLogFilter`` and ``getLogFilter`` should be used instead. - ``nim idetools`` has been replaced by a separate tool `nimsuggest`_. + - *arrow like* operators are not right associative anymore. Language Additions From ada0f14711d3eff140f05f8a845cff5d489a71fd Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 8 Feb 2015 14:15:02 +0100 Subject: [PATCH 280/850] fixes #2073 --- compiler/semstmts.nim | 4 ++-- lib/system.nim | 2 +- tests/closure/ttimeinfo.nim | 15 +++++++++++++++ web/news.txt | 3 ++- 4 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 tests/closure/ttimeinfo.nim diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index b4790e4212..6e5b272de5 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -825,9 +825,9 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode = if gp.len == 0 or (gp.len == 1 and tfRetType in gp[0].typ.flags): pushProcCon(c, s) addResult(c, s.typ.sons[0], n.info, skProc) + addResultNode(c, n) let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos])) n.sons[bodyPos] = transformBody(c.module, semBody, s) - addResultNode(c, n) popProcCon(c) elif efOperand notin flags: localError(n.info, errGenericLambdaNotAllowed) @@ -860,9 +860,9 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode = addParams(c, n.typ.n, skProc) pushProcCon(c, s) addResult(c, n.typ.sons[0], n.info, skProc) + addResultNode(c, n) let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos])) n.sons[bodyPos] = transformBody(c.module, semBody, n.sons[namePos].sym) - addResultNode(c, n) popProcCon(c) popOwner() closeScope(c) diff --git a/lib/system.nim b/lib/system.nim index 19836b68c5..ef70a26728 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -3161,7 +3161,7 @@ when hostOS != "standalone": x[j+i] = item[j] inc(j) -proc compiles*(x): bool {.magic: "Compiles", noSideEffect.} = +proc compiles*(x: expr): bool {.magic: "Compiles", noSideEffect.} = ## Special compile-time procedure that checks whether `x` can be compiled ## without any semantic error. ## This can be used to check whether a type supports some operation: diff --git a/tests/closure/ttimeinfo.nim b/tests/closure/ttimeinfo.nim new file mode 100644 index 0000000000..3138ae72e7 --- /dev/null +++ b/tests/closure/ttimeinfo.nim @@ -0,0 +1,15 @@ +# bug #2073 + +import sequtils +import times + +# 1 +proc f(n: int): TimeInfo = + TimeInfo(year: n, month: mJan, monthday: 1) + +echo toSeq(2000 || 2015).map(f) + +# 2 +echo toSeq(2000 || 2015).map(proc (n: int): TimeInfo = + TimeInfo(year: n, month: mJan, monthday: 1) +) diff --git a/web/news.txt b/web/news.txt index f765479a29..4c97c5f9b0 100644 --- a/web/news.txt +++ b/web/news.txt @@ -21,7 +21,8 @@ News should be used instead. - ``nim idetools`` has been replaced by a separate tool `nimsuggest`_. - *arrow like* operators are not right associative anymore. - + - Typeless parameters are now only allowed in templates and macros. The old + way turned out to be too error-prone. Language Additions ------------------ From 34b4e9fc9624042d9fb94a73535baa76b3033376 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 8 Feb 2015 15:43:50 +0100 Subject: [PATCH 281/850] fixes #2004 --- compiler/semexprs.nim | 37 ++++++++++++++++------------- compiler/seminst.nim | 13 ++++++---- tests/generics/t1056.nim | 3 +-- tests/template/tparams_gensymed.nim | 19 +++++++++++++++ 4 files changed, 49 insertions(+), 23 deletions(-) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index eeada00063..40413e3eb3 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -103,28 +103,31 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = result = newSymNode(s, n.info) of skMacro: result = semMacroExpr(c, n, n, s, flags) of skTemplate: result = semTemplateExpr(c, n, s, flags) - of skVar, skLet, skResult, skParam, skForVar: + of skParam: + markUsed(n.info, s) + styleCheckUse(n.info, s) + if s.typ.kind == tyStatic and s.typ.n != nil: + # XXX see the hack in sigmatch.nim ... + return s.typ.n + elif sfGenSym in s.flags: + if c.p.wasForwarded: + # gensym'ed parameters that nevertheless have been forward declared + # need a special fixup: + let realParam = c.p.owner.typ.n[s.position+1] + internalAssert realParam.kind == nkSym and realParam.sym.kind == skParam + return newSymNode(c.p.owner.typ.n[s.position+1].sym, n.info) + elif c.p.owner.kind == skMacro: + # gensym'ed macro parameters need a similar hack (see bug #1944): + var u = searchInScopes(c, s.name) + internalAssert u != nil and u.kind == skParam and u.owner == s.owner + return newSymNode(u, n.info) + result = newSymNode(s, n.info) + of skVar, skLet, skResult, skForVar: markUsed(n.info, s) styleCheckUse(n.info, s) # if a proc accesses a global variable, it is not side effect free: if sfGlobal in s.flags: incl(c.p.owner.flags, sfSideEffect) - elif s.kind == skParam: - if s.typ.kind == tyStatic and s.typ.n != nil: - # XXX see the hack in sigmatch.nim ... - return s.typ.n - elif sfGenSym in s.flags: - if c.p.wasForwarded: - # gensym'ed parameters that nevertheless have been forward declared - # need a special fixup: - let realParam = c.p.owner.typ.n[s.position+1] - internalAssert realParam.kind == nkSym and realParam.sym.kind == skParam - return newSymNode(c.p.owner.typ.n[s.position+1].sym, n.info) - elif c.p.owner.kind == skMacro: - # gensym'ed macro parameters need a similar hack (see bug #1944): - var u = searchInScopes(c, s.name) - internalAssert u != nil and u.kind == skParam and u.owner == s.owner - return newSymNode(u, n.info) result = newSymNode(s, n.info) # We cannot check for access to outer vars for example because it's still # not sure the symbol really ends up being used: diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 81a4465c59..e02d6d1e54 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -77,11 +77,16 @@ proc removeDefaultParamValues(n: PNode) = proc freshGenSyms(n: PNode, owner: PSym, symMap: var TIdTable) = # we need to create a fresh set of gensym'ed symbols: if n.kind == nkSym and sfGenSym in n.sym.flags: - var x = PSym(idTableGet(symMap, n.sym)) + let s = n.sym + var x = PSym(idTableGet(symMap, s)) if x == nil: - x = copySym(n.sym, false) - x.owner = owner - idTablePut(symMap, n.sym, x) + if s.kind == skParam: + x = owner.typ.n[s.position+1].sym + internalAssert x.kind == skParam + else: + x = copySym(s, false) + x.owner = owner + idTablePut(symMap, s, x) n.sym = x else: for i in 0 .. Date: Sun, 8 Feb 2015 15:47:55 +0100 Subject: [PATCH 282/850] 'nimsuggest' compiles again --- lib/impure/rdstdin.nim | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/impure/rdstdin.nim b/lib/impure/rdstdin.nim index 258da22072..b188ead1f6 100644 --- a/lib/impure/rdstdin.nim +++ b/lib/impure/rdstdin.nim @@ -1,7 +1,7 @@ # # # Nim's Runtime Library -# (c) Copyright 2012 Andreas Rumpf +# (c) Copyright 2015 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -13,6 +13,8 @@ ## is used. This suffices because Windows' console already provides the ## wanted functionality. +{.deadCodeElim: on.} + when defined(Windows): proc readLineFromStdin*(prompt: string): TaintedString {. tags: [ReadIOEffect, WriteIOEffect].} = @@ -31,23 +33,23 @@ when defined(Windows): stdout.write(prompt) result = readLine(stdin, line) - proc getch(): cint {.header: "", importc: "_getch".} - proc readPasswordFromStdin*(prompt: string, password: var TaintedString) = ## Reads a `password` from stdin without printing it. `password` must not ## be ``nil``! + proc getch(): cint {.header: "", importc: "_getch".} + password.setLen(0) var c: char echo prompt while true: - c = getch().char - case c - of '\r', chr(0xA): - break - of '\b': - password.setLen(result.len - 1) - else: - password.add(c) + c = getch().char + case c + of '\r', chr(0xA): + break + of '\b': + password.setLen(password.len - 1) + else: + password.add(c) else: import readline, history, termios, unsigned From 6f1152c66bbf00617ab991e88e547362d9cb2480 Mon Sep 17 00:00:00 2001 From: Simon Hafner Date: Sun, 8 Feb 2015 11:01:09 -0600 Subject: [PATCH 283/850] apparently the json spacing changed --- tests/stdlib/tmitems.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/stdlib/tmitems.nim b/tests/stdlib/tmitems.nim index 2297f0ee93..bf67d2b7b6 100644 --- a/tests/stdlib/tmitems.nim +++ b/tests/stdlib/tmitems.nim @@ -12,7 +12,7 @@ fpqeew [11, 12, 13] [11, 12, 13] { "key1": 11, "key2": 12, "key3": 13} -[ 11, 12, 13] +[11, 12, 13] From 18fb3a391cecab9f9f0d71e455051315c8cf9a6d Mon Sep 17 00:00:00 2001 From: def Date: Sun, 8 Feb 2015 22:53:49 +0100 Subject: [PATCH 284/850] Fix readPasswordFromStdin for Windows --- lib/impure/rdstdin.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/impure/rdstdin.nim b/lib/impure/rdstdin.nim index b188ead1f6..f53058a9b0 100644 --- a/lib/impure/rdstdin.nim +++ b/lib/impure/rdstdin.nim @@ -40,7 +40,7 @@ when defined(Windows): password.setLen(0) var c: char - echo prompt + stdout.write(prompt) while true: c = getch().char case c From ecd0dea091cfddacb2fb28c9fa4b716b571e8007 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 9 Feb 2015 00:08:14 +0100 Subject: [PATCH 285/850] tables work in 'const' sections; echo supports 'nil' strings; minor cleanups --- compiler/ccgexprs.nim | 8 +++++--- compiler/ccgstmts.nim | 9 --------- compiler/llstream.nim | 41 +++++++++++++--------------------------- compiler/treetab.nim | 5 +++-- compiler/types.nim | 10 ++++++---- compiler/vmgen.nim | 3 ++- doc/advopt.txt | 1 - doc/basicopt.txt | 1 - tests/vm/tconsttable.nim | 19 +++++++++++++++++++ todo.txt | 15 ++++++++++++--- web/news.txt | 9 +++++++++ 11 files changed, 69 insertions(+), 52 deletions(-) create mode 100644 tests/vm/tconsttable.nim diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 32678d4725..9b45c44925 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -83,7 +83,9 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): PRope = else: result = toRope("NIM_NIL") of nkStrLit..nkTripleStrLit: - if skipTypes(ty, abstractVarRange).kind == tyString: + if n.strVal.isNil: + result = ropecg(p.module, "((#NimStringDesc*) NIM_NIL)", []) + elif skipTypes(ty, abstractVarRange).kind == tyString: var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId) if id == gBackendId: # string literal not found in the cache: @@ -950,7 +952,7 @@ proc genEcho(p: BProc, n: PNode) = var a: TLoc for i in countup(0, n.len-1): initLocExpr(p, n.sons[i], a) - appf(args, ", ($1)->data", [rdLoc(a)]) + appf(args, ", $1? ($1)->data:\"nil\"", [rdLoc(a)]) linefmt(p, cpsStmts, "printf($1$2);$n", makeCString(repeatStr(n.len, "%s") & tnl), args) @@ -2173,7 +2175,7 @@ proc genConstExpr(p: BProc, n: PNode): PRope = var cs: TBitSet toBitSet(n, cs) result = genRawSetData(cs, int(getSize(n.typ))) - of nkBracket, nkPar, nkClosure: + of nkBracket, nkPar, nkClosure, nkObjConstr: var t = skipTypes(n.typ, abstractInst) if t.kind == tySequence: result = genConstSeq(p, n, t) diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index f5a2c0ef4a..18705c9741 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -253,15 +253,6 @@ proc genConstStmt(p: BProc, t: PNode) = elif c.typ.kind in ConstantDataTypes and lfNoDecl notin c.loc.flags and c.ast.len != 0: if not emitLazily(c): requestConstImpl(p, c) - when false: - # generate the data: - fillLoc(c.loc, locData, c.typ, mangleName(c), OnUnknown) - if sfImportc in c.flags: - appf(p.module.s[cfsData], "extern NIM_CONST $1 $2;$n", - [getTypeDesc(p.module, c.typ), c.loc.r]) - else: - appf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n", - [getTypeDesc(p.module, c.typ), c.loc.r, genConstExpr(p, c.ast)]) proc genIf(p: BProc, n: PNode, d: var TLoc) = # diff --git a/compiler/llstream.nim b/compiler/llstream.nim index be469548d3..69475965d9 100644 --- a/compiler/llstream.nim +++ b/compiler/llstream.nim @@ -30,47 +30,32 @@ type PLLStream* = ref TLLStream -proc llStreamOpen*(data: string): PLLStream -proc llStreamOpen*(f: var File): PLLStream -proc llStreamOpen*(filename: string, mode: FileMode): PLLStream -proc llStreamOpen*(): PLLStream -proc llStreamOpenStdIn*(): PLLStream -proc llStreamClose*(s: PLLStream) -proc llStreamRead*(s: PLLStream, buf: pointer, bufLen: int): int -proc llStreamReadLine*(s: PLLStream, line: var string): bool -proc llStreamReadAll*(s: PLLStream): string -proc llStreamWrite*(s: PLLStream, data: string) -proc llStreamWrite*(s: PLLStream, data: char) -proc llStreamWrite*(s: PLLStream, buf: pointer, buflen: int) -proc llStreamWriteln*(s: PLLStream, data: string) -# implementation - -proc llStreamOpen(data: string): PLLStream = +proc llStreamOpen*(data: string): PLLStream = new(result) result.s = data result.kind = llsString -proc llStreamOpen(f: var File): PLLStream = +proc llStreamOpen*(f: var File): PLLStream = new(result) result.f = f result.kind = llsFile -proc llStreamOpen(filename: string, mode: FileMode): PLLStream = +proc llStreamOpen*(filename: string, mode: FileMode): PLLStream = new(result) result.kind = llsFile if not open(result.f, filename, mode): result = nil -proc llStreamOpen(): PLLStream = +proc llStreamOpen*(): PLLStream = new(result) result.kind = llsNone -proc llStreamOpenStdIn(): PLLStream = +proc llStreamOpenStdIn*(): PLLStream = new(result) result.kind = llsStdIn result.s = "" result.lineOffset = -1 -proc llStreamClose(s: PLLStream) = +proc llStreamClose*(s: PLLStream) = case s.kind of llsNone, llsString, llsStdIn: discard @@ -130,7 +115,7 @@ proc llReadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int = copyMem(buf, addr(s.s[s.rd]), result) inc(s.rd, result) -proc llStreamRead(s: PLLStream, buf: pointer, bufLen: int): int = +proc llStreamRead*(s: PLLStream, buf: pointer, bufLen: int): int = case s.kind of llsNone: result = 0 @@ -144,7 +129,7 @@ proc llStreamRead(s: PLLStream, buf: pointer, bufLen: int): int = of llsStdIn: result = llReadFromStdin(s, buf, bufLen) -proc llStreamReadLine(s: PLLStream, line: var string): bool = +proc llStreamReadLine*(s: PLLStream, line: var string): bool = setLen(line, 0) case s.kind of llsNone: @@ -168,7 +153,7 @@ proc llStreamReadLine(s: PLLStream, line: var string): bool = of llsStdIn: result = readLine(stdin, line) -proc llStreamWrite(s: PLLStream, data: string) = +proc llStreamWrite*(s: PLLStream, data: string) = case s.kind of llsNone, llsStdIn: discard @@ -178,11 +163,11 @@ proc llStreamWrite(s: PLLStream, data: string) = of llsFile: write(s.f, data) -proc llStreamWriteln(s: PLLStream, data: string) = +proc llStreamWriteln*(s: PLLStream, data: string) = llStreamWrite(s, data) llStreamWrite(s, "\n") -proc llStreamWrite(s: PLLStream, data: char) = +proc llStreamWrite*(s: PLLStream, data: char) = var c: char case s.kind of llsNone, llsStdIn: @@ -194,7 +179,7 @@ proc llStreamWrite(s: PLLStream, data: char) = c = data discard writeBuffer(s.f, addr(c), sizeof(c)) -proc llStreamWrite(s: PLLStream, buf: pointer, buflen: int) = +proc llStreamWrite*(s: PLLStream, buf: pointer, buflen: int) = case s.kind of llsNone, llsStdIn: discard @@ -206,7 +191,7 @@ proc llStreamWrite(s: PLLStream, buf: pointer, buflen: int) = of llsFile: discard writeBuffer(s.f, buf, buflen) -proc llStreamReadAll(s: PLLStream): string = +proc llStreamReadAll*(s: PLLStream): string = const bufSize = 2048 case s.kind diff --git a/compiler/treetab.nim b/compiler/treetab.nim index 63f3fc6e21..8d66d56c74 100644 --- a/compiler/treetab.nim +++ b/compiler/treetab.nim @@ -28,8 +28,9 @@ proc hashTree(n: PNode): THash = of nkFloatLit..nkFloat64Lit: if (n.floatVal >= - 1000000.0) and (n.floatVal <= 1000000.0): result = result !& toInt(n.floatVal) - of nkStrLit..nkTripleStrLit: - result = result !& hash(n.strVal) + of nkStrLit..nkTripleStrLit: + if not n.strVal.isNil: + result = result !& hash(n.strVal) else: for i in countup(0, sonsLen(n) - 1): result = result !& hashTree(n.sons[i]) diff --git a/compiler/types.nim b/compiler/types.nim index 78d390f133..3711a96683 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1029,16 +1029,18 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, proc typeAllowedNode(marker: var IntSet, n: PNode, kind: TSymKind, flags: TTypeAllowedFlags = {}): PType = - if n != nil: + if n != nil: result = typeAllowedAux(marker, n.typ, kind, flags) #if not result: debug(n.typ) if result == nil: case n.kind - of nkNone..nkNilLit: + of nkNone..nkNilLit: discard else: for i in countup(0, sonsLen(n) - 1): - result = typeAllowedNode(marker, n.sons[i], kind, flags) + let it = n.sons[i] + if it.kind == nkRecCase and kind == skConst: return n.typ + result = typeAllowedNode(marker, it, kind, flags) if result != nil: break proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]], @@ -1118,7 +1120,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, result = typeAllowedAux(marker, t.sons[i], kind, flags) if result != nil: break of tyObject, tyTuple: - if kind == skConst and t.kind == tyObject: return t + if kind == skConst and t.kind == tyObject and t.sons[0] != nil: return t let flags = flags+{taField} for i in countup(0, sonsLen(t) - 1): result = typeAllowedAux(marker, t.sons[i], kind, flags) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index fe6526a34f..70f81bc723 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -604,7 +604,8 @@ proc genNarrowU(c: PCtx; n: PNode; dest: TDest) = let t = skipTypes(n.typ, abstractVar-{tyTypeDesc}) # uint is uint64 in the VM, we we only need to mask the result for # other unsigned types: - if t.kind in {tyUInt8..tyUInt32, tyInt8..tyInt32}: + if t.kind in {tyUInt8..tyUInt32, tyInt8..tyInt32} or + (t.kind == tyInt and t.size == 4): c.gABC(n, opcNarrowU, dest, TRegister(t.size*8)) proc genBinaryABCnarrow(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) = diff --git a/doc/advopt.txt b/doc/advopt.txt index 78c3d571ac..ae474afc65 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -66,7 +66,6 @@ Advanced options: --threadanalysis:on|off turn thread analysis on|off --tlsEmulation:on|off turn thread local storage emulation on|off --taintMode:on|off turn taint mode on|off - --symbolFiles:on|off turn symbol files on|off (experimental) --implicitStatic:on|off turn implicit compile time evaluation on|off --patterns:on|off turn pattern matching on|off --skipCfg do not read the general configuration file diff --git a/doc/basicopt.txt b/doc/basicopt.txt index e366b2718e..27b10badc8 100644 --- a/doc/basicopt.txt +++ b/doc/basicopt.txt @@ -14,7 +14,6 @@ Options: -p, --path:PATH add path to search paths -d, --define:SYMBOL define a conditional symbol -u, --undef:SYMBOL undefine a conditional symbol - --symbol:SYMBOL declare a conditional symbol -f, --forceBuild force rebuilding of all modules --stackTrace:on|off turn stack tracing on|off --lineTrace:on|off turn line tracing on|off diff --git a/tests/vm/tconsttable.nim b/tests/vm/tconsttable.nim new file mode 100644 index 0000000000..64a74a59d5 --- /dev/null +++ b/tests/vm/tconsttable.nim @@ -0,0 +1,19 @@ +discard """ + output: '''is +finally +nice!''' +""" + +import tables + +const + foo = {"ah": "finally", "this": "is", "possible.": "nice!"}.toTable() + +# protect against overly smart compiler: +var x = "this" + +echo foo[x] +x = "ah" +echo foo[x] +x = "possible." +echo foo[x] diff --git a/todo.txt b/todo.txt index 17b8b3a212..252699bf17 100644 --- a/todo.txt +++ b/todo.txt @@ -1,11 +1,20 @@ -version 0.10 -============ +version 0.10.4 +============== + +- make 'nil' work for 'add' and 'len' +- improve GC-unsafety warnings +- get rid of 'mget'; aka priority of 'var' needs to be 'var{lvalue}' +- improve documentation (theindex!) +- fix the getUniqueType() bug + + +version 1.0 +=========== - nimsuggest: auto-completion needs to work in 'class' macros - improve the docs for inheritance - The bitwise 'not' operator will be renamed to 'bnot' to prevent 'not 4 == 5' from compiling. -> requires 'mixin' annotation for procs! -- parameter lists without type end up in 'experimental' - iterators always require a return type - overloading of '=' diff --git a/web/news.txt b/web/news.txt index 4c97c5f9b0..5cc3a6ed6c 100644 --- a/web/news.txt +++ b/web/news.txt @@ -32,6 +32,15 @@ News - Automatic dereferencing is now done for the first argument of a routine call if overloading resolution produces no match otherwise. This feature has to be enabled with the `experimental`_ pragma. + - Objects that do not use inheritance nor ``case`` can be put into ``const`` + sections. This means that finally this is possible and produces rather + nice code: + + .. code-block:: nim + import tables + + const + foo = {"ah": "finally", "this": "is", "possible.": "nice!"}.toTable() 2014-12-29 Version 0.10.2 released From d6d152e451cf54bf4e20885bdc786ee1187e5cfb Mon Sep 17 00:00:00 2001 From: def Date: Mon, 9 Feb 2015 08:06:56 +0100 Subject: [PATCH 286/850] Add a new line after readPasswordFromStdin, add result --- lib/impure/rdstdin.nim | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/impure/rdstdin.nim b/lib/impure/rdstdin.nim index f53058a9b0..aaf2ed1cac 100644 --- a/lib/impure/rdstdin.nim +++ b/lib/impure/rdstdin.nim @@ -33,9 +33,11 @@ when defined(Windows): stdout.write(prompt) result = readLine(stdin, line) - proc readPasswordFromStdin*(prompt: string, password: var TaintedString) = + proc readPasswordFromStdin*(prompt: string, password: var TaintedString): + bool {.tags: [ReadIOEffect, WriteIOEffect].} = ## Reads a `password` from stdin without printing it. `password` must not - ## be ``nil``! + ## be ``nil``! Returns ``false`` if the end of the file has been reached, + ## ``true`` otherwise. proc getch(): cint {.header: "", importc: "_getch".} password.setLen(0) @@ -50,6 +52,8 @@ when defined(Windows): password.setLen(password.len - 1) else: password.add(c) + stdout.write "\n" + # TODO: How to detect EOF on Windows? else: import readline, history, termios, unsigned @@ -80,7 +84,8 @@ else: discard readline.bind_key('\t'.ord, doNothing) - proc readPasswordFromStdin*(prompt: string, password: var TaintedString) = + proc readPasswordFromStdin*(prompt: string, password: var TaintedString): + bool {.tags: [ReadIOEffect, WriteIOEffect].} = password.setLen(0) let fd = stdin.getFileHandle() var cur, old: Termios @@ -89,10 +94,11 @@ else: cur.lflag = cur.lflag and not Tcflag(ECHO) discard fd.tcsetattr(TCSADRAIN, cur.addr) stdout.write prompt - discard stdin.readLine(password) + result = stdin.readLine(password) + stdout.write "\n" discard fd.tcsetattr(TCSADRAIN, old.addr) proc readPasswordFromStdin*(prompt: string): TaintedString = ## Reads a password from stdin without printing it. result = TaintedString("") - readPasswordFromStdin(prompt, result) + discard readPasswordFromStdin(prompt, result) From 13c5ce820e3c06829772f03e9deb50b90434c076 Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 9 Feb 2015 20:58:36 +0900 Subject: [PATCH 287/850] Date/time parsing --- lib/pure/times.nim | 395 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 388 insertions(+), 7 deletions(-) diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 1cabd381b7..442f46d7ee 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -16,7 +16,7 @@ # of the standard library! import - strutils + strutils, pegs include "system/inclrtl" @@ -26,6 +26,9 @@ type WeekDay* = enum ## represents a weekday dMon, dTue, dWed, dThu, dFri, dSat, dSun +const + digits = {'0','1','2','3','4','5','6','7','8','9'} + var timezone {.importc, header: "".}: int tzname {.importc, header: "" .}: array[0..1, cstring] @@ -744,6 +747,336 @@ proc format*(info: TimeInfo, f: string): string = {.pop.} +proc getMonth(m: int): Month = + case m + of 1: + return mJan + of 2: + return mFeb + of 3: + return mMar + of 4: + return mApr + of 5: + return mMay + of 6: + return mJun + of 7: + return mJul + of 8: + return mAug + of 9: + return mSep + of 10: + return mOct + of 11: + return mNov + of 12: + return mDec + else: + raise newException(ValueError, "invalid month") + +proc parseToken(info: var TimeInfo; token, value: string; j: var int) = + ## Helper of the parse proc to parse individual tokens. + case token + of "d": + if value[j+1] in digits: + #two digit format + info.monthday = value[j..j+1].parseInt() + j += 2 + else: + info.monthday = parseInt($value[j]) + j += 1 + of "dd": + #two digit format + info.monthday = value[j..j+1].parseInt() + j += 2 + of "ddd": + case value[j..j+2].toLower(): + of "sun": + info.weekday = dSun + of "mon": + info.weekday = dMon + of "tue": + info.weekday = dTue + of "wed": + info.weekday = dWed + of "thu": + info.weekday = dThu + of "fri": + info.weekday = dFri + of "sat": + info.weekday = dSat + else: + raise newException(ValueError, "invalid day of week ") + j += 3 + of "dddd": + if value.match(peg"^i'sunday'.*"): + info.weekday = dSun + j += 6 + elif value.match(peg"^i'monday'.*"): + info.weekday = dMon + j += 6 + elif value.match(peg"^i'tuesday'.*"): + info.weekday = dTue + j += 7 + elif value.match(peg"^i'wednesday'.*"): + info.weekday = dWed + j += 9 + elif value.match(peg"^i'thursday'.*"): + info.weekday = dThu + j += 8 + elif value.match(peg"^i'friday'.*"): + info.weekday = dFri + j += 6 + elif value.match(peg"^i'saturday'.*"): + info.weekday = dSat + j += 8 + else: + raise newException(ValueError, "invalid day of week ") + of "h", "H": + if value[j+1] in digits: + #two digit format + info.hour = value[j..j+1].parseInt() + j += 2 + else: + info.hour = parseInt($value[j]) + j += 1 + of "hh", "HH": + #two digit format + info.hour = value[j..j+1].parseInt() + j += 2 + of "m": + if value[j+1] in digits: + #two digit format + info.minute = value[j..j+1].parseInt() + j += 2 + else: + info.minute = parseInt($value[j]) + j += 1 + of "mm": + #two digit format + info.minute = value[j..j+1].parseInt() + j += 2 + of "M": + var month: int + if value[j+1] in digits: + #two digit format + month = value[j..j+1].parseInt() + j += 2 + else: + month = parseInt($value[j]) + j += 1 + info.month = getMonth(month) + of "MM": + var month = value[j..j+1].parseInt() + j += 2 + info.month = getMonth(month) + of "MMM": + case value[j..j+2].toLower(): + of "jan": + info.month = mJan + of "feb": + info.month = mFeb + of "mar": + info.month = mMar + of "apr": + info.month = mApr + of "may": + info.month = mMay + of "jun": + info.month = mJun + of "jul": + info.month = mJul + of "aug": + info.month = mAug + of "sep": + info.month = mSep + of "oct": + info.month = mOct + of "nov": + info.month = mNov + of "dec": + info.month = mDec + else: + raise newException(ValueError, "invalid month") + j += 3 + of "MMMM": + if value.match(peg"^i'january'.*"): + info.month = mJan + j += 7 + elif value.match(peg"^i'february'.*"): + info.month = mFeb + j += 8 + elif value.match(peg"^i'march'.*"): + info.month = mMar + j += 5 + elif value.match(peg"^i'april'.*"): + info.month = mApr + j += 5 + elif value.match(peg"^i'may'.*"): + info.month = mMay + j += 3 + elif value.match(peg"^i'june'.*"): + info.month = mJun + j += 4 + elif value.match(peg"^i'july'.*"): + info.month = mJul + j += 4 + elif value.match(peg"^i'august'.*"): + info.month = mAug + j += 6 + elif value.match(peg"^i'september'.*"): + info.month = mSep + j += 9 + elif value.match(peg"^i'october'.*"): + info.month = mOct + j += 7 + elif value.match(peg"^i'november'.*"): + info.month = mNov + j += 8 + elif value.match(peg"^i'december'.*"): + info.month = mDec + j += 8 + else: + raise newException(ValueError, "invalid month") + of "s": + if value[j+1] in digits: + #two digit format + info.second = value[j..j+1].parseInt() + j += 2 + else: + info.second = parseInt($value[j]) + j += 1 + of "ss": + #two digit format + info.second = value[j..j+1].parseInt() + j += 2 + of "t": + if value[j] == 'P' and info.hour > 0 and info.hour < 12: + info.hour += 12 + j += 1 + of "tt": + if value[j..j+1] == "PM" and info.hour > 0 and info.hour < 12: + info.hour += 12 + j += 2 + of "yy": + #Assumes current century + var year = value[j..j+1].parseInt() + var thisCen = getLocalTime(getTime()).year div 100 + info.year = thisCen*100 + year + j += 2 + of "yyyy": + info.year = value[j..j+3].parseInt() + j += 4 + of "z": + if value[j] == '+': + info.timezone = parseInt($value[j+1]) + elif value[j] == '-': + info.timezone = 0-parseInt($value[j+1]) + else: + raise newException(ValueError, "Sign for timezone " & value[j]) + j += 2 + of "zz": + if value[j] == '+': + info.timezone = value[j+1..j+2].parseInt() + elif value[j] == '-': + info.timezone = 0-value[j+1..j+2].parseInt() + else: + raise newException(ValueError, "Sign for timezone " & value[j]) + j += 3 + of "zzz": + if value[j] == '+': + info.timezone = value[j+1..j+2].parseInt() + elif value[j] == '-': + info.timezone = 0-value[j+1..j+2].parseInt() + else: + raise newException(ValueError, "Sign for timezone " & value[j]) + j += 6 + of "ZZZ": + info.tzname = value[j..j+2].toUpper() + j += 3 + else: + #Ignore the token and move forward in the value string by the same length + j += token.len + +proc parse*(value, layout: string): TimeInfo = + ## This function parses a date/time string using the standard format identifiers (below) + ## The function defaults information not provided in the format string from the running program (timezone, month, year, etc) + ## + ## ========== ================================================================================= ================================================ + ## Specifier Description Example + ## ========== ================================================================================= ================================================ + ## d Numeric value of the day of the month, it will be one or two digits long. ``1/04/2012 -> 1``, ``21/04/2012 -> 21`` + ## dd Same as above, but always two digits. ``1/04/2012 -> 01``, ``21/04/2012 -> 21`` + ## ddd Three letter string which indicates the day of the week. ``Saturday -> Sat``, ``Monday -> Mon`` + ## dddd Full string for the day of the week. ``Saturday -> Saturday``, ``Monday -> Monday`` + ## h The hours in one digit if possible. Ranging from 0-12. ``5pm -> 5``, ``2am -> 2`` + ## hh The hours in two digits always. If the hour is one digit 0 is prepended. ``5pm -> 05``, ``11am -> 11`` + ## H The hours in one digit if possible, randing from 0-24. ``5pm -> 17``, ``2am -> 2`` + ## HH The hours in two digits always. 0 is prepended if the hour is one digit. ``5pm -> 17``, ``2am -> 02`` + ## m The minutes in 1 digit if possible. ``5:30 -> 30``, ``2:01 -> 1`` + ## mm Same as above but always 2 digits, 0 is prepended if the minute is one digit. ``5:30 -> 30``, ``2:01 -> 01`` + ## M The month in one digit if possible. ``September -> 9``, ``December -> 12`` + ## MM The month in two digits always. 0 is prepended. ``September -> 09``, ``December -> 12`` + ## MMM Abbreviated three-letter form of the month. ``September -> Sep``, ``December -> Dec`` + ## MMMM Full month string, properly capitalized. ``September -> September`` + ## s Seconds as one digit if possible. ``00:00:06 -> 6`` + ## ss Same as above but always two digits. 0 is prepended. ``00:00:06 -> 06`` + ## t ``A`` when time is in the AM. ``P`` when time is in the PM. + ## tt Same as above, but ``AM`` and ``PM`` instead of ``A`` and ``P`` respectively. + ## yy Displays the year to two digits. ``2012 -> 12`` + ## yyyy Displays the year to four digits. ``2012 -> 2012`` + ## z Displays the timezone offset from UTC. ``GMT+7 -> +7``, ``GMT-5 -> -5`` + ## zz Same as above but with leading 0. ``GMT+7 -> +07``, ``GMT-5 -> -05`` + ## zzz Same as above but with ``:00``. ``GMT+7 -> +07:00``, ``GMT-5 -> -05:00`` + ## ZZZ Displays the name of the timezone. ``GMT -> GMT``, ``EST -> EST`` + ## ========== ================================================================================= ================================================ + ## + ## Other strings can be inserted by putting them in ``''``. For example + ## ``hh'->'mm`` will give ``01->56``. The following characters can be + ## inserted without quoting them: ``:`` ``-`` ``(`` ``)`` ``/`` ``[`` ``]`` + ## ``,``. However you don't need to necessarily separate format specifiers, a + ## unambiguous format string like ``yyyyMMddhhmmss`` is valid too. + var i = 0 #pointer for format string + var j = 0 #pointer for value string + var token = "" + #Assumes current day of week, month and year, but time is reset to 00:00:00 + var info = getLocalTime(getTime()) + info.hour = 0 + info.minute = 0 + info.second = 0 + while true: + case layout[i] + of ' ', '-', '/', ':', '\'', '\0', '(', ')', '[', ']', ',': + if token.len > 0: + parseToken(info, token, value, j) + #Reset token + token = "" + #Break if at end of line + if layout[i] == '\0': break + #Skip separator and everything between single quotes + #These are literals in both the layout and the value string + if layout[i] == '\'': + inc(i) + inc(j) + while layout[i] != '\'' and layout.len-1 > i: + inc(i) + inc(j) + else: + inc(i) + inc(j) + else: + # Check if the letter being added matches previous accumulated buffer. + if token.len < 1 or token[high(token)] == layout[i]: + token.add(layout[i]) + inc(i) + else: + parseToken(info, token, value, j) + token = "" + return info + + when isMainModule: # $ date --date='@2147483647' # Tue 19 Jan 03:14:07 GMT 2038 @@ -765,12 +1098,12 @@ when isMainModule: " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == "27 27 Mon Monday 4 04 16 16 6 06 1 01 Jan January 29 29 P PM 5 75 975 1975 01975 0 00 00:00 UTC" - when not defined(JS) and sizeof(Time) == 8: - var t3 = getGMTime(fromSeconds(889067643645)) # Fri 7 Jun 19:20:45 BST 30143 - assert t3.format("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & - " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == - "7 07 Fri Friday 6 06 18 18 20 20 6 06 Jun June 45 45 P PM 3 43 143 0143 30143 0 00 00:00 UTC" - assert t3.format(":,[]()-/") == ":,[]()-/" + # when not defined(JS) and sizeof(Time) == 8: + # var t3 = getGMTime(fromSeconds(889067643645)) # Fri 7 Jun 19:20:45 BST 30143 + # assert t3.format("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & + # " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == + # "7 07 Fri Friday 6 06 18 18 20 20 6 06 Jun June 45 45 P PM 3 43 143 0143 30143 0 00 00:00 UTC" + # assert t3.format(":,[]()-/") == ":,[]()-/" var t4 = getGMTime(fromSeconds(876124714)) # Mon 6 Oct 08:58:34 BST 1997 assert t4.format("M MM MMM MMMM") == "10 10 Oct October" @@ -778,3 +1111,51 @@ when isMainModule: # Interval tests assert((t4 - initInterval(years = 2)).format("yyyy") == "1995") assert((t4 - initInterval(years = 7, minutes = 34, seconds = 24)).format("yyyy mm ss") == "1990 24 10") + + var s = "09:04am on Dec 15, 2015" + var f = "hh:mmtt on MMM d, yyyy" + assert($s.parse(f) == "Mon Dec 15 09:04:00 2015") + # ANSIC = "Mon Jan _2 15:04:05 2006" + s = "Mon Jan 2 15:04:05 2006" + f = "ddd MMM d HH:mm:ss yyyy" + assert($s.parse(f) == "Mon Jan 2 15:04:05 2006") + # UnixDate = "Mon Jan _2 15:04:05 MST 2006" + s = "Mon Jan 2 15:04:05 MST 2006" + f = "ddd MMM d HH:mm:ss ZZZ yyyy" + assert($s.parse(f) == "Mon Jan 2 15:04:05 2006") + # RubyDate = "Mon Jan 02 15:04:05 -0700 2006" + s = "Mon Jan 02 15:04:05 -07:00 2006" + f = "ddd MMM dd HH:mm:ss zzz yyyy" + assert($s.parse(f) == "Mon Jan 2 15:04:05 2006") + # RFC822 = "02 Jan 06 15:04 MST" + s = "02 Jan 06 15:04 MST" + f = "dd MMM yy HH:mm ZZZ" + assert($s.parse(f) == "Mon Jan 2 15:04:00 2006") + # RFC822Z = "02 Jan 06 15:04 -0700" # RFC822 with numeric zone + s = "02 Jan 06 15:04 -07:00" + f = "dd MMM yy HH:mm zzz" + assert($s.parse(f) == "Mon Jan 2 15:04:00 2006") + # RFC850 = "Monday, 02-Jan-06 15:04:05 MST" + s = "Monday, 02-Jan-06 15:04:05 MST" + f = "dddd, dd-MMM-yy HH:mm:ss ZZZ" + assert($s.parse(f) == "Mon Jan 2 15:04:05 2006") + # RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST" + s = "Mon, 02 Jan 2006 15:04:05 MST" + f = "ddd, dd MMM yyyy HH:mm:ss ZZZ" + assert($s.parse(f) == "Mon Jan 2 15:04:05 2006") + # RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" # RFC1123 with numeric zone + s = "Mon, 02 Jan 2006 15:04:05 -07:00" + f = "ddd, dd MMM yyyy HH:mm:ss zzz" + assert($s.parse(f) == "Mon Jan 2 15:04:05 2006") + # RFC3339 = "2006-01-02T15:04:05Z07:00" + s = "2006-01-02T15:04:05Z-07:00" + f = "yyyy-MM-ddTHH:mm:ssZzzz" + assert($s.parse(f) == "Mon Jan 2 15:04:05 2006") + # RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00" + s = "2006-01-02T15:04:05.999999999Z-07:00" + f = "yyyy-MM-ddTHH:mm:ss.999999999Zzzz" + assert($s.parse(f) == "Mon Jan 2 15:04:05 2006") + # Kitchen = "3:04PM" + s = "3:04PM" + f = "h:mmtt" + echo "Kitchen: " & $s.parse(f) \ No newline at end of file From 5424ab3d7ed9f3b147e391540612d5c2483e8c86 Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 9 Feb 2015 21:46:18 +0900 Subject: [PATCH 288/850] Date/time parsing with minor changes requested by Dom96 --- lib/pure/times.nim | 61 ++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 442f46d7ee..69d9b89668 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -26,9 +26,6 @@ type WeekDay* = enum ## represents a weekday dMon, dTue, dWed, dThu, dFri, dSat, dSun -const - digits = {'0','1','2','3','4','5','6','7','8','9'} - var timezone {.importc, header: "".}: int tzname {.importc, header: "" .}: array[0..1, cstring] @@ -780,15 +777,15 @@ proc parseToken(info: var TimeInfo; token, value: string; j: var int) = ## Helper of the parse proc to parse individual tokens. case token of "d": - if value[j+1] in digits: - #two digit format + if value[j+1] in Digits: + # two digit format info.monthday = value[j..j+1].parseInt() j += 2 else: info.monthday = parseInt($value[j]) j += 1 of "dd": - #two digit format + # two digit format info.monthday = value[j..j+1].parseInt() j += 2 of "ddd": @@ -835,33 +832,33 @@ proc parseToken(info: var TimeInfo; token, value: string; j: var int) = else: raise newException(ValueError, "invalid day of week ") of "h", "H": - if value[j+1] in digits: - #two digit format + if value[j+1] in Digits: + # two digit format info.hour = value[j..j+1].parseInt() j += 2 else: info.hour = parseInt($value[j]) j += 1 of "hh", "HH": - #two digit format + # two digit format info.hour = value[j..j+1].parseInt() j += 2 of "m": - if value[j+1] in digits: - #two digit format + if value[j+1] in Digits: + # two digit format info.minute = value[j..j+1].parseInt() j += 2 else: info.minute = parseInt($value[j]) j += 1 of "mm": - #two digit format + # two digit format info.minute = value[j..j+1].parseInt() j += 2 of "M": var month: int - if value[j+1] in digits: - #two digit format + if value[j+1] in Digits: + # two digit format month = value[j..j+1].parseInt() j += 2 else: @@ -941,15 +938,15 @@ proc parseToken(info: var TimeInfo; token, value: string; j: var int) = else: raise newException(ValueError, "invalid month") of "s": - if value[j+1] in digits: - #two digit format + if value[j+1] in Digits: + # two digit format info.second = value[j..j+1].parseInt() j += 2 else: info.second = parseInt($value[j]) j += 1 of "ss": - #two digit format + # two digit format info.second = value[j..j+1].parseInt() j += 2 of "t": @@ -961,7 +958,7 @@ proc parseToken(info: var TimeInfo; token, value: string; j: var int) = info.hour += 12 j += 2 of "yy": - #Assumes current century + # Assumes current century var year = value[j..j+1].parseInt() var thisCen = getLocalTime(getTime()).year div 100 info.year = thisCen*100 + year @@ -997,7 +994,7 @@ proc parseToken(info: var TimeInfo; token, value: string; j: var int) = info.tzname = value[j..j+2].toUpper() j += 3 else: - #Ignore the token and move forward in the value string by the same length + # Ignore the token and move forward in the value string by the same length j += token.len proc parse*(value, layout: string): TimeInfo = @@ -1038,10 +1035,10 @@ proc parse*(value, layout: string): TimeInfo = ## inserted without quoting them: ``:`` ``-`` ``(`` ``)`` ``/`` ``[`` ``]`` ## ``,``. However you don't need to necessarily separate format specifiers, a ## unambiguous format string like ``yyyyMMddhhmmss`` is valid too. - var i = 0 #pointer for format string - var j = 0 #pointer for value string + var i = 0 # pointer for format string + var j = 0 # pointer for value string var token = "" - #Assumes current day of week, month and year, but time is reset to 00:00:00 + # Assumes current day of week, month and year, but time is reset to 00:00:00 var info = getLocalTime(getTime()) info.hour = 0 info.minute = 0 @@ -1051,12 +1048,12 @@ proc parse*(value, layout: string): TimeInfo = of ' ', '-', '/', ':', '\'', '\0', '(', ')', '[', ']', ',': if token.len > 0: parseToken(info, token, value, j) - #Reset token + # Reset token token = "" - #Break if at end of line + # Break if at end of line if layout[i] == '\0': break - #Skip separator and everything between single quotes - #These are literals in both the layout and the value string + # Skip separator and everything between single quotes + # These are literals in both the layout and the value string if layout[i] == '\'': inc(i) inc(j) @@ -1098,12 +1095,12 @@ when isMainModule: " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == "27 27 Mon Monday 4 04 16 16 6 06 1 01 Jan January 29 29 P PM 5 75 975 1975 01975 0 00 00:00 UTC" - # when not defined(JS) and sizeof(Time) == 8: - # var t3 = getGMTime(fromSeconds(889067643645)) # Fri 7 Jun 19:20:45 BST 30143 - # assert t3.format("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & - # " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == - # "7 07 Fri Friday 6 06 18 18 20 20 6 06 Jun June 45 45 P PM 3 43 143 0143 30143 0 00 00:00 UTC" - # assert t3.format(":,[]()-/") == ":,[]()-/" + when not defined(JS) and sizeof(Time) == 8: + var t3 = getGMTime(fromSeconds(889067643645)) # Fri 7 Jun 19:20:45 BST 30143 + assert t3.format("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & + " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == + "7 07 Fri Friday 6 06 18 18 20 20 6 06 Jun June 45 45 P PM 3 43 143 0143 30143 0 00 00:00 UTC" + assert t3.format(":,[]()-/") == ":,[]()-/" var t4 = getGMTime(fromSeconds(876124714)) # Mon 6 Oct 08:58:34 BST 1997 assert t4.format("M MM MMM MMMM") == "10 10 Oct October" From 703633bf0c34b9f041a5307c6a80138db38adf84 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 9 Feb 2015 22:29:20 +0100 Subject: [PATCH 289/850] stop after first failing C compilation for --parallelBuild:1 --- compiler/extccomp.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 8e40cca394..1083b75903 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -626,7 +626,9 @@ proc callCCompiler*(projectfile: string) = if gNumberOfProcessors == 0: gNumberOfProcessors = countProcessors() var res = 0 if gNumberOfProcessors <= 1: - for i in countup(0, high(cmds)): res = max(execWithEcho(cmds[i]), res) + for i in countup(0, high(cmds)): + res = execWithEcho(cmds[i]) + if res != 0: rawMessage(errExecutionOfProgramFailed, []) elif optListCmd in gGlobalOptions or gVerbosity > 1: res = execProcesses(cmds, {poEchoCmd, poUseShell, poParentStreams}, gNumberOfProcessors) From 03019849fc34956225a9879ddc9a7d69d8df1cb3 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Mon, 9 Feb 2015 23:00:07 +0000 Subject: [PATCH 290/850] Async await try statement fixes. --- lib/pure/asyncdispatch.nim | 58 ++++++++++++++++++++++++++------ tests/async/tasyncexceptions.nim | 1 - tests/async/tasynctry.nim | 41 ++++++++++++++++++++++ 3 files changed, 89 insertions(+), 11 deletions(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index bbd8ed8958..34c4b5f709 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -1064,6 +1064,17 @@ proc accept*(socket: TAsyncFD, # -- Await Macro +proc skipUntilStmtList(node: PNimrodNode): PNimrodNode {.compileTime.} = + # Skips a nest of StmtList's. + result = node + if node[0].kind == nnkStmtList: + result = skipUntilStmtList(node[0]) + +proc skipStmtList(node: PNimrodNode): PNimrodNode {.compileTime.} = + result = node + if node[0].kind == nnkStmtList: + result = node[0] + template createCb(retFutureSym, iteratorNameSym, name: expr): stmt {.immediate.} = var nameIterVar = iteratorNameSym @@ -1211,26 +1222,53 @@ proc processBody(node, retFutureSym: PNimrodNode, of nnkTryStmt: # try: await x; except: ... result = newNimNode(nnkStmtList, node) + template wrapInTry(n, tryBody: PNimrodNode) = + var temp = n + n[0] = tryBody + tryBody = temp + + # Transform ``except`` body. + # TODO: Could we perform some ``await`` transformation here to get it + # working in ``except``? + tryBody[1] = processBody(n[1], retFutureSym, subTypeIsVoid, nil) + proc processForTry(n: PNimrodNode, i: var int, res: PNimrodNode): bool {.compileTime.} = + ## Transforms the body of the tryStmt. Does not transform the + ## body in ``except``. + ## Returns true if the tryStmt node was transformed into an ifStmt. result = false - while i < n[0].len: - var processed = processBody(n[0][i], retFutureSym, subTypeIsVoid, n) - if processed.kind != n[0][i].kind or processed.len != n[0][i].len: + var skipped = n.skipStmtList() + while i < skipped.len: + var processed = processBody(skipped[i], retFutureSym, + subTypeIsVoid, n) + + # Check if we transformed the node into an exception check. + # This suggests skipped[i] contains ``await``. + if processed.kind != skipped[i].kind or processed.len != skipped[i].len: + processed = processed.skipUntilStmtList() expectKind(processed, nnkStmtList) expectKind(processed[2][1], nnkElse) i.inc - discard processForTry(n, i, processed[2][1][0]) + + if not processForTry(n, i, processed[2][1][0]): + # We need to wrap the nnkElse nodes back into a tryStmt. + # As they are executed if an exception does not happen + # inside the awaited future. + # The following code will wrap the nodes inside the + # original tryStmt. + wrapInTry(n, processed[2][1][0]) + res.add processed result = true else: - res.add n[0][i] + res.add skipped[i] i.inc var i = 0 if not processForTry(node, i, result): - var temp = node - temp[0] = result - result = temp + # If the tryStmt hasn't been transformed we can just put the body + # back into it. + wrapInTry(node, result) return else: discard @@ -1329,8 +1367,8 @@ macro async*(prc: stmt): stmt {.immediate.} = result[6] = outerProcBody #echo(treeRepr(result)) - #if prc[0].getName == "catch": - # echo(toStrLit(result)) + if prc[0].getName == "test3": + echo(toStrLit(result)) proc recvLine*(socket: TAsyncFD): Future[string] {.async.} = ## Reads a line of data from ``socket``. Returned future will complete once diff --git a/tests/async/tasyncexceptions.nim b/tests/async/tasyncexceptions.nim index 30ef417564..c4379f7d87 100644 --- a/tests/async/tasyncexceptions.nim +++ b/tests/async/tasyncexceptions.nim @@ -19,7 +19,6 @@ proc processClient(fd: int) {.async.} = var foo = line[0] if foo == 'g': raise newException(EBase, "foobar") - proc serve() {.async.} = diff --git a/tests/async/tasynctry.nim b/tests/async/tasynctry.nim index 66ea40d498..99433b9d89 100644 --- a/tests/async/tasynctry.nim +++ b/tests/async/tasynctry.nim @@ -49,3 +49,44 @@ proc catch() {.async.} = assert false asyncCheck catch() + +proc test(): Future[bool] {.async.} = + result = false + try: + raise newException(OSError, "Foobar") + except: + result = true + return + +proc foo(): Future[bool] {.async.} = discard + +proc test2(): Future[bool] {.async.} = + result = false + try: + discard await foo() + raise newException(OSError, "Foobar") + except: + result = true + return + +proc test3(): Future[int] {.async.} = + result = 0 + try: + try: + discard await foo() + raise newException(OSError, "Hello") + except: + result = 1 + raise + except: + result = 2 + return + +var x = test() +assert x.read + +x = test2() +assert x.read + +var y = test3() +assert y.read == 2 From 683b82a2ecbfbf04738715b0bd88a44484da078d Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 5 Feb 2015 12:19:19 +0100 Subject: [PATCH 291/850] fixes #2070 --- lib/system/gc.nim | 38 +++++++++++++++++++++++--------------- lib/system/gc_ms.nim | 10 ++++++---- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 844f286907..9459ee6b90 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -528,20 +528,9 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer = zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)), newsize-oldsize) sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3") - sysAssert(res.refcount shr rcShift <=% 1, "growObj: 4") - #if res.refcount <% rcIncrement: - # add(gch.zct, res) - #else: # XXX: what to do here? - # decRef(ol) - if (ol.refcount and ZctFlag) != 0: - var j = gch.zct.len-1 - var d = gch.zct.d - while j >= 0: - if d[j] == ol: - d[j] = res - break - dec(j) - if canbeCycleRoot(ol): excl(gch.cycleRoots, ol) + # This can be wrong for intermediate temps that are nevertheless on the + # heap because of lambda lifting: + #gcAssert(res.refcount shr rcShift <=% 1, "growObj: 4") when logGC: writeCell("growObj old cell", ol) writeCell("growObj new cell", res) @@ -549,7 +538,26 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer = gcTrace(res, csAllocated) when reallyDealloc: sysAssert(allocInv(gch.region), "growObj before dealloc") - rawDealloc(gch.region, ol) + if ol.refcount shr rcShift <=% 1: + # free immediately to save space: + if (ol.refcount and ZctFlag) != 0: + var j = gch.zct.len-1 + var d = gch.zct.d + while j >= 0: + if d[j] == ol: + d[j] = res + break + dec(j) + if canbeCycleRoot(ol): excl(gch.cycleRoots, ol) + rawDealloc(gch.region, ol) + else: + # we split the old refcount in 2 parts. XXX This is still not entirely + # correct if the pointer that receives growObj's result is on the stack. + # A better fix would be to emit the location specific write barrier for + # 'growObj', but this is lost of more work and who knows what new problems + # this would create. + res.refcount = rcIncrement + decRef(ol) else: sysAssert(ol.typ != nil, "growObj: 5") zeroMem(ol, sizeof(TCell)) diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim index 9c3ee8ce2b..014b7c2783 100644 --- a/lib/system/gc_ms.nim +++ b/lib/system/gc_ms.nim @@ -297,10 +297,12 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer = zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)), newsize-oldsize) sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3") - when withBitvectors: excl(gch.allocated, ol) - when reallyDealloc: rawDealloc(gch.region, ol) - else: - zeroMem(ol, sizeof(TCell)) + when false: + # this is wrong since seqs can be shared via 'shallow': + when withBitvectors: excl(gch.allocated, ol) + when reallyDealloc: rawDealloc(gch.region, ol) + else: + zeroMem(ol, sizeof(TCell)) when withBitvectors: incl(gch.allocated, res) when useCellIds: inc gch.idGenerator From 3a8f7d505b3ddfe724af4237516b1ce46c533758 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 9 Feb 2015 03:14:25 +0100 Subject: [PATCH 292/850] temptyseqs works again --- compiler/sem.nim | 6 ++++-- compiler/semexprs.nim | 33 +++++++++++++++++++-------------- compiler/sempass2.nim | 1 + tests/types/temptyseqs.nim | 2 +- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/compiler/sem.nim b/compiler/sem.nim index 214f471d66..2d69d42137 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -130,9 +130,11 @@ proc commonType*(x, y: PType): PType = elif a.kind == tyTuple and b.kind == tyTuple and a.len == b.len: var nt: PType for i in 0.. 0 and n.sons[0].kind == nkExprColonExpr: - for i in countup(0, sonsLen(n) - 1): + elif sonsLen(n) > 0 and n.sons[0].kind == nkExprColonExpr: + # named tuple? + for i in countup(0, sonsLen(n) - 1): var m = n.sons[i].sons[0] - if m.kind != nkSym: + if m.kind != nkSym: internalError(m.info, "changeType(): invalid tuple constr") return - var f = getSymFromList(newType.n, m.sym.name) - if f == nil: - internalError(m.info, "changeType(): invalid identifier") - return - changeType(n.sons[i].sons[1], f.typ, check) + if tup.n != nil: + var f = getSymFromList(newType.n, m.sym.name) + if f == nil: + internalError(m.info, "changeType(): invalid identifier") + return + changeType(n.sons[i].sons[1], f.typ, check) + else: + changeType(n.sons[i].sons[1], tup.sons[i], check) else: for i in countup(0, sonsLen(n) - 1): - var m = n.sons[i] - var a = newNodeIT(nkExprColonExpr, m.info, newType.sons[i]) - addSon(a, newSymNode(newType.n.sons[i].sym)) - addSon(a, m) - changeType(m, tup.sons[i], check) + changeType(n.sons[i], tup.sons[i], check) + when false: + var m = n.sons[i] + var a = newNodeIT(nkExprColonExpr, m.info, newType.sons[i]) + addSon(a, newSymNode(newType.n.sons[i].sym)) + addSon(a, m) + changeType(m, tup.sons[i], check) of nkCharLit..nkUInt64Lit: if check: let value = n.intVal diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index ede556a707..5434f4f8eb 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -683,6 +683,7 @@ proc track(tracked: PEffects, n: PNode) = for child in n: let last = lastSon(child) if child.kind == nkIdentDefs and last.kind != nkEmpty: + # prevent the all too common 'var x = int' bug: XXX track(tracked, last) for i in 0 .. child.len-3: initVar(tracked, child.sons[i], volatileCheck=false) diff --git a/tests/types/temptyseqs.nim b/tests/types/temptyseqs.nim index f8d22bdb83..2b07ba679a 100644 --- a/tests/types/temptyseqs.nim +++ b/tests/types/temptyseqs.nim @@ -5,7 +5,7 @@ discard """ # bug #1708 let foo = { "1" : (bar: @["1"]), - "2" : (baz: @[]) + "2" : (bar: @[]) } # bug #871 From 247af96b00ae4d995bb668504e10d135fa95506d Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 9 Feb 2015 12:42:00 +0100 Subject: [PATCH 293/850] cleaned up some tests --- compiler/semdata.nim | 1 + compiler/sempass2.nim | 4 +++- compiler/semtypes.nim | 7 ++++--- compiler/sigmatch.nim | 2 +- tests/metatype/tautoproc.nim | 4 ++++ tests/metatype/tcompositetypeclasses.nim | 2 +- tests/{matrix => metatype}/tmatrix.nim | 0 tests/{matrix => metatype}/tmatrix1.nim | 0 tests/{matrix => metatype}/tmatrix2.nim | 0 tests/{static/tmatrix.nim => metatype/tmatrix3.nim} | 0 tests/{static => metatype}/tstaticparammacro.nim | 1 + tests/metatype/ttypetraits.nim | 1 + tests/{matrix/issue1013.nim => metatype/tymatrix.nim} | 0 tests/metatype/typeclassinference.nim | 1 + tests/{namspc => modules}/mnamspc1.nim | 0 tests/{namspc => modules}/mnamspc2.nim | 0 tests/{module => modules}/mopaque.nim | 0 tests/{module => modules}/mrecmod.nim | 0 tests/{module => modules}/mrecmod2.nim | 0 tests/{namspc => modules}/tnamspc.nim | 0 tests/{module => modules}/topaque.nim | 0 tests/{module => modules}/trecinca.nim | 2 +- tests/{module => modules}/trecincb.nim | 2 +- tests/{module => modules}/trecmod.nim | 0 tests/{module => modules}/trecmod2.nim | 0 25 files changed, 19 insertions(+), 8 deletions(-) rename tests/{matrix => metatype}/tmatrix.nim (100%) rename tests/{matrix => metatype}/tmatrix1.nim (100%) rename tests/{matrix => metatype}/tmatrix2.nim (100%) rename tests/{static/tmatrix.nim => metatype/tmatrix3.nim} (100%) rename tests/{static => metatype}/tstaticparammacro.nim (98%) rename tests/{matrix/issue1013.nim => metatype/tymatrix.nim} (100%) rename tests/{namspc => modules}/mnamspc1.nim (100%) rename tests/{namspc => modules}/mnamspc2.nim (100%) rename tests/{module => modules}/mopaque.nim (100%) rename tests/{module => modules}/mrecmod.nim (100%) rename tests/{module => modules}/mrecmod2.nim (100%) rename tests/{namspc => modules}/tnamspc.nim (100%) rename tests/{module => modules}/topaque.nim (100%) rename tests/{module => modules}/trecinca.nim (73%) rename tests/{module => modules}/trecincb.nim (72%) rename tests/{module => modules}/trecmod.nim (100%) rename tests/{module => modules}/trecmod2.nim (100%) diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 1577615919..27d4410007 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -221,6 +221,7 @@ proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode = proc makeTypeFromExpr*(c: PContext, n: PNode): PType = result = newTypeS(tyFromExpr, c) + assert n != nil result.n = n proc newTypeWithSons*(c: PContext, kind: TTypeKind, diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 5434f4f8eb..b36103d9eb 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -683,12 +683,14 @@ proc track(tracked: PEffects, n: PNode) = for child in n: let last = lastSon(child) if child.kind == nkIdentDefs and last.kind != nkEmpty: - # prevent the all too common 'var x = int' bug: XXX track(tracked, last) for i in 0 .. child.len-3: initVar(tracked, child.sons[i], volatileCheck=false) addAsgnFact(tracked.guards, child.sons[i], last) notNilCheck(tracked, last, child.sons[i].typ) + #if last.kind != nkEmpty: + # prevent the all too common 'var x = int' bug: XXX + # since 'var (a, b): T = ()' is not even allowed, there is always type # inference for (a, b) and thus no nil checking is necessary. of nkCaseStmt: trackCase(tracked, n) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index d052700b20..048154f120 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -781,9 +781,10 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, result.rawAddSon(paramType) for i in 0 .. paramType.sonsLen - 2: - let dummyType = if paramType.sons[i].kind == tyStatic: tyUnknown - else: tyAnything - result.rawAddSon newTypeS(dummyType, c) + if paramType.sons[i].kind == tyStatic: + result.rawAddSon makeTypeFromExpr(c, ast.emptyNode) # aka 'tyUnkown' + else: + result.rawAddSon newTypeS(tyAnything, c) if paramType.lastSon.kind == tyUserTypeClass: result.kind = tyUserTypeClassInst diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 2e37f3bf13..9a99d5200c 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1056,7 +1056,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = of tyFromExpr: # fix the expression, so it contains the already instantiated types - if f.n == nil: return isGeneric + if f.n == nil or f.n.kind == nkEmpty: return isGeneric let reevaluated = tryResolvingStaticExpr(c, f.n) case reevaluated.typ.kind of tyTypeDesc: diff --git a/tests/metatype/tautoproc.nim b/tests/metatype/tautoproc.nim index 9e8ff0bcb0..562f508fc5 100644 --- a/tests/metatype/tautoproc.nim +++ b/tests/metatype/tautoproc.nim @@ -1,3 +1,7 @@ +discard """ + errormsg: "expression 'generate(builder)' has no type (or is ambiguous)" +""" + # bug #898 proc measureTime(e: auto) = diff --git a/tests/metatype/tcompositetypeclasses.nim b/tests/metatype/tcompositetypeclasses.nim index 5ae93795f1..1cb86e4d76 100644 --- a/tests/metatype/tcompositetypeclasses.nim +++ b/tests/metatype/tcompositetypeclasses.nim @@ -30,7 +30,7 @@ accept bar(vbar) accept baz(vbar) accept baz(vbaz) -reject baz(vnotbaz) +#reject baz(vnotbaz) # XXX this really shouldn't compile reject bar(vfoo) # https://github.com/Araq/Nim/issues/517 diff --git a/tests/matrix/tmatrix.nim b/tests/metatype/tmatrix.nim similarity index 100% rename from tests/matrix/tmatrix.nim rename to tests/metatype/tmatrix.nim diff --git a/tests/matrix/tmatrix1.nim b/tests/metatype/tmatrix1.nim similarity index 100% rename from tests/matrix/tmatrix1.nim rename to tests/metatype/tmatrix1.nim diff --git a/tests/matrix/tmatrix2.nim b/tests/metatype/tmatrix2.nim similarity index 100% rename from tests/matrix/tmatrix2.nim rename to tests/metatype/tmatrix2.nim diff --git a/tests/static/tmatrix.nim b/tests/metatype/tmatrix3.nim similarity index 100% rename from tests/static/tmatrix.nim rename to tests/metatype/tmatrix3.nim diff --git a/tests/static/tstaticparammacro.nim b/tests/metatype/tstaticparammacro.nim similarity index 98% rename from tests/static/tstaticparammacro.nim rename to tests/metatype/tstaticparammacro.nim index ebd6caa470..e577efc566 100644 --- a/tests/static/tstaticparammacro.nim +++ b/tests/metatype/tstaticparammacro.nim @@ -14,6 +14,7 @@ AST b 20Test 20 ''' + disabled: true """ import macros diff --git a/tests/metatype/ttypetraits.nim b/tests/metatype/ttypetraits.nim index 4344855eb6..4c3ad9e0b6 100644 --- a/tests/metatype/ttypetraits.nim +++ b/tests/metatype/ttypetraits.nim @@ -1,6 +1,7 @@ discard """ msg: "int\nstring\nTBar[int]" output: "int\nstring\nTBar[int]\nint\nrange 0..2(int)\nstring" + disabled: true """ import typetraits diff --git a/tests/matrix/issue1013.nim b/tests/metatype/tymatrix.nim similarity index 100% rename from tests/matrix/issue1013.nim rename to tests/metatype/tymatrix.nim diff --git a/tests/metatype/typeclassinference.nim b/tests/metatype/typeclassinference.nim index 2ac037ac5f..fd2d307a92 100644 --- a/tests/metatype/typeclassinference.nim +++ b/tests/metatype/typeclassinference.nim @@ -1,6 +1,7 @@ discard """ errormsg: "type mismatch: got (string) but expected 'ptr'" line: 20 + disabled: true """ import typetraits diff --git a/tests/namspc/mnamspc1.nim b/tests/modules/mnamspc1.nim similarity index 100% rename from tests/namspc/mnamspc1.nim rename to tests/modules/mnamspc1.nim diff --git a/tests/namspc/mnamspc2.nim b/tests/modules/mnamspc2.nim similarity index 100% rename from tests/namspc/mnamspc2.nim rename to tests/modules/mnamspc2.nim diff --git a/tests/module/mopaque.nim b/tests/modules/mopaque.nim similarity index 100% rename from tests/module/mopaque.nim rename to tests/modules/mopaque.nim diff --git a/tests/module/mrecmod.nim b/tests/modules/mrecmod.nim similarity index 100% rename from tests/module/mrecmod.nim rename to tests/modules/mrecmod.nim diff --git a/tests/module/mrecmod2.nim b/tests/modules/mrecmod2.nim similarity index 100% rename from tests/module/mrecmod2.nim rename to tests/modules/mrecmod2.nim diff --git a/tests/namspc/tnamspc.nim b/tests/modules/tnamspc.nim similarity index 100% rename from tests/namspc/tnamspc.nim rename to tests/modules/tnamspc.nim diff --git a/tests/module/topaque.nim b/tests/modules/topaque.nim similarity index 100% rename from tests/module/topaque.nim rename to tests/modules/topaque.nim diff --git a/tests/module/trecinca.nim b/tests/modules/trecinca.nim similarity index 73% rename from tests/module/trecinca.nim rename to tests/modules/trecinca.nim index 62d37783ce..bedea8d7e6 100644 --- a/tests/module/trecinca.nim +++ b/tests/modules/trecinca.nim @@ -1,7 +1,7 @@ discard """ file: "tests/reject/trecincb.nim" line: 9 - errormsg: "recursive dependency: 'tests/module/trecincb.nim'" + errormsg: "recursive dependency: 'trecincb.nim'" """ # Test recursive includes diff --git a/tests/module/trecincb.nim b/tests/modules/trecincb.nim similarity index 72% rename from tests/module/trecincb.nim rename to tests/modules/trecincb.nim index a2934052f9..eb0f72db06 100644 --- a/tests/module/trecincb.nim +++ b/tests/modules/trecincb.nim @@ -1,7 +1,7 @@ discard """ file: "trecincb.nim" line: 9 - errormsg: "recursive dependency: 'tests/module/trecincb.nim'" + errormsg: "recursive dependency: 'trecincb.nim'" """ # Test recursive includes diff --git a/tests/module/trecmod.nim b/tests/modules/trecmod.nim similarity index 100% rename from tests/module/trecmod.nim rename to tests/modules/trecmod.nim diff --git a/tests/module/trecmod2.nim b/tests/modules/trecmod2.nim similarity index 100% rename from tests/module/trecmod2.nim rename to tests/modules/trecmod2.nim From e371bb3e26e8042e131b1c07c187251688c35946 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 9 Feb 2015 13:26:29 +0100 Subject: [PATCH 294/850] fixes #1131 --- compiler/sempass2.nim | 3 --- compiler/semstmts.nim | 4 ++++ tests/metatype/typedesc_as_value.nim | 11 +++++++++++ todo.txt | 1 - 4 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 tests/metatype/typedesc_as_value.nim diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index b36103d9eb..ede556a707 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -688,9 +688,6 @@ proc track(tracked: PEffects, n: PNode) = initVar(tracked, child.sons[i], volatileCheck=false) addAsgnFact(tracked.guards, child.sons[i], last) notNilCheck(tracked, last, child.sons[i].typ) - #if last.kind != nkEmpty: - # prevent the all too common 'var x = int' bug: XXX - # since 'var (a, b): T = ()' is not even allowed, there is always type # inference for (a, b) and thus no nil checking is necessary. of nkCaseStmt: trackCase(tracked, n) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 6e5b272de5..07cae5d043 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -359,6 +359,10 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = var def: PNode if a.sons[length-1].kind != nkEmpty: def = semExprWithType(c, a.sons[length-1], {efAllowDestructor}) + if def.typ.kind == tyTypeDesc and c.p.owner.kind != skMacro: + # prevent the all too common 'var x = int' bug: + localError(def.info, "'typedesc' metatype is not valid here; typed '=' instead of ':'?") + def.typ = errorType(c) if typ != nil: if typ.isMetaType: def = inferWithMetatype(c, typ, def) diff --git a/tests/metatype/typedesc_as_value.nim b/tests/metatype/typedesc_as_value.nim new file mode 100644 index 0000000000..f6e5269870 --- /dev/null +++ b/tests/metatype/typedesc_as_value.nim @@ -0,0 +1,11 @@ +discard """ + errormsg: "'typedesc' metatype is not valid here; typed '=' instead of ':'?" +""" + + +var x = int + +echo x + + + diff --git a/todo.txt b/todo.txt index 252699bf17..fca43ad113 100644 --- a/todo.txt +++ b/todo.txt @@ -5,7 +5,6 @@ version 0.10.4 - improve GC-unsafety warnings - get rid of 'mget'; aka priority of 'var' needs to be 'var{lvalue}' - improve documentation (theindex!) -- fix the getUniqueType() bug version 1.0 From 865d341b3230f235765705fca156e286b7b6b43b Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 9 Feb 2015 15:12:31 +0100 Subject: [PATCH 295/850] unsigned array indexes work better; minor cleanups --- compiler/astalgo.nim | 14 +++++++------- tests/implicit/timplictderef.nim | 21 +++++++++++++++++++-- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index f23e9a9833..e9b82d74b3 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -130,8 +130,8 @@ proc skipConvAndClosure*(n: PNode): PNode = proc sameValue*(a, b: PNode): bool = result = false case a.kind - of nkCharLit..nkInt64Lit: - if b.kind in {nkCharLit..nkInt64Lit}: result = a.intVal == b.intVal + of nkCharLit..nkUInt64Lit: + if b.kind in {nkCharLit..nkUInt64Lit}: result = a.intVal == b.intVal of nkFloatLit..nkFloat64Lit: if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal == b.floatVal of nkStrLit..nkTripleStrLit: @@ -145,13 +145,13 @@ proc leValue*(a, b: PNode): bool = # a <= b? result = false case a.kind - of nkCharLit..nkInt64Lit: - if b.kind in {nkCharLit..nkInt64Lit}: result = a.intVal <= b.intVal - of nkFloatLit..nkFloat64Lit: + of nkCharLit..nkUInt32Lit: + if b.kind in {nkCharLit..nkUInt32Lit}: result = a.intVal <= b.intVal + of nkFloatLit..nkFloat64Lit: if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal <= b.floatVal - of nkStrLit..nkTripleStrLit: + of nkStrLit..nkTripleStrLit: if b.kind in {nkStrLit..nkTripleStrLit}: result = a.strVal <= b.strVal - else: + else: # don't raise an internal error for 'nimrod check': #InternalError(a.info, "leValue") discard diff --git a/tests/implicit/timplictderef.nim b/tests/implicit/timplictderef.nim index 99b0b645be..fcb647217c 100644 --- a/tests/implicit/timplictderef.nim +++ b/tests/implicit/timplictderef.nim @@ -1,9 +1,10 @@ discard """ - output: "2" + output: '''2 +88''' """ type - TValue* {.pure, final.} = object of TObject + TValue* {.pure, final.} = object of RootObj a: int PValue = ref TValue PPValue = ptr PValue @@ -16,3 +17,19 @@ var sp: PPValue = addr x sp.a = 2 if sp.a == 2: echo 2 # with sp[].a the error is gone +# Test the new auto-deref a little + +{.experimental.} + +proc p(x: var int; y: int) = x += y + +block: + var x: ref int + new(x) + + x.p(44) + + var indirect = p + x.indirect(44) + + echo x[] From eec18896b760059af62a7cb63a151339f44c5f66 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 10 Feb 2015 02:03:11 +0100 Subject: [PATCH 296/850] cleaned up GC tests; fixes object variant re-assign bug --- lib/system/assign.nim | 10 +++++++--- tests/gc/gcleak4.nim | 4 +++- todo.txt | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/system/assign.nim b/lib/system/assign.nim index 429a92d341..78995954f7 100644 --- a/lib/system/assign.nim +++ b/lib/system/assign.nim @@ -27,7 +27,7 @@ proc genericAssignAux(dest, src: pointer, n: ptr TNimNode, var m = selectBranch(src, n) # reset if different branches are in use; note different branches also # imply that's not self-assignment (``x = x``)! - if m != dd and dd != nil: + if m != dd and dd != nil: genericResetAux(dest, dd) copyMem(cast[pointer](d +% n.offset), cast[pointer](s +% n.offset), n.typ.size) @@ -205,9 +205,13 @@ proc genericReset(dest: pointer, mt: PNimType) = case mt.kind of tyString, tyRef, tySequence: unsureAsgnRef(cast[PPointer](dest), nil) - of tyObject, tyTuple: - # we don't need to reset m_type field for tyObject + of tyTuple: genericResetAux(dest, mt.node) + of tyObject: + genericResetAux(dest, mt.node) + # also reset the type field for tyObject, for correct branch switching! + var pint = cast[ptr PNimType](dest) + pint[] = nil of tyArray, tyArrayConstr: for i in 0..(mt.size div mt.base.size)-1: genericReset(cast[pointer](d +% i*% mt.base.size), mt.base) diff --git a/tests/gc/gcleak4.nim b/tests/gc/gcleak4.nim index 6f2b8a1fe6..54e74ac7b9 100644 --- a/tests/gc/gcleak4.nim +++ b/tests/gc/gcleak4.nim @@ -38,12 +38,14 @@ proc newPlus(a, b: ref TExpr): ref TPlusExpr = result.b = b result.op2 = $getOccupiedMem() +const Limit = when compileOption("gc", "markAndSweep"): 5*1024*1024 else: 500_000 + for i in 0..100_000: var s: array[0..11, ref TExpr] for j in 0..high(s): s[j] = newPlus(newPlus(newLit(j), newLit(2)), newLit(4)) if eval(s[j]) != j+6: quit "error: wrong result" - if getOccupiedMem() > 500_000: quit("still a leak!") + if getOccupiedMem() > Limit: quit("still a leak!") echo "no leak: ", getOccupiedMem() diff --git a/todo.txt b/todo.txt index fca43ad113..1c10fef8ae 100644 --- a/todo.txt +++ b/todo.txt @@ -5,6 +5,7 @@ version 0.10.4 - improve GC-unsafety warnings - get rid of 'mget'; aka priority of 'var' needs to be 'var{lvalue}' - improve documentation (theindex!) +- ensure (ref T)(a, b) works as a type conversion and type constructor version 1.0 @@ -66,7 +67,6 @@ version 0.9.x - memory manager: add a measure of fragmentation - implement 'bits' pragmas - we need a magic thisModule symbol -- ensure (ref T)(a, b) works as a type conversion and type constructor - optimize 'genericReset'; 'newException' leads to code bloat - The 'do' notation might be trimmed so that its only purpose is to pass multiple multi line constructs to a macro. From c2da0e9b3db54597fc35b65a23d67aa3c5714e82 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 10 Feb 2015 16:19:32 +0100 Subject: [PATCH 297/850] cleanup index generation --- compiler/{nim.ini => installer.ini} | 0 doc/niminst.txt | 2 +- koch.nim | 14 ++++++------ tests/objects/trefobjsyntax.nim | 27 +++++++++++++++++++++++ tests/objvariant/treassign.nim | 27 +++++++++++++++++++++++ todo.txt | 3 --- tools/nimweb.nim | 2 +- web/{nim.ini => website.ini} | 33 +++++++---------------------- 8 files changed, 71 insertions(+), 37 deletions(-) rename compiler/{nim.ini => installer.ini} (100%) create mode 100644 tests/objects/trefobjsyntax.nim create mode 100644 tests/objvariant/treassign.nim rename web/{nim.ini => website.ini} (69%) diff --git a/compiler/nim.ini b/compiler/installer.ini similarity index 100% rename from compiler/nim.ini rename to compiler/installer.ini diff --git a/doc/niminst.txt b/doc/niminst.txt index d743c5187d..ca05cc514d 100644 --- a/doc/niminst.txt +++ b/doc/niminst.txt @@ -190,6 +190,6 @@ Real world example The installers for the Nim compiler itself are generated by niminst. Have a look at its configuration file: -.. include:: compiler/nim.ini +.. include:: compiler/installer.ini :literal: diff --git a/koch.nim b/koch.nim index 782a55e018..b0b4a79da0 100644 --- a/koch.nim +++ b/koch.nim @@ -97,13 +97,13 @@ const compileNimInst = "-d:useLibzipSrc tools/niminst/niminst" proc csource(args: string) = - exec("$4 cc $1 -r $3 --var:version=$2 --var:mingw=none csource compiler/nim.ini $1" % + exec("$4 cc $1 -r $3 --var:version=$2 --var:mingw=none csource compiler/installer.ini $1" % [args, VersionAsString, compileNimInst, findNim()]) proc zip(args: string) = - exec("$3 cc -r $2 --var:version=$1 --var:mingw=none scripts compiler/nim.ini" % + exec("$3 cc -r $2 --var:version=$1 --var:mingw=none scripts compiler/installer.ini" % [VersionAsString, compileNimInst, findNim()]) - exec("$# --var:version=$# --var:mingw=none zip compiler/nim.ini" % + exec("$# --var:version=$# --var:mingw=none zip compiler/installer.ini" % ["tools/niminst/niminst".exe, VersionAsString]) proc buildTool(toolname, args: string) = @@ -121,20 +121,20 @@ proc nsis(args: string) = " nsis compiler/nim") % [VersionAsString, $(sizeof(pointer)*8)]) proc install(args: string) = - exec("$# cc -r $# --var:version=$# --var:mingw=none scripts compiler/nim.ini" % + exec("$# cc -r $# --var:version=$# --var:mingw=none scripts compiler/installer.ini" % [findNim(), compileNimInst, VersionAsString]) exec("sh ./install.sh $#" % args) proc web(args: string) = - exec("$# cc -r tools/nimweb.nim $# web/nim --putenv:nimversion=$#" % + exec("$# cc -r tools/nimweb.nim $# web/website.ini --putenv:nimversion=$#" % [findNim(), args, VersionAsString]) proc website(args: string) = - exec("$# cc -r tools/nimweb.nim $# --website web/nim --putenv:nimversion=$#" % + exec("$# cc -r tools/nimweb.nim $# --website web/website.ini --putenv:nimversion=$#" % [findNim(), args, VersionAsString]) proc pdf(args="") = - exec("$# cc -r tools/nimweb.nim $# --pdf web/nim --putenv:nimversion=$#" % + exec("$# cc -r tools/nimweb.nim $# --pdf web/website.ini --putenv:nimversion=$#" % [findNim(), args, VersionAsString]) # -------------- boot --------------------------------------------------------- diff --git a/tests/objects/trefobjsyntax.nim b/tests/objects/trefobjsyntax.nim new file mode 100644 index 0000000000..9b48de718a --- /dev/null +++ b/tests/objects/trefobjsyntax.nim @@ -0,0 +1,27 @@ +discard """ + output: '''wohoo +baz''' +""" + +# Test to ensure the popular 'ref T' syntax works everywhere + +type + Foo = object + a, b: int + s: string + + FooBar = object of RootObj + n, m: string + Baz = object of FooBar + +proc invoke(a: ref Baz) = + echo "baz" + +# check object construction: +let x = (ref Foo)(a: 0, b: 45, s: "wohoo") +echo x.s + +var y: ref FooBar = (ref Baz)(n: "n", m: "m") + +invoke((ref Baz)(y)) + diff --git a/tests/objvariant/treassign.nim b/tests/objvariant/treassign.nim new file mode 100644 index 0000000000..2938b30a33 --- /dev/null +++ b/tests/objvariant/treassign.nim @@ -0,0 +1,27 @@ +discard """ + output: "SUCCESS" +""" + +type + BasicNumber = object of RootObj + value: float32 + RefChild* = ref object + curr*: TokenObject + Token* {.pure.} = enum + foo, + bar, + TokenObject = object + case kind*: Token + of Token.foo: + foo*: string + of Token.bar: + bar*: BasicNumber + + +var t = RefChild() + +t.curr = TokenObject(kind: Token.bar, bar: BasicNumber(value: 12.34)) + +t.curr = TokenObject(kind: Token.foo, foo: "foo") + +echo "SUCCESS" diff --git a/todo.txt b/todo.txt index 1c10fef8ae..706954f652 100644 --- a/todo.txt +++ b/todo.txt @@ -4,8 +4,6 @@ version 0.10.4 - make 'nil' work for 'add' and 'len' - improve GC-unsafety warnings - get rid of 'mget'; aka priority of 'var' needs to be 'var{lvalue}' -- improve documentation (theindex!) -- ensure (ref T)(a, b) works as a type conversion and type constructor version 1.0 @@ -95,4 +93,3 @@ CGEN ==== - codegen should use "NIM_CAST" macro and respect aliasing rules for GCC - ``restrict`` pragma + backend support -- 'const' objects including case objects diff --git a/tools/nimweb.nim b/tools/nimweb.nim index e74daf98fb..8213cf4185 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -319,7 +319,7 @@ proc buildAddDoc(c: var TConfigData, destPath: string) = # build additional documentation (without the index): var commands = newSeq[string](c.webdoc.len) for i, doc in pairs(c.webdoc): - commands[i] = "nim doc $# --docSeeSrcUrl:$#/$#/$# -o:$# $#" % + commands[i] = "nim doc2 $# --docSeeSrcUrl:$#/$#/$# -o:$# $#" % [c.nimArgs, c.gitRepo, c.gitCommit, doc.pathPart, destPath / changeFileExt(splitFile(doc).name, "html"), doc] mexec(commands, c.numProcessors) diff --git a/web/nim.ini b/web/website.ini similarity index 69% rename from web/nim.ini rename to web/website.ini index 0190416b21..c0a648c562 100644 --- a/web/nim.ini +++ b/web/website.ini @@ -27,19 +27,6 @@ news: news [Ticker] file: ticker.txt -[Quotations] -# Page: quote - Person -# Bad things will happen if you use multiple dashes here. -index: """Is it so bad, then, to be misunderstood? Pythagoras was misunderstood, -and Socrates, and Jesus, and Luther, and Copernicus, and Galileo, and Newton, -and every pure and wise spirit that ever took flesh. To be great is to be -misunderstood. - Ralph Waldo Emerson""" -documentation: """Incorrect documentation is often worse than no documentation. -- Bertrand Meyer""" -download: """There are two major products that come out of Berkeley: LSD and -UNIX. We don't believe this to be a coincidence. - Jeremy S. Anderson.""" -learn: """Repetition renders the ridiculous reasonable. - Norman Wildberger""" - [Documentation] doc: "endb;intern;apis;lib;manual.txt;tut1;tut2;nimc;overview;filters" doc: "tools;niminst;nimgrep;gc;estp;idetools;docgen;koch;backends.txt" @@ -61,7 +48,7 @@ srcdoc2: "pure/httpserver;pure/httpclient;pure/smtp;impure/ssl;pure/fsmonitor" srcdoc2: "pure/ropes;pure/unidecode/unidecode;pure/xmldom;pure/xmldomparser" srcdoc2: "pure/xmlparser;pure/htmlparser;pure/xmltree;pure/colors;pure/mimetypes" srcdoc2: "pure/json;pure/base64;pure/scgi;pure/redis;impure/graphics" -srcdoc2: "impure/rdstdin;wrappers/sphinx" +srcdoc2: "impure/rdstdin" srcdoc2: "pure/collections/tables;pure/collections/sets;pure/collections/lists" srcdoc2: "pure/collections/intsets;pure/collections/queues;pure/encodings" srcdoc2: "pure/events;pure/collections/sequtils;pure/cookies" @@ -71,19 +58,15 @@ srcdoc2: "pure/nimprof;pure/unittest;packages/docutils/highlite" srcdoc2: "packages/docutils/rst;packages/docutils/rstast" srcdoc2: "packages/docutils/rstgen;pure/logging;pure/asyncdispatch;pure/asyncnet" srcdoc2: "pure/rawsockets;pure/asynchttpserver;pure/net;pure/selectors;pure/future" -srcdoc2: "wrappers/expat;wrappers/readline/history" -srcdoc2: "wrappers/libsvm.nim;wrappers/libuv" -srcdoc2: "wrappers/zip/zlib;wrappers/zip/libzip" -srcdoc2: "pure/md5;wrappers/mysql;wrappers/iup" -srcdoc2: "posix/posix;wrappers/odbcsql" -srcdoc2: "wrappers/tre;wrappers/openssl;wrappers/pcre" -srcdoc2: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc" -srcdoc2: "wrappers/readline/readline;wrappers/readline/rltypedefs" -srcdoc2: "wrappers/joyent_http_parser" +srcdoc2: "pure/md5" +srcdoc2: "posix/posix" srcdoc2: "pure/fenv" -webdoc: "pure/md5;wrappers/mysql;wrappers/iup" -webdoc: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc" +; Note: everything under 'webdoc' doesn't get listed in the index, so wrappers +; should live here + +webdoc: "wrappers/mysql;wrappers/iup;wrappers/sphinx" +webdoc: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc;wrappers/odbcsql" webdoc: "wrappers/expat;wrappers/pcre" webdoc: "wrappers/tre;wrappers/openssl" webdoc: "wrappers/libuv;wrappers/joyent_http_parser" From 0284e8d11c5f93f1ff6c44f83ca8e4ba73365c98 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 10 Feb 2015 20:18:23 +0100 Subject: [PATCH 298/850] fixes #2070 --- copying.txt | 2 +- tests/gc/growobjcrash.nim | 29 +++++++++++++++++++++++++++++ tests/testament/categories.nim | 3 ++- 3 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 tests/gc/growobjcrash.nim diff --git a/copying.txt b/copying.txt index 908625e181..d89bace0ba 100644 --- a/copying.txt +++ b/copying.txt @@ -1,7 +1,7 @@ ===================================================== Nim -- a Compiler for Nim. http://nim-lang.org/ -Copyright (C) 2006-2014 Andreas Rumpf. All rights reserved. +Copyright (C) 2006-2015 Andreas Rumpf. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/tests/gc/growobjcrash.nim b/tests/gc/growobjcrash.nim new file mode 100644 index 0000000000..00620fed3c --- /dev/null +++ b/tests/gc/growobjcrash.nim @@ -0,0 +1,29 @@ +discard """ + output: "works" +""" + +import cgi, strtabs + +proc handleRequest(query: string): StringTableRef = + iterator foo(): StringTableRef {.closure.} = + var params = {:}.newStringTable() + for key, val in cgi.decodeData(query): + params[key] = val + yield params + + let x = foo + result = x() + +const Limit = when compileOption("gc", "markAndSweep"): 5*1024*1024 else: 500_000 + +proc main = + var counter = 0 + for i in 0 .. 100_000: + for k, v in handleRequest("nick=Elina2&type=activate"): + inc counter + if counter mod 100 == 0: + if getOccupiedMem() > Limit: + quit "but now a leak" + +main() +echo "works" diff --git a/tests/testament/categories.nim b/tests/testament/categories.nim index 54e9626932..ed4d27cabb 100644 --- a/tests/testament/categories.nim +++ b/tests/testament/categories.nim @@ -120,7 +120,8 @@ proc gcTests(r: var TResults, cat: Category, options: string) = " --gc:markAndSweep", cat, actionRun) testSpec r, makeTest("tests/gc" / filename, options & " -d:release --gc:markAndSweep", cat, actionRun) - + + test "growobjcrash" test "gcbench" test "gcleak" test "gcleak2" From 4ce3c77031d1fa9895431db405e1185c9ae7338b Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 10 Feb 2015 22:23:38 +0100 Subject: [PATCH 299/850] increase limit for 64bit systems --- tests/gc/growobjcrash.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gc/growobjcrash.nim b/tests/gc/growobjcrash.nim index 00620fed3c..a16468c7e8 100644 --- a/tests/gc/growobjcrash.nim +++ b/tests/gc/growobjcrash.nim @@ -14,7 +14,7 @@ proc handleRequest(query: string): StringTableRef = let x = foo result = x() -const Limit = when compileOption("gc", "markAndSweep"): 5*1024*1024 else: 500_000 +const Limit = when compileOption("gc", "markAndSweep"): 5*1024*1024 else: 700_000 proc main = var counter = 0 From 3643068527c619ed29d292b13ef352d7ab02b1b6 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 11 Feb 2015 15:42:33 +0900 Subject: [PATCH 300/850] Date/time parsing with changes suggested by Araq --- lib/pure/times.nim | 617 +++++++++++++++++++++------------------------ 1 file changed, 283 insertions(+), 334 deletions(-) diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 69d9b89668..70bf7073d5 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -16,7 +16,7 @@ # of the standard library! import - strutils, pegs + strutils, parseutils include "system/inclrtl" @@ -744,334 +744,283 @@ proc format*(info: TimeInfo, f: string): string = {.pop.} -proc getMonth(m: int): Month = - case m - of 1: - return mJan - of 2: - return mFeb - of 3: - return mMar - of 4: - return mApr - of 5: - return mMay - of 6: - return mJun - of 7: - return mJul - of 8: - return mAug - of 9: - return mSep - of 10: - return mOct - of 11: - return mNov - of 12: - return mDec - else: - raise newException(ValueError, "invalid month") - proc parseToken(info: var TimeInfo; token, value: string; j: var int) = - ## Helper of the parse proc to parse individual tokens. - case token - of "d": - if value[j+1] in Digits: - # two digit format - info.monthday = value[j..j+1].parseInt() - j += 2 - else: - info.monthday = parseInt($value[j]) - j += 1 - of "dd": - # two digit format - info.monthday = value[j..j+1].parseInt() - j += 2 - of "ddd": - case value[j..j+2].toLower(): - of "sun": - info.weekday = dSun - of "mon": - info.weekday = dMon - of "tue": - info.weekday = dTue - of "wed": - info.weekday = dWed - of "thu": - info.weekday = dThu - of "fri": - info.weekday = dFri - of "sat": - info.weekday = dSat - else: - raise newException(ValueError, "invalid day of week ") - j += 3 - of "dddd": - if value.match(peg"^i'sunday'.*"): - info.weekday = dSun - j += 6 - elif value.match(peg"^i'monday'.*"): - info.weekday = dMon - j += 6 - elif value.match(peg"^i'tuesday'.*"): - info.weekday = dTue - j += 7 - elif value.match(peg"^i'wednesday'.*"): - info.weekday = dWed - j += 9 - elif value.match(peg"^i'thursday'.*"): - info.weekday = dThu - j += 8 - elif value.match(peg"^i'friday'.*"): - info.weekday = dFri - j += 6 - elif value.match(peg"^i'saturday'.*"): - info.weekday = dSat - j += 8 - else: - raise newException(ValueError, "invalid day of week ") - of "h", "H": - if value[j+1] in Digits: - # two digit format - info.hour = value[j..j+1].parseInt() - j += 2 - else: - info.hour = parseInt($value[j]) - j += 1 - of "hh", "HH": - # two digit format - info.hour = value[j..j+1].parseInt() - j += 2 - of "m": - if value[j+1] in Digits: - # two digit format - info.minute = value[j..j+1].parseInt() - j += 2 - else: - info.minute = parseInt($value[j]) - j += 1 - of "mm": - # two digit format - info.minute = value[j..j+1].parseInt() - j += 2 - of "M": - var month: int - if value[j+1] in Digits: - # two digit format - month = value[j..j+1].parseInt() - j += 2 - else: - month = parseInt($value[j]) - j += 1 - info.month = getMonth(month) - of "MM": - var month = value[j..j+1].parseInt() - j += 2 - info.month = getMonth(month) - of "MMM": - case value[j..j+2].toLower(): - of "jan": - info.month = mJan - of "feb": - info.month = mFeb - of "mar": - info.month = mMar - of "apr": - info.month = mApr - of "may": - info.month = mMay - of "jun": - info.month = mJun - of "jul": - info.month = mJul - of "aug": - info.month = mAug - of "sep": - info.month = mSep - of "oct": - info.month = mOct - of "nov": - info.month = mNov - of "dec": - info.month = mDec - else: - raise newException(ValueError, "invalid month") - j += 3 - of "MMMM": - if value.match(peg"^i'january'.*"): - info.month = mJan - j += 7 - elif value.match(peg"^i'february'.*"): - info.month = mFeb - j += 8 - elif value.match(peg"^i'march'.*"): - info.month = mMar - j += 5 - elif value.match(peg"^i'april'.*"): - info.month = mApr - j += 5 - elif value.match(peg"^i'may'.*"): - info.month = mMay - j += 3 - elif value.match(peg"^i'june'.*"): - info.month = mJun - j += 4 - elif value.match(peg"^i'july'.*"): - info.month = mJul - j += 4 - elif value.match(peg"^i'august'.*"): - info.month = mAug - j += 6 - elif value.match(peg"^i'september'.*"): - info.month = mSep - j += 9 - elif value.match(peg"^i'october'.*"): - info.month = mOct - j += 7 - elif value.match(peg"^i'november'.*"): - info.month = mNov - j += 8 - elif value.match(peg"^i'december'.*"): - info.month = mDec - j += 8 - else: - raise newException(ValueError, "invalid month") - of "s": - if value[j+1] in Digits: - # two digit format - info.second = value[j..j+1].parseInt() - j += 2 - else: - info.second = parseInt($value[j]) - j += 1 - of "ss": - # two digit format - info.second = value[j..j+1].parseInt() - j += 2 - of "t": - if value[j] == 'P' and info.hour > 0 and info.hour < 12: - info.hour += 12 - j += 1 - of "tt": - if value[j..j+1] == "PM" and info.hour > 0 and info.hour < 12: - info.hour += 12 - j += 2 - of "yy": - # Assumes current century - var year = value[j..j+1].parseInt() - var thisCen = getLocalTime(getTime()).year div 100 - info.year = thisCen*100 + year - j += 2 - of "yyyy": - info.year = value[j..j+3].parseInt() - j += 4 - of "z": - if value[j] == '+': - info.timezone = parseInt($value[j+1]) - elif value[j] == '-': - info.timezone = 0-parseInt($value[j+1]) - else: - raise newException(ValueError, "Sign for timezone " & value[j]) - j += 2 - of "zz": - if value[j] == '+': - info.timezone = value[j+1..j+2].parseInt() - elif value[j] == '-': - info.timezone = 0-value[j+1..j+2].parseInt() - else: - raise newException(ValueError, "Sign for timezone " & value[j]) - j += 3 - of "zzz": - if value[j] == '+': - info.timezone = value[j+1..j+2].parseInt() - elif value[j] == '-': - info.timezone = 0-value[j+1..j+2].parseInt() - else: - raise newException(ValueError, "Sign for timezone " & value[j]) - j += 6 - of "ZZZ": - info.tzname = value[j..j+2].toUpper() - j += 3 + ## Helper of the parse proc to parse individual tokens. + var sv: int + case token + of "d": + var pd = parseInt(value[j..j+1], sv) + info.monthday = sv + j += pd + of "dd": + info.monthday = value[j..j+1].parseInt() + j += 2 + of "ddd": + case value[j..j+2].toLower(): + of "sun": + info.weekday = dSun + of "mon": + info.weekday = dMon + of "tue": + info.weekday = dTue + of "wed": + info.weekday = dWed + of "thu": + info.weekday = dThu + of "fri": + info.weekday = dFri + of "sat": + info.weekday = dSat else: - # Ignore the token and move forward in the value string by the same length - j += token.len + raise newException(ValueError, "invalid day of week ") + j += 3 + of "dddd": + if value.len >= j+6 and value[j..j+5].cmpIgnoreCase("sunday") == 0: + info.weekday = dSun + j += 6 + elif value.len >= j+6 and value[j..j+5].cmpIgnoreCase("monday") == 0: + info.weekday = dMon + j += 6 + elif value.len >= j+7 and value[j..j+6].cmpIgnoreCase("tuesday") == 0: + info.weekday = dTue + j += 7 + elif value.len >= j+9 and value[j..j+8].cmpIgnoreCase("wednesday") == 0: + info.weekday = dWed + j += 9 + elif value.len >= j+8 and value[j..j+7].cmpIgnoreCase("thursday") == 0: + info.weekday = dThu + j += 8 + elif value.len >= j+6 and value[j..j+5].cmpIgnoreCase("friday") == 0: + info.weekday = dFri + j += 6 + elif value.len >= j+8 and value[j..j+7].cmpIgnoreCase("saturday") == 0: + info.weekday = dSat + j += 8 + else: + raise newException(ValueError, "invalid day of week ") + of "h", "H": + var pd = parseInt(value[j..j+1], sv) + info.hour = sv + j += pd + of "hh", "HH": + info.hour = value[j..j+1].parseInt() + j += 2 + of "m": + var pd = parseInt(value[j..j+1], sv) + info.minute = sv + j += pd + of "mm": + info.minute = value[j..j+1].parseInt() + j += 2 + of "M": + var pd = parseInt(value[j..j+1], sv) + info.month = Month(sv-1) + info.monthday = sv + j += pd + of "MM": + var month = value[j..j+1].parseInt() + j += 2 + info.month = Month(month-1) + of "MMM": + case value[j..j+2].toLower(): + of "jan": + info.month = mJan + of "feb": + info.month = mFeb + of "mar": + info.month = mMar + of "apr": + info.month = mApr + of "may": + info.month = mMay + of "jun": + info.month = mJun + of "jul": + info.month = mJul + of "aug": + info.month = mAug + of "sep": + info.month = mSep + of "oct": + info.month = mOct + of "nov": + info.month = mNov + of "dec": + info.month = mDec + else: + raise newException(ValueError, "invalid month") + j += 3 + of "MMMM": + if value.len >= j+7 and value[j..j+6].cmpIgnoreCase("january") == 0: + info.month = mJan + j += 7 + elif value.len >= j+8 and value[j..j+7].cmpIgnoreCase("february") == 0: + info.month = mFeb + j += 8 + elif value.len >= j+5 and value[j..j+4].cmpIgnoreCase("march") == 0: + info.month = mMar + j += 5 + elif value.len >= j+5 and value[j..j+4].cmpIgnoreCase("april") == 0: + info.month = mApr + j += 5 + elif value.len >= j+3 and value[j..j+2].cmpIgnoreCase("may") == 0: + info.month = mMay + j += 3 + elif value.len >= j+4 and value[j..j+3].cmpIgnoreCase("june") == 0: + info.month = mJun + j += 4 + elif value.len >= j+4 and value[j..j+3].cmpIgnoreCase("july") == 0: + info.month = mJul + j += 4 + elif value.len >= j+6 and value[j..j+5].cmpIgnoreCase("august") == 0: + info.month = mAug + j += 6 + elif value.len >= j+9 and value[j..j+8].cmpIgnoreCase("september") == 0: + info.month = mSep + j += 9 + elif value.len >= j+7 and value[j..j+6].cmpIgnoreCase("october") == 0: + info.month = mOct + j += 7 + elif value.len >= j+8 and value[j..j+7].cmpIgnoreCase("november") == 0: + info.month = mNov + j += 8 + elif value.len >= j+8 and value[j..j+7].cmpIgnoreCase("december") == 0: + info.month = mDec + j += 8 + else: + raise newException(ValueError, "invalid month") + of "s": + var pd = parseInt(value[j..j+1], sv) + info.second = sv + j += pd + of "ss": + info.second = value[j..j+1].parseInt() + j += 2 + of "t": + if value[j] == 'P' and info.hour > 0 and info.hour < 12: + info.hour += 12 + j += 1 + of "tt": + if value[j..j+1] == "PM" and info.hour > 0 and info.hour < 12: + info.hour += 12 + j += 2 + of "yy": + # Assumes current century + var year = value[j..j+1].parseInt() + var thisCen = getLocalTime(getTime()).year div 100 + info.year = thisCen*100 + year + j += 2 + of "yyyy": + info.year = value[j..j+3].parseInt() + j += 4 + of "z": + if value[j] == '+': + info.timezone = parseInt($value[j+1]) + elif value[j] == '-': + info.timezone = 0-parseInt($value[j+1]) + else: + raise newException(ValueError, "Sign for timezone " & value[j]) + j += 2 + of "zz": + if value[j] == '+': + info.timezone = value[j+1..j+2].parseInt() + elif value[j] == '-': + info.timezone = 0-value[j+1..j+2].parseInt() + else: + raise newException(ValueError, "Sign for timezone " & value[j]) + j += 3 + of "zzz": + if value[j] == '+': + info.timezone = value[j+1..j+2].parseInt() + elif value[j] == '-': + info.timezone = 0-value[j+1..j+2].parseInt() + else: + raise newException(ValueError, "Sign for timezone " & value[j]) + j += 6 + of "ZZZ": + info.tzname = value[j..j+2].toUpper() + j += 3 + else: + # Ignore the token and move forward in the value string by the same length + j += token.len proc parse*(value, layout: string): TimeInfo = - ## This function parses a date/time string using the standard format identifiers (below) - ## The function defaults information not provided in the format string from the running program (timezone, month, year, etc) - ## - ## ========== ================================================================================= ================================================ - ## Specifier Description Example - ## ========== ================================================================================= ================================================ - ## d Numeric value of the day of the month, it will be one or two digits long. ``1/04/2012 -> 1``, ``21/04/2012 -> 21`` - ## dd Same as above, but always two digits. ``1/04/2012 -> 01``, ``21/04/2012 -> 21`` - ## ddd Three letter string which indicates the day of the week. ``Saturday -> Sat``, ``Monday -> Mon`` - ## dddd Full string for the day of the week. ``Saturday -> Saturday``, ``Monday -> Monday`` - ## h The hours in one digit if possible. Ranging from 0-12. ``5pm -> 5``, ``2am -> 2`` - ## hh The hours in two digits always. If the hour is one digit 0 is prepended. ``5pm -> 05``, ``11am -> 11`` - ## H The hours in one digit if possible, randing from 0-24. ``5pm -> 17``, ``2am -> 2`` - ## HH The hours in two digits always. 0 is prepended if the hour is one digit. ``5pm -> 17``, ``2am -> 02`` - ## m The minutes in 1 digit if possible. ``5:30 -> 30``, ``2:01 -> 1`` - ## mm Same as above but always 2 digits, 0 is prepended if the minute is one digit. ``5:30 -> 30``, ``2:01 -> 01`` - ## M The month in one digit if possible. ``September -> 9``, ``December -> 12`` - ## MM The month in two digits always. 0 is prepended. ``September -> 09``, ``December -> 12`` - ## MMM Abbreviated three-letter form of the month. ``September -> Sep``, ``December -> Dec`` - ## MMMM Full month string, properly capitalized. ``September -> September`` - ## s Seconds as one digit if possible. ``00:00:06 -> 6`` - ## ss Same as above but always two digits. 0 is prepended. ``00:00:06 -> 06`` - ## t ``A`` when time is in the AM. ``P`` when time is in the PM. - ## tt Same as above, but ``AM`` and ``PM`` instead of ``A`` and ``P`` respectively. - ## yy Displays the year to two digits. ``2012 -> 12`` - ## yyyy Displays the year to four digits. ``2012 -> 2012`` - ## z Displays the timezone offset from UTC. ``GMT+7 -> +7``, ``GMT-5 -> -5`` - ## zz Same as above but with leading 0. ``GMT+7 -> +07``, ``GMT-5 -> -05`` - ## zzz Same as above but with ``:00``. ``GMT+7 -> +07:00``, ``GMT-5 -> -05:00`` - ## ZZZ Displays the name of the timezone. ``GMT -> GMT``, ``EST -> EST`` - ## ========== ================================================================================= ================================================ - ## - ## Other strings can be inserted by putting them in ``''``. For example - ## ``hh'->'mm`` will give ``01->56``. The following characters can be - ## inserted without quoting them: ``:`` ``-`` ``(`` ``)`` ``/`` ``[`` ``]`` - ## ``,``. However you don't need to necessarily separate format specifiers, a - ## unambiguous format string like ``yyyyMMddhhmmss`` is valid too. - var i = 0 # pointer for format string - var j = 0 # pointer for value string - var token = "" - # Assumes current day of week, month and year, but time is reset to 00:00:00 - var info = getLocalTime(getTime()) - info.hour = 0 - info.minute = 0 - info.second = 0 - while true: - case layout[i] - of ' ', '-', '/', ':', '\'', '\0', '(', ')', '[', ']', ',': - if token.len > 0: - parseToken(info, token, value, j) - # Reset token - token = "" - # Break if at end of line - if layout[i] == '\0': break - # Skip separator and everything between single quotes - # These are literals in both the layout and the value string - if layout[i] == '\'': - inc(i) - inc(j) - while layout[i] != '\'' and layout.len-1 > i: - inc(i) - inc(j) - else: - inc(i) - inc(j) - else: - # Check if the letter being added matches previous accumulated buffer. - if token.len < 1 or token[high(token)] == layout[i]: - token.add(layout[i]) - inc(i) - else: - parseToken(info, token, value, j) - token = "" - return info + ## This function parses a date/time string using the standard format identifiers (below) + ## The function defaults information not provided in the format string from the running program (timezone, month, year, etc) + ## + ## ========== ================================================================================= ================================================ + ## Specifier Description Example + ## ========== ================================================================================= ================================================ + ## d Numeric value of the day of the month, it will be one or two digits long. ``1/04/2012 -> 1``, ``21/04/2012 -> 21`` + ## dd Same as above, but always two digits. ``1/04/2012 -> 01``, ``21/04/2012 -> 21`` + ## ddd Three letter string which indicates the day of the week. ``Saturday -> Sat``, ``Monday -> Mon`` + ## dddd Full string for the day of the week. ``Saturday -> Saturday``, ``Monday -> Monday`` + ## h The hours in one digit if possible. Ranging from 0-12. ``5pm -> 5``, ``2am -> 2`` + ## hh The hours in two digits always. If the hour is one digit 0 is prepended. ``5pm -> 05``, ``11am -> 11`` + ## H The hours in one digit if possible, randing from 0-24. ``5pm -> 17``, ``2am -> 2`` + ## HH The hours in two digits always. 0 is prepended if the hour is one digit. ``5pm -> 17``, ``2am -> 02`` + ## m The minutes in 1 digit if possible. ``5:30 -> 30``, ``2:01 -> 1`` + ## mm Same as above but always 2 digits, 0 is prepended if the minute is one digit. ``5:30 -> 30``, ``2:01 -> 01`` + ## M The month in one digit if possible. ``September -> 9``, ``December -> 12`` + ## MM The month in two digits always. 0 is prepended. ``September -> 09``, ``December -> 12`` + ## MMM Abbreviated three-letter form of the month. ``September -> Sep``, ``December -> Dec`` + ## MMMM Full month string, properly capitalized. ``September -> September`` + ## s Seconds as one digit if possible. ``00:00:06 -> 6`` + ## ss Same as above but always two digits. 0 is prepended. ``00:00:06 -> 06`` + ## t ``A`` when time is in the AM. ``P`` when time is in the PM. + ## tt Same as above, but ``AM`` and ``PM`` instead of ``A`` and ``P`` respectively. + ## yy Displays the year to two digits. ``2012 -> 12`` + ## yyyy Displays the year to four digits. ``2012 -> 2012`` + ## z Displays the timezone offset from UTC. ``GMT+7 -> +7``, ``GMT-5 -> -5`` + ## zz Same as above but with leading 0. ``GMT+7 -> +07``, ``GMT-5 -> -05`` + ## zzz Same as above but with ``:00``. ``GMT+7 -> +07:00``, ``GMT-5 -> -05:00`` + ## ZZZ Displays the name of the timezone. ``GMT -> GMT``, ``EST -> EST`` + ## ========== ================================================================================= ================================================ + ## + ## Other strings can be inserted by putting them in ``''``. For example + ## ``hh'->'mm`` will give ``01->56``. The following characters can be + ## inserted without quoting them: ``:`` ``-`` ``(`` ``)`` ``/`` ``[`` ``]`` + ## ``,``. However you don't need to necessarily separate format specifiers, a + ## unambiguous format string like ``yyyyMMddhhmmss`` is valid too. + var i = 0 # pointer for format string + var j = 0 # pointer for value string + var token = "" + # Assumes current day of month, month and year, but time is reset to 00:00:00. Weekday will be reset after parsing. + var info = getLocalTime(getTime()) + info.hour = 0 + info.minute = 0 + info.second = 0 + while true: + case layout[i] + of ' ', '-', '/', ':', '\'', '\0', '(', ')', '[', ']', ',': + if token.len > 0: + parseToken(info, token, value, j) + # Reset token + token = "" + # Break if at end of line + if layout[i] == '\0': break + # Skip separator and everything between single quotes + # These are literals in both the layout and the value string + if layout[i] == '\'': + inc(i) + inc(j) + while layout[i] != '\'' and layout.len-1 > i: + inc(i) + inc(j) + else: + inc(i) + inc(j) + else: + # Check if the letter being added matches previous accumulated buffer. + if token.len < 1 or token[high(token)] == layout[i]: + token.add(layout[i]) + inc(i) + else: + parseToken(info, token, value, j) + token = "" + # Reset weekday as it might not have been provided and the default may be wrong + info.weekday = getLocalTime(timeInfoToTime(info)).weekday + return info when isMainModule: @@ -1095,12 +1044,12 @@ when isMainModule: " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == "27 27 Mon Monday 4 04 16 16 6 06 1 01 Jan January 29 29 P PM 5 75 975 1975 01975 0 00 00:00 UTC" - when not defined(JS) and sizeof(Time) == 8: - var t3 = getGMTime(fromSeconds(889067643645)) # Fri 7 Jun 19:20:45 BST 30143 - assert t3.format("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & - " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == - "7 07 Fri Friday 6 06 18 18 20 20 6 06 Jun June 45 45 P PM 3 43 143 0143 30143 0 00 00:00 UTC" - assert t3.format(":,[]()-/") == ":,[]()-/" + # when not defined(JS) and sizeof(Time) == 8: + # var t3 = getGMTime(fromSeconds(889067643645)) # Fri 7 Jun 19:20:45 BST 30143 + # assert t3.format("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & + # " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == + # "7 07 Fri Friday 6 06 18 18 20 20 6 06 Jun June 45 45 P PM 3 43 143 0143 30143 0 00 00:00 UTC" + # assert t3.format(":,[]()-/") == ":,[]()-/" var t4 = getGMTime(fromSeconds(876124714)) # Mon 6 Oct 08:58:34 BST 1997 assert t4.format("M MM MMM MMMM") == "10 10 Oct October" @@ -1109,9 +1058,9 @@ when isMainModule: assert((t4 - initInterval(years = 2)).format("yyyy") == "1995") assert((t4 - initInterval(years = 7, minutes = 34, seconds = 24)).format("yyyy mm ss") == "1990 24 10") - var s = "09:04am on Dec 15, 2015" - var f = "hh:mmtt on MMM d, yyyy" - assert($s.parse(f) == "Mon Dec 15 09:04:00 2015") + var s = "Tuesday at 09:04am on Dec 15, 2015" + var f = "dddd at hh:mmtt on MMM d, yyyy" + assert($s.parse(f) == "Tue Dec 15 09:04:00 2015") # ANSIC = "Mon Jan _2 15:04:05 2006" s = "Mon Jan 2 15:04:05 2006" f = "ddd MMM d HH:mm:ss yyyy" From 7251fbd76eac33c2fff76051c911380ed37b3a6f Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 11 Feb 2015 15:52:15 +0900 Subject: [PATCH 301/850] Date/time parsing - removed comments from assert --- lib/pure/times.nim | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 70bf7073d5..e85d13e6dc 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -1044,12 +1044,12 @@ when isMainModule: " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == "27 27 Mon Monday 4 04 16 16 6 06 1 01 Jan January 29 29 P PM 5 75 975 1975 01975 0 00 00:00 UTC" - # when not defined(JS) and sizeof(Time) == 8: - # var t3 = getGMTime(fromSeconds(889067643645)) # Fri 7 Jun 19:20:45 BST 30143 - # assert t3.format("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & - # " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == - # "7 07 Fri Friday 6 06 18 18 20 20 6 06 Jun June 45 45 P PM 3 43 143 0143 30143 0 00 00:00 UTC" - # assert t3.format(":,[]()-/") == ":,[]()-/" + when not defined(JS) and sizeof(Time) == 8: + var t3 = getGMTime(fromSeconds(889067643645)) # Fri 7 Jun 19:20:45 BST 30143 + assert t3.format("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & + " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == + "7 07 Fri Friday 6 06 18 18 20 20 6 06 Jun June 45 45 P PM 3 43 143 0143 30143 0 00 00:00 UTC" + assert t3.format(":,[]()-/") == ":,[]()-/" var t4 = getGMTime(fromSeconds(876124714)) # Mon 6 Oct 08:58:34 BST 1997 assert t4.format("M MM MMM MMMM") == "10 10 Oct October" From 743ad639d48082c58685929c68b1463332552e7a Mon Sep 17 00:00:00 2001 From: Hans Raaf Date: Wed, 11 Feb 2015 20:54:34 +0100 Subject: [PATCH 302/850] Fixing dylib name for OSX I don't know if the (15|16...) is supposed to work on OSX. I have "libmysqlclient.18.dylib" in my lib directory and get "could not load: libmysqlclient.(15|16|17[18).dylib" on execution. After removing the pattern I can run my little example program and it works as "libmysqlclient.dylib" is a softlink to the current version anyway. --- lib/wrappers/mysql.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/wrappers/mysql.nim b/lib/wrappers/mysql.nim index 9161f56722..3857744ae1 100644 --- a/lib/wrappers/mysql.nim +++ b/lib/wrappers/mysql.nim @@ -13,7 +13,7 @@ when defined(Unix): when defined(macosx): const - lib = "libmysqlclient.(15|16|17[18).dylib" + lib = "libmysqlclient.(15|16|17|18).dylib" else: const lib = "libmysqlclient.so.(15|16|17|18)" From ceffdebebb4c81a716908f60749aee26e2b1f232 Mon Sep 17 00:00:00 2001 From: Hans Raaf Date: Wed, 11 Feb 2015 21:03:24 +0100 Subject: [PATCH 303/850] Corrected warnings about deprecated names I got warning about deprecated names here. I also know that other names probably need to change (T/P prefixes) but I am unsure about the exact rules. I may do that later if you like. --- lib/impure/db_mysql.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/impure/db_mysql.nim b/lib/impure/db_mysql.nim index 968a2923ad..dab84c2d50 100644 --- a/lib/impure/db_mysql.nim +++ b/lib/impure/db_mysql.nim @@ -16,11 +16,11 @@ type TDbConn* = PMySQL ## encapsulates a database connection TRow* = seq[string] ## a row of a dataset. NULL database values will be ## transformed always to the empty string. - EDb* = object of EIO ## exception that is raised if a database error occurs + EDb* = object of IOError ## exception that is raised if a database error occurs TSqlQuery* = distinct string ## an SQL query string - FDb* = object of FIO ## effect that denotes a database operation + FDb* = object of IOEffect ## effect that denotes a database operation FReadDb* = object of FDb ## effect that denotes a read operation FWriteDb* = object of FDb ## effect that denotes a write operation From 5fbcf93860e68d7ddde4b01aa4b7222a7fcaaabc Mon Sep 17 00:00:00 2001 From: Charles Blake Date: Thu, 12 Feb 2015 05:22:04 -0500 Subject: [PATCH 304/850] Add hcode,rightSize,rawGetKnownHC. Fix inf loop. Make similar changes to those made in sets.nim, including hcode, rightSize rawGet/rawGetKnownHC result protocol, nextTry probe sequence to be the cache friendlier h=h+1 which in turn allows supporting changing deletion to fix the infinite loop bug with local rehashing which in turn has desirable properties of graceful table aging when deletes do happen and also making insert-only usage patterns no longer pay any time/space cost to check deleted status. Unlike collections.sets, this module has add() for duplicate key inserts and a 3rd type of table, CountTable. The first wrinkle is handled by introducing a rawGetDeep for unconditionally adding entries along collision chains. This point of CountTable seems to be space efficiency at 2 items per slot. These changes retain that by keeping the val==0 => EMPTY rule and not caching hash codes. putImpl is expanded in-place for CountTable since the new putImpl() is too different. { Depending on table size relative to caches & key expense, regular Table[A,B] may become faster than CountTable, especially if the basic count update could be something like inc(mGetOrPut(t, key, 0)). } Unit tests pass, but in this module those are much more of just a demo than probing for bugs. Should exercise/test this a little more before merging. --- lib/pure/collections/tables.nim | 204 ++++++++++++++++++++++---------- 1 file changed, 142 insertions(+), 62 deletions(-) diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index 9dcc971481..da9d210506 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -71,8 +71,7 @@ import {.pragma: myShallow.} type - SlotEnum = enum seEmpty, seFilled, seDeleted - KeyValuePair[A, B] = tuple[slot: SlotEnum, key: A, val: B] + KeyValuePair[A, B] = tuple[hcode: THash, key: A, val: B] KeyValuePairSeq[A, B] = seq[KeyValuePair[A, B]] Table* {.myShallow.}[A, B] = object ## generic hash table data: KeyValuePairSeq[A, B] @@ -84,6 +83,14 @@ type when not defined(nimhygiene): {.pragma: dirty.} +# hcode for real keys cannot be zero. hcode==0 signifies an empty slot. These +# two procs retain clarity of that encoding without the space cost of an enum. +proc isEmpty(hcode: THash): bool {.inline.} = + result = hcode == 0 + +proc isFilled(hcode: THash): bool {.inline.} = + result = hcode != 0 + proc len*[A, B](t: Table[A, B]): int = ## returns the number of keys in `t`. result = t.counter @@ -91,28 +98,28 @@ proc len*[A, B](t: Table[A, B]): int = iterator pairs*[A, B](t: Table[A, B]): tuple[key: A, val: B] = ## iterates over any (key, value) pair in the table `t`. for h in 0..high(t.data): - if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) + if isFilled(t.data[h].hcode): yield (t.data[h].key, t.data[h].val) iterator mpairs*[A, B](t: var Table[A, B]): tuple[key: A, val: var B] = ## iterates over any (key, value) pair in the table `t`. The values ## can be modified. for h in 0..high(t.data): - if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) + if isFilled(t.data[h].slot): yield (t.data[h].key, t.data[h].val) iterator keys*[A, B](t: Table[A, B]): A = ## iterates over any key in the table `t`. for h in 0..high(t.data): - if t.data[h].slot == seFilled: yield t.data[h].key + if isFilled(t.data[h].hcode): yield t.data[h].key iterator values*[A, B](t: Table[A, B]): B = ## iterates over any value in the table `t`. for h in 0..high(t.data): - if t.data[h].slot == seFilled: yield t.data[h].val + if isFilled(t.data[h].hcode): yield t.data[h].val iterator mvalues*[A, B](t: var Table[A, B]): var B = ## iterates over any value in the table `t`. The values can be modified. for h in 0..high(t.data): - if t.data[h].slot == seFilled: yield t.data[h].val + if isFilled(t.data[h].hcode): yield t.data[h].val const growthFactor = 2 @@ -121,26 +128,57 @@ proc mustRehash(length, counter: int): bool {.inline.} = assert(length > counter) result = (length * 2 < counter * 3) or (length - counter < 4) -proc nextTry(h, maxHash: THash): THash {.inline.} = - result = ((5 * h) + 1) and maxHash +proc rightSize*(count: int): int {.inline.} = + ## Return the value of `initialSize` to support `count` items. + ## + ## If more items are expected to be added, simply add that + ## expected extra amount to the parameter before calling this. + ## + ## Internally, we want mustRehash(rightSize(x), x) == false. + result = nextPowerOfTwo(count * 3 div 2 + 4) -template rawGetImpl() {.dirty.} = - var h: THash = hash(key) and high(t.data) # start with real hash value - while t.data[h].slot != seEmpty: - if t.data[h].key == key and t.data[h].slot == seFilled: +proc nextTry(h, maxHash: THash): THash {.inline.} = + result = (h + 1) and maxHash + +template rawGetKnownHCImpl() {.dirty.} = + var h: THash = hc and high(t.data) # start with real hash value + while isFilled(t.data[h].hcode): + # Compare hc THEN key with boolean short circuit. This makes the common case + # zero ==key's for missing (e.g.inserts) and exactly one ==key for present. + # It does slow down succeeding lookups by one extra THash cmp&and..usually + # just a few clock cycles, generally worth it for any non-integer-like A. + if t.data[h].hcode == hc and t.data[h].key == key: return h h = nextTry(h, high(t.data)) - result = -1 + result = -1 - h # < 0 => MISSING; insert idx = -1 - result + +template rawGetImpl() {.dirty.} = + hc = hash(key) + if hc == 0: # This almost never taken branch should be very predictable. + hc = 314159265 # Value doesn't matter; Any non-zero favorite is fine. + rawGetKnownHCImpl() + +template rawGetDeepImpl() {.dirty.} = # Search algo for unconditional add + hc = hash(key) + if hc == 0: + hc = 314159265 + var h: THash = hc and high(t.data) + while isFilled(t.data[h].hcode): + h = nextTry(h, high(t.data)) + result = h template rawInsertImpl() {.dirty.} = - var h: THash = hash(key) and high(data) - while data[h].slot == seFilled: - h = nextTry(h, high(data)) data[h].key = key data[h].val = val - data[h].slot = seFilled + data[h].hcode = hc -proc rawGet[A, B](t: Table[A, B], key: A): int = +proc rawGetKnownHC[A, B](t: Table[A, B], key: A, hc: THash): int {.inline.} = + rawGetKnownHCImpl() + +proc rawGetDeep[A, B](t: Table[A, B], key: A, hc: var THash): int {.inline.} = + rawGetDeepImpl() + +proc rawGet[A, B](t: Table[A, B], key: A, hc: var THash): int {.inline.} = rawGetImpl() proc `[]`*[A, B](t: Table[A, B], key: A): B = @@ -148,50 +186,62 @@ proc `[]`*[A, B](t: Table[A, B], key: A): B = ## default empty value for the type `B` is returned ## and no exception is raised. One can check with ``hasKey`` whether the key ## exists. - var index = rawGet(t, key) + var hc: THash + var index = rawGet(t, key, hc) if index >= 0: result = t.data[index].val proc mget*[A, B](t: var Table[A, B], key: A): var B = ## retrieves the value at ``t[key]``. The value can be modified. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. - var index = rawGet(t, key) + var hc: THash + var index = rawGet(t, key, hc) if index >= 0: result = t.data[index].val else: raise newException(KeyError, "key not found: " & $key) iterator allValues*[A, B](t: Table[A, B]; key: A): B = ## iterates over any value in the table `t` that belongs to the given `key`. var h: THash = hash(key) and high(t.data) - while t.data[h].slot != seEmpty: - if t.data[h].key == key and t.data[h].slot == seFilled: + while isFilled(t.data[h].hcode): + if t.data[h].key == key: yield t.data[h].val h = nextTry(h, high(t.data)) proc hasKey*[A, B](t: Table[A, B], key: A): bool = ## returns true iff `key` is in the table `t`. - result = rawGet(t, key) >= 0 + var hc: THash + result = rawGet(t, key, hc) >= 0 proc rawInsert[A, B](t: var Table[A, B], data: var KeyValuePairSeq[A, B], - key: A, val: B) = + key: A, val: B, hc: THash, h: THash) = rawInsertImpl() proc enlarge[A, B](t: var Table[A, B]) = var n: KeyValuePairSeq[A, B] newSeq(n, len(t.data) * growthFactor) - for i in countup(0, high(t.data)): - if t.data[i].slot == seFilled: rawInsert(t, n, t.data[i].key, t.data[i].val) swap(t.data, n) + for i in countup(0, high(n)): + if isFilled(n[i].hcode): + var j = -1 - rawGetKnownHC(t, n[i].key, n[i].hcode) + rawInsert(t, t.data, n[i].key, n[i].val, n[i].hcode, j) template addImpl() {.dirty.} = if mustRehash(len(t.data), t.counter): enlarge(t) - rawInsert(t, t.data, key, val) + var hc: THash + var j = rawGetDeep(t, key, hc) + rawInsert(t, t.data, key, val, hc, j) inc(t.counter) template putImpl() {.dirty.} = - var index = rawGet(t, key) + var hc: THash + var index = rawGet(t, key, hc) if index >= 0: t.data[index].val = val else: - addImpl() + if mustRehash(len(t.data), t.counter): + enlarge(t) + index = rawGetKnownHC(t, key, hc) + rawInsert(t, t.data, key, val, hc, -1 - index) + inc(t.counter) when false: # not yet used: @@ -213,13 +263,30 @@ proc `[]=`*[A, B](t: var Table[A, B], key: A, val: B) = proc add*[A, B](t: var Table[A, B], key: A, val: B) = ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. addImpl() - + +template doWhile(a: expr, b: stmt): stmt = + while true: + b + if not a: break + proc del*[A, B](t: var Table[A, B], key: A) = ## deletes `key` from hash table `t`. - let index = rawGet(t, key) - if index >= 0: - t.data[index].slot = seDeleted + var hc: THash + var i = rawGet(t, key, hc) + let msk = high(t.data) + if i >= 0: + t.data[i].hcode = 0 dec(t.counter) + while true: # KnuthV3 Algo6.4R adapted for i=i+1 instead of i=i-1 + var j = i # The correctness of this depends on (h+1) in nextTry, + var r = j # though may be adaptable to other simple sequences. + t.data[i].hcode = 0 # mark current EMPTY + doWhile ((i >= r and r > j) or (r > j and j > i) or (j > i and i >= r)): + i = (i + 1) and msk # increment mod table size + if isEmpty(t.data[i].hcode): # end of collision cluster; So all done + return + r = t.data[i].hcode and msk # "home" location of key@i + t.data[j] = t.data[i] # data[j] will be marked EMPTY next loop proc initTable*[A, B](initialSize=64): Table[A, B] = ## creates a new hash table that is empty. @@ -234,7 +301,7 @@ proc initTable*[A, B](initialSize=64): Table[A, B] = proc toTable*[A, B](pairs: openArray[tuple[key: A, val: B]]): Table[A, B] = ## creates a new hash table that contains the given `pairs`. - result = initTable[A, B](nextPowerOfTwo(pairs.len+10)) + result = initTable[A, B](rightSize(pairs.len)) for key, val in items(pairs): result[key] = val template dollarImpl(): stmt {.dirty.} = @@ -252,7 +319,7 @@ template dollarImpl(): stmt {.dirty.} = proc `$`*[A, B](t: Table[A, B]): string = ## The `$` operator for hash tables. dollarImpl() - + template equalsImpl() = if s.counter == t.counter: # different insertion orders mean different 'data' seqs, so we have @@ -262,10 +329,10 @@ template equalsImpl() = if not t.hasKey(key): return false if t[key] != val: return false return true - + proc `==`*[A, B](s, t: Table[A, B]): bool = equalsImpl() - + proc indexBy*[A, B, C](collection: A, index: proc(x: B): C): Table[C, B] = ## Index the collection with the proc provided. # TODO: As soon as supported, change collection: A to collection: A[B] @@ -280,28 +347,28 @@ proc len*[A, B](t: TableRef[A, B]): int = iterator pairs*[A, B](t: TableRef[A, B]): tuple[key: A, val: B] = ## iterates over any (key, value) pair in the table `t`. for h in 0..high(t.data): - if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) + if isFilled(t.data[h].hcode): yield (t.data[h].key, t.data[h].val) iterator mpairs*[A, B](t: TableRef[A, B]): tuple[key: A, val: var B] = ## iterates over any (key, value) pair in the table `t`. The values ## can be modified. for h in 0..high(t.data): - if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) + if isFilled(t.data[h].hcode): yield (t.data[h].key, t.data[h].val) iterator keys*[A, B](t: TableRef[A, B]): A = ## iterates over any key in the table `t`. for h in 0..high(t.data): - if t.data[h].slot == seFilled: yield t.data[h].key + if isFilled(t.data[h].hcode): yield t.data[h].key iterator values*[A, B](t: TableRef[A, B]): B = ## iterates over any value in the table `t`. for h in 0..high(t.data): - if t.data[h].slot == seFilled: yield t.data[h].val + if isFilled(t.data[h].hcode): yield t.data[h].val iterator mvalues*[A, B](t: TableRef[A, B]): var B = ## iterates over any value in the table `t`. The values can be modified. for h in 0..high(t.data): - if t.data[h].slot == seFilled: yield t.data[h].val + if isFilled(t.data[h].hcode): yield t.data[h].val proc `[]`*[A, B](t: TableRef[A, B], key: A): B = ## retrieves the value at ``t[key]``. If `key` is not in `t`, @@ -326,7 +393,7 @@ proc `[]=`*[A, B](t: TableRef[A, B], key: A, val: B) = proc add*[A, B](t: TableRef[A, B], key: A, val: B) = ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. t[].add(key, val) - + proc del*[A, B](t: TableRef[A, B], key: A) = ## deletes `key` from hash table `t`. t[].del(key) @@ -360,7 +427,7 @@ proc newTableFrom*[A, B, C](collection: A, index: proc(x: B): C): TableRef[C, B] type OrderedKeyValuePair[A, B] = tuple[ - slot: SlotEnum, next: int, key: A, val: B] + hcode: THash, next: int, key: A, val: B] OrderedKeyValuePairSeq[A, B] = seq[OrderedKeyValuePair[A, B]] OrderedTable* {. myShallow.}[A, B] = object ## table that remembers insertion order @@ -378,7 +445,7 @@ template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} = var h = t.first while h >= 0: var nxt = t.data[h].next - if t.data[h].slot == seFilled: yieldStmt + if isFilled(t.data[h].hcode): yieldStmt h = nxt iterator pairs*[A, B](t: OrderedTable[A, B]): tuple[key: A, val: B] = @@ -409,7 +476,13 @@ iterator mvalues*[A, B](t: var OrderedTable[A, B]): var B = forAllOrderedPairs: yield t.data[h].val -proc rawGet[A, B](t: OrderedTable[A, B], key: A): int = +proc rawGetKnownHC[A, B](t: OrderedTable[A, B], key: A, hc: THash): int = + rawGetKnownHCImpl() + +proc rawGetDeep[A, B](t: OrderedTable[A, B], key: A, hc: var THash): int {.inline.} = + rawGetDeepImpl() + +proc rawGet[A, B](t: OrderedTable[A, B], key: A, hc: var THash): int = rawGetImpl() proc `[]`*[A, B](t: OrderedTable[A, B], key: A): B = @@ -433,7 +506,7 @@ proc hasKey*[A, B](t: OrderedTable[A, B], key: A): bool = proc rawInsert[A, B](t: var OrderedTable[A, B], data: var OrderedKeyValuePairSeq[A, B], - key: A, val: B) = + key: A, val: B, hc: THash, h: THash) = rawInsertImpl() data[h].next = -1 if t.first < 0: t.first = h @@ -446,12 +519,13 @@ proc enlarge[A, B](t: var OrderedTable[A, B]) = var h = t.first t.first = -1 t.last = -1 - while h >= 0: - var nxt = t.data[h].next - if t.data[h].slot == seFilled: - rawInsert(t, n, t.data[h].key, t.data[h].val) - h = nxt swap(t.data, n) + while h >= 0: + var nxt = n[h].next + if isFilled(n[h].hcode): + var j = -1 - rawGetKnownHC(t, n[h].key, n[h].hcode) + rawInsert(t, t.data, n[h].key, n[h].val, n[h].hcode, j) + h = nxt proc `[]=`*[A, B](t: var OrderedTable[A, B], key: A, val: B) = ## puts a (key, value)-pair into `t`. @@ -476,7 +550,7 @@ proc initOrderedTable*[A, B](initialSize=64): OrderedTable[A, B] = proc toOrderedTable*[A, B](pairs: openArray[tuple[key: A, val: B]]): OrderedTable[A, B] = ## creates a new ordered hash table that contains the given `pairs`. - result = initOrderedTable[A, B](nextPowerOfTwo(pairs.len+10)) + result = initOrderedTable[A, B](rightSize(pairs.len)) for key, val in items(pairs): result[key] = val proc `$`*[A, B](t: OrderedTable[A, B]): string = @@ -537,7 +611,7 @@ template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} = var h = t.first while h >= 0: var nxt = t.data[h].next - if t.data[h].slot == seFilled: yieldStmt + if isFilled(t.data[h].hcode): yieldStmt h = nxt iterator pairs*[A, B](t: OrderedTableRef[A, B]): tuple[key: A, val: B] = @@ -604,7 +678,7 @@ proc newOrderedTable*[A, B](initialSize=64): OrderedTableRef[A, B] = proc newOrderedTable*[A, B](pairs: openArray[tuple[key: A, val: B]]): OrderedTableRef[A, B] = ## creates a new ordered hash table that contains the given `pairs`. - result = newOrderedTable[A, B](nextPowerOfTwo(pairs.len+10)) + result = newOrderedTable[A, B](rightSize(pairs.len)) for key, val in items(pairs): result[key] = val proc `$`*[A, B](t: OrderedTableRef[A, B]): string = @@ -665,7 +739,7 @@ proc rawGet[A](t: CountTable[A], key: A): int = while t.data[h].val != 0: if t.data[h].key == key: return h h = nextTry(h, high(t.data)) - result = -1 + result = -1 - h # < 0 => MISSING; insert idx = -1 - result proc `[]`*[A](t: CountTable[A], key: A): int = ## retrieves the value at ``t[key]``. If `key` is not in `t`, @@ -702,21 +776,27 @@ proc enlarge[A](t: var CountTable[A]) = proc `[]=`*[A](t: var CountTable[A], key: A, val: int) = ## puts a (key, value)-pair into `t`. `val` has to be positive. assert val > 0 - putImpl() + var h = rawGet(t, key) + if h >= 0: + t.data[h].val = val + else: + h = -1 - h + t.data[h].key = key + t.data[h].val = val proc initCountTable*[A](initialSize=64): CountTable[A] = ## creates a new count table that is empty. ## ## `initialSize` needs to be a power of two. If you need to accept runtime ## values for this you could use the ``nextPowerOfTwo`` proc from the - ## `math `_ module. + ## `math `_ module or the ``rightSize`` method in this module. assert isPowerOfTwo(initialSize) result.counter = 0 newSeq(result.data, initialSize) proc toCountTable*[A](keys: openArray[A]): CountTable[A] = ## creates a new count table with every key in `keys` having a count of 1. - result = initCountTable[A](nextPowerOfTwo(keys.len+10)) + result = initCountTable[A](rightSize(keys.len)) for key in items(keys): result[key] = 1 proc `$`*[A](t: CountTable[A]): string = @@ -827,13 +907,13 @@ proc newCountTable*[A](initialSize=64): CountTableRef[A] = ## ## `initialSize` needs to be a power of two. If you need to accept runtime ## values for this you could use the ``nextPowerOfTwo`` proc from the - ## `math `_ module. + ## `math `_ module or the ``rightSize`` method in this module. new(result) result[] = initCountTable[A](initialSize) proc newCountTable*[A](keys: openArray[A]): CountTableRef[A] = ## creates a new count table with every key in `keys` having a count of 1. - result = newCountTable[A](nextPowerOfTwo(keys.len+10)) + result = newCountTable[A](rightSize(keys.len)) for key in items(keys): result[key] = 1 proc `$`*[A](t: CountTableRef[A]): string = From 49d88cee68269bf6ed5373777bb76df5c18af495 Mon Sep 17 00:00:00 2001 From: Charles Blake Date: Thu, 12 Feb 2015 06:44:09 -0500 Subject: [PATCH 305/850] Oops - missed updates to a few later rawGet()s. --- lib/pure/collections/tables.nim | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index da9d210506..4858ca2b5a 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -246,7 +246,8 @@ template putImpl() {.dirty.} = when false: # not yet used: template hasKeyOrPutImpl() {.dirty.} = - var index = rawGet(t, key) + var hc: THash + var index = rawGet(t, key, hc) if index >= 0: t.data[index].val = val result = true @@ -490,19 +491,22 @@ proc `[]`*[A, B](t: OrderedTable[A, B], key: A): B = ## default empty value for the type `B` is returned ## and no exception is raised. One can check with ``hasKey`` whether the key ## exists. - var index = rawGet(t, key) + var hc: THash + var index = rawGet(t, key, hc) if index >= 0: result = t.data[index].val proc mget*[A, B](t: var OrderedTable[A, B], key: A): var B = ## retrieves the value at ``t[key]``. The value can be modified. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. - var index = rawGet(t, key) + var hc: THash + var index = rawGet(t, key, hc) if index >= 0: result = t.data[index].val else: raise newException(KeyError, "key not found: " & $key) proc hasKey*[A, B](t: OrderedTable[A, B], key: A): bool = ## returns true iff `key` is in the table `t`. - result = rawGet(t, key) >= 0 + var hc: THash + result = rawGet(t, key, hc) >= 0 proc rawInsert[A, B](t: var OrderedTable[A, B], data: var OrderedKeyValuePairSeq[A, B], From fcfaf2a844432a6bd01147ff58ac7197a00999cb Mon Sep 17 00:00:00 2001 From: Frank Fischer Date: Thu, 12 Feb 2015 12:47:58 +0100 Subject: [PATCH 306/850] fix conditions for int size in 'math.nextPowerOfTwo' #2110 --- lib/pure/math.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pure/math.nim b/lib/pure/math.nim index b9e057e781..62ea1f7560 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -93,9 +93,9 @@ proc nextPowerOfTwo*(x: int): int {.noSideEffect.} = result = x - 1 when defined(cpu64): result = result or (result shr 32) - when sizeof(int) > 16: + when sizeof(int) > 2: result = result or (result shr 16) - when sizeof(int) > 8: + when sizeof(int) > 1: result = result or (result shr 8) result = result or (result shr 4) result = result or (result shr 2) From a21d7c681d9f61f15beddb97fabba0ed6b72640d Mon Sep 17 00:00:00 2001 From: Charles Blake Date: Thu, 12 Feb 2015 06:57:39 -0500 Subject: [PATCH 307/850] New probe seq yields a non-bug swap of 1st 2 keys. --- tests/table/ttables.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/table/ttables.nim b/tests/table/ttables.nim index de4aaed5eb..8534e6767d 100644 --- a/tests/table/ttables.nim +++ b/tests/table/ttables.nim @@ -47,7 +47,7 @@ block tableTest1: for y in 0..1: assert t[(x,y)] == $x & $y assert($t == - "{(x: 0, y: 0): 00, (x: 0, y: 1): 01, (x: 1, y: 0): 10, (x: 1, y: 1): 11}") + "{(x: 0, y: 1): 01, (x: 0, y: 0): 00, (x: 1, y: 0): 10, (x: 1, y: 1): 11}") block tableTest2: var t = initTable[string, float]() From 6e8b2bbfc8549d97397c754981ae0510b7d8ddfd Mon Sep 17 00:00:00 2001 From: Hans Raaf Date: Thu, 12 Feb 2015 13:07:06 +0100 Subject: [PATCH 308/850] Set executable bit on build.sh. I am not sure why this is not set already? To me it is an annoyance that I have to set it manually and then git shows me a change for that file all the time while working. --- build.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 build.sh diff --git a/build.sh b/build.sh old mode 100644 new mode 100755 From 10335fd7264560e9b5a6ca4b2b5fe8e28e78209b Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 11 Feb 2015 17:42:28 +0100 Subject: [PATCH 309/850] fixed minor bugs; cleaned up tests --- compiler/sempass2.nim | 3 +- lib/core/macros.nim | 20 +- lib/pure/collections/tables.nim | 2 +- lib/pure/math.nim | 8 +- lib/pure/net.nim | 9 +- lib/pure/os.nim | 6 +- lib/pure/times.nim | 102 ++-- lib/system.nim | 38 +- lib/system/repr.nim | 6 +- tests/collections/tindexby.nim | 22 + tests/{table => collections}/ttableconstr.nim | 0 tests/collections/ttables.nim | 142 +++++- tests/{table => collections}/ttables2.nim | 0 .../ttablesref.nim} | 2 +- .../ttablesref2.nim} | 0 tests/stdlib/tircbot.nim | 453 ------------------ tests/stdlib/tmitems.nim | 2 +- tests/table/ttables.nim | 128 ----- todo.txt | 1 - 19 files changed, 243 insertions(+), 701 deletions(-) create mode 100644 tests/collections/tindexby.nim rename tests/{table => collections}/ttableconstr.nim (100%) rename tests/{table => collections}/ttables2.nim (100%) rename tests/{table/ptables.nim => collections/ttablesref.nim} (99%) rename tests/{table/ptables2.nim => collections/ttablesref2.nim} (100%) delete mode 100644 tests/stdlib/tircbot.nim delete mode 100644 tests/table/ttables.nim diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index ede556a707..6fa7c756e1 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -859,7 +859,8 @@ proc trackProc*(s: PSym, body: PNode) = if s.typ.lockLevel == UnspecifiedLockLevel: s.typ.lockLevel = t.maxLockLevel elif t.maxLockLevel > s.typ.lockLevel: - localError(s.info, + #localError(s.info, + message(s.info, warnLockLevel, "declared lock level is $1, but real lock level is $2" % [$s.typ.lockLevel, $t.maxLockLevel]) diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 22b9c49073..4c561df703 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -136,12 +136,12 @@ proc len*(n: PNimrodNode): int {.magic: "NLen", noSideEffect.} ## returns the number of children of `n`. proc add*(father, child: PNimrodNode): PNimrodNode {.magic: "NAdd", discardable, - noSideEffect.} + noSideEffect, locks: 0.} ## Adds the `child` to the `father` node. Returns the ## father node so that calls can be nested. proc add*(father: PNimrodNode, children: varargs[PNimrodNode]): PNimrodNode {. - magic: "NAddMultiple", discardable, noSideEffect.} + magic: "NAddMultiple", discardable, noSideEffect, locks: 0.} ## Adds each child of `children` to the `father` node. ## Returns the `father` node so that calls can be nested. @@ -177,13 +177,13 @@ proc newNimNode*(kind: TNimrodNodeKind, proc copyNimNode*(n: PNimrodNode): PNimrodNode {.magic: "NCopyNimNode", noSideEffect.} proc copyNimTree*(n: PNimrodNode): PNimrodNode {.magic: "NCopyNimTree", noSideEffect.} -proc error*(msg: string) {.magic: "NError", gcsafe.} +proc error*(msg: string) {.magic: "NError", benign.} ## writes an error message at compile time -proc warning*(msg: string) {.magic: "NWarning", gcsafe.} +proc warning*(msg: string) {.magic: "NWarning", benign.} ## writes a warning message at compile time -proc hint*(msg: string) {.magic: "NHint", gcsafe.} +proc hint*(msg: string) {.magic: "NHint", benign.} ## writes a hint message at compile time proc newStrLitNode*(s: string): PNimrodNode {.compileTime, noSideEffect.} = @@ -237,7 +237,7 @@ proc genSym*(kind: TNimrodSymKind = nskLet; ident = ""): PNimrodNode {. ## generates a fresh symbol that is guaranteed to be unique. The symbol ## needs to occur in a declaration context. -proc callsite*(): PNimrodNode {.magic: "NCallSite", gcsafe.} +proc callsite*(): PNimrodNode {.magic: "NCallSite", benign.} ## returns the AST of the invocation expression that invoked this macro. proc toStrLit*(n: PNimrodNode): PNimrodNode {.compileTime.} = @@ -387,11 +387,11 @@ proc nestList*(theProc: TNimrodIdent, # This could easily user code and so should be fixed in evals.nim somehow. result = newCall(theProc, x[i], copyNimTree(result)) -proc treeRepr*(n: PNimrodNode): string {.compileTime.} = +proc treeRepr*(n: PNimrodNode): string {.compileTime, benign.} = ## Convert the AST `n` to a human-readable tree-like string. ## ## See also `repr` and `lispRepr`. - proc traverse(res: var string, level: int, n: PNimrodNode) = + proc traverse(res: var string, level: int, n: PNimrodNode) {.benign.} = for i in 0..level-1: res.add " " res.add(($n.kind).substr(3)) @@ -412,7 +412,7 @@ proc treeRepr*(n: PNimrodNode): string {.compileTime.} = result = "" traverse(result, 0, n) -proc lispRepr*(n: PNimrodNode): string {.compileTime.} = +proc lispRepr*(n: PNimrodNode): string {.compileTime, benign.} = ## Convert the AST `n` to a human-readable lisp-like string, ## ## See also `repr` and `treeRepr`. @@ -651,7 +651,7 @@ proc `body=`*(someProc: PNimrodNode, val: PNimrodNode) {.compileTime.} = else: badNodeKind someProc.kind, "body=" -proc basename*(a: PNimrodNode): PNimrodNode {.compiletime.} +proc basename*(a: PNimrodNode): PNimrodNode {.compiletime, benign.} proc `$`*(node: PNimrodNode): string {.compileTime.} = diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index 9dcc971481..671f767cfe 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -347,7 +347,7 @@ proc `$`*[A, B](t: TableRef[A, B]): string = proc `==`*[A, B](s, t: TableRef[A, B]): bool = if isNil(s): result = isNil(t) elif isNil(t): result = false - else: result = equalsImpl() + else: equalsImpl() proc newTableFrom*[A, B, C](collection: A, index: proc(x: B): C): TableRef[C, B] = ## Index the collection with the proc provided. diff --git a/lib/pure/math.nim b/lib/pure/math.nim index b9e057e781..1690377fff 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -129,25 +129,25 @@ proc variance*(x: openArray[float]): float {.noSideEffect.} = result = result + diff*diff result = result / toFloat(len(x)) -proc random*(max: int): int {.gcsafe.} +proc random*(max: int): int {.benign.} ## returns a random number in the range 0..max-1. The sequence of ## random number is always the same, unless `randomize` is called ## which initializes the random number generator with a "random" ## number, i.e. a tickcount. -proc random*(max: float): float {.gcsafe.} +proc random*(max: float): float {.benign.} ## returns a random number in the range 0..= 60.0: - echo("PING -> redis") - assert(database.r.ping() == "PONG") - database.lastPing = t - -proc getCommits*(database: TDb, - plStr: var seq[string]): seq[TEntry] = - result = @[] - var commitsRaw = database.r.lrange("commits", 0, -1) - for c in items(commitsRaw): - var commit: TCommit - commit.hash = c - for key, value in database.r.hPairs(c): - case normalize(key) - of "commitmsg": commit.commitMsg = value - of "date": commit.date = Time(parseInt(value)) - of "username": commit.username = value - else: - echo(key) - assert(false) - - var platformsRaw = database.r.lrange(c & ":platforms", 0, -1) - var platforms: seq[TPlatform] = @[] - for p in items(platformsRaw): - var platform: TPlatform - for key, value in database.r.hPairs(p & ":" & c): - case normalize(key) - of "buildresult": - platform.buildResult = parseInt(value).TBuildResult - of "testresult": - platform.testResult = parseInt(value).TTestResult - of "failreason": - platform.failReason = value - of "total": - platform.total = parseBiggestInt(value) - of "passed": - platform.passed = parseBiggestInt(value) - of "skipped": - platform.skipped = parseBiggestInt(value) - of "failed": - platform.failed = parseBiggestInt(value) - of "csources": - platform.csources = if value == "t": true else: false - else: - echo(normalize(key)) - assert(false) - - platform.platform = p - - platforms.add(platform) - if p notin plStr: - plStr.add(p) - result.add((commit, platforms)) - -proc commitExists*(database: TDb, commit: string, starts = false): bool = - # TODO: Consider making the 'commits' list a set. - for c in items(database.r.lrange("commits", 0, -1)): - if starts: - if c.startsWith(commit): return true - else: - if c == commit: return true - return false - -proc platformExists*(database: TDb, commit: string, platform: string): bool = - for p in items(database.r.lrange(commit & ":" & "platforms", 0, -1)): - if p == platform: return true - -proc expandHash*(database: TDb, commit: string): string = - for c in items(database.r.lrange("commits", 0, -1)): - if c.startsWith(commit): return c - assert false - -proc isNewest*(database: TDb, commit: string): bool = - return database.r.lIndex("commits", 0) == commit - -proc getNewest*(database: TDb): string = - return database.r.lIndex("commits", 0) - -proc addPlatform*(database: TDb, commit: string, platform: string) = - assert database.commitExists(commit) - assert (not database.platformExists(commit, platform)) - var name = platform & ":" & commit - if database.r.exists(name): - if failOnExisting: quit("[FAIL] " & name & " already exists!", 1) - else: echo("[Warning] " & name & " already exists!") - - discard database.r.lPush(commit & ":" & "platforms", platform) - -proc `[]`*(p: seq[TPlatform], name: string): TPlatform = - for platform in items(p): - if platform.platform == name: - return platform - raise newException(ValueError, name & " platforms not found in commits.") - -proc contains*(p: seq[TPlatform], s: string): bool = - for i in items(p): - if i.platform == s: - return true - - -type - PState = ref TState - TState = object of RootObj - dispatcher: Dispatcher - sock: AsyncSocket - ircClient: PAsyncIRC - hubPort: Port - database: TDb - dbConnected: bool - - TSeenType = enum - PSeenJoin, PSeenPart, PSeenMsg, PSeenNick, PSeenQuit - - TSeen = object - nick: string - channel: string - timestamp: Time - case kind*: TSeenType - of PSeenJoin: nil - of PSeenPart, PSeenQuit, PSeenMsg: - msg: string - of PSeenNick: - newNick: string - -const - ircServer = "irc.freenode.net" - joinChans = @["#nim"] - botNickname = "NimBot" - -proc setSeen(d: TDb, s: TSeen) = - discard d.r.del("seen:" & s.nick) - - var hashToSet = @[("type", $s.kind.int), ("channel", s.channel), - ("timestamp", $s.timestamp.int)] - case s.kind - of PSeenJoin: discard - of PSeenPart, PSeenMsg, PSeenQuit: - hashToSet.add(("msg", s.msg)) - of PSeenNick: - hashToSet.add(("newnick", s.newNick)) - - d.r.hMSet("seen:" & s.nick, hashToSet) - -proc getSeen(d: TDb, nick: string, s: var TSeen): bool = - if d.r.exists("seen:" & nick): - result = true - s.nick = nick - # Get the type first - s.kind = d.r.hGet("seen:" & nick, "type").parseInt.TSeenType - - for key, value in d.r.hPairs("seen:" & nick): - case normalize(key) - of "type": - discard - #s.kind = value.parseInt.TSeenType - of "channel": - s.channel = value - of "timestamp": - s.timestamp = Time(value.parseInt) - of "msg": - s.msg = value - of "newnick": - s.newNick = value - -template createSeen(typ: TSeenType, n, c: string): stmt {.immediate, dirty.} = - var seenNick: TSeen - seenNick.kind = typ - seenNick.nick = n - seenNick.channel = c - seenNick.timestamp = getTime() - -proc parseReply(line: string, expect: string): bool = - var jsonDoc = parseJson(line) - return jsonDoc["reply"].str == expect - -proc limitCommitMsg(m: string): string = - ## Limits the message to 300 chars and adds ellipsis. - var m1 = m - if NewLines in m1: - m1 = m1.splitLines()[0] - - if m1.len >= 300: - m1 = m1[0..300] - - if m1.len >= 300 or NewLines in m: m1.add("... ") - - if NewLines in m: m1.add($m.splitLines().len & " more lines") - - return m1 - -proc handleWebMessage(state: PState, line: string) = - echo("Got message from hub: " & line) - var json = parseJson(line) - if json.hasKey("payload"): - for i in 0..min(4, json["payload"]["commits"].len-1): - var commit = json["payload"]["commits"][i] - # Create the message - var message = "" - message.add(json["payload"]["repository"]["owner"]["name"].str & "/" & - json["payload"]["repository"]["name"].str & " ") - message.add(commit["id"].str[0..6] & " ") - message.add(commit["author"]["name"].str & " ") - message.add("[+" & $commit["added"].len & " ") - message.add("±" & $commit["modified"].len & " ") - message.add("-" & $commit["removed"].len & "]: ") - message.add(limitCommitMsg(commit["message"].str)) - - # Send message to #nim. - discard state.ircClient.privmsg(joinChans[0], message) - elif json.hasKey("redisinfo"): - assert json["redisinfo"].hasKey("port") - #let redisPort = json["redisinfo"]["port"].num - state.dbConnected = true - -proc hubConnect(state: PState) -proc handleConnect(s: AsyncSocket, state: PState) = - try: - # Send greeting - var obj = newJObject() - obj["name"] = newJString("irc") - obj["platform"] = newJString("?") - state.sock.send($obj & "\c\L") - - # Wait for reply. - var line = "" - sleep(1500) - if state.sock.recvLine(line): - assert(line != "") - doAssert parseReply(line, "OK") - echo("The hub accepted me!") - else: - raise newException(ValueError, - "Hub didn't accept me. Waited 1.5 seconds.") - - # ask for the redis info - var riobj = newJObject() - riobj["do"] = newJString("redisinfo") - state.sock.send($riobj & "\c\L") - - except OsError: - echo(getCurrentExceptionMsg()) - s.close() - echo("Waiting 5 seconds...") - sleep(5000) - state.hubConnect() - -proc handleRead(s: AsyncSocket, state: PState) = - var line = "" - if state.sock.recvLine(line): - if line != "": - # Handle the message - state.handleWebMessage(line) - else: - echo("Disconnected from hub: ", osErrorMsg()) - s.close() - echo("Reconnecting...") - state.hubConnect() - else: - echo(osErrorMsg()) - -proc hubConnect(state: PState) = - state.sock = asyncSocket() - state.sock.connect("127.0.0.1", state.hubPort) - state.sock.handleConnect = - proc (s: AsyncSocket) = - handleConnect(s, state) - state.sock.handleRead = - proc (s: AsyncSocket) = - handleRead(s, state) - - state.dispatcher.register(state.sock) - -proc handleIrc(irc: PAsyncIRC, event: TIRCEvent, state: PState) = - case event.typ - of EvConnected: discard - of EvDisconnected: - while not state.ircClient.isConnected: - try: - state.ircClient.connect() - except: - echo("Error reconnecting: ", getCurrentExceptionMsg()) - - echo("Waiting 5 seconds...") - sleep(5000) - echo("Reconnected successfully!") - of EvMsg: - echo("< ", event.raw) - case event.cmd - of MPrivMsg: - let msg = event.params[event.params.len-1] - let words = msg.split(' ') - template pm(msg: string): stmt = - state.ircClient.privmsg(event.origin, msg) - case words[0] - of "!ping": pm("pong") - of "!lag": - if state.ircClient.getLag != -1.0: - var lag = state.ircClient.getLag - lag = lag * 1000.0 - pm($int(lag) & "ms between me and the server.") - else: - pm("Unknown.") - of "!seen": - if words.len > 1: - let nick = words[1] - if nick == botNickname: - pm("Yes, I see myself.") - echo(nick) - var seenInfo: TSeen - if state.database.getSeen(nick, seenInfo): - #var mSend = "" - case seenInfo.kind - of PSeenMsg: - pm("$1 was last seen on $2 in $3 saying: $4" % - [seenInfo.nick, $seenInfo.timestamp, - seenInfo.channel, seenInfo.msg]) - of PSeenJoin: - pm("$1 was last seen on $2 joining $3" % - [seenInfo.nick, $seenInfo.timestamp, seenInfo.channel]) - of PSeenPart: - pm("$1 was last seen on $2 leaving $3 with message: $4" % - [seenInfo.nick, $seenInfo.timestamp, seenInfo.channel, - seenInfo.msg]) - of PSeenQuit: - pm("$1 was last seen on $2 quitting with message: $3" % - [seenInfo.nick, $seenInfo.timestamp, seenInfo.msg]) - of PSeenNick: - pm("$1 was last seen on $2 changing nick to $3" % - [seenInfo.nick, $seenInfo.timestamp, seenInfo.newNick]) - - else: - pm("I have not seen " & nick) - else: - pm("Syntax: !seen ") - - # TODO: ... commands - - # -- Seen - # Log this as activity. - createSeen(PSeenMsg, event.nick, event.origin) - seenNick.msg = msg - state.database.setSeen(seenNick) - of MJoin: - createSeen(PSeenJoin, event.nick, event.origin) - state.database.setSeen(seenNick) - of MPart: - createSeen(PSeenPart, event.nick, event.origin) - let msg = event.params[event.params.high] - seenNick.msg = msg - state.database.setSeen(seenNick) - of MQuit: - createSeen(PSeenQuit, event.nick, event.origin) - let msg = event.params[event.params.high] - seenNick.msg = msg - state.database.setSeen(seenNick) - of MNick: - createSeen(PSeenNick, event.nick, "#nim") - seenNick.newNick = event.params[0] - state.database.setSeen(seenNick) - else: - discard # TODO: ? - -proc open(port: Port = Port(5123)): PState = - var res: PState - new(res) - res.dispatcher = newDispatcher() - - res.hubPort = port - res.hubConnect() - let hirc = - proc (a: PAsyncIRC, ev: TIRCEvent) = - handleIrc(a, ev, res) - # Connect to the irc server. - res.ircClient = AsyncIrc(ircServer, nick = botNickname, user = botNickname, - joinChans = joinChans, ircEvent = hirc) - res.ircClient.connect() - res.dispatcher.register(res.ircClient) - - res.dbConnected = false - result = res - -var state = tircbot.open() # Connect to the website and the IRC server. - -while state.dispatcher.poll(): - if state.dbConnected: - state.database.keepAlive() diff --git a/tests/stdlib/tmitems.nim b/tests/stdlib/tmitems.nim index bf67d2b7b6..2c0a0392a5 100644 --- a/tests/stdlib/tmitems.nim +++ b/tests/stdlib/tmitems.nim @@ -11,7 +11,7 @@ fpqeew [11, 12, 13] [11, 12, 13] [11, 12, 13] -{ "key1": 11, "key2": 12, "key3": 13} +{"key1": 11, "key2": 12, "key3": 13} [11, 12, 13] diff --git a/tests/table/ttables.nim b/tests/table/ttables.nim deleted file mode 100644 index de4aaed5eb..0000000000 --- a/tests/table/ttables.nim +++ /dev/null @@ -1,128 +0,0 @@ -discard """ - output: '''true''' -""" - -import hashes, tables - -const - data = { - "34": 123456, "12": 789, - "90": 343, "0": 34404, - "1": 344004, "2": 344774, - "3": 342244, "4": 3412344, - "5": 341232144, "6": 34214544, - "7": 3434544, "8": 344544, - "9": 34435644, "---00": 346677844, - "10": 34484, "11": 34474, "19": 34464, - "20": 34454, "30": 34141244, "40": 344114, - "50": 344490, "60": 344491, "70": 344492, - "80": 344497} - - sorteddata = { - "---00": 346677844, - "0": 34404, - "1": 344004, - "10": 34484, - "11": 34474, - "12": 789, - "19": 34464, - "2": 344774, "20": 34454, - "3": 342244, "30": 34141244, - "34": 123456, - "4": 3412344, "40": 344114, - "5": 341232144, "50": 344490, - "6": 34214544, "60": 344491, - "7": 3434544, "70": 344492, - "8": 344544, "80": 344497, - "9": 34435644, - "90": 343} - -block tableTest1: - var t = initTable[tuple[x, y: int], string]() - t[(0,0)] = "00" - t[(1,0)] = "10" - t[(0,1)] = "01" - t[(1,1)] = "11" - for x in 0..1: - for y in 0..1: - assert t[(x,y)] == $x & $y - assert($t == - "{(x: 0, y: 0): 00, (x: 0, y: 1): 01, (x: 1, y: 0): 10, (x: 1, y: 1): 11}") - -block tableTest2: - var t = initTable[string, float]() - t["test"] = 1.2345 - t["111"] = 1.000043 - t["123"] = 1.23 - t.del("111") - - t["012"] = 67.9 - t["123"] = 1.5 # test overwriting - - assert t["123"] == 1.5 - assert t["111"] == 0.0 # deleted - assert(not hasKey(t, "111")) - - for key, val in items(data): t[key] = val.toFloat - for key, val in items(data): assert t[key] == val.toFloat - - -block orderedTableTest1: - var t = initOrderedTable[string, int](2) - for key, val in items(data): t[key] = val - for key, val in items(data): assert t[key] == val - var i = 0 - # `pairs` needs to yield in insertion order: - for key, val in pairs(t): - assert key == data[i][0] - assert val == data[i][1] - inc(i) - - for key, val in mpairs(t): val = 99 - for val in mvalues(t): assert val == 99 - -block countTableTest1: - var s = data.toTable - var t = initCountTable[string]() - for k in s.keys: t.inc(k) - for k in t.keys: assert t[k] == 1 - t.inc("90", 3) - t.inc("12", 2) - t.inc("34", 1) - assert t.largest()[0] == "90" - - t.sort() - var i = 0 - for k, v in t.pairs: - case i - of 0: assert k == "90" and v == 4 - of 1: assert k == "12" and v == 3 - of 2: assert k == "34" and v == 2 - else: break - inc i - -block SyntaxTest: - var x = toTable[int, string]({:}) - -proc orderedTableSortTest() = - var t = initOrderedTable[string, int](2) - for key, val in items(data): t[key] = val - for key, val in items(data): assert t[key] == val - t.sort(proc (x, y: tuple[key: string, val: int]): int = cmp(x.key, y.key)) - var i = 0 - # `pairs` needs to yield in sorted order: - for key, val in pairs(t): - doAssert key == sorteddata[i][0] - doAssert val == sorteddata[i][1] - inc(i) - - # check that lookup still works: - for key, val in pairs(t): - doAssert val == t[key] - # check that insert still works: - t["newKeyHere"] = 80 - - -orderedTableSortTest() -echo "true" - diff --git a/todo.txt b/todo.txt index 706954f652..57cfea017a 100644 --- a/todo.txt +++ b/todo.txt @@ -41,7 +41,6 @@ Misc - make tuple unpacking work in a non-var/let context - built-in 'getImpl' - prevent 'alloc(TypeWithGCedMemory)' -- some table related tests are wrong (memory usage checks) Bugs From 8763bffa845c2c17e7e70acfc21b556f407d9ecd Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 12 Feb 2015 14:40:50 +0100 Subject: [PATCH 310/850] better handling of gcsafety with --threadAnalysis:off --- compiler/pragmas.nim | 9 ++++----- compiler/sempass2.nim | 43 +++++++++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 90f87696bb..78ee490e28 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -735,11 +735,10 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, incl(sym.flags, sfProcvar) if sym.typ != nil: incl(sym.typ.flags, tfThread) of wGcSafe: - if optThreadAnalysis in gGlobalOptions: - noVal(it) - if sym.kind != skType: incl(sym.flags, sfThread) - if sym.typ != nil: incl(sym.typ.flags, tfGcSafe) - else: invalidPragma(it) + noVal(it) + if sym.kind != skType: incl(sym.flags, sfThread) + if sym.typ != nil: incl(sym.typ.flags, tfGcSafe) + else: invalidPragma(it) of wPacked: noVal(it) if sym.typ == nil: invalidPragma(it) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 6fa7c756e1..3f78629c8f 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -194,6 +194,9 @@ proc warnAboutGcUnsafe(n: PNode) = #assert false message(n.info, warnGcUnsafe, renderTree(n)) +template markGcUnsafe(a: PEffects) = + a.gcUnsafe = true + proc useVar(a: PEffects, n: PNode) = let s = n.sym if isLocalVar(a, s): @@ -209,7 +212,7 @@ proc useVar(a: PEffects, n: PNode) = if (tfHasGCedMem in s.typ.flags or s.typ.isGCedMem) and tfGcSafe notin s.typ.flags: if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) - a.gcUnsafe = true + markGcUnsafe(a) type TIntersection = seq[tuple[id, count: int]] # a simple count table @@ -448,7 +451,7 @@ proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) = if notGcSafe(s.typ) and sfImportc notin s.flags: if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) - tracked.gcUnsafe = true + markGcUnsafe(tracked) mergeLockLevels(tracked, n, s.getLockLevel) proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) = @@ -502,13 +505,13 @@ proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) = # assume GcUnsafe unless in its type; 'forward' does not matter: if notGcSafe(op) and not isOwnedProcVar(a, tracked.owner): if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) - tracked.gcUnsafe = true + markGcUnsafe(tracked) else: mergeEffects(tracked, effectList.sons[exceptionEffects], n) mergeTags(tracked, effectList.sons[tagEffects], n) if notGcSafe(op): if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) - tracked.gcUnsafe = true + markGcUnsafe(tracked) notNilCheck(tracked, n, paramType) proc breaksBlock(n: PNode): bool = @@ -656,7 +659,7 @@ proc track(tracked: PEffects, n: PNode) = # and it's not a recursive call: if not (a.kind == nkSym and a.sym == tracked.owner): warnAboutGcUnsafe(n) - tracked.gcUnsafe = true + markGcUnsafe(tracked) for i in 1 .. s.typ.lockLevel: - #localError(s.info, - message(s.info, warnLockLevel, - "declared lock level is $1, but real lock level is $2" % - [$s.typ.lockLevel, $t.maxLockLevel]) + if sfThread in s.flags and t.gcUnsafe: + if optThreads in gGlobalOptions and optThreadAnalysis in gGlobalOptions: + localError(s.info, "'$1' is not GC-safe" % s.name.s) + else: + localError(s.info, warnGcUnsafe2, s.name.s) + if not t.gcUnsafe: + s.typ.flags.incl tfGcSafe + if s.typ.lockLevel == UnspecifiedLockLevel: + s.typ.lockLevel = t.maxLockLevel + elif t.maxLockLevel > s.typ.lockLevel: + #localError(s.info, + message(s.info, warnLockLevel, + "declared lock level is $1, but real lock level is $2" % + [$s.typ.lockLevel, $t.maxLockLevel]) proc trackTopLevelStmt*(module: PSym; n: PNode) = if n.kind in {nkPragma, nkMacroDef, nkTemplateDef, nkProcDef, From 41385f3aaf4da7a13df64ec98a2b0b713c88c1d6 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 12 Feb 2015 14:41:19 +0100 Subject: [PATCH 311/850] made a test green --- lib/pure/selectors.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim index bd2564937f..593eec15a0 100644 --- a/lib/pure/selectors.nim +++ b/lib/pure/selectors.nim @@ -299,7 +299,7 @@ when isMainModule and not defined(nimdoc): sock: Socket var sock = socket() - if sock == sockets.InvalidSocket: raiseOSError(osLastError()) + if sock == sockets.invalidSocket: raiseOSError(osLastError()) #sock.setBlocking(false) sock.connect("irc.freenode.net", Port(6667)) From c4eddb3fdafe3494fa1b1300bcbf1314b7540490 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 12 Feb 2015 14:56:42 +0100 Subject: [PATCH 312/850] ordinary parameters can follow a varargs parameter --- compiler/sigmatch.nim | 22 ++++++++++++++-------- tests/overload/tparams_after_varargs.nim | 17 +++++++++++++++++ todo.txt | 2 +- web/news.txt | 12 ++++++++++++ 4 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 tests/overload/tparams_after_varargs.nim diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 9a99d5200c..544011f2d1 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1441,13 +1441,14 @@ proc matchesAux(c: PContext, n, nOrig: PNode, return checkConstraint(n.sons[a].sons[1]) if m.baseTypeMatch: - assert(container == nil) + #assert(container == nil) container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg)) addSon(container, arg) setSon(m.call, formal.position + 1, container) if f != formalLen - 1: container = nil - else: + else: setSon(m.call, formal.position + 1, arg) + inc f else: # unnamed param if f >= formalLen: @@ -1466,7 +1467,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, n.sons[a] = prepareOperand(c, formal.typ, n.sons[a]) var arg = paramTypesMatch(m, formal.typ, n.sons[a].typ, n.sons[a], nOrig.sons[a]) - if (arg != nil) and m.baseTypeMatch and (container != nil): + if arg != nil and m.baseTypeMatch and container != nil: addSon(container, arg) incrIndexType(container.typ) else: @@ -1480,7 +1481,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, internalError(n.sons[a].info, "matches") return formal = m.callee.n.sons[f].sym - if containsOrIncl(marker, formal.position): + if containsOrIncl(marker, formal.position) and container.isNil: # already in namedParams: localError(n.sons[a].info, errCannotBindXTwice, formal.name.s) m.state = csNoMatch @@ -1493,17 +1494,22 @@ proc matchesAux(c: PContext, n, nOrig: PNode, m.state = csNoMatch return if m.baseTypeMatch: - assert(container == nil) - container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg)) + #assert(container == nil) + if container.isNil: + container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg)) addSon(container, arg) setSon(m.call, formal.position + 1, implicitConv(nkHiddenStdConv, formal.typ, container, m, c)) - if f != formalLen - 1: container = nil + #if f != formalLen - 1: container = nil + + # pick the formal from the end, so that 'x, y, varargs, z' works: + f = max(f, formalLen - n.len + a + 1) else: setSon(m.call, formal.position + 1, arg) + inc(f) + container = nil checkConstraint(n.sons[a]) inc(a) - inc(f) proc semFinishOperands*(c: PContext, n: PNode) = # this needs to be called to ensure that after overloading resolution every diff --git a/tests/overload/tparams_after_varargs.nim b/tests/overload/tparams_after_varargs.nim new file mode 100644 index 0000000000..a93e280b91 --- /dev/null +++ b/tests/overload/tparams_after_varargs.nim @@ -0,0 +1,17 @@ +discard """ + output: '''a 1 b 2 x @[3, 4, 5] y 6 z 7 +yay +12''' +""" + +proc test(a, b: int, x: varargs[int]; y, z: int) = + echo "a ", a, " b ", b, " x ", @x, " y ", y, " z ", z + +test 1, 2, 3, 4, 5, 6, 7 + +template takesBlock(a, b: int, x: varargs[expr]; blck: stmt) = + blck + echo a, b + +takesBlock 1, 2, "some", 0.90, "random stuff": + echo "yay" diff --git a/todo.txt b/todo.txt index 57cfea017a..15521eae13 100644 --- a/todo.txt +++ b/todo.txt @@ -1,8 +1,8 @@ version 0.10.4 ============== -- make 'nil' work for 'add' and 'len' - improve GC-unsafety warnings +- make 'nil' work for 'add' and 'len' - get rid of 'mget'; aka priority of 'var' needs to be 'var{lvalue}' diff --git a/web/news.txt b/web/news.txt index 5cc3a6ed6c..7ead5a70e3 100644 --- a/web/news.txt +++ b/web/news.txt @@ -43,6 +43,18 @@ News foo = {"ah": "finally", "this": "is", "possible.": "nice!"}.toTable() + - Ordinary parameters can follow after a varargs parameter. This means the + following is finally accepted by the compiler: + + .. code-block:: nim + template takesBlock(a, b: int, x: varargs[expr]; blck: stmt) = + blck + echo a, b + + takesBlock 1, 2, "some", 0.90, "random stuff": + echo "yay" + + 2014-12-29 Version 0.10.2 released ================================== From 61db30727b6fa8233bcbc14246e758eb79a84394 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 12 Feb 2015 15:14:46 +0100 Subject: [PATCH 313/850] Aporia compiles again (disabling thread analysis is horrible!) --- compiler/sigmatch.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 544011f2d1..00802e69b7 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -418,7 +418,8 @@ proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation = if tfNoSideEffect in f.flags and tfNoSideEffect notin a.flags: return isNone - elif tfThread in f.flags and a.flags * {tfThread, tfNoSideEffect} == {}: + elif tfThread in f.flags and a.flags * {tfThread, tfNoSideEffect} == {} and + optThreadAnalysis in gGlobalOptions: # noSideEffect implies ``tfThread``! return isNone elif f.flags * {tfIterator} != a.flags * {tfIterator}: From f9b3f7f98037065ae8fbb8bda562136b2dfde95a Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 12 Feb 2015 16:10:24 +0100 Subject: [PATCH 314/850] fixes #2068 --- compiler/ccgcalls.nim | 30 +- doc/nimc.txt | 941 +++++++++++++++++++++--------------------- todo.txt | 1 + 3 files changed, 490 insertions(+), 482 deletions(-) diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index b9fc694cba..fb878a83e9 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -430,15 +430,27 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) = assert(typ.kind == tyProc) var length = sonsLen(ri) assert(sonsLen(typ) == sonsLen(typ.n)) - - if length > 1: - app(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri)) - app(pl, ~" ") - app(pl, op.r) - if length > 2: - app(pl, ~": ") - app(pl, genArg(p, ri.sons[2], typ.n.sons[2].sym, ri)) - for i in countup(3, length-1): + + # don't call 'ropeToStr' here for efficiency: + let pat = ri.sons[0].sym.loc.r.data + internalAssert pat != nil + var start = 3 + if ' ' in pat: + start = 1 + app(pl, op.r) + if length > 1: + app(pl, ~": ") + app(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri)) + start = 2 + else: + if length > 1: + app(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri)) + app(pl, ~" ") + app(pl, op.r) + if length > 2: + app(pl, ~": ") + app(pl, genArg(p, ri.sons[2], typ.n.sons[2].sym, ri)) + for i in countup(start, length-1): assert(sonsLen(typ) == sonsLen(typ.n)) if i >= sonsLen(typ): internalError(ri.info, "varargs for objective C method?") diff --git a/doc/nimc.txt b/doc/nimc.txt index 80fcf927be..84d596e3c2 100644 --- a/doc/nimc.txt +++ b/doc/nimc.txt @@ -1,45 +1,45 @@ -=================================== - Nim Compiler User Guide -=================================== - -:Author: Andreas Rumpf -:Version: |nimversion| - -.. contents:: - - "Look at you, hacker. A pathetic creature of meat and bone, panting and - sweating as you run through my corridors. How can you challenge a perfect, - immortal machine?" - - -Introduction -============ - -This document describes the usage of the *Nim compiler* -on the different supported platforms. It is not a definition of the Nim -programming language (therefore is the `manual `_). - -Nim is free software; it is licensed under the -`MIT License `_. - - -Compiler Usage -============== - -Command line switches ---------------------- -Basic command line switches are: - -Usage: - -.. include:: basicopt.txt - ----- - -Advanced command line switches are: - -.. include:: advopt.txt - +=================================== + Nim Compiler User Guide +=================================== + +:Author: Andreas Rumpf +:Version: |nimversion| + +.. contents:: + + "Look at you, hacker. A pathetic creature of meat and bone, panting and + sweating as you run through my corridors. How can you challenge a perfect, + immortal machine?" + + +Introduction +============ + +This document describes the usage of the *Nim compiler* +on the different supported platforms. It is not a definition of the Nim +programming language (therefore is the `manual `_). + +Nim is free software; it is licensed under the +`MIT License `_. + + +Compiler Usage +============== + +Command line switches +--------------------- +Basic command line switches are: + +Usage: + +.. include:: basicopt.txt + +---- + +Advanced command line switches are: + +.. include:: advopt.txt + List of warnings @@ -53,21 +53,16 @@ Name Description ========================== ============================================ CannotOpenFile Some file not essential for the compiler's working could not be opened. -OctalEscape The code contains an unsupported octal +OctalEscape The code contains an unsupported octal sequence. Deprecated The code uses a deprecated symbol. ConfigDeprecated The project makes use of a deprecated config file. -SmallLshouldNotBeUsed The letter 'l' should not be used as an +SmallLshouldNotBeUsed The letter 'l' should not be used as an identifier. -AnalysisLoophole The thread analysis was incomplete due to - an indirect call. -DifferentHeaps The code mixes different local heaps in a - very dangerous way. -WriteToForeignHeap The code contains a threading error. -EachIdentIsTuple The code contains a confusing ``var`` +EachIdentIsTuple The code contains a confusing ``var`` declaration. -ShadowIdent A local variable shadows another local +ShadowIdent A local variable shadows another local variable of an outer scope. User Some user defined warning. ========================== ============================================ @@ -103,30 +98,30 @@ enable builds in release mode (``-d:release``) where certain safety checks are omitted for better performance. Another common use is the ``-d:ssl`` switch to activate `SSL sockets `_. - -Configuration files -------------------- - -**Note:** The *project file name* is the name of the ``.nim`` file that is -passed as a command line argument to the compiler. - - -The ``nim`` executable processes configuration files in the following -directories (in this order; later files overwrite previous settings): - -1) ``$nim/config/nim.cfg``, ``/etc/nim.cfg`` (UNIX) or ``%NIMROD%/config/nim.cfg`` (Windows). This file can be skipped with the ``--skipCfg`` command line option. -2) ``/home/$user/.config/nim.cfg`` (UNIX) or ``%APPDATA%/nim.cfg`` (Windows). This file can be skipped with the ``--skipUserCfg`` command line option. -3) ``$parentDir/nim.cfg`` where ``$parentDir`` stands for any parent directory of the project file's path. These files can be skipped with the ``--skipParentCfg`` command line option. -4) ``$projectDir/nim.cfg`` where ``$projectDir`` stands for the project file's path. This file can be skipped with the ``--skipProjCfg`` command line option. -5) A project can also have a project specific configuration file named ``$project.nim.cfg`` that resides in the same directory as ``$project.nim``. This file can be skipped with the ``--skipProjCfg`` command line option. - - -Command line settings have priority over configuration file settings. - -The default build of a project is a `debug build`:idx:. To compile a -`release build`:idx: define the ``release`` symbol:: - - nim c -d:release myproject.nim + +Configuration files +------------------- + +**Note:** The *project file name* is the name of the ``.nim`` file that is +passed as a command line argument to the compiler. + + +The ``nim`` executable processes configuration files in the following +directories (in this order; later files overwrite previous settings): + +1) ``$nim/config/nim.cfg``, ``/etc/nim.cfg`` (UNIX) or ``%NIMROD%/config/nim.cfg`` (Windows). This file can be skipped with the ``--skipCfg`` command line option. +2) ``/home/$user/.config/nim.cfg`` (UNIX) or ``%APPDATA%/nim.cfg`` (Windows). This file can be skipped with the ``--skipUserCfg`` command line option. +3) ``$parentDir/nim.cfg`` where ``$parentDir`` stands for any parent directory of the project file's path. These files can be skipped with the ``--skipParentCfg`` command line option. +4) ``$projectDir/nim.cfg`` where ``$projectDir`` stands for the project file's path. This file can be skipped with the ``--skipProjCfg`` command line option. +5) A project can also have a project specific configuration file named ``$project.nim.cfg`` that resides in the same directory as ``$project.nim``. This file can be skipped with the ``--skipProjCfg`` command line option. + + +Command line settings have priority over configuration file settings. + +The default build of a project is a `debug build`:idx:. To compile a +`release build`:idx: define the ``release`` symbol:: + + nim c -d:release myproject.nim Search path handling @@ -138,8 +133,8 @@ found an ambiguity error is produced. ``nim dump`` shows the contents of the PATH. -However before the PATH is used the current directory is checked for the -file's existance. So if PATH contains ``$lib`` and ``$lib/bar`` and the +However before the PATH is used the current directory is checked for the +file's existance. So if PATH contains ``$lib`` and ``$lib/bar`` and the directory structure looks like this:: $lib/x.nim @@ -152,83 +147,83 @@ And ``main`` imports ``x``, ``foo/x`` is imported. If ``other`` imports ``x`` then both ``$lib/x.nim`` and ``$lib/bar/x.nim`` match and so the compiler should reject it. Currently however this check is not implemented and instead the first matching file is used. - - -Generated C code directory --------------------------- + + +Generated C code directory +-------------------------- The generated files that Nim produces all go into a subdirectory called ``nimcache`` in your project directory. This makes it easy to delete all generated files. Files generated in this directory follow a naming logic which you can read about in the `Nim Backend Integration document `_. -However, the generated C code is not platform independent. C code generated for -Linux does not compile on Windows, for instance. The comment on top of the -C file lists the OS, CPU and CC the file has been compiled for. - - -Compilation cache -================= - -**Warning**: The compilation cache is still highly experimental! - -The ``nimcache`` directory may also contain so called `rod`:idx: -or `symbol files`:idx:. These files are pre-compiled modules that are used by -the compiler to perform `incremental compilation`:idx:. This means that only -modules that have changed since the last compilation (or the modules depending -on them etc.) are re-compiled. However, per default no symbol files are -generated; use the ``--symbolFiles:on`` command line switch to activate them. - -Unfortunately due to technical reasons the ``--symbolFiles:on`` needs -to *aggregate* some generated C code. This means that the resulting executable -might contain some cruft even when dead code elimination is turned on. So -the final release build should be done with ``--symbolFiles:off``. - -Due to the aggregation of C code it is also recommended that each project -resides in its own directory so that the generated ``nimcache`` directory -is not shared between different projects. - - -Cross compilation -================= - -To cross compile, use for example:: - - nim c --cpu:i386 --os:linux --compile_only --gen_script myproject.nim - -Then move the C code and the compile script ``compile_myproject.sh`` to your +However, the generated C code is not platform independent. C code generated for +Linux does not compile on Windows, for instance. The comment on top of the +C file lists the OS, CPU and CC the file has been compiled for. + + +Compilation cache +================= + +**Warning**: The compilation cache is still highly experimental! + +The ``nimcache`` directory may also contain so called `rod`:idx: +or `symbol files`:idx:. These files are pre-compiled modules that are used by +the compiler to perform `incremental compilation`:idx:. This means that only +modules that have changed since the last compilation (or the modules depending +on them etc.) are re-compiled. However, per default no symbol files are +generated; use the ``--symbolFiles:on`` command line switch to activate them. + +Unfortunately due to technical reasons the ``--symbolFiles:on`` needs +to *aggregate* some generated C code. This means that the resulting executable +might contain some cruft even when dead code elimination is turned on. So +the final release build should be done with ``--symbolFiles:off``. + +Due to the aggregation of C code it is also recommended that each project +resides in its own directory so that the generated ``nimcache`` directory +is not shared between different projects. + + +Cross compilation +================= + +To cross compile, use for example:: + + nim c --cpu:i386 --os:linux --compile_only --gen_script myproject.nim + +Then move the C code and the compile script ``compile_myproject.sh`` to your Linux i386 machine and run the script. Another way is to make Nim invoke a cross compiler toolchain:: - - nim c --cpu:arm --os:linux myproject.nim - -For cross compilation, the compiler invokes a C compiler named -like ``$cpu.$os.$cc`` (for example arm.linux.gcc) and the configuration + + nim c --cpu:arm --os:linux myproject.nim + +For cross compilation, the compiler invokes a C compiler named +like ``$cpu.$os.$cc`` (for example arm.linux.gcc) and the configuration system is used to provide meaningful defaults. For example for ``ARM`` your configuration file should contain something like:: arm.linux.gcc.path = "/usr/bin" arm.linux.gcc.exe = "arm-linux-gcc" arm.linux.gcc.linkerexe = "arm-linux-gcc" - - -DLL generation -============== - -Nim supports the generation of DLLs. However, there must be only one -instance of the GC per process/address space. This instance is contained in -``nimrtl.dll``. This means that every generated Nim DLL depends -on ``nimrtl.dll``. To generate the "nimrtl.dll" file, use the command:: - - nim c -d:release lib/nimrtl.nim - -To link against ``nimrtl.dll`` use the command:: - - nim c -d:useNimRtl myprog.nim - -**Note**: Currently the creation of ``nimrtl.dll`` with thread support has -never been tested and is unlikely to work! + + +DLL generation +============== + +Nim supports the generation of DLLs. However, there must be only one +instance of the GC per process/address space. This instance is contained in +``nimrtl.dll``. This means that every generated Nim DLL depends +on ``nimrtl.dll``. To generate the "nimrtl.dll" file, use the command:: + + nim c -d:release lib/nimrtl.nim + +To link against ``nimrtl.dll`` use the command:: + + nim c -d:useNimRtl myprog.nim + +**Note**: Currently the creation of ``nimrtl.dll`` with thread support has +never been tested and is unlikely to work! Additional compilation switches @@ -247,10 +242,10 @@ Define Effect version. ``useFork`` Makes ``osproc`` use ``fork`` instead of ``posix_spawn``. ``useNimRtl`` Compile and link against ``nimrtl.dll``. -``useMalloc`` Makes Nim use C's `malloc`:idx: instead of Nim's +``useMalloc`` Makes Nim use C's `malloc`:idx: instead of Nim's own memory manager. This only works with ``gc:none``. -``useRealtimeGC`` Enables support of Nim's GC for *soft* realtime - systems. See the documentation of the `gc `_ +``useRealtimeGC`` Enables support of Nim's GC for *soft* realtime + systems. See the documentation of the `gc `_ for further information. ``nodejs`` The JS target is actually ``node.js``. ``ssl`` Enables OpenSSL support for the sockets module. @@ -258,84 +253,84 @@ Define Effect ``uClibc`` Use uClibc instead of libc. (Relevant for Unix-like OSes) ================== ========================================================= - - -Additional Features -=================== - -This section describes Nim's additional features that are not listed in the -Nim manual. Some of the features here only make sense for the C code -generator and are subject to change. - - -NoDecl pragma -------------- -The ``noDecl`` pragma can be applied to almost any symbol (variable, proc, -type, etc.) and is sometimes useful for interoperability with C: -It tells Nim that it should not generate a declaration for the symbol in -the C code. For example: - -.. code-block:: Nim - var - EACCES {.importc, noDecl.}: cint # pretend EACCES was a variable, as - # Nim does not know its value - -However, the ``header`` pragma is often the better alternative. - -**Note**: This will not work for the LLVM backend. - - -Header pragma -------------- -The ``header`` pragma is very similar to the ``noDecl`` pragma: It can be -applied to almost any symbol and specifies that it should not be declared -and instead the generated code should contain an ``#include``: - -.. code-block:: Nim - type - PFile {.importc: "FILE*", header: "".} = distinct pointer - # import C's FILE* type; Nim will treat it as a new pointer type - -The ``header`` pragma always expects a string constant. The string contant -contains the header file: As usual for C, a system header file is enclosed -in angle brackets: ``<>``. If no angle brackets are given, Nim -encloses the header file in ``""`` in the generated C code. - -**Note**: This will not work for the LLVM backend. - - -IncompleteStruct pragma ------------------------ -The ``incompleteStruct`` pragma tells the compiler to not use the -underlying C ``struct`` in a ``sizeof`` expression: - -.. code-block:: Nim - type - DIR* {.importc: "DIR", header: "", - final, pure, incompleteStruct.} = object - - -Compile pragma --------------- -The ``compile`` pragma can be used to compile and link a C/C++ source file -with the project: - -.. code-block:: Nim - {.compile: "myfile.cpp".} - -**Note**: Nim computes a CRC checksum and only recompiles the file if it -has changed. You can use the ``-f`` command line option to force recompilation -of the file. - - -Link pragma ------------ -The ``link`` pragma can be used to link an additional file with the project: - -.. code-block:: Nim - {.link: "myfile.o".} - - + + +Additional Features +=================== + +This section describes Nim's additional features that are not listed in the +Nim manual. Some of the features here only make sense for the C code +generator and are subject to change. + + +NoDecl pragma +------------- +The ``noDecl`` pragma can be applied to almost any symbol (variable, proc, +type, etc.) and is sometimes useful for interoperability with C: +It tells Nim that it should not generate a declaration for the symbol in +the C code. For example: + +.. code-block:: Nim + var + EACCES {.importc, noDecl.}: cint # pretend EACCES was a variable, as + # Nim does not know its value + +However, the ``header`` pragma is often the better alternative. + +**Note**: This will not work for the LLVM backend. + + +Header pragma +------------- +The ``header`` pragma is very similar to the ``noDecl`` pragma: It can be +applied to almost any symbol and specifies that it should not be declared +and instead the generated code should contain an ``#include``: + +.. code-block:: Nim + type + PFile {.importc: "FILE*", header: "".} = distinct pointer + # import C's FILE* type; Nim will treat it as a new pointer type + +The ``header`` pragma always expects a string constant. The string contant +contains the header file: As usual for C, a system header file is enclosed +in angle brackets: ``<>``. If no angle brackets are given, Nim +encloses the header file in ``""`` in the generated C code. + +**Note**: This will not work for the LLVM backend. + + +IncompleteStruct pragma +----------------------- +The ``incompleteStruct`` pragma tells the compiler to not use the +underlying C ``struct`` in a ``sizeof`` expression: + +.. code-block:: Nim + type + DIR* {.importc: "DIR", header: "", + final, pure, incompleteStruct.} = object + + +Compile pragma +-------------- +The ``compile`` pragma can be used to compile and link a C/C++ source file +with the project: + +.. code-block:: Nim + {.compile: "myfile.cpp".} + +**Note**: Nim computes a CRC checksum and only recompiles the file if it +has changed. You can use the ``-f`` command line option to force recompilation +of the file. + + +Link pragma +----------- +The ``link`` pragma can be used to link an additional file with the project: + +.. code-block:: Nim + {.link: "myfile.o".} + + PassC pragma ------------ The ``passC`` pragma can be used to pass additional parameters to the C @@ -365,76 +360,76 @@ embed parameters from an external command at compile time: {.passL: gorge("pkg-config --libs sdl").} -Emit pragma ------------ -The ``emit`` pragma can be used to directly affect the output of the -compiler's code generator. So it makes your code unportable to other code -generators/backends. Its usage is highly discouraged! However, it can be -extremely useful for interfacing with `C++`:idx: or `Objective C`:idx: code. - -Example: - -.. code-block:: Nim - {.emit: """ - static int cvariable = 420; - """.} - +Emit pragma +----------- +The ``emit`` pragma can be used to directly affect the output of the +compiler's code generator. So it makes your code unportable to other code +generators/backends. Its usage is highly discouraged! However, it can be +extremely useful for interfacing with `C++`:idx: or `Objective C`:idx: code. + +Example: + +.. code-block:: Nim + {.emit: """ + static int cvariable = 420; + """.} + {.push stackTrace:off.} - proc embedsC() = - var nimVar = 89 - # use backticks to access Nim symbols within an emit section: - {.emit: """fprintf(stdout, "%d\n", cvariable + (int)`nimVar`);""".} + proc embedsC() = + var nimVar = 89 + # use backticks to access Nim symbols within an emit section: + {.emit: """fprintf(stdout, "%d\n", cvariable + (int)`nimVar`);""".} {.pop.} - - embedsC() + + embedsC() As can be seen from the example, to Nim symbols can be referred via backticks. Use two backticks to produce a single verbatim backtick. - -ImportCpp pragma + +ImportCpp pragma ---------------- **Note**: `c2nim `_ can parse a large subset of C++ and knows about the ``importcpp`` pragma pattern language. It is not necessary to know all the details described here. - + Similar to the `importc pragma for C `_, the ``importcpp`` pragma can be used to import `C++`:idx: methods or C++ symbols -in general. The generated code then uses the C++ method calling +in general. The generated code then uses the C++ method calling syntax: ``obj->method(arg)``. In combination with the ``header`` and ``emit`` pragmas this allows *sloppy* interfacing with libraries written in C++: - -.. code-block:: Nim - # Horrible example of how to interface with a C++ engine ... ;-) - - {.link: "/usr/lib/libIrrlicht.so".} - - {.emit: """ - using namespace irr; - using namespace core; - using namespace scene; - using namespace video; - using namespace io; - using namespace gui; - """.} - - const - irr = "" - - type + +.. code-block:: Nim + # Horrible example of how to interface with a C++ engine ... ;-) + + {.link: "/usr/lib/libIrrlicht.so".} + + {.emit: """ + using namespace irr; + using namespace core; + using namespace scene; + using namespace video; + using namespace io; + using namespace gui; + """.} + + const + irr = "" + + type IrrlichtDeviceObj {.final, header: irr, - importcpp: "IrrlichtDevice".} = object - IrrlichtDevice = ptr IrrlichtDeviceObj - - proc createDevice(): IrrlichtDevice {. - header: irr, importcpp: "createDevice(@)".} - proc run(device: IrrlichtDevice): bool {. + importcpp: "IrrlichtDevice".} = object + IrrlichtDevice = ptr IrrlichtDeviceObj + + proc createDevice(): IrrlichtDevice {. + header: irr, importcpp: "createDevice(@)".} + proc run(device: IrrlichtDevice): bool {. header: irr, importcpp: "#.run(@)".} - -The compiler needs to be told to generate C++ (command ``cpp``) for -this to work. The conditional symbol ``cpp`` is defined when the compiler + +The compiler needs to be told to generate C++ (command ``cpp``) for +this to work. The conditional symbol ``cpp`` is defined when the compiler emits C++ code. @@ -446,9 +441,9 @@ declarations. It is usually much better to instead refer to the imported name via the ``namespace::identifier`` notation: .. code-block:: nim - type + type IrrlichtDeviceObj {.final, header: irr, - importcpp: "irr::IrrlichtDevice".} = object + importcpp: "irr::IrrlichtDevice".} = object Importcpp for enums @@ -586,61 +581,61 @@ Produces: std::map x; x[6] = 91.4; - -ImportObjC pragma ------------------ + +ImportObjC pragma +----------------- Similar to the `importc pragma for C `_, the ``importobjc`` pragma can be used to import `Objective C`:idx: methods. The generated code then uses the Objective C method calling syntax: ``[obj method param1: arg]``. In addition with the ``header`` and ``emit`` pragmas this allows *sloppy* interfacing with libraries written in Objective C: - -.. code-block:: Nim - # horrible example of how to interface with GNUStep ... - - {.passL: "-lobjc".} - {.emit: """ - #include - @interface Greeter:Object - { - } - - - (void)greet:(long)x y:(long)dummy; - @end - - #include - @implementation Greeter - - - (void)greet:(long)x y:(long)dummy - { - printf("Hello, World!\n"); - } - @end - - #include - """.} - - type - Id {.importc: "id", header: "", final.} = distinct int - - proc newGreeter: Id {.importobjc: "Greeter new", nodecl.} - proc greet(self: Id, x, y: int) {.importobjc: "greet", nodecl.} - proc free(self: Id) {.importobjc: "free", nodecl.} - - var g = newGreeter() - g.greet(12, 34) - g.free() - -The compiler needs to be told to generate Objective C (command ``objc``) for -this to work. The conditional symbol ``objc`` is defined when the compiler -emits Objective C code. + +.. code-block:: Nim + # horrible example of how to interface with GNUStep ... + + {.passL: "-lobjc".} + {.emit: """ + #include + @interface Greeter:Object + { + } + + - (void)greet:(long)x y:(long)dummy; + @end + + #include + @implementation Greeter + + - (void)greet:(long)x y:(long)dummy + { + printf("Hello, World!\n"); + } + @end + + #include + """.} + + type + Id {.importc: "id", header: "", final.} = distinct int + + proc newGreeter: Id {.importobjc: "Greeter new", nodecl.} + proc greet(self: Id, x, y: int) {.importobjc: "greet", nodecl.} + proc free(self: Id) {.importobjc: "free", nodecl.} + + var g = newGreeter() + g.greet(12, 34) + g.free() + +The compiler needs to be told to generate Objective C (command ``objc``) for +this to work. The conditional symbol ``objc`` is defined when the compiler +emits Objective C code. CodegenDecl pragma ------------------ The ``codegenDecl`` pragma can be used to directly influence Nim's code -generator. It receives a format string that determines how the variable or +generator. It receives a format string that determines how the variable or proc is declared in the generated code: .. code-block:: nim @@ -660,56 +655,56 @@ debugging: .. code-block:: nim {.injectStmt: gcInvariants().} - + # ... complex code here that produces crashes ... - - -LineDir option --------------- -The ``lineDir`` option can be turned on or off. If turned on the -generated C code contains ``#line`` directives. This may be helpful for -debugging with GDB. - - -StackTrace option ------------------ -If the ``stackTrace`` option is turned on, the generated C contains code to -ensure that proper stack traces are given if the program crashes or an -uncaught exception is raised. - - -LineTrace option ----------------- -The ``lineTrace`` option implies the ``stackTrace`` option. If turned on, -the generated C contains code to ensure that proper stack traces with line -number information are given if the program crashes or an uncaught exception -is raised. - -Debugger option ---------------- -The ``debugger`` option enables or disables the *Embedded Nim Debugger*. -See the documentation of endb_ for further information. - - -Breakpoint pragma ------------------ -The *breakpoint* pragma was specially added for the sake of debugging with -ENDB. See the documentation of `endb `_ for further information. - - -Volatile pragma ---------------- -The ``volatile`` pragma is for variables only. It declares the variable as -``volatile``, whatever that means in C/C++ (its semantics are not well defined -in C/C++). - -**Note**: This pragma will not exist for the LLVM backend. + + +LineDir option +-------------- +The ``lineDir`` option can be turned on or off. If turned on the +generated C code contains ``#line`` directives. This may be helpful for +debugging with GDB. + + +StackTrace option +----------------- +If the ``stackTrace`` option is turned on, the generated C contains code to +ensure that proper stack traces are given if the program crashes or an +uncaught exception is raised. + + +LineTrace option +---------------- +The ``lineTrace`` option implies the ``stackTrace`` option. If turned on, +the generated C contains code to ensure that proper stack traces with line +number information are given if the program crashes or an uncaught exception +is raised. + +Debugger option +--------------- +The ``debugger`` option enables or disables the *Embedded Nim Debugger*. +See the documentation of endb_ for further information. + + +Breakpoint pragma +----------------- +The *breakpoint* pragma was specially added for the sake of debugging with +ENDB. See the documentation of `endb `_ for further information. + + +Volatile pragma +--------------- +The ``volatile`` pragma is for variables only. It declares the variable as +``volatile``, whatever that means in C/C++ (its semantics are not well defined +in C/C++). + +**Note**: This pragma will not exist for the LLVM backend. DynlibOverride ============== -By default Nim's ``dynlib`` pragma causes the compiler to generate +By default Nim's ``dynlib`` pragma causes the compiler to generate ``GetProcAddress`` (or their Unix counterparts) calls to bind to a DLL. With the ``dynlibOverride`` command line switch this can be prevented and then via ``--passL`` the static library can be linked @@ -736,28 +731,28 @@ Nim provides the `doc`:idx: and `doc2`:idx: commands to generate HTML documentation from ``.nim`` source files. Only exported symbols will appear in the output. For more details `see the docgen documentation `_. -Nim idetools integration -======================== - -Nim provides language integration with external IDEs through the -idetools command. See the documentation of `idetools `_ -for further information. - - -Nim interactive mode -==================== - -The Nim compiler supports an interactive mode. This is also known as -a `REPL`:idx: (*read eval print loop*). If Nim has been built with the -``-d:useGnuReadline`` switch, it uses the GNU readline library for terminal -input management. To start Nim in interactive mode use the command -``nim i``. To quit use the ``quit()`` command. To determine whether an input -line is an incomplete statement to be continued these rules are used: - -1. The line ends with ``[-+*/\\<>!\?\|%&$@~,;:=#^]\s*$`` (operator symbol followed by optional whitespace). -2. The line starts with a space (indentation). -3. The line is within a triple quoted string literal. However, the detection - does not work if the line contains more than one ``"""``. +Nim idetools integration +======================== + +Nim provides language integration with external IDEs through the +idetools command. See the documentation of `idetools `_ +for further information. + + +Nim interactive mode +==================== + +The Nim compiler supports an interactive mode. This is also known as +a `REPL`:idx: (*read eval print loop*). If Nim has been built with the +``-d:useGnuReadline`` switch, it uses the GNU readline library for terminal +input management. To start Nim in interactive mode use the command +``nim i``. To quit use the ``quit()`` command. To determine whether an input +line is an incomplete statement to be continued these rules are used: + +1. The line ends with ``[-+*/\\<>!\?\|%&$@~,;:=#^]\s*$`` (operator symbol followed by optional whitespace). +2. The line starts with a space (indentation). +3. The line is within a triple quoted string literal. However, the detection + does not work if the line contains more than one ``"""``. Nim for embedded systems @@ -768,107 +763,107 @@ for 16bit micro controllers is feasible. Use the `standalone`:idx: target (``--os:standalone``) for a bare bones standard library that lacks any OS features. -To make the compiler output code for a 16bit target use the ``--cpu:avr`` +To make the compiler output code for a 16bit target use the ``--cpu:avr`` target. For example, to generate code for an `AVR`:idx: processor use this command:: - + nim c --cpu:avr --os:standalone --deadCodeElim:on --genScript x.nim For the ``standalone`` target one needs to provide a file ``panicoverride.nim``. See ``tests/manyloc/standalone/panicoverride.nim`` for an example implementation. - + Nim for realtime systems ======================== -See the documentation of Nim's soft realtime `GC `_ for further +See the documentation of Nim's soft realtime `GC `_ for further information. - -Debugging with Nim -================== - -Nim comes with its own *Embedded Nim Debugger*. See -the documentation of endb_ for further information. - - -Optimizing for Nim -================== - -Nim has no separate optimizer, but the C code that is produced is very -efficient. Most C compilers have excellent optimizers, so usually it is -not needed to optimize one's code. Nim has been designed to encourage -efficient code: The most readable code in Nim is often the most efficient -too. - -However, sometimes one has to optimize. Do it in the following order: - -1. switch off the embedded debugger (it is **slow**!) -2. turn on the optimizer and turn off runtime checks -3. profile your code to find where the bottlenecks are -4. try to find a better algorithm -5. do low-level optimizations - -This section can only help you with the last item. - - -Optimizing string handling --------------------------- - -String assignments are sometimes expensive in Nim: They are required to -copy the whole string. However, the compiler is often smart enough to not copy -strings. Due to the argument passing semantics, strings are never copied when -passed to subroutines. The compiler does not copy strings that are a result from -a procedure call, because the callee returns a new string anyway. -Thus it is efficient to do: - -.. code-block:: Nim - var s = procA() # assignment will not copy the string; procA allocates a new - # string already - -However it is not efficient to do: - -.. code-block:: Nim - var s = varA # assignment has to copy the whole string into a new buffer! - -For ``let`` symbols a copy is not always necessary: - -.. code-block:: Nim - let s = varA # may only copy a pointer if it safe to do so - - -If you know what you're doing, you can also mark single string (or sequence) -objects as `shallow`:idx:\: - -.. code-block:: Nim - var s = "abc" - shallow(s) # mark 's' as shallow string - var x = s # now might not copy the string! - -Usage of ``shallow`` is always safe once you know the string won't be modified -anymore, similar to Ruby's `freeze`:idx:. - - -The compiler optimizes string case statements: A hashing scheme is used for them -if several different string constants are used. So code like this is reasonably -efficient: - -.. code-block:: Nim - case normalize(k.key) - of "name": c.name = v - of "displayname": c.displayName = v - of "version": c.version = v - of "os": c.oses = split(v, {';'}) - of "cpu": c.cpus = split(v, {';'}) - of "authors": c.authors = split(v, {';'}) - of "description": c.description = v - of "app": - case normalize(v) - of "console": c.app = appConsole - of "gui": c.app = appGUI - else: quit(errorStr(p, "expected: console or gui")) - of "license": c.license = UnixToNativePath(k.value) - else: quit(errorStr(p, "unknown variable: " & k.key)) + +Debugging with Nim +================== + +Nim comes with its own *Embedded Nim Debugger*. See +the documentation of endb_ for further information. + + +Optimizing for Nim +================== + +Nim has no separate optimizer, but the C code that is produced is very +efficient. Most C compilers have excellent optimizers, so usually it is +not needed to optimize one's code. Nim has been designed to encourage +efficient code: The most readable code in Nim is often the most efficient +too. + +However, sometimes one has to optimize. Do it in the following order: + +1. switch off the embedded debugger (it is **slow**!) +2. turn on the optimizer and turn off runtime checks +3. profile your code to find where the bottlenecks are +4. try to find a better algorithm +5. do low-level optimizations + +This section can only help you with the last item. + + +Optimizing string handling +-------------------------- + +String assignments are sometimes expensive in Nim: They are required to +copy the whole string. However, the compiler is often smart enough to not copy +strings. Due to the argument passing semantics, strings are never copied when +passed to subroutines. The compiler does not copy strings that are a result from +a procedure call, because the callee returns a new string anyway. +Thus it is efficient to do: + +.. code-block:: Nim + var s = procA() # assignment will not copy the string; procA allocates a new + # string already + +However it is not efficient to do: + +.. code-block:: Nim + var s = varA # assignment has to copy the whole string into a new buffer! + +For ``let`` symbols a copy is not always necessary: + +.. code-block:: Nim + let s = varA # may only copy a pointer if it safe to do so + + +If you know what you're doing, you can also mark single string (or sequence) +objects as `shallow`:idx:\: + +.. code-block:: Nim + var s = "abc" + shallow(s) # mark 's' as shallow string + var x = s # now might not copy the string! + +Usage of ``shallow`` is always safe once you know the string won't be modified +anymore, similar to Ruby's `freeze`:idx:. + + +The compiler optimizes string case statements: A hashing scheme is used for them +if several different string constants are used. So code like this is reasonably +efficient: + +.. code-block:: Nim + case normalize(k.key) + of "name": c.name = v + of "displayname": c.displayName = v + of "version": c.version = v + of "os": c.oses = split(v, {';'}) + of "cpu": c.cpus = split(v, {';'}) + of "authors": c.authors = split(v, {';'}) + of "description": c.description = v + of "app": + case normalize(v) + of "console": c.app = appConsole + of "gui": c.app = appGUI + else: quit(errorStr(p, "expected: console or gui")) + of "license": c.license = UnixToNativePath(k.value) + else: quit(errorStr(p, "unknown variable: " & k.key)) diff --git a/todo.txt b/todo.txt index 15521eae13..408bfefe5c 100644 --- a/todo.txt +++ b/todo.txt @@ -4,6 +4,7 @@ version 0.10.4 - improve GC-unsafety warnings - make 'nil' work for 'add' and 'len' - get rid of 'mget'; aka priority of 'var' needs to be 'var{lvalue}' +- 'result' shadowing warning version 1.0 From c44d947ac55b46425d25a5355416fbb39adbdb87 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 12 Feb 2015 17:32:35 +0100 Subject: [PATCH 315/850] 'auto' can be inferred to be 'void' --- compiler/semexprs.nim | 7 ++++++- tests/types/tauto_canbe_void.nim | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 tests/types/tauto_canbe_void.nim diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 55d2656e0f..dc02f6e069 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1337,7 +1337,12 @@ proc semProcBody(c: PContext, n: PNode): PNode = if c.p.owner.kind notin {skMacro, skTemplate} and c.p.resultSym != nil and c.p.resultSym.typ.isMetaType: - localError(c.p.resultSym.info, errCannotInferReturnType) + if isEmptyType(result.typ): + # we inferred a 'void' return type: + c.p.resultSym.typ = nil + c.p.owner.typ.sons[0] = nil + else: + localError(c.p.resultSym.info, errCannotInferReturnType) closeScope(c) diff --git a/tests/types/tauto_canbe_void.nim b/tests/types/tauto_canbe_void.nim new file mode 100644 index 0000000000..60e83c510d --- /dev/null +++ b/tests/types/tauto_canbe_void.nim @@ -0,0 +1,9 @@ + +import future + +template tempo(s: expr) = + s("arg") + +tempo((s: string)->auto => echo(s)) +tempo((s: string) => echo(s)) + From b226618ce78443d3001d8f5f80b3225a6ad6485d Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 13 Feb 2015 01:21:43 +0100 Subject: [PATCH 316/850] 'passL' is not smart anymore about already known switches; -ldl is now properly appended to the linking command --- compiler/extccomp.nim | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 1083b75903..546849c0b8 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -380,7 +380,7 @@ proc setCC*(ccname: string) = cCompiler = nameToCC(ccname) if cCompiler == ccNone: rawMessage(errUnknownCcompiler, ccname) compileOptions = getConfigVar(cCompiler, ".options.always") - linkOptions = getConfigVar(cCompiler, ".options.linker") + linkOptions = "" ccompilerpath = getConfigVar(cCompiler, ".path") for i in countup(low(CC), high(CC)): undefSymbol(CC[i].name) defineSymbol(CC[cCompiler].name) @@ -389,8 +389,8 @@ proc addOpt(dest: var string, src: string) = if len(dest) == 0 or dest[len(dest)-1] != ' ': add(dest, " ") add(dest, src) -proc addLinkOption*(option: string) = - if find(linkOptions, option, 0) < 0: addOpt(linkOptions, option) +proc addLinkOption*(option: string) = + addOpt(linkOptions, option) proc addCompileOption*(option: string) = if strutils.find(compileOptions, option, 0) < 0: @@ -401,7 +401,7 @@ proc initVars*() = for i in countup(low(CC), high(CC)): undefSymbol(CC[i].name) defineSymbol(CC[cCompiler].name) addCompileOption(getConfigVar(cCompiler, ".options.always")) - addLinkOption(getConfigVar(cCompiler, ".options.linker")) + #addLinkOption(getConfigVar(cCompiler, ".options.linker")) if len(ccompilerpath) == 0: ccompilerpath = getConfigVar(cCompiler, ".path") @@ -553,13 +553,13 @@ proc getCompileCFileCmd*(cfilename: string, isExternal = false): string = cfile = quoteShell(cfile) result = quoteShell(compilePattern % [ "file", cfile, "objfile", objfile, "options", options, - "include", includeCmd, "nimrod", getPrefixDir(), + "include", includeCmd, "nim", getPrefixDir(), "nim", getPrefixDir(), "lib", libpath]) add(result, ' ') addf(result, CC[c].compileTmpl, [ "file", cfile, "objfile", objfile, "options", options, "include", includeCmd, - "nimrod", quoteShell(getPrefixDir()), + "nim", quoteShell(getPrefixDir()), "nim", quoteShell(getPrefixDir()), "lib", quoteShell(libpath)]) @@ -679,15 +679,16 @@ proc callCCompiler*(projectfile: string) = if not exefile.isAbsolute(): exefile = joinPath(splitFile(projectfile).dir, exefile) exefile = quoteShell(exefile) - let linkOptions = getLinkOptions() + let linkOptions = getLinkOptions() & " " & + getConfigVar(cCompiler, ".options.linker") linkCmd = quoteShell(linkCmd % ["builddll", builddll, "buildgui", buildgui, "options", linkOptions, "objfiles", objfiles, - "exefile", exefile, "nimrod", getPrefixDir(), "lib", libpath]) + "exefile", exefile, "nim", getPrefixDir(), "lib", libpath]) linkCmd.add ' ' addf(linkCmd, CC[c].linkTmpl, ["builddll", builddll, "buildgui", buildgui, "options", linkOptions, "objfiles", objfiles, "exefile", exefile, - "nimrod", quoteShell(getPrefixDir()), + "nim", quoteShell(getPrefixDir()), "lib", quoteShell(libpath)]) if optCompileOnly notin gGlobalOptions: if gVerbosity == 1: @@ -716,7 +717,8 @@ proc writeMapping*(gSymbolMapping: PRope) = app(code, strutils.escape(getCompileOptions())) app(code, "\n[Linker]\nFlags=") - app(code, strutils.escape(getLinkOptions())) + app(code, strutils.escape(getLinkOptions() & " " & + getConfigVar(cCompiler, ".options.linker"))) app(code, "\n[Environment]\nlibpath=") app(code, strutils.escape(libpath)) From fde16e6c3eb6c441a7751acccea83588d08e7d65 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 13 Feb 2015 01:39:20 +0100 Subject: [PATCH 317/850] fixes os.moveFile on Windows --- build.sh | 0 lib/pure/os.nim | 12 ++++++++++-- lib/windows/winlean.nim | 8 ++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) mode change 100755 => 100644 build.sh diff --git a/build.sh b/build.sh old mode 100755 new mode 100644 diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 14cbe07bbf..820800a1a7 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -1010,8 +1010,16 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", proc moveFile*(source, dest: string) {.rtl, extern: "nos$1", tags: [ReadIOEffect, WriteIOEffect].} = ## Moves a file from `source` to `dest`. If this fails, `OSError` is raised. - if c_rename(source, dest) != 0'i32: - raise newException(OSError, $strerror(errno)) + when defined(Windows): + when useWinUnicode: + let s = newWideCString(source) + let d = newWideCString(dest) + if moveFileW(s, d, 0'i32) == 0'i32: raiseOSError(osLastError()) + else: + if moveFileA(source, dest, 0'i32) == 0'i32: raiseOSError(osLastError()) + else: + if c_rename(source, dest) != 0'i32: + raise newException(OSError, $strerror(errno)) when not declared(ENOENT) and not defined(Windows): when NoFakeVars: diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 51a12141b1..584f7cf482 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -284,6 +284,10 @@ when useWinUnicode: bFailIfExists: cint): cint {. importc: "CopyFileW", stdcall, dynlib: "kernel32".} + proc moveFileW*(lpExistingFileName, lpNewFileName: WideCString, + bFailIfExists: cint): cint {. + importc: "MoveFileW", stdcall, dynlib: "kernel32".} + proc getEnvironmentStringsW*(): WideCString {. stdcall, dynlib: "kernel32", importc: "GetEnvironmentStringsW".} proc freeEnvironmentStringsW*(para1: WideCString): int32 {. @@ -308,6 +312,10 @@ else: bFailIfExists: cint): cint {. importc: "CopyFileA", stdcall, dynlib: "kernel32".} + proc moveFileA*(lpExistingFileName, lpNewFileName: cstring, + bFailIfExists: cint): cint {. + importc: "MoveFileA", stdcall, dynlib: "kernel32".} + proc getEnvironmentStringsA*(): cstring {. stdcall, dynlib: "kernel32", importc: "GetEnvironmentStringsA".} proc freeEnvironmentStringsA*(para1: cstring): int32 {. From 6eb8867f1af64e28a71fc54e2f3bd3ff16e715e1 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 13 Feb 2015 01:40:29 +0100 Subject: [PATCH 318/850] fixes #2116 --- lib/posix/posix.nim | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index fbd07ca25e..52bef6de4b 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -70,17 +70,10 @@ const STDIN_FILENO* = 0 ## File number of stdin; STDOUT_FILENO* = 1 ## File number of stdout; -when defined(endb): - # to not break bootstrapping again ... - type - TDIR* {.importc: "DIR", header: "", - final, pure, incompleteStruct.} = object - ## A type representing a directory stream. -else: - type - TDIR* {.importc: "DIR", header: "", - final, pure.} = object - ## A type representing a directory stream. +type + TDIR* {.importc: "DIR", header: "", + incompleteStruct.} = object + ## A type representing a directory stream. type SocketHandle* = distinct cint # The type used to represent socket descriptors From 55ab6cc2b37491d397d7f207a759b48882db6d6d Mon Sep 17 00:00:00 2001 From: Hans Raaf Date: Fri, 13 Feb 2015 00:10:24 +0100 Subject: [PATCH 319/850] Disable -pthread for linker on OSX The -pthread is not needed on Darwin/OS X and the Apple compilers give a warning about this if you use --threads:on with the Nim compiler. --- lib/system/threads.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/system/threads.nim b/lib/system/threads.nim index 496c31af14..4e07200072 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -95,7 +95,9 @@ when defined(windows): importc: "TlsGetValue", stdcall, dynlib: "kernel32".} else: - {.passL: "-pthread".} + when not defined(macosx): + {.passL: "-pthread".} + {.passC: "-pthread".} type From 4876aabb39bb4b488a9584684806c4b25aa04006 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 13 Feb 2015 02:08:45 +0100 Subject: [PATCH 320/850] fixes #2113 --- compiler/semexprs.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index dc02f6e069..10e17d59a2 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -686,7 +686,9 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode = # implicit statics. if n.len > 1: for i in 1 .. Date: Fri, 13 Feb 2015 10:09:57 +0100 Subject: [PATCH 321/850] fixes #2118 --- compiler/ccgexprs.nim | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 9b45c44925..6ed4d361c2 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -2107,17 +2107,13 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = discard of nkPragma: genPragma(p, n) of nkPragmaBlock: expr(p, n.lastSon, d) - of nkProcDef, nkMethodDef, nkConverterDef: - if (n.sons[genericParamsPos].kind == nkEmpty): + of nkProcDef, nkMethodDef, nkConverterDef: + if n.sons[genericParamsPos].kind == nkEmpty: var prc = n.sons[namePos].sym # due to a bug/limitation in the lambda lifting, unused inner procs # are not transformed correctly. We work around this issue (#411) here # by ensuring it's no inner proc (owner is a module): - # - # We also check whether the proc captures its environment here to - # prevent issue #1642. - if prc.skipGenericOwner.kind == skModule and - tfCapturesEnv in prc.typ.flags: + if prc.skipGenericOwner.kind == skModule: if (optDeadCodeElim notin gGlobalOptions and sfDeadCodeElim notin getModule(prc).flags) or ({sfExportc, sfCompilerProc} * prc.flags == {sfExportc}) or From e8acaa449bffef964fcbdbddd365cd6073e74501 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 13 Feb 2015 10:27:23 +0100 Subject: [PATCH 322/850] fixes #2102 --- compiler/commands.nim | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/commands.nim b/compiler/commands.nim index c81b81d191..c52515c76e 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -141,7 +141,7 @@ proc expectNoArg(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) = if arg != "": localError(info, errCmdLineNoArgExpected, addPrefix(switch)) proc processSpecificNote(arg: string, state: TSpecialWord, pass: TCmdLinePass, - info: TLineInfo) = + info: TLineInfo; orig: string) = var id = "" # arg = "X]:on|off" var i = 0 var n = hintMin @@ -149,17 +149,17 @@ proc processSpecificNote(arg: string, state: TSpecialWord, pass: TCmdLinePass, add(id, arg[i]) inc(i) if i < len(arg) and (arg[i] == ']'): inc(i) - else: invalidCmdLineOption(pass, arg, info) + else: invalidCmdLineOption(pass, orig, info) if i < len(arg) and (arg[i] in {':', '='}): inc(i) - else: invalidCmdLineOption(pass, arg, info) - if state == wHint: + else: invalidCmdLineOption(pass, orig, info) + if state == wHint: var x = findStr(msgs.HintsToStr, id) if x >= 0: n = TNoteKind(x + ord(hintMin)) - else: invalidCmdLineOption(pass, arg, info) - else: + else: localError(info, "unknown hint: " & id) + else: var x = findStr(msgs.WarningsToStr, id) if x >= 0: n = TNoteKind(x + ord(warnMin)) - else: invalidCmdLineOption(pass, arg, info) + else: localError(info, "unknown warning: " & id) case whichKeyword(substr(arg, i)) of wOn: incl(gNotes, n) of wOff: excl(gNotes, n) @@ -368,8 +368,8 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) = defineSymbol("nogc") else: localError(info, errNoneBoehmRefcExpectedButXFound, arg) of "warnings", "w": processOnOffSwitch({optWarns}, arg, pass, info) - of "warning": processSpecificNote(arg, wWarning, pass, info) - of "hint": processSpecificNote(arg, wHint, pass, info) + of "warning": processSpecificNote(arg, wWarning, pass, info, switch) + of "hint": processSpecificNote(arg, wHint, pass, info, switch) of "hints": processOnOffSwitch({optHints}, arg, pass, info) of "threadanalysis": processOnOffSwitchG({optThreadAnalysis}, arg, pass, info) of "stacktrace": processOnOffSwitch({optStackTrace}, arg, pass, info) From 199707c189a169c4bf0b00f09775c9b7fa9343f3 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 13 Feb 2015 10:55:46 +0100 Subject: [PATCH 323/850] fixes #2103 --- config/nim.cfg | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/config/nim.cfg b/config/nim.cfg index 8f5d7e8e7a..ba0f4c581e 100644 --- a/config/nim.cfg +++ b/config/nim.cfg @@ -10,6 +10,12 @@ cc = gcc +# additional options always passed to the compiler: +--parallel_build: "0" # 0 to auto-detect number of processors + +hint[LineTooLong]=off +#hint[XDeclaredButNotUsed]=off + # example of how to setup a cross-compiler: arm.linux.gcc.exe = "arm-linux-gcc" arm.linux.gcc.linkerexe = "arm-linux-gcc" @@ -66,12 +72,6 @@ path="$lib/pure/unidecode" opt:speed @end -# additional options always passed to the compiler: ---parallel_build: "0" # 0 to auto-detect number of processors - -hint[LineTooLong]=off -#hint[XDeclaredButNotUsed]=off - @if unix: @if not bsd: # -fopenmp From d129e8f6c6b6b39ed76b2e71f0179a1eb6171f1d Mon Sep 17 00:00:00 2001 From: Charles Blake Date: Fri, 13 Feb 2015 08:28:58 -0500 Subject: [PATCH 324/850] Update doc comments to mention rightSize. --- lib/pure/collections/sets.nim | 12 ++++++------ lib/pure/collections/tables.nim | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim index 33fec1a186..c25161ed0a 100644 --- a/lib/pure/collections/sets.nim +++ b/lib/pure/collections/sets.nim @@ -313,9 +313,9 @@ proc init*[A](s: var HashSet[A], initialSize=64) = ## Initializes a hash set. ## ## The `initialSize` parameter needs to be a power of two. You can use - ## `math.nextPowerOfTwo() `_ to guarantee that at - ## runtime. All set variables have to be initialized before you can use them - ## with other procs from this module with the exception of `isValid() + ## `math.nextPowerOfTwo() `_ or `rightSize` to + ## guarantee that at runtime. All set variables must be initialized before + ## use with other procs from this module with the exception of `isValid() ## <#isValid,TSet[A]>`_ and `len() <#len,TSet[A]>`_. ## ## You can call this proc on a previously initialized hash set, which will @@ -719,9 +719,9 @@ proc init*[A](s: var OrderedSet[A], initialSize=64) = ## Initializes an ordered hash set. ## ## The `initialSize` parameter needs to be a power of two. You can use - ## `math.nextPowerOfTwo() `_ to guarantee that at - ## runtime. All set variables have to be initialized before you can use them - ## with other procs from this module with the exception of `isValid() + ## `math.nextPowerOfTwo() `_ or `rightSize` to + ## guarantee that at runtime. All set variables must be initialized before + ## use with other procs from this module with the exception of `isValid() ## <#isValid,TOrderedSet[A]>`_ and `len() <#len,TOrderedSet[A]>`_. ## ## You can call this proc on a previously initialized ordered hash set to diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index 4858ca2b5a..7ed0e46cce 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -294,7 +294,7 @@ proc initTable*[A, B](initialSize=64): Table[A, B] = ## ## `initialSize` needs to be a power of two. If you need to accept runtime ## values for this you could use the ``nextPowerOfTwo`` proc from the - ## `math `_ module. + ## `math `_ module or the ``rightSize`` proc from this module. assert isPowerOfTwo(initialSize) result.counter = 0 newSeq(result.data, initialSize) @@ -544,7 +544,7 @@ proc initOrderedTable*[A, B](initialSize=64): OrderedTable[A, B] = ## ## `initialSize` needs to be a power of two. If you need to accept runtime ## values for this you could use the ``nextPowerOfTwo`` proc from the - ## `math `_ module. + ## `math `_ module or the ``rightSize`` proc from this module. assert isPowerOfTwo(initialSize) result.counter = 0 result.first = -1 @@ -675,7 +675,7 @@ proc newOrderedTable*[A, B](initialSize=64): OrderedTableRef[A, B] = ## ## `initialSize` needs to be a power of two. If you need to accept runtime ## values for this you could use the ``nextPowerOfTwo`` proc from the - ## `math `_ module. + ## `math `_ module or the ``rightSize`` proc from this module. new(result) result[] = initOrderedTable[A, B]() @@ -793,7 +793,7 @@ proc initCountTable*[A](initialSize=64): CountTable[A] = ## ## `initialSize` needs to be a power of two. If you need to accept runtime ## values for this you could use the ``nextPowerOfTwo`` proc from the - ## `math `_ module or the ``rightSize`` method in this module. + ## `math `_ module or the ``rightSize`` proc in this module. assert isPowerOfTwo(initialSize) result.counter = 0 newSeq(result.data, initialSize) From 0a1bc0e9cd30ef1a3654e7637795ed22010e7977 Mon Sep 17 00:00:00 2001 From: Charles Blake Date: Fri, 13 Feb 2015 08:33:15 -0500 Subject: [PATCH 325/850] Update a use of initTable to avoid initial enlarge. --- tests/manyloc/argument_parser/argument_parser.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/manyloc/argument_parser/argument_parser.nim b/tests/manyloc/argument_parser/argument_parser.nim index af671cd852..a507a08e40 100644 --- a/tests/manyloc/argument_parser/argument_parser.nim +++ b/tests/manyloc/argument_parser/argument_parser.nim @@ -302,7 +302,7 @@ template build_specification_lookup(): ## Returns the table used to keep pointers to all of the specifications. var result {.gensym.}: OrderedTable[string, ptr Tparameter_specification] result = initOrderedTable[string, ptr Tparameter_specification]( - nextPowerOfTwo(expected.len)) + tables.rightSize(expected.len)) for i in 0..expected.len-1: for param_to_detect in expected[i].names: if result.hasKey(param_to_detect): From 39b98fede3d982c8599c9ed80f1df1d56a4bcf18 Mon Sep 17 00:00:00 2001 From: Charles Blake Date: Fri, 13 Feb 2015 08:50:26 -0500 Subject: [PATCH 326/850] New probe seq swaps 1st two keys. Fix in cmp. --- tests/collections/ttables.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/collections/ttables.nim b/tests/collections/ttables.nim index de4aaed5eb..8534e6767d 100644 --- a/tests/collections/ttables.nim +++ b/tests/collections/ttables.nim @@ -47,7 +47,7 @@ block tableTest1: for y in 0..1: assert t[(x,y)] == $x & $y assert($t == - "{(x: 0, y: 0): 00, (x: 0, y: 1): 01, (x: 1, y: 0): 10, (x: 1, y: 1): 11}") + "{(x: 0, y: 1): 01, (x: 0, y: 0): 00, (x: 1, y: 0): 10, (x: 1, y: 1): 11}") block tableTest2: var t = initTable[string, float]() From 5068a5aa016fef0b65c7cd6af27eeeefda0e5c95 Mon Sep 17 00:00:00 2001 From: Charles Blake Date: Fri, 13 Feb 2015 14:10:09 -0500 Subject: [PATCH 327/850] assignment -> shallowCopy for efficiency. --- lib/pure/collections/sets.nim | 2 +- lib/pure/collections/tables.nim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim index c25161ed0a..4a20d00a46 100644 --- a/lib/pure/collections/sets.nim +++ b/lib/pure/collections/sets.nim @@ -276,7 +276,7 @@ proc excl*[A](s: var HashSet[A], key: A) = if isEmpty(s.data[i].hcode): # end of collision cluster; So all done return r = s.data[i].hcode and msk # "home" location of key@i - s.data[j] = s.data[i] # data[j] will be marked EMPTY next loop + shallowCopy(s.data[j], s.data[i]) # data[j] will be marked EMPTY next loop proc excl*[A](s: var HashSet[A], other: HashSet[A]) = ## Excludes everything in `other` from `s`. diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index 58305b010b..25fe306c07 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -287,7 +287,7 @@ proc del*[A, B](t: var Table[A, B], key: A) = if isEmpty(t.data[i].hcode): # end of collision cluster; So all done return r = t.data[i].hcode and msk # "home" location of key@i - t.data[j] = t.data[i] # data[j] will be marked EMPTY next loop + shallowCopy(t.data[j], t.data[i]) # data[j] will be marked EMPTY next loop proc initTable*[A, B](initialSize=64): Table[A, B] = ## creates a new hash table that is empty. From f1aa0a745eb6ebd79e231ac2a8bd95b5054eed5a Mon Sep 17 00:00:00 2001 From: PhilipWitte Date: Fri, 13 Feb 2015 13:25:57 -0800 Subject: [PATCH 328/850] Revert docs & learn pages to RTF again --- web/assets/style.css | 14 +++++----- web/documentation.txt | 62 +++++++++++++++++------------------------ web/learn.txt | 64 ++++++++++++++++--------------------------- 3 files changed, 56 insertions(+), 84 deletions(-) diff --git a/web/assets/style.css b/web/assets/style.css index 5e2115ef13..04e7a17697 100644 --- a/web/assets/style.css +++ b/web/assets/style.css @@ -518,15 +518,15 @@ pre .end { background:url("images/tabEnd.png") no-repeat left bottom; } .standout h2 { margin-bottom:10px; padding-bottom:10px; border-bottom:1px dashed rgba(0,0,0,.8); } .standout li { margin:0 !important; padding-top:10px; border-top:1px dashed rgba(0,0,0,.2); } .standout ul { padding-bottom:5px; } - .standout ul.tools { list-style:url("images/docs-tools.png"); } - .standout ul.libraries { list-style:url("images/docs-libraries.png"); } - .standout ul.internals { list-style:url("images/docs-internals.png"); } - .standout ul.tutorials { list-style:url("images/docs-tutorials.png"); } - .standout ul.examples { list-style:url("images/docs-examples.png"); } - .standout ul.articles { list-style:url("images/docs-articles.png"); } + .standout .tools ul { list-style:url("images/docs-tools.png"); } + .standout .libraries ul { list-style:url("images/docs-libraries.png"); } + .standout .internals ul { list-style:url("images/docs-internals.png"); } + .standout .tutorials ul { list-style:url("images/docs-tutorials.png"); } + .standout .examples ul { list-style:url("images/docs-examples.png"); } + .standout .articles ul { list-style:url("images/docs-articles.png"); } .standout li:first-child { padding-top:0; border-top:none; } .standout li p { margin:0 0 10px 0 !important; line-height:130%; } - .standout li > a { font-weight:bold; } + .standout li p > a { font-weight:bold; } .forum-user-info, .forum-user-info * { cursor:help } diff --git a/web/documentation.txt b/web/documentation.txt index c32fd35bab..dbb737cd9c 100644 --- a/web/documentation.txt +++ b/web/documentation.txt @@ -6,22 +6,17 @@ Nim's Documentation Standards & Guides ------------------ - .. raw:: html + .. container:: libraries -
    -
  • - Standard Library
    -

    This document describes Nim's standard library.

    -
  • -
  • - Language Manual
    -

    The Nim manual is a draft that will evolve into a proper specification.

    -
  • -
  • - Compiler User-Guide
    -

    The user guide lists command line arguments, special features of the compiler, etc.

    -
  • -
+ - | `Standard Library `_ + | This document describes Nim's standard library. + + - | `Language Manual `_ + | The Nim manual is a draft that will evolve into a proper specification. + + - | `Compiler User Guide `_ + | The user guide lists command line arguments, special features of the + compiler, etc. .. container:: standout @@ -29,18 +24,14 @@ Nim's Documentation Tools & Features ---------------- - .. raw:: html + .. container:: tools -
    -
  • - Source-Code Filters
    -

    The Nim compiler supports source code filters as a simple yet powerful builtin templating system.

    -
  • -
  • - Tools Documentation
    -

    Description of some tools that come with the standard distribution.

    -
  • -
+ - | `Source Code Filters `_ + | The Nim compiler supports source code filters as a simple yet powerful + builtin templating system. + + - | `Tools Documentation `_ + | Description of some tools that come with the standard distribution. .. container:: standout @@ -48,18 +39,15 @@ Nim's Documentation Internal Details ---------------- - .. raw:: html + .. container:: internals -
    -
  • - Garbage Collector
    -

    Additional documentation about Nim's GC and how to operate it in a realtime setting.

    -
  • -
  • - Internal Documentation
    -

    The internal documentation describes how the compiler is implemented. Read this if you want to hack the compiler.

    -
  • -
+ - | `Garbage Collector `_ + | Additional documentation about Nim's GC and how to operate it in a + realtime setting. + + - | `Internal Documentation `_ + | The internal documentation describes how the compiler is implemented. Read + this if you want to hack the compiler. Search Options diff --git a/web/learn.txt b/web/learn.txt index 4ff4dcafb4..7a9600e570 100644 --- a/web/learn.txt +++ b/web/learn.txt @@ -6,18 +6,13 @@ Learning Nim Tutorials --------- - .. raw:: html + .. container:: tutorials -
    -
  • - Tutorial (part I)
    -

    Learn the basics of Nim's types, variables, procedures, control flow, etc...

    -
  • -
  • - Tutorial (part II)
    -

    Learn Nim's more advanced features such as OOP, generics, macros, etc...

    -
  • -
+ - | `Tutorial (part I) `_ + | Learn the basics of Nim's types, variables, procedures, control flow, etc... + + - | `Tutorial (part II) `_ + | Learn Nim's more advanced features such as OOP, generics, macros, etc... .. container:: standout @@ -25,22 +20,16 @@ Learning Nim Examples -------- - .. raw:: html + .. container:: examples -
    -
  • - Nim by Example
    -

    Nim by Example is an excellent starting place for beginners.

    -
  • -
  • - Nim on Rosetta Code
    -

    Many different Nim code examples comparable to other languages for reference.

    -
  • -
  • - Nim for C/C++ Programmers
    -

    A useful cheat-sheet for those most familiar with C/C++ languages.

    -
  • -
+ - | `Nim by Example `_ + | Nim by Example is an excellent starting place for beginners. + + - | `Nim on Rosetta Code `_ + | Many different Nim code examples comparable to other languages for reference. + + - | `Nim for C/C++ Programmers `_ + | A useful cheat-sheet for those most familiar with C/C++ languages. .. container:: standout @@ -48,21 +37,16 @@ Learning Nim Articles -------- - .. raw:: html + .. container:: articles - + - `How I Start: Nim `_ + - `Getting Started With Nim `_ + - `Getting Started With Nim - Part 2 `_ + - `What is special about Nim? `_ + - `What makes Nim practical? `_ + - `Learn Nim in minutes `_ + - `Dr Dobbs Nimrod Publication `_ + - `Nim articles by Göran Krampe `_ Documentation From df2fdaf3c5fb8249c47be7566543be3482f9cb48 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 14 Feb 2015 14:45:49 +0100 Subject: [PATCH 329/850] fixes #2121 --- compiler/ccgstmts.nim | 2 +- tests/tuples/tgeneric_tuple.nim | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 tests/tuples/tgeneric_tuple.nim diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 18705c9741..61568c9e62 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -48,7 +48,7 @@ proc genVarTuple(p: BProc, n: PNode) = return genLineDir(p, n) initLocExpr(p, n.sons[L-1], tup) - var t = tup.t + var t = tup.t.getUniqueType for i in countup(0, L-3): var v = n.sons[i].sym if sfCompileTime in v.flags: continue diff --git a/tests/tuples/tgeneric_tuple.nim b/tests/tuples/tgeneric_tuple.nim new file mode 100644 index 0000000000..32f0815964 --- /dev/null +++ b/tests/tuples/tgeneric_tuple.nim @@ -0,0 +1,9 @@ +# bug #2121 + +type + Item[K,V] = tuple + key: K + value: V + +var q = newseq[Item[int,int]](0) +let (x,y) = q[0] From ece23d39bce679be75da10e0e6b6fcf1814dca49 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 14 Feb 2015 18:11:52 +0100 Subject: [PATCH 330/850] fixes #2123 --- compiler/parser.nim | 1 + tests/parser/twhen_in_enum.nim | 11 +++++++++++ 2 files changed, 12 insertions(+) create mode 100644 tests/parser/twhen_in_enum.nim diff --git a/compiler/parser.nim b/compiler/parser.nim index f249b37c84..8fbf033d89 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -1597,6 +1597,7 @@ proc parseEnum(p: var TParser): PNode = optInd(p, result) while true: var a = parseSymbol(p) + if a.kind == nkEmpty: return if p.tok.indent >= 0 and p.tok.indent <= p.currInd: add(result, a) break diff --git a/tests/parser/twhen_in_enum.nim b/tests/parser/twhen_in_enum.nim new file mode 100644 index 0000000000..d4a3ea56ac --- /dev/null +++ b/tests/parser/twhen_in_enum.nim @@ -0,0 +1,11 @@ +discard """ + errormsg: "identifier expected, but found 'keyword when'" +""" + +# bug #2123 +type num = enum + NUM_NONE = 0 + NUM_ALL = 1 + when defined(macosx): NUM_OSX = 10 # only this differs for real + NUM_XTRA = 20 + From fb718f2d04f10c63562e14c40da28b8da34d9714 Mon Sep 17 00:00:00 2001 From: def Date: Sat, 14 Feb 2015 19:00:11 +0100 Subject: [PATCH 331/850] nimrod -> nim in some filenames --- compiler/installer.ini | 8 +- compiler/nim.nim | 4 +- config/nimrod.cfg | 136 ------------------------- icons/{nimrod.ico => nim.ico} | Bin icons/nim.rc | 3 + icons/{nimrod.res => nim.res} | Bin icons/{nimrod_icon.o => nim_icon.o} | Bin icons/nimrod.rc | 3 - tests/rodfiles/{nimrod.cfg => nim.cfg} | 0 tools/niminst/nsis.tmpl | 4 +- 10 files changed, 11 insertions(+), 147 deletions(-) delete mode 100644 config/nimrod.cfg rename icons/{nimrod.ico => nim.ico} (100%) create mode 100644 icons/nim.rc rename icons/{nimrod.res => nim.res} (100%) rename icons/{nimrod_icon.o => nim_icon.o} (100%) delete mode 100644 icons/nimrod.rc rename tests/rodfiles/{nimrod.cfg => nim.cfg} (100%) diff --git a/compiler/installer.ini b/compiler/installer.ini index dcf9aa52f4..48cd0b3b96 100644 --- a/compiler/installer.ini +++ b/compiler/installer.ini @@ -51,10 +51,10 @@ Files: "configure;makefile" Files: "*.ini" Files: "koch.nim" -Files: "icons/nimrod.ico" -Files: "icons/nimrod.rc" -Files: "icons/nimrod.res" -Files: "icons/nimrod_icon.o" +Files: "icons/nim.ico" +Files: "icons/nim.rc" +Files: "icons/nim.res" +Files: "icons/nim_icon.o" Files: "icons/koch.ico" Files: "icons/koch.rc" Files: "icons/koch.res" diff --git a/compiler/nim.nim b/compiler/nim.nim index 617758b2de..215f1986ee 100644 --- a/compiler/nim.nim +++ b/compiler/nim.nim @@ -9,9 +9,9 @@ when defined(gcc) and defined(windows): when defined(x86): - {.link: "icons/nimrod.res".} + {.link: "icons/nim.res".} else: - {.link: "icons/nimrod_icon.o".} + {.link: "icons/nim_icon.o".} import commands, lexer, condsyms, options, msgs, nversion, nimconf, ropes, diff --git a/config/nimrod.cfg b/config/nimrod.cfg deleted file mode 100644 index 62a7b16cc6..0000000000 --- a/config/nimrod.cfg +++ /dev/null @@ -1,136 +0,0 @@ -# Configuration file for the Nim Compiler. -# (c) 2015 Andreas Rumpf - -# Feel free to edit the default values as you need. - -# You may set environment variables with -# @putenv "key" "val" -# Environment variables cannot be used in the options, however! - -cc = gcc - -# example of how to setup a cross-compiler: -arm.linux.gcc.exe = "arm-linux-gcc" -arm.linux.gcc.linkerexe = "arm-linux-gcc" - -cs:partial - -path="$lib/core" -path="$lib/pure" -path="$lib/pure/collections" -path="$lib/pure/concurrency" -path="$lib/impure" -path="$lib/wrappers" -# path="$lib/wrappers/cairo" -# path="$lib/wrappers/gtk" -# path="$lib/wrappers/lua" -# path="$lib/wrappers/opengl" -path="$lib/wrappers/pcre" -path="$lib/wrappers/readline" -path="$lib/wrappers/sdl" -# path="$lib/wrappers/x11" -path="$lib/wrappers/zip" -path="$lib/wrappers/libffi" -path="$lib/windows" -path="$lib/posix" -path="$lib/js" -path="$lib/pure/unidecode" - -@if nimbabel: - babelpath="$home/.babel/pkgs/" -@end - -@if release or quick: - obj_checks:off - field_checks:off - range_checks:off - bound_checks:off - overflow_checks:off - assertions:off - stacktrace:off - linetrace:off - debugger:off - line_dir:off - dead_code_elim:on -@end - -@if release: - opt:speed -@end - -# additional options always passed to the compiler: ---parallel_build: "0" # 0 to auto-detect number of processors - -hint[LineTooLong]=off -#hint[XDeclaredButNotUsed]=off - -@if unix: - @if not bsd: - # -fopenmp - gcc.options.linker = "-ldl" - gpp.options.linker = "-ldl" - clang.options.linker = "-ldl" - tcc.options.linker = "-ldl" - @end - @if bsd or haiku: - # BSD got posix_spawn only recently, so we deactivate it for osproc: - define:useFork - # at least NetBSD has problems with thread local storage: - tlsEmulation:on - @end -@end - -# Configuration for the Intel C/C++ compiler: -@if windows: - icl.options.speed = "/Ox /arch:SSE2" - icl.options.always = "/nologo" -@end - -# Configuration for the GNU C/C++ compiler: -@if windows: - #gcc.path = r"$nimrod\dist\mingw\bin" - @if gcc: - tlsEmulation:on - @end -@end - -@if macosx: - cc = clang - tlsEmulation:on - gcc.options.always = "-w -fasm-blocks" - gpp.options.always = "-w -fasm-blocks -fpermissive" -@else: - gcc.options.always = "-w" - gpp.options.always = "-w -fpermissive" -@end - -gcc.options.speed = "-O3 -fno-strict-aliasing" -gcc.options.size = "-Os" -gcc.options.debug = "-g3 -O0" - -gpp.options.speed = "-O3 -fno-strict-aliasing" -gpp.options.size = "-Os" -gpp.options.debug = "-g3 -O0" -#passl = "-pg" - -# Configuration for the LLVM GCC compiler: -llvm_gcc.options.debug = "-g" -llvm_gcc.options.always = "-w" -llvm_gcc.options.speed = "-O2" -llvm_gcc.options.size = "-Os" - -# Configuration for the LLVM CLang compiler: -clang.options.debug = "-g" -clang.options.always = "-w" -clang.options.speed = "-O3" -clang.options.size = "-Os" - -# Configuration for the Visual C/C++ compiler: -vcc.options.linker = "/DEBUG /Zi /Fd\"$projectName.pdb\" /F33554432" # set the stack size to 8 MB -vcc.options.debug = "/Zi /Fd\"$projectName.pdb\"" -vcc.options.always = "/nologo" -vcc.options.speed = "/Ox /arch:SSE2" -vcc.options.size = "/O1" - -# Configuration for the Tiny C Compiler: -tcc.options.always = "-w" diff --git a/icons/nimrod.ico b/icons/nim.ico similarity index 100% rename from icons/nimrod.ico rename to icons/nim.ico diff --git a/icons/nim.rc b/icons/nim.rc new file mode 100644 index 0000000000..c053e08e9e --- /dev/null +++ b/icons/nim.rc @@ -0,0 +1,3 @@ +nimicon ICON "nim.ico" + + diff --git a/icons/nimrod.res b/icons/nim.res similarity index 100% rename from icons/nimrod.res rename to icons/nim.res diff --git a/icons/nimrod_icon.o b/icons/nim_icon.o similarity index 100% rename from icons/nimrod_icon.o rename to icons/nim_icon.o diff --git a/icons/nimrod.rc b/icons/nimrod.rc deleted file mode 100644 index 6f36b81451..0000000000 --- a/icons/nimrod.rc +++ /dev/null @@ -1,3 +0,0 @@ -nimrodicon ICON "nimrod.ico" - - diff --git a/tests/rodfiles/nimrod.cfg b/tests/rodfiles/nim.cfg similarity index 100% rename from tests/rodfiles/nimrod.cfg rename to tests/rodfiles/nim.cfg diff --git a/tools/niminst/nsis.tmpl b/tools/niminst/nsis.tmpl index 23bbf3ac90..aba1e581fd 100644 --- a/tools/niminst/nsis.tmpl +++ b/tools/niminst/nsis.tmpl @@ -50,8 +50,8 @@ SetCompressor /SOLID /FINAL lzma ; Installer and Uninstaller Icons - ; Icon "nimrod.ico" - ; UninstallIcon "nimrod.ico" + ; Icon "nim.ico" + ; UninstallIcon "nim.ico" ; Set installation details to be shown by default ShowInstDetails show From 512db9aea6ac77234e2ea6a48b1cc20e6b24a687 Mon Sep 17 00:00:00 2001 From: def Date: Sat, 14 Feb 2015 19:57:32 +0100 Subject: [PATCH 332/850] Fix documentation a bit in unicode --- lib/pure/unicode.nim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim index b892ec8b40..42e6a31951 100644 --- a/lib/pure/unicode.nim +++ b/lib/pure/unicode.nim @@ -1235,11 +1235,12 @@ proc reversed*(s: string): string = ## returns the reverse of `s`, interpreting it as unicode characters. Unicode ## combining characters are correctly interpreted as well: ## - ## .. code-block: + ## .. code-block:: nim + ## ## assert reversed("Reverse this!") == "!siht esreveR" ## assert reversed("先秦兩漢") == "漢兩秦先" ## assert reversed("as⃝df̅") == "f̅ds⃝a" - ## assert reversed("a⃞b⃞c⃞") == "c⃞b⃞a⃞" + ## assert reversed("a⃞b⃞c⃞") == "c⃞b⃞a⃞" var i = 0 lastI = 0 From 5b32e31a279e2f6a7b19328fbc7c2d13079052f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Sun, 15 Feb 2015 01:03:11 +0500 Subject: [PATCH 333/850] It's 2015 :+1: --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index b08fa22914..2252ea52bb 100644 --- a/readme.md +++ b/readme.md @@ -62,7 +62,7 @@ allowing you to create commercial applications. Read copying.txt for more details. -Copyright (c) 2006-2014 Andreas Rumpf. +Copyright (c) 2006-2015 Andreas Rumpf. All rights reserved. # Build Status From 442dc30922c226b8e5f82630bc76fa877dce1536 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 14 Feb 2015 21:47:21 +0100 Subject: [PATCH 334/850] fixes endless recursion with static type parameters --- compiler/sigmatch.nim | 12 ++++++++++-- tests/metatype/tstaticvector.nim | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 tests/metatype/tstaticvector.nim diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 00802e69b7..7fbf0f1651 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1016,9 +1016,17 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = if result != isNone: put(c.bindings, f, aOrig) else: result = isNone + elif prev.kind == tyStatic: + if aOrig.kind == tyStatic: + result = typeRel(c, prev.lastSon, a) + if result != isNone and prev.n != nil: + if not exprStructuralEquivalent(prev.n, aOrig.n): + result = isNone + else: result = isNone else: - result = typeRel(c, prev, aOrig) - + # XXX endless recursion? + #result = typeRel(c, prev, aOrig) + result = isNone of tyTypeDesc: var prev = PType(idTableGet(c.bindings, f)) if prev == nil: diff --git a/tests/metatype/tstaticvector.nim b/tests/metatype/tstaticvector.nim new file mode 100644 index 0000000000..c9923f4695 --- /dev/null +++ b/tests/metatype/tstaticvector.nim @@ -0,0 +1,17 @@ + +type + RectArray*[R, C: static[int], T] = distinct array[R * C, T] + + StaticMatrix*[R, C: static[int], T] = object + elements*: RectArray[R, C, T] + + StaticVector*[N: static[int], T] = StaticMatrix[N, 1, T] + +proc foo*[N, T](a: StaticVector[N, T]): T = 0.T +proc foobar*[N, T](a, b: StaticVector[N, T]): T = 0.T + + +var a: StaticVector[3, int] + +echo foo(a) # OK +echo foobar(a, a) # <--- hangs compiler From 6244cc2e4fb7aaabd14352a21add5236220a8198 Mon Sep 17 00:00:00 2001 From: def Date: Sat, 14 Feb 2015 23:43:31 +0100 Subject: [PATCH 335/850] Fix cross_calculator example --- .../{nimrod_backend => nim_backend}/backend.nim | 0 .../nimrod.cfg => nim_commandline/nim.cfg} | 2 +- .../nimcalculator.nim | 6 +++--- .../{nimrod_commandline => nim_commandline}/readme.txt | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) rename examples/cross_calculator/{nimrod_backend => nim_backend}/backend.nim (100%) rename examples/cross_calculator/{nimrod_commandline/nimrod.cfg => nim_commandline/nim.cfg} (81%) rename examples/cross_calculator/{nimrod_commandline => nim_commandline}/nimcalculator.nim (97%) rename examples/cross_calculator/{nimrod_commandline => nim_commandline}/readme.txt (60%) diff --git a/examples/cross_calculator/nimrod_backend/backend.nim b/examples/cross_calculator/nim_backend/backend.nim similarity index 100% rename from examples/cross_calculator/nimrod_backend/backend.nim rename to examples/cross_calculator/nim_backend/backend.nim diff --git a/examples/cross_calculator/nimrod_commandline/nimrod.cfg b/examples/cross_calculator/nim_commandline/nim.cfg similarity index 81% rename from examples/cross_calculator/nimrod_commandline/nimrod.cfg rename to examples/cross_calculator/nim_commandline/nim.cfg index c1aedcf6ae..41c0344309 100644 --- a/examples/cross_calculator/nimrod_commandline/nimrod.cfg +++ b/examples/cross_calculator/nim_commandline/nim.cfg @@ -1,4 +1,4 @@ # Nimrod configuration file. # The file is used only to add the path of the backend to the compiler options. -path="../nimrod_backend" +path="../nim_backend" diff --git a/examples/cross_calculator/nimrod_commandline/nimcalculator.nim b/examples/cross_calculator/nim_commandline/nimcalculator.nim similarity index 97% rename from examples/cross_calculator/nimrod_commandline/nimcalculator.nim rename to examples/cross_calculator/nim_commandline/nimcalculator.nim index 440834ca81..69d62a90ca 100644 --- a/examples/cross_calculator/nimrod_commandline/nimcalculator.nim +++ b/examples/cross_calculator/nim_commandline/nimcalculator.nim @@ -21,7 +21,7 @@ type cmdParams, # Two valid parameters were provided cmdInteractive # No parameters were provided, run interactive mode - TParamConfig = object of TObject + TParamConfig = object of RootObj action: TCommand # store the type of operation paramA, paramB: int # possibly store the valid parameters @@ -63,7 +63,7 @@ proc parseCmdLine(): TParamConfig = stdout.write USAGE quit "Unexpected option: " & key, 2 of cmdEnd: break - except EInvalidValue: + except ValueError: stdout.write USAGE quit "Invalid value " & val & " for parameter " & key, 3 @@ -85,7 +85,7 @@ proc parseUserInput(question: string): int = try: result = input.parseInt break - except EInvalidValue: + except ValueError: if input.len < 1: quit "Blank line detected, quitting.", 0 echo "Sorry, `$1' doesn't seem to be a valid integer" % input diff --git a/examples/cross_calculator/nimrod_commandline/readme.txt b/examples/cross_calculator/nim_commandline/readme.txt similarity index 60% rename from examples/cross_calculator/nimrod_commandline/readme.txt rename to examples/cross_calculator/nim_commandline/readme.txt index 5430e7b47b..f95bd962e0 100644 --- a/examples/cross_calculator/nimrod_commandline/readme.txt +++ b/examples/cross_calculator/nim_commandline/readme.txt @@ -1,10 +1,10 @@ -In this directory you will find the nimrod commandline version of the +In this directory you will find the nim commandline version of the cross-calculator sample. The commandline interface can be used non interactively through switches, or interactively when running the command without parameters. Compilation is fairly easy despite having the source split in different -directories. Thanks to the nimrod.cfg file, which adds the ../nimrod_backend +directories. Thanks to the nim.cfg file, which adds the ../nim_backend directory as a search path, you can compile and run the example just fine from -the command line with 'nimrod c -r nimcalculator.nim'. +the command line with 'nim c -r nimcalculator.nim'. From d19a4ca827ab04edc5b497b73132e3f40369e1a8 Mon Sep 17 00:00:00 2001 From: def Date: Sun, 15 Feb 2015 00:05:16 +0100 Subject: [PATCH 336/850] Fix cross_todo example --- .../{nimrod_backend => nim_backend}/backend.nim | 14 +++++++------- .../{nimrod_backend => nim_backend}/readme.txt | 4 ++-- .../testbackend.nim | 0 .../nimrod.cfg => nim_commandline/nim.cfg} | 2 +- .../nimtodo.nim | 10 +++++----- .../readme.txt | 0 6 files changed, 15 insertions(+), 15 deletions(-) rename examples/cross_todo/{nimrod_backend => nim_backend}/backend.nim (95%) rename examples/cross_todo/{nimrod_backend => nim_backend}/readme.txt (78%) rename examples/cross_todo/{nimrod_backend => nim_backend}/testbackend.nim (100%) rename examples/cross_todo/{nimrod_commandline/nimrod.cfg => nim_commandline/nim.cfg} (81%) rename examples/cross_todo/{nimrod_commandline => nim_commandline}/nimtodo.nim (98%) rename examples/cross_todo/{nimrod_commandline => nim_commandline}/readme.txt (100%) diff --git a/examples/cross_todo/nimrod_backend/backend.nim b/examples/cross_todo/nim_backend/backend.nim similarity index 95% rename from examples/cross_todo/nimrod_backend/backend.nim rename to examples/cross_todo/nim_backend/backend.nim index 89e7d0b7e0..9c7d2bafac 100644 --- a/examples/cross_todo/nimrod_backend/backend.nim +++ b/examples/cross_todo/nim_backend/backend.nim @@ -13,7 +13,7 @@ type text*: string ## Description of the task to do. priority*: int ## The priority can be any user defined integer. isDone*: bool ## Done todos are still kept marked. - modificationDate: TTime ## The modification time can't be modified from + modificationDate: Time ## The modification time can't be modified from ## outside of this module, use the ## getModificationDate accessor. @@ -64,7 +64,7 @@ proc openDatabase*(path: string): TDbConn = # - Procs related to TTodo objects # proc initFromDB(id: int64; text: string; priority: int, isDone: bool; - modificationDate: TTime): TTodo = + modificationDate: Time): TTodo = ## Returns an initialized TTodo object created from database parameters. ## ## The proc assumes all values are right. Note this proc is NOT exported. @@ -81,7 +81,7 @@ proc getId*(todo: TTodo): int64 = return todo.id -proc getModificationDate*(todo: TTodo): TTime = +proc getModificationDate*(todo: TTodo): Time = ## Returns the last modification date of a TTodo entry. return todo.modificationDate @@ -99,14 +99,14 @@ proc update*(todo: var TTodo; conn: TDbConn): bool = FROM Todos WHERE id = ?""" try: - let rows = conn.GetAllRows(query, $todo.id) + let rows = conn.getAllRows(query, $todo.id) if len(rows) < 1: return assert(1 == len(rows), "Woah, didn't expect so many rows") todo.text = rows[0][0] todo.priority = rows[0][1].parseInt todo.isDone = rows[0][2].parseBool - todo.modificationDate = TTime(rows[0][3].parseInt) + todo.modificationDate = Time(rows[0][3].parseInt) result = true except: echo("Something went wrong selecting for id " & $todo.id) @@ -202,12 +202,12 @@ proc getPagedTodos*(conn: TDbConn; params: TPagedParams; #echo("Query " & string(query)) #echo("args: " & args.join(", ")) - var newId: biggestInt + var newId: BiggestInt for row in conn.fastRows(query, args): let numChars = row[0].parseBiggestInt(newId) assert(numChars > 0, "Huh, couldn't parse identifier from database?") result.add(initFromDB(int64(newId), row[1], row[2].parseInt, - row[3].parseBool, TTime(row[4].parseInt))) + row[3].parseBool, Time(row[4].parseInt))) proc getTodo*(conn: TDbConn; todoId: int64): ref TTodo = diff --git a/examples/cross_todo/nimrod_backend/readme.txt b/examples/cross_todo/nim_backend/readme.txt similarity index 78% rename from examples/cross_todo/nimrod_backend/readme.txt rename to examples/cross_todo/nim_backend/readme.txt index 6529f2e67b..16cb592fcc 100644 --- a/examples/cross_todo/nimrod_backend/readme.txt +++ b/examples/cross_todo/nim_backend/readme.txt @@ -1,4 +1,4 @@ -This directory contains the nimrod backend code for the todo cross platform +This directory contains the nim backend code for the todo cross platform example. Unlike the cross platform calculator example, this backend features more code, @@ -8,7 +8,7 @@ The test is not embedded directly in the backend.nim file to avoid being able to access internal data types and procs not exported and replicate the environment of client code. -In a bigger project with several people you could run `nimrod doc backend.nim` +In a bigger project with several people you could run `nim doc backend.nim` (or use the doc2 command for a whole project) and provide the generated html documentation to another programer for her to implement an interface without having to look at the source code. diff --git a/examples/cross_todo/nimrod_backend/testbackend.nim b/examples/cross_todo/nim_backend/testbackend.nim similarity index 100% rename from examples/cross_todo/nimrod_backend/testbackend.nim rename to examples/cross_todo/nim_backend/testbackend.nim diff --git a/examples/cross_todo/nimrod_commandline/nimrod.cfg b/examples/cross_todo/nim_commandline/nim.cfg similarity index 81% rename from examples/cross_todo/nimrod_commandline/nimrod.cfg rename to examples/cross_todo/nim_commandline/nim.cfg index c1aedcf6ae..41c0344309 100644 --- a/examples/cross_todo/nimrod_commandline/nimrod.cfg +++ b/examples/cross_todo/nim_commandline/nim.cfg @@ -1,4 +1,4 @@ # Nimrod configuration file. # The file is used only to add the path of the backend to the compiler options. -path="../nimrod_backend" +path="../nim_backend" diff --git a/examples/cross_todo/nimrod_commandline/nimtodo.nim b/examples/cross_todo/nim_commandline/nimtodo.nim similarity index 98% rename from examples/cross_todo/nimrod_commandline/nimtodo.nim rename to examples/cross_todo/nim_commandline/nimtodo.nim index 1067177c38..4ab17e7a21 100644 --- a/examples/cross_todo/nimrod_commandline/nimtodo.nim +++ b/examples/cross_todo/nim_commandline/nimtodo.nim @@ -69,11 +69,11 @@ template parseTodoIdAndSetCommand(newCommand: TCommand): stmt = ## Helper to parse a big todo identifier into todoId and set command. try: let numChars = val.parseBiggestInt(newId) - if numChars < 1: raise newException(EInvalidValue, "Empty string?") + if numChars < 1: raise newException(ValueError, "Empty string?") result.command = newCommand result.todoId = newId - except EOverflow: - raise newException(EInvalidValue, "Value $1 too big" % val) + except OverflowError: + raise newException(ValueError, "Value $1 too big" % val) template verifySingleCommand(actions: stmt): stmt = @@ -111,7 +111,7 @@ proc parseCmdLine(): TParamConfig = usesListParams = false p = initOptParser() key, val: TaintedString - newId: biggestInt + newId: BiggestInt result.initDefaults @@ -178,7 +178,7 @@ proc parseCmdLine(): TParamConfig = abort("Unexpected option '$1'." % [key], 6) of cmdEnd: break - except EInvalidValue: + except ValueError: abort("Invalid integer value '$1' for parameter '$2'." % [val, key], 7) if not specifiedCommand: diff --git a/examples/cross_todo/nimrod_commandline/readme.txt b/examples/cross_todo/nim_commandline/readme.txt similarity index 100% rename from examples/cross_todo/nimrod_commandline/readme.txt rename to examples/cross_todo/nim_commandline/readme.txt From 0a01b9143f892f60b9477e8995f2a11a2ee7734a Mon Sep 17 00:00:00 2001 From: def Date: Sun, 15 Feb 2015 00:07:34 +0100 Subject: [PATCH 337/850] nimrod.cfg isn't working anymore, rename to nim.cfg --- tests/manyloc/keineschweine/enet_server/{nimrod.cfg => nim.cfg} | 0 tests/manyloc/keineschweine/server/{nimrod.cfg => nim.cfg} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename tests/manyloc/keineschweine/enet_server/{nimrod.cfg => nim.cfg} (100%) rename tests/manyloc/keineschweine/server/{nimrod.cfg => nim.cfg} (100%) diff --git a/tests/manyloc/keineschweine/enet_server/nimrod.cfg b/tests/manyloc/keineschweine/enet_server/nim.cfg similarity index 100% rename from tests/manyloc/keineschweine/enet_server/nimrod.cfg rename to tests/manyloc/keineschweine/enet_server/nim.cfg diff --git a/tests/manyloc/keineschweine/server/nimrod.cfg b/tests/manyloc/keineschweine/server/nim.cfg similarity index 100% rename from tests/manyloc/keineschweine/server/nimrod.cfg rename to tests/manyloc/keineschweine/server/nim.cfg From c63c3a86543499c5d5ba3cd477e01be0be876c58 Mon Sep 17 00:00:00 2001 From: Billingsly Wetherfordshire Date: Sat, 14 Feb 2015 17:14:06 -0600 Subject: [PATCH 338/850] Update website.ini generate docs for basic2d,basic3d --- web/website.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/web/website.ini b/web/website.ini index c0a648c562..6757abcd85 100644 --- a/web/website.ini +++ b/web/website.ini @@ -61,6 +61,7 @@ srcdoc2: "pure/rawsockets;pure/asynchttpserver;pure/net;pure/selectors;pure/futu srcdoc2: "pure/md5" srcdoc2: "posix/posix" srcdoc2: "pure/fenv" +srcdoc2: "pure/basic2d;pure/basic3d" ; Note: everything under 'webdoc' doesn't get listed in the index, so wrappers ; should live here From e22ae986f934fa0b1700cbaede89fa762ef16477 Mon Sep 17 00:00:00 2001 From: Billingsly Wetherfordshire Date: Sat, 14 Feb 2015 17:15:30 -0600 Subject: [PATCH 339/850] Update basic3d.nim fix rst error --- lib/pure/basic3d.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/basic3d.nim b/lib/pure/basic3d.nim index c00764fc5b..9a8e006ec3 100644 --- a/lib/pure/basic3d.nim +++ b/lib/pure/basic3d.nim @@ -812,7 +812,7 @@ proc bisect*(v1,v2:TVector3d):TVector3d {.noInit.}= ## Computes the bisector between v1 and v2 as a normalized vector. ## If one of the input vectors has zero length, a normalized version ## of the other is returned. If both input vectors has zero length, - ## an arbitrary normalized vector `v1`is returned. + ## an arbitrary normalized vector `v1` is returned. var vmag1=v1.len vmag2=v2.len From 706544c63cf90d62a8c26a9cb6f8f96e5b478a73 Mon Sep 17 00:00:00 2001 From: Billingsly Wetherfordshire Date: Sat, 14 Feb 2015 17:19:13 -0600 Subject: [PATCH 340/850] Update lib.txt add basic2d/3d to standard libraries list --- doc/lib.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/lib.txt b/doc/lib.txt index b7c94b505a..6897f71e08 100644 --- a/doc/lib.txt +++ b/doc/lib.txt @@ -189,6 +189,12 @@ Math libraries Floating-point environment. Handling of floating-point rounding and exceptions (overflow, zero-devide, etc.). +* `basic2d `_ + Basic 2d support with vectors, points, matrices and some basic utilities. + +* `basic3d `_ + Basic 3d support with vectors, points, matrices and some basic utilities. + Internet Protocols and Support ------------------------------ From 8ed31ffd2b8cd0605c7db764e951b025129696bc Mon Sep 17 00:00:00 2001 From: Billingsly Wetherfordshire Date: Sat, 14 Feb 2015 17:20:21 -0600 Subject: [PATCH 341/850] Update lib.txt removed IRC module from mention on lib.html --- doc/lib.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/doc/lib.txt b/doc/lib.txt index 6897f71e08..da45afea66 100644 --- a/doc/lib.txt +++ b/doc/lib.txt @@ -52,7 +52,7 @@ Core Locks and condition variables for Nim. * `macros `_ - Contains the AST API and documentation of Nim for writing macros. + Contains the AST API and documentation of Nim for writing macros.i * `typeinfo `_ Provides (unsafe) access to Nim's run time type information. @@ -224,9 +224,6 @@ Internet Protocols and Support * `smtp `_ This module implement a simple SMTP client. -* `irc `_ - This module implements an asynchronous IRC client. - * `ftpclient `_ This module implements an FTP client. From 78cae0dd45f41f795a4876f9b31c058fbd3b97c1 Mon Sep 17 00:00:00 2001 From: Billingsly Wetherfordshire Date: Sat, 14 Feb 2015 17:21:20 -0600 Subject: [PATCH 342/850] Update lib.txt oops --- doc/lib.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/lib.txt b/doc/lib.txt index da45afea66..4185e6f749 100644 --- a/doc/lib.txt +++ b/doc/lib.txt @@ -52,7 +52,7 @@ Core Locks and condition variables for Nim. * `macros `_ - Contains the AST API and documentation of Nim for writing macros.i + Contains the AST API and documentation of Nim for writing macros. * `typeinfo `_ Provides (unsafe) access to Nim's run time type information. From a7484ac092bfa47b87fe303ce55c9b2f28e3bc70 Mon Sep 17 00:00:00 2001 From: Hans Raaf Date: Sun, 15 Feb 2015 04:44:15 +0100 Subject: [PATCH 343/850] Fixed non exhaustive case by adding else --- lib/pure/matchers.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/matchers.nim b/lib/pure/matchers.nim index 1188be4cad..d55963c155 100644 --- a/lib/pure/matchers.nim +++ b/lib/pure/matchers.nim @@ -42,7 +42,7 @@ proc validEmailAddress*(s: string): bool {.noSideEffect, case toLower(x) of "com", "org", "net", "gov", "mil", "biz", "info", "mobi", "name", "aero", "jobs", "museum": return true - return false + else: return false proc parseInt*(s: string, value: var int, validRange: Slice[int]) {. noSideEffect, rtl, extern: "nmatchParseInt".} = From 7c1c9a6a9d264feb47b5346c1953b8a72862292e Mon Sep 17 00:00:00 2001 From: Charles Blake Date: Sun, 15 Feb 2015 10:03:41 -0500 Subject: [PATCH 344/850] Add mgetOrPut to support just one probe chase for the common pattern of either updating or initializing table entries. --- lib/pure/collections/tables.nim | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index 25fe306c07..96189baffb 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -257,6 +257,20 @@ when false: inc(t.counter) result = false +proc mgetOrPut*[A, B](t: var Table[A, B], key: A, value: B): var B = + ## retrieves value at ``t[key]`` or puts ``value`` if not present, either way + ## returning a value which can be modified. + var hc: THash # If also desired in OrderedTable, lift this into a template + var index = rawGet(t, key, hc) + if index < 0: # not present: insert + if mustRehash(len(t.data), t.counter): + enlarge(t) + index = rawGet(t, key, hc) + index = -1 - index + rawInsert(t, t.data, key, value, hc, index) + inc(t.counter) + result = t.data[index].val # either way return modifiable val + proc `[]=`*[A, B](t: var Table[A, B], key: A, val: B) = ## puts a (key, value)-pair into `t`. putImpl() From c95f6f117a665bc6d3d64ae8703459759973f63f Mon Sep 17 00:00:00 2001 From: Federico Ceratto Date: Sun, 15 Feb 2015 16:06:06 +0000 Subject: [PATCH 345/850] Fix typos --- compiler/ast.nim | 6 +++--- compiler/canonicalizer.nim | 4 ++-- compiler/ccgexprs.nim | 2 +- compiler/ccgmerge.nim | 2 +- compiler/ccgutils.nim | 2 +- compiler/docgen.nim | 4 ++-- compiler/jsgen.nim | 2 +- compiler/lambdalifting.nim | 4 ++-- compiler/msgs.nim | 8 ++++---- compiler/rodread.nim | 2 +- compiler/semasgn.nim | 2 +- compiler/semdestruct.nim | 2 +- compiler/semexprs.nim | 4 ++-- compiler/seminst.nim | 2 +- compiler/sempass2.nim | 2 +- compiler/semstmts.nim | 6 +++--- compiler/semtempl.nim | 4 ++-- compiler/semtypes.nim | 20 +++++++++---------- compiler/semtypinst.nim | 14 ++++++------- compiler/sigmatch.nim | 16 +++++++-------- compiler/types.nim | 10 +++++----- doc/advopt.txt | 2 +- doc/idetools.txt | 6 +++--- doc/intern.txt | 2 +- koch.nim | 4 ++-- lib/core/macros.nim | 2 +- lib/pure/collections/sequtils.nim | 20 +++++++++---------- lib/pure/colors.nim | 2 +- lib/pure/htmlparser.nim | 4 ++-- lib/pure/json.nim | 2 +- lib/pure/net.nim | 2 +- lib/pure/os.nim | 6 +++--- lib/pure/osproc.nim | 2 +- lib/pure/parsecfg.nim | 2 +- lib/pure/parseutils.nim | 2 +- lib/pure/parsexml.nim | 2 +- lib/pure/sockets.nim | 4 ++-- lib/pure/streams.nim | 20 +++++++++---------- lib/pure/xmlparser.nim | 4 ++-- lib/system.nim | 4 ++-- lib/system/hti.nim | 2 +- lib/wrappers/libffi/msvc/win32.c | 2 +- lib/wrappers/mysql.nim | 2 +- lib/wrappers/readline/history.nim | 2 +- lib/wrappers/readline/tweaked/history.h | 2 +- .../dependencies/chipmunk/chipmunk.nim | 2 +- .../keineschweine/lib/zlib_helpers.nim | 4 ++-- tests/types/tforwty2.nim | 2 +- tinyc/tccgen.c | 2 +- 49 files changed, 115 insertions(+), 115 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 1a5ae8aab7..18b6e6b376 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -314,7 +314,7 @@ type # XXX put this into an include file to avoid this issue! tyNone, tyBool, tyChar, tyEmpty, tyArrayConstr, tyNil, tyExpr, tyStmt, tyTypeDesc, - tyGenericInvokation, # ``T[a, b]`` for types to invoke + tyGenericInvocation, # ``T[a, b]`` for types to invoke tyGenericBody, # ``T[a, b, body]`` last parameter is the body tyGenericInst, # ``T[a, b, realInstance]`` instantiated generic type # realInstance will be a concrete type like tyObject @@ -859,7 +859,7 @@ const OverloadableSyms* = {skProc, skMethod, skIterator, skClosureIterator, skConverter, skModule, skTemplate, skMacro} - GenericTypes*: TTypeKinds = {tyGenericInvokation, tyGenericBody, + GenericTypes*: TTypeKinds = {tyGenericInvocation, tyGenericBody, tyGenericParam} StructuralEquivTypes*: TTypeKinds = {tyArrayConstr, tyNil, tyTuple, tyArray, @@ -1350,7 +1350,7 @@ proc propagateToOwner*(owner, elem: PType) = const HaveTheirOwnEmpty = {tySequence, tySet} owner.flags = owner.flags + (elem.flags * {tfHasMeta}) if tfNotNil in elem.flags: - if owner.kind in {tyGenericInst, tyGenericBody, tyGenericInvokation}: + if owner.kind in {tyGenericInst, tyGenericBody, tyGenericInvocation}: owner.flags.incl tfNotNil elif owner.kind notin HaveTheirOwnEmpty: owner.flags.incl tfNeedsInit diff --git a/compiler/canonicalizer.nim b/compiler/canonicalizer.nim index 02010961dd..50d3fd017e 100644 --- a/compiler/canonicalizer.nim +++ b/compiler/canonicalizer.nim @@ -119,8 +119,8 @@ proc hashType(c: var MD5Context, t: PType) = c.hashSym(t.sym) case t.kind - of tyGenericBody, tyGenericInst, tyGenericInvokation: - for i in countup(0, sonsLen(t) -1 -ord(t.kind != tyGenericInvokation)): + of tyGenericBody, tyGenericInst, tyGenericInvocation: + for i in countup(0, sonsLen(t) -1 -ord(t.kind != tyGenericInvocation)): c.hashType t.sons[i] of tyUserTypeClass: internalAssert t.sym != nil and t.sym.owner != nil diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 6ed4d361c2..3bc0d8afb1 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1390,7 +1390,7 @@ proc genSwap(p: BProc, e: PNode, d: var TLoc) = genAssignment(p, b, tmp, {}) proc rdSetElemLoc(a: TLoc, setType: PType): PRope = - # read a location of an set element; it may need a substraction operation + # read a location of an set element; it may need a subtraction operation # before the set operation result = rdCharLoc(a) assert(setType.kind == tySet) diff --git a/compiler/ccgmerge.nim b/compiler/ccgmerge.nim index 36da68d234..f4f8378346 100644 --- a/compiler/ccgmerge.nim +++ b/compiler/ccgmerge.nim @@ -223,7 +223,7 @@ proc processMergeInfo(L: var TBaseLexer, m: BModule) = of "typeInfo": readIntSet(L, m.typeInfoMarker) of "labels": m.labels = decodeVInt(L.buf, L.bufpos) of "hasframe": m.frameDeclared = decodeVInt(L.buf, L.bufpos) != 0 - else: internalError("ccgmerge: unkown key: " & k) + else: internalError("ccgmerge: unknown key: " & k) when not defined(nimhygiene): {.pragma: inject.} diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim index 1e1fcd6fb3..e4ce0aa6c9 100644 --- a/compiler/ccgutils.nim +++ b/compiler/ccgutils.nim @@ -96,7 +96,7 @@ proc getUniqueType*(key: PType): PType = #if obj.sym != nil and obj.sym.name.s == "TOption": # echo "for ", typeToString(key), " I returned " # debug result - of tyArrayConstr, tyGenericInvokation, tyGenericBody, + of tyArrayConstr, tyGenericInvocation, tyGenericBody, tyOpenArray, tyArray, tySet, tyRange, tyTuple, tyPtr, tyRef, tySequence, tyForward, tyVarargs, tyProxy, tyVar: # tuples are quite horrible as C does not support them directly and diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 3f4f39c279..ce2fa19362 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -126,7 +126,7 @@ proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openArray[string], if not (frmt[i] in {'A'..'Z', '_', 'a'..'z', '\x80'..'\xFF'}): break var idx = getVarIdx(varnames, id) if idx >= 0: app(result, varvalues[idx]) - else: rawMessage(errUnkownSubstitionVar, id) + else: rawMessage(errUnknownSubstitionVar, id) of '{': var id = "" inc(i) @@ -138,7 +138,7 @@ proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openArray[string], # search for the variable: var idx = getVarIdx(varnames, id) if idx >= 0: app(result, varvalues[idx]) - else: rawMessage(errUnkownSubstitionVar, id) + else: rawMessage(errUnknownSubstitionVar, id) else: internalError("ropeFormatNamedVars") var start = i while i < L: diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index beb84b00ac..34f842d4a8 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -148,7 +148,7 @@ proc mapType(typ: PType): TJSTypeKind = tyVarargs: result = etyObject of tyNil: result = etyNull - of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvokation, + of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvocation, tyNone, tyFromExpr, tyForward, tyEmpty, tyFieldAccessor, tyExpr, tyStmt, tyStatic, tyTypeDesc, tyTypeClasses: result = etyNone diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index b7dc277a43..e8c4e88dcd 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -15,7 +15,7 @@ import discard """ The basic approach is that captured vars need to be put on the heap and - that the calling chain needs to be explicitely modelled. Things to consider: + that the calling chain needs to be explicitly modelled. Things to consider: proc a = var v = 0 @@ -583,7 +583,7 @@ proc searchForInnerProcs(o: POuterContext, n: PNode, env: PEnv) = elif it.kind == nkIdentDefs: var L = sonsLen(it) if it.sons[0].kind == nkSym: - # this can be false for recursive invokations that already + # this can be false for recursive invocations that already # transformed it into 'env.varName': env.vars.incl(it.sons[0].sym.id) searchForInnerProcs(o, it.sons[L-1], env) diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 45fc2b1e24..87c6e82255 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -69,7 +69,7 @@ type errInvalidOrderInArrayConstructor, errInvalidOrderInEnumX, errEnumXHasHoles, errExceptExpected, errInvalidTry, errOptionExpected, errXisNoLabel, errNotAllCasesCovered, - errUnkownSubstitionVar, errComplexStmtRequiresInd, errXisNotCallable, + errUnknownSubstitionVar, errComplexStmtRequiresInd, errXisNotCallable, errNoPragmasAllowedForX, errNoGenericParamsAllowedForX, errInvalidParamKindX, errDefaultArgumentInvalid, errNamedParamHasToBeIdent, errNoReturnTypeForX, errConvNeedsOneArg, errInvalidPragmaX, @@ -89,7 +89,7 @@ type errTIsNotAConcreteType, errInvalidSectionStart, errGridTableNotImplemented, errGeneralParseError, errNewSectionExpected, errWhitespaceExpected, errXisNoValidIndexFile, - errCannotRenderX, errVarVarTypeNotAllowed, errInstantiateXExplicitely, + errCannotRenderX, errVarVarTypeNotAllowed, errInstantiateXExplicitly, errOnlyACallOpCanBeDelegator, errUsingNoSymbol, errMacroBodyDependsOnGenericTypes, errDestructorNotGenericEnough, @@ -279,7 +279,7 @@ const errOptionExpected: "option expected, but found \'$1\'", errXisNoLabel: "\'$1\' is not a label", errNotAllCasesCovered: "not all cases are covered", - errUnkownSubstitionVar: "unknown substitution variable: \'$1\'", + errUnknownSubstitionVar: "unknown substitution variable: \'$1\'", errComplexStmtRequiresInd: "complex statement requires indentation", errXisNotCallable: "\'$1\' is not callable", errNoPragmasAllowedForX: "no pragmas allowed for $1", @@ -325,7 +325,7 @@ const errXisNoValidIndexFile: "\'$1\' is no valid index file", errCannotRenderX: "cannot render reStructuredText element \'$1\'", errVarVarTypeNotAllowed: "type \'var var\' is not allowed", - errInstantiateXExplicitely: "instantiate '$1' explicitely", + errInstantiateXExplicitly: "instantiate '$1' explicitly", errOnlyACallOpCanBeDelegator: "only a call operator can be a delegator", errUsingNoSymbol: "'$1' is not a variable, constant or a proc name", errMacroBodyDependsOnGenericTypes: "the macro body cannot be compiled, " & diff --git a/compiler/rodread.nim b/compiler/rodread.nim index 3b3538e5d1..545a8dda93 100644 --- a/compiler/rodread.nim +++ b/compiler/rodread.nim @@ -666,7 +666,7 @@ proc newRodReader(modfilename: string, crc: TCrc32, r.readerIndex = readerIndex r.filename = modfilename initIdTable(r.syms) - # we terminate the file explicitely with ``\0``, so the cast to `cstring` + # we terminate the file explicitly with ``\0``, so the cast to `cstring` # is safe: r.s = cast[cstring](r.memfile.mem) if startsWith(r.s, "NIM:"): diff --git a/compiler/semasgn.nim b/compiler/semasgn.nim index 71ebbbafd4..61e39877af 100644 --- a/compiler/semasgn.nim +++ b/compiler/semasgn.nim @@ -184,7 +184,7 @@ proc liftBodyAux(c: TLiftCtx; t: PType; x, y: PNode) = of tyFromExpr, tyIter, tyProxy, tyBuiltInTypeClass, tyUserTypeClass, tyUserTypeClassInst, tyCompositeTypeClass, tyAnd, tyOr, tyNot, tyAnything, tyMutable, tyGenericParam, tyGenericBody, tyNil, tyExpr, tyStmt, - tyTypeDesc, tyGenericInvokation, tyBigNum, tyConst, tyForward: + tyTypeDesc, tyGenericInvocation, tyBigNum, tyConst, tyForward: internalError(c.info, "assignment requested for type: " & typeToString(t)) of tyDistinct, tyOrdinal, tyRange, tyGenericInst, tyFieldAccessor, tyStatic, tyVar: diff --git a/compiler/semdestruct.nim b/compiler/semdestruct.nim index 4ce610bf96..bbc68ee87a 100644 --- a/compiler/semdestruct.nim +++ b/compiler/semdestruct.nim @@ -30,7 +30,7 @@ proc instantiateDestructor(c: PContext, typ: PType): PType proc doDestructorStuff(c: PContext, s: PSym, n: PNode) = var t = s.typ.sons[1].skipTypes({tyVar}) - if t.kind == tyGenericInvokation: + if t.kind == tyGenericInvocation: for i in 1 .. store(any)|store(x) +# store_unknown (performs some store) --> store(any)|store(x) # load (loads from *type*), recursive (recursive call), unsafe, # endless (has endless loops), --> user effects are defined over *patterns* # --> a TR macro can annotate the proc with user defined annotations diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 07cae5d043..9c8c80d7f5 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -667,8 +667,8 @@ proc checkForMetaFields(n: PNode) = let t = n.sym.typ case t.kind of tySequence, tySet, tyArray, tyOpenArray, tyVar, tyPtr, tyRef, - tyProc, tyGenericInvokation, tyGenericInst: - let start = ord(t.kind in {tyGenericInvokation, tyGenericInst}) + tyProc, tyGenericInvocation, tyGenericInst: + let start = ord(t.kind in {tyGenericInvocation, tyGenericInst}) for i in start .. 0) and (obj.sons[0] != nil): - addInheritedFields(c, check, pos, obj.sons[0].skipGenericInvokation) + addInheritedFields(c, check, pos, obj.sons[0].skipGenericInvocation) addInheritedFieldsAux(c, check, pos, obj.n) proc semObjectNode(c: PContext, n: PNode, prev: PType): PType = @@ -632,7 +632,7 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType): PType = checkSonsLen(n, 3) if n.sons[1].kind != nkEmpty: base = skipTypes(semTypeNode(c, n.sons[1].sons[0], nil), skipPtrs) - var concreteBase = skipGenericInvokation(base).skipTypes(skipPtrs) + var concreteBase = skipGenericInvocation(base).skipTypes(skipPtrs) if concreteBase.kind == tyObject and tfFinal notin concreteBase.flags: addInheritedFields(c, check, pos, concreteBase) else: @@ -777,12 +777,12 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, result = paramType of tyGenericBody: - result = newTypeS(tyGenericInvokation, c) + 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 'tyUnkown' + result.rawAddSon makeTypeFromExpr(c, ast.emptyNode) # aka 'tyUnknown' else: result.rawAddSon newTypeS(tyAnything, c) @@ -823,7 +823,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, result = liftBody result.shouldHaveMeta - of tyGenericInvokation: + of tyGenericInvocation: for i in 1 .. tyGenericInvokation") + if x.kind == tyGenericInvocation or f.sons[0].kind != tyGenericBody: + #InternalError("typeRel: tyGenericInvocation -> tyGenericInvocation") # simply no match for now: discard elif x.kind == tyGenericInst and @@ -897,7 +897,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = # we steal the generic parameters from the tyGenericBody: for i in countup(1, sonsLen(f) - 1): var x = PType(idTableGet(c.bindings, f.sons[0].sons[i - 1])) - if x == nil or x.kind in {tyGenericInvokation, tyGenericParam}: + if x == nil or x.kind in {tyGenericInvocation, tyGenericParam}: internalError("wrong instantiated type!") put(c.bindings, f.sons[i], x) diff --git a/compiler/types.nim b/compiler/types.nim index 3711a96683..2422d5305a 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -396,7 +396,7 @@ proc rangeToStr(n: PNode): string = const typeToStr: array[TTypeKind, string] = ["None", "bool", "Char", "empty", "Array Constructor [$1]", "nil", "expr", "stmt", "typeDesc", - "GenericInvokation", "GenericBody", "GenericInst", "GenericParam", + "GenericInvocation", "GenericBody", "GenericInst", "GenericParam", "distinct $1", "enum", "ordinal[$1]", "array[$1, $2]", "object", "tuple", "set[$1]", "range[$1]", "ptr ", "ref ", "var ", "seq[$1]", "proc", "pointer", "OpenArray[$1]", "string", "CString", "Forward", @@ -432,9 +432,9 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = result = $t.n.intVal else: result = "int literal(" & $t.n.intVal & ")" - of tyGenericBody, tyGenericInst, tyGenericInvokation: + of tyGenericBody, tyGenericInst, tyGenericInvocation: result = typeToString(t.sons[0]) & '[' - for i in countup(1, sonsLen(t) -1 -ord(t.kind != tyGenericInvokation)): + for i in countup(1, sonsLen(t) -1 -ord(t.kind != tyGenericInvocation)): if i > 1: add(result, ", ") add(result, typeToString(t.sons[i], preferGenericArg)) add(result, ']') @@ -941,7 +941,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = result = sameChildrenAux(a, b, c) and sameFlags(a, b) if result and ExactGenericParams in c.flags: result = a.sym.position == b.sym.position - of tyGenericInvokation, tyGenericBody, tySequence, + of tyGenericInvocation, tyGenericBody, tySequence, tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc, tyConst, tyMutable, tyVarargs, tyIter, tyOrdinal, tyTypeClasses, tyFieldAccessor: @@ -1087,7 +1087,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, if taField notin flags: result = t of tyTypeClasses: if not (tfGenericTypeParam in t.flags or taField notin flags): result = t - of tyGenericBody, tyGenericParam, tyGenericInvokation, + of tyGenericBody, tyGenericParam, tyGenericInvocation, tyNone, tyForward, tyFromExpr, tyFieldAccessor: result = t of tyNil: diff --git a/doc/advopt.txt b/doc/advopt.txt index ae474afc65..197c0d7da9 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -18,7 +18,7 @@ Advanced commands: track a file, currently not saved to disk --suggest suggest all possible symbols at position --def list all possible definitions at position - --context list possible invokation context + --context list possible invocation context --usages list all usages of the symbol at position --eval evaluates an expression //serve start the compiler as a service mode (CAAS) diff --git a/doc/idetools.txt b/doc/idetools.txt index 48197f8bf9..81de9598ce 100644 --- a/doc/idetools.txt +++ b/doc/idetools.txt @@ -27,7 +27,7 @@ integrations `_ already available. -Idetools invokation +Idetools invocation =================== Specifying the location of the query @@ -35,7 +35,7 @@ Specifying the location of the query All of the available idetools commands require you to specify a query location through the ``--track`` or ``--trackDirty`` switches. -The general idetools invokations are:: +The general idetools invocations are:: nim idetools --track:FILE,LINE,COL proj.nim @@ -129,7 +129,7 @@ the suggestions sorted first by scope (from innermost to outermost) and then by item name. -Invokation context +Invocation context ------------------ The ``--context`` idetools switch is very similar to the suggestions diff --git a/doc/intern.txt b/doc/intern.txt index a103703d7e..93dcce059b 100644 --- a/doc/intern.txt +++ b/doc/intern.txt @@ -236,7 +236,7 @@ too. Type converters fall into this category: If in the above example module ``B`` is re-compiled, but ``A`` is not then ``B`` needs to be aware of ``toBool`` even though ``toBool`` is not referenced -in ``B`` *explicitely*. +in ``B`` *explicitly*. Both the multi method and the type converter problems are solved by storing them in special sections in the ROD file that are loaded *unconditionally* diff --git a/koch.nim b/koch.nim index b0b4a79da0..9a7afae3db 100644 --- a/koch.nim +++ b/koch.nim @@ -270,13 +270,13 @@ when defined(withUpdate): echo("Fetching updates from repo...") var pullout = execCmdEx(git & " pull origin master") if pullout[1] != 0: - quit("An error has occured.") + quit("An error has occurred.") else: if pullout[0].startsWith("Already up-to-date."): quit("No new changes fetched from the repo. " & "Local branch must be ahead of it. Exiting...") else: - quit("An error has occured.") + quit("An error has occurred.") else: echo("No repo or executable found!") diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 4c561df703..ddbd7a76fb 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -76,7 +76,7 @@ type TNimrodTypeKind* = enum ntyNone, ntyBool, ntyChar, ntyEmpty, ntyArrayConstr, ntyNil, ntyExpr, ntyStmt, - ntyTypeDesc, ntyGenericInvokation, ntyGenericBody, ntyGenericInst, + ntyTypeDesc, ntyGenericInvocation, ntyGenericBody, ntyGenericInst, ntyGenericParam, ntyDistinct, ntyEnum, ntyOrdinal, ntyArray, ntyObject, ntyTuple, ntySet, ntyRange, ntyPtr, ntyRef, ntyVar, diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim index b527b93687..1ec122e78c 100644 --- a/lib/pure/collections/sequtils.nim +++ b/lib/pure/collections/sequtils.nim @@ -320,7 +320,7 @@ template foldl*(sequence, operation: expr): expr = ## ## The ``operation`` parameter should be an expression which uses the ## variables ``a`` and ``b`` for each step of the fold. Since this is a left - ## fold, for non associative binary operations like substraction think that + ## fold, for non associative binary operations like subtraction think that ## the sequence of numbers 1, 2 and 3 will be parenthesized as (((1) - 2) - ## 3). Example: ## @@ -328,12 +328,12 @@ template foldl*(sequence, operation: expr): expr = ## let ## numbers = @[5, 9, 11] ## addition = foldl(numbers, a + b) - ## substraction = foldl(numbers, a - b) + ## subtraction = foldl(numbers, a - b) ## multiplication = foldl(numbers, a * b) ## words = @["nim", "is", "cool"] ## concatenation = foldl(words, a & b) ## assert addition == 25, "Addition is (((5)+9)+11)" - ## assert substraction == -15, "Substraction is (((5)-9)-11)" + ## assert subtraction == -15, "Substraction is (((5)-9)-11)" ## assert multiplication == 495, "Multiplication is (((5)*9)*11)" ## assert concatenation == "nimiscool" assert sequence.len > 0, "Can't fold empty sequences" @@ -356,7 +356,7 @@ template foldr*(sequence, operation: expr): expr = ## ## The ``operation`` parameter should be an expression which uses the ## variables ``a`` and ``b`` for each step of the fold. Since this is a right - ## fold, for non associative binary operations like substraction think that + ## fold, for non associative binary operations like subtraction think that ## the sequence of numbers 1, 2 and 3 will be parenthesized as (1 - (2 - ## (3))). Example: ## @@ -364,12 +364,12 @@ template foldr*(sequence, operation: expr): expr = ## let ## numbers = @[5, 9, 11] ## addition = foldr(numbers, a + b) - ## substraction = foldr(numbers, a - b) + ## subtraction = foldr(numbers, a - b) ## multiplication = foldr(numbers, a * b) ## words = @["nim", "is", "cool"] ## concatenation = foldr(words, a & b) ## assert addition == 25, "Addition is (5+(9+(11)))" - ## assert substraction == 7, "Substraction is (5-(9-(11)))" + ## assert subtraction == 7, "Substraction is (5-(9-(11)))" ## assert multiplication == 495, "Multiplication is (5*(9*(11)))" ## assert concatenation == "nimiscool" assert sequence.len > 0, "Can't fold empty sequences" @@ -507,12 +507,12 @@ when isMainModule: let numbers = @[5, 9, 11] addition = foldl(numbers, a + b) - substraction = foldl(numbers, a - b) + subtraction = foldl(numbers, a - b) multiplication = foldl(numbers, a * b) words = @["nim", "is", "cool"] concatenation = foldl(words, a & b) assert addition == 25, "Addition is (((5)+9)+11)" - assert substraction == -15, "Substraction is (((5)-9)-11)" + assert subtraction == -15, "Substraction is (((5)-9)-11)" assert multiplication == 495, "Multiplication is (((5)*9)*11)" assert concatenation == "nimiscool" @@ -520,12 +520,12 @@ when isMainModule: let numbers = @[5, 9, 11] addition = foldr(numbers, a + b) - substraction = foldr(numbers, a - b) + subtraction = foldr(numbers, a - b) multiplication = foldr(numbers, a * b) words = @["nim", "is", "cool"] concatenation = foldr(words, a & b) assert addition == 25, "Addition is (5+(9+(11)))" - assert substraction == 7, "Substraction is (5-(9-(11)))" + assert subtraction == 7, "Substraction is (5-(9-(11)))" assert multiplication == 495, "Multiplication is (5*(9*(11)))" assert concatenation == "nimiscool" diff --git a/lib/pure/colors.nim b/lib/pure/colors.nim index 7942255cb5..5b1904e542 100644 --- a/lib/pure/colors.nim +++ b/lib/pure/colors.nim @@ -392,7 +392,7 @@ proc parseColor*(name: string): Color = result = Color(parseHexInt(name)) else: var idx = binaryStrSearch(colorNames, name) - if idx < 0: raise newException(ValueError, "unkown color: " & name) + if idx < 0: raise newException(ValueError, "unknown color: " & name) result = colorNames[idx][1] proc isColor*(name: string): bool = diff --git a/lib/pure/htmlparser.nim b/lib/pure/htmlparser.nim index e2cbb4949c..5e4eba4e53 100644 --- a/lib/pure/htmlparser.nim +++ b/lib/pure/htmlparser.nim @@ -552,7 +552,7 @@ proc parse(x: var XmlParser, errors: var seq[string]): XmlNode = proc parseHtml*(s: Stream, filename: string, errors: var seq[string]): XmlNode = ## parses the XML from stream `s` and returns a ``PXmlNode``. Every - ## occured parsing error is added to the `errors` sequence. + ## occurred parsing error is added to the `errors` sequence. var x: XmlParser open(x, s, filename, {reportComments, reportWhitespace}) next(x) @@ -581,7 +581,7 @@ proc parseHtml*(s: Stream): XmlNode = proc loadHtml*(path: string, errors: var seq[string]): XmlNode = ## Loads and parses HTML from file specified by ``path``, and returns - ## a ``PXmlNode``. Every occured parsing error is added to + ## a ``PXmlNode``. Every occurred parsing error is added to ## the `errors` sequence. var s = newFileStream(path, fmRead) if s == nil: raise newException(IOError, "Unable to read file: " & path) diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 2a40b4f1f8..2038b246dc 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -55,7 +55,7 @@ import type JsonEventKind* = enum ## enumeration of all events that may occur when parsing - jsonError, ## an error ocurred during parsing + jsonError, ## an error occurred during parsing jsonEof, ## end of file reached jsonString, ## a string literal jsonInt, ## an integer literal diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 2b81b6fb01..809b7fb69e 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -258,7 +258,7 @@ proc socketError*(socket: Socket, err: int = -1, async = false, of SSL_ERROR_WANT_X509_LOOKUP: raiseSSLError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL: - var errStr = "IO error has occured " + var errStr = "IO error has occurred " let sslErr = ErrPeekLastError() if sslErr == 0 and err == 0: errStr.add "because an EOF was observed that violates the protocol" diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 820800a1a7..d9a5be14a6 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -185,7 +185,7 @@ const proc osErrorMsg*(): string {.rtl, extern: "nos$1", deprecated.} = ## Retrieves the operating system's error flag, ``errno``. ## On Windows ``GetLastError`` is checked before ``errno``. - ## Returns "" if no error occured. + ## Returns "" if no error occurred. ## ## **Deprecated since version 0.9.4**: use the other ``osErrorMsg`` proc. @@ -1099,7 +1099,7 @@ when defined(windows): var env = getEnvironmentStringsW() e = env - if e == nil: return # an error occured + if e == nil: return # an error occurred while true: var eend = strEnd(e) add(environment, $e) @@ -1110,7 +1110,7 @@ when defined(windows): var env = getEnvironmentStringsA() e = env - if e == nil: return # an error occured + if e == nil: return # an error occurred while true: var eend = strEnd(e) add(environment, $e) diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 6361dfb092..cddedf48ae 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -146,7 +146,7 @@ proc startProcess*(command: string, ## of `args` to `command` carefully escaping/quoting any special characters, ## since it will be passed *as is* to the system shell. Each system/shell may ## feature different escaping rules, so try to avoid this kind of shell - ## invokation if possible as it leads to non portable software. + ## invocation if possible as it leads to non portable software. ## ## Return value: The newly created process object. Nil is never returned, ## but ``EOS`` is raised in case of an error. diff --git a/lib/pure/parsecfg.nim b/lib/pure/parsecfg.nim index bb9d2aed25..bb64c8134f 100644 --- a/lib/pure/parsecfg.nim +++ b/lib/pure/parsecfg.nim @@ -35,7 +35,7 @@ type cfgSectionStart, ## a ``[section]`` has been parsed cfgKeyValuePair, ## a ``key=value`` pair has been detected cfgOption, ## a ``--key=value`` command line option - cfgError ## an error ocurred during parsing + cfgError ## an error occurred during parsing CfgEvent* = object of RootObj ## describes a parsing event case kind*: CfgEventKind ## the kind of the event diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim index 2c677fdc20..abe5aa90e1 100644 --- a/lib/pure/parseutils.nim +++ b/lib/pure/parseutils.nim @@ -240,7 +240,7 @@ proc parseBiggestFloat*(s: string, number: var BiggestFloat, start = 0): int {. proc parseFloat*(s: string, number: var float, start = 0): int {. rtl, extern: "npuParseFloat", noSideEffect.} = ## parses a float starting at `start` and stores the value into `number`. - ## Result is the number of processed chars or 0 if there occured a parsing + ## Result is the number of processed chars or 0 if there occurred a parsing ## error. var bf: BiggestFloat result = parseBiggestFloat(s, bf, start) diff --git a/lib/pure/parsexml.nim b/lib/pure/parsexml.nim index 39dead3c00..b957c0cf7b 100644 --- a/lib/pure/parsexml.nim +++ b/lib/pure/parsexml.nim @@ -57,7 +57,7 @@ import type XmlEventKind* = enum ## enumation of all events that may occur when parsing - xmlError, ## an error ocurred during parsing + xmlError, ## an error occurred during parsing xmlEof, ## end of file reached xmlCharData, ## character data xmlWhitespace, ## whitespace has been parsed diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 11eeefcb9a..6c32717a90 100644 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -1467,7 +1467,7 @@ proc recvAsync*(socket: Socket, s: var TaintedString): bool {. of SSL_ERROR_ZERO_RETURN: raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: - raiseSslError("Unexpected error occured.") # This should just not happen. + raiseSslError("Unexpected error occurred.") # This should just not happen. of SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ: return false of SSL_ERROR_WANT_X509_LOOKUP: @@ -1610,7 +1610,7 @@ proc sendAsync*(socket: Socket, data: string): int {.tags: [WriteIOEffect].} = of SSL_ERROR_ZERO_RETURN: raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: - raiseSslError("Unexpected error occured.") # This should just not happen. + raiseSslError("Unexpected error occurred.") # This should just not happen. of SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ: return 0 of SSL_ERROR_WANT_X509_LOOKUP: diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index 55351ffd44..67c80e5926 100644 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.nim @@ -122,41 +122,41 @@ proc read[T](s: Stream, result: var T) = raise newEIO("cannot read from stream") proc readChar*(s: Stream): char = - ## reads a char from the stream `s`. Raises `EIO` if an error occured. + ## reads a char from the stream `s`. Raises `EIO` if an error occurred. ## Returns '\0' as an EOF marker. if readData(s, addr(result), sizeof(result)) != 1: result = '\0' proc readBool*(s: Stream): bool = - ## reads a bool from the stream `s`. Raises `EIO` if an error occured. + ## reads a bool from the stream `s`. Raises `EIO` if an error occurred. read(s, result) proc readInt8*(s: Stream): int8 = - ## reads an int8 from the stream `s`. Raises `EIO` if an error occured. + ## reads an int8 from the stream `s`. Raises `EIO` if an error occurred. read(s, result) proc readInt16*(s: Stream): int16 = - ## reads an int16 from the stream `s`. Raises `EIO` if an error occured. + ## reads an int16 from the stream `s`. Raises `EIO` if an error occurred. read(s, result) proc readInt32*(s: Stream): int32 = - ## reads an int32 from the stream `s`. Raises `EIO` if an error occured. + ## reads an int32 from the stream `s`. Raises `EIO` if an error occurred. read(s, result) proc readInt64*(s: Stream): int64 = - ## reads an int64 from the stream `s`. Raises `EIO` if an error occured. + ## reads an int64 from the stream `s`. Raises `EIO` if an error occurred. read(s, result) proc readFloat32*(s: Stream): float32 = - ## reads a float32 from the stream `s`. Raises `EIO` if an error occured. + ## reads a float32 from the stream `s`. Raises `EIO` if an error occurred. read(s, result) proc readFloat64*(s: Stream): float64 = - ## reads a float64 from the stream `s`. Raises `EIO` if an error occured. + ## reads a float64 from the stream `s`. Raises `EIO` if an error occurred. read(s, result) proc readStr*(s: Stream, length: int): TaintedString = ## reads a string of length `length` from the stream `s`. Raises `EIO` if - ## an error occured. + ## an error occurred. result = newString(length).TaintedString var L = readData(s, addr(string(result)[0]), length) if L != length: setLen(result.string, L) @@ -183,7 +183,7 @@ proc readLine*(s: Stream, line: var TaintedString): bool = proc readLine*(s: Stream): TaintedString = ## Reads a line from a stream `s`. Note: This is not very efficient. Raises - ## `EIO` if an error occured. + ## `EIO` if an error occurred. result = TaintedString"" while true: var c = readChar(s) diff --git a/lib/pure/xmlparser.nim b/lib/pure/xmlparser.nim index 8591e894ce..755bfcdbc4 100644 --- a/lib/pure/xmlparser.nim +++ b/lib/pure/xmlparser.nim @@ -103,7 +103,7 @@ proc parse(x: var XmlParser, errors: var seq[string]): XmlNode = proc parseXml*(s: Stream, filename: string, errors: var seq[string]): XmlNode = ## parses the XML from stream `s` and returns a ``PXmlNode``. Every - ## occured parsing error is added to the `errors` sequence. + ## occurred parsing error is added to the `errors` sequence. var x: XmlParser open(x, s, filename, {reportComments}) while true: @@ -129,7 +129,7 @@ proc parseXml*(s: Stream): XmlNode = proc loadXml*(path: string, errors: var seq[string]): XmlNode = ## Loads and parses XML from file specified by ``path``, and returns - ## a ``PXmlNode``. Every occured parsing error is added to the `errors` + ## a ``PXmlNode``. Every occurred parsing error is added to the `errors` ## sequence. var s = newFileStream(path, fmRead) if s == nil: raise newException(IOError, "Unable to read file: " & path) diff --git a/lib/system.nim b/lib/system.nim index 9dc233cb76..825c2597de 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -357,7 +357,7 @@ type ## ## See the full `exception hierarchy`_. IOError* = object of SystemError ## \ - ## Raised if an IO error occured. + ## Raised if an IO error occurred. ## ## See the full `exception hierarchy`_. OSError* = object of SystemError ## \ @@ -374,7 +374,7 @@ type ## ## See the full `exception hierarchy`_. ArithmeticError* = object of Exception ## \ - ## Raised if any kind of arithmetic error occured. + ## Raised if any kind of arithmetic error occurred. ## ## See the full `exception hierarchy`_. DivByZeroError* = object of ArithmeticError ## \ diff --git a/lib/system/hti.nim b/lib/system/hti.nim index e599668a72..7dee054ac0 100644 --- a/lib/system/hti.nim +++ b/lib/system/hti.nim @@ -26,7 +26,7 @@ type tyExpr, tyStmt, tyTypeDesc, - tyGenericInvokation, # ``T[a, b]`` for types to invoke + tyGenericInvocation, # ``T[a, b]`` for types to invoke tyGenericBody, # ``T[a, b, body]`` last parameter is the body tyGenericInst, # ``T[a, b, realInstance]`` instantiated generic type tyGenericParam, # ``a`` in the example diff --git a/lib/wrappers/libffi/msvc/win32.c b/lib/wrappers/libffi/msvc/win32.c index d1149a85eb..2754fd35d7 100644 --- a/lib/wrappers/libffi/msvc/win32.c +++ b/lib/wrappers/libffi/msvc/win32.c @@ -90,7 +90,7 @@ noclean: // If the return value pointer is NULL, assume no return value. /* - Intel asm is weird. We have to explicitely specify 'DWORD PTR' in the nexr instruction, + Intel asm is weird. We have to explicitly specify 'DWORD PTR' in the nexr instruction, otherwise only one BYTE will be compared (instead of a DWORD)! */ cmp DWORD PTR [ebp + 24], 0 diff --git a/lib/wrappers/mysql.nim b/lib/wrappers/mysql.nim index 3857744ae1..13f3cd1449 100644 --- a/lib/wrappers/mysql.nim +++ b/lib/wrappers/mysql.nim @@ -790,7 +790,7 @@ proc server_init*(argc: cint, argv: cstringArray, groups: cstringArray): cint{. proc server_end*(){.cdecl, dynlib: lib, importc: "mysql_server_end".} # mysql_server_init/end need to be called when using libmysqld or # libmysqlclient (exactly, mysql_server_init() is called by mysql_init() so - # you don't need to call it explicitely; but you need to call + # you don't need to call it explicitly; but you need to call # mysql_server_end() to free memory). The names are a bit misleading # (mysql_SERVER* to be used when using libmysqlCLIENT). So we add more general # names which suit well whether you're using libmysqld or libmysqlclient. We diff --git a/lib/wrappers/readline/history.nim b/lib/wrappers/readline/history.nim index caa857ceb4..495bc15e42 100644 --- a/lib/wrappers/readline/history.nim +++ b/lib/wrappers/readline/history.nim @@ -231,7 +231,7 @@ proc history_truncate_file*(a2: cstring, a3: cint): cint{.cdecl, # -1) If there was an error in expansion. # 2) If the returned line should just be printed. # -# If an error ocurred in expansion, then OUTPUT contains a descriptive +# If an error occurred in expansion, then OUTPUT contains a descriptive # error message. proc history_expand*(a2: cstring, a3: cstringArray): cint{.cdecl, diff --git a/lib/wrappers/readline/tweaked/history.h b/lib/wrappers/readline/tweaked/history.h index 53bd642b11..b791237904 100644 --- a/lib/wrappers/readline/tweaked/history.h +++ b/lib/wrappers/readline/tweaked/history.h @@ -217,7 +217,7 @@ extern int history_truncate_file PARAMS((const char *, int)); -1) If there was an error in expansion. 2) If the returned line should just be printed. - If an error ocurred in expansion, then OUTPUT contains a descriptive + If an error occurred in expansion, then OUTPUT contains a descriptive error message. */ extern int history_expand PARAMS((char *, char **)); diff --git a/tests/manyloc/keineschweine/dependencies/chipmunk/chipmunk.nim b/tests/manyloc/keineschweine/dependencies/chipmunk/chipmunk.nim index 08f1dad505..493a2106cd 100644 --- a/tests/manyloc/keineschweine/dependencies/chipmunk/chipmunk.nim +++ b/tests/manyloc/keineschweine/dependencies/chipmunk/chipmunk.nim @@ -279,7 +279,7 @@ type PSegmentQueryInfo* = ptr TSegmentQueryInfo #/ Segment query info struct. TSegmentQueryInfo*{.pf.} = object - shape*: PShape #/ The shape that was hit, NULL if no collision occured. + shape*: PShape #/ The shape that was hit, NULL if no collision occurred. t*: CpFloat #/ The normalized distance along the query segment in the range [0, 1]. n*: TVector #/ The normal of the surface hit. TShapeType*{.size: sizeof(cint).} = enum diff --git a/tests/manyloc/keineschweine/lib/zlib_helpers.nim b/tests/manyloc/keineschweine/lib/zlib_helpers.nim index ef977afb07..9a6542d75f 100644 --- a/tests/manyloc/keineschweine/lib/zlib_helpers.nim +++ b/tests/manyloc/keineschweine/lib/zlib_helpers.nim @@ -8,7 +8,7 @@ proc compress*(source: string): string = result.setLen destLen var res = zlib.compress(cstring(result), addr destLen, cstring(source), sourceLen) if res != Z_OK: - echo "Error occured: ", res + echo "Error occurred: ", res elif destLen < result.len: result.setLen(destLen) @@ -17,7 +17,7 @@ proc uncompress*(source: string, destLen: var int): string = result.setLen destLen var res = zlib.uncompress(cstring(result), addr destLen, cstring(source), source.len) if res != Z_OK: - echo "Error occured: ", res + echo "Error occurred: ", res when isMainModule: diff --git a/tests/types/tforwty2.nim b/tests/types/tforwty2.nim index d103314c57..52af1c7dd3 100644 --- a/tests/types/tforwty2.nim +++ b/tests/types/tforwty2.nim @@ -1,5 +1,5 @@ # Test for a hard to fix internal error -# occured in the SDL library +# occurred in the SDL library {.push dynlib: "SDL.dll", callconv: cdecl.} diff --git a/tinyc/tccgen.c b/tinyc/tccgen.c index 3135e7b37f..2eacff2c74 100644 --- a/tinyc/tccgen.c +++ b/tinyc/tccgen.c @@ -1203,7 +1203,7 @@ static inline int is_integer_btype(int bt) bt == VT_INT || bt == VT_LLONG); } -/* check types for comparison or substraction of pointers */ +/* check types for comparison or subtraction of pointers */ static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op) { CType *type1, *type2, tmp_type1, tmp_type2; From 657dca5c3b26a088ac291e06308d44d5e52c162f Mon Sep 17 00:00:00 2001 From: Federico Ceratto Date: Sun, 15 Feb 2015 16:20:32 +0000 Subject: [PATCH 346/850] Fix typos --- compiler/cgen.nim | 2 +- compiler/docgen.nim | 2 +- compiler/lambdalifting.nim | 2 +- compiler/lexer.nim | 4 ++-- compiler/msgs.nim | 2 +- compiler/nimblecmd.nim | 2 +- compiler/patterns.nim | 4 ++-- compiler/rodwrite.nim | 2 +- compiler/ropes.nim | 2 +- compiler/semcall.nim | 2 +- compiler/semexprs.nim | 2 +- compiler/semstmts.nim | 2 +- compiler/semtempl.nim | 2 +- compiler/semtypes.nim | 2 +- compiler/types.nim | 2 +- compiler/vmgen.nim | 2 +- config/nimdoc.cfg | 4 ++-- doc/backends.txt | 4 ++-- doc/idetools.txt | 6 +++--- doc/intern.txt | 4 ++-- doc/lib.txt | 2 +- doc/manual/about.txt | 4 ++-- doc/manual/syntax.txt | 2 +- doc/manual/types.txt | 2 +- doc/nimc.txt | 2 +- doc/nimgrep.txt | 8 ++++---- doc/tut2.txt | 6 +++--- examples/cross_calculator/android/readme.txt | 2 +- examples/cross_calculator/ios/src/NRViewController.m | 2 +- examples/cross_todo/nim_backend/backend.nim | 2 +- lib/core/locks.nim | 2 +- lib/packages/docutils/rstgen.nim | 2 +- lib/pure/asyncdispatch.nim | 2 +- lib/pure/basic2d.nim | 6 +++--- lib/pure/basic3d.nim | 8 ++++---- lib/pure/collections/LockFreeHash.nim | 2 +- lib/pure/collections/critbits.nim | 2 +- lib/pure/collections/sequtils.nim | 8 ++++---- lib/pure/collections/tables.nim | 2 +- lib/pure/colors.nim | 2 +- lib/pure/encodings.nim | 2 +- lib/pure/events.nim | 2 +- lib/pure/httpclient.nim | 4 ++-- lib/pure/logging.nim | 2 +- lib/pure/net.nim | 2 +- lib/pure/os.nim | 4 ++-- lib/pure/parseopt2.nim | 2 +- lib/pure/parseutils.nim | 2 +- lib/pure/ropes.nim | 2 +- lib/pure/selectors.nim | 2 +- lib/pure/sockets.nim | 2 +- lib/pure/strutils.nim | 10 +++++----- lib/pure/xmldom.nim | 2 +- lib/system.nim | 8 ++++---- lib/system/arithm.nim | 2 +- lib/system/cgprocs.nim | 2 +- lib/system/dyncalls.nim | 2 +- lib/system/gc.nim | 2 +- lib/system/gc2.nim | 4 ++-- lib/system/gc_ms.nim | 2 +- lib/system/jssys.nim | 2 +- lib/system/sysio.nim | 2 +- lib/system/sysstr.nim | 4 ++-- lib/wrappers/mysql.nim | 8 ++++---- lib/wrappers/sdl/sdl.nim | 10 +++++----- lib/wrappers/sdl/sdl_mixer.nim | 2 +- tests/caas/issue_416_template_shift.txt | 2 +- tests/caas/its_full_of_procs.nim | 2 +- tinyc/arm-gen.c | 2 +- tinyc/c67-gen.c | 2 +- tinyc/i386-asm.c | 2 +- tinyc/lib/bcheck.c | 2 +- tinyc/tcc-doc.html | 6 +++--- tinyc/tcc-doc.texi | 6 +++--- tinyc/tccasm.c | 2 +- tinyc/tccgen.c | 2 +- tinyc/tcctok.h | 2 +- tinyc/win32/include/fcntl.h | 2 +- tools/nimgrep.nim | 2 +- tools/nimrepl.nim | 2 +- web/news.txt | 6 +++--- 81 files changed, 126 insertions(+), 126 deletions(-) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index a606cb5b96..cc376d87a7 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -395,7 +395,7 @@ proc localVarDecl(p: BProc; s: PSym): PRope = proc assignLocalVar(p: BProc, s: PSym) = #assert(s.loc.k == locNone) # not yet assigned - # this need not be fullfilled for inline procs; they are regenerated + # this need not be fulfilled for inline procs; they are regenerated # for each module that uses them! let decl = localVarDecl(p, s).con(";" & tnl) line(p, cpsLocals, decl) diff --git a/compiler/docgen.nim b/compiler/docgen.nim index ce2fa19362..5439922aff 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -272,7 +272,7 @@ proc complexName(k: TSymKind, n: PNode, baseName: string): string = ## type)?(,param type)*``. The callable type part will be added only if the ## node is not a proc, as those are the common ones. The suffix will be a dot ## and a single letter representing the type of the callable. The parameter - ## types will be added with a preceeding dash. Return types won't be added. + ## types will be added with a preceding dash. Return types won't be added. ## ## If you modify the output of this proc, please update the anchor generation ## section of ``doc/docgen.txt``. diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index e8c4e88dcd..123445e1f4 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -999,7 +999,7 @@ proc liftForLoop*(body: PNode): PNode = # proc invoke(iter: iterator(): int) = # for x in iter(): echo x # - # --> When to create the closure? --> for the (count) occurence! + # --> When to create the closure? --> for the (count) occurrence! discard """ for i in foo(): ... diff --git a/compiler/lexer.nim b/compiler/lexer.nim index 4fbac2d5cb..fc40192b81 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -107,7 +107,7 @@ type TToken* = object # a Nim token tokType*: TTokType # the type of the token indent*: int # the indentation; != -1 if the token has been - # preceeded with indentation + # preceded with indentation ident*: PIdent # the parsed identifier iNumber*: BiggestInt # the parsed integer literal fNumber*: BiggestFloat # the parsed floating point literal @@ -679,7 +679,7 @@ proc getOperator(L: var TLexer, tok: var TToken) = inc(pos) endOperator(L, tok, pos, h) # advance pos but don't store it in L.bufpos so the next token (which might - # be an operator too) gets the preceeding spaces: + # be an operator too) gets the preceding spaces: tok.strongSpaceB = 0 while buf[pos] == ' ': inc pos diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 87c6e82255..7b94a34086 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -359,7 +359,7 @@ const errCannotInferReturnType: "cannot infer the return type of the proc", errGenericLambdaNotAllowed: "A nested proc can have generic parameters only when " & "it is used as an operand to another routine and the types " & - "of the generic paramers can be infered from the expected signature.", + "of the generic paramers can be inferred from the expected signature.", errCompilerDoesntSupportTarget: "The current compiler \'$1\' doesn't support the requested compilation target", errUser: "$1", warnCannotOpenFile: "cannot open \'$1\' [CannotOpenFile]", diff --git a/compiler/nimblecmd.nim b/compiler/nimblecmd.nim index 049b94aa96..23f3331a23 100644 --- a/compiler/nimblecmd.nim +++ b/compiler/nimblecmd.nim @@ -33,7 +33,7 @@ proc `<.`(a, b: string): bool = while true: let ii = parseInt(a, verA, i) let jj = parseInt(b, verB, j) - # if A has no number left, but B has, B is prefered: 0.8 vs 0.8.3 + # if A has no number left, but B has, B is preferred: 0.8 vs 0.8.3 if ii <= 0 or jj <= 0: return jj > 0 if verA < verB: return true elif verA > verB: return false diff --git a/compiler/patterns.nim b/compiler/patterns.nim index 9ac0988c5e..368b0b37be 100644 --- a/compiler/patterns.nim +++ b/compiler/patterns.nim @@ -275,7 +275,7 @@ proc applyRule*(c: PContext, s: PSym, n: PNode): PNode = if arg != rs and aliases.isPartOf(rs, arg) == arYes: ok = true break - # constraint not fullfilled: + # constraint not fulfilled: if not ok: return nil of aqNoAlias: # it MUST not alias with any other param: @@ -284,7 +284,7 @@ proc applyRule*(c: PContext, s: PSym, n: PNode): PNode = if arg != rs and aliases.isPartOf(rs, arg) != arNo: ok = false break - # constraint not fullfilled: + # constraint not fulfilled: if not ok: return nil markUsed(n.info, s) diff --git a/compiler/rodwrite.nim b/compiler/rodwrite.nim index 9fed7ac52e..0f211b4baf 100644 --- a/compiler/rodwrite.nim +++ b/compiler/rodwrite.nim @@ -200,7 +200,7 @@ proc encodeType(w: PRodWriter, t: PType, result: var string) = return # we need no surrounding [] here because the type is in a line of its own if t.kind == tyForward: internalError("encodeType: tyForward") - # for the new rodfile viewer we use a preceeding [ so that the data section + # for the new rodfile viewer we use a preceding [ so that the data section # can easily be disambiguated: add(result, '[') encodeVInt(ord(t.kind), result) diff --git a/compiler/ropes.nim b/compiler/ropes.nim index b140816943..ad6801d18c 100644 --- a/compiler/ropes.nim +++ b/compiler/ropes.nim @@ -52,7 +52,7 @@ # Note that the left and right pointers are not needed for leaves. # Leaves have relatively high memory overhead (~30 bytes on a 32 # bit machines) and we produce many of them. This is why we cache and -# share leaves accross different rope trees. +# share leaves across different rope trees. # To cache them they are inserted in a `cache` array. import diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 5cb7130305..43fd5fb864 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -264,7 +264,7 @@ proc inferWithMetatype(c: PContext, formal: PType, instGenericConvertersArg(c, result, m) if result != nil: # This almost exactly replicates the steps taken by the compiler during - # param matching. It performs an embarassing ammount of back-and-forth + # param matching. It performs an embarrassing amount of back-and-forth # type jugling, but it's the price to pay for consistency and correctness result.typ = generateTypeInstance(c, m.bindings, arg.info, formal.skipTypes({tyCompositeTypeClass})) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 786479b955..bce7666267 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1917,7 +1917,7 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = it.sons[0] = newSymNode(f) e = fitNode(c, f.typ, e) # small hack here in a nkObjConstr the ``nkExprColonExpr`` node can have - # 3 childen the last being the field check + # 3 children the last being the field check if check != nil: check.sons[0] = it.sons[0] it.add(check) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 9c8c80d7f5..42471bae76 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -369,7 +369,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = typ = def.typ else: # BUGFIX: ``fitNode`` is needed here! - # check type compability between def.typ and typ + # check type compatibility between def.typ and typ def = fitNode(c, typ, def) #changeType(def.skipConv, typ, check=true) else: diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index a5cfc1c22f..47602368a4 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -494,7 +494,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = semParamList(c, n.sons[paramsPos], gp, s) # a template's parameters are not gensym'ed even if that was originally the # case as we determine whether it's a template parameter in the template - # body by the absense of the skGenSym flag: + # body by the absence of the skGenSym flag: for i in 1 .. s.typ.n.len-1: s.typ.n.sons[i].sym.flags.excl sfGenSym if sonsLen(gp) > 0: diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 7ee2fe380d..808653d552 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -900,7 +900,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, if hasDefault: def = semExprWithType(c, a.sons[length-1]) - # check type compability between def.typ and typ: + # check type compatibility between def.typ and typ: if typ == nil: typ = def.typ elif def != nil: diff --git a/compiler/types.nim b/compiler/types.nim index 2422d5305a..85b0f9ed0b 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -649,7 +649,7 @@ proc lengthOrd(t: PType): BiggestInt = type TDistinctCompare* = enum ## how distinct types are to be compared dcEq, ## a and b should be the same type - dcEqIgnoreDistinct, ## compare symetrically: (distinct a) == b, a == b + dcEqIgnoreDistinct, ## compare symmetrically: (distinct a) == b, a == b ## or a == (distinct b) dcEqOrDistinctOf ## a equals b or a is distinct of b diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 70f81bc723..c699570321 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1246,7 +1246,7 @@ proc genGlobalInit(c: PCtx; n: PNode; s: PSym) = c.globals.add(getNullValue(s.typ, n.info)) s.position = c.globals.len # This is rather hard to support, due to the laziness of the VM code - # generator. See tests/compile/tmacro2 for why this is necesary: + # generator. See tests/compile/tmacro2 for why this is necessary: # var decls{.compileTime.}: seq[PNimrodNode] = @[] let dest = c.getTemp(s.typ) c.gABx(n, opcLdGlobal, dest, s.position) diff --git a/config/nimdoc.cfg b/config/nimdoc.cfg index 2e0bf62a03..e036c3b9a5 100644 --- a/config/nimdoc.cfg +++ b/config/nimdoc.cfg @@ -24,7 +24,7 @@ doc.section.toc = """ """ -# Chunk of HTML emmited for each entry in the HTML table of contents. +# Chunk of HTML emitted for each entry in the HTML table of contents. # Available variables are: # * $desc: the actual docstring of the item. # * $header: the full version of name, including types, pragmas, tags, etc. @@ -45,7 +45,7 @@ $seeSrc """ -# Chunk of HTML emmited for each entry in the HTML table of contents. +# Chunk of HTML emitted for each entry in the HTML table of contents. # See doc.item for available substitution variables. doc.item.toc = """
  • `_ to mark the reference as used, so it does not get freed. And for the C backend you will need to expose the `GC_unref diff --git a/doc/idetools.txt b/doc/idetools.txt index 81de9598ce..2ffe46d4bf 100644 --- a/doc/idetools.txt +++ b/doc/idetools.txt @@ -163,7 +163,7 @@ running/debugged user project. Compiler as a service (CAAS) ============================ -The ocasional use of idetools is acceptable for things like +The occasional use of idetools is acceptable for things like definitions, where the user puts the cursor on a symbol or double clicks it and after a second or two the IDE displays where that symbol is defined. Such latencies would be terrible for features @@ -533,10 +533,10 @@ run it manually. First you have to compile the tester:: Running the ``caasdriver`` without parameters will attempt to process all the test cases in all three operation modes. If a test succeeds nothing will be printed and the process will exit with zero. If any -test fails, the specific line of the test preceeding the failure +test fails, the specific line of the test preceding the failure and the failure itself will be dumped to stdout, along with a final indicator of the success state and operation mode. You can pass the -parameter ``verbose`` to force all output even on successfull tests. +parameter ``verbose`` to force all output even on successful tests. The normal operation mode is called ``ProcRun`` and it involves starting a process for each command or query, similar to running diff --git a/doc/intern.txt b/doc/intern.txt index 93dcce059b..9582fc96f5 100644 --- a/doc/intern.txt +++ b/doc/intern.txt @@ -370,7 +370,7 @@ needed as the data structures needs to be rebuilt periodically anyway. Complete traversal is done in this way:: - for each page decriptor d: + for each page descriptor d: for each bit in d: if bit == 1: traverse the pointer belonging to this bit @@ -406,7 +406,7 @@ The generated code looks roughly like this: setRef(&r->left) } -Note that for systems with a continous stack (which most systems have) +Note that for systems with a continuous stack (which most systems have) the check whether the ref is on the stack is very cheap (only two comparisons). diff --git a/doc/lib.txt b/doc/lib.txt index 4185e6f749..1f972179d4 100644 --- a/doc/lib.txt +++ b/doc/lib.txt @@ -370,7 +370,7 @@ Miscellaneous ------------- * `events `_ - This module implements an event system that is not dependant on external + This module implements an event system that is not dependent on external graphical toolkits. * `oids `_ diff --git a/doc/manual/about.txt b/doc/manual/about.txt index 13307279b4..78167efe3d 100644 --- a/doc/manual/about.txt +++ b/doc/manual/about.txt @@ -25,9 +25,9 @@ with ``'``. An example:: ifStmt = 'if' expr ':' stmts ('elif' expr ':' stmts)* ('else' stmts)? -The binary ``^*`` operator is used as a shorthand for 0 or more occurances +The binary ``^*`` operator is used as a shorthand for 0 or more occurrences separated by its second argument; likewise ``^+`` means 1 or more -occurances: ``a ^+ b`` is short for ``a (b a)*`` +occurrences: ``a ^+ b`` is short for ``a (b a)*`` and ``a ^* b`` is short for ``(a (b a)*)?``. Example:: arrayConstructor = '[' expr ^* ',' ']' diff --git a/doc/manual/syntax.txt b/doc/manual/syntax.txt index b40a8ce91c..cf44eb5881 100644 --- a/doc/manual/syntax.txt +++ b/doc/manual/syntax.txt @@ -59,7 +59,7 @@ Precedence level Operators First charact Strong spaces ------------- -The number of spaces preceeding a non-keyword operator affects precedence +The number of spaces preceding a non-keyword operator affects precedence if the experimental parser directive ``#!strongSpaces`` is used. Indentation is not used to determine the number of spaces. If 2 or more operators have the same number of preceding spaces the precedence table applies, so ``1 + 3 * 4`` diff --git a/doc/manual/types.txt b/doc/manual/types.txt index 32ff19f75b..a207011219 100644 --- a/doc/manual/types.txt +++ b/doc/manual/types.txt @@ -1142,7 +1142,7 @@ modules like `db_sqlite `_. Void type --------- -The ``void`` type denotes the absense of any type. Parameters of +The ``void`` type denotes the absence of any type. Parameters of type ``void`` are treated as non-existent, ``void`` as a return type means that the procedure does not return a value: diff --git a/doc/nimc.txt b/doc/nimc.txt index 84d596e3c2..c46de63741 100644 --- a/doc/nimc.txt +++ b/doc/nimc.txt @@ -134,7 +134,7 @@ found an ambiguity error is produced. ``nim dump`` shows the contents of the PATH. However before the PATH is used the current directory is checked for the -file's existance. So if PATH contains ``$lib`` and ``$lib/bar`` and the +file's existence. So if PATH contains ``$lib`` and ``$lib/bar`` and the directory structure looks like this:: $lib/x.nim diff --git a/doc/nimgrep.txt b/doc/nimgrep.txt index e2f7b228fa..2d429e8b59 100644 --- a/doc/nimgrep.txt +++ b/doc/nimgrep.txt @@ -25,9 +25,9 @@ Compile nimgrep with the command:: And copy the executable somewhere in your ``$PATH``. -Command line switches -===================== - +Command line switches +===================== + Usage: nimgrep [options] [pattern] [replacement] (file/directory)* Options: @@ -37,7 +37,7 @@ Options: --re pattern is a regular expression (default); extended syntax for the regular expression is always turned on --recursive process directories recursively - --confirm confirm each occurence/replacement; there is a chance + --confirm confirm each occurrence/replacement; there is a chance to abort any time without touching the file --stdin read pattern from stdin (to avoid the shell's confusing quoting rules) diff --git a/doc/tut2.txt b/doc/tut2.txt index dbf50894bd..e92c7d2adc 100644 --- a/doc/tut2.txt +++ b/doc/tut2.txt @@ -37,7 +37,7 @@ Object Oriented Programming While Nim's support for object oriented programming (OOP) is minimalistic, powerful OOP techniques can be used. OOP is seen as *one* way to design a program, not *the only* way. Often a procedural approach leads to simpler -and more efficient code. In particular, prefering composition over inheritance +and more efficient code. In particular, preferring composition over inheritance is often the better design. @@ -142,7 +142,7 @@ An example: .. code-block:: nim - # This is an example how an abstract syntax tree could be modeled in Nim + # This is an example how an abstract syntax tree could be modelled in Nim type NodeKind = enum # the different node types nkInt, # a leaf with an integer value @@ -335,7 +335,7 @@ As the example demonstrates, invocation of a multi-method cannot be ambiguous: Collide 2 is preferred over collide 1 because the resolution works from left to right. Thus ``Unit, Thing`` is preferred over ``Thing, Unit``. -**Perfomance note**: Nim does not produce a virtual method table, but +**Performance note**: Nim does not produce a virtual method table, but generates dispatch trees. This avoids the expensive indirect branch for method calls and enables inlining. However, other optimizations like compile time evaluation or dead code elimination do not work with methods. diff --git a/examples/cross_calculator/android/readme.txt b/examples/cross_calculator/android/readme.txt index c04d1d3043..51fa9c6fda 100644 --- a/examples/cross_calculator/android/readme.txt +++ b/examples/cross_calculator/android/readme.txt @@ -10,7 +10,7 @@ just declared as a native method which will be resolved at runtime. The scripts nimbuild.sh and jnibuild.sh are in charge of building the Nim code and generating the jni bridge from the java code respectively. Finally, the ndk-build command from the android ndk tools has to be run to build the binary -libary which will be installed along the final apk. +library which will be installed along the final apk. All these steps are wrapped in the ant build script through the customization of the -post-compile rule. If you have the android ndk tools installed and you diff --git a/examples/cross_calculator/ios/src/NRViewController.m b/examples/cross_calculator/ios/src/NRViewController.m index 1f92f2d38f..f629bfc093 100644 --- a/examples/cross_calculator/ios/src/NRViewController.m +++ b/examples/cross_calculator/ios/src/NRViewController.m @@ -55,7 +55,7 @@ [self.bText resignFirstResponder]; } -/** Custom loadView method for backwards compatiblity. +/** Custom loadView method for backwards compatibility. * Unfortunately I've been unable to coerce Xcode 4.4 to generate nib files * which are compatible with my trusty iOS 3.0 ipod touch so in order to be * fully compatible for all devices we have to build the interface manually in diff --git a/examples/cross_todo/nim_backend/backend.nim b/examples/cross_todo/nim_backend/backend.nim index 9c7d2bafac..5b49bc4a92 100644 --- a/examples/cross_todo/nim_backend/backend.nim +++ b/examples/cross_todo/nim_backend/backend.nim @@ -91,7 +91,7 @@ proc update*(todo: var TTodo; conn: TDbConn): bool = ## ## Use this method if you (or another entity) have modified the database and ## want to update the object you have with whatever the database has stored. - ## Returns true if the update suceeded, or false if the object was not found + ## Returns true if the update succeeded, or false if the object was not found ## in the database any more, in which case you should probably get rid of the ## TTodo object. assert(todo.id >= 0, "The identifier of the todo entry can't be negative") diff --git a/lib/core/locks.nim b/lib/core/locks.nim index 766b7b5363..8a809fc84b 100644 --- a/lib/core/locks.nim +++ b/lib/core/locks.nim @@ -21,7 +21,7 @@ type ## is performed. Deprecated, do not use anymore! AquireEffect* {.deprecated.} = object of LockEffect ## \ ## effect that denotes that some lock is - ## aquired. Deprecated, do not use anymore! + ## acquired. Deprecated, do not use anymore! ReleaseEffect* {.deprecated.} = object of LockEffect ## \ ## effect that denotes that some lock is ## released. Deprecated, do not use anymore! diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index 14614b2edb..e1e5908774 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -1145,7 +1145,7 @@ proc formatNamedVars*(frmt: string, varnames: openArray[string], proc defaultConfig*(): StringTableRef = ## Returns a default configuration for embedded HTML generation. ## - ## The returned ``StringTableRef`` contains the paramters used by the HTML + ## The returned ``StringTableRef`` contains the parameters used by the HTML ## engine to build the final output. For information on what these parameters ## are and their purpose, please look up the file ``config/nimdoc.cfg`` ## bundled with the compiler. diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 34c4b5f709..d6ed660307 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -606,7 +606,7 @@ when defined(windows) or defined(nimdoc): retFuture.fail(newException(OSError, osErrorMsg(err))) elif ret == 0 and bytesReceived == 0 and dataBuf.buf[0] == '\0': # We have to ensure that the buffer is empty because WSARecv will tell - # us immediatelly when it was disconnected, even when there is still + # us immediately when it was disconnected, even when there is still # data in the buffer. # We want to give the user as much data as we can. So we only return # the empty string (which signals a disconnection) when there is diff --git a/lib/pure/basic2d.nim b/lib/pure/basic2d.nim index f2fc1566b2..a344cd053f 100644 --- a/lib/pure/basic2d.nim +++ b/lib/pure/basic2d.nim @@ -18,7 +18,7 @@ import strutils ## ## Quick start example: ## -## # Create a matrix wich first rotates, then scales and at last translates +## # Create a matrix which first rotates, then scales and at last translates ## ## var m:TMatrix2d=rotate(DEG90) & scale(2.0) & move(100.0,200.0) ## @@ -256,7 +256,7 @@ proc `$`* (t:TMatrix2d):string {.noInit.} = proc isUniform*(t:TMatrix2d,tol=1.0e-6):bool= ## Checks if the transform is uniform, that is - ## perpendicular axes of equal lenght, which means (for example) + ## perpendicular axes of equal length, which means (for example) ## it cannot transform a circle into an ellipse. ## `tol` is used as tolerance for both equal length comparison ## and perp. comparison. @@ -305,7 +305,7 @@ proc equals*(m1:TMatrix2d,m2:TMatrix2d,tol=1.0e-6):bool= abs(m1.ty-m2.ty)<=tol proc `=~`*(m1,m2:TMatrix2d):bool= - ## Checks if `m1`and `m2` is aproximately equal, using a + ## Checks if `m1`and `m2` is approximately equal, using a ## tolerance of 1e-6. equals(m1,m2) diff --git a/lib/pure/basic3d.nim b/lib/pure/basic3d.nim index 9a8e006ec3..18ebed67b2 100644 --- a/lib/pure/basic3d.nim +++ b/lib/pure/basic3d.nim @@ -23,7 +23,7 @@ import times ## ## Quick start example: ## -## # Create a matrix wich first rotates, then scales and at last translates +## # Create a matrix which first rotates, then scales and at last translates ## ## var m:TMatrix3d=rotate(PI,vector3d(1,1,2.5)) & scale(2.0) & move(100.0,200.0,300.0) ## @@ -320,7 +320,7 @@ proc rotateZ*(angle:float):TMatrix3d {.noInit.}= proc isUniform*(m:TMatrix3d,tol=1.0e-6):bool= ## Checks if the transform is uniform, that is - ## perpendicular axes of equal lenght, which means (for example) + ## perpendicular axes of equal length, which means (for example) ## it cannot transform a sphere into an ellipsoid. ## `tol` is used as tolerance for both equal length comparison ## and perpendicular comparison. @@ -483,7 +483,7 @@ proc equals*(m1:TMatrix3d,m2:TMatrix3d,tol=1.0e-6):bool= abs(m1.tw-m2.tw)<=tol proc `=~`*(m1,m2:TMatrix3d):bool= - ## Checks if `m1` and `m2` is aproximately equal, using a + ## Checks if `m1` and `m2` is approximately equal, using a ## tolerance of 1e-6. equals(m1,m2) @@ -788,7 +788,7 @@ proc angleTo*(v1,v2:TVector3d):float= proc arbitraryAxis*(norm:TVector3d):TMatrix3d {.noInit.}= ## Computes the rotation matrix that would transform ## world z vector into `norm`. The inverse of this matrix - ## is useful to tranform a planar 3d object to 2d space. + ## is useful to transform a planar 3d object to 2d space. ## This is the same algorithm used to interpret DXF and DWG files. const lim=1.0/64.0 var ax,ay,az:TVector3d diff --git a/lib/pure/collections/LockFreeHash.nim b/lib/pure/collections/LockFreeHash.nim index 5640838b1c..c3954468ac 100644 --- a/lib/pure/collections/LockFreeHash.nim +++ b/lib/pure/collections/LockFreeHash.nim @@ -404,7 +404,7 @@ proc setVal[K,V](table: var PConcTable[K,V], key: int, val: int, #echo("tomb old slot then set in new table") nextTable = copySlotAndCheck(table,idx) return setVal(nextTable, key, val, expVal, match) - # Finaly ready to add new val to table + # Finally ready to add new val to table while true: if match and oldVal != expVal: #echo("set failed, no match oldVal= " & $oldVal & " expVal= " & $expVal) diff --git a/lib/pure/collections/critbits.nim b/lib/pure/collections/critbits.nim index 06babc6bbe..3d10e39aa3 100644 --- a/lib/pure/collections/critbits.nim +++ b/lib/pure/collections/critbits.nim @@ -174,7 +174,7 @@ proc excl*[T](c: var CritBitTree[T], key: string) = iterator leaves[T](n: Node[T]): Node[T] = if n != nil: # XXX actually we could compute the necessary stack size in advance: - # it's rougly log2(c.count). + # it's roughly log2(c.count). var stack = @[n] while stack.len > 0: var it = stack.pop diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim index 1ec122e78c..e690e8ebaa 100644 --- a/lib/pure/collections/sequtils.nim +++ b/lib/pure/collections/sequtils.nim @@ -333,7 +333,7 @@ template foldl*(sequence, operation: expr): expr = ## words = @["nim", "is", "cool"] ## concatenation = foldl(words, a & b) ## assert addition == 25, "Addition is (((5)+9)+11)" - ## assert subtraction == -15, "Substraction is (((5)-9)-11)" + ## assert subtraction == -15, "Subtraction is (((5)-9)-11)" ## assert multiplication == 495, "Multiplication is (((5)*9)*11)" ## assert concatenation == "nimiscool" assert sequence.len > 0, "Can't fold empty sequences" @@ -369,7 +369,7 @@ template foldr*(sequence, operation: expr): expr = ## words = @["nim", "is", "cool"] ## concatenation = foldr(words, a & b) ## assert addition == 25, "Addition is (5+(9+(11)))" - ## assert subtraction == 7, "Substraction is (5-(9-(11)))" + ## assert subtraction == 7, "Subtraction is (5-(9-(11)))" ## assert multiplication == 495, "Multiplication is (5*(9*(11)))" ## assert concatenation == "nimiscool" assert sequence.len > 0, "Can't fold empty sequences" @@ -512,7 +512,7 @@ when isMainModule: words = @["nim", "is", "cool"] concatenation = foldl(words, a & b) assert addition == 25, "Addition is (((5)+9)+11)" - assert subtraction == -15, "Substraction is (((5)-9)-11)" + assert subtraction == -15, "Subtraction is (((5)-9)-11)" assert multiplication == 495, "Multiplication is (((5)*9)*11)" assert concatenation == "nimiscool" @@ -525,7 +525,7 @@ when isMainModule: words = @["nim", "is", "cool"] concatenation = foldr(words, a & b) assert addition == 25, "Addition is (5+(9+(11)))" - assert subtraction == 7, "Substraction is (5-(9-(11)))" + assert subtraction == 7, "Subtraction is (5-(9-(11)))" assert multiplication == 495, "Multiplication is (5*(9*(11)))" assert concatenation == "nimiscool" diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index 25fe306c07..c82f1230a1 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -11,7 +11,7 @@ ## (also often named `dictionary`:idx: in other programming languages) that is ## a mapping from keys to values. ``Table`` is the usual hash table, ## ``OrderedTable`` is like ``Table`` but remembers insertion order -## and ``CountTable`` is a mapping from a key to its number of occurances. +## and ``CountTable`` is a mapping from a key to its number of occurrences. ## For consistency with every other data type in Nim these have **value** ## semantics, this means that ``=`` performs a copy of the hash table. ## For **reference** semantics use the ``Ref`` variant: ``TableRef``, diff --git a/lib/pure/colors.nim b/lib/pure/colors.nim index 5b1904e542..f24cc0072f 100644 --- a/lib/pure/colors.nim +++ b/lib/pure/colors.nim @@ -46,7 +46,7 @@ proc `+`*(a, b: Color): Color = colorOp(satPlus) proc `-`*(a, b: Color): Color = - ## substracts two colors: This uses saturated artithmetic, so that each color + ## subtracts two colors: This uses saturated artithmetic, so that each color ## component cannot overflow (255 is used as a maximum). colorOp(satMinus) diff --git a/lib/pure/encodings.nim b/lib/pure/encodings.nim index 298a6072d5..25c7ad9ef7 100644 --- a/lib/pure/encodings.nim +++ b/lib/pure/encodings.nim @@ -301,7 +301,7 @@ proc getCurrentEncoding*(): string = proc open*(destEncoding = "UTF-8", srcEncoding = "CP1252"): EncodingConverter = ## opens a converter that can convert from `srcEncoding` to `destEncoding`. - ## Raises `EIO` if it cannot fullfill the request. + ## Raises `EIO` if it cannot fulfill the request. when not defined(windows): result = iconvOpen(destEncoding, srcEncoding) if result == nil: diff --git a/lib/pure/events.nim b/lib/pure/events.nim index 77faa6a667..44e9ed2865 100644 --- a/lib/pure/events.nim +++ b/lib/pure/events.nim @@ -9,7 +9,7 @@ ## :Author: Alex Mitchell ## -## This module implements an event system that is not dependant on external +## This module implements an event system that is not dependent on external ## graphical toolkits. It was originally called ``NimEE`` because ## it was inspired by Python's PyEE module. There are two ways you can use ## events: one is a python-inspired way; the other is more of a C-style way. diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 3c14018870..37af14df30 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -385,7 +385,7 @@ proc request*(url: string, httpMethod: string, extraHeaders = "", userAgent = defUserAgent, proxy: Proxy = nil): Response = ## | Requests ``url`` with the custom method string specified by the ## | ``httpMethod`` parameter. - ## | Extra headers can be specified and must be seperated by ``\c\L`` + ## | Extra headers can be specified and must be separated by ``\c\L`` ## | An optional timeout can be specified in miliseconds, if reading from the ## server takes longer than specified an ETimeout exception will be raised. var r = if proxy == nil: parseUri(url) else: proxy.url @@ -436,7 +436,7 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "", body = "", sslContext = defaultSSLContext, timeout = -1, userAgent = defUserAgent, proxy: Proxy = nil): Response = ## | Requests ``url`` with the specified ``httpMethod``. - ## | Extra headers can be specified and must be seperated by ``\c\L`` + ## | Extra headers can be specified and must be separated by ``\c\L`` ## | An optional timeout can be specified in miliseconds, if reading from the ## server takes longer than specified an ETimeout exception will be raised. result = request(url, $httpMethod, extraHeaders, body, sslContext, timeout, diff --git a/lib/pure/logging.nim b/lib/pure/logging.nim index de733b75ca..b64437c896 100644 --- a/lib/pure/logging.nim +++ b/lib/pure/logging.nim @@ -8,7 +8,7 @@ # ## This module implements a simple logger. It has been designed to be as simple -## as possible to avoid bloat, if this library does not fullfill your needs, +## as possible to avoid bloat, if this library does not fulfill your needs, ## write your own. ## ## Format strings support the following variables which must be prefixed with diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 809b7fb69e..2bd4a76d4d 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -887,7 +887,7 @@ proc connectAsync(socket: Socket, name: string, port = Port(0), af: Domain = AF_INET) {.tags: [ReadIOEffect].} = ## A variant of ``connect`` for non-blocking sockets. ## - ## This procedure will immediatelly return, it will not block until a connection + ## This procedure will immediately return, it will not block until a connection ## is made. It is up to the caller to make sure the connection has been established ## by checking (using ``select``) whether the socket is writeable. ## diff --git a/lib/pure/os.nim b/lib/pure/os.nim index d9a5be14a6..ceeba182fe 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -1182,7 +1182,7 @@ proc putEnv*(key, val: string) {.tags: [WriteEnvEffect].} = ## If an error occurs, `EInvalidEnvVar` is raised. # Note: by storing the string in the environment sequence, - # we gurantee that we don't free the memory before the program + # we guarantee that we don't free the memory before the program # ends (this is needed for POSIX compliance). It is also needed so that # the process itself may access its modified environment variables! var indx = findEnvVar(key) @@ -1454,7 +1454,7 @@ proc createHardlink*(src, dest: string) = proc parseCmdLine*(c: string): seq[string] {. noSideEffect, rtl, extern: "nos$1".} = ## Splits a command line into several components; - ## This proc is only occassionally useful, better use the `parseopt` module. + ## This proc is only occasionally useful, better use the `parseopt` module. ## ## On Windows, it uses the following parsing rules ## (see http://msdn.microsoft.com/en-us/library/17w5ykft.aspx ): diff --git a/lib/pure/parseopt2.nim b/lib/pure/parseopt2.nim index 8ed519fa4b..73b498fe02 100644 --- a/lib/pure/parseopt2.nim +++ b/lib/pure/parseopt2.nim @@ -60,7 +60,7 @@ proc initOptParser*(cmdline: string): OptParser {.rtl, deprecated.} = ## Initalizes option parses with cmdline. Splits cmdline in on spaces ## and calls initOptParser(openarray[string]) ## Do not use. - if cmdline == "": # backward compatibilty + if cmdline == "": # backward compatibility return initOptParser(seq[string](nil)) else: return initOptParser(cmdline.split) diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim index abe5aa90e1..eb649a878c 100644 --- a/lib/pure/parseutils.nim +++ b/lib/pure/parseutils.nim @@ -181,7 +181,7 @@ proc parseWhile*(s: string, token: var string, validChars: set[char], token = substr(s, start, i-1) proc captureBetween*(s: string, first: char, second = '\0', start = 0): string = - ## Finds the first occurence of ``first``, then returns everything from there + ## Finds the first occurrence of ``first``, then returns everything from there ## up to ``second``(if ``second`` is '\0', then ``first`` is used). var i = skipUntil(s, first, start)+1+start result = "" diff --git a/lib/pure/ropes.nim b/lib/pure/ropes.nim index 995dff2aa2..4cc64a1543 100644 --- a/lib/pure/ropes.nim +++ b/lib/pure/ropes.nim @@ -43,7 +43,7 @@ proc isConc(r: Rope): bool {.inline.} = return isNil(r.data) # Note that the left and right pointers are not needed for leafs. # Leaves have relatively high memory overhead (~30 bytes on a 32 # bit machine) and we produce many of them. This is why we cache and -# share leafs accross different rope trees. +# share leafs across different rope trees. # To cache them they are inserted in another tree, a splay tree for best # performance. But for the caching tree we use the leaf's left and right # pointers. diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim index 593eec15a0..2ed53ef3ff 100644 --- a/lib/pure/selectors.nim +++ b/lib/pure/selectors.nim @@ -35,7 +35,7 @@ type when defined(nimdoc): type Selector* = ref object - ## An object which holds file descripters to be checked for read/write + ## An object which holds file descriptors to be checked for read/write ## status. fds: Table[SocketHandle, SelectorKey] diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 6c32717a90..8ac5d4f091 100644 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -851,7 +851,7 @@ proc connectAsync*(socket: Socket, name: string, port = Port(0), af: Domain = AF_INET) {.tags: [ReadIOEffect].} = ## A variant of ``connect`` for non-blocking sockets. ## - ## This procedure will immediatelly return, it will not block until a connection + ## This procedure will immediately return, it will not block until a connection ## is made. It is up to the caller to make sure the connection has been established ## by checking (using ``select``) whether the socket is writeable. ## diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index e17d99dc20..17e0b9e632 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -815,8 +815,8 @@ proc rfind*(s: string, sub: char, start: int = -1): int {.noSideEffect, proc count*(s: string, sub: string, overlapping: bool = false): int {.noSideEffect, rtl, extern: "nsuCountString".} = - ## Count the occurences of a substring `sub` in the string `s`. - ## Overlapping occurences of `sub` only count when `overlapping` + ## Count the occurrences of a substring `sub` in the string `s`. + ## Overlapping occurrences of `sub` only count when `overlapping` ## is set to true. var i = 0 while true: @@ -831,14 +831,14 @@ proc count*(s: string, sub: string, overlapping: bool = false): int {.noSideEffe proc count*(s: string, sub: char): int {.noSideEffect, rtl, extern: "nsuCountChar".} = - ## Count the occurences of the character `sub` in the string `s`. + ## Count the occurrences of the character `sub` in the string `s`. for c in s: if c == sub: inc result proc count*(s: string, subs: set[char]): int {.noSideEffect, rtl, extern: "nsuCountCharSet".} = - ## Count the occurences of the group of character `subs` in the string `s`. + ## Count the occurrences of the group of character `subs` in the string `s`. for c in s: if c in subs: inc result @@ -898,7 +898,7 @@ proc replaceWord*(s, sub: string, by = ""): string {.noSideEffect, rtl, extern: "nsuReplaceWord".} = ## Replaces `sub` in `s` by the string `by`. ## - ## Each occurance of `sub` has to be surrounded by word boundaries + ## Each occurrence of `sub` has to be surrounded by word boundaries ## (comparable to ``\\w`` in regular expressions), otherwise it is not ## replaced. const wordChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'} diff --git a/lib/pure/xmldom.nim b/lib/pure/xmldom.nim index 660932d92e..2e55ff1829 100644 --- a/lib/pure/xmldom.nim +++ b/lib/pure/xmldom.nim @@ -642,7 +642,7 @@ proc isEmpty(s: string): bool = return true proc normalize*(n: PNode) = - ## Merges all seperated TextNodes together, and removes any empty TextNodes + ## Merges all separated TextNodes together, and removes any empty TextNodes var curTextNode: PNode = nil var i: int = 0 diff --git a/lib/system.nim b/lib/system.nim index 825c2597de..b86ab7080d 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -73,7 +73,7 @@ type expr* {.magic: Expr.} ## meta type to denote an expression (for templates) stmt* {.magic: Stmt.} ## meta type to denote a statement (for templates) typedesc* {.magic: TypeDesc.} ## meta type to denote a type description - void* {.magic: "VoidType".} ## meta type to denote the absense of any type + void* {.magic: "VoidType".} ## meta type to denote the absence of any type auto* = expr any* = distinct auto @@ -370,7 +370,7 @@ type ## ## See the full `exception hierarchy`_. ResourceExhaustedError* = object of SystemError ## \ - ## Raised if a resource request could not be fullfilled. + ## Raised if a resource request could not be fulfilled. ## ## See the full `exception hierarchy`_. ArithmeticError* = object of Exception ## \ @@ -578,7 +578,7 @@ proc len*(x: cstring): int {.magic: "LengthStr", noSideEffect.} proc len*[I, T](x: array[I, T]): int {.magic: "LengthArray", noSideEffect.} proc len*[T](x: seq[T]): int {.magic: "LengthSeq", noSideEffect.} ## returns the length of an array, an openarray, a sequence or a string. - ## This is rougly the same as ``high(T)-low(T)+1``, but its resulting type is + ## This is roughly the same as ``high(T)-low(T)+1``, but its resulting type is ## always an int. # set routines: @@ -865,7 +865,7 @@ proc contains*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.} ## passes its arguments in reverse order. proc contains*[T](s: Slice[T], value: T): bool {.noSideEffect, inline.} = - ## Checks if `value` is withing the range of `s`; returns true iff + ## Checks if `value` is within the range of `s`; returns true iff ## `value >= s.a and value <= s.b` ## ## .. code-block:: Nim diff --git a/lib/system/arithm.nim b/lib/system/arithm.nim index c4df287cf1..f68e2dcd9f 100644 --- a/lib/system/arithm.nim +++ b/lib/system/arithm.nim @@ -15,7 +15,7 @@ proc raiseOverflow {.compilerproc, noinline, noreturn.} = sysFatal(OverflowError, "over- or underflow") proc raiseDivByZero {.compilerproc, noinline, noreturn.} = - sysFatal(DivByZeroError, "divison by zero") + sysFatal(DivByZeroError, "division by zero") proc addInt64(a, b: int64): int64 {.compilerProc, inline.} = result = a +% b diff --git a/lib/system/cgprocs.nim b/lib/system/cgprocs.nim index 089846578e..f3acc81f24 100644 --- a/lib/system/cgprocs.nim +++ b/lib/system/cgprocs.nim @@ -13,7 +13,7 @@ proc addChar(s: NimString, c: char): NimString {.compilerProc, benign.} type TLibHandle = pointer # private type - TProcAddr = pointer # libary loading and loading of procs: + TProcAddr = pointer # library loading and loading of procs: proc nimLoadLibrary(path: string): TLibHandle {.compilerproc.} proc nimUnloadLibrary(lib: TLibHandle) {.compilerproc.} diff --git a/lib/system/dyncalls.nim b/lib/system/dyncalls.nim index 539e37aaff..44f7b67c31 100644 --- a/lib/system/dyncalls.nim +++ b/lib/system/dyncalls.nim @@ -8,7 +8,7 @@ # # This file implements the ability to call native procs from libraries. -# It is not possible to do this in a platform independant way, unfortunately. +# It is not possible to do this in a platform independent way, unfortunately. # However, the interface has been designed to take platform differences into # account and been ported to all major platforms. diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 9459ee6b90..1f4279c8f5 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -884,7 +884,7 @@ elif stackIncreases: var jmpbufSize {.importc: "sizeof(jmp_buf)", nodecl.}: int # a little hack to get the size of a TJmpBuf in the generated C code - # in a platform independant way + # in a platform independent way template forEachStackSlot(gch, gcMark: expr) {.immediate, dirty.} = var registers: C_JmpBuf diff --git a/lib/system/gc2.nim b/lib/system/gc2.nim index b0173b78f3..f6833e19a5 100644 --- a/lib/system/gc2.nim +++ b/lib/system/gc2.nim @@ -1067,7 +1067,7 @@ proc stackSize(): int {.noinline.} = var jmpbufSize {.importc: "sizeof(jmp_buf)", nodecl.}: int # a little hack to get the size of a TJmpBuf in the generated C code - # in a platform independant way + # in a platform independent way when defined(sparc): # For SPARC architecture. proc isOnStack(p: pointer): bool = @@ -1263,7 +1263,7 @@ proc unmarkStackAndRegisters(gch: var TGcHeap) = # XXX no need for an atomic dec here: if c.refcount--(LocalHeap): # the object survived only because of a stack reference - # it still doesn't have heap refernces + # it still doesn't have heap references addZCT(gch.zct, c) if canbeCycleRoot(c): diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim index 014b7c2783..6fbe942394 100644 --- a/lib/system/gc_ms.nim +++ b/lib/system/gc_ms.nim @@ -476,7 +476,7 @@ elif stackIncreases: var jmpbufSize {.importc: "sizeof(jmp_buf)", nodecl.}: int # a little hack to get the size of a TJmpBuf in the generated C code - # in a platform independant way + # in a platform independent way proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} = var registers: C_JmpBuf diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 9b4a7d5568..15b00f8f1a 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -128,7 +128,7 @@ proc raiseOverflow {.exportc: "raiseOverflow", noreturn.} = raise newException(OverflowError, "over- or underflow") proc raiseDivByZero {.exportc: "raiseDivByZero", noreturn.} = - raise newException(DivByZeroError, "divison by zero") + raise newException(DivByZeroError, "division by zero") proc raiseRangeError() {.compilerproc, noreturn.} = raise newException(RangeError, "value out of range") diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim index 2e254c87b8..aed17de800 100644 --- a/lib/system/sysio.nim +++ b/lib/system/sysio.nim @@ -132,7 +132,7 @@ proc rawFileSize(file: File): int = discard fseek(file, clong(oldPos), 0) proc readAllFile(file: File, len: int): string = - # We aquire the filesize beforehand and hope it doesn't change. + # We acquire the filesize beforehand and hope it doesn't change. # Speeds things up. result = newString(int(len)) if readBuffer(file, addr(result[0]), int(len)) != len: diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim index 440d040a5a..f7e1773be9 100644 --- a/lib/system/sysstr.nim +++ b/lib/system/sysstr.nim @@ -222,9 +222,9 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {. extGetCellType(result).base, waZctDecRef) # XXX: zeroing out the memory can still result in crashes if a wiped-out - # cell is aliased by another pointer (ie proc paramter or a let variable). + # cell is aliased by another pointer (ie proc parameter or a let variable). # This is a tought problem, because even if we don't zeroMem here, in the - # presense of user defined destructors, the user will expect the cell to be + # presence of user defined destructors, the user will expect the cell to be # "destroyed" thus creating the same problem. We can destoy the cell in the # finalizer of the sequence, but this makes destruction non-deterministic. zeroMem(cast[pointer](cast[ByteAddress](result) +% GenericSeqSize +% diff --git a/lib/wrappers/mysql.nim b/lib/wrappers/mysql.nim index 13f3cd1449..937a8952af 100644 --- a/lib/wrappers/mysql.nim +++ b/lib/wrappers/mysql.nim @@ -63,9 +63,9 @@ type const SCRAMBLE_LENGTH* = 20 # Length of random string sent by server on handshake; # this is also length of obfuscated password, - # recieved from client + # received from client SCRAMBLE_LENGTH_323* = 8 # length of password stored in the db: - # new passwords are preceeded with '*' + # new passwords are preceded with '*' SCRAMBLED_PASSWORD_CHAR_LENGTH* = SCRAMBLE_LENGTH * 2 + 1 SCRAMBLED_PASSWORD_CHAR_LENGTH_323* = SCRAMBLE_LENGTH_323 * 2 NOT_NULL_FLAG* = 1 # Field can't be NULL @@ -146,7 +146,7 @@ const MAX_MEDIUMINT_WIDTH* = 8 # Max width for a INT24 w.o. sign MAX_INT_WIDTH* = 10 # Max width for a LONG w.o. sign MAX_BIGINT_WIDTH* = 20 # Max width for a LONGLONG - MAX_CHAR_WIDTH* = 255 # Max length for a CHAR colum + MAX_CHAR_WIDTH* = 255 # Max length for a CHAR column MAX_BLOB_WIDTH* = 8192 # Default width for blob type @@ -558,7 +558,7 @@ type Tstatus* = enum STATUS_READY, STATUS_GET_RESULT, STATUS_USE_RESULT Tprotocol_type* = enum # There are three types of queries - the ones that have to go to - # the master, the ones that go to a slave, and the adminstrative + # the master, the ones that go to a slave, and the administrative # type which must happen on the pivot connectioin PROTOCOL_DEFAULT, PROTOCOL_TCP, PROTOCOL_SOCKET, PROTOCOL_PIPE, PROTOCOL_MEMORY diff --git a/lib/wrappers/sdl/sdl.nim b/lib/wrappers/sdl/sdl.nim index 449b651f9f..5bb5b7ec20 100644 --- a/lib/wrappers/sdl/sdl.nim +++ b/lib/wrappers/sdl/sdl.nim @@ -89,7 +89,7 @@ # As most games will need it. # # April 02 2001 - DL : Added SDL_getenv.h definitions and tested version -# 1.2.0 compatability. +# 1.2.0 compatibility. # # March 13 2001 - MT : Added Linux compatibility. # @@ -118,7 +118,7 @@ # # November 30 2001 - DL : SDL_NOFRAME added as pointed out by Simon Rushton. # -# December 11 2001 - DL : Added $WEAKPACKAGEUNIT ON to facilitate useage in +# December 11 2001 - DL : Added $WEAKPACKAGEUNIT ON to facilitate usage in # Components # # January 05 2002 - DL : Added SDL_Swap32 function as suggested by Matthias @@ -209,7 +209,7 @@ # forgot to apply Michalis Kamburelis' patch to the implementation section. now fixed # # Revision 1.14 2004/12/23 23:42:18 savage -# Applied Patches supplied by Michalis Kamburelis ( THANKS! ), for greater FreePascal compatability. +# Applied Patches supplied by Michalis Kamburelis ( THANKS! ), for greater FreePascal compatibility. # # Revision 1.13 2004/09/30 22:31:59 savage # Updated with slightly different header comments @@ -221,7 +221,7 @@ # Updated so that Library name defines are correctly defined for MacOS X. # # Revision 1.10 2004/07/20 23:57:33 savage -# Thanks to Paul Toth for spotting an error in the SDL Audio Convertion structures. +# Thanks to Paul Toth for spotting an error in the SDL Audio Conversion structures. # In TSDL_AudioCVT the filters variable should point to and array of pointers and not what I had there previously. # # Revision 1.9 2004/07/03 22:07:22 savage @@ -243,7 +243,7 @@ # SDL_GetEnv Fix so that it is not define twice for FPC. Thanks to Rene Hugentobler for pointing out this bug, # # Revision 1.3 2004/02/18 22:35:51 savage -# Brought sdl.pas up to 1.2.7 compatability +# Brought sdl.pas up to 1.2.7 compatibility # Thus... # Added SDL_GL_STEREO, # SDL_GL_MULTISAMPLEBUFFERS, diff --git a/lib/wrappers/sdl/sdl_mixer.nim b/lib/wrappers/sdl/sdl_mixer.nim index 33a71508a2..2f86646359 100644 --- a/lib/wrappers/sdl/sdl_mixer.nim +++ b/lib/wrappers/sdl/sdl_mixer.nim @@ -136,7 +136,7 @@ # Windows unit not used in this file, so it was removed to keep the code tidy. # # Revision 1.3 2004/03/31 10:05:08 savage -# Better defines for Endianess under FreePascal and Borland compilers. +# Better defines for Endianness under FreePascal and Borland compilers. # # Revision 1.2 2004/03/30 20:23:28 savage # Tidied up use of UNIX compiler directive. diff --git a/tests/caas/issue_416_template_shift.txt b/tests/caas/issue_416_template_shift.txt index b1f47c1ac6..e911c1360b 100644 --- a/tests/caas/issue_416_template_shift.txt +++ b/tests/caas/issue_416_template_shift.txt @@ -6,7 +6,7 @@ def\tskType\tsystem.string\tstring > idetools --track:$TESTNIM,12,35 --def $SILENT def\tskLet\t$MODULE.failtest.input\tTaintedString -# The following fail because they seem shifted one colum to the right. +# The following fail because they seem shifted one column to the right. > idetools --track:$TESTNIM,12,16 --def $SILENT def\tskTemplate\tsequtils.toSeq\tproc \(expr\): expr > idetools --track:$TESTNIM,12,22 --def $SILENT diff --git a/tests/caas/its_full_of_procs.nim b/tests/caas/its_full_of_procs.nim index 45347490c0..8f8b667647 100644 --- a/tests/caas/its_full_of_procs.nim +++ b/tests/caas/its_full_of_procs.nim @@ -2,7 +2,7 @@ import unicode, sequtils # This example shows that idetools returns proc as signature for everything # which can be called. While a clever person would use the second column to -# differentiate betwen procs, methods and others, why does the output contain +# differentiate between procs, methods and others, why does the output contain # incorrect information? type diff --git a/tinyc/arm-gen.c b/tinyc/arm-gen.c index 42feecf73d..050a8ad888 100644 --- a/tinyc/arm-gen.c +++ b/tinyc/arm-gen.c @@ -1506,7 +1506,7 @@ void gen_opf(int op) case TOK_UGE: case TOK_ULE: case TOK_UGT: - error("unsigned comparision on floats?"); + error("unsigned comparison on floats?"); break; case TOK_LT: op=TOK_Nset; diff --git a/tinyc/c67-gen.c b/tinyc/c67-gen.c index 04f8a12b74..77c68a2792 100644 --- a/tinyc/c67-gen.c +++ b/tinyc/c67-gen.c @@ -235,7 +235,7 @@ void gsym(int t) } // these are regs that tcc doesn't really know about, -// but asign them unique values so the mapping routines +// but assign them unique values so the mapping routines // can distinquish them #define C67_A0 105 diff --git a/tinyc/i386-asm.c b/tinyc/i386-asm.c index 21b28d7a09..12ff8f2ba9 100644 --- a/tinyc/i386-asm.c +++ b/tinyc/i386-asm.c @@ -1105,7 +1105,7 @@ static void subst_asm_operand(CString *add_str, } } -/* generate prolog and epilog code for asm statment */ +/* generate prolog and epilog code for asm statement */ static void asm_gen_code(ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, diff --git a/tinyc/lib/bcheck.c b/tinyc/lib/bcheck.c index 0ec2a4b479..c59d04eb8d 100644 --- a/tinyc/lib/bcheck.c +++ b/tinyc/lib/bcheck.c @@ -628,7 +628,7 @@ int __bound_delete_region(void *p) } /* return the size of the region starting at p, or EMPTY_SIZE if non - existant region. */ + existent region. */ static unsigned long get_region_size(void *p) { unsigned long addr = (unsigned long)p; diff --git a/tinyc/tcc-doc.html b/tinyc/tcc-doc.html index e40532ed0b..bd856d2566 100644 --- a/tinyc/tcc-doc.html +++ b/tinyc/tcc-doc.html @@ -927,7 +927,7 @@ They can be defined several times in the same source. Use 'b'

    4.4 Directives

    -

    All directives are preceeded by a '.'. The following directives are +

    All directives are preceded by a '.'. The following directives are supported:

      @@ -1365,7 +1365,7 @@ reverse order, a first pass is done to reverse the argument order.

      8.4 Types

      -

      The types are stored in a single 'int' variable. It was choosen in the +

      The types are stored in a single 'int' variable. It was chosen in the first stages of development when tcc was much simpler. Now, it may not be the best solution.

      @@ -1531,7 +1531,7 @@ current position in the code section.
      stab_section
      stabstr_section
      -

      are used when debugging is actived to store debug information +

      are used when debugging is activated to store debug information

      symtab_section
      diff --git a/tinyc/tcc-doc.texi b/tinyc/tcc-doc.texi index 7cc61bbdb9..47a8c8b009 100644 --- a/tinyc/tcc-doc.texi +++ b/tinyc/tcc-doc.texi @@ -673,7 +673,7 @@ They can be defined several times in the same source. Use 'b' @cindex asciz directive @cindex ascii directive -All directives are preceeded by a '.'. The following directives are +All directives are preceded by a '.'. The following directives are supported: @itemize @@ -892,7 +892,7 @@ reverse order, a first pass is done to reverse the argument order. @section Types -The types are stored in a single 'int' variable. It was choosen in the +The types are stored in a single 'int' variable. It was chosen in the first stages of development when tcc was much simpler. Now, it may not be the best solution. @@ -1017,7 +1017,7 @@ are used when bound checking is activated @item stab_section @itemx stabstr_section -are used when debugging is actived to store debug information +are used when debugging is activated to store debug information @item symtab_section @itemx strtab_section diff --git a/tinyc/tccasm.c b/tinyc/tccasm.c index 8834b53fb6..9b5289f773 100644 --- a/tinyc/tccasm.c +++ b/tinyc/tccasm.c @@ -229,7 +229,7 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe) } else { goto cannot_relocate; } - pe->sym = NULL; /* same symbols can be substracted to NULL */ + pe->sym = NULL; /* same symbols can be subtracted to NULL */ } else { cannot_relocate: error("invalid operation with label"); diff --git a/tinyc/tccgen.c b/tinyc/tccgen.c index 2eacff2c74..a88f328191 100644 --- a/tinyc/tccgen.c +++ b/tinyc/tccgen.c @@ -4686,7 +4686,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, if (sym->type.t & VT_EXTERN) { /* if the variable is extern, it was not allocated */ sym->type.t &= ~VT_EXTERN; - /* set array size if it was ommited in extern + /* set array size if it was omitted in extern declaration */ if ((sym->type.t & VT_ARRAY) && sym->type.ref->c < 0 && diff --git a/tinyc/tcctok.h b/tinyc/tcctok.h index 6dc4778211..2be032fa46 100644 --- a/tinyc/tcctok.h +++ b/tinyc/tcctok.h @@ -422,7 +422,7 @@ DEF_FP(mul) DEF_ASM(fcom) - DEF_ASM(fcom_1) /* non existant op, just to have a regular table */ + DEF_ASM(fcom_1) /* non existent op, just to have a regular table */ DEF_FP1(com) DEF_FP(comp) diff --git a/tinyc/win32/include/fcntl.h b/tinyc/win32/include/fcntl.h index 32f4a90e8b..d31bc84d51 100644 --- a/tinyc/win32/include/fcntl.h +++ b/tinyc/win32/include/fcntl.h @@ -50,7 +50,7 @@ #define _O_RANDOM 0x0010 #define _O_SEQUENTIAL 0x0020 -#define _O_TEMPORARY 0x0040 /* Make the file dissappear after closing. +#define _O_TEMPORARY 0x0040 /* Make the file disappear after closing. * WARNING: Even if not created by _open! */ #define _O_NOINHERIT 0x0080 diff --git a/tools/nimgrep.nim b/tools/nimgrep.nim index a38f2a88f7..aeae863003 100644 --- a/tools/nimgrep.nim +++ b/tools/nimgrep.nim @@ -24,7 +24,7 @@ Options: --re pattern is a regular expression (default); extended syntax for the regular expression is always turned on --recursive process directories recursively - --confirm confirm each occurence/replacement; there is a chance + --confirm confirm each occurrence/replacement; there is a chance to abort any time without touching the file --stdin read pattern from stdin (to avoid the shell's confusing quoting rules) diff --git a/tools/nimrepl.nim b/tools/nimrepl.nim index 0c9f946162..3d818a5567 100644 --- a/tools/nimrepl.nim +++ b/tools/nimrepl.nim @@ -130,7 +130,7 @@ proc initControls() = pack_start(MainBox, TopMenu, False, False, 0) - # VPaned - Seperates the InputTextView and the OutputTextView + # VPaned - Separates the InputTextView and the OutputTextView var paned = vpaned_new() set_position(paned, 450) pack_start(MainBox, paned, True, True, 0) diff --git a/web/news.txt b/web/news.txt index 7ead5a70e3..aa093be468 100644 --- a/web/news.txt +++ b/web/news.txt @@ -331,7 +331,7 @@ Library Additions The Nimrod development community is proud to announce the release of version 0.9.4 of the Nimrod compiler and tools. **Note: This release has to be considered beta quality! Lots of new features have been implemented but -unfortunately some do not fullfill our quality standards yet.** +unfortunately some do not fulfill our quality standards yet.** Prebuilt binaries and instructions for building from source are available on the `download page `_. @@ -756,7 +756,7 @@ Changes affecting backwards compatibility - The default calling convention for a procedural **type** is now ``closure``, for procs it remains ``nimcall`` (which is compatible to ``closure``). Activate the warning ``ImplicitClosure`` to make the compiler list the - occurances of proc types which are affected. + occurrences of proc types which are affected. - The Nimrod type system now distinguishes ``openarray`` from ``varargs``. - Templates are now ``hygienic``. Use the ``dirty`` pragma to get the old behaviour. @@ -884,7 +884,7 @@ Language Additions ------------------ - Added new ``is`` and ``of`` operators. -- The built-in type ``void`` can be used to denote the absense of any type. +- The built-in type ``void`` can be used to denote the absence of any type. This is useful in generic code. - Return types may be of the type ``var T`` to return an l-value. - The error pragma can now be used to mark symbols whose *usage* should trigger From cc7236b2dbc665f0416d057324304f184eced263 Mon Sep 17 00:00:00 2001 From: PhilipWitte Date: Sun, 15 Feb 2015 17:54:38 -0800 Subject: [PATCH 347/850] Add support tab to website --- tools/website.tmpl | 2 +- web/support.txt | 2 ++ web/website.ini | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 web/support.txt diff --git a/tools/website.tmpl b/tools/website.tmpl index 6dce93d147..50f8c3aa46 100644 --- a/tools/website.tmpl +++ b/tools/website.tmpl @@ -20,7 +20,7 @@