prepare for upcoming parsing change of unary operators
This commit is contained in:
parent
d7c39dd801
commit
a541be8935
8 changed files with 97 additions and 97 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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, ']')
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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!
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
4
todo.txt
4
todo.txt
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue