diff options
-rw-r--r-- | compiler/sempass2.nim | 3 | ||||
-rw-r--r-- | lib/core/macros.nim | 20 | ||||
-rw-r--r-- | lib/pure/collections/tables.nim | 2 | ||||
-rw-r--r-- | lib/pure/math.nim | 8 | ||||
-rw-r--r-- | lib/pure/net.nim | 9 | ||||
-rw-r--r-- | lib/pure/os.nim | 6 | ||||
-rw-r--r-- | lib/pure/times.nim | 102 | ||||
-rw-r--r-- | lib/system.nim | 38 | ||||
-rw-r--r-- | lib/system/repr.nim | 6 | ||||
-rw-r--r-- | tests/collections/tindexby.nim | 22 | ||||
-rw-r--r-- | tests/collections/ttableconstr.nim (renamed from tests/table/ttableconstr.nim) | 0 | ||||
-rw-r--r-- | tests/collections/ttables.nim | 148 | ||||
-rw-r--r-- | tests/collections/ttables2.nim (renamed from tests/table/ttables2.nim) | 0 | ||||
-rw-r--r-- | tests/collections/ttablesref.nim (renamed from tests/table/ptables.nim) | 2 | ||||
-rw-r--r-- | tests/collections/ttablesref2.nim (renamed from tests/table/ptables2.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tircbot.nim | 453 | ||||
-rw-r--r-- | tests/stdlib/tmitems.nim | 2 | ||||
-rw-r--r-- | tests/table/ttables.nim | 128 | ||||
-rw-r--r-- | todo.txt | 1 |
19 files changed, 246 insertions, 704 deletions
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index ede556a70..6fa7c756e 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -859,7 +859,8 @@ proc trackProc*(s: PSym, body: PNode) = if s.typ.lockLevel == UnspecifiedLockLevel: s.typ.lockLevel = t.maxLockLevel elif t.maxLockLevel > s.typ.lockLevel: - localError(s.info, + #localError(s.info, + message(s.info, warnLockLevel, "declared lock level is $1, but real lock level is $2" % [$s.typ.lockLevel, $t.maxLockLevel]) diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 22b9c4907..4c561df70 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -136,12 +136,12 @@ proc len*(n: PNimrodNode): int {.magic: "NLen", noSideEffect.} ## returns the number of children of `n`. proc add*(father, child: PNimrodNode): PNimrodNode {.magic: "NAdd", discardable, - noSideEffect.} + noSideEffect, locks: 0.} ## Adds the `child` to the `father` node. Returns the ## father node so that calls can be nested. proc add*(father: PNimrodNode, children: varargs[PNimrodNode]): PNimrodNode {. - magic: "NAddMultiple", discardable, noSideEffect.} + magic: "NAddMultiple", discardable, noSideEffect, locks: 0.} ## Adds each child of `children` to the `father` node. ## Returns the `father` node so that calls can be nested. @@ -177,13 +177,13 @@ proc newNimNode*(kind: TNimrodNodeKind, proc copyNimNode*(n: PNimrodNode): PNimrodNode {.magic: "NCopyNimNode", noSideEffect.} proc copyNimTree*(n: PNimrodNode): PNimrodNode {.magic: "NCopyNimTree", noSideEffect.} -proc error*(msg: string) {.magic: "NError", gcsafe.} +proc error*(msg: string) {.magic: "NError", benign.} ## writes an error message at compile time -proc warning*(msg: string) {.magic: "NWarning", gcsafe.} +proc warning*(msg: string) {.magic: "NWarning", benign.} ## writes a warning message at compile time -proc hint*(msg: string) {.magic: "NHint", gcsafe.} +proc hint*(msg: string) {.magic: "NHint", benign.} ## writes a hint message at compile time proc newStrLitNode*(s: string): PNimrodNode {.compileTime, noSideEffect.} = @@ -237,7 +237,7 @@ proc genSym*(kind: TNimrodSymKind = nskLet; ident = ""): PNimrodNode {. ## generates a fresh symbol that is guaranteed to be unique. The symbol ## needs to occur in a declaration context. -proc callsite*(): PNimrodNode {.magic: "NCallSite", gcsafe.} +proc callsite*(): PNimrodNode {.magic: "NCallSite", benign.} ## returns the AST of the invocation expression that invoked this macro. proc toStrLit*(n: PNimrodNode): PNimrodNode {.compileTime.} = @@ -387,11 +387,11 @@ proc nestList*(theProc: TNimrodIdent, # This could easily user code and so should be fixed in evals.nim somehow. result = newCall(theProc, x[i], copyNimTree(result)) -proc treeRepr*(n: PNimrodNode): string {.compileTime.} = +proc treeRepr*(n: PNimrodNode): string {.compileTime, benign.} = ## Convert the AST `n` to a human-readable tree-like string. ## ## See also `repr` and `lispRepr`. - proc traverse(res: var string, level: int, n: PNimrodNode) = + proc traverse(res: var string, level: int, n: PNimrodNode) {.benign.} = for i in 0..level-1: res.add " " res.add(($n.kind).substr(3)) @@ -412,7 +412,7 @@ proc treeRepr*(n: PNimrodNode): string {.compileTime.} = result = "" traverse(result, 0, n) -proc lispRepr*(n: PNimrodNode): string {.compileTime.} = +proc lispRepr*(n: PNimrodNode): string {.compileTime, benign.} = ## Convert the AST `n` to a human-readable lisp-like string, ## ## See also `repr` and `treeRepr`. @@ -651,7 +651,7 @@ proc `body=`*(someProc: PNimrodNode, val: PNimrodNode) {.compileTime.} = else: badNodeKind someProc.kind, "body=" -proc basename*(a: PNimrodNode): PNimrodNode {.compiletime.} +proc basename*(a: PNimrodNode): PNimrodNode {.compiletime, benign.} proc `$`*(node: PNimrodNode): string {.compileTime.} = diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index 9dcc97148..671f767cf 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -347,7 +347,7 @@ proc `$`*[A, B](t: TableRef[A, B]): string = proc `==`*[A, B](s, t: TableRef[A, B]): bool = if isNil(s): result = isNil(t) elif isNil(t): result = false - else: result = equalsImpl() + else: equalsImpl() proc newTableFrom*[A, B, C](collection: A, index: proc(x: B): C): TableRef[C, B] = ## Index the collection with the proc provided. diff --git a/lib/pure/math.nim b/lib/pure/math.nim index b9e057e78..1690377ff 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -129,25 +129,25 @@ proc variance*(x: openArray[float]): float {.noSideEffect.} = result = result + diff*diff result = result / toFloat(len(x)) -proc random*(max: int): int {.gcsafe.} +proc random*(max: int): int {.benign.} ## returns a random number in the range 0..max-1. The sequence of ## random number is always the same, unless `randomize` is called ## which initializes the random number generator with a "random" ## number, i.e. a tickcount. -proc random*(max: float): float {.gcsafe.} +proc random*(max: float): float {.benign.} ## returns a random number in the range 0..<max. The sequence of ## random number is always the same, unless `randomize` is called ## which initializes the random number generator with a "random" ## number, i.e. a tickcount. This has a 16-bit resolution on windows ## and a 48-bit resolution on other platforms. -proc randomize*() {.gcsafe.} +proc randomize*() {.benign.} ## initializes the random number generator with a "random" ## number, i.e. a tickcount. Note: Does nothing for the JavaScript target, ## as JavaScript does not support this. -proc randomize*(seed: int) {.gcsafe.} +proc randomize*(seed: int) {.benign.} ## initializes the random number generator with a specific seed. ## Note: Does nothing for the JavaScript target, ## as JavaScript does not support this. diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 4eacfea78..2b81b6fb0 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -321,7 +321,8 @@ proc bindAddr*(socket: Socket, port = Port(0), address = "") {. dealloc(aiList) proc acceptAddr*(server: Socket, client: var Socket, address: var string, - flags = {SocketFlag.SafeDisconn}) {.tags: [ReadIOEffect].} = + flags = {SocketFlag.SafeDisconn}) {. + tags: [ReadIOEffect], gcsafe, locks: 0.} = ## Blocks until a connection is being made from a client. When a connection ## is made sets ``client`` to the client socket and ``address`` to the address ## of the connecting client. @@ -938,8 +939,12 @@ proc connect*(socket: Socket, address: string, port = Port(0), timeout: int, doAssert socket.handshake() socket.fd.setBlocking(true) -proc isSsl*(socket: Socket): bool = return socket.isSSL +proc isSsl*(socket: Socket): bool = ## Determines whether ``socket`` is a SSL socket. + when defined(ssl): + result = socket.isSSL + else: + result = false proc getFd*(socket: Socket): SocketHandle = return socket.fd ## Returns the socket's file descriptor diff --git a/lib/pure/os.nim b/lib/pure/os.nim index f01343673..14cbe07bb 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -1339,7 +1339,7 @@ proc rawRemoveDir(dir: string) = if rmdir(dir) != 0'i32 and errno != ENOENT: raiseOSError(osLastError()) proc removeDir*(dir: string) {.rtl, extern: "nos$1", tags: [ - WriteDirEffect, ReadDirEffect].} = + WriteDirEffect, ReadDirEffect], benign.} = ## Removes the directory `dir` including all subdirectories and files ## in `dir` (recursively). ## @@ -1385,7 +1385,7 @@ proc createDir*(dir: string) {.rtl, extern: "nos$1", tags: [WriteDirEffect].} = rawCreateDir(dir) proc copyDir*(source, dest: string) {.rtl, extern: "nos$1", - tags: [WriteIOEffect, ReadIOEffect].} = + tags: [WriteIOEffect, ReadIOEffect], benign.} = ## Copies a directory from `source` to `dest`. ## ## If this fails, `OSError` is raised. On the Windows platform this proc will @@ -1558,7 +1558,7 @@ proc copyFileWithPermissions*(source, dest: string, proc copyDirWithPermissions*(source, dest: string, ignorePermissionErrors = true) {.rtl, extern: "nos$1", - tags: [WriteIOEffect, ReadIOEffect].} = + tags: [WriteIOEffect, ReadIOEffect], benign.} = ## Copies a directory from `source` to `dest` preserving file permissions. ## ## If this fails, `OSError` is raised. This is a wrapper proc around `copyDir() diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 1cabd381b..0925e3471 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -63,44 +63,44 @@ elif defined(windows): elif defined(JS): type Time* {.importc.} = object - getDay: proc (): int {.tags: [], raises: [], gcsafe.} - getFullYear: proc (): int {.tags: [], raises: [], gcsafe.} - getHours: proc (): int {.tags: [], raises: [], gcsafe.} - getMilliseconds: proc (): int {.tags: [], raises: [], gcsafe.} - getMinutes: proc (): int {.tags: [], raises: [], gcsafe.} - getMonth: proc (): int {.tags: [], raises: [], gcsafe.} - getSeconds: proc (): int {.tags: [], raises: [], gcsafe.} - getTime: proc (): int {.tags: [], raises: [], gcsafe.} - getTimezoneOffset: proc (): int {.tags: [], raises: [], gcsafe.} - getDate: proc (): int {.tags: [], raises: [], gcsafe.} - getUTCDate: proc (): int {.tags: [], raises: [], gcsafe.} - getUTCFullYear: proc (): int {.tags: [], raises: [], gcsafe.} - getUTCHours: proc (): int {.tags: [], raises: [], gcsafe.} - getUTCMilliseconds: proc (): int {.tags: [], raises: [], gcsafe.} - getUTCMinutes: proc (): int {.tags: [], raises: [], gcsafe.} - getUTCMonth: proc (): int {.tags: [], raises: [], gcsafe.} - getUTCSeconds: proc (): int {.tags: [], raises: [], gcsafe.} - getUTCDay: proc (): int {.tags: [], raises: [], gcsafe.} - getYear: proc (): int {.tags: [], raises: [], gcsafe.} - parse: proc (s: cstring): Time {.tags: [], raises: [], gcsafe.} - setDate: proc (x: int) {.tags: [], raises: [], gcsafe.} - setFullYear: proc (x: int) {.tags: [], raises: [], gcsafe.} - setHours: proc (x: int) {.tags: [], raises: [], gcsafe.} - setMilliseconds: proc (x: int) {.tags: [], raises: [], gcsafe.} - setMinutes: proc (x: int) {.tags: [], raises: [], gcsafe.} - setMonth: proc (x: int) {.tags: [], raises: [], gcsafe.} - setSeconds: proc (x: int) {.tags: [], raises: [], gcsafe.} - setTime: proc (x: int) {.tags: [], raises: [], gcsafe.} - setUTCDate: proc (x: int) {.tags: [], raises: [], gcsafe.} - setUTCFullYear: proc (x: int) {.tags: [], raises: [], gcsafe.} - setUTCHours: proc (x: int) {.tags: [], raises: [], gcsafe.} - setUTCMilliseconds: proc (x: int) {.tags: [], raises: [], gcsafe.} - setUTCMinutes: proc (x: int) {.tags: [], raises: [], gcsafe.} - setUTCMonth: proc (x: int) {.tags: [], raises: [], gcsafe.} - setUTCSeconds: proc (x: int) {.tags: [], raises: [], gcsafe.} - setYear: proc (x: int) {.tags: [], raises: [], gcsafe.} - toGMTString: proc (): cstring {.tags: [], raises: [], gcsafe.} - toLocaleString: proc (): cstring {.tags: [], raises: [], gcsafe.} + getDay: proc (): int {.tags: [], raises: [], benign.} + getFullYear: proc (): int {.tags: [], raises: [], benign.} + getHours: proc (): int {.tags: [], raises: [], benign.} + getMilliseconds: proc (): int {.tags: [], raises: [], benign.} + getMinutes: proc (): int {.tags: [], raises: [], benign.} + getMonth: proc (): int {.tags: [], raises: [], benign.} + getSeconds: proc (): int {.tags: [], raises: [], benign.} + getTime: proc (): int {.tags: [], raises: [], benign.} + getTimezoneOffset: proc (): int {.tags: [], raises: [], benign.} + getDate: proc (): int {.tags: [], raises: [], benign.} + getUTCDate: proc (): int {.tags: [], raises: [], benign.} + getUTCFullYear: proc (): int {.tags: [], raises: [], benign.} + getUTCHours: proc (): int {.tags: [], raises: [], benign.} + getUTCMilliseconds: proc (): int {.tags: [], raises: [], benign.} + getUTCMinutes: proc (): int {.tags: [], raises: [], benign.} + getUTCMonth: proc (): int {.tags: [], raises: [], benign.} + getUTCSeconds: proc (): int {.tags: [], raises: [], benign.} + getUTCDay: proc (): int {.tags: [], raises: [], benign.} + getYear: proc (): int {.tags: [], raises: [], benign.} + parse: proc (s: cstring): Time {.tags: [], raises: [], benign.} + setDate: proc (x: int) {.tags: [], raises: [], benign.} + setFullYear: proc (x: int) {.tags: [], raises: [], benign.} + setHours: proc (x: int) {.tags: [], raises: [], benign.} + setMilliseconds: proc (x: int) {.tags: [], raises: [], benign.} + setMinutes: proc (x: int) {.tags: [], raises: [], benign.} + setMonth: proc (x: int) {.tags: [], raises: [], benign.} + setSeconds: proc (x: int) {.tags: [], raises: [], benign.} + setTime: proc (x: int) {.tags: [], raises: [], benign.} + setUTCDate: proc (x: int) {.tags: [], raises: [], benign.} + setUTCFullYear: proc (x: int) {.tags: [], raises: [], benign.} + setUTCHours: proc (x: int) {.tags: [], raises: [], benign.} + setUTCMilliseconds: proc (x: int) {.tags: [], raises: [], benign.} + setUTCMinutes: proc (x: int) {.tags: [], raises: [], benign.} + setUTCMonth: proc (x: int) {.tags: [], raises: [], benign.} + setUTCSeconds: proc (x: int) {.tags: [], raises: [], benign.} + setYear: proc (x: int) {.tags: [], raises: [], benign.} + toGMTString: proc (): cstring {.tags: [], raises: [], benign.} + toLocaleString: proc (): cstring {.tags: [], raises: [], benign.} type TimeInfo* = object of RootObj ## represents a time in different parts @@ -139,42 +139,42 @@ type {.deprecated: [TMonth: Month, TWeekDay: WeekDay, TTime: Time, TTimeInterval: TimeInterval, TTimeInfo: TimeInfo].} -proc getTime*(): Time {.tags: [TimeEffect], gcsafe.} +proc getTime*(): Time {.tags: [TimeEffect], benign.} ## gets the current calendar time as a UNIX epoch value (number of seconds ## elapsed since 1970) with integer precission. Use epochTime for higher ## resolution. -proc getLocalTime*(t: Time): TimeInfo {.tags: [TimeEffect], raises: [], gcsafe.} +proc getLocalTime*(t: Time): TimeInfo {.tags: [TimeEffect], raises: [], benign.} ## converts the calendar time `t` to broken-time representation, ## expressed relative to the user's specified time zone. -proc getGMTime*(t: Time): TimeInfo {.tags: [TimeEffect], raises: [], gcsafe.} +proc getGMTime*(t: Time): TimeInfo {.tags: [TimeEffect], raises: [], benign.} ## converts the calendar time `t` to broken-down time representation, ## expressed in Coordinated Universal Time (UTC). -proc timeInfoToTime*(timeInfo: TimeInfo): Time {.tags: [], gcsafe.} +proc timeInfoToTime*(timeInfo: TimeInfo): Time {.tags: [], benign.} ## converts a broken-down time structure to ## calendar time representation. The function ignores the specified ## contents of the structure members `weekday` and `yearday` and recomputes ## them from the other information in the broken-down time structure. -proc fromSeconds*(since1970: float): Time {.tags: [], raises: [], gcsafe.} +proc fromSeconds*(since1970: float): Time {.tags: [], raises: [], benign.} ## Takes a float which contains the number of seconds since the unix epoch and ## returns a time object. -proc fromSeconds*(since1970: int64): Time {.tags: [], raises: [], gcsafe.} = +proc fromSeconds*(since1970: int64): Time {.tags: [], raises: [], benign.} = ## Takes an int which contains the number of seconds since the unix epoch and ## returns a time object. fromSeconds(float(since1970)) -proc toSeconds*(time: Time): float {.tags: [], raises: [], gcsafe.} +proc toSeconds*(time: Time): float {.tags: [], raises: [], benign.} ## Returns the time in seconds since the unix epoch. -proc `$` *(timeInfo: TimeInfo): string {.tags: [], raises: [], gcsafe.} +proc `$` *(timeInfo: TimeInfo): string {.tags: [], raises: [], benign.} ## converts a `TimeInfo` object to a string representation. -proc `$` *(time: Time): string {.tags: [], raises: [], gcsafe.} +proc `$` *(time: Time): string {.tags: [], raises: [], benign.} ## converts a calendar time to a string representation. proc `-`*(a, b: Time): int64 {. - rtl, extern: "ntDiffTime", tags: [], raises: [].} + rtl, extern: "ntDiffTime", tags: [], raises: [], benign.} ## computes the difference of two calendar times. Result is in seconds. proc `<`*(a, b: Time): bool {. @@ -194,14 +194,14 @@ proc `==`*(a, b: Time): bool {. when not defined(JS): proc getTzname*(): tuple[nonDST, DST: string] {.tags: [TimeEffect], raises: [], - gcsafe.} + benign.} ## returns the local timezone; ``nonDST`` is the name of the local non-DST ## timezone, ``DST`` is the name of the local DST timezone. -proc getTimezone*(): int {.tags: [TimeEffect], raises: [], gcsafe.} +proc getTimezone*(): int {.tags: [TimeEffect], raises: [], benign.} ## returns the offset of the local (non-DST) timezone in seconds west of UTC. -proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], gcsafe.} +proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], benign.} ## get the miliseconds from the start of the program. **Deprecated since ## version 0.8.10.** Use ``epochTime`` or ``cpuTime`` instead. diff --git a/lib/system.nim b/lib/system.nim index ef70a2672..9dc233cb7 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2098,17 +2098,16 @@ when not defined(nimrodVM) and hostOS != "standalone": ## returns an informative string about the GC's activity. This may be useful ## for tweaking. - # XXX mark these as 'locks: 0' once 0.10.0 has been released - proc GC_ref*[T](x: ref T) {.magic: "GCref", gcsafe.} - proc GC_ref*[T](x: seq[T]) {.magic: "GCref", gcsafe.} - proc GC_ref*(x: string) {.magic: "GCref", gcsafe.} + proc GC_ref*[T](x: ref T) {.magic: "GCref", benign.} + proc GC_ref*[T](x: seq[T]) {.magic: "GCref", benign.} + proc GC_ref*(x: string) {.magic: "GCref", benign.} ## marks the object `x` as referenced, so that it will not be freed until ## it is unmarked via `GC_unref`. If called n-times for the same object `x`, ## n calls to `GC_unref` are needed to unmark `x`. - proc GC_unref*[T](x: ref T) {.magic: "GCunref", gcsafe.} - proc GC_unref*[T](x: seq[T]) {.magic: "GCunref", gcsafe.} - proc GC_unref*(x: string) {.magic: "GCunref", gcsafe.} + proc GC_unref*[T](x: ref T) {.magic: "GCunref", benign.} + proc GC_unref*[T](x: seq[T]) {.magic: "GCunref", benign.} + proc GC_unref*(x: string) {.magic: "GCunref", benign.} ## see the documentation of `GC_ref`. template accumulateResult*(iter: expr) = @@ -2248,14 +2247,9 @@ when not declared(sysFatal): e.msg = message & arg raise e -when defined(nimlocks): - proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", gcsafe, locks: 0.} - ## get type information for `x`. Ordinary code should not use this, but - ## the `typeinfo` module instead. -else: - proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", gcsafe.} - ## get type information for `x`. Ordinary code should not use this, but - ## the `typeinfo` module instead. +proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", benign.} + ## get type information for `x`. Ordinary code should not use this, but + ## the `typeinfo` module instead. {.push stackTrace: off.} proc abs*(x: int): int {.magic: "AbsI", noSideEffect.} = @@ -2455,14 +2449,10 @@ when not defined(JS): #and not defined(NimrodVM): ## Returns ``false`` if the end of the file has been reached, ``true`` ## otherwise. If ``false`` is returned `line` contains no new data. - when not defined(booting): - proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline, - tags: [WriteIOEffect], gcsafe, locks: 0.} - ## writes the values `x` to `f` and then writes "\n". - ## May throw an IO exception. - else: - proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline, - tags: [WriteIOEffect].} + proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline, + tags: [WriteIOEffect], benign.} + ## writes the values `x` to `f` and then writes "\n". + ## May throw an IO exception. proc getFileSize*(f: File): int64 {.tags: [ReadIOEffect], benign.} ## retrieves the file size (in bytes) of `f`. @@ -2576,7 +2566,7 @@ when not defined(JS): #and not defined(NimrodVM): initAllocator() when hasThreadSupport: include "system/syslocks" - include "system/threads" + when hostOS != "standalone": include "system/threads" elif not defined(nogc) and not defined(NimrodVM) and hostOS != "standalone": when not defined(useNimRtl) and not defined(createNimRtl): initStackBottom() initGC() diff --git a/lib/system/repr.nim b/lib/system/repr.nim index 2de603cea..5a243cb44 100644 --- a/lib/system/repr.nim +++ b/lib/system/repr.nim @@ -78,7 +78,7 @@ proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} = type PByteArray = ptr array[0.. 0xffff, int8] -proc addSetElem(result: var string, elem: int, typ: PNimType) {.gcsafe.} = +proc addSetElem(result: var string, elem: int, typ: PNimType) {.benign.} = case typ.kind of tyEnum: add result, reprEnum(elem, typ) of tyBool: add result, reprBool(bool(elem)) @@ -147,7 +147,7 @@ when not defined(useNimRtl): for i in 0..cl.indent-1: add result, ' ' proc reprAux(result: var string, p: pointer, typ: PNimType, - cl: var TReprClosure) {.gcsafe.} + cl: var TReprClosure) {.benign.} proc reprArray(result: var string, p: pointer, typ: PNimType, cl: var TReprClosure) = @@ -172,7 +172,7 @@ when not defined(useNimRtl): add result, "]" proc reprRecordAux(result: var string, p: pointer, n: ptr TNimNode, - cl: var TReprClosure) {.gcsafe.} = + cl: var TReprClosure) {.benign.} = case n.kind of nkNone: sysAssert(false, "reprRecordAux") of nkSlot: diff --git a/tests/collections/tindexby.nim b/tests/collections/tindexby.nim new file mode 100644 index 000000000..f374d5504 --- /dev/null +++ b/tests/collections/tindexby.nim @@ -0,0 +1,22 @@ +import tables + +doAssert indexBy(newSeq[int](), proc(x: int):int = x) == initTable[int, int](), "empty int table" + +var tbl1 = initTable[int, int]() +tbl1.add(1,1) +tbl1.add(2,2) +doAssert indexBy(@[1,2], proc(x: int):int = x) == tbl1, "int table" + +type + TElem = object + foo: int + bar: string + +let + elem1 = TElem(foo: 1, bar: "bar") + elem2 = TElem(foo: 2, bar: "baz") + +var tbl2 = initTable[string, TElem]() +tbl2.add("bar", elem1) +tbl2.add("baz", elem2) +doAssert indexBy(@[elem1,elem2], proc(x: TElem): string = x.bar) == tbl2, "element table" diff --git a/tests/table/ttableconstr.nim b/tests/collections/ttableconstr.nim index 1a21a18d1..1a21a18d1 100644 --- a/tests/table/ttableconstr.nim +++ b/tests/collections/ttableconstr.nim diff --git a/tests/collections/ttables.nim b/tests/collections/ttables.nim index f374d5504..de4aaed5e 100644 --- a/tests/collections/ttables.nim +++ b/tests/collections/ttables.nim @@ -1,22 +1,128 @@ -import tables - -doAssert indexBy(newSeq[int](), proc(x: int):int = x) == initTable[int, int](), "empty int table" - -var tbl1 = initTable[int, int]() -tbl1.add(1,1) -tbl1.add(2,2) -doAssert indexBy(@[1,2], proc(x: int):int = x) == tbl1, "int table" - -type - TElem = object - foo: int - bar: string - -let - elem1 = TElem(foo: 1, bar: "bar") - elem2 = TElem(foo: 2, bar: "baz") +discard """ + output: '''true''' +""" + +import hashes, tables + +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} + + sorteddata = { + "---00": 346677844, + "0": 34404, + "1": 344004, + "10": 34484, + "11": 34474, + "12": 789, + "19": 34464, + "2": 344774, "20": 34454, + "3": 342244, "30": 34141244, + "34": 123456, + "4": 3412344, "40": 344114, + "5": 341232144, "50": 344490, + "6": 34214544, "60": 344491, + "7": 3434544, "70": 344492, + "8": 344544, "80": 344497, + "9": 34435644, + "90": 343} + +block tableTest1: + var t = initTable[tuple[x, y: int], string]() + t[(0,0)] = "00" + t[(1,0)] = "10" + t[(0,1)] = "01" + t[(1,1)] = "11" + for x in 0..1: + for y in 0..1: + assert t[(x,y)] == $x & $y + assert($t == + "{(x: 0, y: 0): 00, (x: 0, y: 1): 01, (x: 1, y: 0): 10, (x: 1, y: 1): 11}") + +block tableTest2: + var t = initTable[string, float]() + t["test"] = 1.2345 + t["111"] = 1.000043 + t["123"] = 1.23 + t.del("111") -var tbl2 = initTable[string, TElem]() -tbl2.add("bar", elem1) -tbl2.add("baz", elem2) -doAssert indexBy(@[elem1,elem2], proc(x: TElem): string = x.bar) == tbl2, "element table" + t["012"] = 67.9 + t["123"] = 1.5 # test overwriting + + assert t["123"] == 1.5 + assert t["111"] == 0.0 # deleted + assert(not hasKey(t, "111")) + + for key, val in items(data): t[key] = val.toFloat + for key, val in items(data): assert t[key] == val.toFloat + + +block orderedTableTest1: + var t = initOrderedTable[string, int](2) + for key, val in items(data): t[key] = val + for key, val in items(data): assert t[key] == val + var i = 0 + # `pairs` needs to yield in insertion order: + for key, val in pairs(t): + assert key == data[i][0] + assert val == data[i][1] + inc(i) + + for key, val in mpairs(t): val = 99 + for val in mvalues(t): assert val == 99 + +block countTableTest1: + var s = data.toTable + var t = initCountTable[string]() + for k in s.keys: 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 + +block SyntaxTest: + var x = toTable[int, string]({:}) + +proc orderedTableSortTest() = + var t = initOrderedTable[string, int](2) + for key, val in items(data): t[key] = val + for key, val in items(data): assert t[key] == val + t.sort(proc (x, y: tuple[key: string, val: int]): int = cmp(x.key, y.key)) + var i = 0 + # `pairs` needs to yield in sorted order: + for key, val in pairs(t): + doAssert key == sorteddata[i][0] + doAssert val == sorteddata[i][1] + inc(i) + + # check that lookup still works: + for key, val in pairs(t): + doAssert val == t[key] + # check that insert still works: + t["newKeyHere"] = 80 + + +orderedTableSortTest() +echo "true" + diff --git a/tests/table/ttables2.nim b/tests/collections/ttables2.nim index 611f3f8ec..611f3f8ec 100644 --- a/tests/table/ttables2.nim +++ b/tests/collections/ttables2.nim diff --git a/tests/table/ptables.nim b/tests/collections/ttablesref.nim index 79a9aab17..e666c7852 100644 --- a/tests/table/ptables.nim +++ b/tests/collections/ttablesref.nim @@ -84,7 +84,7 @@ block orderedTableTest1: block countTableTest1: var s = data.toTable var t = newCountTable[string]() - for k in s.Keys: t.inc(k) + for k in s.keys: t.inc(k) for k in t.keys: assert t[k] == 1 t.inc("90", 3) t.inc("12", 2) diff --git a/tests/table/ptables2.nim b/tests/collections/ttablesref2.nim index 939de2b84..939de2b84 100644 --- a/tests/table/ptables2.nim +++ b/tests/collections/ttablesref2.nim diff --git a/tests/stdlib/tircbot.nim b/tests/stdlib/tircbot.nim deleted file mode 100644 index 6b209dce3..000000000 --- a/tests/stdlib/tircbot.nim +++ /dev/null @@ -1,453 +0,0 @@ -import irc, sockets, asyncio, json, os, strutils, times, redis - -type - TDb* = object - r*: Redis - lastPing: float - - TBuildResult* = enum - bUnknown, bFail, bSuccess - - TTestResult* = enum - tUnknown, tFail, tSuccess - - TEntry* = tuple[c: TCommit, p: seq[TPlatform]] - - TCommit* = object - commitMsg*, username*, hash*: string - date*: Time - - TPlatform* = object - buildResult*: TBuildResult - testResult*: TTestResult - failReason*, platform*: string - total*, passed*, skipped*, failed*: BiggestInt - csources*: bool - -const - listName = "commits" - failOnExisting = false - -proc open*(host = "localhost", port: Port): TDb = - result.r = redis.open(host, port) - result.lastPing = epochTime() - -discard """proc customHSet(database: TDb, name, field, value: string) = - if database.r.hSet(name, field, value).int == 0: - if failOnExisting: - assert(false) - else: - echo("[Warning:REDIS] ", field, " already exists in ", name)""" - -proc updateProperty*(database: TDb, commitHash, platform, property, - value: string) = - var name = platform & ":" & commitHash - if database.r.hSet(name, property, value).int == 0: - echo("[INFO:REDIS] '$1' field updated in hash" % [property]) - else: - echo("[INFO:REDIS] '$1' new field added to hash" % [property]) - -proc globalProperty*(database: TDb, commitHash, property, value: string) = - if database.r.hSet(commitHash, property, value).int == 0: - echo("[INFO:REDIS] '$1' field updated in hash" % [property]) - else: - echo("[INFO:REDIS] '$1' new field added to hash" % [property]) - -proc addCommit*(database: TDb, commitHash, commitMsg, user: string) = - # Add the commit hash to the `commits` list. - discard database.r.lPush(listName, commitHash) - # Add the commit message, current date and username as a property - globalProperty(database, commitHash, "commitMsg", commitMsg) - globalProperty(database, commitHash, "date", $int(getTime())) - globalProperty(database, commitHash, "username", user) - -proc keepAlive*(database: var TDb) = - ## Keep the connection alive. Ping redis in this case. This functions does - ## not guarantee that redis will be pinged. - var t = epochTime() - if t - database.lastPing >= 60.0: - echo("PING -> redis") - assert(database.r.ping() == "PONG") - database.lastPing = t - -proc getCommits*(database: TDb, - plStr: var seq[string]): seq[TEntry] = - result = @[] - var commitsRaw = database.r.lrange("commits", 0, -1) - for c in items(commitsRaw): - var commit: TCommit - commit.hash = c - for key, value in database.r.hPairs(c): - case normalize(key) - of "commitmsg": commit.commitMsg = value - of "date": commit.date = Time(parseInt(value)) - of "username": commit.username = value - else: - echo(key) - assert(false) - - var platformsRaw = database.r.lrange(c & ":platforms", 0, -1) - var platforms: seq[TPlatform] = @[] - for p in items(platformsRaw): - var platform: TPlatform - for key, value in database.r.hPairs(p & ":" & c): - case normalize(key) - of "buildresult": - platform.buildResult = parseInt(value).TBuildResult - of "testresult": - platform.testResult = parseInt(value).TTestResult - of "failreason": - platform.failReason = value - of "total": - platform.total = parseBiggestInt(value) - of "passed": - platform.passed = parseBiggestInt(value) - of "skipped": - platform.skipped = parseBiggestInt(value) - of "failed": - platform.failed = parseBiggestInt(value) - of "csources": - platform.csources = if value == "t": true else: false - else: - echo(normalize(key)) - assert(false) - - platform.platform = p - - platforms.add(platform) - if p notin plStr: - plStr.add(p) - result.add((commit, platforms)) - -proc commitExists*(database: TDb, commit: string, starts = false): bool = - # TODO: Consider making the 'commits' list a set. - for c in items(database.r.lrange("commits", 0, -1)): - if starts: - if c.startsWith(commit): return true - else: - if c == commit: return true - return false - -proc platformExists*(database: TDb, commit: string, platform: string): bool = - for p in items(database.r.lrange(commit & ":" & "platforms", 0, -1)): - if p == platform: return true - -proc expandHash*(database: TDb, commit: string): string = - for c in items(database.r.lrange("commits", 0, -1)): - if c.startsWith(commit): return c - assert false - -proc isNewest*(database: TDb, commit: string): bool = - return database.r.lIndex("commits", 0) == commit - -proc getNewest*(database: TDb): string = - return database.r.lIndex("commits", 0) - -proc addPlatform*(database: TDb, commit: string, platform: string) = - assert database.commitExists(commit) - assert (not database.platformExists(commit, platform)) - var name = platform & ":" & commit - if database.r.exists(name): - if failOnExisting: quit("[FAIL] " & name & " already exists!", 1) - else: echo("[Warning] " & name & " already exists!") - - discard database.r.lPush(commit & ":" & "platforms", platform) - -proc `[]`*(p: seq[TPlatform], name: string): TPlatform = - for platform in items(p): - if platform.platform == name: - return platform - raise newException(ValueError, name & " platforms not found in commits.") - -proc contains*(p: seq[TPlatform], s: string): bool = - for i in items(p): - if i.platform == s: - return true - - -type - PState = ref TState - TState = object of RootObj - dispatcher: Dispatcher - sock: AsyncSocket - ircClient: PAsyncIRC - hubPort: Port - database: TDb - dbConnected: bool - - TSeenType = enum - PSeenJoin, PSeenPart, PSeenMsg, PSeenNick, PSeenQuit - - TSeen = object - nick: string - channel: string - timestamp: Time - case kind*: TSeenType - of PSeenJoin: nil - of PSeenPart, PSeenQuit, PSeenMsg: - msg: string - of PSeenNick: - newNick: string - -const - ircServer = "irc.freenode.net" - joinChans = @["#nim"] - botNickname = "NimBot" - -proc setSeen(d: TDb, s: TSeen) = - discard d.r.del("seen:" & s.nick) - - var hashToSet = @[("type", $s.kind.int), ("channel", s.channel), - ("timestamp", $s.timestamp.int)] - case s.kind - of PSeenJoin: discard - of PSeenPart, PSeenMsg, PSeenQuit: - hashToSet.add(("msg", s.msg)) - of PSeenNick: - hashToSet.add(("newnick", s.newNick)) - - d.r.hMSet("seen:" & s.nick, hashToSet) - -proc getSeen(d: TDb, nick: string, s: var TSeen): bool = - if d.r.exists("seen:" & nick): - result = true - s.nick = nick - # Get the type first - s.kind = d.r.hGet("seen:" & nick, "type").parseInt.TSeenType - - for key, value in d.r.hPairs("seen:" & nick): - case normalize(key) - of "type": - discard - #s.kind = value.parseInt.TSeenType - of "channel": - s.channel = value - of "timestamp": - s.timestamp = Time(value.parseInt) - of "msg": - s.msg = value - of "newnick": - s.newNick = value - -template createSeen(typ: TSeenType, n, c: string): stmt {.immediate, dirty.} = - var seenNick: TSeen - seenNick.kind = typ - seenNick.nick = n - seenNick.channel = c - seenNick.timestamp = getTime() - -proc parseReply(line: string, expect: string): bool = - var jsonDoc = parseJson(line) - return jsonDoc["reply"].str == expect - -proc limitCommitMsg(m: string): string = - ## Limits the message to 300 chars and adds ellipsis. - var m1 = m - if NewLines in m1: - m1 = m1.splitLines()[0] - - if m1.len >= 300: - m1 = m1[0..300] - - if m1.len >= 300 or NewLines in m: m1.add("... ") - - if NewLines in m: m1.add($m.splitLines().len & " more lines") - - return m1 - -proc handleWebMessage(state: PState, line: string) = - echo("Got message from hub: " & line) - var json = parseJson(line) - if json.hasKey("payload"): - for i in 0..min(4, json["payload"]["commits"].len-1): - var commit = json["payload"]["commits"][i] - # Create the message - var message = "" - message.add(json["payload"]["repository"]["owner"]["name"].str & "/" & - json["payload"]["repository"]["name"].str & " ") - message.add(commit["id"].str[0..6] & " ") - message.add(commit["author"]["name"].str & " ") - message.add("[+" & $commit["added"].len & " ") - message.add("±" & $commit["modified"].len & " ") - message.add("-" & $commit["removed"].len & "]: ") - message.add(limitCommitMsg(commit["message"].str)) - - # Send message to #nim. - discard state.ircClient.privmsg(joinChans[0], message) - elif json.hasKey("redisinfo"): - assert json["redisinfo"].hasKey("port") - #let redisPort = json["redisinfo"]["port"].num - state.dbConnected = true - -proc hubConnect(state: PState) -proc handleConnect(s: AsyncSocket, state: PState) = - try: - # Send greeting - var obj = newJObject() - obj["name"] = newJString("irc") - obj["platform"] = newJString("?") - state.sock.send($obj & "\c\L") - - # Wait for reply. - var line = "" - sleep(1500) - if state.sock.recvLine(line): - assert(line != "") - doAssert parseReply(line, "OK") - echo("The hub accepted me!") - else: - raise newException(ValueError, - "Hub didn't accept me. Waited 1.5 seconds.") - - # ask for the redis info - var riobj = newJObject() - riobj["do"] = newJString("redisinfo") - state.sock.send($riobj & "\c\L") - - except OsError: - echo(getCurrentExceptionMsg()) - s.close() - echo("Waiting 5 seconds...") - sleep(5000) - state.hubConnect() - -proc handleRead(s: AsyncSocket, state: PState) = - var line = "" - if state.sock.recvLine(line): - if line != "": - # Handle the message - state.handleWebMessage(line) - else: - echo("Disconnected from hub: ", osErrorMsg()) - s.close() - echo("Reconnecting...") - state.hubConnect() - else: - echo(osErrorMsg()) - -proc hubConnect(state: PState) = - state.sock = asyncSocket() - state.sock.connect("127.0.0.1", state.hubPort) - state.sock.handleConnect = - proc (s: AsyncSocket) = - handleConnect(s, state) - state.sock.handleRead = - proc (s: AsyncSocket) = - handleRead(s, state) - - state.dispatcher.register(state.sock) - -proc handleIrc(irc: PAsyncIRC, event: TIRCEvent, state: PState) = - case event.typ - of EvConnected: discard - of EvDisconnected: - while not state.ircClient.isConnected: - try: - state.ircClient.connect() - except: - echo("Error reconnecting: ", getCurrentExceptionMsg()) - - echo("Waiting 5 seconds...") - sleep(5000) - echo("Reconnected successfully!") - of EvMsg: - echo("< ", event.raw) - case event.cmd - of MPrivMsg: - let msg = event.params[event.params.len-1] - let words = msg.split(' ') - template pm(msg: string): stmt = - state.ircClient.privmsg(event.origin, msg) - case words[0] - of "!ping": pm("pong") - of "!lag": - if state.ircClient.getLag != -1.0: - var lag = state.ircClient.getLag - lag = lag * 1000.0 - pm($int(lag) & "ms between me and the server.") - else: - pm("Unknown.") - of "!seen": - if words.len > 1: - let nick = words[1] - if nick == botNickname: - pm("Yes, I see myself.") - echo(nick) - var seenInfo: TSeen - if state.database.getSeen(nick, seenInfo): - #var mSend = "" - case seenInfo.kind - of PSeenMsg: - pm("$1 was last seen on $2 in $3 saying: $4" % - [seenInfo.nick, $seenInfo.timestamp, - seenInfo.channel, seenInfo.msg]) - of PSeenJoin: - pm("$1 was last seen on $2 joining $3" % - [seenInfo.nick, $seenInfo.timestamp, seenInfo.channel]) - of PSeenPart: - pm("$1 was last seen on $2 leaving $3 with message: $4" % - [seenInfo.nick, $seenInfo.timestamp, seenInfo.channel, - seenInfo.msg]) - of PSeenQuit: - pm("$1 was last seen on $2 quitting with message: $3" % - [seenInfo.nick, $seenInfo.timestamp, seenInfo.msg]) - of PSeenNick: - pm("$1 was last seen on $2 changing nick to $3" % - [seenInfo.nick, $seenInfo.timestamp, seenInfo.newNick]) - - else: - pm("I have not seen " & nick) - else: - pm("Syntax: !seen <nick>") - - # TODO: ... commands - - # -- Seen - # Log this as activity. - createSeen(PSeenMsg, event.nick, event.origin) - seenNick.msg = msg - state.database.setSeen(seenNick) - of MJoin: - createSeen(PSeenJoin, event.nick, event.origin) - state.database.setSeen(seenNick) - of MPart: - createSeen(PSeenPart, event.nick, event.origin) - let msg = event.params[event.params.high] - seenNick.msg = msg - state.database.setSeen(seenNick) - of MQuit: - createSeen(PSeenQuit, event.nick, event.origin) - let msg = event.params[event.params.high] - seenNick.msg = msg - state.database.setSeen(seenNick) - of MNick: - createSeen(PSeenNick, event.nick, "#nim") - seenNick.newNick = event.params[0] - state.database.setSeen(seenNick) - else: - discard # TODO: ? - -proc open(port: Port = Port(5123)): PState = - var res: PState - new(res) - res.dispatcher = newDispatcher() - - res.hubPort = port - res.hubConnect() - let hirc = - proc (a: PAsyncIRC, ev: TIRCEvent) = - handleIrc(a, ev, res) - # Connect to the irc server. - res.ircClient = AsyncIrc(ircServer, nick = botNickname, user = botNickname, - joinChans = joinChans, ircEvent = hirc) - res.ircClient.connect() - res.dispatcher.register(res.ircClient) - - res.dbConnected = false - result = res - -var state = tircbot.open() # Connect to the website and the IRC server. - -while state.dispatcher.poll(): - if state.dbConnected: - state.database.keepAlive() diff --git a/tests/stdlib/tmitems.nim b/tests/stdlib/tmitems.nim index bf67d2b7b..2c0a0392a 100644 --- a/tests/stdlib/tmitems.nim +++ b/tests/stdlib/tmitems.nim @@ -11,7 +11,7 @@ fpqeew [11, 12, 13] [11, 12, 13] [11, 12, 13] -{ "key1": 11, "key2": 12, "key3": 13} +{"key1": 11, "key2": 12, "key3": 13} [11, 12, 13] <Students> <Student Name="Aprilfoo" /> diff --git a/tests/table/ttables.nim b/tests/table/ttables.nim deleted file mode 100644 index de4aaed5e..000000000 --- a/tests/table/ttables.nim +++ /dev/null @@ -1,128 +0,0 @@ -discard """ - output: '''true''' -""" - -import hashes, tables - -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} - - sorteddata = { - "---00": 346677844, - "0": 34404, - "1": 344004, - "10": 34484, - "11": 34474, - "12": 789, - "19": 34464, - "2": 344774, "20": 34454, - "3": 342244, "30": 34141244, - "34": 123456, - "4": 3412344, "40": 344114, - "5": 341232144, "50": 344490, - "6": 34214544, "60": 344491, - "7": 3434544, "70": 344492, - "8": 344544, "80": 344497, - "9": 34435644, - "90": 343} - -block tableTest1: - var t = initTable[tuple[x, y: int], string]() - t[(0,0)] = "00" - t[(1,0)] = "10" - t[(0,1)] = "01" - t[(1,1)] = "11" - for x in 0..1: - for y in 0..1: - assert t[(x,y)] == $x & $y - assert($t == - "{(x: 0, y: 0): 00, (x: 0, y: 1): 01, (x: 1, y: 0): 10, (x: 1, y: 1): 11}") - -block tableTest2: - var t = initTable[string, float]() - t["test"] = 1.2345 - t["111"] = 1.000043 - t["123"] = 1.23 - t.del("111") - - t["012"] = 67.9 - t["123"] = 1.5 # test overwriting - - assert t["123"] == 1.5 - assert t["111"] == 0.0 # deleted - assert(not hasKey(t, "111")) - - for key, val in items(data): t[key] = val.toFloat - for key, val in items(data): assert t[key] == val.toFloat - - -block orderedTableTest1: - var t = initOrderedTable[string, int](2) - for key, val in items(data): t[key] = val - for key, val in items(data): assert t[key] == val - var i = 0 - # `pairs` needs to yield in insertion order: - for key, val in pairs(t): - assert key == data[i][0] - assert val == data[i][1] - inc(i) - - for key, val in mpairs(t): val = 99 - for val in mvalues(t): assert val == 99 - -block countTableTest1: - var s = data.toTable - var t = initCountTable[string]() - for k in s.keys: 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 - -block SyntaxTest: - var x = toTable[int, string]({:}) - -proc orderedTableSortTest() = - var t = initOrderedTable[string, int](2) - for key, val in items(data): t[key] = val - for key, val in items(data): assert t[key] == val - t.sort(proc (x, y: tuple[key: string, val: int]): int = cmp(x.key, y.key)) - var i = 0 - # `pairs` needs to yield in sorted order: - for key, val in pairs(t): - doAssert key == sorteddata[i][0] - doAssert val == sorteddata[i][1] - inc(i) - - # check that lookup still works: - for key, val in pairs(t): - doAssert val == t[key] - # check that insert still works: - t["newKeyHere"] = 80 - - -orderedTableSortTest() -echo "true" - diff --git a/todo.txt b/todo.txt index 706954f65..57cfea017 100644 --- a/todo.txt +++ b/todo.txt @@ -41,7 +41,6 @@ Misc - make tuple unpacking work in a non-var/let context - built-in 'getImpl' - prevent 'alloc(TypeWithGCedMemory)' -- some table related tests are wrong (memory usage checks) Bugs |