From 14e20ad72447ce95f3de16def2a18764f58d631c Mon Sep 17 00:00:00 2001 From: araq Date: Wed, 26 Nov 2025 10:22:47 +0100 Subject: [PATCH] refactoring --- compiler/ast.nim | 4 -- compiler/ast2nif.nim | 28 ++++++------ compiler/astalgo.nim | 101 ------------------------------------------ compiler/astdef.nim | 103 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 118 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 7ae2f67765..30b824d6c9 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -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) diff --git a/compiler/ast2nif.nim b/compiler/ast2nif.nim index dbf388e9d6..93751804b8 100644 --- a/compiler/ast2nif.nim +++ b/compiler/ast2nif.nim @@ -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 diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index 14dc7c5994..baa852b9e0 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -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 diff --git a/compiler/astdef.nim b/compiler/astdef.nim index fb32178223..cc0c4c49a6 100644 --- a/compiler/astdef.nim +++ b/compiler/astdef.nim @@ -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))