diff options
author | Araq <rumpf_a@web.de> | 2013-05-14 00:41:07 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2013-05-14 00:41:07 +0200 |
commit | 9b9a18094732ec88157a11d3845d626b8970bfb9 (patch) | |
tree | 54e47ed39c83c32224362e9bb73c18be9fdb95a9 /compiler | |
parent | 61b304832365d4d534628e002ac1e8620b19d94c (diff) | |
download | Nim-9b9a18094732ec88157a11d3845d626b8970bfb9.tar.gz |
'inject' for 'for' loop variables
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/parser.nim | 10 | ||||
-rw-r--r-- | compiler/semstmts.nim | 10 | ||||
-rw-r--r-- | compiler/semtempl.nim | 44 |
3 files changed, 38 insertions, 26 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) |