diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/ecmas.html | 21 | ||||
-rw-r--r-- | tests/ecmas.nim | 16 | ||||
-rw-r--r-- | tests/gcbench.nim | 172 | ||||
-rw-r--r-- | tests/hallo.nim | 34 | ||||
-rw-r--r-- | tests/rectest.nim | 6 | ||||
-rw-r--r-- | tests/tparscfg.nim | 25 | ||||
-rw-r--r-- | tests/tparsopt.nim | 27 | ||||
-rw-r--r-- | tests/tradix.nim | 319 | ||||
-rw-r--r-- | tests/tstrset.nim | 76 | ||||
-rw-r--r-- | tests/tstrtabs.nim | 12 |
10 files changed, 708 insertions, 0 deletions
diff --git a/tests/ecmas.html b/tests/ecmas.html new file mode 100644 index 000000000..25eb93dc3 --- /dev/null +++ b/tests/ecmas.html @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<!-- This has been written by hand. (c) 2008 Andreas Rumpf --> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<title>Nimrod ECMAScript Generator Test</title> +<style type="text/css"> +span.DecNumber {color: blue} +</style> +<script src="rod_gen/ecmas.js" type="text/javascript"></script> +</head> +<body onload="OnLoad()"> +<form name="form1" action="ecmas.html"> + <input type="text" name="input" size="3" /> + <input type="button" value="Calculate square" onclick="OnButtonClick()" /> +</form> + +</body> +</html> diff --git a/tests/ecmas.nim b/tests/ecmas.nim new file mode 100644 index 000000000..59e7ae1e8 --- /dev/null +++ b/tests/ecmas.nim @@ -0,0 +1,16 @@ +# This file tests the ECMAScript generator + +import + dom, strutils + +# We need to declare the used elements here. This is annoying but +# prevents any kind of typo: +var + inputElement {.importc: "document.form1.input", nodecl.}: ref TElement + +proc OnButtonClick() {.exportc.} = + var x: int = parseInt($inputElement.value) + echo($(x * x)) + +proc OnLoad() {.exportc.} = + echo("Welcome! Please take your time to fill in this formular!") diff --git a/tests/gcbench.nim b/tests/gcbench.nim new file mode 100644 index 000000000..4c94fe360 --- /dev/null +++ b/tests/gcbench.nim @@ -0,0 +1,172 @@ +# This is adapted from a benchmark written by John Ellis and Pete Kovac +# of Post Communications. +# It was modified by Hans Boehm of Silicon Graphics. +# +# This is no substitute for real applications. No actual application +# is likely to behave in exactly this way. However, this benchmark was +# designed to be more representative of real applications than other +# Java GC benchmarks of which we are aware. +# It attempts to model those properties of allocation requests that +# are important to current GC techniques. +# It is designed to be used either to obtain a single overall performance +# number, or to give a more detailed estimate of how collector +# performance varies with object lifetimes. It prints the time +# required to allocate and collect balanced binary trees of various +# sizes. Smaller trees result in shorter object lifetimes. Each cycle +# allocates roughly the same amount of memory. +# Two data structures are kept around during the entire process, so +# that the measured performance is representative of applications +# that maintain some live in-memory data. One of these is a tree +# containing many pointers. The other is a large array containing +# double precision floating point numbers. Both should be of comparable +# size. +# +# The results are only really meaningful together with a specification +# of how much memory was used. It is possible to trade memory for +# better time performance. This benchmark should be run in a 32 MB +# heap, though we don't currently know how to enforce that uniformly. +# +# Unlike the original Ellis and Kovac benchmark, we do not attempt +# measure pause times. This facility should eventually be added back +# in. There are several reasons for omitting it for now. The original +# implementation depended on assumptions about the thread scheduler +# that don't hold uniformly. The results really measure both the +# scheduler and GC. Pause time measurements tend to not fit well with +# current benchmark suites. As far as we know, none of the current +# commercial Java implementations seriously attempt to minimize GC pause +# times. +# +# Known deficiencies: +# - No way to check on memory use +# - No cyclic data structures +# - No attempt to measure variation with object size +# - Results are sensitive to locking cost, but we dont +# check for proper locking +# + +import + strutils, times + +type + PNode = ref TNode + TNode {.final.} = object + left, right: PNode + i, j: int + +proc newNode(l, r: PNode): PNode = + new(result) + result.left = l + result.right = r + +const + kStretchTreeDepth = 18 # about 16Mb + kLongLivedTreeDepth = 16 # about 4Mb + kArraySize = 500000 # about 4Mb + kMinTreeDepth = 4 + kMaxTreeDepth = 16 + +# Nodes used by a tree of a given size +proc TreeSize(i: int): int = return ((1 shl (i + 1)) - 1) + +# Number of iterations to use for a given tree depth +proc NumIters(i: int): int = + return 2 * TreeSize(kStretchTreeDepth) div TreeSize(i) + +# Build tree top down, assigning to older objects. +proc Populate(iDepth: int, thisNode: PNode) = + if iDepth <= 0: + return + else: + new(thisNode.left) + new(thisNode.right) + Populate(iDepth-1, thisNode.left) + Populate(iDepth-1, thisNode.right) + +# Build tree bottom-up +proc MakeTree(iDepth: int): PNode = + if iDepth <= 0: + new(result) + else: + return newNode(MakeTree(iDepth-1), + MakeTree(iDepth-1)) + +proc PrintDiagnostics() = + var + FreeMemory = getFreeMem() + TotalMemory = getTotalMem() + + echo("Total memory available: " & $TotalMemory & " bytes") + echo("Free memory: " & $FreeMemory & " bytes") + +proc TimeConstruction(depth: int) = + var + root, tempTree: PNode + t: int + iNumIters: int + + iNumIters = NumIters(depth) + + echo("Creating " & $iNumIters & " trees of depth " & $depth) + t = getStartMilsecs() + for i in 0..iNumIters-1: + new(tempTree) + Populate(depth, tempTree) + tempTree = nil + echo("\tTop down construction took " & + $(getStartMilsecs() - t) & "msecs") + t = getStartMilsecs() + for i in 0..iNumIters-1: + tempTree = MakeTree(depth) + tempTree = nil + echo("\tBottom up construction took " & + $(getStartMilsecs() - t) & "msecs") + +type + tMyArray = seq[float] + +proc main() = + var + root, longLivedTree, tempTree: PNode + t: int + myarray: tMyArray + + echo("Garbage Collector Test") + echo(" Stretching memory with a binary tree of depth " & + $kStretchTreeDepth) + PrintDiagnostics() + t = getStartMilsecs() + + # Stretch the memory space quickly + tempTree = MakeTree(kStretchTreeDepth) + tempTree = nil + + # Create a long lived object + echo(" Creating a long-lived binary tree of depth " & + $kLongLivedTreeDepth) + new(longLivedTree) + Populate(kLongLivedTreeDepth, longLivedTree) + + # Create long-lived array, filling half of it + echo(" Creating a long-lived array of " & $kArraySize & " doubles") + myarray = [] + setlength(myarray, kArraySize) + for i in 0..kArraySize div 2 -1: + myarray[i] = 1.0 / toFloat(i) + + PrintDiagnostics() + + var d = kMinTreeDepth + while d <= kMaxTreeDepth: + TimeConstruction(d) + inc(d, 2) + + if longLivedTree == nil or myarray[1000] != 1.0/1000.0: + echo("Failed") + # fake reference to LongLivedTree + # and array to keep them from being optimized away + + var elapsed = getStartMilsecs() - t + PrintDiagnostics() + echo("Completed in " & $elapsed & "ms.") + +main() diff --git a/tests/hallo.nim b/tests/hallo.nim new file mode 100644 index 000000000..070633793 --- /dev/null +++ b/tests/hallo.nim @@ -0,0 +1,34 @@ +# Hallo world program + +echo("Hi! What's your name?") +var name = readLine(stdin) + +if name == "Andreas": + echo("What a nice name!") +elif name == "": + echo("Don't you have a name?") +else: + echo("Your name is not Andreas...") + +for i in 0..name.len-1: + if name[i] == 'm': + echo("hey, there is an *m* in your name!") + +echo("Please give your password: (12345)") +var pw = readLine(stdin) + +while pw != "12345": + echo("Wrong password! Next try: ") + pw = readLine(stdin) + +echo("""Login complete! +What do you want to do? +delete-everything +restart-computer +go-for-a-walk""") + +case readline(stdin) +of "delete-everything", "restart-computer": + echo("permission denied") +of "go-for-a-walk": echo("please yourself") +else: echo("unknown command") diff --git a/tests/rectest.nim b/tests/rectest.nim new file mode 100644 index 000000000..f08306cfd --- /dev/null +++ b/tests/rectest.nim @@ -0,0 +1,6 @@ +# Test the error message + +proc main() = + main() + +main() diff --git a/tests/tparscfg.nim b/tests/tparscfg.nim new file mode 100644 index 000000000..33347285c --- /dev/null +++ b/tests/tparscfg.nim @@ -0,0 +1,25 @@ + +import + os, parsecfg, strutils + +var + p: TCfgParser + +if open(p, paramStr(1)): + while true: + var e = next(p) + case e.kind + of cfgEof: + echo("EOF!") + break + of cfgSectionStart: ## a ``[section]`` has been parsed + echo("new section: " & e.section) + of cfgKeyValuePair: + echo("key-value-pair: " & e.key & ": " & e.value) + of cfgOption: + echo("command: " & e.key & ": " & e.value) + of cfgError: + echo(e.msg) + close(p) +else: + echo("cannot open: " & paramStr(1)) diff --git a/tests/tparsopt.nim b/tests/tparsopt.nim new file mode 100644 index 000000000..2b2da7e51 --- /dev/null +++ b/tests/tparsopt.nim @@ -0,0 +1,27 @@ +# Test the new parseopt module + +import + parseopt + +proc writeHelp() = + writeln(stdout, "Usage: tparsopt [options] filename [options]") + +proc writeVersion() = + writeln(stdout, "Version: 1.0.0") + +var + filename = "" +for kind, key, val in getopt(): + case kind + of cmdArgument: + filename = key + of cmdLongOption, cmdShortOption: + case key + of "help", "h": writeHelp() + of "version", "v": writeVersion() + else: + writeln(stdout, "Unknown command line option: ", key, ": ", val) + of cmdEnd: assert(false) # cannot happen +if filename == "": + # no filename has been given, so we show the help: + writeHelp() diff --git a/tests/tradix.nim b/tests/tradix.nim new file mode 100644 index 000000000..208f9ae9d --- /dev/null +++ b/tests/tradix.nim @@ -0,0 +1,319 @@ +# implements and tests an efficient radix tree + +## another method to store an efficient array of pointers: +## We use a radix tree with node compression. +## There are two node kinds: + +const bitsPerUnit = 8*sizeof(int) + +type + TRadixNodeKind = enum rnLinear, rnFull, rnLeafBits, rnLeafLinear + PRadixNode = ptr TRadixNode + TRadixNode {.pure.} = object + kind: TRadixNodeKind + TRadixNodeLinear = object of TRadixNode + len: byte + keys: array [0..31, byte] + vals: array [0..31, PRadixNode] + + TRadixNodeFull = object of TRadixNode + b: array [0..255, PRadixNode] + TRadixNodeLeafBits = object of TRadixNode + b: array [0..7, int] + TRadixNodeLeafLinear = object of TRadixNode + len: byte + keys: array [0..31, byte] + +var + root: PRadixNode + +proc searchInner(r: PRadixNode, a: int): PRadixNode = + case r.kind + of rnLinear: + var x = cast[ptr TRadixNodeLinear](r) + for i in 0..x.len-1: + if ze(x.keys[i]) == a: return x.vals[i] + of rnFull: + var x = cast[ptr TRadixNodeFull](r) + return x.b[a] + else: assert(false) + +proc testBit(w, i: int): bool {.inline.} = + result = (w and (1 shl (i %% BitsPerUnit))) != 0 + +proc setBit(w: var int, i: int) {.inline.} = + w = w or (1 shl (i %% bitsPerUnit)) + +proc resetBit(w: var int, i: int) {.inline.} = + w = w and not (1 shl (i %% bitsPerUnit)) + +proc testOrSetBit(w: var int, i: int): bool {.inline.} = + var x = (1 shl (i %% bitsPerUnit)) + if (w and x) != 0: return true + w = w or x + +proc searchLeaf(r: PRadixNode, a: int): bool = + case r.kind + of rnLeafBits: + var x = cast[ptr TRadixNodeLeafBits](r) + return testBit(x.b[a /% BitsPerUnit], a) + of rnLeafLinear: + var x = cast[ptr TRadixNodeLeafLinear](r) + for i in 0..x.len-1: + if ze(x.keys[i]) == a: return true + else: assert(false) + +proc exclLeaf(r: PRadixNode, a: int) = + case r.kind + of rnLeafBits: + var x = cast[ptr TRadixNodeLeafBits](r) + resetBit(x.b[a /% BitsPerUnit], a) + of rnLeafLinear: + var x = cast[ptr TRadixNodeLeafLinear](r) + var L = ze(x.len) + for i in 0..L-1: + if ze(x.keys[i]) == a: + x.keys[i] = x.keys[L-1] + dec(x.len) + return + else: assert(false) + +proc in_Operator*(r: PRadixNode, a: TAddress): bool = + if r == nil: return false + var x = searchInner(r, a shr 24 and 0xff) + if x == nil: return false + x = searchInner(x, a shr 16 and 0xff) + if x == nil: return false + x = searchInner(x, a shr 8 and 0xff) + if x == nil: return false + return searchLeaf(x, a and 0xff) + +proc excl*(r: PRadixNode, a: TAddress): bool = + if r == nil: return false + var x = searchInner(r, a shr 24 and 0xff) + if x == nil: return false + x = searchInner(x, a shr 16 and 0xff) + if x == nil: return false + x = searchInner(x, a shr 8 and 0xff) + if x == nil: return false + exclLeaf(x, a and 0xff) + +proc addLeaf(r: var PRadixNode, a: int): bool = + if r == nil: + # a linear node: + var x = cast[ptr TRadixNodeLinear](alloc(sizeof(TRadixNodeLinear))) + x.kind = rnLeafLinear + x.len = 1 + x.keys[0] = toU8(a) + r = x + return false # not already in set + case r.kind + of rnLeafBits: + var x = cast[ptr TRadixNodeLeafBits](r) + return testOrSetBit(x.b[a /% BitsPerUnit], a) + of rnLeafLinear: + var x = cast[ptr TRadixNodeLeafLinear](r) + var L = ze(x.len) + for i in 0..L-1: + if ze(x.keys[i]) == a: return true + if L <= high(x.keys): + x.keys[L] = toU8(a) + inc(x.len) + else: + # transform into a full node: + var y = cast[ptr TRadixNodeLeafBits](alloc0(sizeof(TRadixNodeLeafBits))) + y.kind = rnLeafBits + for i in 0..x.len-1: + var u = ze(x.keys[i]) + setBit(y.b[u /% BitsPerUnit], u) + setBit(y.b[a /% BitsPerUnit], a) + dealloc(r) + r = y + else: assert(false) + +proc addInner(r: var PRadixNode, a: int, d: int): bool = + if d == 0: + return addLeaf(r, a and 0xff) + var k = a shr d and 0xff + if r == nil: + # a linear node: + var x = cast[ptr TRadixNodeLinear](alloc(sizeof(TRadixNodeLinear))) + x.kind = rnLinear + x.len = 1 + x.keys[0] = toU8(k) + r = x + return addInner(x.vals[0], a, d-8) + case r.kind + of rnLinear: + var x = cast[ptr TRadixNodeLinear](r) + var L = ze(x.len) + for i in 0..L-1: + if ze(x.keys[i]) == k: # already exists + return addInner(x.vals[i], a, d-8) + if L <= high(x.keys): + x.keys[L] = toU8(k) + inc(x.len) + return addInner(x.vals[L], a, d-8) + else: + # transform into a full node: + var y = cast[ptr TRadixNodeFull](alloc0(sizeof(TRadixNodeFull))) + y.kind = rnFull + for i in 0..L-1: y.b[ze(x.keys[i])] = x.vals[i] + dealloc(r) + r = y + return addInner(y.b[k], a, d-8) + of rnFull: + var x = cast[ptr TRadixNodeFull](r) + return addInner(x.b[k], a, d-8) + else: assert(false) + +proc incl*(r: var PRadixNode, a: TAddress) {.inline.} = + discard addInner(r, a, 24) + +proc testOrIncl*(r: var PRadixNode, a: TAddress): bool {.inline.} = + return addInner(r, a, 24) + +iterator innerElements(r: PRadixNode): tuple[prefix: int, n: PRadixNode] = + if r != nil: + case r.kind + of rnFull: + var r = cast[ptr TRadixNodeFull](r) + for i in 0..high(r.b): + if r.b[i] != nil: + yield (i, r.b[i]) + of rnLinear: + var r = cast[ptr TRadixNodeLinear](r) + for i in 0..ze(r.len)-1: + yield (ze(r.keys[i]), r.vals[i]) + else: assert(false) + +iterator leafElements(r: PRadixNode): int = + if r != nil: + case r.kind + of rnLeafBits: + var r = cast[ptr TRadixNodeLeafBits](r) + # iterate over any bit: + for i in 0..high(r.b): + if r.b[i] != 0: # test all bits for zero + for j in 0..BitsPerUnit-1: + if testBit(r.b[i], j): + yield i*BitsPerUnit+j + of rnLeafLinear: + var r = cast[ptr TRadixNodeLeafLinear](r) + for i in 0..ze(r.len)-1: + yield ze(r.keys[i]) + else: assert(false) + +iterator elements*(r: PRadixNode): TAddress {.inline.} = + for p1, n1 in innerElements(r): + for p2, n2 in innerElements(n1): + for p3, n3 in innerElements(n2): + for p4 in leafElements(n3): + yield p1 shl 24 or p2 shl 16 or p3 shl 8 or p4 + +proc main() = + const + numbers = [128, 1, 2, 3, 4, 255, 17, -8, 45, 19_000] + var + r: PRadixNode = nil + for x in items(numbers): + echo testOrIncl(r, x) + for x in elements(r): echo(x) + +main() + + +when false: + proc traverse(r: PRadixNode, prefix: int, d: int) = + if r == nil: return + case r.kind + of rnLeafBits: + assert(d == 0) + var x = cast[ptr TRadixNodeLeafBits](r) + # iterate over any bit: + for i in 0..high(x.b): + if x.b[i] != 0: # test all bits for zero + for j in 0..BitsPerUnit-1: + if testBit(x.b[i], j): + visit(prefix or i*BitsPerUnit+j) + of rnLeafLinear: + assert(d == 0) + var x = cast[ptr TRadixNodeLeafLinear](r) + for i in 0..ze(x.len)-1: + visit(prefix or ze(x.keys[i])) + of rnFull: + var x = cast[ptr TRadixNodeFull](r) + for i in 0..high(r.b): + if r.b[i] != nil: + traverse(r.b[i], prefix or (i shl d), d-8) + of rnLinear: + var x = cast[ptr TRadixNodeLinear](r) + for i in 0..ze(x.len)-1: + traverse(x.vals[i], prefix or (ze(x.keys[i]) shl d), d-8) + + type + TRadixIter {.final.} = object + r: PRadixNode + p: int + x: int + + proc init(i: var TRadixIter, r: PRadixNode) = + i.r = r + i.x = 0 + i.p = 0 + + proc nextr(i: var TRadixIter): PRadixNode = + if i.r == nil: return nil + case i.r.kind + of rnFull: + var r = cast[ptr TRadixNodeFull](i.r) + while i.x <= high(r.b): + if r.b[i.x] != nil: + i.p = i.x + return r.b[i.x] + inc(i.x) + of rnLinear: + var r = cast[ptr TRadixNodeLinear](i.r) + if i.x < ze(r.len): + i.p = ze(r.keys[i.x]) + result = r.vals[i.x] + inc(i.x) + else: assert(false) + + proc nexti(i: var TRadixIter): int = + result = -1 + case i.r.kind + of rnLeafBits: + var r = cast[ptr TRadixNodeLeafBits](i.r) + # iterate over any bit: + for i in 0..high(r.b): + if x.b[i] != 0: # test all bits for zero + for j in 0..BitsPerUnit-1: + if testBit(x.b[i], j): + visit(prefix or i*BitsPerUnit+j) + of rnLeafLinear: + var r = cast[ptr TRadixNodeLeafLinear](i.r) + if i.x < ze(r.len): + result = ze(r.keys[i.x]) + inc(i.x) + + iterator elements(r: PRadixNode): TAddress {.inline.} = + var + a, b, c, d: TRadixIter + init(a, r) + while true: + var x = nextr(a) + if x != nil: + init(b, x) + while true: + var y = nextr(b) + if y != nil: + init(c, y) + while true: + var z = nextr(c) + if z != nil: + init(d, z) + while true: + var q = nexti(d) + if q != -1: + yield a.p shl 24 or b.p shl 16 or c.p shl 8 or q diff --git a/tests/tstrset.nim b/tests/tstrset.nim new file mode 100644 index 000000000..76900bf63 --- /dev/null +++ b/tests/tstrset.nim @@ -0,0 +1,76 @@ +# test a simple yet highly efficient set of strings + +type + TRadixNodeKind = enum rnLinear, rnFull, rnLeaf + PRadixNode = ptr TRadixNode + TRadixNode = object + kind: TRadixNodeKind + TRadixNodeLinear = object of TRadixNode + len: byte + keys: array [0..31, char] + vals: array [0..31, PRadixNode] + TRadixNodeFull = object of TRadixNode + b: array [char, PRadixNode] + TRadixNodeLeaf = object of TRadixNode + s: string + PRadixNodeLinear = ref TRadixNodeLinear + PRadixNodeFull = ref TRadixNodeFull + PRadixNodeLeaf = ref TRadixNodeLeaf + +proc search(r: PRadixNode, s: string): PRadixNode = + var r = r + var i = 0 + while r != nil: + case r.kind + of rnLinear: + var x = PRadixNodeLinear(r) + for j in 0..x.len-1: + if x.keys[j] == s[i]: + if s[i] == '\0': return r + r = x.vals[j] + inc(i) + break + break # character not found + of rnFull: + var x = PRadixNodeFull(r) + var y = x.b[s[i]] + if s[i] == '\0': + return if y != nil: r else: nil + r = y + inc(i) + of rnLeaf: + var x = PRadixNodeLeaf(r) + var j = 0 + while true: + if x.s[j] != s[i]: return nil + if s[i] == '\0': return r + inc(j) + inc(i) + +proc in_Operator*(r: PRadixNode, s: string): bool = + return search(r, s) != nil + +proc testOrincl*(r: var PRadixNode, s: string): bool = + nil + +proc incl*(r: var PRadixNode, s: string) = discard testOrIncl(r, s) + +proc excl*(r: var PRadixNode, s: string) = + x = search(r, s) + if x == nil: return + case x.kind + of rnLeaf: PRadixNodeLeaf(x).s = "" + of rnFull: PRadixNodeFull(x).b['\0'] = nil + of rnLinear: + var x = PRadixNodeLinear(x) + for i in 0..x.len-1: + if x.keys[i] == '\0': + swap(x.keys[i], x.keys[x.len-1]) + dec(x.len) + break + +var + root: PRadixNode + + + diff --git a/tests/tstrtabs.nim b/tests/tstrtabs.nim new file mode 100644 index 000000000..299db609d --- /dev/null +++ b/tests/tstrtabs.nim @@ -0,0 +1,12 @@ +import strtabs + +var tab = newStringTable(["key1", "val1", "key2", "val2"], + modeStyleInsensitive) +for i in 0..80: + tab["key_" & $i] = "value" & $i + +for key, val in pairs(tab): + writeln(stdout, key, ": ", val) +writeln(stdout, "length of table ", $tab.len) + +writeln(stdout, `%`("$key1 = $key2; ${PATH}", tab, {useEnvironment})) |