prepare for upcoming parsing change of unary operators

This commit is contained in:
Araq 2015-03-22 02:13:53 +01:00
commit a541be8935
8 changed files with 97 additions and 97 deletions

View file

@ -9,7 +9,7 @@
# This module implements the symbol importing mechanism. # This module implements the symbol importing mechanism.
import import
intsets, strutils, os, ast, astalgo, msgs, options, idents, rodread, lookups, intsets, strutils, os, ast, astalgo, msgs, options, idents, rodread, lookups,
semdata, passes, renderer semdata, passes, renderer
@ -73,12 +73,12 @@ proc rawImportSymbol(c: PContext, s: PSym) =
if etyp.kind in {tyBool, tyEnum} and sfPure notin s.flags: if etyp.kind in {tyBool, tyEnum} and sfPure notin s.flags:
for j in countup(0, sonsLen(etyp.n) - 1): for j in countup(0, sonsLen(etyp.n) - 1):
var e = etyp.n.sons[j].sym var e = etyp.n.sons[j].sym
if e.kind != skEnumField: if e.kind != skEnumField:
internalError(s.info, "rawImportSymbol") internalError(s.info, "rawImportSymbol")
# BUGFIX: because of aliases for enums the symbol may already # BUGFIX: because of aliases for enums the symbol may already
# have been put into the symbol table # have been put into the symbol table
# BUGFIX: but only iff they are the same symbols! # BUGFIX: but only iff they are the same symbols!
var it: TIdentIter var it: TIdentIter
check = initIdentIter(it, c.importTable.symbols, e.name) check = initIdentIter(it, c.importTable.symbols, e.name)
while check != nil: while check != nil:
if check.id == e.id: if check.id == e.id:
@ -92,7 +92,7 @@ proc rawImportSymbol(c: PContext, s: PSym) =
if s.kind == skConverter: addConverter(c, s) if s.kind == skConverter: addConverter(c, s)
if hasPattern(s): addPattern(c, s) if hasPattern(s): addPattern(c, s)
proc importSymbol(c: PContext, n: PNode, fromMod: PSym) = proc importSymbol(c: PContext, n: PNode, fromMod: PSym) =
let ident = lookups.considerQuotedIdent(n) let ident = lookups.considerQuotedIdent(n)
let s = strTableGet(fromMod.tab, ident) let s = strTableGet(fromMod.tab, ident)
if s == nil: if s == nil:
@ -143,7 +143,7 @@ proc importForwarded(c: PContext, n: PNode, exceptSet: IntSet) =
of nkExportExceptStmt: of nkExportExceptStmt:
localError(n.info, errGenerated, "'export except' not implemented") localError(n.info, errGenerated, "'export except' not implemented")
else: else:
for i in 0 ..safeLen(n)-1: for i in 0..safeLen(n)-1:
importForwarded(c, n.sons[i], exceptSet) importForwarded(c, n.sons[i], exceptSet)
proc importModuleAs(n: PNode, realModule: PSym): PSym = proc importModuleAs(n: PNode, realModule: PSym): PSym =
@ -155,7 +155,7 @@ proc importModuleAs(n: PNode, realModule: PSym): PSym =
# some misguided guy will write 'import abc.foo as foo' ... # some misguided guy will write 'import abc.foo as foo' ...
result = createModuleAlias(realModule, n.sons[1].ident, realModule.info) result = createModuleAlias(realModule, n.sons[1].ident, realModule.info)
proc myImportModule(c: PContext, n: PNode): PSym = proc myImportModule(c: PContext, n: PNode): PSym =
var f = checkModuleName(n) var f = checkModuleName(n)
if f != InvalidFileIDX: if f != InvalidFileIDX:
result = importModuleAs(n, gImportModule(c.module, f)) result = importModuleAs(n, gImportModule(c.module, f))
@ -164,10 +164,10 @@ proc myImportModule(c: PContext, n: PNode): PSym =
if sfDeprecated in result.flags: if sfDeprecated in result.flags:
message(n.info, warnDeprecated, result.name.s) message(n.info, warnDeprecated, result.name.s)
proc evalImport(c: PContext, n: PNode): PNode = proc evalImport(c: PContext, n: PNode): PNode =
result = n result = n
var emptySet: IntSet var emptySet: IntSet
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
var m = myImportModule(c, n.sons[i]) var m = myImportModule(c, n.sons[i])
if m != nil: if m != nil:
# ``addDecl`` needs to be done before ``importAllSymbols``! # ``addDecl`` needs to be done before ``importAllSymbols``!
@ -175,7 +175,7 @@ proc evalImport(c: PContext, n: PNode): PNode =
importAllSymbolsExcept(c, m, emptySet) importAllSymbolsExcept(c, m, emptySet)
#importForwarded(c, m.ast, emptySet) #importForwarded(c, m.ast, emptySet)
proc evalFrom(c: PContext, n: PNode): PNode = proc evalFrom(c: PContext, n: PNode): PNode =
result = n result = n
checkMinSonsLen(n, 2) checkMinSonsLen(n, 2)
var m = myImportModule(c, n.sons[0]) var m = myImportModule(c, n.sons[0])
@ -186,7 +186,7 @@ proc evalFrom(c: PContext, n: PNode): PNode =
if n.sons[i].kind != nkNilLit: if n.sons[i].kind != nkNilLit:
importSymbol(c, n.sons[i], m) importSymbol(c, n.sons[i], m)
proc evalImportExcept*(c: PContext, n: PNode): PNode = proc evalImportExcept*(c: PContext, n: PNode): PNode =
result = n result = n
checkMinSonsLen(n, 2) checkMinSonsLen(n, 2)
var m = myImportModule(c, n.sons[0]) var m = myImportModule(c, n.sons[0])
@ -194,7 +194,7 @@ proc evalImportExcept*(c: PContext, n: PNode): PNode =
n.sons[0] = newSymNode(m) n.sons[0] = newSymNode(m)
addDecl(c, m) # add symbol to symbol table of module addDecl(c, m) # add symbol to symbol table of module
var exceptSet = initIntSet() var exceptSet = initIntSet()
for i in countup(1, sonsLen(n) - 1): for i in countup(1, sonsLen(n) - 1):
let ident = lookups.considerQuotedIdent(n.sons[i]) let ident = lookups.considerQuotedIdent(n.sons[i])
exceptSet.incl(ident.id) exceptSet.incl(ident.id)
importAllSymbolsExcept(c, m, exceptSet) importAllSymbolsExcept(c, m, exceptSet)

