new tester; all tests categorized

This commit is contained in:
Araq 2014-01-13 02:10:03 +01:00
commit 20b5f31c03
481 changed files with 794 additions and 2506 deletions

View file

@ -0,0 +1,31 @@
discard """
file: "tbintre2.nim"
output: "helloworld99110223"
"""
# Same test, but check module boundaries
import tbintree
var
root: PBinaryTree[string]
x = newNode("hello")
add(root, x)
add(root, "world")
if find(root, "world"):
for str in items(root):
stdout.write(str)
else:
stdout.writeln("BUG")
var
r2: PBinaryTree[int]
add(r2, newNode(110))
add(r2, 223)
add(r2, 99)
for y in items(r2):
stdout.write(y)
#OUT helloworld99110223

107
tests/generics/tbintree.nim Normal file
View file

@ -0,0 +1,107 @@
discard """
file: "tbintree.nim"
output: "helloworld99110223"
"""
type
TBinaryTree[T] = object # TBinaryTree is a generic type with
# with generic param ``T``
le, ri: ref TBinaryTree[T] # left and right subtrees; may be nil
data: T # the data stored in a node
PBinaryTree*[A] = ref TBinaryTree[A] # type that is exported
proc newNode*[T](data: T): PBinaryTree[T] =
# constructor for a node
new(result)
result.data = data
proc add*[Ty](root: var PBinaryTree[Ty], n: PBinaryTree[Ty]) =
# insert a node into the tree
if root == nil:
root = n
else:
var it = root
while it != nil:
# compare the data items; uses the generic ``cmp`` proc that works for
# any type that has a ``==`` and ``<`` operator
var c = cmp(n.data, it.data)
if c < 0:
if it.le == nil:
it.le = n
return
it = it.le
else:
if it.ri == nil:
it.ri = n
return
it = it.ri
proc add*[Ty](root: var PBinaryTree[Ty], data: Ty) =
# convenience proc:
add(root, newNode(data))
proc find*[Ty2](b: PBinaryTree[Ty2], data: Ty2): bool =
# for testing this needs to be recursive, so that the
# instantiated type is checked for proper tyGenericInst envelopes
if b == nil:
result = false
else:
var c = cmp(data, b.data)
if c < 0: result = find(b.le, data)
elif c > 0: result = find(b.ri, data)
else: result = true
iterator preorder*[T](root: PBinaryTree[T]): T =
# Preorder traversal of a binary tree.
# Since recursive iterators are not yet implemented,
# this uses an explicit stack:
var stack: seq[PBinaryTree[T]] = @[root]
while stack.len > 0:
var n = stack.pop()
while n != nil:
yield n.data
add(stack, n.ri) # push right subtree onto the stack
n = n.le # and follow the left pointer
iterator items*[T](root: PBinaryTree[T]): T =
## Inorder traversal of the binary tree.
var stack: seq[PBinaryTree[T]] = @[]
var n = root
while true:
while n != nil:
add(stack, n)
n = n.le
if stack.len > 0:
n = stack.pop()
yield n.data
n = n.ri
if stack.len == 0 and n == nil: break
proc debug[T](a: PBinaryTree[T]) =
if a != nil:
debug(a.le)
echo a.data
debug(a.ri)
when isMainModule:
var
root: PBinaryTree[string]
x = newNode("hello")
add(root, x)
add(root, "world")
if find(root, "world"):
for str in items(root):
stdout.write(str)
else:
stdout.writeln("BUG")
var
r2: PBinaryTree[int]
add(r2, newNode(110))
add(r2, 223)
add(r2, 99)
for y in items(r2):
stdout.write(y)
#OUT helloworld99110223

View file

@ -0,0 +1,11 @@
##
## can_alias_generic Nimrod Module
##
## Created by Eric Doughty-Papassideris on 2011-02-16.
## Copyright (c) 2011 FWA. All rights reserved.
type
TGen[T] = object
TGen2[T] = TGen[T]

View file

@ -0,0 +1,17 @@
discard """
disabled: false
"""
##
## can_alias_specialised_generic Nimrod Module
##
## Created by Eric Doughty-Papassideris on 2011-02-16.
## Copyright (c) 2011 FWA. All rights reserved.
type
TGen[T] = object
TSpef = TGen[string]
var
s: TSpef

View file

@ -0,0 +1,17 @@
##
## can_inherit_generic Nimrod Module
##
## Created by Eric Doughty-Papassideris on 2011-02-16.
## Copyright (c) 2011 FWA. All rights reserved.
type
TGen[T] = object of TObject
x, y: T
TSpef[T] = object of TGen[T]
var s: TSpef[float]
s.x = 0.4
s.y = 0.6

View file

@ -0,0 +1,11 @@
##
## can_specialise_generic Nimrod Module
##
## Created by Eric Doughty-Papassideris on 2011-02-16.
## Copyright (c) 2011 FWA. All rights reserved.
type
TGen[T] = object {.inheritable.}
TSpef = object of TGen[string]

View file

@ -0,0 +1,38 @@
discard """
file: "texplicitgeneric1.nim"
output: "Key: 12 value: 12Key: 13 value: 13 Key: A value: 12 Key: B value: 13"
"""
# test explicit type instantiation
type
TDict*[TKey, TValue] = object
data: seq[tuple[k: TKey, v: TValue]]
PDict*[TKey, #with `==`(a, b: TKey): bool
# hash(a: TKey): int,
TValue] = ref TDict[TKey, TValue]
proc newDict*[TKey, TValue](): PDict[TKey, TValue] =
new(result)
result.data = @[]
proc add*[TKey, TValue](d: PDict[TKey, TValue], k: TKey, v: TValue) =
d.data.add((k, v))
iterator items*[Tkey, tValue](d: PDict[TKey, TValue]): tuple[k: TKey,
v: TValue] =
for k, v in items(d.data): yield (k, v)
var d = newDict[int, string]()
d.add(12, "12")
d.add(13, "13")
for k, v in items(d):
stdout.write("Key: ", $k, " value: ", v)
var c = newDict[char, string]()
c.add('A', "12")
c.add('B', "13")
for k, v in items(c):
stdout.write(" Key: ", $k, " value: ", v)

View file

@ -0,0 +1,35 @@
discard """
output: "Key: 12 value: 12Key: 13 value: 13 Key: A value: 12 Key: B value: 13"
disabled: true
"""
# test explicit type instantiation
type
TDict*[TKey, TValue] = object
data: seq[tuple[k: TKey, v: TValue]]
PDict*[TKey, TValue] = ref TDict[TKey, TValue]
proc newDict*[TKey, TValue](): PDict[TKey, TValue] =
new(result)
result.data = @[]
proc add*(d: PDict, k: TKey, v: TValue) =
d.data.add((k, v))
#iterator items*(d: PDict): tuple[k: TKey, v: TValue] =
# for k, v in items(d.data): yield (k, v)
var d = newDict[int, string]()
d.add(12, "12")
d.add(13, "13")
for k, v in items(d):
stdout.write("Key: ", $k, " value: ", v)
var c = newDict[char, string]()
c.add('A', "12")
c.add('B', "13")
for k, v in items(c):
stdout.write(" Key: ", $k, " value: ", v)

View file

@ -0,0 +1,13 @@
discard """
output: "1.1000000000000001e+00 11"
ccodecheck: "!@'ClEnv'"
"""
proc p[T](a, b: T): T
echo p(0.9, 0.1), " ", p(9, 1)
proc p[T](a, b: T): T =
let c = b
result = a + b + c

View file

@ -0,0 +1,19 @@
import tables
type
TX = TTable[string, int]
proc foo(models: seq[TTable[string, float]]): seq[float] =
result = @[]
for model in models.items:
result.add model["foobar"]
# bug #686
type TType[T; A] = array[A, T]
proc foo[T](p: TType[T, range[0..1]]) =
echo "foo"
proc foo[T](p: TType[T, range[0..2]]) =
echo "bar"

View file

@ -0,0 +1,53 @@
discard """
output: "100 0"
"""
# A min-heap.
type
TNode[T] = tuple[priority: int, data: T]
TBinHeap[T] = object
heap: seq[TNode[T]]
last: int
PBinHeap[T] = ref TBinHeap[T]
proc newBinHeap*[T](heap: var PBinHeap[T], size: int) =
new(heap)
heap.last = 0
newSeq(heap.heap, size)
#newSeq(heap.seq, size)
proc parent(elem: int): int {.inline.} =
return (elem-1) div 2
proc siftUp[T](heap: PBinHeap[T], elem: int) =
var idx = elem
while idx != 0:
var p = parent(idx)
if heap.heap[idx].priority < heap.heap[p].priority:
swap(heap.heap[idx], heap.heap[p])
idx = p
else:
break
proc add*[T](heap: PBinHeap[T], priority: int, data: T) =
var node: TNode[T]
node.priority = priority
node.data = data
heap.heap[heap.last] = node
siftUp(heap, heap.last)
inc(heap.last)
proc print*[T](heap: PBinHeap[T]) =
for i in countup(0, heap.last):
stdout.write($heap.heap[i].data, " ")
var
heap: PBinHeap[int]
newBinHeap(heap, 256)
add(heap, 1, 100)
print(heap)

View file

@ -0,0 +1,15 @@
import tables
type
TX = TTable[string, int]
proc foo(models: seq[TX]): seq[int] =
result = @[]
for model in models.items:
result.add model["foobar"]
type
obj = object
field: TTable[string, string]
var t: Obj
discard initTable[type(t.field), string]()

View file

