documented hygienic templates; made tests green; fixed system.clamp
This commit is contained in:
parent
a95e958046
commit
f893179889
11 changed files with 123 additions and 48 deletions
|
|
@ -11,6 +11,9 @@
|
|||
## to do so, the 'next' and 'prev' pointers are not hidden from you and can
|
||||
## be manipulated directly for efficiency.
|
||||
|
||||
when not defined(nimhygiene):
|
||||
{.pragma: dirty.}
|
||||
|
||||
type
|
||||
TDoublyLinkedNode* {.pure,
|
||||
final.}[T] = object ## a node a doubly linked list consists of
|
||||
|
|
@ -62,13 +65,13 @@ proc newSinglyLinkedNode*[T](value: T): PSinglyLinkedNode[T] =
|
|||
new(result)
|
||||
result.value = value
|
||||
|
||||
template itemsListImpl() =
|
||||
template itemsListImpl() {.dirty.} =
|
||||
var it = L.head
|
||||
while it != nil:
|
||||
yield it.value
|
||||
it = it.next
|
||||
|
||||
template itemsRingImpl() =
|
||||
template itemsRingImpl() {.dirty.} =
|
||||
var it = L.head
|
||||
if it != nil:
|
||||
while true:
|
||||
|
|
@ -76,14 +79,14 @@ template itemsRingImpl() =
|
|||
it = it.next
|
||||
if it == L.head: break
|
||||
|
||||
template nodesListImpl() =
|
||||
template nodesListImpl() {.dirty.} =
|
||||
var it = L.head
|
||||
while it != nil:
|
||||
var nxt = it.next
|
||||
yield it
|
||||
it = nxt
|
||||
|
||||
template nodesRingImpl() =
|
||||
template nodesRingImpl() {.dirty.} =
|
||||
var it = L.head
|
||||
if it != nil:
|
||||
while true:
|
||||
|
|
@ -92,7 +95,7 @@ template nodesRingImpl() =
|
|||
it = nxt
|
||||
if it == L.head: break
|
||||
|
||||
template findImpl() =
|
||||
template findImpl() {.dirty.} =
|
||||
for x in nodes(L):
|
||||
if x.value == value: return x
|
||||
|
||||
|
|
@ -132,7 +135,7 @@ iterator nodes*[T](L: TDoublyLinkedRing[T]): PDoublyLinkedNode[T] =
|
|||
## list during traversal is supported.
|
||||
nodesRingImpl()
|
||||
|
||||
template dollarImpl() =
|
||||
template dollarImpl() {.dirty.} =
|
||||
result = "["
|
||||
for x in nodes(L):
|
||||
if result.len > 1: result.add(", ")
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@
|
|||
## **Note**: This interface will change as soon as the compiler supports
|
||||
## closures and proper coroutines.
|
||||
|
||||
when not defined(nimhygiene):
|
||||
{.pragma: dirty.}
|
||||
|
||||
proc concat*[T](seqs: varargs[seq[T]]): seq[T] =
|
||||
## Takes several sequences' items and returns them inside of one sequence.
|
||||
var L = 0
|
||||
|
|
@ -50,7 +53,7 @@ proc filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): seq[T] =
|
|||
## Returns all items in a sequence that fulfilled the predicate.
|
||||
accumulateResult(filter(seq1, pred))
|
||||
|
||||
template filterIt*(seq1, pred: expr): expr {.immediate.} =
|
||||
template filterIt*(seq1, pred: expr): expr {.immediate, dirty.} =
|
||||
## Finds a specific item in a sequence as long as the
|
||||
## predicate returns true. The predicate needs to be an expression
|
||||
## containing ``it``: ``filterIt("abcxyz", it == 'x')``.
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ import
|
|||
os, hashes, math
|
||||
|
||||
{.pragma: myShallow.}
|
||||
when not defined(nimhygiene):
|
||||
{.pragma: dirty.}
|
||||
|
||||
type
|
||||
TSlotEnum = enum seEmpty, seFilled, seDeleted
|
||||
|
|
@ -48,7 +50,7 @@ proc mustRehash(length, counter: int): bool {.inline.} =
|
|||
proc nextTry(h, maxHash: THash): THash {.inline.} =
|
||||
result = ((5 * h) + 1) and maxHash
|
||||
|
||||
template rawGetImpl() =
|
||||
template rawGetImpl() {.dirty.} =
|
||||
var h: THash = hash(key) and high(s.data) # start with real hash value
|
||||
while s.data[h].slot != seEmpty:
|
||||
if s.data[h].key == key and s.data[h].slot == seFilled:
|
||||
|
|
@ -56,7 +58,7 @@ template rawGetImpl() =
|
|||
h = nextTry(h, high(s.data))
|
||||
result = -1
|
||||
|
||||
template rawInsertImpl() =
|
||||
template rawInsertImpl() {.dirty.} =
|
||||
var h: THash = hash(key) and high(data)
|
||||
while data[h].slot == seFilled:
|
||||
h = nextTry(h, high(data))
|
||||
|
|
@ -81,14 +83,14 @@ proc Enlarge[A](s: var TSet[A]) =
|
|||
if s.data[i].slot == seFilled: RawInsert(s, n, s.data[i].key)
|
||||
swap(s.data, n)
|
||||
|
||||
template inclImpl() =
|
||||
template inclImpl() {.dirty.} =
|
||||
var index = RawGet(s, key)
|
||||
if index < 0:
|
||||
if mustRehash(len(s.data), s.counter): Enlarge(s)
|
||||
RawInsert(s, s.data, key)
|
||||
inc(s.counter)
|
||||
|
||||
template containsOrInclImpl() =
|
||||
template containsOrInclImpl() {.dirty.} =
|
||||
var index = RawGet(s, key)
|
||||
if index >= 0:
|
||||
result = true
|
||||
|
|
@ -125,7 +127,7 @@ proc toSet*[A](keys: openarray[A]): TSet[A] =
|
|||
result = initSet[A](nextPowerOfTwo(keys.len+10))
|
||||
for key in items(keys): result.incl(key)
|
||||
|
||||
template dollarImpl(): stmt =
|
||||
template dollarImpl(): stmt {.dirty.} =
|
||||
result = "{"
|
||||
for key in items(s):
|
||||
if result.len > 1: result.add(", ")
|
||||
|
|
@ -155,7 +157,7 @@ proc card*[A](s: TOrderedSet[A]): int {.inline.} =
|
|||
## alias for `len`.
|
||||
result = s.counter
|
||||
|
||||
template forAllOrderedPairs(yieldStmt: stmt) =
|
||||
template forAllOrderedPairs(yieldStmt: stmt) {.dirty.} =
|
||||
var h = s.first
|
||||
while h >= 0:
|
||||
var nxt = s.data[h].next
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ type
|
|||
data: TKeyValuePairSeq[A, B]
|
||||
counter: int
|
||||
|
||||
when not defined(nimhygiene):
|
||||
{.pragma: dirty.}
|
||||
|
||||
proc len*[A, B](t: TTable[A, B]): int =
|
||||
## returns the number of keys in `t`.
|
||||
result = t.counter
|
||||
|
|
@ -66,7 +69,7 @@ proc mustRehash(length, counter: int): bool {.inline.} =
|
|||
proc nextTry(h, maxHash: THash): THash {.inline.} =
|
||||
result = ((5 * h) + 1) and maxHash
|
||||
|
||||
template rawGetImpl() =
|
||||
template rawGetImpl() {.dirty.} =
|
||||
var h: THash = hash(key) and high(t.data) # start with real hash value
|
||||
while t.data[h].slot != seEmpty:
|
||||
if t.data[h].key == key and t.data[h].slot == seFilled:
|
||||
|
|
@ -74,7 +77,7 @@ template rawGetImpl() =
|
|||
h = nextTry(h, high(t.data))
|
||||
result = -1
|
||||
|
||||
template rawInsertImpl() =
|
||||
template rawInsertImpl() {.dirty.} =
|
||||
var h: THash = hash(key) and high(data)
|
||||
while data[h].slot == seFilled:
|
||||
h = nextTry(h, high(data))
|
||||
|
|
@ -115,12 +118,12 @@ proc Enlarge[A, B](t: var TTable[A, B]) =
|
|||
if t.data[i].slot == seFilled: RawInsert(t, n, t.data[i].key, t.data[i].val)
|
||||
swap(t.data, n)
|
||||
|
||||
template AddImpl() =
|
||||
template AddImpl() {.dirty.} =
|
||||
if mustRehash(len(t.data), t.counter): Enlarge(t)
|
||||
RawInsert(t, t.data, key, val)
|
||||
inc(t.counter)
|
||||
|
||||
template PutImpl() =
|
||||
template PutImpl() {.dirty.} =
|
||||
var index = RawGet(t, key)
|
||||
if index >= 0:
|
||||
t.data[index].val = val
|
||||
|
|
@ -129,7 +132,7 @@ template PutImpl() =
|
|||
|
||||
when false:
|
||||
# not yet used:
|
||||
template HasKeyOrPutImpl() =
|
||||
template HasKeyOrPutImpl() {.dirty.} =
|
||||
var index = RawGet(t, key)
|
||||
if index >= 0:
|
||||
t.data[index].val = val
|
||||
|
|
@ -168,7 +171,7 @@ proc toTable*[A, B](pairs: openarray[tuple[key: A,
|
|||
result = initTable[A, B](nextPowerOfTwo(pairs.len+10))
|
||||
for key, val in items(pairs): result[key] = val
|
||||
|
||||
template dollarImpl(): stmt =
|
||||
template dollarImpl(): stmt {.dirty.} =
|
||||
if t.len == 0:
|
||||
result = "{:}"
|
||||
else:
|
||||
|
|
@ -199,7 +202,7 @@ proc len*[A, B](t: TOrderedTable[A, B]): int {.inline.} =
|
|||
## returns the number of keys in `t`.
|
||||
result = t.counter
|
||||
|
||||
template forAllOrderedPairs(yieldStmt: stmt) =
|
||||
template forAllOrderedPairs(yieldStmt: stmt) {.dirty.} =
|
||||
var h = t.first
|
||||
while h >= 0:
|
||||
var nxt = t.data[h].next
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue