summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/passes.nim13
-rw-r--r--compiler/sem.nim6
-rw-r--r--compiler/semstmts.nim68
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()