make tests green

This commit is contained in:
Araq 2014-08-31 15:15:26 +02:00
commit 30823c1ce3
44 changed files with 415 additions and 403 deletions

View file

@ -23,12 +23,14 @@ type
## in preventDeadlocks-mode guarantees re-entrancy. ## in preventDeadlocks-mode guarantees re-entrancy.
TCond* = TSysCond ## Nim condition variable TCond* = TSysCond ## Nim condition variable
FLock* = object of TEffect ## effect that denotes that some lock operation LockEffect* = object of RootEffect ## effect that denotes that some lock operation
## is performed ## is performed
FAquireLock* = object of FLock ## effect that denotes that some lock is AquireEffect* = object of LockEffect ## effect that denotes that some lock is
## aquired ## aquired
FReleaseLock* = object of FLock ## effect that denotes that some lock is ReleaseEffect* = object of LockEffect ## effect that denotes that some lock is
## released ## released
{.deprecated: [FLock: LockEffect, FAquireLock: AquireEffect,
FReleaseLock: ReleaseEffect].}
const const
noDeadlocks = defined(preventDeadlocks) noDeadlocks = defined(preventDeadlocks)
@ -58,7 +60,7 @@ proc deinitLock*(lock: var TLock) {.inline.} =
## Frees the resources associated with the lock. ## Frees the resources associated with the lock.
deinitSys(lock) deinitSys(lock)
proc tryAcquire*(lock: var TLock): bool {.tags: [FAquireLock].} = proc tryAcquire*(lock: var TLock): bool {.tags: [AquireEffect].} =
## Tries to acquire the given lock. Returns `true` on success. ## Tries to acquire the given lock. Returns `true` on success.
result = tryAcquireSys(lock) result = tryAcquireSys(lock)
when noDeadlocks: when noDeadlocks:
@ -90,7 +92,7 @@ proc tryAcquire*(lock: var TLock): bool {.tags: [FAquireLock].} =
inc(locksLen) inc(locksLen)
assert orderedLocks() assert orderedLocks()
proc acquire*(lock: var TLock) {.tags: [FAquireLock].} = proc acquire*(lock: var TLock) {.tags: [AquireEffect].} =
## Acquires the given lock. ## Acquires the given lock.
when nodeadlocks: when nodeadlocks:
var p = addr(lock) var p = addr(lock)
@ -135,7 +137,7 @@ proc acquire*(lock: var TLock) {.tags: [FAquireLock].} =
else: else:
acquireSys(lock) acquireSys(lock)
proc release*(lock: var TLock) {.tags: [FReleaseLock].} = proc release*(lock: var TLock) {.tags: [ReleaseEffect].} =
## Releases the given lock. ## Releases the given lock.
when nodeadlocks: when nodeadlocks:
var p = addr(lock) var p = addr(lock)

View file

@ -74,7 +74,7 @@ proc newGenTable*[T](mode: TGenTableMode): PGenTable[T] =
proc nextTry(h, maxHash: THash): THash {.inline.} = proc nextTry(h, maxHash: THash): THash {.inline.} =
result = ((5 * h) + 1) and maxHash result = ((5 * h) + 1) and maxHash
proc RawGet[T](tbl: PGenTable[T], key: string): int = proc rawGet[T](tbl: PGenTable[T], key: string): int =
var h: THash var h: THash
h = myhash(tbl, key) and high(tbl.data) # start with real hash value h = myhash(tbl, key) and high(tbl.data) # start with real hash value
while not isNil(tbl.data[h].key): while not isNil(tbl.data[h].key):
@ -83,7 +83,7 @@ proc RawGet[T](tbl: PGenTable[T], key: string): int =
h = nextTry(h, high(tbl.data)) h = nextTry(h, high(tbl.data))
result = - 1 result = - 1
proc RawInsert[T](tbl: PGenTable[T], data: var TGenKeyValuePairSeq[T], proc rawInsert[T](tbl: PGenTable[T], data: var TGenKeyValuePairSeq[T],
key: string, val: T) = key: string, val: T) =
var h: THash var h: THash
h = myhash(tbl, key) and high(data) h = myhash(tbl, key) and high(data)
@ -92,12 +92,12 @@ proc RawInsert[T](tbl: PGenTable[T], data: var TGenKeyValuePairSeq[T],
data[h].key = key data[h].key = key
data[h].val = val data[h].val = val
proc Enlarge[T](tbl: PGenTable[T]) = proc enlarge[T](tbl: PGenTable[T]) =
var n: TGenKeyValuePairSeq[T] var n: TGenKeyValuePairSeq[T]
newSeq(n, len(tbl.data) * growthFactor) newSeq(n, len(tbl.data) * growthFactor)
for i in countup(0, high(tbl.data)): for i in countup(0, high(tbl.data)):
if not isNil(tbl.data[i].key): if not isNil(tbl.data[i].key):
RawInsert[T](tbl, n, tbl.data[i].key, tbl.data[i].val) rawInsert[T](tbl, n, tbl.data[i].key, tbl.data[i].val)
swap(tbl.data, n) swap(tbl.data, n)
proc hasKey*[T](tbl: PGenTable[T], key: string): bool = proc hasKey*[T](tbl: PGenTable[T], key: string): bool =
@ -108,17 +108,17 @@ proc `[]`*[T](tbl: PGenTable[T], key: string): T =
## retrieves the value at ``tbl[key]``. If `key` is not in `tbl`, ## retrieves the value at ``tbl[key]``. If `key` is not in `tbl`,
## default(T) is returned and no exception is raised. One can check ## default(T) is returned and no exception is raised. One can check
## with ``hasKey`` whether the key exists. ## with ``hasKey`` whether the key exists.
var index = RawGet(tbl, key) var index = rawGet(tbl, key)
if index >= 0: result = tbl.data[index].val if index >= 0: result = tbl.data[index].val
proc `[]=`*[T](tbl: PGenTable[T], key: string, val: T) = proc `[]=`*[T](tbl: PGenTable[T], key: string, val: T) =
## puts a (key, value)-pair into `tbl`. ## puts a (key, value)-pair into `tbl`.
var index = RawGet(tbl, key) var index = rawGet(tbl, key)
if index >= 0: if index >= 0:
tbl.data[index].val = val tbl.data[index].val = val
else: else:
if mustRehash(len(tbl.data), tbl.counter): Enlarge(tbl) if mustRehash(len(tbl.data), tbl.counter): enlarge(tbl)
RawInsert(tbl, tbl.data, key, val) rawInsert(tbl, tbl.data, key, val)
inc(tbl.counter) inc(tbl.counter)

View file

@ -422,7 +422,7 @@ proc toHtmlTag(s: string): THtmlTag =
of "wbr": tagWbr of "wbr": tagWbr
else: tagUnknown else: tagUnknown
proc htmlTag*(n: PXmlNode): THtmlTag = proc htmlTag*(n: XmlNode): THtmlTag =
## gets `n`'s tag as a ``THtmlTag``. ## gets `n`'s tag as a ``THtmlTag``.
if n.clientData == 0: if n.clientData == 0:
n.clientData = toHtmlTag(n.tag).ord n.clientData = toHtmlTag(n.tag).ord
@ -438,24 +438,24 @@ proc entityToUtf8*(entity: string): string =
## converts an HTML entity name like ``Ü`` to its UTF-8 equivalent. ## converts an HTML entity name like ``Ü`` to its UTF-8 equivalent.
## "" is returned if the entity name is unknown. The HTML parser ## "" is returned if the entity name is unknown. The HTML parser
## already converts entities to UTF-8. ## already converts entities to UTF-8.
for name, val in items(entities): for name, val in items(Entities):
if name == entity: return toUTF8(TRune(val)) if name == entity: return toUTF8(Rune(val))
result = "" result = ""
proc addNode(father, son: PXmlNode) = proc addNode(father, son: XmlNode) =
if son != nil: add(father, son) if son != nil: add(father, son)
proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode proc parse(x: var XmlParser, errors: var seq[string]): XmlNode
proc expected(x: var TXmlParser, n: PXmlNode): string = proc expected(x: var XmlParser, n: XmlNode): string =
result = errorMsg(x, "</" & n.tag & "> expected") result = errorMsg(x, "</" & n.tag & "> expected")
template elemName(x: expr): expr = rawData(x) template elemName(x: expr): expr = rawData(x)
proc untilElementEnd(x: var TXmlParser, result: PXmlNode, proc untilElementEnd(x: var XmlParser, result: XmlNode,
errors: var seq[string]) = errors: var seq[string]) =
# we parsed e.g. ``<br>`` and don't really expect a ``</br>``: # we parsed e.g. ``<br>`` and don't really expect a ``</br>``:
if result.htmlTag in singleTags: if result.htmlTag in SingleTags:
if x.kind != xmlElementEnd or cmpIgnoreCase(x.elemName, result.tag) != 0: if x.kind != xmlElementEnd or cmpIgnoreCase(x.elemName, result.tag) != 0:
return return
while true: while true:
@ -496,7 +496,7 @@ proc untilElementEnd(x: var TXmlParser, result: PXmlNode,
else: else:
result.addNode(parse(x, errors)) result.addNode(parse(x, errors))
proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode = proc parse(x: var XmlParser, errors: var seq[string]): XmlNode =
case x.kind case x.kind
of xmlComment: of xmlComment:
result = newComment(x.rawData) result = newComment(x.rawData)
@ -549,11 +549,11 @@ proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode =
next(x) next(x)
of xmlEof: discard of xmlEof: discard
proc parseHtml*(s: PStream, filename: string, proc parseHtml*(s: Stream, filename: string,
errors: var seq[string]): PXmlNode = errors: var seq[string]): XmlNode =
## parses the XML from stream `s` and returns a ``PXmlNode``. Every ## parses the XML from stream `s` and returns a ``PXmlNode``. Every
## occured parsing error is added to the `errors` sequence. ## occured parsing error is added to the `errors` sequence.
var x: TXmlParser var x: XmlParser
open(x, s, filename, {reportComments, reportWhitespace}) open(x, s, filename, {reportComments, reportWhitespace})
next(x) next(x)
# skip the DOCTYPE: # skip the DOCTYPE:
@ -573,21 +573,21 @@ proc parseHtml*(s: PStream, filename: string,
if result.len == 1: if result.len == 1:
result = result[0] result = result[0]
proc parseHtml*(s: PStream): PXmlNode = proc parseHtml*(s: Stream): XmlNode =
## parses the XTML from stream `s` and returns a ``PXmlNode``. All parsing ## parses the XTML from stream `s` and returns a ``PXmlNode``. All parsing
## errors are ignored. ## errors are ignored.
var errors: seq[string] = @[] var errors: seq[string] = @[]
result = parseHtml(s, "unknown_html_doc", errors) result = parseHtml(s, "unknown_html_doc", errors)
proc loadHtml*(path: string, errors: var seq[string]): PXmlNode = proc loadHtml*(path: string, errors: var seq[string]): XmlNode =
## Loads and parses HTML from file specified by ``path``, and returns ## Loads and parses HTML from file specified by ``path``, and returns
## a ``PXmlNode``. Every occured parsing error is added to ## a ``PXmlNode``. Every occured parsing error is added to
## the `errors` sequence. ## the `errors` sequence.
var s = newFileStream(path, fmRead) var s = newFileStream(path, fmRead)
if s == nil: raise newException(EIO, "Unable to read file: " & path) if s == nil: raise newException(IOError, "Unable to read file: " & path)
result = parseHtml(s, path, errors) result = parseHtml(s, path, errors)
proc loadHtml*(path: string): PXmlNode = proc loadHtml*(path: string): XmlNode =
## Loads and parses HTML from file specified by ``path``, and returns ## Loads and parses HTML from file specified by ``path``, and returns
## a ``PXmlNode``. All parsing errors are ignored. ## a ``PXmlNode``. All parsing errors are ignored.
var errors: seq[string] = @[] var errors: seq[string] = @[]
@ -600,7 +600,7 @@ when isMainModule:
var x = loadHtml(paramStr(1), errors) var x = loadHtml(paramStr(1), errors)
for e in items(errors): echo e for e in items(errors): echo e
var f: TFile var f: File
if open(f, "test.txt", fmWrite): if open(f, "test.txt", fmWrite):
f.write($x) f.write($x)
f.close() f.close()

View file

@ -276,14 +276,14 @@ proc parseComment(my: var XmlParser) =
my.bufpos = pos my.bufpos = pos
my.kind = xmlComment my.kind = xmlComment
proc parseWhitespace(my: var XmlParser, skip=False) = proc parseWhitespace(my: var XmlParser, skip=false) =
var pos = my.bufpos var pos = my.bufpos
var buf = my.buf var buf = my.buf
while true: while true:
case buf[pos] case buf[pos]
of ' ', '\t': of ' ', '\t':
if not skip: add(my.a, buf[pos]) if not skip: add(my.a, buf[pos])
Inc(pos) inc(pos)
of '\c': of '\c':
# the specification says that CR-LF, CR are to be transformed to LF # the specification says that CR-LF, CR are to be transformed to LF
pos = lexbase.handleCR(my, pos) pos = lexbase.handleCR(my, pos)
@ -304,7 +304,7 @@ const
proc parseName(my: var XmlParser, dest: var string) = proc parseName(my: var XmlParser, dest: var string) =
var pos = my.bufpos var pos = my.bufpos
var buf = my.buf var buf = my.buf
if buf[pos] in nameStartChar: if buf[pos] in NameStartChar:
while true: while true:
add(dest, buf[pos]) add(dest, buf[pos])
inc(pos) inc(pos)
@ -385,11 +385,11 @@ proc parsePI(my: var XmlParser) =
inc(pos) inc(pos)
of '\c': of '\c':
# the specification says that CR-LF, CR are to be transformed to LF # the specification says that CR-LF, CR are to be transformed to LF
pos = lexbase.HandleCR(my, pos) pos = lexbase.handleCR(my, pos)
buf = my.buf buf = my.buf
add(my.b, '\L') add(my.b, '\L')
of '\L': of '\L':
pos = lexbase.HandleLF(my, pos) pos = lexbase.handleLF(my, pos)
buf = my.buf buf = my.buf
add(my.b, '\L') add(my.b, '\L')
else: else:
@ -420,11 +420,11 @@ proc parseSpecial(my: var XmlParser) =
inc(pos) inc(pos)
add(my.a, '>') add(my.a, '>')
of '\c': of '\c':
pos = lexbase.HandleCR(my, pos) pos = lexbase.handleCR(my, pos)
buf = my.buf buf = my.buf
add(my.a, '\L') add(my.a, '\L')
of '\L': of '\L':
pos = lexbase.HandleLF(my, pos) pos = lexbase.handleLF(my, pos)
buf = my.buf buf = my.buf
add(my.a, '\L') add(my.a, '\L')
else: else:
@ -441,7 +441,7 @@ proc parseTag(my: var XmlParser) =
my.kind = xmlCharData my.kind = xmlCharData
add(my.a, '<') add(my.a, '<')
return return
parseWhitespace(my, skip=True) parseWhitespace(my, skip=true)
if my.buf[my.bufpos] in NameStartChar: if my.buf[my.bufpos] in NameStartChar:
# an attribute follows: # an attribute follows:
my.kind = xmlElementOpen my.kind = xmlElementOpen
@ -461,7 +461,7 @@ proc parseTag(my: var XmlParser) =
proc parseEndTag(my: var XmlParser) = proc parseEndTag(my: var XmlParser) =
inc(my.bufpos, 2) inc(my.bufpos, 2)
parseName(my, my.a) parseName(my, my.a)
parseWhitespace(my, skip=True) parseWhitespace(my, skip=true)
if my.buf[my.bufpos] == '>': if my.buf[my.bufpos] == '>':
inc(my.bufpos) inc(my.bufpos)
else: else:
@ -477,12 +477,12 @@ proc parseAttribute(my: var XmlParser) =
if my.a.len == 0: if my.a.len == 0:
markError(my, errGtExpected) markError(my, errGtExpected)
return return
parseWhitespace(my, skip=True) parseWhitespace(my, skip=true)
if my.buf[my.bufpos] != '=': if my.buf[my.bufpos] != '=':
markError(my, errEqExpected) markError(my, errEqExpected)
return return
inc(my.bufpos) inc(my.bufpos)
parseWhitespace(my, skip=True) parseWhitespace(my, skip=true)
var pos = my.bufpos var pos = my.bufpos
var buf = my.buf var buf = my.buf
@ -507,11 +507,11 @@ proc parseAttribute(my: var XmlParser) =
pendingSpace = true pendingSpace = true
inc(pos) inc(pos)
of '\c': of '\c':
pos = lexbase.HandleCR(my, pos) pos = lexbase.handleCR(my, pos)
buf = my.buf buf = my.buf
pendingSpace = true pendingSpace = true
of '\L': of '\L':
pos = lexbase.HandleLF(my, pos) pos = lexbase.handleLF(my, pos)
buf = my.buf buf = my.buf
pendingSpace = true pendingSpace = true
else: else:
@ -527,7 +527,7 @@ proc parseAttribute(my: var XmlParser) =
else: else:
markError(my, errQuoteExpected) markError(my, errQuoteExpected)
my.bufpos = pos my.bufpos = pos
parseWhitespace(my, skip=True) parseWhitespace(my, skip=true)
proc parseCharData(my: var XmlParser) = proc parseCharData(my: var XmlParser) =
var pos = my.bufpos var pos = my.bufpos
@ -537,11 +537,11 @@ proc parseCharData(my: var XmlParser) =
of '\0', '<', '&': break of '\0', '<', '&': break
of '\c': of '\c':
# the specification says that CR-LF, CR are to be transformed to LF # the specification says that CR-LF, CR are to be transformed to LF
pos = lexbase.HandleCR(my, pos) pos = lexbase.handleCR(my, pos)
buf = my.buf buf = my.buf
add(my.a, '\L') add(my.a, '\L')
of '\L': of '\L':
pos = lexbase.HandleLF(my, pos) pos = lexbase.handleLF(my, pos)
buf = my.buf buf = my.buf
add(my.a, '\L') add(my.a, '\L')
else: else:

View file

@ -186,7 +186,7 @@ proc `&`*(a: string, b: Rope): Rope {.rtl, extern: "nroConcStrRope".} =
## the concatenation operator for ropes. ## the concatenation operator for ropes.
result = rope(a) & b result = rope(a) & b
proc `&`*(a: openarray[Rope]): Rope {.rtl, extern: "nroConcOpenArray".} = proc `&`*(a: openArray[Rope]): Rope {.rtl, extern: "nroConcOpenArray".} =
## the concatenation operator for an openarray of ropes. ## the concatenation operator for an openarray of ropes.
for i in countup(0, high(a)): result = result & a[i] for i in countup(0, high(a)): result = result & a[i]
@ -233,7 +233,7 @@ iterator items*(r: Rope): char =
for s in leaves(r): for s in leaves(r):
for c in items(s): yield c for c in items(s): yield c
proc write*(f: TFile, r: Rope) {.rtl, extern: "nro$1".} = proc write*(f: File, r: Rope) {.rtl, extern: "nro$1".} =
## writes a rope to a file. ## writes a rope to a file.
for s in leaves(r): write(f, s) for s in leaves(r): write(f, s)
@ -291,7 +291,7 @@ when false:
if i - 1 >= start: if i - 1 >= start:
add(result, substr(frmt, start, i-1)) add(result, substr(frmt, start, i-1))
proc `%`*(frmt: string, args: openarray[Rope]): Rope {. proc `%`*(frmt: string, args: openArray[Rope]): Rope {.
rtl, extern: "nroFormat".} = rtl, extern: "nroFormat".} =
## `%` substitution operator for ropes. Does not support the ``$identifier`` ## `%` substitution operator for ropes. Does not support the ``$identifier``
## nor ``${identifier}`` notations. ## nor ``${identifier}`` notations.
@ -324,9 +324,9 @@ proc `%`*(frmt: string, args: openarray[Rope]): Rope {.
j = j * 10 + ord(frmt[i]) - ord('0') j = j * 10 + ord(frmt[i]) - ord('0')
inc(i) inc(i)
if frmt[i] == '}': inc(i) if frmt[i] == '}': inc(i)
else: raise newException(EInvalidValue, "invalid format string") else: raise newException(ValueError, "invalid format string")
add(result, args[j-1]) add(result, args[j-1])
else: raise newException(EInvalidValue, "invalid format string") else: raise newException(ValueError, "invalid format string")
var start = i var start = i
while i < length: while i < length:
if frmt[i] != '$': inc(i) if frmt[i] != '$': inc(i)
@ -334,15 +334,15 @@ proc `%`*(frmt: string, args: openarray[Rope]): Rope {.
if i - 1 >= start: if i - 1 >= start:
add(result, substr(frmt, start, i - 1)) add(result, substr(frmt, start, i - 1))
proc addf*(c: var Rope, frmt: string, args: openarray[Rope]) {. proc addf*(c: var Rope, frmt: string, args: openArray[Rope]) {.
rtl, extern: "nro$1".} = rtl, extern: "nro$1".} =
## shortcut for ``add(c, frmt % args)``. ## shortcut for ``add(c, frmt % args)``.
add(c, frmt % args) add(c, frmt % args)
proc equalsFile*(r: Rope, f: TFile): bool {.rtl, extern: "nro$1File".} = proc equalsFile*(r: Rope, f: File): bool {.rtl, extern: "nro$1File".} =
## returns true if the contents of the file `f` equal `r`. ## returns true if the contents of the file `f` equal `r`.
var bufSize = 1024 # reasonable start value var bufSize = 1024 # reasonable start value
var buf = alloc(BufSize) var buf = alloc(bufSize)
for s in leaves(r): for s in leaves(r):
if s.len > bufSize: if s.len > bufSize:
bufSize = max(bufSize * 2, s.len) bufSize = max(bufSize * 2, s.len)
@ -357,7 +357,7 @@ proc equalsFile*(r: Rope, f: TFile): bool {.rtl, extern: "nro$1File".} =
proc equalsFile*(r: Rope, f: string): bool {.rtl, extern: "nro$1Str".} = proc equalsFile*(r: Rope, f: string): bool {.rtl, extern: "nro$1Str".} =
## returns true if the contents of the file `f` equal `r`. If `f` does not ## returns true if the contents of the file `f` equal `r`. If `f` does not
## exist, false is returned. ## exist, false is returned.
var bin: TFile var bin: File
result = open(bin, f) result = open(bin, f)
if result: if result:
result = equalsFile(r, bin) result = equalsFile(r, bin)

View file

@ -2694,7 +2694,7 @@ elif defined(JS):
proc GC_disable() = discard proc GC_disable() = discard
proc GC_enable() = discard proc GC_enable() = discard
proc GC_fullCollect() = discard proc GC_fullCollect() = discard
proc GC_setStrategy(strategy: TGC_Strategy) = discard proc GC_setStrategy(strategy: GC_Strategy) = discard
proc GC_enableMarkAndSweep() = discard proc GC_enableMarkAndSweep() = discard
proc GC_disableMarkAndSweep() = discard proc GC_disableMarkAndSweep() = discard
proc GC_getStatistics(): string = return "" proc GC_getStatistics(): string = return ""
@ -2706,7 +2706,7 @@ elif defined(JS):
proc dealloc(p: pointer) = discard proc dealloc(p: pointer) = discard
proc alloc(size: int): pointer = discard proc alloc(size: int): pointer = discard
proc alloc0(size: int): pointer = discard proc alloc0(size: int): pointer = discard
proc realloc(p: Pointer, newsize: int): pointer = discard proc realloc(p: pointer, newsize: int): pointer = discard
proc allocShared(size: int): pointer = discard proc allocShared(size: int): pointer = discard
proc allocShared0(size: int): pointer = discard proc allocShared0(size: int): pointer = discard

View file

@ -31,7 +31,7 @@ when someGcc and hasThreadSupport:
## with acquire loads ## with acquire loads
## and release stores in all threads. ## and release stores in all threads.
TAtomType* = TNumber|pointer|ptr|char TAtomType* = SomeNumber|pointer|ptr|char
## Type Class representing valid types for use with atomic procs ## Type Class representing valid types for use with atomic procs
proc atomicLoadN*[T: TAtomType](p: ptr T, mem: AtomMemModel): T {. proc atomicLoadN*[T: TAtomType](p: ptr T, mem: AtomMemModel): T {.

View file

@ -53,8 +53,8 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel,
proc storeAux(dest, src: pointer, n: ptr TNimNode, t: PRawChannel, proc storeAux(dest, src: pointer, n: ptr TNimNode, t: PRawChannel,
mode: TLoadStoreMode) {.gcsafe.} = mode: TLoadStoreMode) {.gcsafe.} =
var var
d = cast[TAddress](dest) d = cast[ByteAddress](dest)
s = cast[TAddress](src) s = cast[ByteAddress](src)
case n.kind case n.kind
of nkSlot: storeAux(cast[pointer](d +% n.offset), of nkSlot: storeAux(cast[pointer](d +% n.offset),
cast[pointer](s +% n.offset), n.typ, t, mode) cast[pointer](s +% n.offset), n.typ, t, mode)
@ -70,8 +70,8 @@ proc storeAux(dest, src: pointer, n: ptr TNimNode, t: PRawChannel,
proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel,
mode: TLoadStoreMode) = mode: TLoadStoreMode) =
var var
d = cast[TAddress](dest) d = cast[ByteAddress](dest)
s = cast[TAddress](src) s = cast[ByteAddress](src)
sysAssert(mt != nil, "mt == nil") sysAssert(mt != nil, "mt == nil")
case mt.kind case mt.kind
of tyString: of tyString:
@ -108,11 +108,11 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel,
x[] = alloc(t.region, seq.len *% mt.base.size +% GenericSeqSize) x[] = alloc(t.region, seq.len *% mt.base.size +% GenericSeqSize)
else: else:
unsureAsgnRef(x, newObj(mt, seq.len * mt.base.size + GenericSeqSize)) unsureAsgnRef(x, newObj(mt, seq.len * mt.base.size + GenericSeqSize))
var dst = cast[TAddress](cast[PPointer](dest)[]) var dst = cast[ByteAddress](cast[PPointer](dest)[])
for i in 0..seq.len-1: for i in 0..seq.len-1:
storeAux( storeAux(
cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize), cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize),
cast[pointer](cast[TAddress](s2) +% i *% mt.base.size +% cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +%
GenericSeqSize), GenericSeqSize),
mt.base, t, mode) mt.base, t, mode)
var dstseq = cast[PGenericSeq](dst) var dstseq = cast[PGenericSeq](dst)
@ -192,7 +192,7 @@ template lockChannel(q: expr, action: stmt) {.immediate.} =
template sendImpl(q: expr) {.immediate.} = template sendImpl(q: expr) {.immediate.} =
if q.mask == ChannelDeadMask: if q.mask == ChannelDeadMask:
sysFatal(EDeadThread, "cannot send message; thread died") sysFatal(DeadThreadError, "cannot send message; thread died")
acquireSys(q.lock) acquireSys(q.lock)
var m: TMsg var m: TMsg
shallowCopy(m, msg) shallowCopy(m, msg)
@ -215,7 +215,7 @@ proc llRecv(q: PRawChannel, res: pointer, typ: PNimType) =
q.ready = false q.ready = false
if typ != q.elemType: if typ != q.elemType:
releaseSys(q.lock) releaseSys(q.lock)
sysFatal(EInvalidValue, "cannot receive message of wrong type") sysFatal(ValueError, "cannot receive message of wrong type")
rawRecv(q, res, typ) rawRecv(q, res, typ)
proc recv*[TMsg](c: var TChannel[TMsg]): TMsg = proc recv*[TMsg](c: var TChannel[TMsg]): TMsg =

View file

@ -80,11 +80,11 @@ template gcAssert(cond: bool, msg: string) =
proc cellToUsr(cell: PCell): pointer {.inline.} = proc cellToUsr(cell: PCell): pointer {.inline.} =
# convert object (=pointer to refcount) to pointer to userdata # convert object (=pointer to refcount) to pointer to userdata
result = cast[pointer](cast[TAddress](cell)+%TAddress(sizeof(TCell))) result = cast[pointer](cast[ByteAddress](cell)+%ByteAddress(sizeof(TCell)))
proc usrToCell(usr: pointer): PCell {.inline.} = proc usrToCell(usr: pointer): PCell {.inline.} =
# convert pointer to userdata to object (=pointer to refcount) # convert pointer to userdata to object (=pointer to refcount)
result = cast[PCell](cast[TAddress](usr)-%TAddress(sizeof(TCell))) result = cast[PCell](cast[ByteAddress](usr)-%ByteAddress(sizeof(TCell)))
proc canbeCycleRoot(c: PCell): bool {.inline.} = proc canbeCycleRoot(c: PCell): bool {.inline.} =
result = ntfAcyclic notin c.typ.flags result = ntfAcyclic notin c.typ.flags
@ -169,7 +169,7 @@ proc initGC() =
init(gch.marked) init(gch.marked)
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} = proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} =
var d = cast[TAddress](dest) var d = cast[ByteAddress](dest)
case n.kind case n.kind
of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op) of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op)
of nkList: of nkList:
@ -181,7 +181,7 @@ proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} =
of nkNone: sysAssert(false, "forAllSlotsAux") of nkNone: sysAssert(false, "forAllSlotsAux")
proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) = proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) =
var d = cast[TAddress](dest) var d = cast[ByteAddress](dest)
if dest == nil: return # nothing to do if dest == nil: return # nothing to do
if ntfNoRefs notin mt.flags: if ntfNoRefs notin mt.flags:
case mt.kind case mt.kind
@ -206,7 +206,7 @@ proc forAllChildren(cell: PCell, op: TWalkOp) =
of tyRef: # common case of tyRef: # common case
forAllChildrenAux(cellToUsr(cell), cell.typ.base, op) forAllChildrenAux(cellToUsr(cell), cell.typ.base, op)
of tySequence: of tySequence:
var d = cast[TAddress](cellToUsr(cell)) var d = cast[ByteAddress](cellToUsr(cell))
var s = cast[PGenericSeq](d) var s = cast[PGenericSeq](d)
if s != nil: if s != nil:
for i in 0..s.len-1: for i in 0..s.len-1:
@ -220,7 +220,7 @@ proc rawNewObj(typ: PNimType, size: int, gch: var TGcHeap): pointer =
gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1") gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1")
collectCT(gch) collectCT(gch)
var res = cast[PCell](rawAlloc(gch.region, size + sizeof(TCell))) var res = cast[PCell](rawAlloc(gch.region, size + sizeof(TCell)))
gcAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "newObj: 2") gcAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "newObj: 2")
# now it is buffered in the ZCT # now it is buffered in the ZCT
res.typ = typ res.typ = typ
when leakDetector and not hasThreadSupport: when leakDetector and not hasThreadSupport:
@ -280,9 +280,9 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
var oldsize = cast[PGenericSeq](old).len*elemSize + GenericSeqSize var oldsize = cast[PGenericSeq](old).len*elemSize + GenericSeqSize
copyMem(res, ol, oldsize + sizeof(TCell)) copyMem(res, ol, oldsize + sizeof(TCell))
zeroMem(cast[pointer](cast[TAddress](res)+% oldsize +% sizeof(TCell)), zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)),
newsize-oldsize) newsize-oldsize)
sysAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "growObj: 3") sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
when withBitvectors: excl(gch.allocated, ol) when withBitvectors: excl(gch.allocated, ol)
when reallyDealloc: rawDealloc(gch.region, ol) when reallyDealloc: rawDealloc(gch.region, ol)
else: else:
@ -379,7 +379,7 @@ proc markGlobals(gch: var TGcHeap) =
proc gcMark(gch: var TGcHeap, p: pointer) {.inline.} = proc gcMark(gch: var TGcHeap, p: pointer) {.inline.} =
# the addresses are not as cells on the stack, so turn them to cells: # the addresses are not as cells on the stack, so turn them to cells:
var cell = usrToCell(p) var cell = usrToCell(p)
var c = cast[TAddress](cell) var c = cast[ByteAddress](cell)
if c >% PageSize: if c >% PageSize:
# fast check: does it look like a cell? # fast check: does it look like a cell?
var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell)) var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell))
@ -404,8 +404,8 @@ when not defined(useNimRtl):
# the first init must be the one that defines the stack bottom: # the first init must be the one that defines the stack bottom:
if gch.stackBottom == nil: gch.stackBottom = theStackBottom if gch.stackBottom == nil: gch.stackBottom = theStackBottom
else: else:
var a = cast[TAddress](theStackBottom) # and not PageMask - PageSize*2 var a = cast[ByteAddress](theStackBottom) # and not PageMask - PageSize*2
var b = cast[TAddress](gch.stackBottom) var b = cast[ByteAddress](gch.stackBottom)
#c_fprintf(c_stdout, "old: %p new: %p;\n",gch.stackBottom,theStackBottom) #c_fprintf(c_stdout, "old: %p new: %p;\n",gch.stackBottom,theStackBottom)
when stackIncreases: when stackIncreases:
gch.stackBottom = cast[pointer](min(a, b)) gch.stackBottom = cast[pointer](min(a, b))
@ -421,9 +421,9 @@ when defined(sparc): # For SPARC architecture.
proc isOnStack(p: pointer): bool = proc isOnStack(p: pointer): bool =
var stackTop {.volatile.}: pointer var stackTop {.volatile.}: pointer
stackTop = addr(stackTop) stackTop = addr(stackTop)
var b = cast[TAddress](gch.stackBottom) var b = cast[ByteAddress](gch.stackBottom)
var a = cast[TAddress](stackTop) var a = cast[ByteAddress](stackTop)
var x = cast[TAddress](p) var x = cast[ByteAddress](p)
result = a <=% x and x <=% b result = a <=% x and x <=% b
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} = proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
@ -440,7 +440,7 @@ when defined(sparc): # For SPARC architecture.
# Addresses decrease as the stack grows. # Addresses decrease as the stack grows.
while sp <= max: while sp <= max:
gcMark(gch, sp[]) gcMark(gch, sp[])
sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer)) sp = cast[ppointer](cast[ByteAddress](sp) +% sizeof(pointer))
elif defined(ELATE): elif defined(ELATE):
{.error: "stack marking code is to be written for this architecture".} {.error: "stack marking code is to be written for this architecture".}
@ -452,9 +452,9 @@ elif stackIncreases:
proc isOnStack(p: pointer): bool = proc isOnStack(p: pointer): bool =
var stackTop {.volatile.}: pointer var stackTop {.volatile.}: pointer
stackTop = addr(stackTop) stackTop = addr(stackTop)
var a = cast[TAddress](gch.stackBottom) var a = cast[ByteAddress](gch.stackBottom)
var b = cast[TAddress](stackTop) var b = cast[ByteAddress](stackTop)
var x = cast[TAddress](p) var x = cast[ByteAddress](p)
result = a <=% x and x <=% b result = a <=% x and x <=% b
var var
@ -465,8 +465,8 @@ elif stackIncreases:
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} = proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
var registers: C_JmpBuf var registers: C_JmpBuf
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers. if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
var max = cast[TAddress](gch.stackBottom) var max = cast[ByteAddress](gch.stackBottom)
var sp = cast[TAddress](addr(registers)) +% jmpbufSize -% sizeof(pointer) var sp = cast[ByteAddress](addr(registers)) +% jmpbufSize -% sizeof(pointer)
# sp will traverse the JMP_BUF as well (jmp_buf size is added, # sp will traverse the JMP_BUF as well (jmp_buf size is added,
# otherwise sp would be below the registers structure). # otherwise sp would be below the registers structure).
while sp >=% max: while sp >=% max:
@ -480,9 +480,9 @@ else:
proc isOnStack(p: pointer): bool = proc isOnStack(p: pointer): bool =
var stackTop {.volatile.}: pointer var stackTop {.volatile.}: pointer
stackTop = addr(stackTop) stackTop = addr(stackTop)
var b = cast[TAddress](gch.stackBottom) var b = cast[ByteAddress](gch.stackBottom)
var a = cast[TAddress](stackTop) var a = cast[ByteAddress](stackTop)
var x = cast[TAddress](p) var x = cast[ByteAddress](p)
result = a <=% x and x <=% b result = a <=% x and x <=% b
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} = proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
@ -492,8 +492,8 @@ else:
type PStackSlice = ptr array [0..7, pointer] type PStackSlice = ptr array [0..7, pointer]
var registers {.noinit.}: C_JmpBuf var registers {.noinit.}: C_JmpBuf
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers. if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
var max = cast[TAddress](gch.stackBottom) var max = cast[ByteAddress](gch.stackBottom)
var sp = cast[TAddress](addr(registers)) var sp = cast[ByteAddress](addr(registers))
# loop unrolled: # loop unrolled:
while sp <% max - 8*sizeof(pointer): while sp <% max - 8*sizeof(pointer):
gcMark(gch, cast[PStackSlice](sp)[0]) gcMark(gch, cast[PStackSlice](sp)[0])
@ -546,7 +546,7 @@ when not defined(useNimRtl):
else: else:
dec(gch.recGcLock) dec(gch.recGcLock)
proc GC_setStrategy(strategy: TGC_Strategy) = discard proc GC_setStrategy(strategy: GC_Strategy) = discard
proc GC_enableMarkAndSweep() = proc GC_enableMarkAndSweep() =
gch.cycleThreshold = InitialThreshold gch.cycleThreshold = InitialThreshold

