diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2014-04-09 22:56:18 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2014-04-09 22:56:18 +0200 |
commit | a690e7b26772a9bb8367acb451a6250449e666ab (patch) | |
tree | 9aca0024db9c75970c4dfac10c55f1961c21ca25 /tests/misc | |
parent | d0f013477b16520eefff69b861d2f26744463880 (diff) | |
parent | a157985e01cbf80383d5e50836072d70678c9de3 (diff) | |
download | Nim-a690e7b26772a9bb8367acb451a6250449e666ab.tar.gz |
Merge pull request #1075 from flaviut/inlinedocs
Add some documentations and code examples in system
Diffstat (limited to 'tests/misc')
68 files changed, 2414 insertions, 0 deletions
diff --git a/tests/misc/99bottles.nim b/tests/misc/99bottles.nim new file mode 100644 index 000000000..14904ac0f --- /dev/null +++ b/tests/misc/99bottles.nim @@ -0,0 +1 @@ +# Test if the compiler detects invalid module names diff --git a/tests/misc/minit.nim b/tests/misc/minit.nim new file mode 100644 index 000000000..75fcebb77 --- /dev/null +++ b/tests/misc/minit.nim @@ -0,0 +1,2 @@ +# Test the new initialization for modules +write(stdout, "Hello from module! ") diff --git a/tests/misc/mvarious.nim b/tests/misc/mvarious.nim new file mode 100644 index 000000000..c0a8add73 --- /dev/null +++ b/tests/misc/mvarious.nim @@ -0,0 +1,6 @@ +# Test a submodule + +#type +# TStringArr = array [0.. *] of string + +proc exportme* = discard diff --git a/tests/misc/t99bott.nim b/tests/misc/t99bott.nim new file mode 100644 index 000000000..d18cb0d5c --- /dev/null +++ b/tests/misc/t99bott.nim @@ -0,0 +1,36 @@ +discard """ + file: "t99bott.nim" + line: 26 + errormsg: "cannot evaluate at compile time: bn" + disabled: false +""" +## 99 Bottles of Beer +## http://www.99-bottles-of-beer.net/ +## Nimrod version + +## Author: Philippe Lhoste <PhiLho(a)GMX.net> http://Phi.Lho.free.fr +# 2012-11-25 +# Loosely based on my old Lua version... Updated to current official lyrics. + +proc GetBottleNumber(n: int): string = + var bs: string + if n == 0: + bs = "No more bottles" + elif n == 1: + bs = "1 bottle" + else: + bs = $n & " bottles" + return bs & " of beer" + +for bn in countdown(99, 1): + const cur = GetBottleNumber(bn) + echo(cur, " on the wall, ", cur, ".") + echo("Take one down and pass it around, ", GetBottleNumber(bn-1), + " on the wall.\n") + +echo "No more bottles of beer on the wall, no more bottles of beer." +echo "Go to the store and buy some more, 99 bottles of beer on the wall." + + + + diff --git a/tests/misc/tack.nim b/tests/misc/tack.nim new file mode 100644 index 000000000..680ff567e --- /dev/null +++ b/tests/misc/tack.nim @@ -0,0 +1,21 @@ +discard """ + file: "tack.nim" + output: "125" +""" +# the Ackermann function + +proc ack(x, y: int): int = + if x != 0: + if y != 0: + return ack(x-1, ack(x, y-1)) + return ack(x-1, 1) + else: + return y + 1 +# if x == 0: return y + 1 +# elif y == 0: return ack(x-1, 1) +# else: return ack(x-1, ack(x, y-1)) + +# echo(ack(0, 0)) +write(stdout, ack(3, 4)) #OUT 125 + + diff --git a/tests/misc/tatomic.nim b/tests/misc/tatomic.nim new file mode 100644 index 000000000..1fa0cff8d --- /dev/null +++ b/tests/misc/tatomic.nim @@ -0,0 +1,12 @@ +discard """ + file: "tatomic.nim" + line: 7 + errormsg: "identifier expected, but found 'keyword atomic'" +""" +var + atomic: int + +echo atomic + + + diff --git a/tests/misc/tbug511622.nim b/tests/misc/tbug511622.nim new file mode 100644 index 000000000..a5360423d --- /dev/null +++ b/tests/misc/tbug511622.nim @@ -0,0 +1,16 @@ +discard """ + file: "tbug511622.nim" + output: "3" +""" +import StrUtils, Math + +proc FibonacciA(n: int): int64 = + var fn = float64(n) + var p: float64 = (1.0 + sqrt(5.0)) / 2.0 + var q: float64 = 1.0 / p + return int64((pow(p, fn) + pow(q, fn)) / sqrt(5.0)) + +echo FibonacciA(4) #OUT 3 + + + diff --git a/tests/misc/tcmdline.nim b/tests/misc/tcmdline.nim new file mode 100644 index 000000000..f4ee20d31 --- /dev/null +++ b/tests/misc/tcmdline.nim @@ -0,0 +1,14 @@ +# Test the command line + +import + os, strutils + +var + i: int + params = paramCount() +i = 0 +writeln(stdout, "This exe: " & getAppFilename()) +writeln(stdout, "Number of parameters: " & $params) +while i <= params: + writeln(stdout, paramStr(i)) + i = i + 1 diff --git a/tests/misc/tcolonisproc.nim b/tests/misc/tcolonisproc.nim new file mode 100644 index 000000000..e55587dfc --- /dev/null +++ b/tests/misc/tcolonisproc.nim @@ -0,0 +1,12 @@ + +proc p(a, b: int, c: proc ()) = + c() + + +p(1, 3): + echo 1 + echo 3 + +p(1, 1, proc() = + echo 1 + echo 2) diff --git a/tests/misc/tdllvar.nim b/tests/misc/tdllvar.nim new file mode 100644 index 000000000..ab767770c --- /dev/null +++ b/tests/misc/tdllvar.nim @@ -0,0 +1,16 @@ +import os + +proc getDllName: string = + result = "mylib.dll" + if ExistsFile(result): return + result = "mylib2.dll" + if ExistsFile(result): return + quit("could not load dynamic library") + +proc myImport(s: cstring) {.cdecl, importc, dynlib: getDllName().} +proc myImport2(s: int) {.cdecl, importc, dynlib: getDllName().} + +myImport("test2") +myImport2(12) + + diff --git a/tests/misc/temit.nim b/tests/misc/temit.nim new file mode 100644 index 000000000..ff8df0585 --- /dev/null +++ b/tests/misc/temit.nim @@ -0,0 +1,20 @@ +discard """ + file: "temit.nim" + output: "509" +""" +# Test the new ``emit`` pragma: + +{.emit: """ +static int cvariable = 420; + +""".} + +proc embedsC() = + var nimrodVar = 89 + {.emit: """printf("%d\n", cvariable + (int)`nimrodVar`);""".} + +embedsC() + + + + diff --git a/tests/misc/temptyecho.nim b/tests/misc/temptyecho.nim new file mode 100644 index 000000000..5f1aa6515 --- /dev/null +++ b/tests/misc/temptyecho.nim @@ -0,0 +1,2 @@ +echo() + diff --git a/tests/misc/tendian.nim b/tests/misc/tendian.nim new file mode 100644 index 000000000..256e2653c --- /dev/null +++ b/tests/misc/tendian.nim @@ -0,0 +1,3 @@ +# test the new endian magic + +writeln(stdout, repr(system.cpuEndian)) diff --git a/tests/misc/teventemitter.nim b/tests/misc/teventemitter.nim new file mode 100644 index 000000000..9ecf72ea2 --- /dev/null +++ b/tests/misc/teventemitter.nim @@ -0,0 +1,33 @@ +discard """ + output: "pie" +""" + +import tables, lists + +type + TEventArgs = object of TObject + TEventEmitter = object of TObject + events*: TTable[string, TDoublyLinkedList[proc(e: TEventArgs) {.nimcall.}]] + +proc emit*(emitter: TEventEmitter, event: string, args: TEventArgs) = + for func in nodes(emitter.events[event]): + func.value(args) #call function with args. + +proc on*(emitter: var TEventEmitter, event: string, + func: proc(e: TEventArgs) {.nimcall.}) = + if not hasKey(emitter.events, event): + var list: TDoublyLinkedList[proc(e: TEventArgs) {.nimcall.}] + add(emitter.events, event, list) #if not, add it. + append(emitter.events.mget(event), func) + +proc initEmitter(emitter: var TEventEmitter) = + emitter.events = initTable[string, + TDoublyLinkedList[proc(e: TEventArgs) {.nimcall.}]]() + +var + ee: TEventEmitter + args: TEventArgs +initEmitter(ee) +ee.on("print", proc(e: TEventArgs) = echo("pie")) +ee.emit("print", args) + diff --git a/tests/misc/tevents.nim b/tests/misc/tevents.nim new file mode 100644 index 000000000..fb94b1f79 --- /dev/null +++ b/tests/misc/tevents.nim @@ -0,0 +1,48 @@ +discard """ +file: "tevents.nim" +output: '''HandlePrintEvent: Output -> Handled print event +HandlePrintEvent2: Output -> printing for ME +HandlePrintEvent2: Output -> printing for ME''' +""" + +import events + +type + TPrintEventArgs = object of TEventArgs + user*: string + +proc handleprintevent*(e: TEventArgs) = + write(stdout, "HandlePrintEvent: Output -> Handled print event\n") + +proc handleprintevent2*(e: TEventArgs) = + var args: TPrintEventArgs = TPrintEventArgs(e) + write(stdout, "HandlePrintEvent2: Output -> printing for " & args.user) + +var ee = initEventEmitter() + +var eventargs: TPrintEventArgs +eventargs.user = "ME\n" + +##method one test + +ee.on("print", handleprintevent) +ee.on("print", handleprintevent2) + +ee.emit("print", eventargs) + +##method two test + +type + TSomeObject = object of TObject + PrintEvent: TEventHandler + +var obj: TSomeObject +obj.PrintEvent = initEventHandler("print") +obj.PrintEvent.addHandler(handleprintevent2) + +ee.emit(obj.PrintEvent, eventargs) + +obj.PrintEvent.removeHandler(handleprintevent2) + +ee.emit(obj.PrintEvent, eventargs) + diff --git a/tests/misc/tfib.nim b/tests/misc/tfib.nim new file mode 100644 index 000000000..09a4d5038 --- /dev/null +++ b/tests/misc/tfib.nim @@ -0,0 +1,11 @@ + +iterator fibonacci(): int = + var a = 0 + var b = 1 + while true: + yield a + var c = b + b = a + a = a + c + + diff --git a/tests/misc/tfilter.nim b/tests/misc/tfilter.nim new file mode 100644 index 000000000..5846d0efb --- /dev/null +++ b/tests/misc/tfilter.nim @@ -0,0 +1,41 @@ +discard """ + output: "02468101214161820\n15" +""" + +proc filter[T](list: seq[T], f: proc (item: T): bool {.closure.}): seq[T] = + result = @[] + for i in items(list): + if f(i): + result.add(i) + +let nums = @[0, 1, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] + +when true: + let nums2 = filter(nums, + (proc (item: int): bool = + result = (item mod 2) == 0) + ) + +proc outer = + # lets use a proper closure this time: + var modulo = 2 + let nums2 = filter(nums, + (proc (item: int): bool = result = (item mod modulo) == 0) + ) + + for n in nums2: stdout.write(n) + stdout.write("\n") + +outer() + +import math +proc compose[T](f1, f2: proc (x: T): T {.closure.}): proc (x: T): T {.closure.} = + result = (proc (x: T): T = + result = f1(f2(x))) + + +proc add5(x: int): int = result = x + 5 + +var test = compose(add5, add5) +echo test(5) + diff --git a/tests/misc/tgenconstraints.nim b/tests/misc/tgenconstraints.nim new file mode 100644 index 000000000..6e8fdc738 --- /dev/null +++ b/tests/misc/tgenconstraints.nim @@ -0,0 +1,32 @@ +discard """ + file: "tgenconstraints.nim" + line: 25 + disabled: true + errormsg: "cannot instantiate T2" +""" + +type + T1[T: int|string] = object + x: T + + T2[T: Ordinal] = object + x: T + +var x1: T1[int] +var x2: T1[string] +var x3: T2[int] + +proc foo[T](x: T): T2[T] {.discardable.} = + var o: T1[T] + +foo(10) + +# XXX: allow type intersections in situation like this +proc bar(x: int|TNumber): T1[type(x)] {.discardable.} = + when type(x) is TNumber: + var o: T2[type(x)] + +bar "test" +bar 100 +bar 1.1 + diff --git a/tests/misc/tgetstartmilsecs.nim b/tests/misc/tgetstartmilsecs.nim new file mode 100644 index 000000000..5a3368e0f --- /dev/null +++ b/tests/misc/tgetstartmilsecs.nim @@ -0,0 +1,7 @@ +# +import times, os + +var start = epochTime() +os.sleep(1000) + +echo epochTime() - start #OUT 1000 diff --git a/tests/misc/tgtk.nim b/tests/misc/tgtk.nim new file mode 100644 index 000000000..7febb0ab8 --- /dev/null +++ b/tests/misc/tgtk.nim @@ -0,0 +1,51 @@ + +import + gtk2, glib2, atk, gdk2, gdk2pixbuf, libglade2, pango, + pangoutils + +proc hello(widget: PWidget, data: pointer) {.cdecl.} = + write(stdout, "Hello World\n") + +proc delete_event(widget: PWidget, event: PEvent, + data: pointer): bool {.cdecl.} = + # If you return FALSE in the "delete_event" signal handler, + # GTK will emit the "destroy" signal. Returning TRUE means + # you don't want the window to be destroyed. + # This is useful for popping up 'are you sure you want to quit?' + # type dialogs. + write(stdout, "delete event occurred\n") + # Change TRUE to FALSE and the main window will be destroyed with + # a "delete_event". + return false + +# Another callback +proc mydestroy(widget: PWidget, data: pointer) {.cdecl.} = + gtk2.main_quit() + +proc mymain() = + # GtkWidget is the storage type for widgets + gtk2.nimrod_init() + var window = window_new(gtk2.WINDOW_TOPLEVEL) + discard g_signal_connect(window, "delete_event", + Gcallback(delete_event), nil) + discard g_signal_connect(window, "destroy", Gcallback(mydestroy), nil) + # Sets the border width of the window. + set_border_width(window, 10) + + # Creates a new button with the label "Hello World". + var button = button_new("Hello World") + + discard g_signal_connect(button, "clicked", Gcallback(hello), nil) + + # This packs the button into the window (a gtk container). + add(window, button) + + # The final step is to display this newly created widget. + show(button) + + # and the window + show(window) + + gtk2.main() + +mymain() diff --git a/tests/misc/thallo.nim b/tests/misc/thallo.nim new file mode 100644 index 000000000..7244c27a1 --- /dev/null +++ b/tests/misc/thallo.nim @@ -0,0 +1,85 @@ +# Hallo + +import + os, strutils, macros + +type + TMyEnum = enum + meA, meB, meC, meD + +when isMainModule: + {.hint: "this is the main file".} + +proc fac[T](x: T): T = + # test recursive generic procs + if x <= 1: return 1 + else: return x.`*`(fac(x-1)) + +macro macrotest(n: expr): stmt {.immediate.} = + let n = callsite() + expectKind(n, nnkCall) + expectMinLen(n, 2) + result = newNimNode(nnkStmtList, n) + for i in 2..n.len-1: + result.add(newCall("write", n[1], n[i])) + result.add(newCall("writeln", n[1], newStrLitNode(""))) + +macro debug(n: expr): stmt {.immediate.} = + let n = callsite() + result = newNimNode(nnkStmtList, n) + for i in 1..n.len-1: + result.add(newCall("write", newIdentNode("stdout"), toStrLit(n[i]))) + result.add(newCall("write", newIdentNode("stdout"), newStrLitNode(": "))) + result.add(newCall("writeln", newIdentNode("stdout"), n[i])) + +macrotest(stdout, "finally", 4, 5, "variable", "argument lists") +macrotest(stdout) + +#GC_disable() + +echo("This was compiled by Nimrod version " & system.nimrodVersion) +writeln(stdout, "Hello", " World", "!") + +echo(["a", "b", "c", "d"].len) +for x in items(["What's", "your", "name", "?", ]): + echo(x) +var `name` = readLine(stdin) +{.breakpoint.} +echo("Hi " & thallo.name & "!\n") +debug(name) + +var testseq: seq[string] = @[ + "a", "b", "c", "d", "e" +] +echo(repr(testseq)) + +var dummy = "hello" +echo(substr(dummy, 2, 3)) + +echo($meC) + +# test tuples: +for x, y in items([(1, 2), (3, 4), (6, 1), (5, 2)]): + echo x + echo y + +proc simpleConst(): int = return 34 + +# test constant evaluation: +const + constEval3 = simpleConst() + constEval = "abc".contains('b') + constEval2 = fac(7) + +echo(constEval3) +echo(constEval) +echo(constEval2) +echo(1.`+`(2)) + +for i in 2..6: + for j in countdown(i+4, 2): + echo(fac(i * j)) + +when isMainModule: + {.hint: "this is the main file".} + diff --git a/tests/misc/theaproots.nim b/tests/misc/theaproots.nim new file mode 100644 index 000000000..aec140f42 --- /dev/null +++ b/tests/misc/theaproots.nim @@ -0,0 +1,71 @@ +type + Bar = object + x: int + + Foo = object + rheap: ref Bar + rmaybe: ref Bar + rstack: ref Bar + list: seq[ref Bar] + listarr: array[0..5, ref Bar] + nestedtup: Tup + inner: TInner + inref: ref TInner + + TInner = object + inref: ref Bar + + Tup = tuple + tupbar: ref Bar + inner: TInner + +proc acc(x: var Foo): var ref Bar = + result = x.rheap + +proc test(maybeFoo: var Foo, + maybeSeq: var seq[ref Bar], + bars: var openarray[ref Bar], + maybeTup: var Tup) = + var bb: ref Bar + maybeFoo.rmaybe = bb + maybeFoo.list[3] = bb + maybeFoo.listarr[3] = bb + acc(maybeFoo) = bb + + var localFoo: Foo + localFoo.rstack = bb + localFoo.list[3] = bb + localFoo.listarr[3] = bb + acc(localFoo) = bb + + var heapFoo: ref Foo + heapFoo.rheap = bb + heapFoo.list[3] = bb + heapFoo.listarr[3] = bb + acc(heapFoo[]) = bb + + heapFoo.nestedtup.tupbar = bb + heapFoo.nestedtup.inner.inref = bb + heapFoo.inner.inref = bb + heapFoo.inref.inref = bb + + var locseq: seq[ref Bar] + locseq[3] = bb + + var locarr: array[0..4, ref Bar] + locarr[3] = bb + + maybeSeq[3] = bb + + bars[3] = bb + + maybeTup[0] = bb + +var + ff: ref Foo + tt: Tup + gseq: seq[ref Bar] + +new(ff) + +test(ff[], gseq, gseq, tt) diff --git a/tests/misc/thintoff.nim b/tests/misc/thintoff.nim new file mode 100644 index 000000000..807ff44f3 --- /dev/null +++ b/tests/misc/thintoff.nim @@ -0,0 +1,12 @@ +discard """ + file: "thintoff.nim" + output: "0" +""" + +{.hint[XDeclaredButNotUsed]: off.} +var + x: int + +echo x #OUT 0 + + diff --git a/tests/misc/tinc.nim b/tests/misc/tinc.nim new file mode 100644 index 000000000..8038a2a01 --- /dev/null +++ b/tests/misc/tinc.nim @@ -0,0 +1,12 @@ +discard """ + file: "tinc.nim" + line: 8 + errormsg: "for a \'var\' type a variable needs to be passed" +""" +var x = 0 + +inc(x+1) + + + + diff --git a/tests/misc/tinit.nim b/tests/misc/tinit.nim new file mode 100644 index 000000000..5c75567ec --- /dev/null +++ b/tests/misc/tinit.nim @@ -0,0 +1,12 @@ +discard """ + file: "tinit.nim" + output: "Hello from module! Hello from main module!" +""" +# Test the new init section in modules + +import minit + +write(stdout, "Hello from main module!\n") +#OUT Hello from module! Hello from main module! + + diff --git a/tests/misc/tinout.nim b/tests/misc/tinout.nim new file mode 100644 index 000000000..034c496f5 --- /dev/null +++ b/tests/misc/tinout.nim @@ -0,0 +1,16 @@ +discard """ + file: "tinout.nim" + line: 12 + errormsg: "for a \'var\' type a variable needs to be passed" +""" +# Test in out checking for parameters + +proc abc(x: var int) = + x = 0 + +proc b() = + abc(3) #ERROR + +b() + + diff --git a/tests/misc/tints.nim b/tests/misc/tints.nim new file mode 100644 index 000000000..fb2852af9 --- /dev/null +++ b/tests/misc/tints.nim @@ -0,0 +1,45 @@ +discard """ + file: "tints.nim" + output: "Success" +""" +# Test the different integer operations + +var testNumber = 0 + +template test(opr, a, b, c: expr): stmt {.immediate.} = + # test the expression at compile and runtime + block: + const constExpr = opr(a, b) + when constExpr != c: + {.error: "Test failed " & $constExpr & " " & $c.} + inc(testNumber) + #Echo("Test: " & $testNumber) + var aa = a + var bb = b + var varExpr = opr(aa, bb) + assert(varExpr == c) + +test(`+`, 12'i8, -13'i16, -1'i16) +test(`shl`, 0b11, 0b100, 0b110000) +test(`shl`, 0b11'i32, 0b100'i64, 0b110000'i64) +test(`shl`, 0b11'i32, 0b100'i32, 0b110000'i32) + +test(`or`, 0xf0f0'i16, 0x0d0d'i16, 0xfdfd'i16) +test(`and`, 0xf0f0'i16, 0xfdfd'i16, 0xf0f0'i16) + +test(`shr`, 0xffffffffffffffff'i64, 0x4'i64, 0x0fffffffffffffff'i64) +test(`shr`, 0xffff'i16, 0x4'i16, 0x0fff'i16) +test(`shr`, 0xff'i8, 0x4'i8, 0x0f'i8) + +test(`shr`, 0xffffffff'i64, 0x4'i64, 0x0fffffff'i64) +test(`shr`, 0xffffffff'i32, 0x4'i32, 0x0fffffff'i32) + +test(`shl`, 0xffffffffffffffff'i64, 0x4'i64, 0xfffffffffffffff0'i64) +test(`shl`, 0xffff'i16, 0x4'i16, 0xfff0'i16) +test(`shl`, 0xff'i8, 0x4'i8, 0xf0'i8) + +test(`shl`, 0xffffffff'i64, 0x4'i64, 0xffffffff0'i64) +test(`shl`, 0xffffffff'i32, 0x4'i32, 0xfffffff0'i32) + +Echo("Success") #OUT Success + diff --git a/tests/misc/tinvalidarrayaccess.nim b/tests/misc/tinvalidarrayaccess.nim new file mode 100644 index 000000000..03105b41b --- /dev/null +++ b/tests/misc/tinvalidarrayaccess.nim @@ -0,0 +1,14 @@ +discard """ + errormsg: "index out of bounds" + line: 11 +""" + + +type TTestArr = array[0..1, int16] +var f: TTestArr +f[0] = 30 +f[1] = 40 +f[2] = 50 +f[3] = 60 + +echo(repr(f)) diff --git a/tests/misc/tinvalidnewseq.nim b/tests/misc/tinvalidnewseq.nim new file mode 100644 index 000000000..957a25560 --- /dev/null +++ b/tests/misc/tinvalidnewseq.nim @@ -0,0 +1,27 @@ +discard """ + file: "tinvalidnewseq.nim" + line: 15 + errormsg: "type mismatch: got (array[0..6, string], int literal(7))" +""" +import re, strutils + +type + TURL = tuple[protocol, subdomain, domain, port: string, path: seq[string]] + +proc parseURL(url: string): TURL = + #([a-zA-Z]+://)?(\w+?\.)?(\w+)(\.\w+)(:[0-9]+)?(/.+)? + var pattern: string = r"([a-zA-Z]+://)?(\w+?\.)?(\w+)(\.\w+)(:[0-9]+)?(/.+)?" + var m: array[0..6, string] #Array with the matches + newSeq(m, 7) #ERROR + discard regexprs.match(url, re(pattern), m) + + result = (protocol: m[1], subdomain: m[2], domain: m[3] & m[4], + port: m[5], path: m[6].split('/')) + +var r: TUrl + +r = parseUrl(r"http://google.com/search?var=bleahdhsad") +echo(r.domain) + + + diff --git a/tests/misc/tlastmod.nim b/tests/misc/tlastmod.nim new file mode 100644 index 000000000..75b047fc8 --- /dev/null +++ b/tests/misc/tlastmod.nim @@ -0,0 +1,18 @@ +# test the new LastModificationTime() proc + +import + os, times, strutils + +proc main() = + var + a, b: TTime + a = getLastModificationTime(ParamStr(1)) + b = getLastModificationTime(ParamStr(2)) + writeln(stdout, $a) + writeln(stdout, $b) + if a < b: + Write(stdout, "$2 is newer than $1\n" % [ParamStr(1), ParamStr(2)]) + else: + Write(stdout, "$1 is newer than $2\n" % [ParamStr(1), ParamStr(2)]) + +main() diff --git a/tests/misc/tlibs.nim b/tests/misc/tlibs.nim new file mode 100644 index 000000000..e7a02c7fd --- /dev/null +++ b/tests/misc/tlibs.nim @@ -0,0 +1,28 @@ +discard """ + disabled: true +""" + +# Test wether the bindings at least compile... + +import + unicode, cgi, terminal, libcurl, + parsexml, parseopt, parsecfg, + osproc, complex, + sdl, smpeg, sdl_gfx, sdl_net, sdl_mixer, sdl_ttf, + sdl_image, sdl_mixer_nosmpeg, + cursorfont, xatom, xf86vmode, xkb, xrandr, xshm, xvlib, keysym, xcms, xi, + xkblib, xrender, xutil, x, xf86dga, xinerama, xlib, xresource, xv, + gtk2, glib2, pango, gdk2, + cairowin32, cairoxlib, + odbcsql, + gl, glut, glu, glx, glext, wingl, + lua, lualib, lauxlib, mysql, sqlite3, python, tcl, + db_postgres, db_mysql, db_sqlite, ropes, sockets, browsers, httpserver, + httpclient, parseutils, unidecode, xmldom, xmldomparser, xmltree, xmlparser, + htmlparser, re, graphics, colors, pegs, subexes, dialogs + +when defined(linux): + import + zlib, zipfiles + +writeln(stdout, "test compilation of binding modules") diff --git a/tests/misc/tlocals.nim b/tests/misc/tlocals.nim new file mode 100644 index 000000000..af8a54946 --- /dev/null +++ b/tests/misc/tlocals.nim @@ -0,0 +1,11 @@ +discard """ + output: "(x: string here, a: 1)" +""" + +proc simple[T](a: T) = + var + x = "string here" + echo locals() + +simple(1) + diff --git a/tests/misc/tloops.nim b/tests/misc/tloops.nim new file mode 100644 index 000000000..f6f939769 --- /dev/null +++ b/tests/misc/tloops.nim @@ -0,0 +1,87 @@ +# Test nested loops and some other things + +proc andTest() = + var a = 0 == 5 and 6 == 6 + +proc incx(x: var int) = # is built-in proc + x = x + 1 + +proc decx(x: var int) = + x = x - 1 + +proc First(y: var int) = + var x: int + i_ncx(x) + if x == 10: + y = 0 + else: + if x == 0: + incx(x) + else: + x=11 + +proc TestLoops() = + var i, j: int + while i >= 0: + if i mod 3 == 0: + break + i = i + 1 + while j == 13: + j = 13 + break + break + + while True: + break + + +proc Foo(n: int): int = + var + a, old: int + b, c: bool + F_irst(a) + if a == 10: + a = 30 + elif a == 11: + a = 22 + elif a == 12: + a = 23 + elif b: + old = 12 + else: + a = 40 + + # + b = false or 2 == 0 and 3 == 9 + a = 0 + 3 * 5 + 6 + 7 + +8 # 36 + while b: + a = a + 3 + a = a + 5 + write(stdout, "Hello!") + + +# We should come till here :-) +discard Foo(345) + +# test the new type symbol lookup feature: + +type + MyType[T] = tuple[ + x, y, z: T] + MyType2 = tuple[x, y: float] + +proc main[T]() = + var myType: MyType[T] + var b: MyType[T] + b = (1, 2, 3) + myType = b + echo myType + + var myType2: MyType2 + var c: MyType2 + c = (1.0, 2.0) + myType2 = c + echo myType2 + +main[int]() + diff --git a/tests/misc/tmandelbrot.nim b/tests/misc/tmandelbrot.nim new file mode 100644 index 000000000..1e39c8756 --- /dev/null +++ b/tests/misc/tmandelbrot.nim @@ -0,0 +1,57 @@ +discard """ + cmd: "nimrod cc --hints:on -d:release $# $#" +""" + +# -*- nimrod -*- + +import math +import os +import strutils + +type TComplex = tuple[re, im: float] + +proc `+` (a, b: TComplex): TComplex = + return (a.re + b.re, a.im + b.im) + +proc `*` (a, b: TComplex): TComplex = + result.re = a.re * b.re - a.im * b.im + result.im = a.re * b.im + a.im * b.re + +proc abs2 (a: TComplex): float = + return a.re * a.re + a.im * a.im + +var size = parseInt (paramStr (1)) +var bit = 128 +var byteAcc = 0 + +stdout.writeln ("P4") +stdout.write ($size) +stdout.write (" ") +stdout.writeln ($size) + +var fsize = float (size) +for y in 0 .. size-1: + var fy = 2.0 * float (y) / fsize - 1.0 + for x in 0 .. size-1: + var z = (0.0, 0.0) + var c = (float (2*x) / fsize - 1.5, fy) + + block iter: + for i in 0 .. 49: + z = z*z + c + if abs2 (z) >= 4.0: + break iter + byteAcc = byteAcc + bit + + if bit > 1: + bit = bit div 2 + else: + stdout.write (chr (byteAcc)) + bit = 128 + byteAcc = 0 + + if bit != 128: + stdout.write (chr (byteAcc)) + bit = 128 + byteAcc = 0 + diff --git a/tests/misc/tmemoization.nim b/tests/misc/tmemoization.nim new file mode 100644 index 000000000..180acd89b --- /dev/null +++ b/tests/misc/tmemoization.nim @@ -0,0 +1,17 @@ +discard """ + msg: "test 1\ntest 2\ntest 3" + output: "TEST 1\nTEST 2\nTEST 3" +""" + +import strutils + +proc foo(s: static[string]): string = + static: echo s + + const R = s.toUpper + return R + +echo foo("test 1") +echo foo("test 2") +echo foo("test " & $3) + diff --git a/tests/misc/tmissingnilcheck.nim b/tests/misc/tmissingnilcheck.nim new file mode 100644 index 000000000..c2f23ae87 --- /dev/null +++ b/tests/misc/tmissingnilcheck.nim @@ -0,0 +1,20 @@ +discard """ + disabled: true +""" + +type + PFutureBase = ref object + callback: proc () {.closure.} + +proc newConnection = + iterator newConnectionIter(): PFutureBase {.closure.} = + discard + var newConnectionIterVar = newConnectionIter + var first = newConnectionIterVar() + + proc cb {.closure.} = + discard + + first.callback = cb + +newConnection() diff --git a/tests/misc/tnew.nim b/tests/misc/tnew.nim new file mode 100644 index 000000000..6527541a2 --- /dev/null +++ b/tests/misc/tnew.nim @@ -0,0 +1,49 @@ +# Test the implementation of the new operator +# and the code generation for gc walkers +# (and the garbage collector): + +type + PNode = ref TNode + TNode = object + data: int + str: string + le, ri: PNode + + TStressTest = ref array [0..45, array [1..45, TNode]] + +proc finalizer(n: PNode) = + write(stdout, n.data) + write(stdout, " is now freed\n") + +proc newNode(data: int, le, ri: PNode): PNode = + new(result, finalizer) + result.le = le + result.ri = ri + result.data = data + +# now loop and build a tree +proc main() = + var + i = 0 + p: TStressTest + while i < 1000: + var n: PNode + + n = newNode(i, nil, newNode(i + 10000, nil, nil)) + inc(i) + new(p) + + write(stdout, "Simple tree node allocation worked!\n") + i = 0 + while i < 1000: + var m = newNode(i + 20000, nil, nil) + var k = newNode(i + 30000, nil, nil) + m.le = m + m.ri = k + k.le = m + k.ri = k + inc(i) + + write(stdout, "Simple cycle allocation worked!\n") + +main() diff --git a/tests/misc/tnewderef.nim b/tests/misc/tnewderef.nim new file mode 100644 index 000000000..89dc4c8d1 --- /dev/null +++ b/tests/misc/tnewderef.nim @@ -0,0 +1,11 @@ +discard """ + output: 3 + +""" + +var x: ref int +new(x) +x[] = 3 + +echo x[] + diff --git a/tests/misc/tnewlibs.nim b/tests/misc/tnewlibs.nim new file mode 100644 index 000000000..3b74a9b63 --- /dev/null +++ b/tests/misc/tnewlibs.nim @@ -0,0 +1,21 @@ +discard """ + disabled: true +""" + +# Test wether the bindings at least compile... + +import + tcl, + sdl, smpeg, sdl_gfx, sdl_net, sdl_mixer, sdl_ttf, + sdl_image, sdl_mixer_nosmpeg, + gtk2, glib2, pango, gdk2, + unicode, cgi, terminal, libcurl, + parsexml, parseopt, parsecfg, + osproc, + cairowin32, cairoxlib, + gl, glut, glu, glx, glext, wingl, + lua, lualib, lauxlib, mysql, sqlite3, db_mongo, md5, asyncio, mimetypes, + cookies, events, ftpclient, scgi, irc + + +writeln(stdout, "test compilation of binding modules") diff --git a/tests/misc/tnewsets.nim b/tests/misc/tnewsets.nim new file mode 100644 index 000000000..415fe8f7e --- /dev/null +++ b/tests/misc/tnewsets.nim @@ -0,0 +1,6 @@ +# new test for sets: + +const elem = ' ' + +var s: set[char] = {elem} +assert(elem in s and 'a' not_in s and 'c' not_in s ) diff --git a/tests/misc/tnewuns.nim b/tests/misc/tnewuns.nim new file mode 100644 index 000000000..5181e467c --- /dev/null +++ b/tests/misc/tnewuns.nim @@ -0,0 +1,12 @@ +# test the new unsigned operations: + +import + strutils + +var + x, y: int + +x = 1 +y = high(int) + +writeln(stdout, $ ( x +% y ) ) diff --git a/tests/misc/tnoforward.nim b/tests/misc/tnoforward.nim new file mode 100644 index 000000000..342e757b8 --- /dev/null +++ b/tests/misc/tnoforward.nim @@ -0,0 +1,14 @@ +discard """ + disabled: true +""" + +{. noforward: on .} + +proc foo(x: int) = + bar x + +proc bar(x: int) = + echo x + +foo(10) + diff --git a/tests/misc/tnoinst.nim b/tests/misc/tnoinst.nim new file mode 100644 index 000000000..db1058d09 --- /dev/null +++ b/tests/misc/tnoinst.nim @@ -0,0 +1,16 @@ +discard """ + line: 12 + errormsg: "instantiate 'notConcrete' explicitly" +""" + +proc wrap[T]() = + proc notConcrete[T](x, y: int): int = + var dummy: T + result = x - y + + var x: proc (x, y: T): int + x = notConcrete + + +wrap[int]() + diff --git a/tests/misc/tnolen.nim b/tests/misc/tnolen.nim new file mode 100644 index 000000000..dcf6811eb --- /dev/null +++ b/tests/misc/tnolen.nim @@ -0,0 +1,9 @@ +discard """ + line: 8 + errormsg: "type mismatch: got (int literal(3))" +""" + +# please finally disallow Len(3) + +echo len(3) + diff --git a/tests/misc/tnoop.nim b/tests/misc/tnoop.nim new file mode 100644 index 000000000..c79403e11 --- /dev/null +++ b/tests/misc/tnoop.nim @@ -0,0 +1,12 @@ +discard """ + file: "tnoop.nim" + line: 11 + errormsg: "expression \'a()\' cannot be called" +""" +# Tests the new check in the semantic pass + +var + a: int + +a() #ERROR_MSG expression 'a()' cannot be called + diff --git a/tests/misc/tnot.nim b/tests/misc/tnot.nim new file mode 100644 index 000000000..cd0f538e6 --- /dev/null +++ b/tests/misc/tnot.nim @@ -0,0 +1,22 @@ +discard """ + file: "tnot.nim" + line: 14 + errormsg: "type mismatch" +""" +# BUG: following compiles, but should not: + +proc nodeOfDegree(x: Int): bool = + result = false + +proc main = + for j in 0..2: + for i in 0..10: + if not nodeOfDegree(1) >= 0: #ERROR_MSG type mismatch + Echo "Yes" + else: + Echo "No" + +main() + + + diff --git a/tests/misc/tparedef.nim b/tests/misc/tparedef.nim new file mode 100644 index 000000000..dedebf6b7 --- /dev/null +++ b/tests/misc/tparedef.nim @@ -0,0 +1,4 @@ +# This test is now superfluous: + +proc a(a: int) = + return diff --git a/tests/misc/tpos.nim b/tests/misc/tpos.nim new file mode 100644 index 000000000..3d72536dd --- /dev/null +++ b/tests/misc/tpos.nim @@ -0,0 +1,35 @@ +discard """ + file: "tpos.nim" + output: "6" +""" +# test this particular function + +proc mypos(sub, s: string, start: int = 0): int = + var + i, j, M, N: int + M = sub.len + N = s.len + i = start + j = 0 + if i >= N: + result = -1 + else: + while True: + if s[i] == sub[j]: + Inc(i) + Inc(j) + else: + i = i - j + 1 + j = 0 + if (j >= M) or (i >= N): break + if j >= M: + result = i - M + else: + result = -1 + +var sub = "hello" +var s = "world hello" +write(stdout, mypos(sub, s)) +#OUT 6 + + diff --git a/tests/misc/tprep.nim b/tests/misc/tprep.nim new file mode 100644 index 000000000..4ef9e2543 --- /dev/null +++ b/tests/misc/tprep.nim @@ -0,0 +1,30 @@ +# Test the features that used to belong to the preprocessor + +import + times + +#{.warning: "This is only a test warning!".} + +const + case2 = true + case3 = true + +when defined(case1): + {.hint: "Case 1".} + when case3: + {.hint: "Case 1.3".} +elif case2: + {.hint: "Case 2".} + when case3: + {.hint: "Case 2.3".} +elif case3: + {.hint: "Case 3".} +else: + {.hint: "unknown case".} + +var + s: string +write(stdout, "compiled at " & system.compileDate & + " " & compileTime & "\n") +echo getDateStr() +echo getClockStr() diff --git a/tests/misc/tquicksort.nim b/tests/misc/tquicksort.nim new file mode 100644 index 000000000..6706a185e --- /dev/null +++ b/tests/misc/tquicksort.nim @@ -0,0 +1,26 @@ +proc QuickSort(list: seq[int]): seq[int] = + if len(list) == 0: + return @[] + var pivot = list[0] + var left: seq[int] = @[] + var right: seq[int] = @[] + for i in low(list)..high(list): + if list[i] < pivot: + left.add(list[i]) + elif list[i] > pivot: + right.add(list[i]) + result = QuickSort(left) & + pivot & + QuickSort(right) + +proc echoSeq(a: seq[int]) = + for i in low(a)..high(a): + echo(a[i]) + +var + list: seq[int] + +list = QuickSort(@[89,23,15,23,56,123,356,12,7,1,6,2,9,4,3]) +echoSeq(list) + + diff --git a/tests/misc/tradix.nim b/tests/misc/tradix.nim new file mode 100644 index 000000000..e5998ee12 --- /dev/null +++ b/tests/misc/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, inheritable.} = object + kind: TRadixNodeKind + TRadixNodeLinear = object of TRadixNode + len: int8 + keys: array [0..31, int8] + 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: int8 + keys: array [0..31, int8] + +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..ze(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..ze(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 contains*(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'i8 + 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..ze(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'i8 + 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/misc/trawstr.nim b/tests/misc/trawstr.nim new file mode 100644 index 000000000..ab2aae159 --- /dev/null +++ b/tests/misc/trawstr.nim @@ -0,0 +1,12 @@ +discard """ + file: "trawstr.nim" + line: 10 + errormsg: "closing \" expected" +""" +# Test the new raw strings: + +const + xxx = r"This is a raw string!" + yyy = "This not\" #ERROR + + diff --git a/tests/misc/treadln.nim b/tests/misc/treadln.nim new file mode 100644 index 000000000..1117ab5f9 --- /dev/null +++ b/tests/misc/treadln.nim @@ -0,0 +1,12 @@ +# test the improved readline handling that does not care whether its +# Macintosh, Unix or Windows text format. + +var + inp: TFile + line: string + +if open(inp, "readme.txt"): + while not EndOfFile(inp): + line = readLine(inp) + echo("#" & line & "#") + close(inp) diff --git a/tests/misc/treadx.nim b/tests/misc/treadx.nim new file mode 100644 index 000000000..49b6ad691 --- /dev/null +++ b/tests/misc/treadx.nim @@ -0,0 +1,14 @@ + +when not defined(windows): + import posix + + var inp = "" + var buf: array[0..10, char] + while true: + var r = read(0, addr(buf), sizeof(buf)-1) + add inp, $buf + if r != sizeof(buf)-1: break + + echo inp + #dafkladskölklödsaf ölksdakölfölksfklwe4iojr389wr 89uweokf sdlkf jweklr jweflksdj fioewjfsdlfsd + diff --git a/tests/misc/tromans.nim b/tests/misc/tromans.nim new file mode 100644 index 000000000..fa6a63595 --- /dev/null +++ b/tests/misc/tromans.nim @@ -0,0 +1,71 @@ +discard """ + file: "tromans.nim" + output: "success" +""" +import + strutils + +## Convert an integer to a Roman numeral +# See http://en.wikipedia.org/wiki/Roman_numerals for reference + +proc raiseInvalidValue(msg: string) {.noreturn.} = + # Yes, we really need a shorthand for this code... + var e: ref EInvalidValue + new(e) + e.msg = msg + raise e + +# I should use a class, perhaps. +# --> No. Why introduce additional state into such a simple and nice +# interface? State is evil. :D + +proc RomanToDecimal(romanVal: string): int = + result = 0 + var prevVal = 0 + for i in countdown(romanVal.len - 1, 0): + var val = 0 + case romanVal[i] + of 'I', 'i': val = 1 + of 'V', 'v': val = 5 + of 'X', 'x': val = 10 + of 'L', 'l': val = 50 + of 'C', 'c': val = 100 + of 'D', 'd': val = 500 + of 'M', 'm': val = 1000 + else: raiseInvalidValue("Incorrect character in roman numeral! (" & + $romanVal[i] & ")") + if val >= prevVal: + inc(result, val) + else: + dec(result, val) + prevVal = val + +proc DecimalToRoman(decValParam: int): string = + # Apparently numbers cannot be above 4000 + # Well, they can be (using overbar or parenthesis notation) + # but I see little interest (beside coding challenge) in coding them as + # we rarely use huge Roman numeral. + const romanComposites = [ + ("M", 1000), ("CM", 900), + ("D", 500), ("CD", 400), ("C", 100), + ("XC", 90), ("L", 50), ("XL", 40), ("X", 10), ("IX", 9), + ("V", 5), ("IV", 4), ("I", 1)] + if decValParam < 1 or decValParam > 3999: + raiseInvalidValue("number not representable") + result = "" + var decVal = decValParam + for key, val in items(romanComposites): + while decVal >= val: + dec(decVal, val) + result.add(key) + +for i in 1..100: + if RomanToDecimal(DecimalToRoman(i)) != i: quit "BUG" + +for i in items([1238, 1777, 3830, 2401, 379, 33, 940, 3973]): + if RomanToDecimal(DecimalToRoman(i)) != i: quit "BUG" + +echo "success" #OUT success + + + diff --git a/tests/misc/tshadow_magic_type.nim b/tests/misc/tshadow_magic_type.nim new file mode 100644 index 000000000..03c83079e --- /dev/null +++ b/tests/misc/tshadow_magic_type.nim @@ -0,0 +1,24 @@ +type + TListItemType* = enum + RedisNil, RedisString + + TListItem* = object + case kind*: TListItemType + of RedisString: + str*: string + else: nil + TRedisList* = seq[TListItem] + +# Caused by this. +proc seq*() = + discard + +proc lrange*(key: string): TRedisList = + var foo: TListItem + foo.kind = RedisNil + result = @[foo] + +when isMainModule: + var p = lrange("mylist") + for i in items(p): + echo(i.str) diff --git a/tests/misc/tsimplesort.nim b/tests/misc/tsimplesort.nim new file mode 100644 index 000000000..0167ca78a --- /dev/null +++ b/tests/misc/tsimplesort.nim @@ -0,0 +1,313 @@ +discard """ + output: '''true''' +""" + +import hashes, math + + +when defined(shallowADT): + {.pragma: myShallow, shallow.} +else: + {.pragma: myShallow.} + +type + TSlotEnum = enum seEmpty, seFilled, seDeleted + TKeyValuePair[A, B] = tuple[slot: TSlotEnum, key: A, val: B] + TKeyValuePairSeq[A, B] = seq[TKeyValuePair[A, B]] + TTable* {.final, myShallow.}[A, B] = object + data: TKeyValuePairSeq[A, B] + counter: int + +proc len*[A, B](t: TTable[A, B]): int = + ## returns the number of keys in `t`. + result = t.counter + +iterator pairs*[A, B](t: TTable[A, B]): tuple[key: A, val: B] = + ## iterates over any (key, value) pair in the table `t`. + for h in 0..high(t.data): + if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) + +iterator keys*[A, B](t: TTable[A, B]): A = + ## iterates over any key in the table `t`. + for h in 0..high(t.data): + if t.data[h].slot == seFilled: yield t.data[h].key + +iterator values*[A, B](t: TTable[A, B]): B = + ## iterates over any value in the table `t`. + for h in 0..high(t.data): + if t.data[h].slot == seFilled: yield t.data[h].val + +const + growthFactor = 2 + +proc mustRehash(length, counter: int): bool {.inline.} = + assert(length > counter) + result = (length * 2 < counter * 3) or (length - counter < 4) + +proc nextTry(h, maxHash: THash): THash {.inline.} = + result = ((5 * h) + 1) and maxHash + +template rawGetImpl() = + 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: + return h + h = nextTry(h, high(t.data)) + result = -1 + +template rawInsertImpl() = + var h: THash = hash(key) and high(data) + while data[h].slot == seFilled: + h = nextTry(h, high(data)) + data[h].key = key + data[h].val = val + data[h].slot = seFilled + +proc RawGet[A, B](t: TTable[A, B], key: A): int = + rawGetImpl() + +proc `[]`*[A, B](t: TTable[A, B], key: A): B = + ## retrieves the value at ``t[key]``. If `key` is not in `t`, + ## default empty value for the type `B` is returned + ## and no exception is raised. One can check with ``hasKey`` whether the key + ## exists. + var index = RawGet(t, key) + if index >= 0: result = t.data[index].val + +proc hasKey*[A, B](t: TTable[A, B], key: A): bool = + ## returns true iff `key` is in the table `t`. + result = rawGet(t, key) >= 0 + +proc RawInsert[A, B](t: var TTable[A, B], data: var TKeyValuePairSeq[A, B], + key: A, val: B) = + rawInsertImpl() + +proc Enlarge[A, B](t: var TTable[A, B]) = + var n: TKeyValuePairSeq[A, B] + newSeq(n, len(t.data) * growthFactor) + for i in countup(0, high(t.data)): + if t.data[i].slot == seFilled: RawInsert(t, n, t.data[i].key, t.data[i].val) + swap(t.data, n) + +template PutImpl() = + var index = RawGet(t, key) + if index >= 0: + t.data[index].val = val + else: + if mustRehash(len(t.data), t.counter): Enlarge(t) + RawInsert(t, t.data, key, val) + inc(t.counter) + +proc `[]=`*[A, B](t: var TTable[A, B], key: A, val: B) = + ## puts a (key, value)-pair into `t`. + putImpl() + +proc del*[A, B](t: var TTable[A, B], key: A) = + ## deletes `key` from hash table `t`. + var index = RawGet(t, key) + if index >= 0: + t.data[index].slot = seDeleted + dec(t.counter) + +proc initTable*[A, B](initialSize=64): TTable[A, B] = + ## creates a new hash table that is empty. `initialSize` needs to be + ## a power of two. + assert isPowerOfTwo(initialSize) + result.counter = 0 + newSeq(result.data, initialSize) + +proc toTable*[A, B](pairs: openarray[tuple[key: A, + val: B]]): TTable[A, B] = + ## creates a new hash table that contains the given `pairs`. + result = initTable[A, B](nextPowerOfTwo(pairs.len+10)) + for key, val in items(pairs): result[key] = val + +template dollarImpl(): stmt = + if t.len == 0: + result = "{:}" + else: + result = "{" + for key, val in pairs(t): + if result.len > 1: result.add(", ") + result.add($key) + result.add(": ") + result.add($val) + result.add("}") + +proc `$`*[A, B](t: TTable[A, B]): string = + ## The `$` operator for hash tables. + dollarImpl() + +# ------------------------------ count tables ------------------------------- + +type + TCountTable* {.final, myShallow.}[ + A] = object ## table that counts the number of each key + data: seq[tuple[key: A, val: int]] + counter: int + +proc len*[A](t: TCountTable[A]): int = + ## returns the number of keys in `t`. + result = t.counter + +iterator pairs*[A](t: TCountTable[A]): tuple[key: A, val: int] = + ## iterates over any (key, value) pair in the table `t`. + for h in 0..high(t.data): + if t.data[h].val != 0: yield (t.data[h].key, t.data[h].val) + +iterator keys*[A](t: TCountTable[A]): A = + ## iterates over any key in the table `t`. + for h in 0..high(t.data): + if t.data[h].val != 0: yield t.data[h].key + +iterator values*[A](t: TCountTable[A]): int = + ## iterates over any value in the table `t`. + for h in 0..high(t.data): + if t.data[h].val != 0: yield t.data[h].val + +proc RawGet[A](t: TCountTable[A], key: A): int = + var h: THash = hash(key) and high(t.data) # start with real hash value + while t.data[h].val != 0: + if t.data[h].key == key: return h + h = nextTry(h, high(t.data)) + result = -1 + +proc `[]`*[A](t: TCountTable[A], key: A): int = + ## retrieves the value at ``t[key]``. If `key` is not in `t`, + ## 0 is returned. One can check with ``hasKey`` whether the key + ## exists. + var index = RawGet(t, key) + if index >= 0: result = t.data[index].val + +proc hasKey*[A](t: TCountTable[A], key: A): bool = + ## returns true iff `key` is in the table `t`. + result = rawGet(t, key) >= 0 + +proc RawInsert[A](t: TCountTable[A], data: var seq[tuple[key: A, val: int]], + key: A, val: int) = + var h: THash = hash(key) and high(data) + while data[h].val != 0: h = nextTry(h, high(data)) + data[h].key = key + data[h].val = val + +proc Enlarge[A](t: var TCountTable[A]) = + var n: seq[tuple[key: A, val: int]] + newSeq(n, len(t.data) * growthFactor) + for i in countup(0, high(t.data)): + if t.data[i].val != 0: RawInsert(t, n, t.data[i].key, t.data[i].val) + swap(t.data, n) + +proc `[]=`*[A](t: var TCountTable[A], key: A, val: int) = + ## puts a (key, value)-pair into `t`. `val` has to be positive. + assert val > 0 + PutImpl() + +proc initCountTable*[A](initialSize=64): TCountTable[A] = + ## creates a new count table that is empty. `initialSize` needs to be + ## a power of two. + assert isPowerOfTwo(initialSize) + result.counter = 0 + newSeq(result.data, initialSize) + +proc toCountTable*[A](keys: openArray[A]): TCountTable[A] = + ## creates a new count table with every key in `keys` having a count of 1. + result = initCountTable[A](nextPowerOfTwo(keys.len+10)) + for key in items(keys): result[key] = 1 + +proc `$`*[A](t: TCountTable[A]): string = + ## The `$` operator for count tables. + dollarImpl() + +proc inc*[A](t: var TCountTable[A], key: A, val = 1) = + ## increments `t[key]` by `val`. + var index = RawGet(t, key) + if index >= 0: + inc(t.data[index].val, val) + else: + if mustRehash(len(t.data), t.counter): Enlarge(t) + RawInsert(t, t.data, key, val) + inc(t.counter) + +proc Smallest*[A](t: TCountTable[A]): tuple[key: A, val: int] = + ## returns the largest (key,val)-pair. Efficiency: O(n) + assert t.len > 0 + var minIdx = 0 + for h in 1..high(t.data): + if t.data[h].val > 0 and t.data[minIdx].val > t.data[h].val: minIdx = h + result.key = t.data[minIdx].key + result.val = t.data[minIdx].val + +proc Largest*[A](t: TCountTable[A]): tuple[key: A, val: int] = + ## returns the (key,val)-pair with the largest `val`. Efficiency: O(n) + assert t.len > 0 + var maxIdx = 0 + for h in 1..high(t.data): + if t.data[maxIdx].val < t.data[h].val: maxIdx = h + result.key = t.data[maxIdx].key + result.val = t.data[maxIdx].val + +proc sort*[A](t: var TCountTable[A]) = + ## sorts the count table so that the entry with the highest counter comes + ## first. This is destructive! You must not modify `t` afterwards! + ## You can use the iterators `pairs`, `keys`, and `values` to iterate over + ## `t` in the sorted order. + + # we use shellsort here; fast enough and simple + var h = 1 + while true: + h = 3 * h + 1 + if h >= high(t.data): break + while true: + h = h div 3 + for i in countup(h, high(t.data)): + var j = i + while t.data[j-h].val <= t.data[j].val: + var xyz = t.data[j] + t.data[j] = t.data[j-h] + t.data[j-h] = xyz + j = j-h + if j < h: break + if h == 1: break + + +const + data = { + "34": 123456, "12": 789, + "90": 343, "0": 34404, + "1": 344004, "2": 344774, + "3": 342244, "4": 3412344, + "5": 341232144, "6": 34214544, + "7": 3434544, "8": 344544, + "9": 34435644, "---00": 346677844, + "10": 34484, "11": 34474, "19": 34464, + "20": 34454, "30": 34141244, "40": 344114, + "50": 344490, "60": 344491, "70": 344492, + "80": 344497} + +proc countTableTest1 = + var s = initTable[string, int](64) + for key, val in items(data): s[key] = val + var w: tuple[key: string, val: int] #type(otherCountTable.data[0]) + + var t = initCountTable[string]() + for k, v in items(data): t.inc(k) + for k in t.keys: assert t[k] == 1 + t.inc("90", 3) + t.inc("12", 2) + t.inc("34", 1) + assert t.largest()[0] == "90" + t.sort() + + var i = 0 + for k, v in t.pairs: + case i + of 0: assert k == "90" and v == 4 + of 1: assert k == "12" and v == 3 + of 2: assert k == "34" and v == 2 + else: break + inc i + +countTableTest1() +echo true + + diff --git a/tests/misc/tsimtych.nim b/tests/misc/tsimtych.nim new file mode 100644 index 000000000..dd969958c --- /dev/null +++ b/tests/misc/tsimtych.nim @@ -0,0 +1,12 @@ +discard """ + file: "tsimtych.nim" + line: 10 + errormsg: "type mismatch: got (bool) but expected \'string\'" +""" +# Test 2 +# Simple type checking + +var a: string +a = false #ERROR + + diff --git a/tests/misc/tsizeof.nim b/tests/misc/tsizeof.nim new file mode 100644 index 000000000..f7b70dd4d --- /dev/null +++ b/tests/misc/tsizeof.nim @@ -0,0 +1,10 @@ +# Test the sizeof proc + +type + TMyRecord {.final.} = object + x, y: int + b: bool + r: float + s: string + +write(stdout, sizeof(TMyRecord)) diff --git a/tests/misc/tslices.nim b/tests/misc/tslices.nim new file mode 100644 index 000000000..0de1171e3 --- /dev/null +++ b/tests/misc/tslices.nim @@ -0,0 +1,59 @@ +discard """ + file: "tslices.nim" + output: '''456456 +456456 +456456 +Zugr5nd +egerichtetd +verichtetd +''' +""" + +# Test the new slices. + +import strutils + +var mystr = "Abgrund" +mystr[..1] = "Zu" + +mystr[4..4] = "5" + +type + TEnum = enum e1, e2, e3, e4, e5, e6 + +var myarr: array[TEnum, int] = [1, 2, 3, 4, 5, 6] +myarr[e1..e3] = myarr[e4..e6] +myarr[..e3] = myarr[e4..e6] + +for x in items(myarr): stdout.write(x) +echo() + +var myarr2: array[0..5, int] = [1, 2, 3, 4, 5, 6] +myarr2[0..2] = myarr2[3..5] + +for x in items(myarr2): stdout.write(x) +echo() + + +var myseq = @[1, 2, 3, 4, 5, 6] +myseq[0..2] = myseq[-3.. -1] + +for x in items(myseq): stdout.write(x) +echo() + +echo mystr + +mystr[4..4] = "u" + +# test full replacement +mystr[.. -2] = "egerichtet" + +echo mystr + +mystr[0..2] = "ve" +echo mystr + +var s = "abcdef" +s[1 .. -2] = "xyz" +assert s == "axyzf" + diff --git a/tests/misc/tsortdev.nim b/tests/misc/tsortdev.nim new file mode 100644 index 000000000..d7d42d22c --- /dev/null +++ b/tests/misc/tsortdev.nim @@ -0,0 +1,59 @@ +discard """ + output: "done" +""" + +import algorithm, strutils + +proc cmpPlatforms(a, b: string): int = + if a == b: return 0 + var dashes = a.split('-') + var dashes2 = b.split('-') + if dashes[0] == dashes2[0]: + if dashes[1] == dashes2[1]: return system.cmp(a,b) + case dashes[1] + of "x86": + return 1 + of "x86_64": + if dashes2[1] == "x86": return -1 + else: return 1 + of "ppc64": + if dashes2[1] == "x86" or dashes2[1] == "x86_64": return -1 + else: return 1 + else: + return system.cmp(dashes[1], dashes2[1]) + else: + case dashes[0] + of "linux": + return 1 + of "windows": + if dashes2[0] == "linux": return -1 + else: return 1 + of "macosx": + if dashes2[0] == "linux" or dashes2[0] == "windows": return -1 + else: return 1 + else: + if dashes2[0] == "linux" or dashes2[0] == "windows" or + dashes2[0] == "macosx": return -1 + else: + return system.cmp(a, b) + +proc sorted[T](a: openArray[T]): bool = + result = true + for i in 0 .. < a.high: + if cmpPlatforms(a[i], a[i+1]) > 0: + echo "Out of order: ", a[i], " ", a[i+1] + result = false + +proc main() = + var testData = @["netbsd-x86_64", "windows-x86", "linux-x86_64", "linux-x86", + "linux-ppc64", "macosx-x86-1058", "macosx-x86-1068"] + + sort(testData, cmpPlatforms) + + doAssert sorted(testData) + +for i in 0..1_000: + main() + +echo "done" + diff --git a/tests/misc/tstrace.nim b/tests/misc/tstrace.nim new file mode 100644 index 000000000..3032a34a3 --- /dev/null +++ b/tests/misc/tstrace.nim @@ -0,0 +1,16 @@ +# Test the new stacktraces (great for debugging!) + +{.push stack_trace: on.} + +proc recTest(i: int) = + # enter + if i < 10: + recTest(i+1) + else: # should printStackTrace() + var p: ptr int = nil + p[] = 12 + # leave + +{.pop.} + +recTest(0) diff --git a/tests/misc/tstrange.nim b/tests/misc/tstrange.nim new file mode 100644 index 000000000..3947755fc --- /dev/null +++ b/tests/misc/tstrange.nim @@ -0,0 +1,23 @@ +discard """ + file: "tstrange.nim" + output: "hallo4" +""" +# test for extremely strange bug + +proc ack(x: int, y: int): int = + if x != 0: + if y != 5: + return y + return x + return x+y + +proc gen[T](a: T) = + write(stdout, a) + + +gen("hallo") +write(stdout, ack(5, 4)) +#OUT hallo4 + + + diff --git a/tests/misc/tstrdesc.nim b/tests/misc/tstrdesc.nim new file mode 100644 index 000000000..1c2e85b4b --- /dev/null +++ b/tests/misc/tstrdesc.nim @@ -0,0 +1,14 @@ +var + x: array [0..2, int] + +x = [0, 1, 2] + +type + TStringDesc {.final.} = object + len, space: int # len and space without counting the terminating zero + data: array [0..0, char] # for the '\0' character + +var + emptyString {.exportc: "emptyString".}: TStringDesc + + diff --git a/tests/misc/tstrdist.nim b/tests/misc/tstrdist.nim new file mode 100644 index 000000000..3e1939e73 --- /dev/null +++ b/tests/misc/tstrdist.nim @@ -0,0 +1,26 @@ +# compute the edit distance between two strings + +proc editDistance(a, b: string): int = + var + c: seq[int] + n = a.len + m = b.len + newSeq(c, (n+1)*(m+1)) + for i in 0..n: + c[i*n] = i # [i,0] + for j in 0..m: + c[j] = j # [0,j] + + for i in 1..n: + for j in 1..m: + var x = c[(i-1)*n + j]+1 + var y = c[i*n + j-1]+1 + var z: int + if a[i-1] == b[j-1]: + z = c[(i-1)*n + j-1] + else: + z = c[(i-1)*n + j-1]+1 + c[(i-1)*n + (j-1)] = min(x,min(y,z)) + return c[n*m] + +write(stdout, editDistance("abc", "abd")) diff --git a/tests/misc/tvarious.nim b/tests/misc/tvarious.nim new file mode 100644 index 000000000..ed2964cf9 --- /dev/null +++ b/tests/misc/tvarious.nim @@ -0,0 +1,64 @@ +# Test various aspects + +# bug #572 +var a=12345678901'u64 + +var x = (x: 42, y: (a: 8, z: 10)) +echo x.y + +import + mvarious + +type + PA = ref TA + PB = ref TB + + TB = object + a: PA + + TA = object + b: TB + x: int + +proc getPA(): PA = + var + b: bool + b = not false + return nil + +# bug #501 +proc f(): int = 54 + +var + global: int + +var + s: string + i: int + r: TA + +r.b.a.x = 0 +global = global + 1 +exportme() +write(stdout, "Hallo wie heißt du? ") +write(stdout, getPA().x) +s = readLine(stdin) +i = 0 +while i < s.len: + if s[i] == 'c': write(stdout, "'c' in deinem Namen gefunden\n") + i = i + 1 + +write(stdout, "Du heißt " & s) + +# bug #544 +when false: + # yay, fails again + type Bar [T; I:range] = array[I, T] + proc foo*[T; I:range](a, b: Bar[T, I]): Bar[T, I] = + when len(a) != 3: + # Error: constant expression expected + {.fatal:"Dimensions have to be 3".} + #... + block: + var a, b: Bar[int, 0..2] + discard foo(a, b) diff --git a/tests/misc/tvarious1.nim b/tests/misc/tvarious1.nim new file mode 100644 index 000000000..6e4612ae3 --- /dev/null +++ b/tests/misc/tvarious1.nim @@ -0,0 +1,41 @@ +discard """ + file: "tlenopenarray.nim" + output: '''1 +0 +Whopie +12''' +""" + +echo len([1_000_000]) #OUT 1 + +type + TArray = array[0..3, int] + TVector = distinct array[0..3, int] +proc `[]`(v: TVector; idx: int): int = TArray(v)[idx] +var v: TVector +echo v[2] + +# bug #569 + +import queues + +type + TWidget = object + names: TQueue[string] + +var w = TWidget(names: initQueue[string]()) + +add(w.names, "Whopie") + +for n in w.names: echo(n) + +# bug #681 + +type TSomeRange = object + hour: range[0..23] + +var value: string +var val12 = TSomeRange(hour: 12) + +value = $(if val12.hour > 12: val12.hour - 12 else: val12.hour) +echo value diff --git a/tests/misc/tvarnums.nim b/tests/misc/tvarnums.nim new file mode 100644 index 000000000..4f99df8b9 --- /dev/null +++ b/tests/misc/tvarnums.nim @@ -0,0 +1,142 @@ +discard """ + file: "tvarnums.nim" + output: "Success!" +""" +# Test variable length binary integers + +import + strutils + +type + TBuffer = array [0..10, int8] + +proc toVarNum(x: int32, b: var TBuffer) = + # encoding: first bit indicates end of number (0 if at end) + # second bit of the first byte denotes the sign (1 --> negative) + var a = x + if x != low(x): + # low(int) is a special case, + # because abs() does not work here! + # we leave x as it is and use the check >% instead of > + # for low(int) this is needed and positive numbers are not affected + # anyway + a = abs(x) + # first 6 bits: + b[0] = toU8(ord(a >% 63'i32) shl 7 or (ord(x < 0'i32) shl 6) or (int(a) and 63)) + a = a shr 6'i32 # skip first 6 bits + var i = 1 + while a != 0'i32: + b[i] = toU8(ord(a >% 127'i32) shl 7 or (int(a) and 127)) + inc(i) + a = a shr 7'i32 + +proc toVarNum64(x: int64, b: var TBuffer) = + # encoding: first bit indicates end of number (0 if at end) + # second bit of the first byte denotes the sign (1 --> negative) + var a = x + if x != low(x): + # low(int) is a special case, + # because abs() does not work here! + # we leave x as it is and use the check >% instead of > + # for low(int) this is needed and positive numbers are not affected + # anyway + a = abs(x) + # first 6 bits: + b[0] = toU8(ord(a >% 63'i64) shl 7 or (ord(x < 0'i64) shl 6) or int(a and 63)) + a = a shr 6 # skip first 6 bits + var i = 1 + while a != 0'i64: + b[i] = toU8(ord(a >% 127'i64) shl 7 or int(a and 127)) + inc(i) + a = a shr 7 + +proc toNum64(b: TBuffer): int64 = + # treat first byte different: + result = ze64(b[0]) and 63 + var + i = 0 + Shift = 6'i64 + while (ze(b[i]) and 128) != 0: + inc(i) + result = result or ((ze64(b[i]) and 127) shl Shift) + inc(Shift, 7) + if (ze(b[0]) and 64) != 0: # sign bit set? + result = not result +% 1 + # this is the same as ``- result`` + # but gives no overflow error for low(int) + +proc toNum(b: TBuffer): int32 = + # treat first byte different: + result = ze(b[0]) and 63 + var + i = 0 + Shift = 6'i32 + while (ze(b[i]) and 128) != 0: + inc(i) + result = result or ((int32(ze(b[i])) and 127'i32) shl Shift) + Shift = shift + 7'i32 + if (ze(b[0]) and (1 shl 6)) != 0: # sign bit set? + result = (not result) +% 1'i32 + # this is the same as ``- result`` + # but gives no overflow error for low(int) + +proc toBinary(x: int64): string = + result = newString(64) + for i in 0..63: + result[63-i] = chr((int(x shr i) and 1) + ord('0')) + +proc t64(i: int64) = + var + b: TBuffer + toVarNum64(i, b) + var x = toNum64(b) + if x != i: + writeln(stdout, $i) + writeln(stdout, toBinary(i)) + writeln(stdout, toBinary(x)) + +proc t32(i: int32) = + var + b: TBuffer + toVarNum(i, b) + var x = toNum(b) + if x != i: + writeln(stdout, toBinary(i)) + writeln(stdout, toBinary(x)) + +proc tm(i: int32) = + var + b: TBuffer + toVarNum64(i, b) + var x = toNum(b) + if x != i: + writeln(stdout, toBinary(i)) + writeln(stdout, toBinary(x)) + +t32(0) +t32(1) +t32(-1) +t32(-100_000) +t32(100_000) +t32(low(int32)) +t32(high(int32)) + +t64(low(int64)) +t64(high(int64)) +t64(0) +t64(-1) +t64(1) +t64(1000_000) +t64(-1000_000) + +tm(0) +tm(1) +tm(-1) +tm(-100_000) +tm(100_000) +tm(low(int32)) +tm(high(int32)) + +writeln(stdout, "Success!") #OUT Success! + + |