mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-23 15:11:40 +00:00
refactoring
This commit is contained in:
@@ -736,10 +736,6 @@ proc appendToModule*(m: PSym, n: PNode) =
|
||||
assert m.astImpl.kind == nkStmtList
|
||||
m.astImpl.add(n)
|
||||
|
||||
const # for all kind of hash tables:
|
||||
GrowthFactor* = 2 # must be power of 2, > 0
|
||||
StartSize* = 8 # must be power of 2, > 0
|
||||
|
||||
proc copyStrTable*(dest: var TStrTable, src: TStrTable) =
|
||||
dest.counter = src.counter
|
||||
setLen(dest.data, src.data.len)
|
||||
|
||||
@@ -901,20 +901,22 @@ proc loadNode(c: var DecodeContext; n: var Cursor): PNode =
|
||||
else:
|
||||
raiseAssert "Not yet implemented " & $n.kind
|
||||
|
||||
when false:
|
||||
proc loadNifModule*(c: var DecodeContext; f: FileIndex): PNode =
|
||||
let moduleSuffix = moduleSuffix(c.infos.config, f)
|
||||
let modFile = toGeneratedFile(c.infos.config, AbsoluteFile(moduleSuffix), ".nif").string
|
||||
proc moduleSuffix(conf: ConfigRef; f: FileIndex): string =
|
||||
moduleSuffix(toFullPath(conf, f), cast[seq[string]](conf.searchPaths))
|
||||
|
||||
var buf = createTokenBuf(300)
|
||||
var s = nifstreams.open(modFile)
|
||||
# XXX We can optimize this here and only load the top level entries!
|
||||
try:
|
||||
nifcursors.parse(s, buf, NoLineInfo)
|
||||
finally:
|
||||
nifstreams.close(s)
|
||||
var n = cursorAt(buf, 0)
|
||||
result = loadNode(c, n)
|
||||
proc loadNifModule*(c: var DecodeContext; f: FileIndex; interf, inferfHidden: var TStrTable): PNode =
|
||||
let suffix = moduleSuffix(c.infos.config, f)
|
||||
let modFile = toGeneratedFile(c.infos.config, AbsoluteFile(suffix), ".nif").string
|
||||
|
||||
var buf = createTokenBuf(300)
|
||||
var s = nifstreams.open(modFile)
|
||||
# XXX We can optimize this here and only load the top level entries!
|
||||
try:
|
||||
nifcursors.parse(s, buf, NoLineInfo)
|
||||
finally:
|
||||
nifstreams.close(s)
|
||||
var n = cursorAt(buf, 0)
|
||||
result = loadNode(c, n)
|
||||
|
||||
when isMainModule:
|
||||
import std / syncio
|
||||
|
||||
@@ -68,8 +68,6 @@ template mdbg*: bool {.deprecated.} =
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
proc lookupInRecord*(n: PNode, field: PIdent): PSym
|
||||
proc mustRehash*(length, counter: int): bool
|
||||
proc nextTry*(h, maxHash: Hash): Hash {.inline.}
|
||||
|
||||
# ------------- table[int, int] ---------------------------------------------
|
||||
const
|
||||
@@ -216,10 +214,6 @@ proc getNamedParamFromList*(list: PNode, ident: PIdent): PSym =
|
||||
proc hashNode(p: RootRef): Hash =
|
||||
result = hash(cast[pointer](p))
|
||||
|
||||
proc mustRehash(length, counter: int): bool =
|
||||
assert(length > counter)
|
||||
result = (length * 2 < counter * 3) or (length - counter < 4)
|
||||
|
||||
import std/tables
|
||||
|
||||
const backrefStyle = "\e[90m"
|
||||
@@ -484,12 +478,6 @@ proc debug(n: PNode; conf: ConfigRef) =
|
||||
this.value(n)
|
||||
echo($this.res)
|
||||
|
||||
proc nextTry(h, maxHash: Hash): Hash {.inline.} =
|
||||
result = ((5 * h) + 1) and maxHash
|
||||
# For any initial h in range(maxHash), repeating that maxHash times
|
||||
# generates each int in range(maxHash) exactly once (see any text on
|
||||
# random-number generation for proof).
|
||||
|
||||
proc objectSetContains*(t: TObjectSet, obj: RootRef): bool =
|
||||
# returns true whether n is in t
|
||||
var h: Hash = hashNode(obj) and high(t.data) # start with real hash value
|
||||
@@ -537,95 +525,6 @@ proc objectSetContainsOrIncl*(t: var TObjectSet, obj: RootRef): bool =
|
||||
inc(t.counter)
|
||||
result = false
|
||||
|
||||
proc strTableContains*(t: TStrTable, n: PSym): bool =
|
||||
var h: Hash = n.name.h and high(t.data) # start with real hash value
|
||||
while t.data[h] != nil:
|
||||
if (t.data[h] == n):
|
||||
return true
|
||||
h = nextTry(h, high(t.data))
|
||||
result = false
|
||||
|
||||
proc strTableRawInsert(data: var seq[PSym], n: PSym) =
|
||||
var h: Hash = n.name.h and high(data)
|
||||
while data[h] != nil:
|
||||
if data[h] == n:
|
||||
# allowed for 'export' feature:
|
||||
#InternalError(n.info, "StrTableRawInsert: " & n.name.s)
|
||||
return
|
||||
h = nextTry(h, high(data))
|
||||
assert(data[h] == nil)
|
||||
data[h] = n
|
||||
|
||||
proc symTabReplaceRaw(data: var seq[PSym], prevSym: PSym, newSym: PSym) =
|
||||
assert prevSym.name.h == newSym.name.h
|
||||
var h: Hash = prevSym.name.h and high(data)
|
||||
while data[h] != nil:
|
||||
if data[h] == prevSym:
|
||||
data[h] = newSym
|
||||
return
|
||||
h = nextTry(h, high(data))
|
||||
assert false
|
||||
|
||||
proc symTabReplace*(t: var TStrTable, prevSym: PSym, newSym: PSym) =
|
||||
symTabReplaceRaw(t.data, prevSym, newSym)
|
||||
|
||||
proc strTableEnlarge(t: var TStrTable) =
|
||||
var n: seq[PSym]
|
||||
newSeq(n, t.data.len * GrowthFactor)
|
||||
for i in 0..high(t.data):
|
||||
if t.data[i] != nil: strTableRawInsert(n, t.data[i])
|
||||
swap(t.data, n)
|
||||
|
||||
proc strTableAdd*(t: var TStrTable, n: PSym) =
|
||||
if mustRehash(t.data.len, t.counter): strTableEnlarge(t)
|
||||
strTableRawInsert(t.data, n)
|
||||
inc(t.counter)
|
||||
|
||||
proc strTableInclReportConflict*(t: var TStrTable, n: PSym;
|
||||
onConflictKeepOld = false): PSym =
|
||||
# if `t` has a conflicting symbol (same identifier as `n`), return it
|
||||
# otherwise return `nil`. Incl `n` to `t` unless `onConflictKeepOld = true`
|
||||
# and a conflict was found.
|
||||
assert n.name != nil
|
||||
var h: Hash = n.name.h and high(t.data)
|
||||
var replaceSlot = -1
|
||||
while true:
|
||||
var it = t.data[h]
|
||||
if it == nil: break
|
||||
# Semantic checking can happen multiple times thanks to templates
|
||||
# and overloading: (var x=@[]; x).mapIt(it).
|
||||
# So it is possible the very same sym is added multiple
|
||||
# times to the symbol table which we allow here with the 'it == n' check.
|
||||
if it.name.id == n.name.id:
|
||||
if it == n: return nil
|
||||
replaceSlot = h
|
||||
h = nextTry(h, high(t.data))
|
||||
if replaceSlot >= 0:
|
||||
result = t.data[replaceSlot] # found it
|
||||
if not onConflictKeepOld:
|
||||
t.data[replaceSlot] = n # overwrite it with newer definition!
|
||||
return result # but return the old one
|
||||
elif mustRehash(t.data.len, t.counter):
|
||||
strTableEnlarge(t)
|
||||
strTableRawInsert(t.data, n)
|
||||
else:
|
||||
assert(t.data[h] == nil)
|
||||
t.data[h] = n
|
||||
inc(t.counter)
|
||||
result = nil
|
||||
|
||||
proc strTableIncl*(t: var TStrTable, n: PSym;
|
||||
onConflictKeepOld = false): bool {.discardable.} =
|
||||
result = strTableInclReportConflict(t, n, onConflictKeepOld) != nil
|
||||
|
||||
proc strTableGet*(t: TStrTable, name: PIdent): PSym =
|
||||
var h: Hash = name.h and high(t.data)
|
||||
while true:
|
||||
result = t.data[h]
|
||||
if result == nil: break
|
||||
if result.name.id == name.id: break
|
||||
h = nextTry(h, high(t.data))
|
||||
|
||||
|
||||
type
|
||||
TIdentIter* = object # iterator over all syms with same identifier
|
||||
|
||||
@@ -1031,3 +1031,106 @@ proc forcePartial*(t: PType) =
|
||||
t.paddingAtEndImpl = 0'i16
|
||||
t.locImpl = TLoc()
|
||||
t.typeInstImpl = nil
|
||||
|
||||
const # for all kind of hash tables:
|
||||
GrowthFactor* = 2 # must be power of 2, > 0
|
||||
StartSize* = 8 # must be power of 2, > 0
|
||||
|
||||
proc nextTry*(h, maxHash: Hash): Hash {.inline.} =
|
||||
result = ((5 * h) + 1) and maxHash
|
||||
# For any initial h in range(maxHash), repeating that maxHash times
|
||||
# generates each int in range(maxHash) exactly once (see any text on
|
||||
# random-number generation for proof).
|
||||
|
||||
proc mustRehash*(length, counter: int): bool =
|
||||
assert(length > counter)
|
||||
result = (length * 2 < counter * 3) or (length - counter < 4)
|
||||
|
||||
proc strTableContains*(t: TStrTable, n: PSym): bool =
|
||||
var h: Hash = n.name.h and high(t.data) # start with real hash value
|
||||
while t.data[h] != nil:
|
||||
if (t.data[h] == n):
|
||||
return true
|
||||
h = nextTry(h, high(t.data))
|
||||
result = false
|
||||
|
||||
proc strTableRawInsert(data: var seq[PSym], n: PSym) =
|
||||
var h: Hash = n.name.h and high(data)
|
||||
while data[h] != nil:
|
||||
if data[h] == n:
|
||||
# allowed for 'export' feature:
|
||||
#InternalError(n.info, "StrTableRawInsert: " & n.name.s)
|
||||
return
|
||||
h = nextTry(h, high(data))
|
||||
assert(data[h] == nil)
|
||||
data[h] = n
|
||||
|
||||
proc symTabReplaceRaw(data: var seq[PSym], prevSym: PSym, newSym: PSym) =
|
||||
assert prevSym.name.h == newSym.name.h
|
||||
var h: Hash = prevSym.name.h and high(data)
|
||||
while data[h] != nil:
|
||||
if data[h] == prevSym:
|
||||
data[h] = newSym
|
||||
return
|
||||
h = nextTry(h, high(data))
|
||||
assert false
|
||||
|
||||
proc symTabReplace*(t: var TStrTable, prevSym: PSym, newSym: PSym) =
|
||||
symTabReplaceRaw(t.data, prevSym, newSym)
|
||||
|
||||
proc strTableEnlarge(t: var TStrTable) =
|
||||
var n: seq[PSym]
|
||||
newSeq(n, t.data.len * GrowthFactor)
|
||||
for i in 0..high(t.data):
|
||||
if t.data[i] != nil: strTableRawInsert(n, t.data[i])
|
||||
swap(t.data, n)
|
||||
|
||||
proc strTableAdd*(t: var TStrTable, n: PSym) =
|
||||
if mustRehash(t.data.len, t.counter): strTableEnlarge(t)
|
||||
strTableRawInsert(t.data, n)
|
||||
inc(t.counter)
|
||||
|
||||
proc strTableInclReportConflict*(t: var TStrTable, n: PSym;
|
||||
onConflictKeepOld = false): PSym =
|
||||
# if `t` has a conflicting symbol (same identifier as `n`), return it
|
||||
# otherwise return `nil`. Incl `n` to `t` unless `onConflictKeepOld = true`
|
||||
# and a conflict was found.
|
||||
assert n.name != nil
|
||||
var h: Hash = n.name.h and high(t.data)
|
||||
var replaceSlot = -1
|
||||
while true:
|
||||
var it = t.data[h]
|
||||
if it == nil: break
|
||||
# Semantic checking can happen multiple times thanks to templates
|
||||
# and overloading: (var x=@[]; x).mapIt(it).
|
||||
# So it is possible the very same sym is added multiple
|
||||
# times to the symbol table which we allow here with the 'it == n' check.
|
||||
if it.name.id == n.name.id:
|
||||
if it == n: return nil
|
||||
replaceSlot = h
|
||||
h = nextTry(h, high(t.data))
|
||||
if replaceSlot >= 0:
|
||||
result = t.data[replaceSlot] # found it
|
||||
if not onConflictKeepOld:
|
||||
t.data[replaceSlot] = n # overwrite it with newer definition!
|
||||
return result # but return the old one
|
||||
elif mustRehash(t.data.len, t.counter):
|
||||
strTableEnlarge(t)
|
||||
strTableRawInsert(t.data, n)
|
||||
else:
|
||||
assert(t.data[h] == nil)
|
||||
t.data[h] = n
|
||||
inc(t.counter)
|
||||
result = nil
|
||||
|
||||
proc strTableIncl*(t: var TStrTable, n: PSym;
|
||||
onConflictKeepOld = false): bool {.discardable.} =
|
||||
result = strTableInclReportConflict(t, n, onConflictKeepOld) != nil
|
||||
|
||||
proc strTableGet*(t: TStrTable, name: PIdent): PSym =
|
||||
var h: Hash = name.h and high(t.data)
|
||||
while true:
|
||||
result = t.data[h]
|
||||
if result == nil: break
|
||||
if result.name.id == name.id: break
|
||||
h = nextTry(h, high(t.data))
|
||||
|
||||
Reference in New Issue
Block a user