Skip to content

Commit

Permalink
allow proc expressions in place of statements (nim-lang#20935)
Browse files Browse the repository at this point in the history
properly fixes nim-lang#18714
  • Loading branch information
metagn authored Nov 29, 2022
1 parent 555c5ed commit 15d00ca
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 7 deletions.
22 changes: 15 additions & 7 deletions compiler/parser.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1157,7 +1157,6 @@ proc parseProcExpr(p: var Parser; isExpr: bool; kind: TNodeKind): PNode =
#| routineExpr = ('proc' | 'func' | 'iterator') paramListColon pragma? ('=' COMMENT? stmt)?
# either a proc type or a anonymous proc
let info = parLineInfo(p)
getTok(p)
let hasSignature = p.tok.tokType in {tkParLe, tkColon} and p.tok.indent < 0
let params = parseParamList(p)
let pragmas = optPragmas(p)
Expand All @@ -1168,7 +1167,7 @@ proc parseProcExpr(p: var Parser; isExpr: bool; kind: TNodeKind): PNode =
params = params, name = p.emptyNode, pattern = p.emptyNode,
genericParams = p.emptyNode, pragmas = pragmas, exceptions = p.emptyNode)
else:
result = newNodeI(nkProcTy, info)
result = newNodeI(if kind == nkIteratorDef: nkIteratorTy else: nkProcTy, info)
if hasSignature:
result.add(params)
if kind == nkFuncDef:
Expand Down Expand Up @@ -1309,12 +1308,15 @@ proc primary(p: var Parser, mode: PrimaryMode): PNode =

case p.tok.tokType
of tkTuple: result = parseTuple(p, mode == pmTypeDef)
of tkProc: result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkLambda)
of tkFunc: result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkFuncDef)
of tkIterator:
of tkProc:
getTok(p)
result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkLambda)
if result.kind == nkLambda: result.transitionSonsKind(nkIteratorDef)
else: result.transitionSonsKind(nkIteratorTy)
of tkFunc:
getTok(p)
result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkFuncDef)
of tkIterator:
getTok(p)
result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkIteratorDef)
of tkEnum:
if mode == pmTypeDef:
prettySection:
Expand Down Expand Up @@ -1832,6 +1834,12 @@ proc parseRoutine(p: var Parser, kind: TNodeKind): PNode =
result = newNodeP(kind, p)
getTok(p)
optInd(p, result)
if kind in {nkProcDef, nkLambda, nkIteratorDef, nkFuncDef} and
p.tok.tokType notin {tkSymbol, tokKeywordLow..tokKeywordHigh, tkAccent}:
# no name; lambda or proc type
# in every context that we can parse a routine, we can also parse these
result = parseProcExpr(p, true, if kind == nkProcDef: nkLambda else: kind)
return
result.add(identVis(p))
if p.tok.tokType == tkCurlyLe and p.validInd: result.add(p.parsePattern)
else: result.add(p.emptyNode)
Expand Down
3 changes: 3 additions & 0 deletions tests/parser/tprocexprasstmt.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
func r(): auto =
func(): int = 2
discard r()()

0 comments on commit 15d00ca

Please sign in to comment.