From 9a629d72e8560011d1f9351d22ffee8b7ed5bd43 Mon Sep 17 00:00:00 2001 From: apense Date: Sun, 12 Apr 2015 20:38:35 -0400 Subject: [PATCH 01/12] Added peeking procedures to streams Adds peeking to streams, which is just like reading, but at the end, the stream position hasn't changed. --- lib/pure/streams.nim | 112 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 1 deletion(-) diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index e706f20160..798c587a1d 100644 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.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. @@ -31,6 +31,8 @@ type getPositionImpl*: proc (s: Stream): int {.nimcall, tags: [], gcsafe.} readDataImpl*: proc (s: Stream, buffer: pointer, bufLen: int): int {.nimcall, tags: [ReadIOEffect], gcsafe.} + peekDataImpl*: proc (s: Stream, buffer: pointer, + bufLen: int): int {.nimcall, tags: [ReadIOEffect], gcsafe.} writeDataImpl*: proc (s: Stream, buffer: pointer, bufLen: int) {.nimcall, tags: [WriteIOEffect], gcsafe.} flushImpl*: proc (s: Stream) {.nimcall, tags: [WriteIOEffect], gcsafe.} @@ -84,6 +86,11 @@ proc readData*(s, unused: Stream, buffer: pointer, ## low level proc that reads data into an untyped `buffer` of `bufLen` size. result = s.readDataImpl(s, buffer, bufLen) +proc peekData*(s: Stream, buffer: pointer, bufLen: int): int = + ## low level proc that reads data into an untyped `buffer` of `bufLen` size + ## without moving stream position + result = s.peekDataImpl(s, buffer, bufLen) + proc writeData*(s: Stream, buffer: pointer, bufLen: int) = ## low level proc that writes an untyped `buffer` of `bufLen` size ## to the stream `s`. @@ -121,39 +128,77 @@ proc read[T](s: Stream, result: var T) = if readData(s, addr(result), sizeof(T)) != sizeof(T): raise newEIO("cannot read from stream") +proc peek[T](s: Stream, result: var T) = + ## generic peek procedure. Peeks `result` from the stream `s`. + if peekData(s, addr(result), sizeof(T)) != sizeof(T): + raise newEIO("cannot read from stream") + proc readChar*(s: Stream): char = ## 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 peekChar*(s: Stream): char = + ## peeks a char from the stream `s`. Raises `EIO` if an error occurred. + ## Returns '\0' as an EOF marker. + if peekData(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 occurred. read(s, result) +proc peekBool*(s: Stream): bool = + ## peeks a bool from the stream `s`. Raises `EIO` if an error occured. + peek(s, result) + proc readInt8*(s: Stream): int8 = ## reads an int8 from the stream `s`. Raises `EIO` if an error occurred. read(s, result) +proc peekInt8*(s: Stream): int8 = + ## peeks an int8 from the stream `s`. Raises `EIO` if an error occurred. + peek(s, result) + proc readInt16*(s: Stream): int16 = ## reads an int16 from the stream `s`. Raises `EIO` if an error occurred. read(s, result) +proc peekInt16*(s: Stream): int16 = + ## peeks an int16 from the stream `s`. Raises `EIO` if an error occurred. + peek(s, result) + proc readInt32*(s: Stream): int32 = ## reads an int32 from the stream `s`. Raises `EIO` if an error occurred. read(s, result) +proc peekInt32*(s: Stream): int32 = + ## peeks an int32 from the stream `s`. Raises `EIO` if an error occurred. + peek(s, result) + proc readInt64*(s: Stream): int64 = ## reads an int64 from the stream `s`. Raises `EIO` if an error occurred. read(s, result) +proc peekInt64*(s: Stream): int64 = + ## peeks an int64 from the stream `s`. Raises `EIO` if an error occurred. + peek(s, result) + proc readFloat32*(s: Stream): float32 = ## reads a float32 from the stream `s`. Raises `EIO` if an error occurred. read(s, result) +proc peekFloat32*(s: Stream): float32 = + ## peeks a float32 from the stream `s`. Raises `EIO` if an error occurred. + peek(s, result) + proc readFloat64*(s: Stream): float64 = ## reads a float64 from the stream `s`. Raises `EIO` if an error occurred. read(s, result) +proc peekFloat64*(s: Stream): float64 = + ## peeks a float64 from the stream `s`. Raises `EIO` if an error occurred. + peek(s, result) + proc readStr*(s: Stream, length: int): TaintedString = ## reads a string of length `length` from the stream `s`. Raises `EIO` if ## an error occurred. @@ -161,6 +206,13 @@ proc readStr*(s: Stream, length: int): TaintedString = var L = readData(s, addr(string(result)[0]), length) if L != length: setLen(result.string, L) +proc peekStr*(s: Stream, length: int): TaintedString = + ## peeks a string of length `length` from the stream `s`. Raises `EIO` if + ## an error occurred. + result = newString(length).TaintedString + var L = peekData(s, addr(string(result)[0]), length) + if L != length: setLen(result.string, L) + proc readLine*(s: Stream, line: var TaintedString): bool = ## reads a line of text from the stream `s` into `line`. `line` must not be ## ``nil``! May throw an IO exception. @@ -181,6 +233,30 @@ proc readLine*(s: Stream, line: var TaintedString): bool = line.string.add(c) result = true +proc peekLine*(s: Stream, line: var TaintedString): bool = + ## peeks a line of text from the stream `s` into `line`. `line` must not be + ## ``nil``! May throw an IO exception. + ## A line of text may be delimited by ``CR``, ``LF`` or + ## ``CRLF``. The newline character(s) are not part of the returned string. + ## Returns ``false`` if the end of the file has been reached, ``true`` + ## otherwise. If ``false`` is returned `line` contains no new data. + line.string.setLen(0) + let pos = getPosition(s) + while true: + var c = readChar(s) + if c == '\c': + c = readChar(s) + break + elif c == '\L': break + elif c == '\0': + if line.len > 0: break + else: + setPosition(s, pos) + return false + line.string.add(c) + setPosition(s, pos) + result = true + proc readLine*(s: Stream): TaintedString = ## Reads a line from a stream `s`. Note: This is not very efficient. Raises ## `EIO` if an error occurred. @@ -195,6 +271,23 @@ proc readLine*(s: Stream): TaintedString = else: result.string.add(c) +proc peekLine*(s: Stream): TaintedString = + ## Peeks a line from a stream `s`. Note: This is not very efficient. Raises + ## `EIO` if an error occurred. + result = TaintedString"" + let pos = getPosition(s) + while true: + var c = readChar(s) + if c == '\c': + c = readChar(s) + setPosition(s, pos) + break + if c == '\L' or c == '\0': + setPosition(s, pos) + break + else: + result.string.add(c) + type StringStream* = ref StringStreamObj ## a stream that encapsulates a string StringStreamObj* = object of StreamObj @@ -222,6 +315,12 @@ proc ssReadData(s: Stream, buffer: pointer, bufLen: int): int = copyMem(buffer, addr(s.data[s.pos]), result) inc(s.pos, result) +proc ssPeekData(s: Stream, buffer: pointer, bufLen: int): int = + var s = StringStream(s) + result = min(bufLen, s.data.len - s.pos) + if result > 0: + copyMem(buffer, addr(s.data[s.pos]), result) + proc ssWriteData(s: Stream, buffer: pointer, bufLen: int) = var s = StringStream(s) if bufLen <= 0: @@ -245,6 +344,7 @@ proc newStringStream*(s: string = ""): StringStream = result.setPositionImpl = ssSetPosition result.getPositionImpl = ssGetPosition result.readDataImpl = ssReadData + result.peekDataImpl = ssPeekData result.writeDataImpl = ssWriteData when not defined(js): @@ -266,6 +366,11 @@ when not defined(js): proc fsReadData(s: Stream, buffer: pointer, bufLen: int): int = result = readBuffer(FileStream(s).f, buffer, bufLen) + + proc fsPeekData(s: Stream, buffer: pointer, bufLen: int): int = + let pos = fsGetPosition(s) + result = readBuffer(FileStream(s).f, buffer, bufLen) + fsSetPosition(s, pos) proc fsWriteData(s: Stream, buffer: pointer, bufLen: int) = if writeBuffer(FileStream(s).f, buffer, bufLen) != bufLen: @@ -280,6 +385,7 @@ when not defined(js): result.setPositionImpl = fsSetPosition result.getPositionImpl = fsGetPosition result.readDataImpl = fsReadData + result.peekDataImpl = fsPeekData result.writeDataImpl = fsWriteData result.flushImpl = fsFlush @@ -329,6 +435,9 @@ else: proc hsReadData(s: FileHandleStream, buffer: pointer, bufLen: int): int = result = posix.read(s.handle, buffer, bufLen) inc(s.pos, result) + + proc hsPeekData(s: FileHandleStream, buffer: pointer, bufLen: int): int = + result = posix.read(s.handle, buffer, bufLen) proc hsWriteData(s: FileHandleStream, buffer: pointer, bufLen: int) = if posix.write(s.handle, buffer, bufLen) != bufLen: @@ -344,6 +453,7 @@ else: result.setPosition = hsSetPosition result.getPosition = hsGetPosition result.readData = hsReadData + result.peekData = hsPeekData result.writeData = hsWriteData proc newFileHandleStream*(filename: string, From 80b5e612c0f92f2bae6e148317a682deb86821f0 Mon Sep 17 00:00:00 2001 From: apense Date: Mon, 4 May 2015 08:49:41 -0400 Subject: [PATCH 02/12] Update streams.nim --- lib/pure/streams.nim | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index 798c587a1d..ce33a96254 100644 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.nim @@ -471,3 +471,13 @@ else: var handle = open(filename, flags) if handle < 0: raise newEOS("posix.open() call failed") result = newFileHandleStream(handle) + +when defined(testing): + var ss = newStringStream("The quick brown fox jumped over the lazy dog.\nThe lazy dog ran") + assert(ss.getPosition == 0) + assert(ss.peekStr(5) == "The q") + assert(ss.getPosition == 0) # haven't moved + assert(ss.readStr(5) == "The q") + assert(ss.getPosition == 5) # did move + assert(ss.peekLine() == "uick brown fox jumped over the lazy dog.") + assert(ss.getPosition == 5) # haven't moved From 2a08bbdf31ce693ec0741ecbc9ae78a4d7b9a051 Mon Sep 17 00:00:00 2001 From: Reimer Behrends Date: Thu, 7 May 2015 14:35:39 +0200 Subject: [PATCH 03/12] Fix GC scanning of registers on x86_64 architectures. It is possible for jmp_buf to not be word-aligned or addresses in the register dump to not be word-aligned. This can result in either addresses in registers being missed or even addresses on the stack past the register area not being scanned properly. --- lib/system/gc.nim | 9 +++++++++ lib/system/gc_ms.nim | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/lib/system/gc.nim b/lib/system/gc.nim index c4374d00c6..e0d1006d95 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -922,6 +922,15 @@ else: if c_setjmp(registers) == 0'i32: # To fill the C stack with registers. var max = cast[ByteAddress](gch.stackBottom) var sp = cast[ByteAddress](addr(registers)) + when defined(amd64): + # words within the jmp_buf structure may not be properly aligned. + let regEnd = sp +% sizeof(registers) + while sp <% regEnd: + gcMark(gch, cast[PPointer](sp)[]) + gcMark(gch, cast[PPointer](sp +% sizeof(pointer) div 2)[]) + sp = sp +% sizeof(pointer) + # Make sure sp is word-aligned + sp = sp and not (sizeof(pointer) - 1) # loop unrolled: while sp <% max - 8*sizeof(pointer): gcMark(gch, cast[PStackSlice](sp)[0]) diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim index e287bf5d90..a0699f46a8 100644 --- a/lib/system/gc_ms.nim +++ b/lib/system/gc_ms.nim @@ -514,6 +514,15 @@ else: if c_setjmp(registers) == 0'i32: # To fill the C stack with registers. var max = cast[ByteAddress](gch.stackBottom) var sp = cast[ByteAddress](addr(registers)) + when defined(amd64): + # words within the jmp_buf structure may not be properly aligned. + let regEnd = sp +% sizeof(registers) + while sp <% regEnd: + gcMark(gch, cast[PPointer](sp)[]) + gcMark(gch, cast[PPointer](sp +% sizeof(pointer) div 2)[]) + sp = sp +% sizeof(pointer) + # Make sure sp is word-aligned + sp = sp and not (sizeof(pointer) - 1) # loop unrolled: while sp <% max - 8*sizeof(pointer): gcMark(gch, cast[PStackSlice](sp)[0]) From 7b26df50d75f64216997c71a304c7b413fc65dda Mon Sep 17 00:00:00 2001 From: apense Date: Fri, 15 May 2015 23:52:55 -0400 Subject: [PATCH 04/12] Small sequence fix for algorithm.nim Since #853 was fixed, this should work fine. The `result = @[]` was swapped to the same syntax, too. --- lib/pure/algorithm.nim | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim index 6dfdff2750..352b177e23 100644 --- a/lib/pure/algorithm.nim +++ b/lib/pure/algorithm.nim @@ -232,7 +232,7 @@ template sortedByIt*(seq1, op: expr): expr = proc product*[T](x: openArray[seq[T]]): seq[seq[T]] = ## produces the Cartesian product of the array. Warning: complexity ## may explode. - result = @[] + result = newSeq[seq[T]]() if x.len == 0: return if x.len == 1: @@ -242,8 +242,7 @@ proc product*[T](x: openArray[seq[T]]): seq[seq[T]] = indexes = newSeq[int](x.len) initial = newSeq[int](x.len) index = 0 - # replace with newSeq as soon as #853 is fixed - var next: seq[T] = @[] + var next = newSeq[T]() next.setLen(x.len) for i in 0..(x.len-1): if len(x[i]) == 0: return From d48bcb9873e426ece794d517290f262f6345f3b2 Mon Sep 17 00:00:00 2001 From: apense Date: Thu, 21 May 2015 17:51:41 -0400 Subject: [PATCH 05/12] Rewrote some peeking procedures Use `defer`s and `read...` procs that are already in place. Someone should check that the `defer`s are written correctly. I'm new to using them. --- lib/pure/streams.nim | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index ce33a96254..9054031e0e 100644 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.nim @@ -240,22 +240,9 @@ proc peekLine*(s: Stream, line: var TaintedString): bool = ## ``CRLF``. The newline character(s) are not part of the returned string. ## Returns ``false`` if the end of the file has been reached, ``true`` ## otherwise. If ``false`` is returned `line` contains no new data. - line.string.setLen(0) let pos = getPosition(s) - while true: - var c = readChar(s) - if c == '\c': - c = readChar(s) - break - elif c == '\L': break - elif c == '\0': - if line.len > 0: break - else: - setPosition(s, pos) - return false - line.string.add(c) - setPosition(s, pos) - result = true + defer: setPosition(s, pos) + readLine(s, line) proc readLine*(s: Stream): TaintedString = ## Reads a line from a stream `s`. Note: This is not very efficient. Raises @@ -274,19 +261,9 @@ proc readLine*(s: Stream): TaintedString = proc peekLine*(s: Stream): TaintedString = ## Peeks a line from a stream `s`. Note: This is not very efficient. Raises ## `EIO` if an error occurred. - result = TaintedString"" let pos = getPosition(s) - while true: - var c = readChar(s) - if c == '\c': - c = readChar(s) - setPosition(s, pos) - break - if c == '\L' or c == '\0': - setPosition(s, pos) - break - else: - result.string.add(c) + defer: setPosition(s, pos) + readLine(s) type StringStream* = ref StringStreamObj ## a stream that encapsulates a string From 1dd2379e4c662a090086456fdbe0569332967db0 Mon Sep 17 00:00:00 2001 From: HOLYCOWBATMAN Date: Sun, 24 May 2015 15:29:35 -0400 Subject: [PATCH 06/12] system.nim -> disabled Uninit warnings --- lib/system.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 1e6f76f3df..c02ae4bb39 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -61,7 +61,7 @@ const on* = true ## alias for ``true`` off* = false ## alias for ``false`` -{.push warning[GcMem]: off.} +{.push warning[GcMem]: off, warning[Uninit]: off.} {.push hints: off.} type @@ -3273,4 +3273,4 @@ proc xlen*[T](x: seq[T]): int {.magic: "XLenSeq", noSideEffect.} = ## This is an optimization that rarely makes sense. discard -{.pop.} #{.push warning[GcMem]: off.} +{.pop.} #{.push warning[GcMem]: off, warning[Uninit]: off.} From 928b730d1b6ee24e39c0ed5e6c5326f0c3f002a6 Mon Sep 17 00:00:00 2001 From: Simon Hafner Date: Sun, 24 May 2015 14:29:43 -0500 Subject: [PATCH 07/12] fixes #2694 --- compiler/nimsuggest/nimsuggest.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/nimsuggest/nimsuggest.nim b/compiler/nimsuggest/nimsuggest.nim index 3b4aa658de..b049899cb4 100644 --- a/compiler/nimsuggest/nimsuggest.nim +++ b/compiler/nimsuggest/nimsuggest.nim @@ -118,7 +118,7 @@ proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int) = gTrackPos = newLineInfo(dirtyIdx, line, col) gErrorCounter = 0 - if not isKnownFile: + if isKnownFile: compileProject(dirtyIdx) else: compileProject() From f610f8c5f049940aa5f6140b66830a1b2581a64c Mon Sep 17 00:00:00 2001 From: apense Date: Sun, 24 May 2015 18:36:52 -0400 Subject: [PATCH 08/12] Added defer statement All peeks should be covered by defer now, I think --- lib/pure/streams.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index 9054031e0e..77698d3292 100644 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.nim @@ -346,8 +346,8 @@ when not defined(js): proc fsPeekData(s: Stream, buffer: pointer, bufLen: int): int = let pos = fsGetPosition(s) + defer: fsSetPosition(s, pos) result = readBuffer(FileStream(s).f, buffer, bufLen) - fsSetPosition(s, pos) proc fsWriteData(s: Stream, buffer: pointer, bufLen: int) = if writeBuffer(FileStream(s).f, buffer, bufLen) != bufLen: From 4cc722a41420e24f53a3a66be08e3b4a41b76d69 Mon Sep 17 00:00:00 2001 From: Simon Hafner Date: Sun, 24 May 2015 15:22:22 -0500 Subject: [PATCH 09/12] now nimsuggest works on the first sug --- compiler/nimsuggest/nimsuggest.nim | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/nimsuggest/nimsuggest.nim b/compiler/nimsuggest/nimsuggest.nim index b049899cb4..2c785d118b 100644 --- a/compiler/nimsuggest/nimsuggest.nim +++ b/compiler/nimsuggest/nimsuggest.nim @@ -118,10 +118,9 @@ proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int) = gTrackPos = newLineInfo(dirtyIdx, line, col) gErrorCounter = 0 - if isKnownFile: - compileProject(dirtyIdx) - else: + if not isKnownFile: compileProject() + compileProject(dirtyIdx) proc executeEPC(cmd: IdeCmd, args: SexpNode) = let @@ -192,8 +191,6 @@ proc parseCmdLine(cmd: string) = execute(gIdeCmd, orig, dirtyfile, line, col-1) proc serve() = - # do not stop after the first error: - msgs.gErrorMax = high(int) case gMode: of mstdin: echo Help @@ -278,6 +275,9 @@ proc mainCommand = # current path is always looked first for modules prependStr(searchPaths, gProjectPath) + # do not stop after the first error: + msgs.gErrorMax = high(int) + compileProject() serve() proc processCmdLine*(pass: TCmdLinePass, cmd: string) = From bdb55c5d1d85f9425004f53f7e2cac5d31c90023 Mon Sep 17 00:00:00 2001 From: Flaviu Tamas Date: Sun, 24 May 2015 22:06:12 -0400 Subject: [PATCH 10/12] Fix typo in manual See IRC logs around Sun May 24 22:06:26 EDT 2015 for details --- doc/manual/trmacros.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/manual/trmacros.txt b/doc/manual/trmacros.txt index 90d01e475b..53c604f7bc 100644 --- a/doc/manual/trmacros.txt +++ b/doc/manual/trmacros.txt @@ -345,15 +345,15 @@ optimization for types that have copying semantics: ## puts a (key, value)-pair into `t`. The semantics of string require ## a copy here: let idx = findInsertionPosition(key) - t[idx] = key - t[idx] = val + t[idx].key = key + t[idx].val = val proc `[]=`*(t: var Table, key: string{call}, val: string{call}) = ## puts a (key, value)-pair into `t`. Optimized version that knows that ## the strings are unique and thus don't need to be copied: let idx = findInsertionPosition(key) - shallowCopy t[idx], key - shallowCopy t[idx], val + shallowCopy t[idx].key, key + shallowCopy t[idx].val, val var t: Table # overloading resolution ensures that the optimized []= is called here: From d8921a44859646d67f38f9bbb039b48e7285790e Mon Sep 17 00:00:00 2001 From: reactormonk Date: Sun, 24 May 2015 21:08:12 -0500 Subject: [PATCH 11/12] Revert "Fix typo in manual" --- doc/manual/trmacros.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/manual/trmacros.txt b/doc/manual/trmacros.txt index 53c604f7bc..90d01e475b 100644 --- a/doc/manual/trmacros.txt +++ b/doc/manual/trmacros.txt @@ -345,15 +345,15 @@ optimization for types that have copying semantics: ## puts a (key, value)-pair into `t`. The semantics of string require ## a copy here: let idx = findInsertionPosition(key) - t[idx].key = key - t[idx].val = val + t[idx] = key + t[idx] = val proc `[]=`*(t: var Table, key: string{call}, val: string{call}) = ## puts a (key, value)-pair into `t`. Optimized version that knows that ## the strings are unique and thus don't need to be copied: let idx = findInsertionPosition(key) - shallowCopy t[idx].key, key - shallowCopy t[idx].val, val + shallowCopy t[idx], key + shallowCopy t[idx], val var t: Table # overloading resolution ensures that the optimized []= is called here: From 513423a08dcc6f2011f9af394c2a66c54445d5eb Mon Sep 17 00:00:00 2001 From: apense Date: Mon, 25 May 2015 02:44:08 -0400 Subject: [PATCH 12/12] Corrected various links within documentation Corrected `noSideEffect pragma` links in lib/system (The newer documentation uses slightly different links) Corrected `noSideEffect pragma` in types links to match the updated link names Minor link adjustment in stmts to match the newer link names --- doc/manual/stmts.txt | 6 +++--- doc/manual/types.txt | 2 +- lib/system.nim | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/manual/stmts.txt b/doc/manual/stmts.txt index 5e47110e9a..210ca70642 100644 --- a/doc/manual/stmts.txt +++ b/doc/manual/stmts.txt @@ -176,9 +176,9 @@ The rules for compile-time computability are: 1. Literals are compile-time computable. 2. Type conversions are compile-time computable. 3. Procedure calls of the form ``p(X)`` are compile-time computable if - ``p`` is a proc without side-effects (see the `noSideEffect pragma`_ - for details) and if ``X`` is a (possibly empty) list of compile-time - computable arguments. + ``p`` is a proc without side-effects (see the `noSideEffect pragma + <#pragmas-nosideeffect-pragma>`_ for details) and if ``X`` is a + (possibly empty) list of compile-time computable arguments. Constants cannot be of type ``ptr``, ``ref``, ``var`` or ``object``, nor can diff --git a/doc/manual/types.txt b/doc/manual/types.txt index bdf51941da..689605f08a 100644 --- a/doc/manual/types.txt +++ b/doc/manual/types.txt @@ -963,7 +963,7 @@ Most calling conventions exist only for the Windows 32-bit platform. Assigning/passing a procedure to a procedural variable is only allowed if one of the following conditions hold: 1) The procedure that is accessed resides in the current module. -2) The procedure is marked with the ``procvar`` pragma (see `procvar pragma`_). +2) The procedure is marked with the ``procvar`` pragma (see `procvar pragma <#pragmas-procvar-pragma>`_). 3) The procedure has a calling convention that differs from ``nimcall``. 4) The procedure is anonymous. diff --git a/lib/system.nim b/lib/system.nim index c02ae4bb39..a4b053ca78 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2248,14 +2248,14 @@ proc echo*(x: varargs[expr, `$`]) {.magic: "Echo", tags: [WriteIOEffect], ## Unlike other IO operations this is guaranteed to be thread-safe as ## ``echo`` is very often used for debugging convenience. If you want to use ## ``echo`` inside a `proc without side effects - ## `_ you can use `debugEcho <#debugEcho>`_ + ## `_ you can use `debugEcho <#debugEcho>`_ ## instead. proc debugEcho*(x: varargs[expr, `$`]) {.magic: "Echo", noSideEffect, tags: [], raises: [].} ## Same as `echo <#echo>`_, but as a special semantic rule, ``debugEcho`` ## pretends to be free of side effects, so that it can be used for debugging - ## routines marked as `noSideEffect `_. + ## routines marked as `noSideEffect `_. template newException*(exceptn: typedesc, message: string): expr = ## creates an exception object of type ``exceptn`` and sets its ``msg`` field