View file

@ -55,21 +55,21 @@
# share leaves across different rope trees. # share leaves across different rope trees.
# To cache them they are inserted in a `cache` array. # To cache them they are inserted in a `cache` array.
import import
strutils, platform, hashes, crc, options strutils, platform, hashes, crc, options
type type
TFormatStr* = string # later we may change it to CString for better TFormatStr* = string # later we may change it to CString for better
# performance of the code generator (assignments # performance of the code generator (assignments
# copy the format strings # copy the format strings
# though it is not necessary) # though it is not necessary)
PRope* = ref TRope PRope* = ref TRope
TRope*{.acyclic.} = object of RootObj # the empty rope is represented TRope*{.acyclic.} = object of RootObj # the empty rope is represented
# by nil to safe space # by nil to safe space
left*, right*: PRope left*, right*: PRope
length*: int length*: int
data*: string # != nil if a leaf data*: string # != nil if a leaf
TRopeSeq* = seq[PRope] TRopeSeq* = seq[PRope]
TRopesError* = enum TRopesError* = enum
@ -99,14 +99,14 @@ proc ropeInvariant*(r: PRope): bool
var errorHandler*: proc(err: TRopesError, msg: string, useWarning = false) var errorHandler*: proc(err: TRopesError, msg: string, useWarning = false)
# avoid dependency on msgs.nim # avoid dependency on msgs.nim
proc ropeLen(a: PRope): int = proc ropeLen(a: PRope): int =
if a == nil: result = 0 if a == nil: result = 0
else: result = a.length else: result = a.length
proc newRope*(data: string = nil): PRope = proc newRope*(data: string = nil): PRope =
new(result) new(result)
if data != nil: if data != nil:
result.length = len(data) result.length = len(data)
result.data = data result.data = data
@ -119,17 +119,17 @@ proc newMutableRope*(capacity = 30): PRope =
proc freezeMutableRope*(r: PRope) {.inline.} = proc freezeMutableRope*(r: PRope) {.inline.} =
r.length = r.data.len r.length = r.data.len
var var
cache: array[0..2048*2 -1, PRope] cache: array[0..2048*2 - 1, PRope]
proc resetRopeCache* = proc resetRopeCache* =
for i in low(cache)..high(cache): for i in low(cache)..high(cache):
cache[i] = nil cache[i] = nil
proc ropeInvariant(r: PRope): bool = proc ropeInvariant(r: PRope): bool =
if r == nil: if r == nil:
result = true result = true
else: else:
result = true # result = true #
# if r.data <> snil then # if r.data <> snil then
# result := true # result := true
@ -137,13 +137,13 @@ proc ropeInvariant(r: PRope): bool =
# result := (r.left <> nil) and (r.right <> nil); # result := (r.left <> nil) and (r.right <> nil);
# if result then result := ropeInvariant(r.left); # if result then result := ropeInvariant(r.left);
# if result then result := ropeInvariant(r.right); # if result then result := ropeInvariant(r.right);
# end # end
var gCacheTries* = 0 var gCacheTries* = 0
var gCacheMisses* = 0 var gCacheMisses* = 0
var gCacheIntTries* = 0 var gCacheIntTries* = 0
proc insertInCache(s: string): PRope = proc insertInCache(s: string): PRope =
inc gCacheTries inc gCacheTries
var h = hash(s) and high(cache) var h = hash(s) and high(cache)
result = cache[h] result = cache[h]
@ -151,7 +151,7 @@ proc insertInCache(s: string): PRope =
inc gCacheMisses inc gCacheMisses
result = newRope(s) result = newRope(s)
cache[h] = result cache[h] = result
proc toRope(s: string): PRope = proc toRope(s: string): PRope =
if s.len == 0: if s.len == 0:
result = nil result = nil
@ -159,21 +159,21 @@ proc toRope(s: string): PRope =
result = insertInCache(s) result = insertInCache(s)
assert(ropeInvariant(result)) assert(ropeInvariant(result))
proc ropeSeqInsert(rs: var TRopeSeq, r: PRope, at: Natural) = proc ropeSeqInsert(rs: var TRopeSeq, r: PRope, at: Natural) =
var length = len(rs) var length = len(rs)
if at > length: if at > length:
setLen(rs, at + 1) setLen(rs, at + 1)
else: else:
setLen(rs, length + 1) # move old rope elements: setLen(rs, length + 1) # move old rope elements:
for i in countdown(length, at + 1): for i in countdown(length, at + 1):
rs[i] = rs[i - 1] # this is correct, I used pen and paper to validate it rs[i] = rs[i - 1] # this is correct, I used pen and paper to validate it
rs[at] = r rs[at] = r
proc newRecRopeToStr(result: var string, resultLen: var int, r: PRope) = proc newRecRopeToStr(result: var string, resultLen: var int, r: PRope) =
var stack = @[r] var stack = @[r]
while len(stack) > 0: while len(stack) > 0:
var it = pop(stack) var it = pop(stack)
while it.data == nil: while it.data == nil:
add(stack, it.right) add(stack, it.right)
it = it.left it = it.left
assert(it.data != nil) assert(it.data != nil)
@ -181,15 +181,15 @@ proc newRecRopeToStr(result: var string, resultLen: var int, r: PRope) =
inc(resultLen, it.length) inc(resultLen, it.length)
assert(resultLen <= len(result)) assert(resultLen <= len(result))
proc ropeToStr(p: PRope): string = proc ropeToStr(p: PRope): string =
if p == nil: if p == nil:
result = "" result = ""
else: else:
result = newString(p.length) result = newString(p.length)
var resultLen = 0 var resultLen = 0
newRecRopeToStr(result, resultLen, p) newRecRopeToStr(result, resultLen, p)
proc con(a, b: PRope): PRope = proc con(a, b: PRope): PRope =
if a == nil: result = b if a == nil: result = b
elif b == nil: result = a elif b == nil: result = a
else: else:
@ -201,7 +201,7 @@ proc con(a, b: PRope): PRope =
proc con(a: PRope, b: string): PRope = result = con(a, toRope(b)) proc con(a: PRope, b: string): PRope = result = con(a, toRope(b))
proc con(a: string, b: PRope): PRope = result = con(toRope(a), b) proc con(a: string, b: PRope): PRope = result = con(toRope(a), b)
proc con(a: varargs[PRope]): PRope = proc con(a: varargs[PRope]): PRope =
for i in countup(0, high(a)): result = con(result, a[i]) for i in countup(0, high(a)): result = con(result, a[i])
proc ropeConcat*(a: varargs[PRope]): PRope = proc ropeConcat*(a: varargs[PRope]): PRope =
@ -216,11 +216,11 @@ proc app(a: var PRope, b: PRope) = a = con(a, b)
proc app(a: var PRope, b: string) = a = con(a, b) proc app(a: var PRope, b: string) = a = con(a, b)
proc prepend(a: var PRope, b: PRope) = a = con(b, a) proc prepend(a: var PRope, b: PRope) = a = con(b, a)
proc writeRope*(f: File, c: PRope) = proc writeRope*(f: File, c: PRope) =
var stack = @[c] var stack = @[c]
while len(stack) > 0: while len(stack) > 0:
var it = pop(stack) var it = pop(stack)
while it.data == nil: while it.data == nil:
add(stack, it.right) add(stack, it.right)
it = it.left it = it.left
assert(it != nil) assert(it != nil)
@ -239,28 +239,28 @@ var
rnl* = tnl.newRope rnl* = tnl.newRope
softRnl* = tnl.newRope softRnl* = tnl.newRope
proc ropef(frmt: TFormatStr, args: varargs[PRope]): PRope = proc ropef(frmt: TFormatStr, args: varargs[PRope]): PRope =
var i = 0 var i = 0
var length = len(frmt) var length = len(frmt)
result = nil result = nil
var num = 0 var num = 0
while i <= length - 1: while i <= length - 1:
if frmt[i] == '$': if frmt[i] == '$':
inc(i) # skip '$' inc(i) # skip '$'
case frmt[i] case frmt[i]
of '$': of '$':
app(result, "$") app(result, "$")
inc(i) inc(i)
of '#': of '#':
inc(i) inc(i)
app(result, args[num]) app(result, args[num])
inc(num) inc(num)
of '0'..'9': of '0'..'9':
var j = 0 var j = 0
while true: while true:
j = (j * 10) + ord(frmt[i]) - ord('0') j = (j * 10) + ord(frmt[i]) - ord('0')
inc(i) inc(i)
if (i > length + 0 - 1) or not (frmt[i] in {'0'..'9'}): break if (i > length + 0 - 1) or not (frmt[i] in {'0'..'9'}): break
num = j num = j
if j > high(args) + 1: if j > high(args) + 1:
errorHandler(rInvalidFormatStr, $(j)) errorHandler(rInvalidFormatStr, $(j))
@ -278,7 +278,7 @@ proc ropef(frmt: TFormatStr, args: varargs[PRope]): PRope =
while i < length: while i < length:
if frmt[i] != '$': inc(i) if frmt[i] != '$': inc(i)
else: break else: break
if i - 1 >= start: if i - 1 >= start:
app(result, substr(frmt, start, i - 1)) app(result, substr(frmt, start, i - 1))
assert(ropeInvariant(result)) assert(ropeInvariant(result))
@ -293,13 +293,13 @@ else:
return r return r
{.pop.} {.pop.}
proc appf(c: var PRope, frmt: TFormatStr, args: varargs[PRope]) = proc appf(c: var PRope, frmt: TFormatStr, args: varargs[PRope]) =
app(c, ropef(frmt, args)) app(c, ropef(frmt, args))
const const
bufSize = 1024 # 1 KB is reasonable bufSize = 1024 # 1 KB is reasonable
proc auxRopeEqualsFile(r: PRope, bin: var File, buf: pointer): bool = proc auxRopeEqualsFile(r: PRope, bin: var File, buf: pointer): bool =
if r.data != nil: if r.data != nil:
if r.length > bufSize: if r.length > bufSize:
errorHandler(rTokenTooLong, r.data) errorHandler(rTokenTooLong, r.data)
@ -307,56 +307,56 @@ proc auxRopeEqualsFile(r: PRope, bin: var File, buf: pointer): bool =
var readBytes = readBuffer(bin, buf, r.length) var readBytes = readBuffer(bin, buf, r.length)
result = readBytes == r.length and result = readBytes == r.length and
equalMem(buf, addr(r.data[0]), r.length) # BUGFIX equalMem(buf, addr(r.data[0]), r.length) # BUGFIX
else: else:
result = auxRopeEqualsFile(r.left, bin, buf) result = auxRopeEqualsFile(r.left, bin, buf)
if result: result = auxRopeEqualsFile(r.right, bin, buf) if result: result = auxRopeEqualsFile(r.right, bin, buf)
proc ropeEqualsFile(r: PRope, f: string): bool = proc ropeEqualsFile(r: PRope, f: string): bool =
var bin: File var bin: File
result = open(bin, f) result = open(bin, f)
if not result: if not result:
return # not equal if file does not exist return # not equal if file does not exist
var buf = alloc(bufSize) var buf = alloc(bufSize)
result = auxRopeEqualsFile(r, bin, buf) result = auxRopeEqualsFile(r, bin, buf)
if result: if result:
result = readBuffer(bin, buf, bufSize) == 0 # really at the end of file? result = readBuffer(bin, buf, bufSize) == 0 # really at the end of file?
dealloc(buf) dealloc(buf)
close(bin) close(bin)
proc crcFromRopeAux(r: PRope, startVal: TCrc32): TCrc32 = proc crcFromRopeAux(r: PRope, startVal: TCrc32): TCrc32 =
if r.data != nil: if r.data != nil:
result = startVal result = startVal
for i in countup(0, len(r.data) - 1): for i in countup(0, len(r.data) - 1):
result = updateCrc32(r.data[i], result) result = updateCrc32(r.data[i], result)
else: else:
result = crcFromRopeAux(r.left, startVal) result = crcFromRopeAux(r.left, startVal)
result = crcFromRopeAux(r.right, result) result = crcFromRopeAux(r.right, result)
proc newCrcFromRopeAux(r: PRope, startVal: TCrc32): TCrc32 = proc newCrcFromRopeAux(r: PRope, startVal: TCrc32): TCrc32 =
# XXX profiling shows this is actually expensive # XXX profiling shows this is actually expensive
var stack: TRopeSeq = @[r] var stack: TRopeSeq = @[r]
result = startVal result = startVal
while len(stack) > 0: while len(stack) > 0:
var it = pop(stack) var it = pop(stack)
while it.data == nil: while it.data == nil:
add(stack, it.right) add(stack, it.right)
it = it.left it = it.left
assert(it.data != nil) assert(it.data != nil)
var i = 0 var i = 0
var L = len(it.data) var L = len(it.data)
while i < L: while i < L:
result = updateCrc32(it.data[i], result) result = updateCrc32(it.data[i], result)
inc(i) inc(i)
proc crcFromRope(r: PRope): TCrc32 = proc crcFromRope(r: PRope): TCrc32 =
result = newCrcFromRopeAux(r, InitCrc32) result = newCrcFromRopeAux(r, InitCrc32)
proc writeRopeIfNotEqual(r: PRope, filename: string): bool = proc writeRopeIfNotEqual(r: PRope, filename: string): bool =
# returns true if overwritten # returns true if overwritten
var c: TCrc32 var c: TCrc32
c = crcFromFile(filename) c = crcFromFile(filename)
if c != crcFromRope(r): if c != crcFromRope(r):
writeRope(r, filename) writeRope(r, filename)
result = true result = true
else: else:
result = false result = false

