mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-19 07:21:19 +00:00
Implements #2154.
When unpacking tuples in var/let declarations a part of the tuple can now be discarded using a single underscore.
This commit is contained in:
@@ -221,6 +221,7 @@ type
|
||||
nkGotoState, # used for the state machine (for iterators)
|
||||
nkState, # give a label to a code section (for iterators)
|
||||
nkBreakState, # special break statement for easier code generation
|
||||
nkUnderscore, # underscore inside a tuple unpack ``(_, x) = foo()``
|
||||
TNodeKinds* = set[TNodeKind]
|
||||
|
||||
type
|
||||
|
||||
@@ -384,7 +384,8 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) =
|
||||
tkBracketDotLe, tkBracketDotRi, tkCurlyDotLe, tkCurlyDotRi, tkParDotLe,
|
||||
tkParDotRi, tkComma, tkSemiColon, tkColon, tkEquals, tkDot, tkDotDot,
|
||||
tkAccent, tkColonColon,
|
||||
tkGStrLit, tkGTripleStrLit, tkInfixOpr, tkPrefixOpr, tkPostfixOpr:
|
||||
tkGStrLit, tkGTripleStrLit, tkInfixOpr, tkPrefixOpr, tkPostfixOpr,
|
||||
tkUnderscore:
|
||||
dispA(result, "<span class=\"Other\">$1</span>", "\\spanOther{$1}",
|
||||
[toRope(esc(d.target, literal))])
|
||||
inc(d.id)
|
||||
|
||||
@@ -62,6 +62,7 @@ type
|
||||
tkColon, tkColonColon, tkEquals, tkDot, tkDotDot,
|
||||
tkOpr, tkComment, tkAccent,
|
||||
tkSpaces, tkInfixOpr, tkPrefixOpr, tkPostfixOpr,
|
||||
tkUnderscore
|
||||
|
||||
TTokTypes* = set[TTokType]
|
||||
|
||||
@@ -96,7 +97,7 @@ const
|
||||
":", "::", "=", ".", "..",
|
||||
"tkOpr", "tkComment", "`",
|
||||
"tkSpaces", "tkInfixOpr",
|
||||
"tkPrefixOpr", "tkPostfixOpr"]
|
||||
"tkPrefixOpr", "tkPostfixOpr", "_"]
|
||||
|
||||
type
|
||||
TNumericalBase* = enum
|
||||
@@ -874,6 +875,9 @@ proc rawGetTok(L: var TLexer, tok: var TToken) =
|
||||
of '`':
|
||||
tok.tokType = tkAccent
|
||||
inc(L.bufpos)
|
||||
of '_':
|
||||
tok.tokType = tkUnderscore
|
||||
inc(L.bufpos)
|
||||
of '\"':
|
||||
# check for extended raw string literal:
|
||||
var rawMode = L.bufpos > 0 and L.buf[L.bufpos-1] in SymChars
|
||||
|
||||
@@ -20,6 +20,7 @@ proc considerQuotedIdent*(n: PNode): PIdent =
|
||||
case n.kind
|
||||
of nkIdent: result = n.ident
|
||||
of nkSym: result = n.sym.name
|
||||
of nkUnderscore: result = getIdent"_"
|
||||
of nkAccQuoted:
|
||||
case n.len
|
||||
of 0:
|
||||
|
||||
@@ -296,12 +296,15 @@ proc colcom(p: var TParser, n: PNode) =
|
||||
skipComment(p, n)
|
||||
|
||||
proc parseSymbol(p: var TParser, allowNil = false): PNode =
|
||||
#| symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`'
|
||||
#| symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'='|'_')+)+ '`'
|
||||
#| | IDENT | 'addr' | 'type'
|
||||
case p.tok.tokType
|
||||
of tkSymbol, tkAddr, tkType:
|
||||
result = newIdentNodeP(p.tok.ident, p)
|
||||
getTok(p)
|
||||
of tkUnderscore:
|
||||
result = newNodeP(nkUnderscore, p)
|
||||
getTok(p)
|
||||
of tkAccent:
|
||||
result = newNodeP(nkAccQuoted, p)
|
||||
getTok(p)
|
||||
@@ -643,6 +646,9 @@ proc identOrLiteral(p: var TParser, mode: TPrimaryMode): PNode =
|
||||
of tkNil:
|
||||
result = newNodeP(nkNilLit, p)
|
||||
getTok(p)
|
||||
of tkUnderscore:
|
||||
result = newNodeP(nkUnderscore, p)
|
||||
getTok(p)
|
||||
of tkParLe:
|
||||
# () constructor
|
||||
if mode in {pmTypeDesc, pmTypeDef}:
|
||||
@@ -1814,7 +1820,7 @@ proc parseVarTuple(p: var TParser): PNode =
|
||||
result = newNodeP(nkVarTuple, p)
|
||||
getTok(p) # skip '('
|
||||
optInd(p, result)
|
||||
while p.tok.tokType in {tkSymbol, tkAccent}:
|
||||
while p.tok.tokType in {tkSymbol, tkAccent, tkUnderscore}:
|
||||
var a = identWithPragma(p)
|
||||
addSon(result, a)
|
||||
if p.tok.tokType != tkComma: break
|
||||
|
||||
@@ -349,6 +349,7 @@ proc atom(n: PNode): string =
|
||||
else:
|
||||
result = litAux(n, (cast[PInt64](addr(n.floatVal)))[], 8) & "\'f64"
|
||||
of nkNilLit: result = "nil"
|
||||
of nkUnderscore: result = "_"
|
||||
of nkType:
|
||||
if (n.typ != nil) and (n.typ.sym != nil): result = n.typ.sym.name.s
|
||||
else: result = "[type node]"
|
||||
@@ -805,7 +806,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
|
||||
of nkTripleStrLit: putRawStr(g, tkTripleStrLit, n.strVal)
|
||||
of nkEmpty: discard
|
||||
of nkType: put(g, tkInvalid, atom(n))
|
||||
of nkSym, nkIdent: gident(g, n)
|
||||
of nkSym, nkIdent, nkUnderscore: gident(g, n)
|
||||
of nkIntLit: put(g, tkIntLit, atom(n))
|
||||
of nkInt8Lit: put(g, tkInt8Lit, atom(n))
|
||||
of nkInt16Lit: put(g, tkInt16Lit, atom(n))
|
||||
|
||||
@@ -403,7 +403,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
|
||||
a.sons[j].kind != nkUnderscore: addInterfaceDecl(c, v)
|
||||
when oKeepVariableNames:
|
||||
if c.inUnrolledContext > 0: v.flags.incl(sfShadowed)
|
||||
else:
|
||||
|
||||
18
tests/parser/ttupleunpack.nim
Normal file
18
tests/parser/ttupleunpack.nim
Normal file
@@ -0,0 +1,18 @@
|
||||
discard """
|
||||
file: "ttupleunpack.nim"
|
||||
output: ""
|
||||
exitcode: 0
|
||||
"""
|
||||
proc foo(): tuple[x, y, z: int] =
|
||||
return (4, 2, 3)
|
||||
|
||||
var (x, _, y) = foo()
|
||||
doAssert x == 4
|
||||
doAssert y == 3
|
||||
|
||||
iterator bar(): tuple[x, y, z: int] =
|
||||
yield (1,2,3)
|
||||
|
||||
for x, y, _ in bar():
|
||||
doAssert x == 1
|
||||
doAssert y == 2
|
||||
Reference in New Issue
Block a user