cleanups for underscores in tuple unpacking

This commit is contained in:
Araq 2015-04-24 13:08:42 +02:00
commit 6ca38472a1
4 changed files with 67 additions and 42 deletions

View file

@ -868,9 +868,14 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) =
tok.tokType = tkAccent tok.tokType = tkAccent
inc(L.bufpos) inc(L.bufpos)
of '_': of '_':
inc(L.bufpos)
if L.buf[L.bufpos] notin SymChars:
tok.tokType = tkSymbol tok.tokType = tkSymbol
tok.ident = getIdent("_") tok.ident = getIdent("_")
inc(L.bufpos) else:
tok.literal = $c
tok.tokType = tkInvalid
lexMessage(L, errInvalidToken, c & " (\\" & $(ord(c)) & ')')
of '\"': of '\"':
# check for extended raw string literal: # check for extended raw string literal:
var rawMode = L.bufpos > 0 and L.buf[L.bufpos-1] in SymChars var rawMode = L.bufpos > 0 and L.buf[L.bufpos-1] in SymChars

View file

@ -369,9 +369,10 @@ proc addToVarSection(c: PContext; result: var PNode; orig, identDefs: PNode) =
else: else:
result.add identDefs result.add identDefs
proc isDiscardUnderscore(n: PNode): bool = proc isDiscardUnderscore(v: PSym): bool =
if n.kind != nkIdent: return false if v.name.s == "_":
return n.ident.s == "_" v.flags.incl(sfGenSym)
result = true
proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
var b: PNode var b: PNode
@ -436,10 +437,8 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
for j in countup(0, length-3): for j in countup(0, length-3):
var v = semIdentDef(c, a.sons[j], symkind) var v = semIdentDef(c, a.sons[j], symkind)
if sfGenSym notin v.flags and if sfGenSym notin v.flags and not isDiscardUnderscore(v):
not isDiscardUnderscore(a.sons[j]): addInterfaceDecl(c, v) addInterfaceDecl(c, v)
if isDiscardUnderscore(a.sons[j]):
v.flags.incl(sfGenSym)
when oKeepVariableNames: when oKeepVariableNames:
if c.inUnrolledContext > 0: v.flags.incl(sfShadowed) if c.inUnrolledContext > 0: v.flags.incl(sfShadowed)
else: else:
@ -554,7 +553,8 @@ proc semForVars(c: PContext, n: PNode): PNode =
if getCurrOwner().kind == skModule: incl(v.flags, sfGlobal) if getCurrOwner().kind == skModule: incl(v.flags, sfGlobal)
v.typ = iter.sons[i] v.typ = iter.sons[i]
n.sons[i] = newSymNode(v) 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) inc(c.p.nestedLoopCounter)
n.sons[length-1] = semStmt(c, n.sons[length-1]) n.sons[length-1] = semStmt(c, n.sons[length-1])
dec(c.p.nestedLoopCounter) dec(c.p.nestedLoopCounter)

View file

@ -129,6 +129,7 @@ initialized and does not rely on syntactic properties:
x = a() x = a()
use x use x
let statement let statement
------------- -------------
@ -141,6 +142,19 @@ nor can their address be taken. They cannot be assigned new values.
For let variables the same pragmas are available as for ordinary variables. For let variables the same pragmas are available as for ordinary variables.
Tuple unpacking
---------------
In a ``var`` or ``let`` statement tuple unpacking can be performed. The special
identifier ``_`` can be used to ignore some parts of the tuple:
.. code-block:: nim
proc returnsTuple(): (int, int, int) = (4, 2, 3)
let (x, _, z) = returnsTuple()
Const section Const section
------------- -------------

View file

@ -4,6 +4,11 @@ discard """
exitcode: 0 exitcode: 0
""" """
proc returnsTuple(): (int, int, int) = (4, 2, 3)
proc main2 =
let (x, _, z) = returnsTuple()
proc main() = proc main() =
proc foo(): tuple[x, y, z: int] = proc foo(): tuple[x, y, z: int] =
@ -16,8 +21,8 @@ proc main() =
var (a, _, _) = foo() var (a, _, _) = foo()
doAssert a == 4 doAssert a == 4
var (a, _, _xx) = foo() var (aa, _, _) = foo()
doAssert a == 4 doAssert aa == 4
iterator bar(): tuple[x, y, z: int] = iterator bar(): tuple[x, y, z: int] =
yield (1,2,3) yield (1,2,3)
@ -27,3 +32,4 @@ proc main() =
doAssert y == 2 doAssert y == 2
main() main()
main2()