diff options
author | cooldome <cdome@bk.ru> | 2019-03-18 10:09:49 +0000 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2019-03-18 11:09:49 +0100 |
commit | 862897dc0f122e374c0e4d44770ffcd8825e51e3 (patch) | |
tree | c92794e887760bc44be045a46a3182f093a027e5 | |
parent | c19cd14fc96cfdc77c98e90adeb4e1eb8b5d9b26 (diff) | |
download | Nim-862897dc0f122e374c0e4d44770ffcd8825e51e3.tar.gz |
Support for stmtListExpr in parser after major keywords. Scaled down version. (#10852)
* Support for stmtListExpr in parser after major keywords * fixes #4035
-rw-r--r-- | changelog.md | 10 | ||||
-rw-r--r-- | compiler/parser.nim | 31 | ||||
-rw-r--r-- | tests/macros/ttryparseexpr.nim | 5 | ||||
-rw-r--r-- | tests/parser/tstmtlist_expr.nim | 20 |
4 files changed, 54 insertions, 12 deletions
diff --git a/changelog.md b/changelog.md index 2fb80dfc5..6e3872219 100644 --- a/changelog.md +++ b/changelog.md @@ -29,6 +29,16 @@ - `getImpl` on a `var` or `let` symbol will now return the full `IdentDefs` 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. diff --git a/compiler/parser.nim b/compiler/parser.nim index 855fc2f4a..1acfe1b98 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -238,6 +238,7 @@ proc newIdentNodeP(ident: PIdent, p: TParser): PNode = proc parseExpr(p: var TParser): PNode proc parseStmt(p: var TParser): PNode +proc parseStmtListExpr(p: var TParser): PNode proc parseTypeDesc(p: var TParser): 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 opNode = newIdentNodeP(p.tok.ident, p) # skip operator: getTok(p) - optInd(p, a) + flexComment(p, a) + optPar(p) # read sub-expression with higher priority: var b = simpleExprAux(p, opPrec + leftAssoc, modeB) addSon(a, opNode) @@ -1479,12 +1481,12 @@ proc parseFromStmt(p: var TParser): PNode = #expectNl(p) proc parseReturnOrRaise(p: var TParser, kind: TNodeKind): PNode = - #| returnStmt = 'return' optInd expr? - #| raiseStmt = 'raise' optInd expr? - #| yieldStmt = 'yield' optInd expr? - #| discardStmt = 'discard' optInd expr? - #| breakStmt = 'break' optInd expr? - #| continueStmt = 'break' optInd expr? + #| returnStmt = 'return' stmtListExpr? + #| raiseStmt = 'raise' stmtListExpr? + #| yieldStmt = 'yield' stmtListExpr? + #| discardStmt = 'discard' stmtListExpr? + #| breakStmt = 'break' stmtListExpr? + #| continueStmt = 'break' stmtListExpr? result = newNodeP(kind, p) getTok(p) if p.tok.tokType == tkComment: @@ -1494,9 +1496,7 @@ proc parseReturnOrRaise(p: var TParser, kind: TNodeKind): PNode = # NL terminates: addSon(result, p.emptyNode) else: - var e = parseExpr(p) - e = postExprBlocks(p, e) - addSon(result, e) + addSon(result, parseStmtListExpr(p)) proc parseIfOrWhen(p: var TParser, kind: TNodeKind): PNode = #| condStmt = expr colcom stmt COMMENT? @@ -2249,6 +2249,17 @@ proc parseStmt(p: var TParser): PNode = getTok(p) 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 = ## Parses the rest of the input stream held by the parser into a PNode. result = newNodeP(nkStmtList, p) diff --git a/tests/macros/ttryparseexpr.nim b/tests/macros/ttryparseexpr.nim index 54442b662..d1084937b 100644 --- a/tests/macros/ttryparseexpr.nim +++ b/tests/macros/ttryparseexpr.nim @@ -1,5 +1,5 @@ discard """ - outputsub: '''Error: invalid indentation 45''' + outputsub: '''Error: expression expected, but found '[EOF]' -- 45''' """ # feature request #1473 @@ -9,6 +9,7 @@ macro test(text: string): untyped = try: result = parseExpr(text.strVal) except ValueError: + echo text result = newLit getCurrentExceptionMsg() const @@ -17,4 +18,4 @@ const b = test("valid") c = test("\"") # bug #2504 -echo a, " ", b +echo a, " -- ", b diff --git a/tests/parser/tstmtlist_expr.nim b/tests/parser/tstmtlist_expr.nim new file mode 100644 index 000000000..8b4bb8505 --- /dev/null +++ b/tests/parser/tstmtlist_expr.nim @@ -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) \ No newline at end of file |