diff --git a/compiler/ast2nif.nim b/compiler/ast2nif.nim index c419a934d8..01830b65fe 100644 --- a/compiler/ast2nif.nim +++ b/compiler/ast2nif.nim @@ -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 diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index fa7440aa8e..7deaa18157 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -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)]) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 399b07d1a5..b8de2a6de5 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -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") diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 48bf1ad6e3..b380b136d2 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -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) diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index 479babb0b9..5b5668024a 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -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 diff --git a/compiler/ic/cbackend.nim b/compiler/ic/cbackend.nim index 1cf5301bc0..0ea7d66e59 100644 --- a/compiler/ic/cbackend.nim +++ b/compiler/ic/cbackend.nim @@ -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] diff --git a/compiler/ic/enum2nif.nim b/compiler/ic/enum2nif.nim index bb0ed83ad1..4b7860fc96 100644 --- a/compiler/ic/enum2nif.nim +++ b/compiler/ic/enum2nif.nim @@ -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 diff --git a/compiler/modulegraphs.nim b/compiler/modulegraphs.nim index d338194ea5..372b096782 100644 --- a/compiler/modulegraphs.nim +++ b/compiler/modulegraphs.nim @@ -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) diff --git a/compiler/nifbackend.nim b/compiler/nifbackend.nim index b061591bf8..39da0d762e 100644 --- a/compiler/nifbackend.nim +++ b/compiler/nifbackend.nim @@ -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: diff --git a/compiler/options.nim b/compiler/options.nim index 479148d07c..6dcec635b3 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -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] diff --git a/compiler/pipelines.nim b/compiler/pipelines.nim index 7834a013c2..989f9c2d9a 100644 --- a/compiler/pipelines.nim +++ b/compiler/pipelines.nim @@ -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, diff --git a/compiler/renderer.nim b/compiler/renderer.nim index a2e7626b42..e8cdfad6d2 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -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 & ')') diff --git a/compiler/scriptconfig.nim b/compiler/scriptconfig.nim index e2df695268..10d3f73bc0 100644 --- a/compiler/scriptconfig.nim +++ b/compiler/scriptconfig.nim @@ -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 diff --git a/tools/enumgen.nim b/tools/enumgen.nim index 655cd030c2..d1a6473475 100644 --- a/tools/enumgen.nim +++ b/tools/enumgen.nim @@ -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", ""),