mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-08 14:03:23 +00:00
Merge pull request #1075 from flaviut/inlinedocs
Add some documentations and code examples in system
This commit is contained in:
1
bin/empty.txt
Normal file
1
bin/empty.txt
Normal file
@@ -0,0 +1 @@
|
||||
This file keeps several tools from deleting this subdirectory.
|
||||
1
build/empty.txt
Normal file
1
build/empty.txt
Normal file
@@ -0,0 +1 @@
|
||||
This file keeps several tools from deleting this subdirectory.
|
||||
120
lib/system.nim
120
lib/system.nim
@@ -302,7 +302,7 @@ type
|
||||
## value does not fit.
|
||||
|
||||
EOutOfRange* = object of ESynch ## is raised if a range check error
|
||||
## occured.
|
||||
## occurred.
|
||||
|
||||
EStackOverflow* = object of ESystem ## is raised if the hardware stack
|
||||
## used for subroutine calls overflowed.
|
||||
@@ -534,6 +534,10 @@ proc `div` *(x, y: int32): int32 {.magic: "DivI", noSideEffect.}
|
||||
proc `div` *(x, y: int64): int64 {.magic: "DivI64", noSideEffect.}
|
||||
## computes the integer division. This is roughly the same as
|
||||
## ``floor(x/y)``.
|
||||
## .. code-block:: Nimrod
|
||||
## 1 div 2 == 0
|
||||
## 2 div 2 == 1
|
||||
## 3 div 2 == 1
|
||||
|
||||
proc `mod` *(x, y: int): int {.magic: "ModI", noSideEffect.}
|
||||
proc `mod` *(x, y: int8): int8 {.magic: "ModI", noSideEffect.}
|
||||
@@ -549,6 +553,10 @@ proc `shr` *(x, y: int16): int16 {.magic: "ShrI", noSideEffect.}
|
||||
proc `shr` *(x, y: int32): int32 {.magic: "ShrI", noSideEffect.}
|
||||
proc `shr` *(x, y: int64): int64 {.magic: "ShrI64", noSideEffect.}
|
||||
## computes the `shift right` operation of `x` and `y`.
|
||||
## .. code-block:: Nimrod
|
||||
## 0b0001_0000'i8 shr 2 == 0b0100_0000'i8
|
||||
## 0b1000_0000'i8 shr 2 == 0b0000_0000'i8
|
||||
## 0b0000_0001'i8 shr 9 == 0b0000_0000'i8
|
||||
|
||||
proc `shl` *(x, y: int): int {.magic: "ShlI", noSideEffect.}
|
||||
proc `shl` *(x, y: int8): int8 {.magic: "ShlI", noSideEffect.}
|
||||
@@ -741,15 +749,49 @@ proc contains*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.}
|
||||
## passes its arguments in reverse order.
|
||||
|
||||
proc contains*[T](s: TSlice[T], value: T): bool {.noSideEffect, inline.} =
|
||||
## Checks if `value` is withing the range of `s`; returns true iff
|
||||
## `value >= s.a and value <= s.b`
|
||||
##
|
||||
## .. code-block:: Nimrod
|
||||
## assert((1..3).contains(1) == true)
|
||||
## assert((1..3).contains(2) == true)
|
||||
## assert((1..3).contains(4) == false)
|
||||
result = s.a <= value and value <= s.b
|
||||
|
||||
template `in` * (x, y: expr): expr {.immediate.} = contains(y, x)
|
||||
## Suger for contains
|
||||
##
|
||||
## .. code-block:: Nimrod
|
||||
## assert(1 in (1..3) == true)
|
||||
## assert(5 in (1..3) == false)
|
||||
template `notin` * (x, y: expr): expr {.immediate.} = not contains(y, x)
|
||||
## Sugar for not containing
|
||||
##
|
||||
## .. code-block:: Nimrod
|
||||
## assert(1 notin (1..3) == false)
|
||||
## assert(5 notin (1..3) == true)
|
||||
|
||||
proc `is` *[T, S](x: T, y: S): bool {.magic: "Is", noSideEffect.}
|
||||
## Checks if T is of the same type as S
|
||||
##
|
||||
## .. code-block:: Nimrod
|
||||
## proc test[T](a: T): int =
|
||||
## when (T is int):
|
||||
## return a
|
||||
## else:
|
||||
## return 0
|
||||
##
|
||||
## assert(test[int](3) == 3)
|
||||
## assert(test[string]("xyz") == 0)
|
||||
template `isnot` *(x, y: expr): expr {.immediate.} = not (x is y)
|
||||
|
||||
## Negated version of `is`. Equivalent to `not(is(x,y))`
|
||||
proc `of` *[T, S](x: T, y: S): bool {.magic: "Of", noSideEffect.}
|
||||
## Checks if `x` has a type of `y`
|
||||
##
|
||||
## .. code-block:: Nimrod
|
||||
## assert(EFloatingPoint is EBase)
|
||||
## assert(EIO is ESystem)
|
||||
## assert(EDivByZero is EBase)
|
||||
|
||||
proc cmp*[T](x, y: T): int {.procvar.} =
|
||||
## Generic compare proc. Returns a value < 0 iff x < y, a value > 0 iff x > y
|
||||
@@ -800,19 +842,48 @@ proc newStringOfCap*(cap: int): string {.
|
||||
|
||||
proc `&` * (x: string, y: char): string {.
|
||||
magic: "ConStrStr", noSideEffect, merge.}
|
||||
## Concatenates `x` with `y`
|
||||
##
|
||||
## .. code-block:: Nimrod
|
||||
## assert("ab" & 'c' == "abc")
|
||||
proc `&` * (x: char, y: char): string {.
|
||||
magic: "ConStrStr", noSideEffect, merge.}
|
||||
## Concatenates `x` and `y` into a string
|
||||
##
|
||||
## .. code-block:: Nimrod
|
||||
## assert('a' & 'b' == "ab")
|
||||
proc `&` * (x, y: string): string {.
|
||||
magic: "ConStrStr", noSideEffect, merge.}
|
||||
## Concatenates `x` and `y`
|
||||
##
|
||||
## .. code-block:: Nimrod
|
||||
## assert("ab" & "cd" == "abcd")
|
||||
proc `&` * (x: char, y: string): string {.
|
||||
magic: "ConStrStr", noSideEffect, merge.}
|
||||
## is the `concatenation operator`. It concatenates `x` and `y`.
|
||||
## Concatenates `x` with `y`
|
||||
##
|
||||
## .. code-block:: Nimrod
|
||||
## assert('a' & "bc" == "abc")
|
||||
|
||||
# implementation note: These must all have the same magic value "ConStrStr" so
|
||||
# that the merge optimization works properly.
|
||||
|
||||
proc add*(x: var string, y: char) {.magic: "AppendStrCh", noSideEffect.}
|
||||
## Appends `y` to `x` in place
|
||||
##
|
||||
## .. code-block:: Nimrod
|
||||
## var tmp = ""
|
||||
## tmp.add('a')
|
||||
## tmp.add('b')
|
||||
## assert(tmp == "ab")
|
||||
proc add*(x: var string, y: string) {.magic: "AppendStrStr", noSideEffect.}
|
||||
## Concatenates `x` and `y` in place
|
||||
##
|
||||
## .. code-block:: Nimrod
|
||||
## var tmp = ""
|
||||
## tmp.add("ab")
|
||||
## tmp.add("cd")
|
||||
## assert(tmp == "abcd")
|
||||
|
||||
type
|
||||
TEndian* = enum ## is a type describing the endianness of a processor.
|
||||
@@ -922,9 +993,9 @@ const
|
||||
## failure.
|
||||
|
||||
var programResult* {.exportc: "nim_program_result".}: int
|
||||
## modify this varialbe to specify the exit code of the program
|
||||
## modify this variable to specify the exit code of the program
|
||||
## under normal circumstances. When the program is terminated
|
||||
## prematurelly using ``quit``, this value is ignored.
|
||||
## prematurely using ``quit``, this value is ignored.
|
||||
|
||||
proc quit*(errorcode: int = QuitSuccess) {.
|
||||
magic: "Exit", importc: "exit", header: "<stdlib.h>", noReturn.}
|
||||
@@ -1281,42 +1352,42 @@ template `>%` *(x, y: expr): expr {.immediate.} = y <% x
|
||||
## Returns true iff ``unsigned(x) > unsigned(y)``.
|
||||
|
||||
proc `$` *(x: int): string {.magic: "IntToStr", noSideEffect.}
|
||||
## The stingify operator for an integer argument. Returns `x`
|
||||
## The stringify operator for an integer argument. Returns `x`
|
||||
## converted to a decimal string.
|
||||
|
||||
proc `$` *(x: int64): string {.magic: "Int64ToStr", noSideEffect.}
|
||||
## The stingify operator for an integer argument. Returns `x`
|
||||
## The stringify operator for an integer argument. Returns `x`
|
||||
## converted to a decimal string.
|
||||
|
||||
when not defined(NimrodVM):
|
||||
when not defined(JS) and hostOS != "standalone":
|
||||
proc `$` *(x: uint64): string {.noSideEffect.}
|
||||
## The stingify operator for an unsigned integer argument. Returns `x`
|
||||
## The stringify operator for an unsigned integer argument. Returns `x`
|
||||
## converted to a decimal string.
|
||||
|
||||
proc `$` *(x: float): string {.magic: "FloatToStr", noSideEffect.}
|
||||
## The stingify operator for a float argument. Returns `x`
|
||||
## The stringify operator for a float argument. Returns `x`
|
||||
## converted to a decimal string.
|
||||
|
||||
proc `$` *(x: bool): string {.magic: "BoolToStr", noSideEffect.}
|
||||
## The stingify operator for a boolean argument. Returns `x`
|
||||
## The stringify operator for a boolean argument. Returns `x`
|
||||
## converted to the string "false" or "true".
|
||||
|
||||
proc `$` *(x: char): string {.magic: "CharToStr", noSideEffect.}
|
||||
## The stingify operator for a character argument. Returns `x`
|
||||
## The stringify operator for a character argument. Returns `x`
|
||||
## converted to a string.
|
||||
|
||||
proc `$` *(x: cstring): string {.magic: "CStrToStr", noSideEffect.}
|
||||
## The stingify operator for a CString argument. Returns `x`
|
||||
## The stringify operator for a CString argument. Returns `x`
|
||||
## converted to a string.
|
||||
|
||||
proc `$` *(x: string): string {.magic: "StrToStr", noSideEffect.}
|
||||
## The stingify operator for a string argument. Returns `x`
|
||||
## The stringify operator for a string argument. Returns `x`
|
||||
## as it is. This operator is useful for generic code, so
|
||||
## that ``$expr`` also works if ``expr`` is already a string.
|
||||
|
||||
proc `$` *[TEnum: enum](x: TEnum): string {.magic: "EnumToStr", noSideEffect.}
|
||||
## The stingify operator for an enumeration argument. This works for
|
||||
## The stringify operator for an enumeration argument. This works for
|
||||
## any enumeration type thanks to compiler magic. If
|
||||
## a ``$`` operator for a concrete enumeration is provided, this is
|
||||
## used instead. (In other words: *Overwriting* is possible.)
|
||||
@@ -1436,7 +1507,11 @@ proc max*(x, y: float): float {.magic: "MaxF64", noSideEffect.} =
|
||||
{.pop.}
|
||||
|
||||
proc clamp*[T](x, a, b: T): T =
|
||||
## limits the value ``x`` within the interval [a, b]
|
||||
## limits the value ``x`` within the interval [a, b]
|
||||
##
|
||||
## .. code-block:: Nimrod
|
||||
## assert((1.4).clamp(0.0, 1.0) == 1.0)
|
||||
## assert((0.5).clamp(0.0, 1.0) == 0.5)
|
||||
if x < a: return a
|
||||
if x > b: return b
|
||||
return x
|
||||
@@ -1535,6 +1610,11 @@ proc `@`*[T](a: openArray[T]): seq[T] =
|
||||
for i in 0..a.len-1: result[i] = a[i]
|
||||
|
||||
proc `&` *[T](x, y: seq[T]): seq[T] {.noSideEffect.} =
|
||||
## Concatenates two sequences.
|
||||
## Requires copying of the sequences.
|
||||
##
|
||||
## .. code-block:: Nimrod
|
||||
## assert(@[1, 2, 3, 4] & @[5, 6] == @[1, 2, 3, 4, 5, 6])
|
||||
newSeq(result, x.len + y.len)
|
||||
for i in 0..x.len-1:
|
||||
result[i] = x[i]
|
||||
@@ -1542,12 +1622,22 @@ proc `&` *[T](x, y: seq[T]): seq[T] {.noSideEffect.} =
|
||||
result[i+x.len] = y[i]
|
||||
|
||||
proc `&` *[T](x: seq[T], y: T): seq[T] {.noSideEffect.} =
|
||||
## Appends element y to the end of the sequence.
|
||||
## Requires copying of the sequence
|
||||
##
|
||||
## .. code-block:: Nimrod
|
||||
## assert(@[1, 2, 3] & 4 == @[1, 2, 3, 4])
|
||||
newSeq(result, x.len + 1)
|
||||
for i in 0..x.len-1:
|
||||
result[i] = x[i]
|
||||
result[x.len] = y
|
||||
|
||||
proc `&` *[T](x: T, y: seq[T]): seq[T] {.noSideEffect.} =
|
||||
## Prepends the element x to the beginning of the sequence.
|
||||
## Requires copying of the sequence
|
||||
##
|
||||
## .. code-block:: Nimrod
|
||||
## assert(1 & @[2, 3, 4] == @[1, 2, 3, 4])
|
||||
newSeq(result, y.len + 1)
|
||||
result[0] = x
|
||||
for i in 0..y.len-1:
|
||||
|
||||
1
tests/misc/99bottles.nim
Normal file
1
tests/misc/99bottles.nim
Normal file
@@ -0,0 +1 @@
|
||||
# Test if the compiler detects invalid module names
|
||||
2
tests/misc/minit.nim
Normal file
2
tests/misc/minit.nim
Normal file
@@ -0,0 +1,2 @@
|
||||
# Test the new initialization for modules
|
||||
write(stdout, "Hello from module! ")
|
||||
6
tests/misc/mvarious.nim
Normal file
6
tests/misc/mvarious.nim
Normal file
@@ -0,0 +1,6 @@
|
||||
# Test a submodule
|
||||
|
||||
#type
|
||||
# TStringArr = array [0.. *] of string
|
||||
|
||||
proc exportme* = discard
|
||||
36
tests/misc/t99bott.nim
Normal file
36
tests/misc/t99bott.nim
Normal file
@@ -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."
|
||||
|
||||
|
||||
|
||||
|
||||
21
tests/misc/tack.nim
Normal file
21
tests/misc/tack.nim
Normal file
@@ -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
|
||||
|
||||
|
||||
12
tests/misc/tatomic.nim
Normal file
12
tests/misc/tatomic.nim
Normal file
@@ -0,0 +1,12 @@
|
||||
discard """
|
||||
file: "tatomic.nim"
|
||||
line: 7
|
||||
errormsg: "identifier expected, but found 'keyword atomic'"
|
||||
"""
|
||||
var
|
||||
atomic: int
|
||||
|
||||
echo atomic
|
||||
|
||||
|
||||
|
||||
16
tests/misc/tbug511622.nim
Normal file
16
tests/misc/tbug511622.nim
Normal file
@@ -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
|
||||
|
||||
|
||||
|
||||
14
tests/misc/tcmdline.nim
Normal file
14
tests/misc/tcmdline.nim
Normal file
@@ -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
|
||||
12
tests/misc/tcolonisproc.nim
Normal file
12
tests/misc/tcolonisproc.nim
Normal file
@@ -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)
|
||||
16
tests/misc/tdllvar.nim
Normal file
16
tests/misc/tdllvar.nim
Normal file
@@ -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)
|
||||
|
||||
|
||||
20
tests/misc/temit.nim
Normal file
20
tests/misc/temit.nim
Normal file
@@ -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()
|
||||
|
||||
|
||||
|
||||
|
||||
2
tests/misc/temptyecho.nim
Normal file
2
tests/misc/temptyecho.nim
Normal file
@@ -0,0 +1,2 @@
|
||||
echo()
|
||||
|
||||
3
tests/misc/tendian.nim
Normal file
3
tests/misc/tendian.nim
Normal file
@@ -0,0 +1,3 @@
|
||||
# test the new endian magic
|
||||
|
||||
writeln(stdout, repr(system.cpuEndian))
|
||||
33
tests/misc/teventemitter.nim
Normal file
33
tests/misc/teventemitter.nim
Normal file
@@ -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)
|
||||
|
||||
48
tests/misc/tevents.nim
Normal file
48
tests/misc/tevents.nim
Normal file
@@ -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)
|
||||
|
||||
11
tests/misc/tfib.nim
Normal file
11
tests/misc/tfib.nim
Normal file
@@ -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
|
||||
|
||||
|
||||
41
tests/misc/tfilter.nim
Normal file
41
tests/misc/tfilter.nim
Normal file
@@ -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)
|
||||
|
||||
32
tests/misc/tgenconstraints.nim
Normal file
32
tests/misc/tgenconstraints.nim
Normal file
@@ -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
|
||||
|
||||
7
tests/misc/tgetstartmilsecs.nim
Normal file
7
tests/misc/tgetstartmilsecs.nim
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
import times, os
|
||||
|
||||
var start = epochTime()
|
||||
os.sleep(1000)
|
||||
|
||||
echo epochTime() - start #OUT 1000
|
||||
51
tests/misc/tgtk.nim
Normal file
51
tests/misc/tgtk.nim
Normal file
@@ -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()
|
||||
85
tests/misc/thallo.nim
Normal file
85
tests/misc/thallo.nim
Normal file
@@ -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".}
|
||||
|
||||
71
tests/misc/theaproots.nim
Normal file
71
tests/misc/theaproots.nim
Normal file
@@ -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)
|
||||
12
tests/misc/thintoff.nim
Normal file
12
tests/misc/thintoff.nim
Normal file
@@ -0,0 +1,12 @@
|
||||
discard """
|
||||
file: "thintoff.nim"
|
||||
output: "0"
|
||||
"""
|
||||
|
||||
{.hint[XDeclaredButNotUsed]: off.}
|
||||
var
|
||||
x: int
|
||||
|
||||
echo x #OUT 0
|
||||
|
||||
|
||||
12
tests/misc/tinc.nim
Normal file
12
tests/misc/tinc.nim
Normal file
@@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
12
tests/misc/tinit.nim
Normal file
12
tests/misc/tinit.nim
Normal file
@@ -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!
|
||||
|
||||
|
||||
16
tests/misc/tinout.nim
Normal file
16
tests/misc/tinout.nim
Normal file
@@ -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()
|
||||
|
||||
|
||||
45
tests/misc/tints.nim
Normal file
45
tests/misc/tints.nim
Normal file
@@ -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
|
||||
|
||||
14
tests/misc/tinvalidarrayaccess.nim
Normal file
14
tests/misc/tinvalidarrayaccess.nim
Normal file
@@ -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))
|
||||
27
tests/misc/tinvalidnewseq.nim
Normal file
27
tests/misc/tinvalidnewseq.nim
Normal file
@@ -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)
|
||||
|
||||
|
||||
|
||||
18
tests/misc/tlastmod.nim
Normal file
18
tests/misc/tlastmod.nim
Normal file
@@ -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()
|
||||
28
tests/misc/tlibs.nim
Normal file
28
tests/misc/tlibs.nim
Normal file
@@ -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")
|
||||
11
tests/misc/tlocals.nim
Normal file
11
tests/misc/tlocals.nim
Normal file
@@ -0,0 +1,11 @@
|
||||
discard """
|
||||
output: "(x: string here, a: 1)"
|
||||
"""
|
||||
|
||||
proc simple[T](a: T) =
|
||||
var
|
||||
x = "string here"
|
||||
echo locals()
|
||||
|
||||
simple(1)
|
||||
|
||||
87
tests/misc/tloops.nim
Normal file
87
tests/misc/tloops.nim
Normal file
@@ -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]()
|
||||
|
||||
57
tests/misc/tmandelbrot.nim
Normal file
57
tests/misc/tmandelbrot.nim
Normal file
@@ -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
|
||||
|
||||
17
tests/misc/tmemoization.nim
Normal file
17
tests/misc/tmemoization.nim
Normal file
@@ -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)
|
||||
|
||||
20
tests/misc/tmissingnilcheck.nim
Normal file
20
tests/misc/tmissingnilcheck.nim
Normal file
@@ -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()
|
||||
49
tests/misc/tnew.nim
Normal file
49
tests/misc/tnew.nim
Normal file
@@ -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()
|
||||
11
tests/misc/tnewderef.nim
Normal file
11
tests/misc/tnewderef.nim
Normal file
@@ -0,0 +1,11 @@
|
||||
discard """
|
||||
output: 3
|
||||
|
||||
"""
|
||||
|
||||
var x: ref int
|
||||
new(x)
|
||||
x[] = 3
|
||||
|
||||
echo x[]
|
||||
|
||||
21
tests/misc/tnewlibs.nim
Normal file
21
tests/misc/tnewlibs.nim
Normal file
@@ -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")
|
||||
6
tests/misc/tnewsets.nim
Normal file
6
tests/misc/tnewsets.nim
Normal file
@@ -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 )
|
||||
12
tests/misc/tnewuns.nim
Normal file
12
tests/misc/tnewuns.nim
Normal file
@@ -0,0 +1,12 @@
|
||||
# test the new unsigned operations:
|
||||
|
||||
import
|
||||
strutils
|
||||
|
||||
var
|
||||
x, y: int
|
||||
|
||||
x = 1
|
||||
y = high(int)
|
||||
|
||||
writeln(stdout, $ ( x +% y ) )
|
||||
14
tests/misc/tnoforward.nim
Normal file
14
tests/misc/tnoforward.nim
Normal file
@@ -0,0 +1,14 @@
|
||||
discard """
|
||||
disabled: true
|
||||
"""
|
||||
|
||||
{. noforward: on .}
|
||||
|
||||
proc foo(x: int) =
|
||||
bar x
|
||||
|
||||
proc bar(x: int) =
|
||||
echo x
|
||||
|
||||
foo(10)
|
||||
|
||||
16
tests/misc/tnoinst.nim
Normal file
16
tests/misc/tnoinst.nim
Normal file
@@ -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]()
|
||||
|
||||
9
tests/misc/tnolen.nim
Normal file
9
tests/misc/tnolen.nim
Normal file
@@ -0,0 +1,9 @@
|
||||
discard """
|
||||
line: 8
|
||||
errormsg: "type mismatch: got (int literal(3))"
|
||||
"""
|
||||
|
||||
# please finally disallow Len(3)
|
||||
|
||||
echo len(3)
|
||||
|
||||
12
tests/misc/tnoop.nim
Normal file
12
tests/misc/tnoop.nim
Normal file
@@ -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
|
||||
|
||||
22
tests/misc/tnot.nim
Normal file
22
tests/misc/tnot.nim
Normal file
@@ -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()
|
||||
|
||||
|
||||
|
||||
4
tests/misc/tparedef.nim
Normal file
4
tests/misc/tparedef.nim
Normal file
@@ -0,0 +1,4 @@
|
||||
# This test is now superfluous:
|
||||
|
||||
proc a(a: int) =
|
||||
return
|
||||
35
tests/misc/tpos.nim
Normal file
35
tests/misc/tpos.nim
Normal file
@@ -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
|
||||
|
||||
|
||||
30
tests/misc/tprep.nim
Normal file
30
tests/misc/tprep.nim
Normal file
@@ -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()
|
||||
26
tests/misc/tquicksort.nim
Normal file
26
tests/misc/tquicksort.nim
Normal file
@@ -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)
|
||||
|
||||
|
||||
319
tests/misc/tradix.nim
Normal file
319
tests/misc/tradix.nim
Normal file
@@ -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
|
||||
12
tests/misc/trawstr.nim
Normal file
12
tests/misc/trawstr.nim
Normal file
@@ -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
|
||||
|
||||
|
||||
12
tests/misc/treadln.nim
Normal file
12
tests/misc/treadln.nim
Normal file
@@ -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)
|
||||
14
tests/misc/treadx.nim
Normal file
14
tests/misc/treadx.nim
Normal file
@@ -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
|
||||
|
||||
71
tests/misc/tromans.nim
Normal file
71
tests/misc/tromans.nim
Normal file
@@ -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
|
||||
|
||||
|
||||
|
||||
24
tests/misc/tshadow_magic_type.nim
Normal file
24
tests/misc/tshadow_magic_type.nim
Normal file
@@ -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)
|
||||
313
tests/misc/tsimplesort.nim
Normal file
313
tests/misc/tsimplesort.nim
Normal file
@@ -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
|
||||
|
||||
|
||||
12
tests/misc/tsimtych.nim
Normal file
12
tests/misc/tsimtych.nim
Normal file
@@ -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
|
||||
|
||||
|
||||
10
tests/misc/tsizeof.nim
Normal file
10
tests/misc/tsizeof.nim
Normal file
@@ -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))
|
||||
59
tests/misc/tslices.nim
Normal file
59
tests/misc/tslices.nim
Normal file
@@ -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"
|
||||
|
||||
59
tests/misc/tsortdev.nim
Normal file
59
tests/misc/tsortdev.nim
Normal file
@@ -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"
|
||||
|
||||
16
tests/misc/tstrace.nim
Normal file
16
tests/misc/tstrace.nim
Normal file
@@ -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)
|
||||
23
tests/misc/tstrange.nim
Normal file
23
tests/misc/tstrange.nim
Normal file
@@ -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
|
||||
|
||||
|
||||
|
||||
14
tests/misc/tstrdesc.nim
Normal file
14
tests/misc/tstrdesc.nim
Normal file
@@ -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
|
||||
|
||||
|
||||
26
tests/misc/tstrdist.nim
Normal file
26
tests/misc/tstrdist.nim
Normal file
@@ -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"))
|
||||
64
tests/misc/tvarious.nim
Normal file
64
tests/misc/tvarious.nim
Normal file
@@ -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)
|
||||
41
tests/misc/tvarious1.nim
Normal file
41
tests/misc/tvarious1.nim
Normal file
@@ -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
|
||||
142
tests/misc/tvarnums.nim
Normal file
142
tests/misc/tvarnums.nim
Normal file
@@ -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!
|
||||
|
||||
|
||||
Reference in New Issue
Block a user