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:
parent
3751019823
commit
b38eb2e2a8
8 changed files with 39 additions and 6 deletions
|
|
@ -221,6 +221,7 @@ type
|
||||||
nkGotoState, # used for the state machine (for iterators)
|
nkGotoState, # used for the state machine (for iterators)
|
||||||
nkState, # give a label to a code section (for iterators)
|
nkState, # give a label to a code section (for iterators)
|
||||||
nkBreakState, # special break statement for easier code generation
|
nkBreakState, # special break statement for easier code generation
|
||||||
|
nkUnderscore, # underscore inside a tuple unpack ``(_, x) = foo()``
|
||||||
TNodeKinds* = set[TNodeKind]
|
TNodeKinds* = set[TNodeKind]
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -384,7 +384,8 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) =
|
||||||
tkBracketDotLe, tkBracketDotRi, tkCurlyDotLe, tkCurlyDotRi, tkParDotLe,
|
tkBracketDotLe, tkBracketDotRi, tkCurlyDotLe, tkCurlyDotRi, tkParDotLe,
|
||||||
tkParDotRi, tkComma, tkSemiColon, tkColon, tkEquals, tkDot, tkDotDot,
|
tkParDotRi, tkComma, tkSemiColon, tkColon, tkEquals, tkDot, tkDotDot,
|
||||||
tkAccent, tkColonColon,
|
tkAccent, tkColonColon,
|
||||||
tkGStrLit, tkGTripleStrLit, tkInfixOpr, tkPrefixOpr, tkPostfixOpr:
|
tkGStrLit, tkGTripleStrLit, tkInfixOpr, tkPrefixOpr, tkPostfixOpr,
|
||||||
|
tkUnderscore:
|
||||||
dispA(result, "<span class=\"Other\">$1</span>", "\\spanOther{$1}",
|
dispA(result, "<span class=\"Other\">$1</span>", "\\spanOther{$1}",
|
||||||
[toRope(esc(d.target, literal))])
|
[toRope(esc(d.target, literal))])
|
||||||
inc(d.id)
|
inc(d.id)
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ type
|
||||||
tkColon, tkColonColon, tkEquals, tkDot, tkDotDot,
|
tkColon, tkColonColon, tkEquals, tkDot, tkDotDot,
|
||||||
tkOpr, tkComment, tkAccent,
|
tkOpr, tkComment, tkAccent,
|
||||||
tkSpaces, tkInfixOpr, tkPrefixOpr, tkPostfixOpr,
|
tkSpaces, tkInfixOpr, tkPrefixOpr, tkPostfixOpr,
|
||||||
|
tkUnderscore
|
||||||
|
|
||||||
TTokTypes* = set[TTokType]
|
TTokTypes* = set[TTokType]
|
||||||
|
|
||||||
|
|
@ -96,7 +97,7 @@ const
|
||||||
":", "::", "=", ".", "..",
|
":", "::", "=", ".", "..",
|
||||||
"tkOpr", "tkComment", "`",
|
"tkOpr", "tkComment", "`",
|
||||||
"tkSpaces", "tkInfixOpr",
|
"tkSpaces", "tkInfixOpr",
|
||||||
"tkPrefixOpr", "tkPostfixOpr"]
|
"tkPrefixOpr", "tkPostfixOpr", "_"]
|
||||||
|
|
||||||
type
|
type
|
||||||
TNumericalBase* = enum
|
TNumericalBase* = enum
|
||||||
|
|
@ -874,6 +875,9 @@ proc rawGetTok(L: var TLexer, tok: var TToken) =
|
||||||
of '`':
|
of '`':
|
||||||
tok.tokType = tkAccent
|
tok.tokType = tkAccent
|
||||||
inc(L.bufpos)
|
inc(L.bufpos)
|
||||||
|
of '_':
|
||||||
|
tok.tokType = tkUnderscore
|
||||||
|
inc(L.bufpos)
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ proc considerQuotedIdent*(n: PNode): PIdent =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkIdent: result = n.ident
|
of nkIdent: result = n.ident
|
||||||
of nkSym: result = n.sym.name
|
of nkSym: result = n.sym.name
|
||||||
|
of nkUnderscore: result = getIdent"_"
|
||||||
of nkAccQuoted:
|
of nkAccQuoted:
|
||||||
case n.len
|
case n.len
|
||||||
of 0:
|
of 0:
|
||||||
|
|
|
||||||
|
|
@ -296,12 +296,15 @@ proc colcom(p: var TParser, n: PNode) =
|
||||||
skipComment(p, n)
|
skipComment(p, n)
|
||||||
|
|
||||||
proc parseSymbol(p: var TParser, allowNil = false): PNode =
|
proc parseSymbol(p: var TParser, allowNil = false): PNode =
|
||||||
#| symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`'
|
#| symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'='|'_')+)+ '`'
|
||||||
#| | IDENT | 'addr' | 'type'
|
#| | IDENT | 'addr' | 'type'
|
||||||
case p.tok.tokType
|
case p.tok.tokType
|
||||||
of tkSymbol, tkAddr, tkType:
|
of tkSymbol, tkAddr, tkType:
|
||||||
result = newIdentNodeP(p.tok.ident, p)
|
result = newIdentNodeP(p.tok.ident, p)
|
||||||
getTok(p)
|
getTok(p)
|
||||||
|
of tkUnderscore:
|
||||||
|
result = newNodeP(nkUnderscore, p)
|
||||||
|
getTok(p)
|
||||||
of tkAccent:
|
of tkAccent:
|
||||||
result = newNodeP(nkAccQuoted, p)
|
result = newNodeP(nkAccQuoted, p)
|
||||||
getTok(p)
|
getTok(p)
|
||||||
|
|
@ -643,6 +646,9 @@ proc identOrLiteral(p: var TParser, mode: TPrimaryMode): PNode =
|
||||||
of tkNil:
|
of tkNil:
|
||||||
result = newNodeP(nkNilLit, p)
|
result = newNodeP(nkNilLit, p)
|
||||||
getTok(p)
|
getTok(p)
|
||||||
|
of tkUnderscore:
|
||||||
|
result = newNodeP(nkUnderscore, p)
|
||||||
|
getTok(p)
|
||||||
of tkParLe:
|
of tkParLe:
|
||||||
# () constructor
|
# () constructor
|
||||||
if mode in {pmTypeDesc, pmTypeDef}:
|
if mode in {pmTypeDesc, pmTypeDef}:
|
||||||
|
|
@ -1814,7 +1820,7 @@ proc parseVarTuple(p: var TParser): PNode =
|
||||||
result = newNodeP(nkVarTuple, p)
|
result = newNodeP(nkVarTuple, p)
|
||||||
getTok(p) # skip '('
|
getTok(p) # skip '('
|
||||||
optInd(p, result)
|
optInd(p, result)
|
||||||
while p.tok.tokType in {tkSymbol, tkAccent}:
|
while p.tok.tokType in {tkSymbol, tkAccent, tkUnderscore}:
|
||||||
var a = identWithPragma(p)
|
var a = identWithPragma(p)
|
||||||
addSon(result, a)
|
addSon(result, a)
|
||||||
if p.tok.tokType != tkComma: break
|
if p.tok.tokType != tkComma: break
|
||||||
|
|
|
||||||
|
|
@ -349,6 +349,7 @@ proc atom(n: PNode): string =
|
||||||
else:
|
else:
|
||||||
result = litAux(n, (cast[PInt64](addr(n.floatVal)))[], 8) & "\'f64"
|
result = litAux(n, (cast[PInt64](addr(n.floatVal)))[], 8) & "\'f64"
|
||||||
of nkNilLit: result = "nil"
|
of nkNilLit: result = "nil"
|
||||||
|
of nkUnderscore: result = "_"
|
||||||
of nkType:
|
of nkType:
|
||||||
if (n.typ != nil) and (n.typ.sym != nil): result = n.typ.sym.name.s
|
if (n.typ != nil) and (n.typ.sym != nil): result = n.typ.sym.name.s
|
||||||
else: result = "[type node]"
|
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 nkTripleStrLit: putRawStr(g, tkTripleStrLit, n.strVal)
|
||||||
of nkEmpty: discard
|
of nkEmpty: discard
|
||||||
of nkType: put(g, tkInvalid, atom(n))
|
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 nkIntLit: put(g, tkIntLit, atom(n))
|
||||||
of nkInt8Lit: put(g, tkInt8Lit, atom(n))
|
of nkInt8Lit: put(g, tkInt8Lit, atom(n))
|
||||||
of nkInt16Lit: put(g, tkInt16Lit, 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):
|
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: addInterfaceDecl(c, v)
|
if sfGenSym notin v.flags and
|
||||||
|
a.sons[j].kind != nkUnderscore: addInterfaceDecl(c, v)
|
||||||
when oKeepVariableNames:
|
when oKeepVariableNames:
|
||||||
if c.inUnrolledContext > 0: v.flags.incl(sfShadowed)
|
if c.inUnrolledContext > 0: v.flags.incl(sfShadowed)
|
||||||
else:
|
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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue