Support for stmtListExpr in parser after major keywords. Scaled down version. (#10852)
* Support for stmtListExpr in parser after major keywords * fixes #4035
This commit is contained in:
parent
c19cd14fc9
commit
862897dc0f
4 changed files with 54 additions and 12 deletions
10
changelog.md
10
changelog.md
|
|
@ -29,6 +29,16 @@
|
||||||
|
|
||||||
- `getImpl` on a `var` or `let` symbol will now return the full `IdentDefs`
|
- `getImpl` on a `var` or `let` symbol will now return the full `IdentDefs`
|
||||||
tree from the symbol declaration instead of just the initializer portion.
|
tree from the symbol declaration instead of just the initializer portion.
|
||||||
|
- it is now possible to use statement list expressions after keywords with
|
||||||
|
indentation: raise, return, discard, yield. This helps parsing code produced
|
||||||
|
by Nim template expansion where stmtListExpr can appear in place of any expression.
|
||||||
|
Example:
|
||||||
|
```nim
|
||||||
|
raise
|
||||||
|
var e = new(Exception)
|
||||||
|
e.msg = "My Exception msg"
|
||||||
|
e
|
||||||
|
```
|
||||||
|
|
||||||
- To use multi-methods, explicit `--multimethods:on` is now needed.
|
- To use multi-methods, explicit `--multimethods:on` is now needed.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -238,6 +238,7 @@ proc newIdentNodeP(ident: PIdent, p: TParser): PNode =
|
||||||
|
|
||||||
proc parseExpr(p: var TParser): PNode
|
proc parseExpr(p: var TParser): PNode
|
||||||
proc parseStmt(p: var TParser): PNode
|
proc parseStmt(p: var TParser): PNode
|
||||||
|
proc parseStmtListExpr(p: var TParser): PNode
|
||||||
proc parseTypeDesc(p: var TParser): PNode
|
proc parseTypeDesc(p: var TParser): PNode
|
||||||
proc parseParamList(p: var TParser, retColon = true): PNode
|
proc parseParamList(p: var TParser, retColon = true): PNode
|
||||||
|
|
||||||
|
|
@ -806,7 +807,8 @@ proc parseOperators(p: var TParser, headNode: PNode,
|
||||||
var a = newNodeP(nkInfix, p)
|
var a = newNodeP(nkInfix, p)
|
||||||
var opNode = newIdentNodeP(p.tok.ident, p) # skip operator:
|
var opNode = newIdentNodeP(p.tok.ident, p) # skip operator:
|
||||||
getTok(p)
|
getTok(p)
|
||||||
optInd(p, a)
|
flexComment(p, a)
|
||||||
|
optPar(p)
|
||||||
# read sub-expression with higher priority:
|
# read sub-expression with higher priority:
|
||||||
var b = simpleExprAux(p, opPrec + leftAssoc, modeB)
|
var b = simpleExprAux(p, opPrec + leftAssoc, modeB)
|
||||||
addSon(a, opNode)
|
addSon(a, opNode)
|
||||||
|
|
@ -1479,12 +1481,12 @@ proc parseFromStmt(p: var TParser): PNode =
|
||||||
#expectNl(p)
|
#expectNl(p)
|
||||||
|
|
||||||
proc parseReturnOrRaise(p: var TParser, kind: TNodeKind): PNode =
|
proc parseReturnOrRaise(p: var TParser, kind: TNodeKind): PNode =
|
||||||
#| returnStmt = 'return' optInd expr?
|
#| returnStmt = 'return' stmtListExpr?
|
||||||
#| raiseStmt = 'raise' optInd expr?
|
#| raiseStmt = 'raise' stmtListExpr?
|
||||||
#| yieldStmt = 'yield' optInd expr?
|
#| yieldStmt = 'yield' stmtListExpr?
|
||||||
#| discardStmt = 'discard' optInd expr?
|
#| discardStmt = 'discard' stmtListExpr?
|
||||||
#| breakStmt = 'break' optInd expr?
|
#| breakStmt = 'break' stmtListExpr?
|
||||||
#| continueStmt = 'break' optInd expr?
|
#| continueStmt = 'break' stmtListExpr?
|
||||||
result = newNodeP(kind, p)
|
result = newNodeP(kind, p)
|
||||||
getTok(p)
|
getTok(p)
|
||||||
if p.tok.tokType == tkComment:
|
if p.tok.tokType == tkComment:
|
||||||
|
|
@ -1494,9 +1496,7 @@ proc parseReturnOrRaise(p: var TParser, kind: TNodeKind): PNode =
|
||||||
# NL terminates:
|
# NL terminates:
|
||||||
addSon(result, p.emptyNode)
|
addSon(result, p.emptyNode)
|
||||||
else:
|
else:
|
||||||
var e = parseExpr(p)
|
addSon(result, parseStmtListExpr(p))
|
||||||
e = postExprBlocks(p, e)
|
|
||||||
addSon(result, e)
|
|
||||||
|
|
||||||
proc parseIfOrWhen(p: var TParser, kind: TNodeKind): PNode =
|
proc parseIfOrWhen(p: var TParser, kind: TNodeKind): PNode =
|
||||||
#| condStmt = expr colcom stmt COMMENT?
|
#| condStmt = expr colcom stmt COMMENT?
|
||||||
|
|
@ -2249,6 +2249,17 @@ proc parseStmt(p: var TParser): PNode =
|
||||||
getTok(p)
|
getTok(p)
|
||||||
if err and p.tok.tokType == tkEof: break
|
if err and p.tok.tokType == tkEof: break
|
||||||
|
|
||||||
|
proc parseStmtListExpr(p: var TParser): PNode =
|
||||||
|
#| stmtListExpr = (IND{>} stmt) / expr
|
||||||
|
if p.tok.indent > p.currInd:
|
||||||
|
result = parseStmt(p)
|
||||||
|
result.kind = nkStmtListExpr
|
||||||
|
if result.len == 1:
|
||||||
|
result = result[0]
|
||||||
|
else:
|
||||||
|
result = parseExpr(p)
|
||||||
|
result = postExprBlocks(p, result)
|
||||||
|
|
||||||
proc parseAll(p: var TParser): PNode =
|
proc parseAll(p: var TParser): PNode =
|
||||||
## Parses the rest of the input stream held by the parser into a PNode.
|
## Parses the rest of the input stream held by the parser into a PNode.
|
||||||
result = newNodeP(nkStmtList, p)
|
result = newNodeP(nkStmtList, p)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
discard """
|
discard """
|
||||||
outputsub: '''Error: invalid indentation 45'''
|
outputsub: '''Error: expression expected, but found '[EOF]' -- 45'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# feature request #1473
|
# feature request #1473
|
||||||
|
|
@ -9,6 +9,7 @@ macro test(text: string): untyped =
|
||||||
try:
|
try:
|
||||||
result = parseExpr(text.strVal)
|
result = parseExpr(text.strVal)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
echo text
|
||||||
result = newLit getCurrentExceptionMsg()
|
result = newLit getCurrentExceptionMsg()
|
||||||
|
|
||||||
const
|
const
|
||||||
|
|
@ -17,4 +18,4 @@ const
|
||||||
b = test("valid")
|
b = test("valid")
|
||||||
c = test("\"") # bug #2504
|
c = test("\"") # bug #2504
|
||||||
|
|
||||||
echo a, " ", b
|
echo a, " -- ", b
|
||||||
|
|
|
||||||
20
tests/parser/tstmtlist_expr.nim
Normal file
20
tests/parser/tstmtlist_expr.nim
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
discard """
|
||||||
|
output: '''10'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
proc xx(a: int): int =
|
||||||
|
let y = 0
|
||||||
|
return
|
||||||
|
var x = 0
|
||||||
|
x + y
|
||||||
|
|
||||||
|
proc b(x: int): int =
|
||||||
|
raise
|
||||||
|
var e: ref Exception
|
||||||
|
new(e)
|
||||||
|
e.msg = "My Exception msg"
|
||||||
|
e
|
||||||
|
|
||||||
|
##issue 4035
|
||||||
|
echo(5 +
|
||||||
|
5)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue