Merge remote-tracking branch 'upstream/devel' into devel

This commit is contained in:
Oscar Campbell
2015-05-25 19:51:58 +02:00
8 changed files with 130 additions and 16 deletions

View File

@@ -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) =

View File

@@ -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

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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.}

View File

@@ -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])

View File

@@ -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])