summary refs log tree commit diff stats
path: root/compiler/semstmts.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/semstmts.nim')
-rw-r--r--compiler/semstmts.nim85
1 files changed, 70 insertions, 15 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index a8463cbed..84a09a7e6 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -102,10 +102,6 @@ proc semDestructorCheck(c: PContext, n: PNode, flags: TExprFlags) {.inline.} =
         c.p.owner.kind notin {skTemplate, skMacro}:
       localError(n.info, errGenerated, "value expected, but got a type")
 
-proc newDeref(n: PNode): PNode {.inline.} =
-  result = newNodeIT(nkHiddenDeref, n.info, n.typ.sons[0])
-  addSon(result, n)
-
 proc semExprBranch(c: PContext, n: PNode): PNode =
   result = semExpr(c, n)
   if result.typ != nil:
@@ -373,6 +369,11 @@ proc addToVarSection(c: PContext; result: var PNode; orig, identDefs: PNode) =
   else:
     result.add identDefs
 
+proc isDiscardUnderscore(v: PSym): bool =
+  if v.name.s == "_":
+    v.flags.incl(sfGenSym)
+    result = true
+
 proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
   var b: PNode
   result = copyNode(n)
@@ -436,7 +437,8 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
 
     for j in countup(0, length-3):
       var v = semIdentDef(c, a.sons[j], symkind)
-      if sfGenSym notin v.flags: addInterfaceDecl(c, v)
+      if sfGenSym notin v.flags and not isDiscardUnderscore(v):
+        addInterfaceDecl(c, v)
       when oKeepVariableNames:
         if c.inUnrolledContext > 0: v.flags.incl(sfShadowed)
         else:
@@ -551,7 +553,8 @@ proc semForVars(c: PContext, n: PNode): PNode =
       if getCurrOwner().kind == skModule: incl(v.flags, sfGlobal)
       v.typ = iter.sons[i]
       n.sons[i] = newSymNode(v)
-      if sfGenSym notin v.flags: addForVarDecl(c, v)
+      if sfGenSym notin v.flags and not isDiscardUnderscore(v):
+        addForVarDecl(c, v)
   inc(c.p.nestedLoopCounter)
   n.sons[length-1] = semStmt(c, n.sons[length-1])
   dec(c.p.nestedLoopCounter)
@@ -741,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) =
@@ -1030,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()
@@ -1265,6 +1318,8 @@ proc semPragmaBlock(c: PContext, n: PNode): PNode =
     of wLocks:
       result = n
       result.typ = n.sons[1].typ
+    of wNoRewrite:
+      incl(result.flags, nfNoRewrite)
     else: discard
 
 proc semStaticStmt(c: PContext, n: PNode): PNode =