diff options
-rw-r--r-- | compiler/passes.nim | 13 | ||||
-rw-r--r-- | compiler/sem.nim | 6 | ||||
-rw-r--r-- | compiler/semstmts.nim | 68 |
3 files changed, 75 insertions, 12 deletions
diff --git a/compiler/passes.nim b/compiler/passes.nim index e031dae10..ceb3e2b8a 100644 --- a/compiler/passes.nim +++ b/compiler/passes.nim @@ -190,8 +190,17 @@ proc processModule(module: PSym, stream: PLLStream, rd: PRodReader) = while true: var n = parseTopLevelStmt(p) if n.kind == nkEmpty: break - if not processTopLevelStmt(n, a): break - + if sfNoForward in module.flags: + # read everything, no streaming possible + var sl = newNodeI(nkStmtList, n.info) + sl.add n + while true: + var n = parseTopLevelStmt(p) + if n.kind == nkEmpty: break + sl.add n + discard processTopLevelStmt(sl, a) + break + elif not processTopLevelStmt(n, a): break closeParsers(p) if s.kind != llsStdIn: break closePasses(a) diff --git a/compiler/sem.nim b/compiler/sem.nim index 346a17df1..d23dd1543 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -421,7 +421,11 @@ proc myOpenCached(module: PSym, rd: PRodReader): PPassContext = for m in items(rd.methods): methodDef(m, true) proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = - result = semStmt(c, n) + if sfNoForward in c.module.flags: + result = semAllTypeSections(c, n) + else: + result = n + result = semStmt(c, result) # BUGFIX: process newly generated generics here, not at the end! if c.lastGenericIdx < c.generics.len: var a = newNodeI(nkStmtList, n.info) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 43cdca866..84a09a7e6 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -744,13 +744,62 @@ proc typeSectionFinalPass(c: PContext, n: PNode) = if s.typ.kind in {tyObject, tyTuple} and not s.typ.n.isNil: checkForMetaFields(s.typ.n) +proc semAllTypeSections(c: PContext; n: PNode): PNode = + proc gatherStmts(c: PContext; n: PNode; result: PNode) {.nimcall.} = + case n.kind + of nkIncludeStmt: + for i in 0..<n.len: + var f = checkModuleName(n.sons[i]) + if f != InvalidFileIDX: + if containsOrIncl(c.includedFiles, f): + localError(n.info, errRecursiveDependencyX, f.toFilename) + else: + let code = gIncludeFile(c.module, f) + gatherStmts c, code, result + excl(c.includedFiles, f) + of nkStmtList: + for i in 0 ..< n.len: + gatherStmts(c, n.sons[i], result) + of nkTypeSection: + incl n.flags, nfSem + typeSectionLeftSidePass(c, n) + result.add n + else: + result.add n + + result = newNodeI(nkStmtList, n.info) + gatherStmts(c, n, result) + + template rec(name) = + for i in 0 ..< result.len: + if result[i].kind == nkTypeSection: + name(c, result[i]) + + rec typeSectionRightSidePass + rec typeSectionFinalPass + when false: + # too beautiful to delete: + template rec(name; setbit=false) = + proc `name rec`(c: PContext; n: PNode) {.nimcall.} = + if n.kind == nkTypeSection: + when setbit: incl n.flags, nfSem + name(c, n) + elif n.kind == nkStmtList: + for i in 0 ..< n.len: + `name rec`(c, n.sons[i]) + `name rec`(c, n) + rec typeSectionLeftSidePass, true + rec typeSectionRightSidePass + rec typeSectionFinalPass + proc semTypeSection(c: PContext, n: PNode): PNode = ## Processes a type section. This must be done in separate passes, in order ## to allow the type definitions in the section to reference each other ## without regard for the order of their definitions. - typeSectionLeftSidePass(c, n) - typeSectionRightSidePass(c, n) - typeSectionFinalPass(c, n) + if sfNoForward notin c.module.flags or nfSem notin n.flags: + typeSectionLeftSidePass(c, n) + typeSectionRightSidePass(c, n) + typeSectionFinalPass(c, n) result = n proc semParamList(c: PContext, n, genericParams: PNode, s: PSym) = @@ -1033,12 +1082,13 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, n.sons[namePos] = newSymNode(s) s.ast = n #s.scope = c.currentScope - - if sfNoForward in c.module.flags and - sfSystemModule notin c.module.flags: - addInterfaceOverloadableSymAt(c, c.currentScope, s) - s.flags.incl sfForward - return + when false: + # disable for now + if sfNoForward in c.module.flags and + sfSystemModule notin c.module.flags: + addInterfaceOverloadableSymAt(c, c.currentScope, s) + s.flags.incl sfForward + return else: s = n[namePos].sym s.owner = getCurrOwner() |