From 41587a533959e4269be29f4f238d524048ac303a Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 28 Dec 2014 00:42:24 +0100 Subject: [PATCH 01/34] fixes #1781 --- compiler/vmdef.nim | 3 ++- compiler/vmgen.nim | 13 ++++++++----- tests/vm/triangle_array.nim | 17 +++++++++++++++++ 3 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 tests/vm/triangle_array.nim diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim index c06606318..3d49cb130 100644 --- a/compiler/vmdef.nim +++ b/compiler/vmdef.nim @@ -164,7 +164,8 @@ type slotTempInt, # some temporary int slotTempFloat, # some temporary float slotTempStr, # some temporary string - slotTempComplex # some complex temporary (s.node field is used) + slotTempComplex, # some complex temporary (s.node field is used) + slotTempPerm # slot is temporary but permanent (hack) PProc* = ref object blocks*: seq[TBlock] # blocks; temp data structure diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index c4101874c..9a3fc260a 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -16,7 +16,7 @@ # types that use the 'node' field; the reason is that slots are # re-used in a register based VM. Example: # -# .. code-block:: nimrod +# .. code-block:: nim # let s = a & b # no matter what, create fresh node # s = a & b # no matter what, keep the node # @@ -28,7 +28,7 @@ # this copy depends on the involved types. import - unsigned, strutils, ast, astalgo, types, msgs, renderer, vmdef, + unsigned, strutils, ast, astalgo, types, msgs, renderer, vmdef, trees, intsets, rodread, magicsys, options, lowerings from os import splitFile @@ -58,6 +58,7 @@ proc codeListing(c: PCtx, result: var string, start=0; last = -1) = if i in jumpTargets: result.addf("L$1:\n", i) let x = c.code[i] + result.add($i) let opc = opcode(x) if opc in {opcConv, opcCast}: let y = c.code[i+1] @@ -188,7 +189,7 @@ proc getTemp(c: PCtx; typ: PType): TRegister = proc freeTemp(c: PCtx; r: TRegister) = let c = c.prc - if c.slots[r].kind >= slotSomeTemp: c.slots[r].inUse = false + if c.slots[r].kind in {slotSomeTemp..slotTempComplex}: c.slots[r].inUse = false proc getTempRange(c: PCtx; n: int; kind: TSlotKind): TRegister = # if register pressure is high, we re-use more aggressively: @@ -1074,8 +1075,10 @@ proc genAddrDeref(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode; c.gABC(n, opcNodeToReg, dest, dest) elif c.prc.slots[tmp].kind >= slotTempUnknown: gABC(c, n, opcAddrNode, dest, tmp) - # XXX this can still be wrong sometimes; hopefully it's only generated - # in call contexts, where it is safe + # hack ahead; in order to fix bug #1781 we mark the temporary as + # permanent, so that it's not used for anything else: + c.prc.slots[tmp].kind = slotTempPerm + # XXX this is still a hack #message(n.info, warnUser, "suspicious opcode used") else: gABC(c, n, opcAddrReg, dest, tmp) diff --git a/tests/vm/triangle_array.nim b/tests/vm/triangle_array.nim new file mode 100644 index 000000000..054c66f22 --- /dev/null +++ b/tests/vm/triangle_array.nim @@ -0,0 +1,17 @@ +discard """ + output: "56" +""" + +# bug #1781 + +proc initCombinations: array[11, array[11, int]] = + result[0] = [1,2,3,4,5,6,7,8,9,10,11] + result[1][1 .. 10] = [12,13,14,15,16,17,18,19,20,21] + result[2][2 .. 10] = [22,23,24,25,26,27,28,29,30] + result[3][3 .. 10] = [31,32,33,34,35,36,37,38] + result[4][4 .. 10] = [39,40,41,42,43,44,45] + result[5][5 .. 10] = [46,47,48,49,50,51] + result[6][6 .. 10] = [52,53,54,55,56] + +const combinations = initCombinations() +echo combinations[6][10] From 03afbe00b99da07940adf143de1c2db5bf0c5336 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 28 Dec 2014 00:52:10 +0100 Subject: [PATCH 02/34] minor improvements --- lib/pure/pegs.nim | 2 +- lib/system/excpt.nim | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim index 8b7554661..7cef0a00d 100644 --- a/lib/pure/pegs.nim +++ b/lib/pure/pegs.nim @@ -1433,7 +1433,7 @@ proc eat(p: var PegParser, kind: TTokKind) = if p.tok.kind == kind: getTok(p) else: pegError(p, tokKindToStr[kind] & " expected") -proc parseExpr(p: var PegParser): Peg +proc parseExpr(p: var PegParser): Peg {.gcsafe.} proc getNonTerminal(p: var PegParser, name: string): NonTerminal = for i in 0..high(p.nonterms): diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index e21eeca6a..237b42482 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -296,15 +296,15 @@ when not defined(noSignalHandler): template processSignal(s, action: expr) {.immediate, dirty.} = if s == SIGINT: action("SIGINT: Interrupted by Ctrl-C.\n") elif s == SIGSEGV: - action("SIGSEGV: Illegal storage access. (Attempt to read from nil?)\n") + action("SIGSEGV: Illegal storage access. (Try to compile with -d:useSysAssert -d:useGcAssert for details.)\n") elif s == SIGABRT: when defined(endb): if dbgAborting: return # the debugger wants to abort action("SIGABRT: Abnormal termination.\n") elif s == SIGFPE: action("SIGFPE: Arithmetic error.\n") elif s == SIGILL: action("SIGILL: Illegal operation.\n") - elif s == SIGBUS: - action("SIGBUS: Illegal storage access. (Attempt to read from nil?)\n") + elif s == SIGBUS: + action("SIGBUS: Illegal storage access. (Try to compile with -d:useSysAssert -d:useGcAssert for details.)\n") else: block platformSpecificSignal: when declared(SIGPIPE): From f73938218ec39209ef1d898e26350e4828e1248c Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 28 Dec 2014 01:59:30 +0100 Subject: [PATCH 03/34] fixes #1708, fixes #871 --- compiler/sem.nim | 20 ++++++++++++++++++++ compiler/semexprs.nim | 5 +++-- tests/misc/tcolonisproc.nim | 9 +++++---- tests/misc/tnoinst.nim | 1 + tests/types/temptyseqs.nim | 26 ++++++++++++++++++++++++++ tests/vm/tstringnil.nim | 2 +- web/news.txt | 18 +++++++++++------- 7 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 tests/types/temptyseqs.nim diff --git a/compiler/sem.nim b/compiler/sem.nim index 91adcac5e..9ac7ad139 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -67,12 +67,25 @@ proc fitNode(c: PContext, formal: PType, arg: PNode): PNode = # error correction: result = copyTree(arg) result.typ = formal + else: + let x = result.skipConv + if x.kind == nkPar and formal.kind != tyExpr: + changeType(x, formal, check=true) proc inferWithMetatype(c: PContext, formal: PType, arg: PNode, coerceDistincts = false): PNode var commonTypeBegin = PType(kind: tyExpr) +proc isEmptyContainer(t: PType): bool = + case t.kind + of tyExpr, tyNil: result = true + of tyArray, tyArrayConstr: result = t.sons[1].kind == tyEmpty + of tySet, tySequence, tyOpenArray, tyVarargs: + result = t.sons[0].kind == tyEmpty + of tyGenericInst: result = isEmptyContainer(t.lastSon) + else: result = false + proc commonType*(x, y: PType): PType = # new type relation that is used for array constructors, # if expressions, etc.: @@ -96,6 +109,13 @@ proc commonType*(x, y: PType): PType = # check for seq[empty] vs. seq[int] let idx = ord(b.kind in {tyArray, tyArrayConstr}) if a.sons[idx].kind == tyEmpty: return y + elif a.kind == tyTuple and b.kind == tyTuple and a.len == b.len: + var nt: PType + for i in 0.. Date: Sun, 28 Dec 2014 15:23:05 +0000 Subject: [PATCH 04/34] macros.`$` can now turn a nnkSym into a string. --- lib/core/macros.nim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/core/macros.nim b/lib/core/macros.nim index ed5d3c50c..353254d49 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -649,6 +649,8 @@ proc `$`*(node: PNimrodNode): string {.compileTime.} = result = $node.basename.ident & "*" of nnkStrLit..nnkTripleStrLit: result = node.strVal + of nnkSym: + result = $node.symbol else: badNodeKind node.kind, "$" From a0ad3aa1836902c5c478e57c8fbee75c60a0a155 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 28 Dec 2014 22:24:29 +0100 Subject: [PATCH 05/34] work around a regression caused by the new 'echo' implementation --- lib/pure/unittest.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index 6c0246f8b..21efea3bc 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -97,7 +97,9 @@ proc checkpoint*(msg: string) = template fail* = bind checkpoints for msg in items(checkpoints): - echo msg + # this used to be 'echo' which now breaks due to a bug. XXX will revisit + # this issue later. + stdout.writeln msg when not defined(ECMAScript): if abortOnError: quit(1) From cfb76164b875e4a8e3f5cb1fb8c298d5e3416cab Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 28 Dec 2014 23:01:11 +0100 Subject: [PATCH 06/34] fixes a long standing openssl wrapper bug: pass C compliant allocation functions to CRYPTO_set_mem_functions --- lib/wrappers/openssl.nim | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index ba25fbf1a..f091d8f46 100644 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -280,9 +280,18 @@ when not useWinVersion: proc CRYPTO_set_mem_functions(a,b,c: pointer){.cdecl, dynlib: DLLUtilName, importc.} + proc allocWrapper(size: int): pointer {.cdecl.} = alloc(size) + proc reallocWrapper(p: pointer; newsize: int): pointer {.cdecl.} = + if p == nil: + if newSize > 0: result = alloc(newsize) + elif newsize == 0: dealloc(p) + else: result = realloc(p, newsize) + proc deallocWrapper(p: pointer) {.cdecl.} = + if p != nil: dealloc(p) + proc CRYPTO_malloc_init*() = when not useWinVersion: - CRYPTO_set_mem_functions(alloc, realloc, dealloc) + CRYPTO_set_mem_functions(allocWrapper, reallocWrapper, deallocWrapper) proc SSL_CTX_ctrl*(ctx: SslCtx, cmd: cInt, larg: int, parg: pointer): int{. cdecl, dynlib: DLLSSLName, importc.} From 2bd425c5b403d4e42162245c39b93193769b4d3d Mon Sep 17 00:00:00 2001 From: gmpreussner Date: Sun, 28 Dec 2014 19:49:03 -0500 Subject: [PATCH 07/34] Fixed tusertypeclasses test --- tests/metatype/tusertypeclasses.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/metatype/tusertypeclasses.nim b/tests/metatype/tusertypeclasses.nim index a5d575dbf..6e9e4934b 100644 --- a/tests/metatype/tusertypeclasses.nim +++ b/tests/metatype/tusertypeclasses.nim @@ -12,7 +12,7 @@ type (x < y) is bool ObjectContainer = generic C - C.len is ordinal + C.len is Ordinal for v in items(C): v.type is tuple|object From 27f17437935ee335880c25c1f914f08f753b39ac Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 29 Dec 2014 10:32:00 +0100 Subject: [PATCH 08/34] release of 0.10.2 --- compiler/semexprs.nim | 7 +- compiler/sigmatch.nim | 5 + doc/lib.txt | 4 +- lib/system.nim | 2 +- tests/stdlib/tmath2.nim | 4 +- tests/stdlib/tparsefloat.nim | 3 - tests/stdlib/tpegs.nim | 64 ++-- tests/stdlib/tsockets.nim | 12 - web/download.txt | 16 +- web/news.txt | 329 ++++++++++---------- web/{babelpkglist.nim => nimblepkglist.nim} | 0 web/ticker.txt | 10 +- 12 files changed, 224 insertions(+), 232 deletions(-) delete mode 100644 tests/stdlib/tparsefloat.nim delete mode 100644 tests/stdlib/tsockets.nim rename web/{babelpkglist.nim => nimblepkglist.nim} (100%) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index b11e8cb61..ee3391e3e 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -927,17 +927,18 @@ 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]) - + #debug ty let tbody = ty.sons[0] for s in countup(0, tbody.len-2): let tParam = tbody.sons[s] - if tParam.sym.name == paramName: + if tParam.sym.name.id == paramName.id: let rawTyp = ty.sons[s + 1] if rawTyp.kind == tyStatic: return rawTyp.n else: let foundTyp = makeTypeDesc(c, rawTyp) return newSymNode(copySym(tParam.sym).linkTo(foundTyp), info) + #echo "came here: returned nil" proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = ## returns nil if it's not a built-in field access @@ -972,7 +973,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = # look up if the identifier belongs to the enum: while ty != nil: f = getSymFromList(ty.n, i) - if f != nil: break + if f != nil: break ty = ty.sons[0] # enum inheritance if f != nil: result = newSymNode(f) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 1ec48bd0e..06f9d58b7 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1083,6 +1083,11 @@ proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType, arg: PNode): PNode = # arg.typ can be nil in 'suggest': if isNil(arg.typ): return nil + + # sem'checking for 'echo' needs to be re-entrant: + # XXX we will revisit this issue after 0.10.2 is released + if f == arg.typ and arg.kind == nkHiddenStdConv: return arg + var call = newNodeI(nkCall, arg.info) call.add(f.n.copyTree) call.add(arg.copyTree) diff --git a/doc/lib.txt b/doc/lib.txt index 7d100e1ca..45d9dfd2a 100644 --- a/doc/lib.txt +++ b/doc/lib.txt @@ -154,8 +154,8 @@ Generic Operating System Services * `streams `_ This module provides a stream interface and two implementations thereof: - the `PFileStream` and the `PStringStream` which implement the stream - interface for Nim file objects (`TFile`) and strings. Other modules + the `FileStream` and the `StringStream` which implement the stream + interface for Nim file objects (`File`) and strings. Other modules may provide other implementations for this standard stream interface. * `marshal `_ diff --git a/lib/system.nim b/lib/system.nim index 0cd4b84e2..ca85bf1ad 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 = 1 + NimPatch*: int = 2 ## is the patch number of Nim's version. NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch diff --git a/tests/stdlib/tmath2.nim b/tests/stdlib/tmath2.nim index 935b08634..88d96c80a 100644 --- a/tests/stdlib/tmath2.nim +++ b/tests/stdlib/tmath2.nim @@ -58,7 +58,7 @@ proc TestLoops() = break break - while True: + while true: break @@ -73,7 +73,7 @@ proc main() = res: int s: string #write(stdout, mymax(23, 45)) - write(stdout, "Hallo! Wie heißt du? ") + write(stdout, "Hallo! Wie heisst du? ") s = readLine(stdin) # test the case statement case s diff --git a/tests/stdlib/tparsefloat.nim b/tests/stdlib/tparsefloat.nim deleted file mode 100644 index 38ed2db6d..000000000 --- a/tests/stdlib/tparsefloat.nim +++ /dev/null @@ -1,3 +0,0 @@ -import strutils - -echo ParseFloat("5000") / ParseFloat("10") diff --git a/tests/stdlib/tpegs.nim b/tests/stdlib/tpegs.nim index e5353e4ff..1bc2669c3 100644 --- a/tests/stdlib/tpegs.nim +++ b/tests/stdlib/tpegs.nim @@ -397,7 +397,7 @@ proc esc(c: char, reserved = {'\0'..'\255'}): string = elif c in reserved: result = '\\' & c else: result = $c -proc singleQuoteEsc(c: Char): string = return "'" & esc(c, {'\''}) & "'" +proc singleQuoteEsc(c: char): string = return "'" & esc(c, {'\''}) & "'" proc singleQuoteEsc(str: string): string = result = "'" @@ -421,11 +421,11 @@ proc charSetEscAux(cc: set[char]): string = c1 = c2 inc(c1) -proc CharSetEsc(cc: set[char]): string = +proc charSetEsc(cc: set[char]): string = if card(cc) >= 128+64: - result = "[^" & CharSetEscAux({'\1'..'\xFF'} - cc) & ']' + result = "[^" & charSetEscAux({'\1'..'\xFF'} - cc) & ']' else: - result = '[' & CharSetEscAux(cc) & ']' + result = '[' & charSetEscAux(cc) & ']' proc toStrAux(r: TPeg, res: var string) = case r.kind @@ -522,12 +522,12 @@ proc `$` *(r: TPeg): string {.rtl, extern: "npegsToString".} = type TCaptures* {.final.} = object ## contains the captured substrings. - matches: array[0..maxSubpatterns-1, tuple[first, last: int]] + matches: array[0..MaxSubpatterns-1, tuple[first, last: int]] ml: int origStart: int proc bounds*(c: TCaptures, - i: range[0..maxSubpatterns-1]): tuple[first, last: int] = + i: range[0..MaxSubpatterns-1]): tuple[first, last: int] = ## returns the bounds ``[first..last]`` of the `i`'th capture. result = c.matches[i] @@ -695,7 +695,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. while start+result < s.len: var x = rawMatch(s, p.sons[0], start+result, c) if x >= 0: - if idx < maxSubpatterns: + if idx < MaxSubpatterns: c.matches[idx] = (start, start+result-1) #else: silently ignore the capture inc(result, x) @@ -739,7 +739,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. inc(c.ml) result = rawMatch(s, p.sons[0], start, c) if result >= 0: - if idx < maxSubpatterns: + if idx < MaxSubpatterns: c.matches[idx] = (start, start+result-1) #else: silently ignore the capture else: @@ -836,7 +836,7 @@ iterator findAll*(s: string, pattern: TPeg, start = 0): string = while i < s.len: var L = matchLen(s, pattern, matches, i) if L < 0: break - for k in 0..maxSubPatterns-1: + for k in 0..MaxSubPatterns-1: if isNil(matches[k]): break yield matches[k] inc(i, L) @@ -866,7 +866,7 @@ template `=~`*(s: string, pattern: TPeg): expr = ## echo("syntax error") ## when not definedInScope(matches): - var matches {.inject.}: array[0..maxSubpatterns-1, string] + var matches {.inject.}: array[0..MaxSubpatterns-1, string] match(s, pattern, matches) # ------------------------- more string handling ------------------------------ @@ -907,7 +907,7 @@ proc replacef*(s: string, sub: TPeg, by: string): string {. ## "var1<-keykey; val2<-key2key2" result = "" var i = 0 - var caps: array[0..maxSubpatterns-1, string] + var caps: array[0..MaxSubpatterns-1, string] while i < s.len: var x = matchLen(s, sub, caps, i) if x <= 0: @@ -924,7 +924,7 @@ proc replace*(s: string, sub: TPeg, by = ""): string {. ## in `by`. result = "" var i = 0 - var caps: array[0..maxSubpatterns-1, string] + var caps: array[0..MaxSubpatterns-1, string] while i < s.len: var x = matchLen(s, sub, caps, i) if x <= 0: @@ -942,7 +942,7 @@ proc parallelReplace*(s: string, subs: varargs[ ## applied in parallel. result = "" var i = 0 - var caps: array[0..maxSubpatterns-1, string] + var caps: array[0..MaxSubpatterns-1, string] while i < s.len: block searchSubs: for j in 0..high(subs): @@ -1055,7 +1055,7 @@ type TPegLexer {.inheritable.} = object ## the lexer object. bufpos: int ## the current position within the buffer buf: cstring ## the buffer itself - LineNumber: int ## the current line number + lineNumber: int ## the current line number lineStart: int ## index of last line start in buffer colOffset: int ## column to add filename: string @@ -1118,38 +1118,38 @@ proc getEscapedChar(c: var TPegLexer, tok: var TToken) = case c.buf[c.bufpos] of 'r', 'R', 'c', 'C': add(tok.literal, '\c') - Inc(c.bufpos) + inc(c.bufpos) of 'l', 'L': add(tok.literal, '\L') - Inc(c.bufpos) + inc(c.bufpos) of 'f', 'F': add(tok.literal, '\f') inc(c.bufpos) of 'e', 'E': add(tok.literal, '\e') - Inc(c.bufpos) + inc(c.bufpos) of 'a', 'A': add(tok.literal, '\a') - Inc(c.bufpos) + inc(c.bufpos) of 'b', 'B': add(tok.literal, '\b') - Inc(c.bufpos) + inc(c.bufpos) of 'v', 'V': add(tok.literal, '\v') - Inc(c.bufpos) + inc(c.bufpos) of 't', 'T': add(tok.literal, '\t') - Inc(c.bufpos) + inc(c.bufpos) of 'x', 'X': inc(c.bufpos) var xi = 0 handleHexChar(c, xi) handleHexChar(c, xi) if xi == 0: tok.kind = tkInvalid - else: add(tok.literal, Chr(xi)) + else: add(tok.literal, chr(xi)) of '0'..'9': var val = ord(c.buf[c.bufpos]) - ord('0') - Inc(c.bufpos) + inc(c.bufpos) var i = 1 while (i <= 3) and (c.buf[c.bufpos] in {'0'..'9'}): val = val * 10 + ord(c.buf[c.bufpos]) - ord('0') @@ -1159,11 +1159,11 @@ proc getEscapedChar(c: var TPegLexer, tok: var TToken) = else: tok.kind = tkInvalid of '\0'..'\31': tok.kind = tkInvalid - elif c.buf[c.bufpos] in strutils.letters: + elif c.buf[c.bufpos] in strutils.Letters: tok.kind = tkInvalid else: add(tok.literal, c.buf[c.bufpos]) - Inc(c.bufpos) + inc(c.bufpos) proc skip(c: var TPegLexer) = var pos = c.bufpos @@ -1171,7 +1171,7 @@ proc skip(c: var TPegLexer) = while true: case buf[pos] of ' ', '\t': - Inc(pos) + inc(pos) of '#': while not (buf[pos] in {'\c', '\L', '\0'}): inc(pos) of '\c': @@ -1203,7 +1203,7 @@ proc getString(c: var TPegLexer, tok: var TToken) = break else: add(tok.literal, buf[pos]) - Inc(pos) + inc(pos) c.bufpos = pos proc getDollar(c: var TPegLexer, tok: var TToken) = @@ -1244,7 +1244,7 @@ proc getCharSet(c: var TPegLexer, tok: var TToken) = break else: ch = buf[pos] - Inc(pos) + inc(pos) incl(tok.charset, ch) if buf[pos] == '-': if buf[pos+1] == ']': @@ -1264,7 +1264,7 @@ proc getCharSet(c: var TPegLexer, tok: var TToken) = break else: ch2 = buf[pos] - Inc(pos) + inc(pos) for i in ord(ch)+1 .. ord(ch2): incl(tok.charset, chr(i)) c.bufpos = pos @@ -1275,7 +1275,7 @@ proc getSymbol(c: var TPegLexer, tok: var TToken) = var buf = c.buf while true: add(tok.literal, buf[pos]) - Inc(pos) + inc(pos) if buf[pos] notin strutils.IdentChars: break c.bufpos = pos tok.kind = tkIdentifier @@ -1312,11 +1312,11 @@ proc getTok(c: var TPegLexer, tok: var TToken) = getCharset(c, tok) of '(': tok.kind = tkParLe - Inc(c.bufpos) + inc(c.bufpos) add(tok.literal, '(') of ')': tok.kind = tkParRi - Inc(c.bufpos) + inc(c.bufpos) add(tok.literal, ')') of '.': tok.kind = tkAny diff --git a/tests/stdlib/tsockets.nim b/tests/stdlib/tsockets.nim deleted file mode 100644 index ff566df74..000000000 --- a/tests/stdlib/tsockets.nim +++ /dev/null @@ -1,12 +0,0 @@ -import sockets, os -var s: TSocket -s = socket() -if s == InvalidSocket: osError(osLastError()) - -s.connect("www.google.com", TPort(80)) - -var data: string = "" -s.readLine(data) -echo(data) - - diff --git a/web/download.txt b/web/download.txt index f57e5a249..248c0b1bf 100644 --- a/web/download.txt +++ b/web/download.txt @@ -1,6 +1,6 @@ -You can download the latest version of the Nimrod compiler here. +You can download the latest version of the Nim compiler here. -**Note:** The Nimrod compiler requires a C compiler to compile software. On +**Note:** The Nim compiler requires a C compiler to compile software. On Windows we recommend that you use `Mingw-w64 `_. GCC is recommended on Linux and clang on Mac OS X. @@ -9,10 +9,12 @@ and clang on Mac OS X. Binaries ======== -Unfortunately for now we only provide builds for Windows. +Unfortunately for now we provide no binary builds. -* 32 bit: `nimrod_0.9.6.exe `_ -* 64 bit: `nimrod_0.9.6_x64.exe `_ +.. + Unfortunately for now we only provide builds for Windows. + * 32 bit: `nim_0.10.2.exe `_ + * 64 bit: `nim_0.10.2_x64.exe `_ Installation based on generated C code @@ -22,13 +24,13 @@ This installation method is the preferred way for Linux, Mac OS X, and other Uni like systems. Binary packages may be provided later. -Download `nimrod_0.9.6.zip `_, extract it and follow +Download `nim_0.10.2.zip `_, extract it and follow these instructions: * sh build.sh * Add ``$your_install_dir/bin`` to your PATH. -There are other ways to install Nimrod (like using the ``install.sh`` script), +There are other ways to install Nim (like using the ``install.sh`` script), but these tend to cause more problems. diff --git a/web/news.txt b/web/news.txt index a2b3bdd4c..ddeab0f9b 100644 --- a/web/news.txt +++ b/web/news.txt @@ -2,198 +2,197 @@ News ==== -.. - 2014-10-21 Version 0.10.2 released - ================================== +2014-12-29 Version 0.10.2 released +================================== - This release marks the completion of a very important change to the project: - the official renaming from Nimrod to Nim. Version 0.10.2 contains many language - changes, some of which may break your existing code. For your convenience, we - added a new tool called `nimfix `_ that will help you convert your - existing projects so that it works with the latest version of the compiler. +This release marks the completion of a very important change to the project: +the official renaming from Nimrod to Nim. Version 0.10.2 contains many language +changes, some of which may break your existing code. For your convenience, we +added a new tool called `nimfix `_ that will help you convert your +existing projects so that it works with the latest version of the compiler. - Progress towards version 1.0 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Progress towards version 1.0 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Although Nim is still pre-1.0, we were able to keep the number of breaking - changes to a minimum so far. Starting with version 1.0, we will not introduce - any breaking changes between major release versions. - One of Nim's goals is to ensure that the compiler is as efficient as possible. - Take a look at the - `latest benchmarks `_, - which show that Nim is consistently near - the top and already nearly as fast as C and C++. Recent developments, such as - the new ``asyncdispatch`` module will allow you to write efficient web server - applications using non-blocking code. Nim now also has a built-in thread pool - for lightweight threading through the use of ``spawn``. +Although Nim is still pre-1.0, we were able to keep the number of breaking +changes to a minimum so far. Starting with version 1.0, we will not introduce +any breaking changes between major release versions. +One of Nim's goals is to ensure that the compiler is as efficient as possible. +Take a look at the +`latest benchmarks `_, +which show that Nim is consistently near +the top and already nearly as fast as C and C++. Recent developments, such as +the new ``asyncdispatch`` module will allow you to write efficient web server +applications using non-blocking code. Nim now also has a built-in thread pool +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 new and searchable forums, a new website, and our - documentation generator ``docgen`` has seen major improvements. +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 +documentation generator ``docgen`` has seen major improvements. - What's left to be done - ~~~~~~~~~~~~~~~~~~~~~~ +What's left to be done +~~~~~~~~~~~~~~~~~~~~~~ - The 1.0 release is actually very close. Apart from bug fixes, there are - two major features missing or incomplete: +The 1.0 release is actually very close. Apart from bug fixes, there are +two major features missing or incomplete: - * ``static[T]`` needs to be defined precisely and the bugs in the - implementation need to be fixed. - * Overloading of the assignment operator is required for some generic - containers and needs to be implemented. +* ``static[T]`` needs to be defined precisely and the bugs in the + implementation need to be fixed. +* Overloading of the assignment operator is required for some generic + containers and needs to be implemented. - This means that fancy matrix libraries will finally start to work, which used - to be a major point of pain in the language. +This means that fancy matrix libraries will finally start to work, which used +to be a major point of pain in the language. - Nimble and other Nim tools - ~~~~~~~~~~~~~~~~~~~~~~~~~~ +Nimble and other Nim tools +~~~~~~~~~~~~~~~~~~~~~~~~~~ - Outside of the language and the compiler itself many Nim tools have seen - considerable improvements. +Outside of the language and the compiler itself many Nim tools have seen +considerable improvements. - Babel the Nim package manager has been renamed to Nimble. Nimble's purpose - is the installation of packages containing libraries and/or applications - written in Nim. - Even though Nimble is still very young it already is very - functional. It can install packages by name, it does so by accessing a - packages repository which is hosted on a Github repo. Packages can also be - installed via a Git repo URL or Mercurial repo URL. The package repository - is searchable through Nimble. Anyone is free to add their own packages to - the package repository by forking the - `nim-lang/packages `_ repo and creating - a pull request. Nimble is fully cross-platform and should be fully functional - on all major operating systems. - It is of course completely written in Nim. +Babel the Nim package manager has been renamed to Nimble. Nimble's purpose +is the installation of packages containing libraries and/or applications +written in Nim. +Even though Nimble is still very young it already is very +functional. It can install packages by name, it does so by accessing a +packages repository which is hosted on a Github repo. Packages can also be +installed via a Git repo URL or Mercurial repo URL. The package repository +is searchable through Nimble. Anyone is free to add their own packages to +the package repository by forking the +`nim-lang/packages `_ repo and creating +a pull request. Nimble is fully cross-platform and should be fully functional +on all major operating systems. +It is of course completely written in Nim. - Changelog - ~~~~~~~~~ +Changelog +~~~~~~~~~ - Changes affecting backwards compatibility - ----------------------------------------- +Changes affecting backwards compatibility +----------------------------------------- - - **The language has been renamed from Nimrod to Nim.** The name of the - compiler changed from ``nimrod`` to ``nim`` too. - - ``system.fileHandle`` has been renamed to ``system.getFileHandle`` to - prevent name conflicts with the new type ``FileHandle``. - - Comments are now not part of the AST anymore, as such you cannot use them - in place of ``discard``. - - Large parts of the stdlib got rid of the T/P type prefixes. Instead most - types now simply start with an uppercased letter. The - so called "partial case sensitivity" rule is now active allowing for code - like ``var foo: Foo`` in more contexts. - - String case (or any non-ordinal case) statements - without 'else' are deprecated. - - Recursive tuple types are not allowed anymore. Use ``object`` instead. - - The PEGS module returns ``nil`` instead of ``""`` when an optional capture - fails to match. - - The re module returns ``nil`` instead of ``""`` when an optional capture - fails to match. - - The "symmetric set difference" operator (``-+-``) never worked and has been - removed. - - ``defer`` is a keyword now. - - ``func`` is a keyword now. - - The ``using`` language feature now needs to be activated via the new - ``{.experimental.}`` pragma that enables experimental language features. - - Destructors are now officially *experimental*. - - Standalone ``except`` and ``finally`` statements are deprecated now. - The standalone ``finally`` can be replaced with ``defer``, - standalone ``except`` requires an explicit ``try``. - - Operators ending in ``>`` are considered as "arrow like" and have their - own priority level and are right associative. This means that - the ``=>`` and ``->`` operators from the `future `_ module - work better. - - Field names in tuples are now ignored for type comparisons. This allows - for greater interoperability between different modules. - - Statement lists are not converted to an implicit ``do`` block anymore. This - means the confusing ``nnkDo`` nodes when working with macros are gone for - good. +- **The language has been renamed from Nimrod to Nim.** The name of the + compiler changed from ``nimrod`` to ``nim`` too. +- ``system.fileHandle`` has been renamed to ``system.getFileHandle`` to + prevent name conflicts with the new type ``FileHandle``. +- Comments are now not part of the AST anymore, as such you cannot use them + in place of ``discard``. +- Large parts of the stdlib got rid of the T/P type prefixes. Instead most + types now simply start with an uppercased letter. The + so called "partial case sensitivity" rule is now active allowing for code + like ``var foo: Foo`` in more contexts. +- String case (or any non-ordinal case) statements + without 'else' are deprecated. +- Recursive tuple types are not allowed anymore. Use ``object`` instead. +- The PEGS module returns ``nil`` instead of ``""`` when an optional capture + fails to match. +- The re module returns ``nil`` instead of ``""`` when an optional capture + fails to match. +- The "symmetric set difference" operator (``-+-``) never worked and has been + removed. +- ``defer`` is a keyword now. +- ``func`` is a keyword now. +- The ``using`` language feature now needs to be activated via the new + ``{.experimental.}`` pragma that enables experimental language features. +- Destructors are now officially *experimental*. +- Standalone ``except`` and ``finally`` statements are deprecated now. + The standalone ``finally`` can be replaced with ``defer``, + standalone ``except`` requires an explicit ``try``. +- Operators ending in ``>`` are considered as "arrow like" and have their + own priority level and are right associative. This means that + the ``=>`` and ``->`` operators from the `future `_ module + work better. +- Field names in tuples are now ignored for type comparisons. This allows + for greater interoperability between different modules. +- Statement lists are not converted to an implicit ``do`` block anymore. This + means the confusing ``nnkDo`` nodes when working with macros are gone for + good. - Language Additions - ------------------ +Language Additions +------------------ - - The new concurrency model has been implemented including ``locks`` sections, - lock levels and object field ``guards``. - - The ``parallel`` statement has been implemented. - - ``deepCopy`` has been added to the language. - - 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 - level with the ``--experimental`` command line option. +- The new concurrency model has been implemented including ``locks`` sections, + lock levels and object field ``guards``. +- The ``parallel`` statement has been implemented. +- ``deepCopy`` has been added to the language. +- 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 + level with the ``--experimental`` command line option. - Compiler Additions - ------------------ +Compiler Additions +------------------ - - The compiler now supports *mixed* Objective C / C++ / C code generation: - The modules that use ``importCpp`` or ``importObjc`` are compiled to C++ - or Objective C code, any other module is compiled to C code. This - improves interoperability. - - There is a new ``parallel`` statement for safe fork&join parallel computing. - - ``guard`` and ``lock`` pragmas have been implemented to support safer - concurrent programming. - - The following procs are now available at compile-time:: +- The compiler now supports *mixed* Objective C / C++ / C code generation: + The modules that use ``importCpp`` or ``importObjc`` are compiled to C++ + or Objective C code, any other module is compiled to C code. This + improves interoperability. +- There is a new ``parallel`` statement for safe fork&join parallel computing. +- ``guard`` and ``lock`` pragmas have been implemented to support safer + concurrent programming. +- 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, - os.getEnv, os.existsEnv, os.dirExists, os.fileExists, - system.writeFile + 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, + os.getEnv, os.existsEnv, os.dirExists, os.fileExists, + system.writeFile - - Two backticks now produce a single backtick within an ``emit`` or ``asm`` - statement. - - There is a new tool, `nimfix `_ to help you in updating your - code from Nimrod to Nim. - - The compiler's output has been prettified. +- Two backticks now produce a single backtick within an ``emit`` or ``asm`` + statement. +- There is a new tool, `nimfix `_ to help you in updating your + code from Nimrod to Nim. +- The compiler's output has been prettified. - Library Additions - ----------------- +Library Additions +----------------- - - Added module ``fenv`` to control the handling of floating-point rounding and - exceptions (overflow, division by zero, etc.). - - ``system.setupForeignThreadGc`` can be used for better interaction with - foreign libraries that create threads and run a Nim callback from these - foreign threads. - - List comprehensions have been implemented as a macro in the ``future`` - module. - - The new Async module (``asyncnet``) now supports SSL. - - The ``smtp`` module now has an async implementation. - - Added module ``asyncfile`` which implements asynchronous file reading - and writing. - - ``osproc.kill`` has been added. - - ``asyncnet`` and ``asynchttpserver`` now support ``SO_REUSEADDR``. +- Added module ``fenv`` to control the handling of floating-point rounding and + exceptions (overflow, division by zero, etc.). +- ``system.setupForeignThreadGc`` can be used for better interaction with + foreign libraries that create threads and run a Nim callback from these + foreign threads. +- List comprehensions have been implemented as a macro in the ``future`` + module. +- The new Async module (``asyncnet``) now supports SSL. +- The ``smtp`` module now has an async implementation. +- Added module ``asyncfile`` which implements asynchronous file reading + and writing. +- ``osproc.kill`` has been added. +- ``asyncnet`` and ``asynchttpserver`` now support ``SO_REUSEADDR``. - Bugfixes - -------- +Bugfixes +-------- - - ``nil`` and ``NULL`` are now preserved between Nim and databases in the - ``db_*`` modules. - - Fixed issue with OS module in non-unicode mode on Windows. - - Fixed issue with ``x.low`` - (`#1366 `_). - - Fixed tuple unpacking issue inside closure iterators - (`#1067 `_). - - Fixed ENDB compilation issues. - - Many ``asynchttpserver`` fixes. - - Macros can now keep global state across macro calls - (`#903 `_). - - ``osproc`` fixes on Windows. - - ``osproc.terminate`` fixed. - - Improvements to exception handling in async procedures. - (`#1487 `_). - - ``try`` now works at compile-time. - - Fixes ``T = ref T`` to be an illegal recursive type. - - Self imports are now disallowed. - - Improved effect inference. - - Fixes for the ``math`` module on Windows. - - User defined pragmas will now work for generics that have - been instantiated in different modules. - - Fixed queue exhaustion bug. - - Many, many more. +- ``nil`` and ``NULL`` are now preserved between Nim and databases in the + ``db_*`` modules. +- Fixed issue with OS module in non-unicode mode on Windows. +- Fixed issue with ``x.low`` + (`#1366 `_). +- Fixed tuple unpacking issue inside closure iterators + (`#1067 `_). +- Fixed ENDB compilation issues. +- Many ``asynchttpserver`` fixes. +- Macros can now keep global state across macro calls + (`#903 `_). +- ``osproc`` fixes on Windows. +- ``osproc.terminate`` fixed. +- Improvements to exception handling in async procedures. + (`#1487 `_). +- ``try`` now works at compile-time. +- Fixes ``T = ref T`` to be an illegal recursive type. +- Self imports are now disallowed. +- Improved effect inference. +- Fixes for the ``math`` module on Windows. +- User defined pragmas will now work for generics that have + been instantiated in different modules. +- Fixed queue exhaustion bug. +- Many, many more. 2014-12-09 New website design! diff --git a/web/babelpkglist.nim b/web/nimblepkglist.nim similarity index 100% rename from web/babelpkglist.nim rename to web/nimblepkglist.nim diff --git a/web/ticker.txt b/web/ticker.txt index a0d2f0a78..64218084e 100644 --- a/web/ticker.txt +++ b/web/ticker.txt @@ -1,13 +1,13 @@ + +

Dec 29, 2014

+

Nim version 0.10.2 has been released!

+
+

Dec 9, 2014

The new website design and forum are now online!

- -

Oct 19, 2014

-

Nimrod version 0.9.6 has been released!

-
-

Feb 11, 2014

Nimrod featured in Dr. Dobb's Journal

From 3f113f946d3a8569f420e1465445ec162bfcaf99 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 29 Dec 2014 12:12:05 +0100 Subject: [PATCH 09/34] 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 9ee3eb9b9..fe1b9a192 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 f380d2548aefc53b817385b874cee51e21950c3a Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 29 Dec 2014 13:41:19 +0100 Subject: [PATCH 10/34] minor website update --- web/download.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/download.txt b/web/download.txt index 248c0b1bf..1ba1ad5f7 100644 --- a/web/download.txt +++ b/web/download.txt @@ -13,8 +13,8 @@ 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 `_ + * 32 bit: `nim_0.10.2.exe `_ + * 64 bit: `nim_0.10.2_x64.exe `_ Installation based on generated C code @@ -24,7 +24,7 @@ This installation method is the preferred way for Linux, Mac OS X, and other Uni like systems. Binary packages may be provided later. -Download `nim_0.10.2.zip `_, extract it and follow +Download `nim-0.10.2.zip `_, extract it and follow these instructions: * sh build.sh From 6d749aed291dbe27a42fef25550460cbd2fe6990 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Mon, 29 Dec 2014 18:00:50 +0000 Subject: [PATCH 11/34] 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 ddeab0f9b..cca2aaeee 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 12/34] 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 0b18e6bcc..4c48350aa 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 13/34] 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 1baff8c55..0ed4289c4 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 14/34] 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 cca2aaeee..75c574405 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 15/34] 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 254b91c77..908625e18 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 16/34] 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 565bb4353..d85dbf42c 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 ed2964cf9..434d25e48 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 17/34] 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 ca85bf1ad..b7c77e276 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 18/34] 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 f423a34a3..becec928e 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 19/34] 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 76d17bc4a..51a12141b 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 20/34] 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 bbd3776d7..0596076b3 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 1ba1ad5f7..497781ad6 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 75c574405..ee9ad8837 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 21/34] 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 deb120372..0498a0e70 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 62a011999..e23deea5b 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 22/34] removed outdated documentation --- doc/nimc.txt | 52 ---------------------------------------------------- 1 file changed, 52 deletions(-) diff --git a/doc/nimc.txt b/doc/nimc.txt index 92acd3979..a2274febd 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 23/34] 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 eb16217cd..ffe2d5e88 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 24/34] 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 ee3391e3e..b2f623fb8 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 7c32b0051..06959b8d1 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 2decb5d0b..81a4465c5 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 4305a48e1..eb15c3809 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 06f9d58b7..d7bf4fee9 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 000000000..188db88f6 --- /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 25/34] 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 576b6d2bb..1f14eb21b 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 26/34] 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 79228c1a4..e3831617c 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 27/34] 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 f67cd239e..4a77773e6 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 28/34] 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 b2f623fb8..60240e6eb 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 06959b8d1..1ab4f5989 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 000000000..73a24a76a --- /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 29/34] 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 d7bf4fee9..b58818a29 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 3c2b9ee5e..8b7fe4e46 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 30/34] 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 ba7697c4c..f4d8b9dcb 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 b2f623fb8..f71847946 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 a7603147c..3b0332939 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 c700db323..f7b00c8f8 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 000000000..23b9ce64f --- /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 31/34] 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 6e239d681..9d3409164 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 e2d2203779ed17174542e2ae4b64132cc8a5c7f0 Mon Sep 17 00:00:00 2001 From: Konstantin Molchanov Date: Thu, 1 Jan 2015 21:43:14 +0300 Subject: [PATCH 32/34] 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 46eda7ae3..472017563 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 33/34] 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 6f7a216a5..fed52ac15 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 34/34] 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 3e5ca0795..d07d6eae1 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 000000000..acccf182c --- /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)