summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/parser.nim10
-rw-r--r--compiler/semstmts.nim10
-rw-r--r--compiler/semtempl.nim44
-rw-r--r--doc/grammar.txt4
-rw-r--r--lib/pure/collections/sequtils.nim3
5 files changed, 41 insertions, 30 deletions
diff --git a/compiler/parser.nim b/compiler/parser.nim
index e2167f460..7cfd35a41 100644
--- a/compiler/parser.nim
+++ b/compiler/parser.nim
@@ -817,7 +817,7 @@ proc parseTuple(p: var TParser, indentAllowed = false): PNode =
           if not sameInd(p): break
 
 proc parseParamList(p: var TParser, retColon = true): PNode =
-  #| paramList = '(' identColonEquals ^* (comma/semicolon) ')'
+  #| paramList = '(' declColonEquals ^* (comma/semicolon) ')'
   #| paramListArrow = paramList? ('->' optInd typeDesc)?
   #| paramListColon = paramList? (':' optInd typeDesc)?
   var a: PNode
@@ -829,7 +829,7 @@ proc parseParamList(p: var TParser, retColon = true): PNode =
     while true:
       case p.tok.tokType
       of tkSymbol, tkAccent: 
-        a = parseIdentColonEquals(p, {withBothOptional})
+        a = parseIdentColonEquals(p, {withBothOptional, withPragma})
       of tkParRi: 
         break 
       else: 
@@ -1278,15 +1278,15 @@ proc parseExceptBlock(p: var TParser, kind: TNodeKind): PNode =
   addSon(result, parseStmt(p))
 
 proc parseFor(p: var TParser): PNode =
-  #| forStmt = 'for' symbol (comma symbol)* 'in' expr colcom stmt
+  #| forStmt = 'for' (identWithPragma ^+ comma) 'in' expr colcom stmt
   result = newNodeP(nkForStmt, p)
   getTokNoInd(p)
-  var a = parseSymbol(p)
+  var a = identWithPragma(p)
   addSon(result, a)
   while p.tok.tokType == tkComma:
     getTok(p)
     optInd(p, a)
-    a = parseSymbol(p)
+    a = identWithPragma(p)
     addSon(result, a)
   eat(p, tkIn)
   addSon(result, parseExpr(p))
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 2c3adfeda..f65355069 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -570,6 +570,10 @@ proc addForVarDecl(c: PContext, v: PSym) =
       Message(v.info, warnShadowIdent, v.name.s)
   addDecl(c, v)
 
+proc symForVar(c: PContext, n: PNode): PSym =
+  let m = if n.kind == nkPragmaExpr: n.sons[0] else: n
+  result = newSymG(skForVar, m, c)
+
 proc semForVars(c: PContext, n: PNode): PNode =
   result = n
   var length = sonsLen(n)
@@ -578,7 +582,7 @@ proc semForVars(c: PContext, n: PNode): PNode =
   # and thus no tuple unpacking:
   if iter.kind != tyTuple or length == 3: 
     if length == 3:
-      var v = newSymG(skForVar, n.sons[0], c)
+      var v = symForVar(c, n.sons[0])
       if getCurrOwner().kind == skModule: incl(v.flags, sfGlobal)
       # BUGFIX: don't use `iter` here as that would strip away
       # the ``tyGenericInst``! See ``tests/compile/tgeneric.nim``
@@ -591,8 +595,8 @@ proc semForVars(c: PContext, n: PNode): PNode =
   elif length-2 != sonsLen(iter):
     LocalError(n.info, errWrongNumberOfVariables)
   else:
-    for i in countup(0, length - 3): 
-      var v = newSymG(skForVar, n.sons[i], c)
+    for i in countup(0, length - 3):
+      var v = symForVar(c, n.sons[i])
       if getCurrOwner().kind == skModule: incl(v.flags, sfGlobal)
       v.typ = iter.sons[i]
       n.sons[i] = newSymNode(v)
diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim
index f88c7e3a4..d0914d7c9 100644
--- a/compiler/semtempl.nim
+++ b/compiler/semtempl.nim
@@ -176,6 +176,18 @@ proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode =
     n.sons[i] = semTemplBody(c, n.sons[i])
   closeScope(c)
 
+proc semTemplSomeDecl(c: var TemplCtx, n: PNode, symKind: TSymKind) =
+  for i in countup(ord(symkind == skConditional), sonsLen(n) - 1):
+    var a = n.sons[i]
+    if a.kind == nkCommentStmt: continue
+    if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): IllFormedAst(a)
+    checkMinSonsLen(a, 3)
+    var L = sonsLen(a)
+    a.sons[L-2] = semTemplBody(c, a.sons[L-2])
+    a.sons[L-1] = semTemplBody(c, a.sons[L-1])
+    for j in countup(0, L-3):
+      addLocalDecl(c, a.sons[j], symKind)
+
 proc semPattern(c: PContext, n: PNode): PNode
 proc semTemplBody(c: var TemplCtx, n: PNode): PNode = 
   result = n
@@ -201,10 +213,18 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
     result = semMixinStmt(c.c, n, c.toMixin)
   of nkEmpty, nkSym..nkNilLit:
     nil
-  of nkIfStmt: 
-    for i in countup(0, sonsLen(n)-1): 
-      n.sons[i] = semTemplBodyScope(c, n.sons[i])
-  of nkWhileStmt: 
+  of nkIfStmt:
+    for i in countup(0, sonsLen(n)-1):
+      var it = n.sons[i]
+      if it.len == 2:
+        when newScopeForIf: openScope(c)
+        it.sons[0] = semTemplBody(c, it.sons[0])
+        when not newScopeForIf: openScope(c)
+        it.sons[1] = semTemplBody(c, it.sons[1])
+        closeScope(c)
+      else:
+        n.sons[i] = semTemplBodyScope(c, it)
+  of nkWhileStmt:
     openScope(c)
     for i in countup(0, sonsLen(n)-1): 
       n.sons[i] = semTemplBody(c, n.sons[i])
@@ -248,18 +268,8 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
       for j in countup(0, L-2): 
         a.sons[j] = semTemplBody(c, a.sons[j])
       a.sons[L-1] = semTemplBodyScope(c, a.sons[L-1])
-  of nkVarSection, nkLetSection:
-    let symKind = if n.kind == nkLetSection: skLet else: skVar
-    for i in countup(0, sonsLen(n) - 1): 
-      var a = n.sons[i]
-      if a.kind == nkCommentStmt: continue 
-      if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): IllFormedAst(a)
-      checkMinSonsLen(a, 3)
-      var L = sonsLen(a)
-      a.sons[L-2] = semTemplBody(c, a.sons[L-2])
-      a.sons[L-1] = semTemplBody(c, a.sons[L-1])
-      for j in countup(0, L-3):
-        addLocalDecl(c, a.sons[j], symKind)
+  of nkVarSection: semTemplSomeDecl(c, n, skVar)
+  of nkLetSection: semTemplSomeDecl(c, n, skLet)
   of nkConstSection:
     for i in countup(0, sonsLen(n) - 1): 
       var a = n.sons[i]
@@ -424,8 +434,6 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
     addInterfaceOverloadableSymAt(c, s, curScope)
   else:
     SymTabReplace(c.tab.stack[curScope], proto, s)
-    # XXX this seems wrong: We need to check for proto before and overwrite
-    # proto.ast ...
   if n.sons[patternPos].kind != nkEmpty:
     c.patterns.add(s)
 
diff --git a/doc/grammar.txt b/doc/grammar.txt
index 217007281..3aa556ce3 100644
--- a/doc/grammar.txt
+++ b/doc/grammar.txt
@@ -75,7 +75,7 @@ inlTupleDecl = 'tuple'
     [' optInd  (identColonEquals (comma/semicolon)?)*  optPar ']'
 extTupleDecl = 'tuple'
     COMMENT? (IND{>} identColonEquals (IND{=} identColonEquals)*)?
-paramList = '(' identColonEquals ^* (comma/semicolon) ')'
+paramList = '(' declColonEquals ^* (comma/semicolon) ')'
 paramListArrow = paramList? ('->' optInd typeDesc)?
 paramListColon = paramList? (':' optInd typeDesc)?
 doBlock = 'do' paramListArrow pragmas? colcom stmt
@@ -132,7 +132,7 @@ tryStmt = 'try' colcom stmt &(IND{=}? 'except'|'finally')
            (IND{=}? 'except' exprList colcom stmt)*
            (IND{=}? 'finally' colcom stmt)?
 exceptBlock = 'except' colcom stmt
-forStmt = 'for' symbol (comma symbol)* 'in' expr colcom stmt
+forStmt = 'for' (identWithPragma ^+ comma) 'in' expr colcom stmt
 blockStmt = 'block' symbol? colcom stmt
 staticStmt = 'static' colcom stmt
 asmStmt = 'asm' pragma? (STR_LIT | RSTR_LIT | TRIPLE_STR_LIT)
diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim
index c2d638a8c..705a97469 100644
--- a/lib/pure/collections/sequtils.nim
+++ b/lib/pure/collections/sequtils.nim
@@ -132,8 +132,7 @@ template filterIt*(seq1, pred: expr): expr {.immediate.} =
   ##    assert acceptable == @[-2.0, 24.5, 44.31]
   ##    assert notAcceptable == @[-272.15, 99.9, -113.44]
   var result {.gensym.}: type(seq1) = @[]
-  for internalit in items(seq1):
-    let it {.inject.} = internalit
+  for it {.inject.} in items(seq1):
     if pred: result.add(it)
   result