mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 17:34:43 +00:00
Merge remote-tracking branch 'upstream/devel' into devel
This commit is contained in:
@@ -119,9 +119,8 @@ proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int) =
|
||||
gTrackPos = newLineInfo(dirtyIdx, line, col)
|
||||
gErrorCounter = 0
|
||||
if not isKnownFile:
|
||||
compileProject(dirtyIdx)
|
||||
else:
|
||||
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) =
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -243,7 +243,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:
|
||||
@@ -253,8 +253,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
|
||||
|
||||
@@ -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,17 @@ 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.
|
||||
let pos = getPosition(s)
|
||||
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
|
||||
## `EIO` if an error occurred.
|
||||
@@ -195,6 +258,13 @@ 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.
|
||||
let pos = getPosition(s)
|
||||
defer: setPosition(s, pos)
|
||||
readLine(s)
|
||||
|
||||
type
|
||||
StringStream* = ref StringStreamObj ## a stream that encapsulates a string
|
||||
StringStreamObj* = object of StreamObj
|
||||
@@ -222,6 +292,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 +321,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 +343,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)
|
||||
defer: fsSetPosition(s, pos)
|
||||
result = readBuffer(FileStream(s).f, buffer, bufLen)
|
||||
|
||||
proc fsWriteData(s: Stream, buffer: pointer, bufLen: int) =
|
||||
if writeBuffer(FileStream(s).f, buffer, bufLen) != bufLen:
|
||||
@@ -280,6 +362,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 +412,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 +430,7 @@ else:
|
||||
result.setPosition = hsSetPosition
|
||||
result.getPosition = hsGetPosition
|
||||
result.readData = hsReadData
|
||||
result.peekData = hsPeekData
|
||||
result.writeData = hsWriteData
|
||||
|
||||
proc newFileHandleStream*(filename: string,
|
||||
@@ -361,3 +448,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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
## <manual.html#nosideeffect-pragma>`_ you can use `debugEcho <#debugEcho>`_
|
||||
## <manual.html#pragmas-nosideeffect-pragma>`_ 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 <manual.html#nosideeffect-pragma>`_.
|
||||
## routines marked as `noSideEffect <manual.html#pragmas-nosideeffect-pragma>`_.
|
||||
|
||||
template newException*(exceptn: typedesc, message: string): expr =
|
||||
## creates an exception object of type ``exceptn`` and sets its ``msg`` field
|
||||
@@ -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.}
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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])
|
||||
|
||||
Reference in New Issue
Block a user