Merge branch 'devel' into araq-better-codegen
This commit is contained in:
commit
2e93bac227
8 changed files with 133 additions and 8 deletions
|
|
@ -631,7 +631,7 @@ type
|
||||||
mPointer, mEmptySet, mIntSetBaseType, mNil, mExpr, mStmt, mTypeDesc,
|
mPointer, mEmptySet, mIntSetBaseType, mNil, mExpr, mStmt, mTypeDesc,
|
||||||
mVoidType, mPNimrodNode, mShared, mGuarded, mLock, mSpawn, mDeepCopy,
|
mVoidType, mPNimrodNode, mShared, mGuarded, mLock, mSpawn, mDeepCopy,
|
||||||
mIsMainModule, mCompileDate, mCompileTime, mProcCall,
|
mIsMainModule, mCompileDate, mCompileTime, mProcCall,
|
||||||
mCpuEndian, mHostOS, mHostCPU, mAppType,
|
mCpuEndian, mHostOS, mHostCPU, mBuildOS, mBuildCPU, mAppType,
|
||||||
mNaN, mInf, mNegInf,
|
mNaN, mInf, mNegInf,
|
||||||
mCompileOption, mCompileOptionArg,
|
mCompileOption, mCompileOptionArg,
|
||||||
mNLen, mNChild, mNSetChild, mNAdd, mNAddMultiple, mNDel, mNKind,
|
mNLen, mNChild, mNSetChild, mNAdd, mNAddMultiple, mNDel, mNKind,
|
||||||
|
|
|
||||||
|
|
@ -616,6 +616,8 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
|
||||||
of mCpuEndian: result = newIntNodeT(ord(CPU[targetCPU].endian), n)
|
of mCpuEndian: result = newIntNodeT(ord(CPU[targetCPU].endian), n)
|
||||||
of mHostOS: result = newStrNodeT(toLowerAscii(platform.OS[targetOS].name), n)
|
of mHostOS: result = newStrNodeT(toLowerAscii(platform.OS[targetOS].name), n)
|
||||||
of mHostCPU: result = newStrNodeT(platform.CPU[targetCPU].name.toLowerAscii, n)
|
of mHostCPU: result = newStrNodeT(platform.CPU[targetCPU].name.toLowerAscii, n)
|
||||||
|
of mBuildOS: result = newStrNodeT(toLowerAscii(platform.OS[platform.hostOS].name), n)
|
||||||
|
of mBuildCPU: result = newStrNodeT(platform.CPU[platform.hostCPU].name.toLowerAscii, n)
|
||||||
of mAppType: result = getAppType(n)
|
of mAppType: result = getAppType(n)
|
||||||
of mNaN: result = newFloatNodeT(NaN, n)
|
of mNaN: result = newFloatNodeT(NaN, n)
|
||||||
of mInf: result = newFloatNodeT(Inf, n)
|
of mInf: result = newFloatNodeT(Inf, n)
|
||||||
|
|
|
||||||
|
|
@ -633,6 +633,9 @@ the ``vtptr`` magic produced types bound to ``ptr`` types.
|
||||||
Symbol lookup in generics
|
Symbol lookup in generics
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
Open and Closed symbols
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The symbol binding rules in generics are slightly subtle: There are "open" and
|
The symbol binding rules in generics are slightly subtle: There are "open" and
|
||||||
"closed" symbols. A "closed" symbol cannot be re-bound in the instantiation
|
"closed" symbols. A "closed" symbol cannot be re-bound in the instantiation
|
||||||
context, an "open" symbol can. Per default overloaded symbols are open
|
context, an "open" symbol can. Per default overloaded symbols are open
|
||||||
|
|
@ -658,6 +661,9 @@ the ``Index`` type is defined *after* the ``==`` for tuples; yet the example
|
||||||
compiles as the instantiation takes the currently defined symbols into account
|
compiles as the instantiation takes the currently defined symbols into account
|
||||||
too.
|
too.
|
||||||
|
|
||||||
|
Mixin statement
|
||||||
|
---------------
|
||||||
|
|
||||||
A symbol can be forced to be open by a `mixin`:idx: declaration:
|
A symbol can be forced to be open by a `mixin`:idx: declaration:
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
|
|
|
||||||
|
|
@ -287,8 +287,6 @@ proc exclImpl[A](s: var HashSet[A], key: A) : bool {. inline .} =
|
||||||
|
|
||||||
if i >= 0:
|
if i >= 0:
|
||||||
result = false
|
result = false
|
||||||
s.data[i].hcode = 0
|
|
||||||
s.data[i].key = default(type(s.data[i].key))
|
|
||||||
dec(s.counter)
|
dec(s.counter)
|
||||||
while true: # KnuthV3 Algo6.4R adapted for i=i+1 instead of i=i-1
|
while true: # KnuthV3 Algo6.4R adapted for i=i+1 instead of i=i-1
|
||||||
var j = i # The correctness of this depends on (h+1) in nextTry,
|
var j = i # The correctness of this depends on (h+1) in nextTry,
|
||||||
|
|
@ -300,7 +298,7 @@ proc exclImpl[A](s: var HashSet[A], key: A) : bool {. inline .} =
|
||||||
if isEmpty(s.data[i].hcode): # end of collision cluster; So all done
|
if isEmpty(s.data[i].hcode): # end of collision cluster; So all done
|
||||||
return
|
return
|
||||||
r = s.data[i].hcode and msk # "home" location of key@i
|
r = s.data[i].hcode and msk # "home" location of key@i
|
||||||
shallowCopy(s.data[j], s.data[i]) # data[j] will be marked EMPTY next loop
|
shallowCopy(s.data[j], s.data[i]) # data[i] will be marked EMPTY next loop
|
||||||
|
|
||||||
proc missingOrExcl*[A](s: var HashSet[A], key: A): bool =
|
proc missingOrExcl*[A](s: var HashSet[A], key: A): bool =
|
||||||
## Excludes `key` in the set `s` and tells if `key` was removed from `s`.
|
## Excludes `key` in the set `s` and tells if `key` was removed from `s`.
|
||||||
|
|
@ -662,9 +660,12 @@ proc card*[A](s: OrderedSet[A]): int {.inline.} =
|
||||||
|
|
||||||
template forAllOrderedPairs(yieldStmt: untyped) {.dirty.} =
|
template forAllOrderedPairs(yieldStmt: untyped) {.dirty.} =
|
||||||
var h = s.first
|
var h = s.first
|
||||||
|
var idx = 0
|
||||||
while h >= 0:
|
while h >= 0:
|
||||||
var nxt = s.data[h].next
|
var nxt = s.data[h].next
|
||||||
if isFilled(s.data[h].hcode): yieldStmt
|
if isFilled(s.data[h].hcode):
|
||||||
|
yieldStmt
|
||||||
|
inc(idx)
|
||||||
h = nxt
|
h = nxt
|
||||||
|
|
||||||
iterator items*[A](s: OrderedSet[A]): A =
|
iterator items*[A](s: OrderedSet[A]): A =
|
||||||
|
|
@ -689,6 +690,11 @@ iterator items*[A](s: OrderedSet[A]): A =
|
||||||
forAllOrderedPairs:
|
forAllOrderedPairs:
|
||||||
yield s.data[h].key
|
yield s.data[h].key
|
||||||
|
|
||||||
|
iterator pairs*[A](s: OrderedSet[A]): tuple[a: int, b: A] =
|
||||||
|
assert s.isValid, "The set needs to be initialized"
|
||||||
|
forAllOrderedPairs:
|
||||||
|
yield (idx, s.data[h].key)
|
||||||
|
|
||||||
proc rawGetKnownHC[A](s: OrderedSet[A], key: A, hc: Hash): int {.inline.} =
|
proc rawGetKnownHC[A](s: OrderedSet[A], key: A, hc: Hash): int {.inline.} =
|
||||||
rawGetKnownHCImpl()
|
rawGetKnownHCImpl()
|
||||||
|
|
||||||
|
|
@ -760,6 +766,67 @@ proc incl*[A](s: var HashSet[A], other: OrderedSet[A]) =
|
||||||
assert other.isValid, "The set `other` needs to be initialized."
|
assert other.isValid, "The set `other` needs to be initialized."
|
||||||
for item in other: incl(s, item)
|
for item in other: incl(s, item)
|
||||||
|
|
||||||
|
proc exclImpl[A](s: var OrderedSet[A], key: A) : bool {. inline .} =
|
||||||
|
assert s.isValid, "The set needs to be initialized."
|
||||||
|
var hc: Hash
|
||||||
|
var i = rawGet(s, key, hc)
|
||||||
|
var msk = high(s.data)
|
||||||
|
result = true
|
||||||
|
|
||||||
|
if i >= 0:
|
||||||
|
result = false
|
||||||
|
# Fix ordering
|
||||||
|
if s.first == i:
|
||||||
|
s.first = s.data[i].next
|
||||||
|
else:
|
||||||
|
var itr = s.first
|
||||||
|
while true:
|
||||||
|
if (s.data[itr].next == i):
|
||||||
|
s.data[itr].next = s.data[i].next
|
||||||
|
if s.last == i:
|
||||||
|
s.last = itr
|
||||||
|
break
|
||||||
|
itr = s.data[itr].next
|
||||||
|
|
||||||
|
dec(s.counter)
|
||||||
|
while true: # KnuthV3 Algo6.4R adapted for i=i+1 instead of i=i-1
|
||||||
|
var j = i # The correctness of this depends on (h+1) in nextTry,
|
||||||
|
var r = j # though may be adaptable to other simple sequences.
|
||||||
|
s.data[i].hcode = 0 # mark current EMPTY
|
||||||
|
s.data[i].key = default(type(s.data[i].key))
|
||||||
|
s.data[i].next = 0
|
||||||
|
doWhile((i >= r and r > j) or (r > j and j > i) or (j > i and i >= r)):
|
||||||
|
i = (i + 1) and msk # increment mod table size
|
||||||
|
if isEmpty(s.data[i].hcode): # end of collision cluster; So all done
|
||||||
|
return
|
||||||
|
r = s.data[i].hcode and msk # "home" location of key@i
|
||||||
|
shallowCopy(s.data[j], s.data[i]) # data[i] will be marked EMPTY next loop
|
||||||
|
|
||||||
|
proc missingOrExcl*[A](s: var OrderedSet[A], key: A): bool =
|
||||||
|
## Excludes `key` in the set `s` and tells if `key` was removed from `s`. Efficiency: O(n).
|
||||||
|
##
|
||||||
|
## The difference with regards to the `excl() <#excl,TOrderedSet[A],A>`_ proc is
|
||||||
|
## that this proc returns `true` if `key` was not present in `s`. Example:
|
||||||
|
##
|
||||||
|
## .. code-block::
|
||||||
|
## var s = toOrderedSet([2, 3, 6, 7])
|
||||||
|
## assert s.missingOrExcl(4) == true
|
||||||
|
## assert s.missingOrExcl(6) == false
|
||||||
|
exclImpl(s, key)
|
||||||
|
|
||||||
|
|
||||||
|
proc excl*[A](s: var OrderedSet[A], key: A) =
|
||||||
|
## Excludes `key` from the set `s`. Efficiency: O(n).
|
||||||
|
##
|
||||||
|
## This doesn't do anything if `key` is not found in `s`. Example:
|
||||||
|
##
|
||||||
|
## .. code-block::
|
||||||
|
## var s = toOrderedSet([2, 3, 6, 7])
|
||||||
|
## s.excl(2)
|
||||||
|
## s.excl(2)
|
||||||
|
## assert s.len == 3
|
||||||
|
discard exclImpl(s, key)
|
||||||
|
|
||||||
proc containsOrIncl*[A](s: var OrderedSet[A], key: A): bool =
|
proc containsOrIncl*[A](s: var OrderedSet[A], key: A): bool =
|
||||||
## Includes `key` in the set `s` and tells if `key` was added to `s`.
|
## Includes `key` in the set `s` and tells if `key` was added to `s`.
|
||||||
##
|
##
|
||||||
|
|
@ -986,6 +1053,24 @@ when isMainModule and not defined(release):
|
||||||
assert a.len == b.card
|
assert a.len == b.card
|
||||||
assert a.len == 2
|
assert a.len == 2
|
||||||
|
|
||||||
|
block setPairsIterator:
|
||||||
|
var s = toOrderedSet([1, 3, 5, 7])
|
||||||
|
var items = newSeq[tuple[a: int, b: int]]()
|
||||||
|
for idx, item in s: items.add((idx, item))
|
||||||
|
assert items == @[(0, 1), (1, 3), (2, 5), (3, 7)]
|
||||||
|
|
||||||
|
block exclusions:
|
||||||
|
var s = toOrderedSet([1, 2, 3, 6, 7, 4])
|
||||||
|
|
||||||
|
s.excl(3)
|
||||||
|
s.excl(3)
|
||||||
|
s.excl(1)
|
||||||
|
s.excl(4)
|
||||||
|
|
||||||
|
var items = newSeq[int]()
|
||||||
|
for item in s: items.add item
|
||||||
|
assert items == @[2, 6, 7]
|
||||||
|
|
||||||
#block orderedSetIterator:
|
#block orderedSetIterator:
|
||||||
# var a = initOrderedSet[int]()
|
# var a = initOrderedSet[int]()
|
||||||
# for value in [9, 2, 1, 5, 1, 8, 4, 2]:
|
# for value in [9, 2, 1, 5, 1, 8, 4, 2]:
|
||||||
|
|
@ -1030,6 +1115,11 @@ when isMainModule and not defined(release):
|
||||||
if s <= i or mustRehash(s, i):
|
if s <= i or mustRehash(s, i):
|
||||||
echo "performance issue: rightSize() will not elide enlarge() at ", i
|
echo "performance issue: rightSize() will not elide enlarge() at ", i
|
||||||
|
|
||||||
|
block missingOrExcl:
|
||||||
|
var s = toOrderedSet([2, 3, 6, 7])
|
||||||
|
assert s.missingOrExcl(4) == true
|
||||||
|
assert s.missingOrExcl(6) == false
|
||||||
|
|
||||||
when not defined(testing):
|
when not defined(testing):
|
||||||
echo "Micro tests run successfully."
|
echo "Micro tests run successfully."
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -498,7 +498,7 @@ proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
|
||||||
# Cannot use INET6_ADDRSTRLEN here, because it's a C define.
|
# Cannot use INET6_ADDRSTRLEN here, because it's a C define.
|
||||||
var buf: array[64, char]
|
var buf: array[64, char]
|
||||||
if inet_ntop(name.sin6_family.cint,
|
if inet_ntop(name.sin6_family.cint,
|
||||||
addr name, buf.cstring, sizeof(buf).int32).isNil:
|
addr name.sin6_addr, buf.cstring, sizeof(buf).int32).isNil:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
result = ($buf, Port(nativesockets.ntohs(name.sin6_port)))
|
result = ($buf, Port(nativesockets.ntohs(name.sin6_port)))
|
||||||
else:
|
else:
|
||||||
|
|
@ -534,7 +534,7 @@ proc getPeerAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
|
||||||
# Cannot use INET6_ADDRSTRLEN here, because it's a C define.
|
# Cannot use INET6_ADDRSTRLEN here, because it's a C define.
|
||||||
var buf: array[64, char]
|
var buf: array[64, char]
|
||||||
if inet_ntop(name.sin6_family.cint,
|
if inet_ntop(name.sin6_family.cint,
|
||||||
addr name, buf.cstring, sizeof(buf).int32).isNil:
|
addr name.sin6_addr, buf.cstring, sizeof(buf).int32).isNil:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
result = ($buf, Port(nativesockets.ntohs(name.sin6_port)))
|
result = ($buf, Port(nativesockets.ntohs(name.sin6_port)))
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -717,7 +717,7 @@ proc len*[TOpenArray: openArray|varargs](x: TOpenArray): int {.
|
||||||
magic: "LengthOpenArray", noSideEffect.}
|
magic: "LengthOpenArray", noSideEffect.}
|
||||||
proc len*(x: string): int {.magic: "LengthStr", noSideEffect.}
|
proc len*(x: string): int {.magic: "LengthStr", noSideEffect.}
|
||||||
proc len*(x: cstring): int {.magic: "LengthStr", noSideEffect.}
|
proc len*(x: cstring): int {.magic: "LengthStr", noSideEffect.}
|
||||||
proc len*[I, T](x: array[I, T]): int {.magic: "LengthArray", noSideEffect.}
|
proc len*(x: (type array)|array): int {.magic: "LengthArray", noSideEffect.}
|
||||||
proc len*[T](x: seq[T]): int {.magic: "LengthSeq", noSideEffect.}
|
proc len*[T](x: seq[T]): int {.magic: "LengthSeq", noSideEffect.}
|
||||||
## returns the length of an array, an openarray, a sequence or a string.
|
## returns the length of an array, an openarray, a sequence or a string.
|
||||||
## This is roughly the same as ``high(T)-low(T)+1``, but its resulting type is
|
## This is roughly the same as ``high(T)-low(T)+1``, but its resulting type is
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,15 @@
|
||||||
# Nim's configuration system now uses Nim for scripting. This module provides
|
# Nim's configuration system now uses Nim for scripting. This module provides
|
||||||
# a few things that are required for this to work.
|
# a few things that are required for this to work.
|
||||||
|
|
||||||
|
const
|
||||||
|
buildOS* {.magic: "BuildOS".}: string = ""
|
||||||
|
## The OS this build is running on. Can be different from ``system.hostOS``
|
||||||
|
## for cross compilations.
|
||||||
|
|
||||||
|
buildCPU* {.magic: "BuildCPU".}: string = ""
|
||||||
|
## The CPU this build is running on. Can be different from ``system.hostCPU``
|
||||||
|
## for cross compilations.
|
||||||
|
|
||||||
template builtin = discard
|
template builtin = discard
|
||||||
|
|
||||||
# We know the effects better than the compiler:
|
# We know the effects better than the compiler:
|
||||||
|
|
|
||||||
18
tests/array/tarraylen.nim
Normal file
18
tests/array/tarraylen.nim
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
discard """
|
||||||
|
output: ""
|
||||||
|
"""
|
||||||
|
var a: array[0, int]
|
||||||
|
doAssert a.len == 0
|
||||||
|
doAssert array[0..0, int].len == 1
|
||||||
|
doAssert array[0..0, int]([1]).len == 1
|
||||||
|
doAssert array[1..1, int].len == 1
|
||||||
|
doAssert array[1..1, int]([1]).len == 1
|
||||||
|
doAssert array[2, int].len == 2
|
||||||
|
doAssert array[2, int]([1, 2]).len == 2
|
||||||
|
doAssert array[1..3, int].len == 3
|
||||||
|
doAssert array[1..3, int]([1, 2, 3]).len == 3
|
||||||
|
doAssert array[0..2, int].len == 3
|
||||||
|
doAssert array[0..2, int]([1, 2, 3]).len == 3
|
||||||
|
doAssert array[-2 .. -2, int].len == 1
|
||||||
|
doAssert([1, 2, 3].len == 3)
|
||||||
|
doAssert([42].len == 1)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue