Merge branch 'devel' of github.com:Araq/Nimrod into seq_toString

This commit is contained in:
Simon Hafner 2014-03-31 15:49:04 -05:00
commit ffb36db5a6
215 changed files with 9066 additions and 4504 deletions

View file

@ -185,6 +185,8 @@ proc `..`*[T](b: T): TSlice[T] {.noSideEffect, inline.} =
when not defined(niminheritable):
{.pragma: inheritable.}
when not defined(nimunion):
{.pragma: unchecked.}
const NoFakeVars* = defined(NimrodVM) ## true if the backend doesn't support \
## "fake variables" like 'var EBADF {.importc.}: cint'.
@ -194,9 +196,10 @@ when not defined(JS):
TGenericSeq {.compilerproc, pure, inheritable.} = object
len, reserved: int
PGenericSeq {.exportc.} = ptr TGenericSeq
UncheckedCharArray {.unchecked.} = array[0..100_000_000, char]
# len and space without counting the terminating zero:
NimStringDesc {.compilerproc, final.} = object of TGenericSeq
data: array[0..100_000_000, char]
data: UncheckedCharArray
NimString = ptr NimStringDesc
when not defined(JS) and not defined(NimrodVM):
@ -257,6 +260,7 @@ type
## system raises.
EIO* = object of ESystem ## raised if an IO error occured.
EOS* = object of ESystem ## raised if an operating system service failed.
errorCode*: int32 ## OS-defined error code describing this error.
EInvalidLibrary* = object of EOS ## raised if a dynamic library
## could not be loaded.
EResourceExhausted* = object of ESystem ## raised if a resource request
@ -1161,6 +1165,14 @@ when not defined(nimrodVM):
## from it before writing to it is undefined behaviour!
## The allocated memory belongs to its allocating thread!
## Use `allocShared` to allocate from a shared heap.
proc createU*(T: typedesc, size = 1.Positive): ptr T {.inline.} =
## allocates a new memory block with at least ``T.sizeof * size``
## bytes. The block has to be freed with ``resize(block, 0)`` or
## ``free(block)``. The block is not initialized, so reading
## from it before writing to it is undefined behaviour!
## The allocated memory belongs to its allocating thread!
## Use `createSharedU` to allocate from a shared heap.
cast[ptr T](alloc(T.sizeof * size))
proc alloc0*(size: int): pointer {.noconv, rtl, tags: [].}
## allocates a new memory block with at least ``size`` bytes. The
## block has to be freed with ``realloc(block, 0)`` or
@ -1168,14 +1180,31 @@ when not defined(nimrodVM):
## containing zero, so it is somewhat safer than ``alloc``.
## The allocated memory belongs to its allocating thread!
## Use `allocShared0` to allocate from a shared heap.
proc realloc*(p: pointer, newsize: int): pointer {.noconv, rtl, tags: [].}
proc create*(T: typedesc, size = 1.Positive): ptr T {.inline.} =
## allocates a new memory block with at least ``T.sizeof * size``
## bytes. The block has to be freed with ``resize(block, 0)`` or
## ``free(block)``. The block is initialized with all bytes
## containing zero, so it is somewhat safer than ``createU``.
## The allocated memory belongs to its allocating thread!
## Use `createShared` to allocate from a shared heap.
cast[ptr T](alloc0(T.sizeof * size))
proc realloc*(p: pointer, newSize: int): pointer {.noconv, rtl, tags: [].}
## grows or shrinks a given memory block. If p is **nil** then a new
## memory block is returned. In either way the block has at least
## ``newsize`` bytes. If ``newsize == 0`` and p is not **nil**
## ``newSize`` bytes. If ``newSize == 0`` and p is not **nil**
## ``realloc`` calls ``dealloc(p)``. In other cases the block has to
## be freed with ``dealloc``.
## The allocated memory belongs to its allocating thread!
## Use `reallocShared` to reallocate from a shared heap.
proc resize*[T](p: ptr T, newSize: Natural): ptr T {.inline.} =
## grows or shrinks a given memory block. If p is **nil** then a new
## memory block is returned. In either way the block has at least
## ``T.sizeof * newSize`` bytes. If ``newSize == 0`` and p is not
## **nil** ``resize`` calls ``free(p)``. In other cases the block
## has to be freed with ``free``. The allocated memory belongs to
## its allocating thread!
## Use `resizeShared` to reallocate from a shared heap.
cast[ptr T](realloc(p, T.sizeof * newSize))
proc dealloc*(p: pointer) {.noconv, rtl, tags: [].}
## frees the memory allocated with ``alloc``, ``alloc0`` or
## ``realloc``. This procedure is dangerous! If one forgets to
@ -1184,31 +1213,60 @@ when not defined(nimrodVM):
## or other memory may be corrupted.
## The freed memory must belong to its allocating thread!
## Use `deallocShared` to deallocate from a shared heap.
proc free*[T](p: ptr T) {.inline.} =
dealloc(p)
proc allocShared*(size: int): pointer {.noconv, rtl.}
## allocates a new memory block on the shared heap with at
## least ``size`` bytes. The block has to be freed with
## ``reallocShared(block, 0)`` or ``deallocShared(block)``. The block
## is not initialized, so reading from it before writing to it is
## undefined behaviour!
proc createSharedU*(T: typedesc, size = 1.Positive): ptr T {.inline.} =
## allocates a new memory block on the shared heap with at
## least ``T.sizeof * size`` bytes. The block has to be freed with
## ``resizeShared(block, 0)`` or ``freeShared(block)``. The block
## is not initialized, so reading from it before writing to it is
## undefined behaviour!
cast[ptr T](allocShared(T.sizeof * size))
proc allocShared0*(size: int): pointer {.noconv, rtl.}
## allocates a new memory block on the shared heap with at
## least ``size`` bytes. The block has to be freed with
## ``reallocShared(block, 0)`` or ``deallocShared(block)``.
## The block is initialized with all bytes
## containing zero, so it is somewhat safer than ``allocShared``.
proc reallocShared*(p: pointer, newsize: int): pointer {.noconv, rtl.}
proc createShared*(T: typedesc, size = 1.Positive): ptr T {.inline.} =
## allocates a new memory block on the shared heap with at
## least ``T.sizeof * size`` bytes. The block has to be freed with
## ``resizeShared(block, 0)`` or ``freeShared(block)``.
## The block is initialized with all bytes
## containing zero, so it is somewhat safer than ``createSharedU``.
cast[ptr T](allocShared0(T.sizeof * size))
proc reallocShared*(p: pointer, newSize: int): pointer {.noconv, rtl.}
## grows or shrinks a given memory block on the heap. If p is **nil**
## then a new memory block is returned. In either way the block has at least
## ``newsize`` bytes. If ``newsize == 0`` and p is not **nil**
## then a new memory block is returned. In either way the block has at
## least ``newSize`` bytes. If ``newSize == 0`` and p is not **nil**
## ``reallocShared`` calls ``deallocShared(p)``. In other cases the
## block has to be freed with ``deallocShared``.
proc resizeShared*[T](p: ptr T, newSize: Natural): ptr T {.inline.} =
## grows or shrinks a given memory block on the heap. If p is **nil**
## then a new memory block is returned. In either way the block has at
## least ``T.sizeof * newSize`` bytes. If ``newSize == 0`` and p is
## not **nil** ``resizeShared`` calls ``freeShared(p)``. In other
## cases the block has to be freed with ``freeShared``.
cast[ptr T](reallocShared(p, T.sizeof * newSize))
proc deallocShared*(p: pointer) {.noconv, rtl.}
## frees the memory allocated with ``allocShared``, ``allocShared0`` or
## ``reallocShared``. This procedure is dangerous! If one forgets to
## free the memory a leak occurs; if one tries to access freed
## memory (or just freeing it twice!) a core dump may happen
## or other memory may be corrupted.
proc freeShared*[T](p: ptr T) {.inline.} =
## frees the memory allocated with ``createShared``, ``createSharedU`` or
## ``resizeShared``. This procedure is dangerous! If one forgets to
## free the memory a leak occurs; if one tries to access freed
## memory (or just freeing it twice!) a core dump may happen
## or other memory may be corrupted.
deallocShared(p)
proc swap*[T](a, b: var T) {.magic: "Swap", noSideEffect.}
## swaps the values `a` and `b`. This is often more efficient than
@ -1399,20 +1457,6 @@ iterator items*[IX, T](a: array[IX, T]): T {.inline.} =
if i >= high(IX): break
inc(i)
iterator items*[T](a: seq[T]): T {.inline.} =
## iterates over each item of `a`.
var i = 0
while i < len(a):
yield a[i]
inc(i)
iterator items*(a: string): char {.inline.} =
## iterates over each item of `a`.
var i = 0
while i < len(a):
yield a[i]
inc(i)
iterator items*[T](a: set[T]): T {.inline.} =
## iterates over each element of `a`. `items` iterates only over the
## elements that are really in the set (and not over the ones the set is
@ -1514,7 +1558,7 @@ when not defined(NimrodVM):
proc seqToPtr[T](x: seq[T]): pointer {.inline, nosideeffect.} =
result = cast[pointer](x)
else:
proc seqToPtr[T](x: seq[T]): pointer {.noStackFrame, nosideeffect.} =
proc seqToPtr[T](x: seq[T]): pointer {.asmNoStackFrame, nosideeffect.} =
asm """return `x`"""
proc `==` *[T](x, y: seq[T]): bool {.noSideEffect.} =
@ -1802,7 +1846,7 @@ type
len*: int ## length of the inspectable slots
when defined(JS):
proc add*(x: var string, y: cstring) {.noStackFrame.} =
proc add*(x: var string, y: cstring) {.asmNoStackFrame.} =
asm """
var len = `x`[0].length-1;
for (var i = 0; i < `y`.length; ++i) {
@ -2019,8 +2063,10 @@ when not defined(JS): #and not defined(NimrodVM):
## Flushes `f`'s buffer.
proc readAll*(file: TFile): TaintedString {.tags: [FReadIO].}
## Reads all data from the stream `file`. Raises an IO exception
## in case of an error
## Reads all data from the stream `file`.
##
## Raises an IO exception in case of an error. It is an error if the
## current file position is not at the beginning of the file.
proc readFile*(filename: string): TaintedString {.tags: [FReadIO].}
## Opens a file named `filename` for reading. Then calls `readAll`
@ -2309,12 +2355,32 @@ when not defined(JS): #and not defined(NimrodVM):
when not defined(NimrodVM):
proc likely*(val: bool): bool {.importc: "likely", nodecl, nosideeffect.}
## can be used to mark a condition to be likely. This is a hint for the
## optimizer.
## Hints the optimizer that `val` is likely going to be true.
##
## You can use this proc to decorate a branch condition. On certain
## platforms this can help the processor predict better which branch is
## going to be run. Example:
##
## .. code-block:: nimrod
## for value in inputValues:
## if likely(value <= 100):
## process(value)
## else:
## echo "Value too big!"
proc unlikely*(val: bool): bool {.importc: "unlikely", nodecl, nosideeffect.}
## can be used to mark a condition to be unlikely. This is a hint for the
## optimizer.
## Hints the optimizer that `val` is likely going to be false.
##
## You can use this proc to decorate a branch condition. On certain
## platforms this can help the processor predict better which branch is
## going to be run. Example:
##
## .. code-block:: nimrod
## for value in inputValues:
## if unlikely(value > 100):
## echo "Value too big!"
## else:
## process(value)
proc rawProc*[T: proc](x: T): pointer {.noSideEffect, inline.} =
## retrieves the raw proc pointer of the closure `x`. This is
@ -2612,6 +2678,24 @@ template doAssert*(cond: bool, msg = "") =
if not cond:
raiseAssert(astToStr(cond) & ' ' & msg)
iterator items*[T](a: seq[T]): T {.inline.} =
## iterates over each item of `a`.
var i = 0
let L = len(a)
while i < L:
yield a[i]
inc(i)
assert(len(a) == L, "seq modified while iterating over it")
iterator items*(a: string): char {.inline.} =
## iterates over each item of `a`.
var i = 0
let L = len(a)
while i < L:
yield a[i]
inc(i)
assert(len(a) == L, "string modified while iterating over it")
when not defined(nimhygiene):
{.pragma: inject.}