View file

@ -18,7 +18,7 @@ type
PSafePoint = ptr TSafePoint PSafePoint = ptr TSafePoint
TSafePoint {.compilerproc, final.} = object TSafePoint {.compilerproc, final.} = object
prev: PSafePoint # points to next safe point prev: PSafePoint # points to next safe point
exc: ref E_Base exc: ref Exception
PCallFrame = ptr TCallFrame PCallFrame = ptr TCallFrame
TCallFrame {.importc, nodecl, final.} = object TCallFrame {.importc, nodecl, final.} = object
@ -97,7 +97,7 @@ proc rawWriteStackTrace(): string =
else: else:
result = "No stack traceback available\n" result = "No stack traceback available\n"
proc raiseException(e: ref E_Base, ename: cstring) {. proc raiseException(e: ref Exception, ename: cstring) {.
compilerproc, asmNoStackFrame.} = compilerproc, asmNoStackFrame.} =
e.name = ename e.name = ename
if excHandler != nil: if excHandler != nil:
@ -120,24 +120,24 @@ proc raiseException(e: ref E_Base, ename: cstring) {.
proc reraiseException() {.compilerproc, asmNoStackFrame.} = proc reraiseException() {.compilerproc, asmNoStackFrame.} =
if excHandler == nil: if excHandler == nil:
raise newException(ENoExceptionToReraise, "no exception to reraise") raise newException(ReraiseError, "no exception to reraise")
else: else:
asm """throw excHandler.exc;""" asm """throw excHandler.exc;"""
proc raiseOverflow {.exportc: "raiseOverflow", noreturn.} = proc raiseOverflow {.exportc: "raiseOverflow", noreturn.} =
raise newException(EOverflow, "over- or underflow") raise newException(OverflowError, "over- or underflow")
proc raiseDivByZero {.exportc: "raiseDivByZero", noreturn.} = proc raiseDivByZero {.exportc: "raiseDivByZero", noreturn.} =
raise newException(EDivByZero, "divison by zero") raise newException(DivByZeroError, "divison by zero")
proc raiseRangeError() {.compilerproc, noreturn.} = proc raiseRangeError() {.compilerproc, noreturn.} =
raise newException(EOutOfRange, "value out of range") raise newException(RangeError, "value out of range")
proc raiseIndexError() {.compilerproc, noreturn.} = proc raiseIndexError() {.compilerproc, noreturn.} =
raise newException(EInvalidIndex, "index out of bounds") raise newException(IndexError, "index out of bounds")
proc raiseFieldError(f: string) {.compilerproc, noreturn.} = proc raiseFieldError(f: string) {.compilerproc, noreturn.} =
raise newException(EInvalidField, f & " is not accessible") raise newException(FieldError, f & " is not accessible")
proc SetConstr() {.varargs, asmNoStackFrame, compilerproc.} = proc SetConstr() {.varargs, asmNoStackFrame, compilerproc.} =
asm """ asm """
@ -260,7 +260,7 @@ proc eqStrings(a, b: string): bool {.asmNoStackFrame, compilerProc.} =
""" """
type type
TDocument {.importc.} = object of TObject TDocument {.importc.} = object of RootObj
write: proc (text: cstring) {.nimcall.} write: proc (text: cstring) {.nimcall.}
writeln: proc (text: cstring) {.nimcall.} writeln: proc (text: cstring) {.nimcall.}
createAttribute: proc (identifier: cstring): ref TNode {.nimcall.} createAttribute: proc (identifier: cstring): ref TNode {.nimcall.}
@ -283,7 +283,7 @@ type
DocumentTypeNode, DocumentTypeNode,
DocumentFragmentNode, DocumentFragmentNode,
NotationNode NotationNode
TNode* {.importc.} = object of TObject TNode* {.importc.} = object of RootObj
attributes*: seq[ref TNode] attributes*: seq[ref TNode]
childNodes*: seq[ref TNode] childNodes*: seq[ref TNode]
data*: cstring data*: cstring
@ -515,7 +515,7 @@ proc isFatPointer(ti: PNimType): bool =
proc nimCopy(x: pointer, ti: PNimType): pointer {.compilerproc.} proc nimCopy(x: pointer, ti: PNimType): pointer {.compilerproc.}
proc nimCopyAux(dest, src: Pointer, n: ptr TNimNode) {.compilerproc.} = proc nimCopyAux(dest, src: pointer, n: ptr TNimNode) {.compilerproc.} =
case n.kind case n.kind
of nkNone: sysAssert(false, "nimCopyAux") of nkNone: sysAssert(false, "nimCopyAux")
of nkSlot: of nkSlot:
@ -566,7 +566,7 @@ proc nimCopy(x: pointer, ti: PNimType): pointer =
else: else:
result = x result = x
proc genericReset(x: Pointer, ti: PNimType): pointer {.compilerproc.} = proc genericReset(x: pointer, ti: PNimType): pointer {.compilerproc.} =
case ti.kind case ti.kind
of tyPtr, tyRef, tyVar, tyNil: of tyPtr, tyRef, tyVar, tyNil:
if not isFatPointer(ti): if not isFatPointer(ti):
@ -621,7 +621,7 @@ proc chckObj(obj, subclass: PNimType) {.compilerproc.} =
if x == subclass: return # optimized fast path if x == subclass: return # optimized fast path
while x != subclass: while x != subclass:
if x == nil: if x == nil:
raise newException(EInvalidObjectConversion, "invalid object conversion") raise newException(ObjectConversionError, "invalid object conversion")
x = x.base x = x.base
proc isObj(obj, subclass: PNimType): bool {.compilerproc.} = proc isObj(obj, subclass: PNimType): bool {.compilerproc.} =

View file

@ -305,22 +305,26 @@ proc running*[TArg](t: TThread[TArg]): bool {.inline.} =
## returns true if `t` is running. ## returns true if `t` is running.
result = t.dataFn != nil result = t.dataFn != nil
proc joinThread*[TArg](t: TThread[TArg]) {.inline.} = when hostOS == "windows":
## waits for the thread `t` to finish. proc joinThread*[TArg](t: TThread[TArg]) {.inline.} =
when hostOS == "windows": ## waits for the thread `t` to finish.
discard waitForSingleObject(t.sys, -1'i32) discard waitForSingleObject(t.sys, -1'i32)
else:
discard pthread_join(t.sys, nil)
proc joinThreads*[TArg](t: varargs[TThread[TArg]]) = proc joinThreads*[TArg](t: varargs[TThread[TArg]]) =
## waits for every thread in `t` to finish. ## waits for every thread in `t` to finish.
when hostOS == "windows":
var a: array[0..255, TSysThread] var a: array[0..255, TSysThread]
sysAssert a.len >= t.len, "a.len >= t.len" sysAssert a.len >= t.len, "a.len >= t.len"
for i in 0..t.high: a[i] = t[i].sys for i in 0..t.high: a[i] = t[i].sys
discard waitForMultipleObjects(t.len.int32, discard waitForMultipleObjects(t.len.int32,
cast[ptr TSysThread](addr(a)), 1, -1) cast[ptr TSysThread](addr(a)), 1, -1)
else:
else:
proc joinThread*[TArg](t: TThread[TArg]) {.inline.} =
## waits for the thread `t` to finish.
discard pthread_join(t.sys, nil)
proc joinThreads*[TArg](t: varargs[TThread[TArg]]) =
## waits for every thread in `t` to finish.
for i in 0..t.high: joinThread(t[i]) for i in 0..t.high: joinThread(t[i])
when false: when false:
@ -335,27 +339,37 @@ when false:
when declared(registerThread): unregisterThread(addr(t)) when declared(registerThread): unregisterThread(addr(t))
t.dataFn = nil t.dataFn = nil
proc createThread*[TArg](t: var TThread[TArg], when hostOS == "windows":
tp: proc (arg: TArg) {.thread.}, proc createThread*[TArg](t: var TThread[TArg],
param: TArg) = tp: proc (arg: TArg) {.thread.},
## creates a new thread `t` and starts its execution. Entry point is the param: TArg) =
## proc `tp`. `param` is passed to `tp`. `TArg` can be ``void`` if you ## creates a new thread `t` and starts its execution. Entry point is the
## don't need to pass any data to the thread. ## proc `tp`. `param` is passed to `tp`. `TArg` can be ``void`` if you
when TArg isnot void: t.data = param ## don't need to pass any data to the thread.
t.dataFn = tp when TArg isnot void: t.data = param
when hasSharedHeap: t.stackSize = ThreadStackSize t.dataFn = tp
when hostOS == "windows": when hasSharedHeap: t.stackSize = ThreadStackSize
var dummyThreadId: int32 var dummyThreadId: int32
t.sys = createThread(nil, ThreadStackSize, threadProcWrapper[TArg], t.sys = createThread(nil, ThreadStackSize, threadProcWrapper[TArg],
addr(t), 0'i32, dummyThreadId) addr(t), 0'i32, dummyThreadId)
if t.sys <= 0: if t.sys <= 0:
raise newException(EResourceExhausted, "cannot create thread") raise newException(ResourceExhaustedError, "cannot create thread")
else:
else:
proc createThread*[TArg](t: var TThread[TArg],
tp: proc (arg: TArg) {.thread.},
param: TArg) =
## creates a new thread `t` and starts its execution. Entry point is the
## proc `tp`. `param` is passed to `tp`. `TArg` can be ``void`` if you
## don't need to pass any data to the thread.
when TArg isnot void: t.data = param
t.dataFn = tp
when hasSharedHeap: t.stackSize = ThreadStackSize
var a {.noinit.}: Tpthread_attr var a {.noinit.}: Tpthread_attr
pthread_attr_init(a) pthread_attr_init(a)
pthread_attr_setstacksize(a, ThreadStackSize) pthread_attr_setstacksize(a, ThreadStackSize)
if pthread_create(t.sys, a, threadProcWrapper[TArg], addr(t)) != 0: if pthread_create(t.sys, a, threadProcWrapper[TArg], addr(t)) != 0:
raise newException(EResourceExhausted, "cannot create thread") raise newException(ResourceExhaustedError, "cannot create thread")
proc threadId*[TArg](t: var TThread[TArg]): TThreadId[TArg] {.inline.} = proc threadId*[TArg](t: var TThread[TArg]): TThreadId[TArg] {.inline.} =
## returns the thread ID of `t`. ## returns the thread ID of `t`.

View file

@ -5,7 +5,7 @@ discard """
# Test the case statement # Test the case statement
type type
tenum = enum eA, eB, eC Tenum = enum eA, eB, eC
var var
x: string = "yyy" x: string = "yyy"

View file

@ -20,46 +20,46 @@ proc threadFunc(interval: tuple[a, b: int]) {.thread.} =
when nodeadlocks: when nodeadlocks:
case i mod 6 case i mod 6
of 0: of 0:
Acquire(L) # lock stdout acquire(L) # lock stdout
Acquire(M) acquire(M)
Acquire(N) acquire(N)
of 1: of 1:
Acquire(L) acquire(L)
Acquire(N) # lock stdout acquire(N) # lock stdout
Acquire(M) acquire(M)
of 2: of 2:
Acquire(M) acquire(M)
Acquire(L) acquire(L)
Acquire(N) acquire(N)
of 3: of 3:
Acquire(M) acquire(M)
Acquire(N) acquire(N)
Acquire(L) acquire(L)
of 4: of 4:
Acquire(N) acquire(N)
Acquire(M) acquire(M)
Acquire(L) acquire(L)
of 5: of 5:
Acquire(N) acquire(N)
Acquire(L) acquire(L)
Acquire(M) acquire(M)
else: assert false else: assert false
else: else:
Acquire(L) # lock stdout acquire(L) # lock stdout
Acquire(M) acquire(M)
echo i echo i
os.sleep(10) os.sleep(10)
when nodeadlocks: when nodeadlocks:
echo "deadlocks prevented: ", deadlocksPrevented echo "deadlocks prevented: ", deadlocksPrevented
when nodeadlocks: when nodeadlocks:
Release(N) release(N)
Release(M) release(M)
Release(L) release(L)
InitLock(L) initLock(L)
InitLock(M) initLock(M)
InitLock(N) initLock(N)
proc main = proc main =
for i in 0..high(thr): for i in 0..high(thr):

View file

@ -10,7 +10,7 @@ type
s: string, s: string,
x, y: int, x, y: int,
z: float, z: float,
chars: set[Char]] chars: set[char]]
proc testSem = proc testSem =
var var

View file

@ -1,6 +1,6 @@
discard """ discard """
file: "tfloat1.nim" file: "tfloat1.nim"
outputsub: "Error: unhandled exception: FPU operation caused an overflow [EFloatOverflow]" outputsub: "Error: unhandled exception: FPU operation caused an overflow [FloatOverflowError]"
exitcode: "1" exitcode: "1"
""" """
# Test new floating point exceptions # Test new floating point exceptions
@ -10,6 +10,6 @@ discard """
var x = 0.8 var x = 0.8
var y = 0.0 var y = 0.0
echo x / y #OUT Error: unhandled exception: FPU operation caused an overflow [EFloatOverflow] echo x / y #OUT Error: unhandled exception: FPU operation caused an overflow

View file

@ -1,6 +1,6 @@
discard """ discard """
file: "tfloat2.nim" file: "tfloat2.nim"
outputsub: "Error: unhandled exception: FPU operation caused a NaN result [EFloatInvalidOp]" outputsub: "Error: unhandled exception: FPU operation caused a NaN result [FloatInvalidOpError]"
exitcode: "1" exitcode: "1"
""" """
# Test new floating point exceptions # Test new floating point exceptions
@ -10,6 +10,6 @@ discard """
var x = 0.0 var x = 0.0
var y = 0.0 var y = 0.0
echo x / y #OUT Error: unhandled exception: FPU operation caused a NaN result [EFloatInvalidOp] echo x / y #OUT Error: unhandled exception: FPU operation caused a NaN result

View file

@ -13,7 +13,7 @@ void printFloats(void) {
} }
""".} """.}
proc c_printf(frmt: CString) {.importc: "printf", header: "<stdio.h>", varargs.} proc c_printf(frmt: cstring) {.importc: "printf", header: "<stdio.h>", varargs.}
proc printFloats {.importc, nodecl.} proc printFloats {.importc, nodecl.}
var x: float = 1.234567890123456789 var x: float = 1.234567890123456789

View file

@ -29,5 +29,5 @@ for i in 0 .. <10:
f.func = proc = f.func = proc =
echo f.id echo f.id
gc_fullcollect() GC_fullcollect()
echo alive_foos.len <= 3 echo alive_foos.len <= 3

View file

@ -18,7 +18,7 @@ proc newDict*[TKey, TValue](): PDict[TKey, TValue] =
proc add*[TKey, TValue](d: PDict[TKey, TValue], k: TKey, v: TValue) = proc add*[TKey, TValue](d: PDict[TKey, TValue], k: TKey, v: TValue) =
d.data.add((k, v)) d.data.add((k, v))
iterator items*[Tkey, tValue](d: PDict[TKey, TValue]): tuple[k: TKey, iterator items*[Tkey, TValue](d: PDict[TKey, TValue]): tuple[k: TKey,
v: TValue] = v: TValue] =
for k, v in items(d.data): yield (k, v) for k, v in items(d.data): yield (k, v)

View file

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

View file

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

View file

@ -25,7 +25,7 @@ proc filter[T,D](data: seq[T], env:D, pred: TFilterProc[T,D]): seq[T] =
for e in data: for e in data:
if pred(e, env): result.add(e) if pred(e, env): result.add(e)
proc predTest(item: int, value: int): Bool = proc predTest(item: int, value: int): bool =
return item <= value return item <= value
proc test(data: seq[int], value: int): seq[int] = proc test(data: seq[int], value: int): seq[int] =

View file

@ -1,15 +1,15 @@
type type
TMaybe[T] = object TMaybe[T] = object
case empty: Bool case empty: bool
of False: value: T of false: value: T
else: nil else: nil
proc Just*[T](val: T): TMaybe[T] = proc Just*[T](val: T): TMaybe[T] =
result.empty = False result.empty = false
result.value = val result.value = val
proc Nothing[T](): TMaybe[T] = proc Nothing[T](): TMaybe[T] =
result.empty = True result.empty = true
proc safeReadLine(): TMaybe[string] = proc safeReadLine(): TMaybe[string] =
var r = stdin.readLine() var r = stdin.readLine()

View file

@ -44,8 +44,8 @@ block Test1:
# a non-generic iterator! # a non-generic iterator!
var t = initTable[int, string]() var t = initTable[int, string]()
for k, v in t.pairs: nil for k, v in t.pairs: discard
for k, v in t.pairs: nil for k, v in t.pairs: discard
echo "true" echo "true"

View file

@ -21,13 +21,13 @@ iterator tokenize2(s: string, seps: set[char] = Whitespace): tuple[
yield (substr(s, i, j-1), false) yield (substr(s, i, j-1), false)
i = j i = j
for word, isSep in tokenize2("ta da", whiteSpace): for word, isSep in tokenize2("ta da", WhiteSpace):
var titer2TestVar = 0 var titer2TestVar = 0
stdout.write(titer2TestVar) stdout.write(titer2TestVar)
proc wordWrap2(s: string, maxLineWidth = 80, proc wordWrap2(s: string, maxLineWidth = 80,
splitLongWords = true, splitLongWords = true,
seps: set[char] = whitespace, seps: set[char] = Whitespace,
newLine = "\n"): string = newLine = "\n"): string =
result = "" result = ""
for word, isSep in tokenize2(s, seps): for word, isSep in tokenize2(s, seps):

View file

@ -47,7 +47,7 @@ iterator count3(): int {.closure.} =
yield 2 yield 2
yield 3 yield 3
for word, isSep in tokenize2("ta da", whiteSpace): for word, isSep in tokenize2("ta da", WhiteSpace):
if not isSep: if not isSep:
stdout.write(word) stdout.write(word)
echo "" echo ""
@ -56,7 +56,7 @@ proc inProc() =
for c in count3(): for c in count3():
echo c echo c
for word, isSep in tokenize2("ta da", whiteSpace): for word, isSep in tokenize2("ta da", WhiteSpace):
stdout.write(word) stdout.write(word)
for c in count3(): for c in count3():

View file

@ -2,7 +2,7 @@ discard """
output: '''x: 0 y: 0''' output: '''x: 0 y: 0'''
""" """
proc ToString*[T](x: T): string = return $x proc toString*[T](x: T): string = return $x
type type

View file

@ -6,13 +6,13 @@ import
proc main() = proc main() =
var var
a, b: TTime a, b: TTime
a = getLastModificationTime(ParamStr(1)) a = getLastModificationTime(paramStr(1))
b = getLastModificationTime(ParamStr(2)) b = getLastModificationTime(paramStr(2))
writeln(stdout, $a) writeln(stdout, $a)
writeln(stdout, $b) writeln(stdout, $b)
if a < b: if a < b:
Write(stdout, "$2 is newer than $1\n" % [ParamStr(1), ParamStr(2)]) write(stdout, "$2 is newer than $1\n" % [paramStr(1), paramStr(2)])
else: else:
Write(stdout, "$1 is newer than $2\n" % [ParamStr(1), ParamStr(2)]) write(stdout, "$1 is newer than $2\n" % [paramStr(1), paramStr(2)])
main() main()

View file

@ -31,7 +31,7 @@ proc TestLoops() =
break break
break break
while True: while true:
break break

View file

@ -5,16 +5,16 @@ discard """
""" """
# BUG: following compiles, but should not: # BUG: following compiles, but should not:
proc nodeOfDegree(x: Int): bool = proc nodeOfDegree(x: int): bool =
result = false result = false
proc main = proc main =
for j in 0..2: for j in 0..2:
for i in 0..10: for i in 0..10:
if not nodeOfDegree(1) >= 0: #ERROR_MSG type mismatch if not nodeOfDegree(1) >= 0: #ERROR_MSG type mismatch
Echo "Yes" echo "Yes"
else: else:
Echo "No" echo "No"
main() main()

View file

@ -14,10 +14,10 @@ proc mypos(sub, s: string, start: int = 0): int =
if i >= N: if i >= N:
result = -1 result = -1
else: else:
while True: while true:
if s[i] == sub[j]: if s[i] == sub[j]:
Inc(i) inc(i)
Inc(j) inc(j)
else: else:
i = i - j + 1 i = i - j + 1
j = 0 j = 0

View file

@ -24,7 +24,7 @@ else:
var var
s: string s: string
write(stdout, "compiled at " & system.compileDate & write(stdout, "compiled at " & system.CompileDate &
" " & compileTime & "\n") " " & CompileTime & "\n")
echo getDateStr() echo getDateStr()
echo getClockStr() echo getClockStr()

View file

@ -4,7 +4,7 @@
## We use a radix tree with node compression. ## We use a radix tree with node compression.
## There are two node kinds: ## There are two node kinds:
const bitsPerUnit = 8*sizeof(int) const BitsPerUnit = 8*sizeof(int)
type type
TRadixNodeKind = enum rnLinear, rnFull, rnLeafBits, rnLeafLinear TRadixNodeKind = enum rnLinear, rnFull, rnLeafBits, rnLeafLinear
@ -42,13 +42,13 @@ proc testBit(w, i: int): bool {.inline.} =
result = (w and (1 shl (i %% BitsPerUnit))) != 0 result = (w and (1 shl (i %% BitsPerUnit))) != 0
proc setBit(w: var int, i: int) {.inline.} = proc setBit(w: var int, i: int) {.inline.} =
w = w or (1 shl (i %% bitsPerUnit)) w = w or (1 shl (i %% BitsPerUnit))
proc resetBit(w: var int, i: int) {.inline.} = proc resetBit(w: var int, i: int) {.inline.} =
w = w and not (1 shl (i %% bitsPerUnit)) w = w and not (1 shl (i %% BitsPerUnit))
proc testOrSetBit(w: var int, i: int): bool {.inline.} = proc testOrSetBit(w: var int, i: int): bool {.inline.} =
var x = (1 shl (i %% bitsPerUnit)) var x = (1 shl (i %% BitsPerUnit))
if (w and x) != 0: return true if (w and x) != 0: return true
w = w or x w = w or x
@ -78,7 +78,7 @@ proc exclLeaf(r: PRadixNode, a: int) =
return return
else: assert(false) else: assert(false)
proc contains*(r: PRadixNode, a: TAddress): bool = proc contains*(r: PRadixNode, a: ByteAddress): bool =
if r == nil: return false if r == nil: return false
var x = searchInner(r, a shr 24 and 0xff) var x = searchInner(r, a shr 24 and 0xff)
if x == nil: return false if x == nil: return false
@ -88,7 +88,7 @@ proc contains*(r: PRadixNode, a: TAddress): bool =
if x == nil: return false if x == nil: return false
return searchLeaf(x, a and 0xff) return searchLeaf(x, a and 0xff)
proc excl*(r: PRadixNode, a: TAddress): bool = proc excl*(r: PRadixNode, a: ByteAddress): bool =
if r == nil: return false if r == nil: return false
var x = searchInner(r, a shr 24 and 0xff) var x = searchInner(r, a shr 24 and 0xff)
if x == nil: return false if x == nil: return false
@ -167,10 +167,10 @@ proc addInner(r: var PRadixNode, a: int, d: int): bool =
return addInner(x.b[k], a, d-8) return addInner(x.b[k], a, d-8)
else: assert(false) else: assert(false)
proc incl*(r: var PRadixNode, a: TAddress) {.inline.} = proc incl*(r: var PRadixNode, a: ByteAddress) {.inline.} =
discard addInner(r, a, 24) discard addInner(r, a, 24)
proc testOrIncl*(r: var PRadixNode, a: TAddress): bool {.inline.} = proc testOrIncl*(r: var PRadixNode, a: ByteAddress): bool {.inline.} =
return addInner(r, a, 24) return addInner(r, a, 24)
iterator innerElements(r: PRadixNode): tuple[prefix: int, n: PRadixNode] = iterator innerElements(r: PRadixNode): tuple[prefix: int, n: PRadixNode] =
@ -204,7 +204,7 @@ iterator leafElements(r: PRadixNode): int =
yield ze(r.keys[i]) yield ze(r.keys[i])
else: assert(false) else: assert(false)
iterator elements*(r: PRadixNode): TAddress {.inline.} = iterator elements*(r: PRadixNode): ByteAddress {.inline.} =
for p1, n1 in innerElements(r): for p1, n1 in innerElements(r):
for p2, n2 in innerElements(n1): for p2, n2 in innerElements(n1):
for p3, n3 in innerElements(n2): for p3, n3 in innerElements(n2):
@ -297,7 +297,7 @@ when false:
result = ze(r.keys[i.x]) result = ze(r.keys[i.x])
inc(i.x) inc(i.x)
iterator elements(r: PRadixNode): TAddress {.inline.} = iterator elements(r: PRadixNode): ByteAddress {.inline.} =
var var
a, b, c, d: TRadixIter a, b, c, d: TRadixIter
init(a, r) init(a, r)

View file

@ -2,11 +2,11 @@
# Macintosh, Unix or Windows text format. # Macintosh, Unix or Windows text format.
var var
inp: TFile inp: File
line: string line: string
if open(inp, "readme.txt"): if open(inp, "readme.txt"):
while not EndOfFile(inp): while not endOfFile(inp):
line = readLine(inp) line = readLine(inp)
echo("#" & line & "#") echo("#" & line & "#")
close(inp) close(inp)

View file

@ -4,11 +4,7 @@ discard """
import hashes, math import hashes, math
{.pragma: myShallow.}
when defined(shallowADT):
{.pragma: myShallow, shallow.}
else:
{.pragma: myShallow.}
type type
TSlotEnum = enum seEmpty, seFilled, seDeleted TSlotEnum = enum seEmpty, seFilled, seDeleted
@ -63,7 +59,7 @@ template rawInsertImpl() =
data[h].val = val data[h].val = val
data[h].slot = seFilled data[h].slot = seFilled
proc RawGet[A, B](t: TTable[A, B], key: A): int = proc rawGet[A, B](t: TTable[A, B], key: A): int =
rawGetImpl() rawGetImpl()
proc `[]`*[A, B](t: TTable[A, B], key: A): B = proc `[]`*[A, B](t: TTable[A, B], key: A): B =
@ -71,31 +67,31 @@ proc `[]`*[A, B](t: TTable[A, B], key: A): B =
## default empty value for the type `B` is returned ## default empty value for the type `B` is returned
## and no exception is raised. One can check with ``hasKey`` whether the key ## and no exception is raised. One can check with ``hasKey`` whether the key
## exists. ## exists.
var index = RawGet(t, key) var index = rawGet(t, key)
if index >= 0: result = t.data[index].val if index >= 0: result = t.data[index].val
proc hasKey*[A, B](t: TTable[A, B], key: A): bool = proc hasKey*[A, B](t: TTable[A, B], key: A): bool =
## returns true iff `key` is in the table `t`. ## returns true iff `key` is in the table `t`.
result = rawGet(t, key) >= 0 result = rawGet(t, key) >= 0
proc RawInsert[A, B](t: var TTable[A, B], data: var TKeyValuePairSeq[A, B], proc rawInsert[A, B](t: var TTable[A, B], data: var TKeyValuePairSeq[A, B],
key: A, val: B) = key: A, val: B) =
rawInsertImpl() rawInsertImpl()
proc Enlarge[A, B](t: var TTable[A, B]) = proc enlarge[A, B](t: var TTable[A, B]) =
var n: TKeyValuePairSeq[A, B] var n: TKeyValuePairSeq[A, B]
newSeq(n, len(t.data) * growthFactor) newSeq(n, len(t.data) * growthFactor)
for i in countup(0, high(t.data)): 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) if t.data[i].slot == seFilled: rawInsert(t, n, t.data[i].key, t.data[i].val)
swap(t.data, n) swap(t.data, n)
template PutImpl() = template putImpl() =
var index = RawGet(t, key) var index = rawGet(t, key)
if index >= 0: if index >= 0:
t.data[index].val = val t.data[index].val = val
else: else:
if mustRehash(len(t.data), t.counter): Enlarge(t) if mustRehash(len(t.data), t.counter): enlarge(t)
RawInsert(t, t.data, key, val) rawInsert(t, t.data, key, val)
inc(t.counter) inc(t.counter)
proc `[]=`*[A, B](t: var TTable[A, B], key: A, val: B) = proc `[]=`*[A, B](t: var TTable[A, B], key: A, val: B) =
@ -104,7 +100,7 @@ proc `[]=`*[A, B](t: var TTable[A, B], key: A, val: B) =
proc del*[A, B](t: var TTable[A, B], key: A) = proc del*[A, B](t: var TTable[A, B], key: A) =
## deletes `key` from hash table `t`. ## deletes `key` from hash table `t`.
var index = RawGet(t, key) var index = rawGet(t, key)
if index >= 0: if index >= 0:
t.data[index].slot = seDeleted t.data[index].slot = seDeleted
dec(t.counter) dec(t.counter)
@ -183,24 +179,24 @@ proc hasKey*[A](t: TCountTable[A], key: A): bool =
## returns true iff `key` is in the table `t`. ## returns true iff `key` is in the table `t`.
result = rawGet(t, key) >= 0 result = rawGet(t, key) >= 0
proc RawInsert[A](t: TCountTable[A], data: var seq[tuple[key: A, val: int]], proc rawInsert[A](t: TCountTable[A], data: var seq[tuple[key: A, val: int]],
key: A, val: int) = key: A, val: int) =
var h: THash = hash(key) and high(data) var h: THash = hash(key) and high(data)
while data[h].val != 0: h = nextTry(h, high(data)) while data[h].val != 0: h = nextTry(h, high(data))
data[h].key = key data[h].key = key
data[h].val = val data[h].val = val
proc Enlarge[A](t: var TCountTable[A]) = proc enlarge[A](t: var TCountTable[A]) =
var n: seq[tuple[key: A, val: int]] var n: seq[tuple[key: A, val: int]]
newSeq(n, len(t.data) * growthFactor) newSeq(n, len(t.data) * growthFactor)
for i in countup(0, high(t.data)): 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) if t.data[i].val != 0: rawInsert(t, n, t.data[i].key, t.data[i].val)
swap(t.data, n) swap(t.data, n)
proc `[]=`*[A](t: var TCountTable[A], key: A, val: int) = proc `[]=`*[A](t: var TCountTable[A], key: A, val: int) =
## puts a (key, value)-pair into `t`. `val` has to be positive. ## puts a (key, value)-pair into `t`. `val` has to be positive.
assert val > 0 assert val > 0
PutImpl() putImpl()
proc initCountTable*[A](initialSize=64): TCountTable[A] = proc initCountTable*[A](initialSize=64): TCountTable[A] =
## creates a new count table that is empty. `initialSize` needs to be ## creates a new count table that is empty. `initialSize` needs to be
@ -224,11 +220,11 @@ proc inc*[A](t: var TCountTable[A], key: A, val = 1) =
if index >= 0: if index >= 0:
inc(t.data[index].val, val) inc(t.data[index].val, val)
else: else:
if mustRehash(len(t.data), t.counter): Enlarge(t) if mustRehash(len(t.data), t.counter): enlarge(t)
RawInsert(t, t.data, key, val) rawInsert(t, t.data, key, val)
inc(t.counter) inc(t.counter)
proc Smallest*[A](t: TCountTable[A]): tuple[key: A, val: int] = proc smallest*[A](t: TCountTable[A]): tuple[key: A, val: int] =
## returns the largest (key,val)-pair. Efficiency: O(n) ## returns the largest (key,val)-pair. Efficiency: O(n)
assert t.len > 0 assert t.len > 0
var minIdx = 0 var minIdx = 0
@ -237,7 +233,7 @@ proc Smallest*[A](t: TCountTable[A]): tuple[key: A, val: int] =
result.key = t.data[minIdx].key result.key = t.data[minIdx].key
result.val = t.data[minIdx].val result.val = t.data[minIdx].val
proc Largest*[A](t: TCountTable[A]): tuple[key: A, val: int] = proc largest*[A](t: TCountTable[A]): tuple[key: A, val: int] =
## returns the (key,val)-pair with the largest `val`. Efficiency: O(n) ## returns the (key,val)-pair with the largest `val`. Efficiency: O(n)
assert t.len > 0 assert t.len > 0
var maxIdx = 0 var maxIdx = 0

View file

@ -74,7 +74,7 @@ proc toNum(b: TBuffer): int32 =
while (ze(b[i]) and 128) != 0: while (ze(b[i]) and 128) != 0:
inc(i) inc(i)
result = result or ((int32(ze(b[i])) and 127'i32) shl Shift) result = result or ((int32(ze(b[i])) and 127'i32) shl Shift)
Shift = shift + 7'i32 Shift = Shift + 7'i32
if (ze(b[0]) and (1 shl 6)) != 0: # sign bit set? if (ze(b[0]) and (1 shl 6)) != 0: # sign bit set?
result = (not result) +% 1'i32 result = (not result) +% 1'i32
# this is the same as ``- result`` # this is the same as ``- result``

View file

@ -7,7 +7,7 @@ some(10)'''
import strutils import strutils
type Option[A] = object type Option[A] = object
case isDefined*: Bool case isDefined*: bool
of true: of true:
value*: A value*: A
of false: of false:
@ -19,7 +19,7 @@ proc some[A](value: A): Option[A] =
proc none[A](): Option[A] = proc none[A](): Option[A] =
Option[A](isDefined: false) Option[A](isDefined: false)
proc `$`[A](o: Option[A]): String = proc `$`[A](o: Option[A]): string =
if o.isDefined: if o.isDefined:
"some($1)" % [$o.value] "some($1)" % [$o.value]
else: else:
@ -27,14 +27,14 @@ proc `$`[A](o: Option[A]): String =
let x = some("str") let x = some("str")
let y = some(5) let y = some(5)
let z = none[Int]() let z = none[int]()
echo x, ", ", y, ", ", z echo x, ", ", y, ", ", z
proc intOrString[A : Int | String](o: Option[A]): Option[A] = proc intOrString[A : int | string](o: Option[A]): Option[A] =
when A is Int: when A is int:
some(o.value + 5) some(o.value + 5)
elif A is String: elif A is string:
some(o.value & "!") some(o.value & "!")
else: else:
o o

View file

@ -12,7 +12,7 @@ a = high(int)
b = -2 b = -2
try: try:
writeln(stdout, b - a) writeln(stdout, b - a)
except EOverflow: except OverflowError:
writeln(stdout, "the computation overflowed") writeln(stdout, "the computation overflowed")
{.pop.} # overflow check {.pop.} # overflow check

View file

@ -1,6 +1,6 @@
discard """ discard """
file: "toverflw2.nim" file: "toverflw2.nim"
outputsub: "Error: unhandled exception: over- or underflow [EOverflow]" outputsub: "Error: unhandled exception: over- or underflow [OverflowError]"
exitcode: "1" exitcode: "1"
""" """
var a : int32 = 2147483647 var a : int32 = 2147483647

View file

@ -1,6 +1,6 @@
proc doSomething(v: Int, x: proc(v:Int):Int): Int = return x(v) proc doSomething(v: int, x: proc(v:int):int): int = return x(v)
proc doSomething(v: Int, x: proc(v:Int)) = x(v) proc doSomething(v: int, x: proc(v:int)) = x(v)
echo doSomething(10, proc(v: Int): Int = return v div 2) echo doSomething(10, proc(v: int): int = return v div 2)

View file

@ -6,7 +6,7 @@
type type
PSDL_semaphore = ptr TSDL_semaphore PSDL_semaphore = ptr TSDL_semaphore
TSDL_semaphore {.final.} = object TSDL_semaphore {.final.} = object
sem: Pointer #PSem_t; sem: pointer #PSem_t;
when not defined(USE_NAMED_SEMAPHORES): when not defined(USE_NAMED_SEMAPHORES):
sem_data: int sem_data: int
when defined(BROKEN_SEMGETVALUE): when defined(BROKEN_SEMGETVALUE):

View file

@ -11,6 +11,6 @@ type
kids: seq[TLegal] kids: seq[TLegal]
TIllegal {.final.} = object #ERROR_MSG illegal recursion in type 'TIllegal' TIllegal {.final.} = object #ERROR_MSG illegal recursion in type 'TIllegal'
y: Int y: int
x: array[0..3, TIllegal] x: array[0..3, TIllegal]

View file

@ -10,7 +10,7 @@ proc main =
elif name == "name": elif name == "name":
echo("Very funny, your name is name.") echo("Very funny, your name is name.")
else: else:
Echo("Hi, ", name, "!") echo("Hi, ", name, "!")
let (x, y) = ("abc", name) let (x, y) = ("abc", name)
echo y, x echo y, x

View file

@ -6,7 +6,7 @@ import strutils
const const
HelpText = """ HelpText = """
+-----------------------------------------------------------------+ +-----------------------------------------------------------------+
| Maintenance program for Nim | | Maintenance program for Nim |
| Version $1| | Version $1|
| (c) 2012 Andreas Rumpf | | (c) 2012 Andreas Rumpf |
+-----------------------------------------------------------------+ +-----------------------------------------------------------------+
@ -27,5 +27,5 @@ Possible Commands:
""" % [NimVersion & repeatChar(44-len(NimVersion)), """ % [NimVersion & repeatChar(44-len(NimVersion)),
CompileDate, CompileTime] CompileDate, CompileTime]
echo helpText echo HelpText