IC: code generation progress (#25379)

This commit is contained in:
Andreas Rumpf
2025-12-29 00:20:33 +01:00
committed by GitHub
parent 91d51923b9
commit 02893e2f4c
14 changed files with 465 additions and 303 deletions

View File

@@ -164,7 +164,7 @@ type
const
# Symbol kinds that are always local to a proc and should never have module suffix
skLocalSymKinds = {skParam, skGenericParam, skForVar, skResult, skTemp}
skLocalSymKinds = {skParam, skForVar, skResult, skTemp}
proc isLocalSym(sym: PSym): bool {.inline.} =
sym.kindImpl in skLocalSymKinds or
@@ -362,10 +362,7 @@ proc writeSymDef(w: var Writer; dest: var TokenBuf; sym: PSym) =
writeSym(w, dest, sym.ownerFieldImpl)
# Store the AST for routine symbols and constants
# Constants need their AST for astdef() to return the constant's value
if sym.kindImpl in routineKinds + {skConst}:
writeNode(w, dest, sym.astImpl, forAst = true)
else:
dest.addDotToken
writeNode(w, dest, sym.astImpl, forAst = true)
writeLoc w, dest, sym.locImpl
writeNode(w, dest, sym.constraintImpl)
writeSym(w, dest, sym.instantiatedFromImpl)
@@ -438,14 +435,20 @@ proc addLocalSym(w: var Writer; n: PNode) =
w.locals.incl(n.sym.itemId)
proc addLocalSyms(w: var Writer; n: PNode) =
if n.kind in {nkIdentDefs, nkVarTuple}:
case n.kind
of nkIdentDefs, nkVarTuple:
# nkIdentDefs: [ident1, ident2, ..., type, default]
# All children except the last two are identifiers
for i in 0 ..< max(0, n.len - 2):
addLocalSyms(w, n[i])
elif n.kind == nkSym:
of nkPostfix:
addLocalSyms(w, n[1])
of nkPragmaExpr:
addLocalSyms(w, n[0])
of nkSym:
addLocalSym(w, n)
else:
discard
proc trInclude(w: var Writer; n: PNode) =
w.deps.addParLe pool.tags.getOrIncl(toNifTag(n.kind)), trLineInfo(w, n.info)
@@ -456,6 +459,9 @@ proc trInclude(w: var Writer; n: PNode) =
w.deps.addStrLit child.strVal # raw string literal, no wrapper needed
w.deps.addParRi
proc moduleSuffix(conf: ConfigRef; f: FileIndex): string =
cachedModuleSuffix(conf, f)
proc trImport(w: var Writer; n: PNode) =
for child in n:
if child.kind == nkSym:
@@ -464,7 +470,7 @@ proc trImport(w: var Writer; n: PNode) =
w.deps.addDotToken # type
let s = child.sym
assert s.kindImpl == skModule
let fp = toFullPath(w.infos.config, s.positionImpl.FileIndex)
let fp = moduleSuffix(w.infos.config, s.positionImpl.FileIndex)
w.deps.addStrLit fp # raw string literal, no wrapper needed
w.deps.addParRi
@@ -512,14 +518,14 @@ proc writeNode(w: var Writer; dest: var TokenBuf; n: PNode; forAst = false) =
of nkNilLit:
w.withNode dest, n:
discard
of nkLetSection, nkVarSection, nkConstSection, nkGenericParams:
of nkLetSection, nkVarSection, nkConstSection:
# Track local variables declared in let/var sections
w.withNode dest, n:
for child in n:
addLocalSyms w, child
# Process the child node
writeNode(w, dest, child, forAst)
of nkForStmt, nkTypeDef:
of nkForStmt:
# Track for loop variable (first child is the loop variable)
w.withNode dest, n:
if n.len > 0:
@@ -535,7 +541,7 @@ proc writeNode(w: var Writer; dest: var TokenBuf; n: PNode; forAst = false) =
addLocalSyms(w, n[i])
writeNode(w, dest, n[i], forAst)
dec w.inProc
of nkProcDef, nkFuncDef, nkMethodDef, nkIteratorDef, nkConverterDef, nkMacroDef:
of nkProcDef, nkFuncDef, nkMethodDef, nkIteratorDef, nkConverterDef, nkMacroDef, nkTemplateDef:
# For top-level named routines (not forAst), just write the symbol.
# The full AST will be stored in the symbol's sdef.
if not forAst and n[namePos].kind == nkSym:
@@ -602,16 +608,53 @@ proc writeNode(w: var Writer; dest: var TokenBuf; n: PNode; forAst = false) =
# Write the export statement as a regular node
w.withNode dest, n:
for i in 0 ..< n.len:
writeNode(w, dest, n[i], forAst)
if n[i].kind == nkSym and n[i].sym.kindImpl == skModule:
discard "do not write module syms here"
else:
writeNode(w, dest, n[i], forAst)
else:
w.withNode dest, n:
for i in 0 ..< n.len:
writeNode(w, dest, n[i], forAst)
proc writeToplevelNode(w: var Writer; dest: var TokenBuf; n: PNode) =
proc writeGlobal(w: var Writer; dest: var TokenBuf; n: PNode) =
case n.kind
of nkVarTuple:
writeNode(w, dest, n)
of nkIdentDefs, nkConstDef:
# nkIdentDefs: [ident1, ident2, ..., type, default]
# All children except the last two are identifiers
for i in 0 ..< max(0, n.len - 2):
writeGlobal(w, dest, n[i])
of nkPostfix:
writeGlobal(w, dest, n[1])
of nkPragmaExpr:
writeGlobal(w, dest, n[0])
of nkSym:
writeSym(w, dest, n.sym)
else:
discard
proc writeGlobals(w: var Writer; dest: var TokenBuf; n: PNode) =
w.withNode dest, n:
for child in n:
writeGlobal(w, dest, child)
proc writeToplevelNode(w: var Writer; dest, bottom: var TokenBuf; n: PNode) =
case n.kind
of nkStmtList, nkStmtListExpr:
for son in n: writeToplevelNode(w, dest, son)
for son in n: writeToplevelNode(w, dest, bottom, son)
of nkEmpty:
discard "ignore"
of nkTypeSection, nkCommentStmt, nkMixinStmt, nkBindStmt, nkUsingStmt,
nkPragma,
nkProcDef, nkFuncDef, nkMethodDef, nkIteratorDef, nkConverterDef, nkMacroDef, nkTemplateDef:
# We write purely declarative nodes at the bottom of the file
writeNode(w, bottom, n)
of nkConstSection:
writeGlobals(w, bottom, n)
of nkLetSection, nkVarSection:
writeGlobals(w, dest, n)
else:
writeNode w, dest, n
@@ -652,6 +695,7 @@ let repMethodTag = registerTag("repmethod")
#let repClassTag = registerTag("repclass")
let includeTag = registerTag("include")
let importTag = registerTag("import")
let implTag = registerTag("implementation")
proc writeOp(w: var Writer; content: var TokenBuf; op: LogEntry) =
case op.kind
@@ -706,8 +750,14 @@ proc writeNifModule*(config: ConfigRef; thisModule: int32; n: PNode;
if op.module == thisModule.int:
writeOp(w, content, op)
w.writeToplevelNode content, n
var bottom = createTokenBuf(300)
w.writeToplevelNode content, bottom, n
# the implTag is used to tell the loader that the
# bottom of the file is the implementation of the module:
content.addParLe implTag, NoLineInfo
content.addParRi()
content.add bottom
content.addParRi()
let m = modname(w.currentModule, w.infos.config)
@@ -817,10 +867,14 @@ proc cursorFromIndexEntry(c: var DecodeContext; module: FileIndex; entry: NifInd
nifcursors.parse(s[], buf, entry.info)
result = cursorAt(buf, 0)
proc moduleId(c: var DecodeContext; suffix: string): FileIndex =
type
LoadFlag* = enum
LoadFullAst, AlwaysLoadInterface
proc moduleId(c: var DecodeContext; suffix: string; flags: set[LoadFlag] = {}): FileIndex =
var isKnownFile = false
result = c.infos.config.registerNifSuffix(suffix, isKnownFile)
if not isKnownFile:
if not isKnownFile or AlwaysLoadInterface in flags:
let modFile = (getNimcacheDir(c.infos.config) / RelativeFile(suffix & ".nif")).string
let idxFile = (getNimcacheDir(c.infos.config) / RelativeFile(suffix & ".s.idx.nif")).string
if not fileExists(modFile):
@@ -1099,6 +1153,8 @@ proc loadSymFromCursor(c: var DecodeContext; s: PSym; n: var Cursor; thisModule:
inc n
var isKnownFile = false
s.positionImpl = int c.infos.config.registerNifSuffix(thisModule, isKnownFile)
# do to the precompiled mechanism things end up as main modules which are not!
excl s.flagsImpl, sfMainModule
else:
loadField s.positionImpl
@@ -1110,12 +1166,7 @@ proc loadSymFromCursor(c: var DecodeContext; s: PSym; n: var Cursor; thisModule:
s.ownerFieldImpl = loadSymStub(c, n, thisModule, localSyms)
# Load the AST for routine symbols and constants
# Constants need their AST for astdef() to return the constant's value
if s.kindImpl in routineKinds + {skConst}:
s.astImpl = loadNode(c, n, thisModule, localSyms)
elif n.kind == DotToken:
inc n
else:
raiseAssert "expected '.' for non-routine symbol AST but got " & $n.kind
s.astImpl = loadNode(c, n, thisModule, localSyms)
loadLoc c, n, s.locImpl
s.constraintImpl = loadNode(c, n, thisModule, localSyms)
s.instantiatedFromImpl = loadSymStub(c, n, thisModule, localSyms)
@@ -1303,9 +1354,6 @@ proc loadNode(c: var DecodeContext; n: var Cursor; thisModule: string;
else:
raiseAssert "expected string literal but got " & $n.kind
proc moduleSuffix(conf: ConfigRef; f: FileIndex): string =
cachedModuleSuffix(conf, f)
proc loadSymFromIndexEntry(c: var DecodeContext; module: FileIndex;
nifName: string; entry: NifIndexEntry; thisModule: string): PSym =
## Loads a symbol from the NIF index entry using the entry directly.
@@ -1494,8 +1542,32 @@ proc nextSubtree(r: var Stream; dest: var TokenBuf; tok: var PackedToken) =
dec nested
if nested == 0: break
proc processTopLevel(c: var DecodeContext; s: var Stream; loadFullAst: bool; suffix: string; logOps: var seq[LogEntry]; module: int): PNode =
result = newNode(nkStmtList)
type
ModuleSuffix* = distinct string
PrecompiledModule* = object
topLevel*: PNode # top level statements of the main module
deps*: seq[ModuleSuffix] # other modules we need to process the top level statements of
logOps*: seq[LogEntry]
module*: PSym # set by modulegraphs.nim!
proc loadImport(c: var DecodeContext; s: var Stream; deps: var seq[ModuleSuffix]; tok: var PackedToken) =
tok = next(s) # skip `(import`
if tok.kind == DotToken:
tok = next(s) # skip dot
if tok.kind == DotToken:
tok = next(s) # skip dot
if tok.kind == StringLit:
deps.add ModuleSuffix(pool.strings[tok.litId])
tok = next(s)
else:
raiseAssert "expected StringLit but got " & $tok.kind
if tok.kind == ParRi:
tok = next(s) # skip )
else:
raiseAssert "expected ParRi but got " & $tok.kind
proc processTopLevel(c: var DecodeContext; s: var Stream; flags: set[LoadFlag] = {}; suffix: string; module: int): PrecompiledModule =
result = PrecompiledModule(topLevel: newNode(nkStmtList))
var localSyms = initTable[string, PSym]()
var t = next(s) # skip dot
@@ -1512,60 +1584,62 @@ proc processTopLevel(c: var DecodeContext; s: var Stream; loadFullAst: bool; suf
var cursor = cursorAt(buf, 0)
let replayNode = loadNode(c, cursor, suffix, localSyms)
if replayNode != nil:
result.sons.add replayNode
result.topLevel.sons.add replayNode
t = next(s)
if t.kind == ParRi:
t = next(s)
else:
raiseAssert "expected ParRi but got " & $t.kind
elif t.tagId == repConverterTag:
t = loadLogOp(c, logOps, s, ConverterEntry, attachedTrace, module)
t = loadLogOp(c, result.logOps, s, ConverterEntry, attachedTrace, module)
elif t.tagId == repDestroyTag:
t = loadLogOp(c, logOps, s, HookEntry, attachedDestructor, module)
t = loadLogOp(c, result.logOps, s, HookEntry, attachedDestructor, module)
elif t.tagId == repWasMovedTag:
t = loadLogOp(c, logOps, s, HookEntry, attachedWasMoved, module)
t = loadLogOp(c, result.logOps, s, HookEntry, attachedWasMoved, module)
elif t.tagId == repCopyTag:
t = loadLogOp(c, logOps, s, HookEntry, attachedAsgn, module)
t = loadLogOp(c, result.logOps, s, HookEntry, attachedAsgn, module)
elif t.tagId == repSinkTag:
t = loadLogOp(c, logOps, s, HookEntry, attachedSink, module)
t = loadLogOp(c, result.logOps, s, HookEntry, attachedSink, module)
elif t.tagId == repDupTag:
t = loadLogOp(c, logOps, s, HookEntry, attachedDup, module)
t = loadLogOp(c, result.logOps, s, HookEntry, attachedDup, module)
elif t.tagId == repTraceTag:
t = loadLogOp(c, logOps, s, HookEntry, attachedTrace, module)
t = loadLogOp(c, result.logOps, s, HookEntry, attachedTrace, module)
elif t.tagId == repDeepCopyTag:
t = loadLogOp(c, logOps, s, HookEntry, attachedDeepCopy, module)
t = loadLogOp(c, result.logOps, s, HookEntry, attachedDeepCopy, module)
elif t.tagId == repEnumToStrTag:
t = loadLogOp(c, logOps, s, EnumToStrEntry, attachedTrace, module)
t = loadLogOp(c, result.logOps, s, EnumToStrEntry, attachedTrace, module)
elif t.tagId == repMethodTag:
t = loadLogOp(c, logOps, s, MethodEntry, attachedTrace, module)
t = loadLogOp(c, result.logOps, s, MethodEntry, attachedTrace, module)
#elif t.tagId == repClassTag:
# t = loadLogOp(c, logOps, s, ClassEntry, attachedTrace, module)
elif t.tagId == includeTag or t.tagId == importTag:
elif t.tagId == includeTag:
t = skipTree(s)
elif loadFullAst:
elif t.tagId == importTag:
loadImport(c, s, result.deps, t)
elif t.tagId == implTag:
cont = false
elif LoadFullAst in flags:
# Parse the full statement
var buf = createTokenBuf(50)
nextSubtree(s, buf, t)
t = next(s) # skip ParRi
var cursor = cursorAt(buf, 0)
let stmtNode = loadNode(c, cursor, suffix, localSyms)
if stmtNode != nil:
result.sons.add stmtNode
result.topLevel.sons.add stmtNode
else:
cont = false
else:
cont = false
proc loadNifModule*(c: var DecodeContext; f: FileIndex; interf, interfHidden: var TStrTable;
logOps: var seq[LogEntry];
loadFullAst: bool = false): PNode =
let suffix = moduleSuffix(c.infos.config, f)
# Ensure module index is loaded - moduleId returns the FileIndex for this suffix
let module = moduleId(c, suffix)
proc loadNifModule*(c: var DecodeContext; suffix: ModuleSuffix; interf, interfHidden: var TStrTable;
flags: set[LoadFlag] = {}): PrecompiledModule =
# Ensure module index is loaded - moduleId returns the FileIndex for this suffix
let module = moduleId(c, string(suffix), flags)
# Populate interface tables from the NIF index structure
# Symbols are created as stubs (Partial state) and will be loaded lazily via loadSym
populateInterfaceTablesFromIndex(c, module, interf, interfHidden, suffix)
populateInterfaceTablesFromIndex(c, module, interf, interfHidden, string(suffix))
# Load the module AST (or just replay actions if loadFullAst is false)
let s = addr c.mods[module].stream
@@ -1575,10 +1649,14 @@ proc loadNifModule*(c: var DecodeContext; f: FileIndex; interf, interfHidden: va
if t.kind == ParLe and pool.tags[t.tagId] == toNifTag(nkStmtList):
t = next(s[]) # skip (stmts
t = next(s[]) # skip flags
result = processTopLevel(c, s[], loadFullAst, suffix, logOps, f.int)
result = processTopLevel(c, s[], flags, string(suffix), module.int)
else:
result = newNode(nkStmtList)
result = PrecompiledModule(topLevel: newNode(nkStmtList))
proc loadNifModule*(c: var DecodeContext; f: FileIndex; interf, interfHidden: var TStrTable;
flags: set[LoadFlag] = {}): PrecompiledModule =
let suffix = ModuleSuffix(moduleSuffix(c.infos.config, f))
result = loadNifModule(c, suffix, interf, interfHidden, flags)
when isMainModule:
import std / syncio

View File

@@ -126,7 +126,7 @@ proc genVarTuple(p: BProc, n: PNode) =
let vn = n[i]
let v = vn.sym
if sfCompileTime in v.flags: continue
ensureMutable v
backendEnsureMutable v
if sfGlobal in v.flags:
assignGlobalVar(p, vn, "")
genObjectInit(p, cpsInit, v.typ, v.locImpl, constructObj)
@@ -136,7 +136,7 @@ proc genVarTuple(p: BProc, n: PNode) =
initLocalVar(p, v, immediateAsgn=isAssignedImmediately(p.config, n[^1]))
var field = initLoc(locExpr, vn, tup.storage)
let rtup = rdLoc(tup)
let fieldName =
let fieldName =
if t.kind == tyTuple:
"Field" & $i
else:
@@ -490,14 +490,17 @@ proc genClosureVar(p: BProc, a: PNode) =
constructLoc(p, v)
proc genVarStmt(p: BProc, n: PNode) =
for it in n.sons:
if it.kind == nkCommentStmt: continue
if it.kind == nkIdentDefs:
for it in n:
case it.kind
of nkCommentStmt: discard
of nkIdentDefs:
# can be a lifted var nowadays ...
if it[0].kind == nkSym:
genSingleVar(p, it)
else:
genClosureVar(p, it)
of nkSym:
genSingleVar(p, it.sym, newSymNode(it.sym), it.sym.astdef)
else:
genVarTuple(p, it)
@@ -740,9 +743,10 @@ proc genBlock(p: BProc, n: PNode, d: var TLoc) =
# named block?
assert(n[0].kind == nkSym)
var sym = n[0].sym
ensureMutable sym
backendEnsureMutable sym
sym.locImpl.k = locOther
sym.position = p.breakIdx+1
sym.positionImpl = p.breakIdx+1
# ^ IC: review this
expr(p, n[1], d)
endSimpleBlock(p, scope)
@@ -1255,7 +1259,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
initElifBranch(p.s(cpsStmts), ifStmt, orExpr)
if exvar != nil:
fillLocalName(p, exvar.sym)
ensureMutable exvar.sym
backendEnsureMutable exvar.sym
fillLoc(exvar.sym.locImpl, locTemp, exvar, OnStack)
linefmt(p, cpsStmts, "$1 $2 = T$3_;$n", [getTypeDesc(p.module, exvar.sym.typ),
rdLoc(exvar.sym.loc), rope(etmp+1)])
@@ -1304,7 +1308,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
if isImportedException(typeNode.typ, p.config):
let exvar = t[i][j][2] # ex1 in `except ExceptType as ex1:`
fillLocalName(p, exvar.sym)
ensureMutable exvar.sym
backendEnsureMutable exvar.sym
fillLoc(exvar.sym.locImpl, locTemp, exvar, OnStack)
startBlockWith(p):
lineCg(p, cpsStmts, "catch ($1& $2) {$n", [getTypeDesc(p.module, typeNode.typ), rdLoc(exvar.sym.loc)])
@@ -1396,7 +1400,7 @@ proc genTryCppOld(p: BProc, t: PNode, d: var TLoc) =
if t[i][j].isInfixAs():
let exvar = t[i][j][2] # ex1 in `except ExceptType as ex1:`
fillLocalName(p, exvar.sym)
ensureMutable exvar.sym
backendEnsureMutable exvar.sym
fillLoc(exvar.sym.locImpl, locTemp, exvar, OnUnknown)
startBlockWith(p):
lineCg(p, cpsStmts, "catch ($1& $2) {$n", [getTypeDesc(p.module, t[i][j][1].typ), rdLoc(exvar.sym.loc)])

View File

@@ -1864,7 +1864,7 @@ proc genTypeInfoV2Impl(m: BModule; t, origType: PType, name: Rope; info: TLineIn
proc myModuleOpenForCodegen(m: BModule; idx: FileIndex): bool {.inline.} =
if moduleOpenForCodegen(m.g.graph, idx):
result = idx.int < m.g.modules.len and m.g.modules[idx.int] != nil
result = idx.int < m.g.mods.len and m.g.mods[idx.int] != nil
else:
result = false
@@ -1898,7 +1898,7 @@ proc genTypeInfoV2(m: BModule; t: PType; info: TLineInfo): Rope =
let owner = t.skipTypes(typedescPtrs).itemId.module
if owner != m.module.position and myModuleOpenForCodegen(m, FileIndex owner):
# make sure the type info is created in the owner module
discard genTypeInfoV2(m.g.modules[owner], origType, info)
discard genTypeInfoV2(m.g.mods[owner], origType, info)
# reference the type info as extern here
cgsym(m, "TNimTypeV2")
declareNimType(m, "TNimTypeV2", result, owner)
@@ -1983,7 +1983,7 @@ proc genTypeInfoV1(m: BModule; t: PType; info: TLineInfo): Rope =
var owner = t.skipTypes(typedescPtrs).itemId.module
if owner != m.module.position and myModuleOpenForCodegen(m, FileIndex owner):
# make sure the type info is created in the owner module
discard genTypeInfoV1(m.g.modules[owner], origType, info)
discard genTypeInfoV1(m.g.mods[owner], origType, info)
# reference the type info as extern here
cgsym(m, "TNimType")
cgsym(m, "TNimNode")

View File

@@ -67,19 +67,19 @@ proc findPendingModule(m: BModule, s: PSym): BModule =
# TODO fixme
if m.config.symbolFiles == v2Sf or optCompress in m.config.globalOptions:
let ms = s.itemId.module #getModule(s)
result = m.g.modules[ms]
result = m.g.mods[ms]
elif m.config.cmd in {cmdNifC, cmdM}:
var ms = getModule(s)
registerModule m.g.graph, ms
if ms.position >= m.g.modules.len:
if ms.position >= m.g.mods.len:
result = newModule(m.g, ms, m.config, idGeneratorFromModule(ms))
else:
result = m.g.modules[ms.position]
result = m.g.mods[ms.position]
if result == nil:
result = newModule(m.g, ms, m.config, idGeneratorFromModule(ms))
else:
var ms = getModule(s)
result = m.g.modules[ms.position]
result = m.g.mods[ms.position]
proc initLoc(k: TLocKind, lode: PNode, s: TStorageLoc, flags: TLocFlags = {}): TLoc =
result = TLoc(k: k, storage: s, lode: lode,
@@ -133,10 +133,10 @@ proc getModuleDllPath(m: BModule): Rope =
result = makeCString(dir.string & "/" & filename)
proc getModuleDllPath(m: BModule, module: int): Rope =
result = getModuleDllPath(m.g.modules[module])
result = getModuleDllPath(m.g.mods[module])
proc getModuleDllPath(m: BModule, s: PSym): Rope =
result = getModuleDllPath(m.g.modules[s.itemId.module])
result = getModuleDllPath(m.g.mods[s.itemId.module])
import std/macros
@@ -1720,9 +1720,12 @@ proc genMainProcs(m: BModule) =
proc genMainProcsWithResult(m: BModule) =
genMainProcs(m)
var res = "nim_program_result"
if m.hcrOn: res = cDeref(res)
m.s[cfsProcs].addReturn(res)
if m.config.cmd != cmdNifC:
var res = "nim_program_result"
if m.hcrOn: res = cDeref(res)
m.s[cfsProcs].addReturn(res)
else:
m.s[cfsProcs].addReturn(cIntValue(0))
proc genNimMainInner(m: BModule) =
m.s[cfsProcs].addDeclWithVisibility(Private):
@@ -1960,7 +1963,7 @@ proc registerModuleToMain(g: BModuleList; m: BModule) =
if m.hcrOn:
var hcrModuleMeta = newBuilder("")
let systemModulePath = getModuleDllPath(m, g.modules[g.graph.config.m.systemFileIdx.int].module)
let systemModulePath = getModuleDllPath(m, g.mods[g.graph.config.m.systemFileIdx.int].module)
let mainModulePath = getModuleDllPath(m, m.module)
hcrModuleMeta.addDeclWithVisibility(Private):
hcrModuleMeta.addArrayVarWithInitializer(kind = Local,
@@ -1977,7 +1980,7 @@ proc registerModuleToMain(g: BModuleList; m: BModule) =
g.graph.importDeps.withValue(FileIndex(m.module.position), deps):
for curr in deps[]:
hcrModuleMeta.addField(modules, ""):
hcrModuleMeta.add(getModuleDllPath(m, g.modules[curr.int].module))
hcrModuleMeta.add(getModuleDllPath(m, g.mods[curr.int].module))
hcrModuleMeta.addField(modules, ""):
hcrModuleMeta.add("\"\"")
hcrModuleMeta.addDeclWithVisibility(ExportLib):
@@ -2170,6 +2173,8 @@ proc genInitCode(m: BModule) =
else:
prcBody.add(extract(m.thing.s(section)))
#echo "PRE INIT PROC ", m.module.name.s, " ", m.s[cfsVars].buf.len
if m.preInitProc.s(cpsInit).buf.len > 0 or m.preInitProc.s(cpsStmts).buf.len > 0:
# Give this small function its own scope
prcBody.addScope():
@@ -2386,10 +2391,10 @@ proc newModule(g: BModuleList; module: PSym; conf: ConfigRef; idgen: IdGenerator
# we should create only one cgen module for each module sym
result = rawNewModule(g, module, conf)
result.idgen = idgen
if module.position >= g.modules.len:
setLen(g.modules, module.position + 1)
if module.position >= g.mods.len:
setLen(g.mods, module.position + 1)
#growCache g.modules, module.position
g.modules[module.position] = result
g.mods[module.position] = result
template injectG() {.dirty.} =
if graph.backend == nil:
@@ -2523,13 +2528,7 @@ proc shouldRecompile(m: BModule; code: Rope, cfile: Cfile): bool =
rawMessage(m.config, errCannotOpenFile, cfile.cname.string)
result = true
# We need 2 different logics here: pending modules (including
# 'nim__dat') may require file merging for the combination of dead code
# elimination and incremental compilation! Non pending modules need no
# such logic and in fact the logic hurts for the main module at least;
# it would generate multiple 'main' procs, for instance.
proc writeModule(m: BModule, pending: bool) =
proc writeModule(m: BModule) =
let cfile = getCFile(m)
if moduleHasChanged(m.g.graph, m.module):
genInitCode(m)
@@ -2658,7 +2657,7 @@ proc genForwardedProcs(g: BModuleList) =
while g.forwardedProcs.len > 0:
let
prc = g.forwardedProcs.pop()
m = g.modules[prc.itemId.module]
m = g.mods[prc.itemId.module]
if sfForward in prc.flags:
internalError(m.config, prc.info, "still forwarded: " & prc.name.s)
@@ -2674,6 +2673,6 @@ proc cgenWriteModules*(backend: RootRef, config: ConfigRef) =
genForwardedProcs(g)
for m in cgenModules(g):
m.writeModule(pending=true)
m.writeModule()
writeMapping(config, g.mapping)
if g.generatedHeader != nil: writeHeader(g.generatedHeader)

View File

@@ -117,7 +117,7 @@ type
BModuleList* = ref object of RootObj
mainModProcs*, mainModInit*, otherModsInit*, mainDatInit*: Builder
mapping*: Rope # the generated mapping file (if requested)
modules*: seq[BModule] # list of all compiled modules
mods*: seq[BModule] # list of all compiled modules
modulesClosed*: seq[BModule] # list of the same compiled modules, but in the order they were closed
forwardedProcs*: seq[PSym] # procs that did not yet have a body
generatedHeader*: BModule

View File

@@ -40,7 +40,7 @@ proc setupBackendModule(g: ModuleGraph; m: var LoadedModule) =
var bmod = cgen.newModule(BModuleList(g.backend), m.module, g.config, idgenFromLoadedModule(m))
proc generateCodeForModule(g: ModuleGraph; m: var LoadedModule; alive: var AliveSyms) =
var bmod = BModuleList(g.backend).modules[m.module.position]
var bmod = BModuleList(g.backend).mods[m.module.position]
assert bmod != nil
bmod.flags.incl useAliveDataFromDce
bmod.alive = move alive[m.module.position]

View File

@@ -404,140 +404,140 @@ proc parse*(t: typedesc[TSymKind]; s: string): TSymKind =
proc toNifTag*(s: TTypeKind): string =
case s
of tyNone: "none"
of tyBool: "bool"
of tyChar: "char"
of tyEmpty: "empty"
of tyAlias: "alias"
of tyNil: "nil"
of tyUntyped: "untyped"
of tyTyped: "typed"
of tyTypeDesc: "typedesc"
of tyGenericInvocation: "ginvoke"
of tyGenericBody: "gbody"
of tyGenericInst: "ginst"
of tyGenericParam: "gparam"
of tyDistinct: "distinct"
of tyEnum: "enum"
of tyOrdinal: "ordinal"
of tyArray: "array"
of tyObject: "object"
of tyTuple: "tuple"
of tySet: "set"
of tyRange: "range"
of tyPtr: "ptr"
of tyRef: "ref"
of tyVar: "mut"
of tySequence: "seq"
of tyProc: "proctype"
of tyPointer: "pointer"
of tyOpenArray: "openarray"
of tyString: "string"
of tyCstring: "cstring"
of tyForward: "forward"
of tyInt: "int"
of tyInt8: "int8"
of tyInt16: "int16"
of tyInt32: "int32"
of tyInt64: "int64"
of tyFloat: "float"
of tyFloat32: "float32"
of tyFloat64: "float64"
of tyFloat128: "float128"
of tyUInt: "uint"
of tyUInt8: "uint8"
of tyUInt16: "uint16"
of tyUInt32: "uint32"
of tyUInt64: "uint64"
of tyOwned: "owned"
of tySink: "sink"
of tyLent: "lent"
of tyVarargs: "varargs"
of tyUncheckedArray: "uarray"
of tyError: "error"
of tyBuiltInTypeClass: "bconcept"
of tyUserTypeClass: "uconcept"
of tyUserTypeClassInst: "uconceptinst"
of tyCompositeTypeClass: "cconcept"
of tyInferred: "inferred"
of tyAnd: "and"
of tyOr: "or"
of tyNot: "not"
of tyAnything: "anything"
of tyStatic: "static"
of tyFromExpr: "fromx"
of tyConcept: "concept"
of tyVoid: "void"
of tyIterable: "iterable"
of tyNone: "n0"
of tyBool: "b0"
of tyChar: "c0"
of tyEmpty: "e0"
of tyAlias: "a0"
of tyNil: "n1"
of tyUntyped: "U0"
of tyTyped: "t0"
of tyTypeDesc: "t1"
of tyGenericInvocation: "g0"
of tyGenericBody: "g1"
of tyGenericInst: "g2"
of tyGenericParam: "g4"
of tyDistinct: "d0"
of tyEnum: "e1"
of tyOrdinal: "o0"
of tyArray: "a1"
of tyObject: "o1"
of tyTuple: "t2"
of tySet: "s0"
of tyRange: "r0"
of tyPtr: "p0"
of tyRef: "r1"
of tyVar: "v0"
of tySequence: "s1"
of tyProc: "p1"
of tyPointer: "p2"
of tyOpenArray: "o3"
of tyString: "s2"
of tyCstring: "c1"
of tyForward: "F0"
of tyInt: "i0"
of tyInt8: "i1"
of tyInt16: "i2"
of tyInt32: "i3"
of tyInt64: "i4"
of tyFloat: "f0"
of tyFloat32: "f1"
of tyFloat64: "f2"
of tyFloat128: "f3"
of tyUInt: "u0"
of tyUInt8: "u1"
of tyUInt16: "u2"
of tyUInt32: "u3"
of tyUInt64: "u4"
of tyOwned: "o2"
of tySink: "s3"
of tyLent: "L0"
of tyVarargs: "v1"
of tyUncheckedArray: "U1"
of tyError: "e2"
of tyBuiltInTypeClass: "b1"
of tyUserTypeClass: "U2"
of tyUserTypeClassInst: "U3"
of tyCompositeTypeClass: "c2"
of tyInferred: "I0"
of tyAnd: "a2"
of tyOr: "o4"
of tyNot: "n2"
of tyAnything: "a3"
of tyStatic: "s4"
of tyFromExpr: "F1"
of tyConcept: "c3"
of tyVoid: "v2"
of tyIterable: "I1"
proc parse*(t: typedesc[TTypeKind]; s: string): TTypeKind =
case s
of "none": tyNone
of "bool": tyBool
of "char": tyChar
of "empty": tyEmpty
of "alias": tyAlias
of "nil": tyNil
of "untyped": tyUntyped
of "typed": tyTyped
of "typedesc": tyTypeDesc
of "ginvoke": tyGenericInvocation
of "gbody": tyGenericBody
of "ginst": tyGenericInst
of "gparam": tyGenericParam
of "distinct": tyDistinct
of "enum": tyEnum
of "ordinal": tyOrdinal
of "array": tyArray
of "object": tyObject
of "tuple": tyTuple
of "set": tySet
of "range": tyRange
of "ptr": tyPtr
of "ref": tyRef
of "mut": tyVar
of "seq": tySequence
of "proctype": tyProc
of "pointer": tyPointer
of "openarray": tyOpenArray
of "string": tyString
of "cstring": tyCstring
of "forward": tyForward
of "int": tyInt
of "int8": tyInt8
of "int16": tyInt16
of "int32": tyInt32
of "int64": tyInt64
of "float": tyFloat
of "float32": tyFloat32
of "float64": tyFloat64
of "float128": tyFloat128
of "uint": tyUInt
of "uint8": tyUInt8
of "uint16": tyUInt16
of "uint32": tyUInt32
of "uint64": tyUInt64
of "owned": tyOwned
of "sink": tySink
of "lent": tyLent
of "varargs": tyVarargs
of "uarray": tyUncheckedArray
of "error": tyError
of "bconcept": tyBuiltInTypeClass
of "uconcept": tyUserTypeClass
of "uconceptinst": tyUserTypeClassInst
of "cconcept": tyCompositeTypeClass
of "inferred": tyInferred
of "and": tyAnd
of "or": tyOr
of "not": tyNot
of "anything": tyAnything
of "static": tyStatic
of "fromx": tyFromExpr
of "concept": tyConcept
of "void": tyVoid
of "iterable": tyIterable
of "n0": tyNone
of "b0": tyBool
of "c0": tyChar
of "e0": tyEmpty
of "a0": tyAlias
of "n1": tyNil
of "U0": tyUntyped
of "t0": tyTyped
of "t1": tyTypeDesc
of "g0": tyGenericInvocation
of "g1": tyGenericBody
of "g2": tyGenericInst
of "g4": tyGenericParam
of "d0": tyDistinct
of "e1": tyEnum
of "o0": tyOrdinal
of "a1": tyArray
of "o1": tyObject
of "t2": tyTuple
of "s0": tySet
of "r0": tyRange
of "p0": tyPtr
of "r1": tyRef
of "v0": tyVar
of "s1": tySequence
of "p1": tyProc
of "p2": tyPointer
of "o3": tyOpenArray
of "s2": tyString
of "c1": tyCstring
of "F0": tyForward
of "i0": tyInt
of "i1": tyInt8
of "i2": tyInt16
of "i3": tyInt32
of "i4": tyInt64
of "f0": tyFloat
of "f1": tyFloat32
of "f2": tyFloat64
of "f3": tyFloat128
of "u0": tyUInt
of "u1": tyUInt8
of "u2": tyUInt16
of "u3": tyUInt32
of "u4": tyUInt64
of "o2": tyOwned
of "s3": tySink
of "L0": tyLent
of "v1": tyVarargs
of "U1": tyUncheckedArray
of "e2": tyError
of "b1": tyBuiltInTypeClass
of "U2": tyUserTypeClass
of "U3": tyUserTypeClassInst
of "c2": tyCompositeTypeClass
of "I0": tyInferred
of "a2": tyAnd
of "o4": tyOr
of "n2": tyNot
of "a3": tyAnything
of "s4": tyStatic
of "F1": tyFromExpr
of "c3": tyConcept
of "v2": tyVoid
of "I1": tyIterable
else: tyNone

View File

@@ -471,7 +471,7 @@ proc copyTypeProps*(g: ModuleGraph; module: int; dest, src: PType) =
proc loadCompilerProc*(g: ModuleGraph; name: string): PSym =
result = nil
if g.config.symbolFiles == disabledSf:
if g.config.symbolFiles == disabledSf and optWithinConfigSystem notin g.config.globalOptions:
# For NIF-based compilation, search in loaded NIF modules
when not defined(nimKochBootstrap):
# Only try to resolve from NIF if we're actually using NIF files (cmdNifC)
@@ -599,9 +599,10 @@ proc registerModule*(g: ModuleGraph; m: PSym) =
if m.position >= g.packed.len:
setLen(g.packed.pm, m.position + 1)
g.ifaces[m.position] = Iface(module: m, converters: @[], patterns: @[],
uniqueName: rope(uniqueModuleName(g.config, m)))
initStrTables(g, m)
if g.ifaces[m.position].module == nil:
g.ifaces[m.position] = Iface(module: m, converters: @[], patterns: @[],
uniqueName: rope(uniqueModuleName(g.config, m)))
initStrTables(g, m)
proc registerModuleById*(g: ModuleGraph; m: FileIndex) =
registerModule(g, g.packed[int m].module)
@@ -814,31 +815,33 @@ proc moduleFromRodFile*(g: ModuleGraph; fileIdx: FileIndex;
when not defined(nimKochBootstrap):
proc moduleFromNifFile*(g: ModuleGraph; fileIdx: FileIndex;
cachedModules: var seq[FileIndex];
loadFullAst: bool = false): PSym =
flags: set[LoadFlag] = {}): PrecompiledModule =
## Returns 'nil' if the module needs to be recompiled.
## Loads module from NIF file when optCompress is enabled.
## When loadFullAst is true, loads the complete module AST for code generation.
if not fileExists(toNifFilename(g.config, fileIdx)):
return nil
return PrecompiledModule(module: nil)
# Create module symbol
let filename = AbsoluteFile toFullPath(g.config, fileIdx)
result = PSym(
let m = PSym(
kindImpl: skModule,
itemId: ItemId(module: int32(fileIdx), item: 0'i32),
name: getIdent(g.cache, splitFile(filename).name),
infoImpl: newLineInfo(fileIdx, 1, 1),
positionImpl: int(fileIdx))
setOwner(result, getPackage(g.config, g.cache, fileIdx))
setOwner(m, getPackage(g.config, g.cache, fileIdx))
# Register module in graph
registerModule(g, result)
var opsLog: seq[LogEntry] = @[]
result.astImpl = loadNifModule(ast.program, fileIdx, g.ifaces[fileIdx.int].interf,
g.ifaces[fileIdx.int].interfHidden, opsLog, loadFullAst)
registerModule(g, m)
result = loadNifModule(ast.program, fileIdx,
g.ifaces[fileIdx.int].interf,
g.ifaces[fileIdx.int].interfHidden, flags)
result.module = m
# Register hooks from NIF index with the module graph
for x in opsLog:
for x in result.logOps:
case x.kind
of HookEntry:
g.loadedOps[x.op][x.key] = x.sym
@@ -852,7 +855,6 @@ when not defined(nimKochBootstrap):
raiseAssert "GenericInstEntry should not be in the NIF index"
# Register methods per type from NIF index
discard "todo"
cachedModules.add fileIdx
proc configComplete*(g: ModuleGraph) =
rememberStartupConfig(g.startupPackedConfig, g.config)

View File

@@ -25,30 +25,36 @@ when defined(nimPreviewSlimSystem):
import ast, options, lineinfos, modulegraphs, cgendata, cgen,
pathutils, extccomp, msgs, modulepaths, idents, types, ast2nif
proc loadModuleDependencies(g: ModuleGraph; mainFileIdx: FileIndex): seq[PSym] =
proc loadModuleDependencies(g: ModuleGraph; mainFileIdx: FileIndex): seq[PrecompiledModule] =
## Traverse the module dependency graph using a stack.
## Returns all modules that need code generation, in dependency order.
var visited = initIntSet()
var stack: seq[FileIndex] = @[mainFileIdx]
let mainModule = moduleFromNifFile(g, mainFileIdx, {LoadFullAst})
var stack: seq[ModuleSuffix] = @[]
result = @[]
var cachedModules: seq[FileIndex] = @[]
if mainModule.module != nil:
incl mainModule.module.flagsImpl, sfMainModule
for dep in mainModule.deps:
stack.add dep
var visited = initHashSet[string]()
while stack.len > 0:
let fileIdx = stack.pop()
let suffix = stack.pop()
if not visited.containsOrIncl(int(fileIdx)):
# Only load full AST for main module; others are loaded lazily by codegen
let isMainModule = fileIdx == mainFileIdx
let module = moduleFromNifFile(g, fileIdx, cachedModules, loadFullAst=isMainModule)
if module != nil:
result.add module
if isMainModule:
incl module.flagsImpl, sfMainModule
# Add dependencies to stack (they come from cachedModules)
for dep in cachedModules:
if not visited.contains(int(dep)):
if not visited.containsOrIncl(suffix.string):
let nifFile = toGeneratedFile(g.config, AbsoluteFile(suffix.string), ".nif")
let fileIdx = msgs.fileInfoIdx(g.config, nifFile)
let precomp = moduleFromNifFile(g, fileIdx, {LoadFullAst})
if precomp.module != nil:
result.add precomp
for dep in precomp.deps:
if not visited.contains(dep.string):
stack.add dep
cachedModules.setLen(0)
if mainModule.module != nil:
result.add mainModule
proc setupNifBackendModule(g: ModuleGraph; module: PSym): BModule =
## Set up a BModule for code generation from a NIF module.
@@ -56,38 +62,44 @@ proc setupNifBackendModule(g: ModuleGraph; module: PSym): BModule =
g.backend = cgendata.newModuleList(g)
result = cgen.newModule(BModuleList(g.backend), module, g.config, idGeneratorFromModule(module))
proc generateCodeForModule(g: ModuleGraph; module: PSym) =
## Generate C code for a single module.
let moduleId = module.position
var bmod = BModuleList(g.backend).modules[moduleId]
if bmod == nil:
bmod = setupNifBackendModule(g, module)
# Generate code for the module's top-level statements
if module.ast != nil:
cgen.genTopLevelStmt(bmod, module.ast)
proc finishModule(g: ModuleGraph; bmod: BModule) =
# Finalize the module (this adds it to modulesClosed)
# Create an empty stmt list as the init body - genInitCode in writeModule will set it up properly
let initStmt = newNodeI(nkStmtList, module.info)
let initStmt = newNode(nkStmtList)
finalCodegenActions(g, bmod, initStmt)
# Generate dispatcher methods
for disp in getDispatchers(g):
genProcLvl3(bmod, disp)
proc generateCodeForModule(g: ModuleGraph; precomp: PrecompiledModule) =
## Generate C code for a single module.
let moduleId = precomp.module.position
var bmod = BModuleList(g.backend).mods[moduleId]
if bmod == nil:
bmod = setupNifBackendModule(g, precomp.module)
# Generate code for the module's top-level statements
if precomp.topLevel != nil:
cgen.genTopLevelStmt(bmod, precomp.topLevel)
proc generateCode*(g: ModuleGraph; mainFileIdx: FileIndex) =
## Main entry point for NIF-based C code generation.
## Traverses the module dependency graph and generates C code.
# Reset backend state
resetForBackend(g)
let mainModule = g.getModule(mainFileIdx)
var isKnownFile = false
let systemFileIdx = registerNifSuffix(g.config, "sysma2dyk", isKnownFile)
g.config.m.systemFileIdx = systemFileIdx
#msgs.fileInfoIdx(g.config,
# g.config.libpath / RelativeFile"system.nim")
# Load system module first - it's always needed and contains essential hooks
var cachedModules: seq[FileIndex] = @[]
if g.config.m.systemFileIdx != InvalidFileIdx:
g.systemModule = moduleFromNifFile(g, g.config.m.systemFileIdx, cachedModules)
var precompSys = PrecompiledModule(module: nil)
precompSys = moduleFromNifFile(g, systemFileIdx, {LoadFullAst, AlwaysLoadInterface})
g.systemModule = precompSys.module
# Load all modules in dependency order using stack traversal
# This must happen BEFORE any code generation so that hooks are loaded into loadedOps
@@ -98,29 +110,35 @@ proc generateCode*(g: ModuleGraph; mainFileIdx: FileIndex) =
return
# Set up backend modules for all modules that need code generation
for module in modules:
discard setupNifBackendModule(g, module)
for m in modules:
discard setupNifBackendModule(g, m.module)
# Also ensure system module is set up and generated first if it exists
if g.systemModule != nil and g.systemModule != mainModule:
let systemBmod = BModuleList(g.backend).modules[g.systemModule.position]
if systemBmod == nil:
discard setupNifBackendModule(g, g.systemModule)
generateCodeForModule(g, g.systemModule)
if precompSys.module != nil:
discard setupNifBackendModule(g, precompSys.module)
generateCodeForModule(g, precompSys)
# Generate code for all modules except main (main goes last)
# This ensures all modules are added to modulesClosed
for module in modules:
if module != mainModule and module != g.systemModule:
generateCodeForModule(g, module)
# Track which modules have been processed to avoid duplicates
var processed = initIntSet()
if precompSys.module != nil:
processed.incl precompSys.module.position
# Generate main module last (so all init procs are registered)
if mainModule != nil:
generateCodeForModule(g, mainModule)
# Generate code for all modules (skip system since it's already processed)
for m in modules:
if not processed.containsOrIncl(m.module.position):
generateCodeForModule(g, m)
# during code generation of `main.nim` we can trigger the code generation
# of symbols in different modules so we need to finish these modules
# here later, after the above loop!
for m in BModuleList(g.backend).mods:
if m != nil:
assert m.module != nil
#if sfMainModule notin m.module.flags:
finishModule g, m
# Write C files
if g.backend != nil:
cgenWriteModules(g.backend, g.config)
cgenWriteModules(g.backend, g.config)
# Run C compiler
if g.config.cmd != cmdTcc:

View File

@@ -112,6 +112,7 @@ type # please make sure we have under 32 options
optJsBigInt64 # use bigints for 64-bit integers in JS
optItaniumMangle # mangling follows the Itanium spec
optCompress # turn on AST compression by converting it to NIF
optWithinConfigSystem # we still compile within the configuration system
TGlobalOptions* = set[TGlobalOption]

View File

@@ -286,8 +286,8 @@ proc compilePipelineModule*(graph: ModuleGraph; fileIdx: FileIndex; flags: TSymF
sfMainModule notin flags and
not graph.withinSystem and
not graph.config.isDefined("nimscript"):
result = moduleFromNifFile(graph, fileIdx, cachedModules)
if result == nil:
let precomp = moduleFromNifFile(graph, fileIdx)
if precomp.module == nil:
let nifPath = toNifFilename(graph.config, fileIdx)
localError(graph.config, unknownLineInfo,
"nim m requires precompiled NIF for import: " & toFullPath(graph.config, fileIdx) &
@@ -385,7 +385,8 @@ proc compilePipelineProject*(graph: ModuleGraph; projectFileIdx = InvalidFileIdx
graph.config.libpath / RelativeFile"system.nim")
var cachedModules: seq[FileIndex] = @[]
when not defined(nimKochBootstrap):
graph.systemModule = moduleFromNifFile(graph, graph.config.m.systemFileIdx, cachedModules)
let precomp = moduleFromNifFile(graph, graph.config.m.systemFileIdx)
graph.systemModule = precomp.module
if graph.systemModule == nil:
let nifPath = toNifFilename(graph.config, graph.config.m.systemFileIdx)
localError(graph.config, unknownLineInfo,

View File

@@ -1836,6 +1836,9 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext, fromStmtList = false) =
putWithSpace(g, tkSymbol, "error")
#gcomma(g, n, c)
gsub(g, n[0], c)
of nkReplayAction:
put(g, tkSymbol, "replayaction")
#gsons(g, n, c, 0)
else:
#nkNone, nkExplicitTypeListCall:
internalError(g.config, n.info, "renderer.gsub(" & $n.kind & ')')

View File

@@ -213,6 +213,7 @@ proc runNimScript*(cache: IdentCache; scriptName: AbsoluteFile;
unregisterArcOrc(conf)
conf.globalOptions.excl optOwnedRefs
conf.selectedGC = gcUnselected
conf.globalOptions.incl optWithinConfigSystem
var m = graph.makeModule(scriptName)
incl(m, sfMainModule)
@@ -251,4 +252,5 @@ proc runNimScript*(cache: IdentCache; scriptName: AbsoluteFile;
#initDefines()
undefSymbol(conf.symbols, "nimscript")
undefSymbol(conf.symbols, "nimconfig")
conf.globalOptions.excl optWithinConfigSystem
conf.symbolFiles = oldSymbolFiles

View File

@@ -28,10 +28,6 @@ const
("nkError", "err"),
("nkType", "onlytype"),
("nkTypeSection", "type"),
("tySequence", "seq"),
("tyVar", "mut"),
("tyProc", "proctype"),
("tyUncheckedArray", "uarray"),
("nkExprEqExpr", "vv"),
("nkExprColonExpr", "kv"),
("nkDerefExpr", "deref"),
@@ -55,17 +51,75 @@ const
("mVar", "varm"),
("mInSet", "contains"),
("mNil", "nilm"),
("tyBuiltInTypeClass", "bconcept"),
("tyUserTypeClass", "uconcept"),
("tyUserTypeClassInst", "uconceptinst"),
("tyCompositeTypeClass", "cconcept"),
("tyGenericInvocation", "ginvoke"),
("tyGenericBody", "gbody"),
("tyGenericInst", "ginst"),
("tyGenericParam", "gparam"),
("nkStmtList", "stmts"),
("nkDotExpr", "dot"),
("nkBracketExpr", "at")
("nkBracketExpr", "at"),
("tyNone", "n0"), # we always use a digit for type kinds so there can be no overlap with node kinds
("tyBool", "b0"),
("tyChar", "c0"),
("tyEmpty", "e0"),
("tyAlias", "a0"),
("tyNil", "n1"),
("tyUntyped", "U0"),
("tyTyped", "t0"),
("tyTypeDesc", "t1"),
("tyGenericInvocation", "g0"),
("tyGenericBody", "g1"),
("tyGenericInst", "g2"),
("tyGenericParam", "g4"),
("tyDistinct", "d0"),
("tyEnum", "e1"),
("tyOrdinal", "o0"),
("tyArray", "a1"),
("tyObject", "o1"),
("tyTuple", "t2"),
("tySet", "s0"),
("tyRange", "r0"),
("tyPtr", "p0"),
("tyRef", "r1"),
("tyVar", "v0"),
("tySequence", "s1"),
("tyProc", "p1"),
("tyPointer", "p2"),
("tyOpenArray", "o3"),
("tyString", "s2"),
("tyCstring", "c1"),
("tyForward", "F0"),
("tyInt", "i0"),
("tyInt8", "i1"),
("tyInt16", "i2"),
("tyInt32", "i3"),
("tyInt64", "i4"),
("tyFloat", "f0"),
("tyFloat32", "f1"),
("tyFloat64", "f2"),
("tyFloat128", "f3"),
("tyUInt", "u0"),
("tyUInt8", "u1"),
("tyUInt16", "u2"),
("tyUInt32", "u3"),
("tyUInt64", "u4"),
("tyOwned", "o2"),
("tySink", "s3"),
("tyLent", "L0"),
("tyVarargs", "v1"),
("tyUncheckedArray", "U1"),
("tyError", "e2"),
("tyBuiltInTypeClass", "b1"),
("tyUserTypeClass", "U2"),
("tyUserTypeClassInst", "U3"),
("tyCompositeTypeClass", "c2"),
("tyInferred", "I0"),
("tyAnd", "a2"),
("tyOr", "o4"),
("tyNot", "n2"),
("tyAnything", "a3"),
("tyStatic", "s4"),
("tyFromExpr", "F1"),
("tyConcept", "c3"),
("tyVoid", "v2"),
("tyIterable", "I1")
]
SuffixesToReplace = [
("Section", ""), ("Branch", ""), ("Stmt", ""), ("I", ""),