@ -0,0 +1,474 @@
import strutils
type
PNode[T,D] = ref TNode[T,D]
TItem {.acyclic, pure, final, shallow.} [T,D] = object
key: T
value: D
node: PNode[T,D]
when not (D is string):
val_set: Bool
TItems[T,D] = seq[ref TItem[T,D]]
TNode {.acyclic, pure, final, shallow.} [T,D] = object
slots: TItems[T,D]
left: PNode[T,D]
count: Int32
RPath[T,D] = tuple[
Xi: Int,
Nd: PNode[T,D] ]
const
cLen1 = 2
cLen2 = 16
cLen3 = 32
cLenCenter = 80
clen4 = 96
cLenMax = 128
cCenter = cLenMax div 2
proc len[T,D] (n:PNode[T,D]): Int {.inline.} =
return n.Count
proc clean[T: TOrdinal|TNumber](o: var T) {.inline.} = nil
proc clean[T: string|seq](o: var T) {.inline.} =
o = nil
proc clean[T,D] (o: ref TItem[T,D]) {.inline.} =
when (D is string) :
o.Value = nil
else :
o.val_set = false
proc isClean[T,D] (it: ref TItem[T,D]): Bool {.inline.} =
when (D is string) :
return it.Value == nil
else :
return not it.val_set
proc isClean[T,D] (n: PNode[T,D], x: Int): Bool {.inline.} =
when (D is string) :
return n.slots[x].Value == nil
else :
return not n.slots[x].val_set
proc setItem[T,D] (AKey: T, AValue: D, ANode: PNode[T,D]): ref TItem[T,D] {.inline.} =
new(Result)
Result.Key = AKey
Result.Value = AValue
Result.Node = ANode
when not (D is string) :
Result.val_set = true
proc cmp[T:Int8|Int16|Int32|Int64|Int] (a,b: T): T {.inline.} =
return a-b
template binSearchImpl *(docmp: expr) {.immediate.} =
var bFound = false
result = 0
var H = haystack.len -1
while result <= H :
var I {.inject.} = (result + H) shr 1
var SW = docmp
if SW < 0: result = I + 1
else:
H = I - 1
if SW == 0 : bFound = True
if bFound: inc(result)
else: result = - result
proc bSearch[T,D] (haystack: PNode[T,D], needle:T): Int {.inline.} =
binSearchImpl(haystack.slots[I].key.cmp(needle))
proc DeleteItem[T,D] (n: PNode[T,D], x: Int): PNode[T,D] {.inline.} =
var w = n.slots[x]
if w.Node != nil :
clean(w)
return n
dec(n.Count)
if n.Count > 0 :
for i in countup(x, n.Count -1) : n.slots[i] = n.slots[i + 1]
n.slots[n.Count] = nil
case n.Count
of cLen1 : setLen(n.slots, cLen1)
of cLen2 : setLen(n.slots, cLen2)
of cLen3 : setLen(n.slots, cLen3)
of cLenCenter : setLen(n.slots, cLenCenter)
of cLen4 : setLen(n.slots, cLen4)
else: nil
Result = n
else :
Result = n.Left
n.slots = nil
n.Left = nil
proc InternalDelete[T,D] (ANode: PNode[T,D], key: T, AValue: var D): PNode[T,D] =
var Path: array[0..20, RPath[T,D]]
var n = ANode
Result = n
clean(AValue)
var h = 0
while n != nil:
var x = bSearch(n, key)
if x <= 0 :
Path[h].Nd = n
Path[h].Xi = - x
inc(h)
if x == 0 :
n = n.Left
else :
x = (-x) -1
if x < n.Count :
n = n.slots[x].Node
else :
n = nil
else :
dec(x)
if isClean(n, x) : return
AValue = n.slots[x].Value
var n2 = DeleteItem(n, x)
dec(h)
while (n2 != n) and (h >=0) :
n = n2
var w = addr Path[h]
x = w.Xi -1
if x >= 0 :
if (n == nil) and isClean(w.Nd, x) :
n = w.Nd
n.slots[x].Node = nil
n2 = DeleteItem(n, x)
else :
w.Nd.slots[x].Node = n
return
else :
w.Nd.Left = n
return
dec(h)
if h < 0:
Result = n2
return
proc InternalFind[T,D] (n: PNode[T,D], key: T): ref TItem[T,D] {.inline.} =
var wn = n
while wn != nil :
var x = bSearch(wn, key)
if x <= 0 :
if x == 0 :
wn = wn.Left
else :
x = (-x) -1
if x < wn.Count :
wn = wn.slots[x].Node
else :
return nil
else :
return wn.slots[x - 1]
return nil
proc traceTree[T,D](root: PNode[T,D]) =
proc traceX(x: Int) =
write stdout, "("
write stdout, x
write stdout, ") "
proc traceEl(el: ref TItem[T,D]) =
write stdout, " key: "
write stdout, el.Key
write stdout, " value: "
write stdout, el.Value
proc traceln(space: string) =
writeln stdout, ""
write stdout, space
proc doTrace(n: PNode[T,D], level: Int) =
var space = repeatChar(2 * level)
traceln(space)
write stdout, "node: "
if n == nil:
writeln stdout, "is empty"
return
write stdout, n.Count
write stdout, " elements: "
if n.Left != nil:
traceln(space)
write stdout, "left: "
doTrace(n.left, level +1)
for i, el in n.slots :
if el != nil and not isClean(el):
traceln(space)
traceX(i)
if i >= n.Count:
write stdout, "error "
else:
traceEl(el)
if el.Node != nil: doTrace(el.Node, level +1)
else : write stdout, " empty "
elif i < n.Count :
traceln(space)
traceX(i)
write stdout, "clean: "
when T is string :
if el.Key != nil: write stdout, el.Key
else : write stdout, el.Key
if el.Node != nil: doTrace(el.Node, level +1)
else : write stdout, " empty "
writeln stdout,""
doTrace(root, 0)
proc InsertItem[T,D](APath: RPath[T,D], ANode:PNode[T,D], AKey: T, AValue: D) =
var x = - APath.Xi
inc(APath.Nd.Count)
case APath.Nd.Count
of cLen1: setLen(APath.Nd.slots, cLen2)
of cLen2: setLen(APath.Nd.slots, cLen3)
of cLen3: setLen(APath.Nd.slots, cLenCenter)
of cLenCenter: setLen(APath.Nd.slots, cLen4)
of cLen4: setLen(APath.Nd.slots, cLenMax)
else: nil
for i in countdown(APath.Nd.Count.int - 1, x + 1): shallowCopy(APath.Nd.slots[i], APath.Nd.slots[i - 1])
APath.Nd.slots[x] = setItem(AKey, AValue, ANode)
proc SplitPage[T,D](n, left: PNode[T,D], xi: Int, AKey:var T, AValue:var D): PNode[T,D] =
var x = -Xi
var it1: TItems[T,D]
it1.newSeq(cLenCenter)
new(Result)
Result.slots.newSeq(cLenCenter)
Result.Count = cCenter
if x == cCenter:
for i in 0..cCenter -1: shallowCopy(it1[i], left.slots[i])
for i in 0..cCenter -1: shallowCopy(Result.slots[i], left.slots[cCenter + i])
Result.Left = n
else :
if x < cCenter :
for i in 0..x-1: shallowCopy(it1[i], left.slots[i])
it1[x] = setItem(AKey, AValue, n)
for i in x+1 .. cCenter -1: shallowCopy(it1[i], left.slots[i-1])
var w = left.slots[cCenter -1]
AKey = w.Key
AValue = w.Value
Result.Left = w.Node
for i in 0..cCenter -1: shallowCopy(Result.slots[i], left.slots[cCenter + i])
else :
for i in 0..cCenter -1: shallowCopy(it1[i], left.slots[i])
x = x - (cCenter + 1)
for i in 0..x-1: shallowCopy(Result.slots[i], left.slots[cCenter + i + 1])
Result.slots[x] = setItem(AKey, AValue, n)
for i in x+1 .. cCenter -1: shallowCopy(Result.slots[i], left.slots[cCenter + i])
var w = left.slots[cCenter]
AKey = w.Key
AValue = w.Value
Result.Left = w.Node
left.Count = cCenter
shallowCopy(left.slots, it1)
proc InternalPut[T,D](ANode: ref TNode[T,D], AKey: T, AValue: D, OldValue: var D): ref TNode[T,D] =
var h: Int
var Path: array[0..30, RPath[T,D]]
var left: PNode[T,D]
var n = ANode
Result = ANode
h = 0
while n != nil:
var x = bSearch[T,D](n, AKey)
if x <= 0 :
Path[h].Nd = n
Path[h].Xi = x
inc(h)
if x == 0 :
n = n.Left
else :
x = (-x) -1
if x < n.Count :
n = n.slots[x].Node
else :
n = nil
else :
var w = n.slots[x - 1]
OldValue = w.Value
w.Value = AValue
return
dec(h)
left = nil
var lKey = AKey
var lValue = AValue
while h >= 0 :
if Path[h].Nd.Count < cLenMax :
InsertItem(Path[h], n, lKey, lValue)
return
else :
left = Path[h].Nd
n = SplitPage(n, left, Path[h].Xi, lKey, lValue)
dec(h)
new(Result)
Result.slots.newSeq(cLen1)
Result.Count = 1
Result.Left = left
Result.slots[0] = setItem(lKey, lValue, n)
proc CleanTree[T,D](n: PNode[T,D]): PNode[T,D] =
if n.Left != nil :
n.Left = CleanTree(n.Left)
for i in 0 .. n.Count - 1 :
var w = n.slots[i]
if w.Node != nil :
w.Node = CleanTree(w.Node)
clean(w.Value)
clean(w.Key)
n.slots = nil
return nil
proc VisitAllNodes[T,D](n: PNode[T,D], visit: proc(n: PNode[T,D]): PNode[T,D] {.closure.} ): PNode[T,D] =
if n != nil :
if n.Left != nil :
n.Left = VisitAllNodes(n.Left, visit)
for i in 0 .. n.Count - 1 :
var w = n.slots[i]
if w.Node != nil :
w.Node = VisitAllNodes(w.Node, visit)
return visit(n)
return nil
proc VisitAllNodes[T,D](n: PNode[T,D], visit: proc(n: PNode[T,D]) {.closure.} ) =
if n != nil:
if n.Left != nil :
VisitAllNodes(n.Left, visit)
for i in 0 .. n.Count - 1 :
var w = n.slots[i]
if w.Node != nil :
VisitAllNodes(w.Node, visit)
visit(n)
proc VisitAll[T,D](n: PNode[T,D], visit: proc(AKey: T, AValue: D) {.closure.} ) =
if n != nil:
if n.Left != nil :
VisitAll(n.Left, visit)
for i in 0 .. n.Count - 1 :
var w = n.slots[i]
if not w.isClean :
visit(w.Key, w.Value)
if w.Node != nil :
VisitAll(w.Node, visit)
proc VisitAll[T,D](n: PNode[T,D], visit: proc(AKey: T, AValue: var D):Bool {.closure.} ): PNode[T,D] =
if n != nil:
var n1 = n.Left
if n1 != nil :
var n2 = VisitAll(n1, visit)
if n1 != n2 :
n.Left = n2
var i = 0
while i < n.Count :
var w = n.slots[i]
if not w.isClean :
if visit(w.Key, w.Value) :
Result = DeleteItem(n, i)
if Result == nil : return
dec(i)
n1 = w.Node
if n1 != nil :
var n2 = VisitAll(n1, visit)
if n1 != n2 :
w.Node = n2
inc(i)
return n
iterator keys* [T,D] (n: PNode[T,D]): T =
if n != nil :
var Path: array[0..20, RPath[T,D]]
var level = 0
var nd = n
var i = -1
while true :
if i < nd.Count :
Path[level].Nd = nd
Path[level].Xi = i
if i < 0 :
if nd.Left != nil :
nd = nd.Left
inc(level)
else : inc(i)
else :
var w = nd.slots[i]
if not w.isClean() :
yield w.Key
if w.Node != nil :
nd = w.Node
i = -1
inc(level)
else : inc(i)
else :
dec(level)
if level < 0 : break
nd = Path[level].Nd
i = Path[level].Xi
inc(i)
when isMainModule:
proc test() =
var oldValue: Int
var root = InternalPut[int, int](nil, 312, 312, oldValue)
var someOtherRoot = InternalPut[string, int](nil, "312", 312, oldValue)
var it1 = InternalFind(root, 312)
echo it1.Value
for i in 1..1_000_000:
root = InternalPut(root, i, i, oldValue)
var cnt = 0
oldValue = -1
when true : # code compiles, when this or the other when is switched to false
for k in root.keys :
if k <= oldValue :
echo k
oldValue = k
inc(cnt)
echo cnt
when true :
cnt = 0
VisitAll(root, proc(key, val: int) = inc(cnt))
echo cnt
when true :
root = VisitAll(root, proc(key: int, value: var int): bool =
return key mod 2 == 0 )
cnt = 0
oldValue = -1
VisitAll(root, proc(key: int, value: int) {.closure.} =
if key <= oldValue :
echo key
oldValue = key
inc(cnt) )
echo cnt
root = VisitAll(root, proc(key: int, value: var int): bool =
return key mod 2 != 0 )
cnt = 0
oldValue = -1
VisitAll(root, proc(key: int, value: int) {.closure.} =
if key <= oldValue :
echo "error ", key
oldValue = key
inc(cnt) )
echo cnt
#traceTree(root)
test()

View file

@ -0,0 +1,10 @@
type
TIDGen*[A: Ordinal] = object
next: A
free: seq[A]
proc newIDGen*[A]: TIDGen[A] =
newSeq result.free, 0
var x = newIDGen[int]()

View file

@ -0,0 +1,29 @@
type
TFoo[T, U, R = int] = object
x: T
y: U
z: R
TBar[T] = TFoo[T, array[4, T], T]
var x1: TFoo[int, float]
static:
assert type(x1.x) is int
assert type(x1.y) is float
assert type(x1.z) is int
var x2: TFoo[string, R = float, U = seq[int]]
static:
assert type(x2.x) is string
assert type(x2.y) is seq[int]
assert type(x2.z) is float
var x3: TBar[float]
static:
assert type(x3.x) is float
assert type(x3.y) is array[4, float]
assert type(x3.z) is float

View file

@ -0,0 +1,22 @@
discard """
disabled: false
"""
type
TMatcherKind = enum
mkTerminal, mkSequence, mkAlternation, mkRepeat
TMatcher[T] = object
case kind: TMatcherKind
of mkTerminal:
value: T
of mkSequence, mkAlternation:
matchers: seq[TMatcher[T]]
of mkRepeat:
matcher: PMatcher[T]
min, max: int
PMatcher[T] = ref TMatcher[T]
var
m: PMatcher[int]

View file

@ -0,0 +1,18 @@
type
TMatcherKind = enum
mkTerminal, mkSequence, mkAlternation, mkRepeat
TMatcher[T] = object
case kind: TMatcherKind
of mkTerminal:
value: T
of mkSequence, mkAlternation:
matchers: seq[TMatcher[T]]
of mkRepeat:
matcher: ref TMatcher[T]
min, max: int
var
m: ref TMatcher[int]

View file

@ -0,0 +1,36 @@
discard """
output: "0false12"
"""
# Test multiple generic instantiation of generic proc vars:
proc threadProcWrapper[TMsg]() =
var x: TMsg
stdout.write($x)
#var x = threadProcWrapper[int]
#x()
#var y = threadProcWrapper[bool]
#y()
threadProcWrapper[int]()
threadProcWrapper[bool]()
type
TFilterProc[T,D] = proc (item: T, env:D): bool {.nimcall.}
proc filter[T,D](data: seq[T], env:D, pred: TFilterProc[T,D]): seq[T] =
result = @[]
for e in data:
if pred(e, env): result.add(e)
proc predTest(item: int, value: int): Bool =
return item <= value
proc test(data: seq[int], value: int): seq[int] =
return filter(data, value, predTest)
for x in items(test(@[1,2,3], 2)):
stdout.write(x)