View file

@ -228,7 +228,7 @@ proc semArrayIndex(c: PContext, n: PNode): PType =
if not isOrdinalType(e.typ.lastSon): if not isOrdinalType(e.typ.lastSon):
localError(n[1].info, errOrdinalTypeExpected) localError(n[1].info, errOrdinalTypeExpected)
result = makeRangeWithStaticExpr(c, e) result = makeRangeWithStaticExpr(c, e)
if c.inGenericContext >0: result.flags.incl tfUnresolved if c.inGenericContext > 0: result.flags.incl tfUnresolved
elif e.kind in nkCallKinds and hasGenericArguments(e): elif e.kind in nkCallKinds and hasGenericArguments(e):
if not isOrdinalType(e.typ): if not isOrdinalType(e.typ):
localError(n[1].info, errOrdinalTypeExpected) localError(n[1].info, errOrdinalTypeExpected)

View file

@ -434,7 +434,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
result = "int literal(" & $t.n.intVal & ")" result = "int literal(" & $t.n.intVal & ")"
of tyGenericBody, tyGenericInst, tyGenericInvocation: of tyGenericBody, tyGenericInst, tyGenericInvocation:
result = typeToString(t.sons[0]) & '[' result = typeToString(t.sons[0]) & '['
for i in countup(1, sonsLen(t) -1 -ord(t.kind != tyGenericInvocation)): for i in countup(1, sonsLen(t)-1-ord(t.kind != tyGenericInvocation)):
if i > 1: add(result, ", ") if i > 1: add(result, ", ")
add(result, typeToString(t.sons[i], preferGenericArg)) add(result, typeToString(t.sons[i], preferGenericArg))
add(result, ']') add(result, ']')

View file

@ -734,14 +734,14 @@ proc basename*(a: NimNode): NimNode =
of nnkIdent: return a of nnkIdent: return a
of nnkPostfix, nnkPrefix: return a[1] of nnkPostfix, nnkPrefix: return a[1]
else: else:
quit "Do not know how to get basename of ("& treeRepr(a) &")\n"& repr(a) quit "Do not know how to get basename of (" & treeRepr(a) & ")\n" & repr(a)
proc `basename=`*(a: NimNode; val: string) {.compileTime.}= proc `basename=`*(a: NimNode; val: string) {.compileTime.}=
case a.kind case a.kind
of nnkIdent: macros.`ident=`(a, !val) of nnkIdent: macros.`ident=`(a, !val)
of nnkPostfix, nnkPrefix: a[1] = ident(val) of nnkPostfix, nnkPrefix: a[1] = ident(val)
else: else:
quit "Do not know how to get basename of ("& treeRepr(a)& ")\n"& repr(a) quit "Do not know how to get basename of (" & treeRepr(a) & ")\n" & repr(a)
proc postfix*(node: NimNode; op: string): NimNode {.compileTime.} = proc postfix*(node: NimNode; op: string): NimNode {.compileTime.} =
newNimNode(nnkPostfix).add(ident(op), node) newNimNode(nnkPostfix).add(ident(op), node)

View file

@ -81,7 +81,7 @@ proc deduplicate*[T](seq1: seq[T]): seq[T] =
if not result.contains(itm): result.add(itm) if not result.contains(itm): result.add(itm)
{.deprecated: [distnct: deduplicate].} {.deprecated: [distnct: deduplicate].}
proc zip*[S, T](seq1: seq[S], seq2: seq[T]): seq[tuple[a: S, b: T]] = proc zip*[S, T](seq1: seq[S], seq2: seq[T]): seq[tuple[a: S, b: T]] =
## Returns a new sequence with a combination of the two input sequences. ## Returns a new sequence with a combination of the two input sequences.
## ##
@ -181,7 +181,7 @@ iterator filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): T =
## for n in filter(numbers, proc (x: int): bool = x mod 2 == 0): ## for n in filter(numbers, proc (x: int): bool = x mod 2 == 0):
## echo($n) ## echo($n)
## # echoes 4, 8, 4 in separate lines ## # echoes 4, 8, 4 in separate lines
for i in countup(0, len(seq1) -1): for i in countup(0, len(seq1)-1):
var item = seq1[i] var item = seq1[i]
if pred(item): yield seq1[i] if pred(item): yield seq1[i]
@ -228,7 +228,7 @@ proc delete*[T](s: var seq[T], first=0, last=0) =
## var dest = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1] ## var dest = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1]
## dest.delete(3, 8) ## dest.delete(3, 8)
## assert outcome == dest ## assert outcome == dest
var i = first var i = first
var j = last+1 var j = last+1
var newLen = len(s)-j+i var newLen = len(s)-j+i
@ -246,12 +246,12 @@ proc insert*[T](dest: var seq[T], src: openArray[T], pos=0) =
## ##
##.. code-block:: ##.. code-block::
## var dest = @[1,1,1,1,1,1,1,1] ## var dest = @[1,1,1,1,1,1,1,1]
## let ## let
## src = @[2,2,2,2,2,2] ## src = @[2,2,2,2,2,2]
## outcome = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1] ## outcome = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1]
## dest.insert(src, 3) ## dest.insert(src, 3)
## assert dest == outcome ## assert dest == outcome
var j = len(dest) - 1 var j = len(dest) - 1
var i = len(dest) + len(src) - 1 var i = len(dest) + len(src) - 1
dest.setLen(i + 1) dest.setLen(i + 1)
@ -553,12 +553,12 @@ when isMainModule:
var dest = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1] var dest = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1]
dest.delete(3, 8) dest.delete(3, 8)
assert outcome == dest, """\ assert outcome == dest, """\
Deleting range 3-9 from [1,1,1,2,2,2,2,2,2,1,1,1,1,1] Deleting range 3-9 from [1,1,1,2,2,2,2,2,2,1,1,1,1,1]
is [1,1,1,1,1,1,1,1]""" is [1,1,1,1,1,1,1,1]"""
block: # insert tests block: # insert tests
var dest = @[1,1,1,1,1,1,1,1] var dest = @[1,1,1,1,1,1,1,1]
let let
src = @[2,2,2,2,2,2] src = @[2,2,2,2,2,2]
outcome = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1] outcome = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1]
dest.insert(src, 3) dest.insert(src, 3)
@ -610,7 +610,7 @@ when isMainModule:
let let
a = @[1, 2, 3] a = @[1, 2, 3]
b: seq[int] = @[] b: seq[int] = @[]
doAssert a.repeat(3) == @[1, 2, 3, 1, 2, 3, 1, 2, 3] doAssert a.repeat(3) == @[1, 2, 3, 1, 2, 3, 1, 2, 3]
doAssert a.repeat(0) == @[] doAssert a.repeat(0) == @[]
#doAssert a.repeat(-1) == @[] # will not compile! #doAssert a.repeat(-1) == @[] # will not compile!

View file

@ -192,7 +192,7 @@ proc `[]`*[A, B](t: Table[A, B], key: A): B =
proc mget*[A, B](t: var Table[A, B], key: A): var B = proc mget*[A, B](t: var Table[A, B], key: A): var B =
## retrieves the value at ``t[key]``. The value can be modified. ## retrieves the value at ``t[key]``. The value can be modified.
## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. ## If `key` is not in `t`, the ``KeyError`` exception is raised.
var hc: THash var hc: THash
var index = rawGet(t, key, hc) var index = rawGet(t, key, hc)
if index >= 0: result = t.data[index].val if index >= 0: result = t.data[index].val
@ -314,7 +314,7 @@ proc initTable*[A, B](initialSize=64): Table[A, B] =
result.counter = 0 result.counter = 0
newSeq(result.data, initialSize) newSeq(result.data, initialSize)
proc toTable*[A, B](pairs: openArray[(A, proc toTable*[A, B](pairs: openArray[(A,
B)]): Table[A, B] = B)]): Table[A, B] =
## creates a new hash table that contains the given `pairs`. ## creates a new hash table that contains the given `pairs`.
result = initTable[A, B](rightSize(pairs.len)) result = initTable[A, B](rightSize(pairs.len))
@ -532,7 +532,7 @@ proc hasKey*[A, B](t: OrderedTable[A, B], key: A): bool =
var hc: THash var hc: THash
result = rawGet(t, key, hc) >= 0 result = rawGet(t, key, hc) >= 0
proc rawInsert[A, B](t: var OrderedTable[A, B], proc rawInsert[A, B](t: var OrderedTable[A, B],
data: var OrderedKeyValuePairSeq[A, B], data: var OrderedKeyValuePairSeq[A, B],
key: A, val: B, hc: THash, h: THash) = key: A, val: B, hc: THash, h: THash) =
rawInsertImpl() rawInsertImpl()
@ -584,7 +584,7 @@ proc initOrderedTable*[A, B](initialSize=64): OrderedTable[A, B] =
result.last = -1 result.last = -1
newSeq(result.data, initialSize) newSeq(result.data, initialSize)
proc toOrderedTable*[A, B](pairs: openArray[(A, proc toOrderedTable*[A, B](pairs: openArray[(A,
B)]): OrderedTable[A, B] = B)]): OrderedTable[A, B] =
## creates a new ordered hash table that contains the given `pairs`. ## creates a new ordered hash table that contains the given `pairs`.
result = initOrderedTable[A, B](rightSize(pairs.len)) result = initOrderedTable[A, B](rightSize(pairs.len))
@ -594,7 +594,7 @@ proc `$`*[A, B](t: OrderedTable[A, B]): string =
## The `$` operator for ordered hash tables. ## The `$` operator for ordered hash tables.
dollarImpl() dollarImpl()
proc sort*[A, B](t: var OrderedTable[A, B], proc sort*[A, B](t: var OrderedTable[A, B],
cmp: proc (x,y: (A, B)): int) = cmp: proc (x,y: (A, B)): int) =
## sorts `t` according to `cmp`. This modifies the internal list ## sorts `t` according to `cmp`. This modifies the internal list
## that kept the insertion order, so insertion order is lost after this ## that kept the insertion order, so insertion order is lost after this
@ -617,7 +617,7 @@ proc sort*[A, B](t: var OrderedTable[A, B],
while i < insize: while i < insize:
inc(psize) inc(psize)
q = t.data[q].next q = t.data[q].next
if q < 0: break if q < 0: break
inc(i) inc(i)
qsize = insize qsize = insize
while psize > 0 or (qsize > 0 and q >= 0): while psize > 0 or (qsize > 0 and q >= 0):
@ -625,7 +625,7 @@ proc sort*[A, B](t: var OrderedTable[A, B],
e = q; q = t.data[q].next; dec(qsize) e = q; q = t.data[q].next; dec(qsize)
elif qsize == 0 or q < 0: elif qsize == 0 or q < 0:
e = p; p = t.data[p].next; dec(psize) e = p; p = t.data[p].next; dec(psize)
elif cmp((t.data[p].key, t.data[p].val), elif cmp((t.data[p].key, t.data[p].val),
(t.data[q].key, t.data[q].val)) <= 0: (t.data[q].key, t.data[q].val)) <= 0:
e = p; p = t.data[p].next; dec(psize) e = p; p = t.data[p].next; dec(psize)
else: else:
@ -730,7 +730,7 @@ proc `$`*[A, B](t: OrderedTableRef[A, B]): string =
## The `$` operator for ordered hash tables. ## The `$` operator for ordered hash tables.
dollarImpl() dollarImpl()
proc sort*[A, B](t: OrderedTableRef[A, B], proc sort*[A, B](t: OrderedTableRef[A, B],
cmp: proc (x,y: (A, B)): int) = cmp: proc (x,y: (A, B)): int) =
## sorts `t` according to `cmp`. This modifies the internal list ## sorts `t` according to `cmp`. This modifies the internal list
## that kept the insertion order, so insertion order is lost after this ## that kept the insertion order, so insertion order is lost after this
@ -848,7 +848,7 @@ proc `$`*[A](t: CountTable[A]): string =
## The `$` operator for count tables. ## The `$` operator for count tables.
dollarImpl() dollarImpl()
proc inc*[A](t: var CountTable[A], key: A, val = 1) = proc inc*[A](t: var CountTable[A], key: A, val = 1) =
## increments `t[key]` by `val`. ## increments `t[key]` by `val`.
var index = rawGet(t, key) var index = rawGet(t, key)
if index >= 0: if index >= 0:
@ -965,7 +965,7 @@ proc `$`*[A](t: CountTableRef[A]): string =
## The `$` operator for count tables. ## The `$` operator for count tables.
dollarImpl() dollarImpl()
proc inc*[A](t: CountTableRef[A], key: A, val = 1) = proc inc*[A](t: CountTableRef[A], key: A, val = 1) =
## increments `t[key]` by `val`. ## increments `t[key]` by `val`.
t[].inc(key, val) t[].inc(key, val)

View file

@ -1,16 +1,16 @@
version 0.10.4 version 0.10.4
============== ==============
- improve the parser; deal with echo $foo gotcha
- improve GC-unsafety warnings - improve GC-unsafety warnings
- make 'nil' work for 'add' and 'len' - make 'nil' work for 'add' and 'len'
- disallow negative indexing
- improve the parser; deal with echo $foo gotcha
- add "all threads are blocked" detection to 'spawn' - add "all threads are blocked" detection to 'spawn'
version 1.0 version 1.0
=========== ===========
- disallow negative indexing
- figure out why C++ bootstrapping is so much slower - figure out why C++ bootstrapping is so much slower
- nimsuggest: auto-completion needs to work in 'class' macros - nimsuggest: auto-completion needs to work in 'class' macros
- improve the docs for inheritance - improve the docs for inheritance