View file

@ -0,0 +1,12 @@
type
TProperty[T] = object of TObject
getProc: proc(property: TProperty[T]): T {.nimcall.}
setProc: proc(property: TProperty[T], value: T) {.nimcall.}
value: T
proc newProperty[T](value: TObject): TProperty[T] =
result.getProc = proc (property: TProperty[T]) =
return property.value

View file

@ -0,0 +1,26 @@
type
PA[T] = ref TA[T]
TA[T] = object
field: T
var a: PA[string]
new(a)
a.field = "some string"
when false:
# Compiles unless you use var a: PA[string]
type
PA = ref TA
TA[T] = object
# Cannot instantiate:
type
TA[T] = object
a: PA[T]
PA[T] = ref TA[T]
type
PA[T] = ref TA[T]
TA[T] = object

View file

@ -0,0 +1,36 @@
discard """
file: "tgenericshardcases.nim"
output: "2\n5\n126\n3"
"""
import typetraits
proc typeNameLen(x: typedesc): int {.compileTime.} =
result = x.name.len
macro selectType(a, b: typedesc): typedesc =
result = a
type
Foo[T] = object
data1: array[T.high, int]
data2: array[typeNameLen(T), float] # data3: array[0..T.typeNameLen, selectType(float, int)]
MyEnum = enum A, B, C, D
var f1: Foo[MyEnum]
var f2: Foo[int8]
echo high(f1.data1) # (D = 3) - 1 == 2
echo high(f1.data2) # (MyEnum.len = 6) - 1 == 5
echo high(f2.data1) # 127 - 1 == 126
echo high(f2.data2) # int8.len - 1 == 3
#static:
# assert high(f1.data1) == ord(D)
# assert high(f1.data2) == 6 # length of MyEnum
# assert high(f2.data1) == 127
# assert high(f2.data2) == 4 # length of int8

View file

@ -0,0 +1,12 @@
template tmp[T](x: var seq[T]) =
#var yz: T # XXX doesn't work yet
x = @[1, 2, 3]
macro tmp2[T](x: var seq[T]): stmt =
nil
var y: seq[int]
tmp(y)
tmp(y)
echo y.repr

View file

@ -0,0 +1,23 @@
type
TMaybe[T] = object
case empty: Bool
of False: value: T
else: nil
proc Just*[T](val: T): TMaybe[T] =
result.empty = False
result.value = val
proc Nothing[T](): TMaybe[T] =
result.empty = True
proc safeReadLine(): TMaybe[string] =
var r = stdin.readLine()
if r == "": return Nothing[string]()
else: return Just(r)
when isMainModule:
var Test = Just("Test")
echo(Test.value)
var mSomething = safeReadLine()
echo(mSomething.value)

View file

@ -0,0 +1,15 @@
##
## specialised_is_equivalent Nimrod Module
##
## Created by Eric Doughty-Papassideris on 2011-02-16.
## Copyright (c) 2011 FWA. All rights reserved.
type
TGen[T] = tuple[a: T]
TSpef = tuple[a: string]
var
a: TGen[string]
b: TSpef
a = b

View file

@ -0,0 +1,39 @@
discard """
cmd: "nimrod cc --hints:on --threads:on $# $#"
"""
type
TThreadFuncArgs[T] = object of TObject
a: proc(): T {.thread.}
b: proc(val: T) {.thread.}
proc handleThreadFunc(arg: TThreadFuncArgs[int]){.thread.} =
var func = arg.a
var callback = arg.b
var output = func()
callback(output)
proc `@||->`*[T](func: proc(): T {.thread.},
callback: proc(val: T){.thread.}): TThread[TThreadFuncArgs[T]] =
var thr: TThread[TThreadFuncArgs[T]]
var args: TThreadFuncArgs[T]
args.a = func
args.b = callback
createThread(thr, handleThreadFunc, args)
return thr
proc `||->`*[T](func: proc(): T{.thread.}, callback: proc(val: T){.thread.}) =
discard func @||-> callback
when isMainModule:
import os
proc testFunc(): int {.thread.} =
return 1
proc callbackFunc(val: int) {.thread.} =
echo($(val))
var thr = (testFunc @||-> callbackFunc)
echo("test")
joinThread(thr)
os.sleep(3000)

View file

@ -0,0 +1,26 @@
discard """
output: "direct\ngeneric\ngeneric"
"""
proc withDirectType(args: string) =
echo "direct"
proc withDirectType[T](arg: T) =
echo "generic"
proc withOpenArray(args: openarray[string]) =
echo "openarray"
proc withOpenArray[T](arg: T) =
echo "generic"
proc withVarargs(args: varargs[string]) =
echo "varargs"
proc withVarargs[T](arg: T) =
echo "generic"
withDirectType "string"
withOpenArray "string"
withVarargs "string"