Restore the old behavior of parsing "quote do:"

close #5845
This commit is contained in:
Zahary Karadjov
2017-07-18 11:50:06 +03:00
committed by Andreas Rumpf
parent c3e5c6c326
commit 7ad115f530
6 changed files with 260 additions and 215 deletions

View File

@@ -685,6 +685,11 @@ proc namedParams(p: var TParser, callee: PNode,
# progress guaranteed
exprColonEqExprListAux(p, endTok, result)
proc commandParam(p: var TParser): PNode =
result = parseExpr(p)
if p.tok.tokType == tkDo:
result = postExprBlocks(p, result)
proc primarySuffix(p: var TParser, r: PNode, baseIndent: int): PNode =
#| primarySuffix = '(' (exprColonEqExpr comma?)* ')' doBlocks?
#| | doBlocks
@@ -733,7 +738,7 @@ proc primarySuffix(p: var TParser, r: PNode, baseIndent: int): PNode =
when true:
# progress NOT guaranteed
p.hasProgress = false
addSon result, parseExpr(p)
addSon result, commandParam(p)
if not p.hasProgress: break
else:
while p.tok.tokType != tkEof:
@@ -1253,14 +1258,12 @@ proc parseExprStmt(p: var TParser): PNode =
while true:
getTok(p)
optInd(p, result)
var e = parseExpr(p)
addSon(result, e)
addSon(result, commandParam(p))
if p.tok.tokType != tkComma: break
elif p.tok.indent < 0 and isExprStart(p):
result = newNode(nkCommand, a.info, @[a])
while true:
var e = parseExpr(p)
addSon(result, e)
addSon(result, commandParam(p))
if p.tok.tokType != tkComma: break
getTok(p)
optInd(p, result)

View File

@@ -248,12 +248,20 @@ calls can use the ``do`` keyword:
.. code-block:: nim
sort(cities) do (x,y: string) -> int:
cmp(x.len, y.len)
# Less parenthesis using the method plus command syntax:
cities = cities.map do (x:string) -> string:
"City of " & x
# In macros, the do notation is often used for quasi-quoting
macroResults.add quote do:
if not `ex`:
echo `info`, ": Check failed: ", `expString`
``do`` is written after the parentheses enclosing the regular proc params.
The proc expression represented by the do block is appended to them.
In calls using the command syntax, the do block will bind to the immediately
preceeding expression, transforming it in a call.
``do`` with parentheses is an anonymous ``proc``; however a ``do`` without
parentheses is just a block of code. The ``do`` notation can be used to

View File

@@ -408,20 +408,19 @@ macro `{}`*(typ: typedesc, xs: varargs[untyped]): auto =
kString = quote do:
when compiles($`k`): $`k` else: "invalid"
v = x[1]
body.add(quote do:
body.add quote do:
when compiles(`a`.`k`):
`a`.`k` = `v`
elif compiles(`a`[`k`]):
`a`[`k`] = `v`
else:
`a`[`kString`] = `v`
)
else:
error("Expression `" & $x.toStrLit & "` not allowed in `{}` macro")
body.add(quote do:
body.add quote do:
return `a`
)
result = quote do:
proc inner(): `typ` {.gensym.} =

View File

@@ -5,7 +5,9 @@ lost focus 1
lost focus 2
registered handler for UserEvent 1
registered handler for UserEvent 2
registered handler for UserEvent 3'''
registered handler for UserEvent 3
registered handler for UserEvent 4
'''
"""
import future
@@ -35,11 +37,14 @@ b.onFocusLost:
b.onFocusLost do:
echo "lost focus 2"
b.onUserEvent "UserEvent 1" do:
b.onUserEvent("UserEvent 1") do:
discard
b.onUserEvent "UserEvent 2":
discard
b.onUserEvent("UserEvent 3", () => echo "event 3")
b.onUserEvent("UserEvent 3"):
discard
b.onUserEvent("UserEvent 4", () => echo "event 4")

View File

@@ -309,11 +309,11 @@ block:
on("click") do (e: Event):
console.log e
jslib.on "reloaded" do:
jslib.on("reloaded") do:
console.log jsarguments[0]
# this test case is different from the above, because
# `subscribe` is not overloaded in the current scope
jslib.subscribe "updates":
jslib.subscribe("updates"):
console.log jsarguments[0]

View File

@@ -1,51 +1,59 @@
discard """
nimout: '''
StmtList
Ident !"foo"
Ident !"foo010"
Call
Ident !"foo"
Ident !"foo020"
Call
Ident !"foo"
Ident !"foo030"
Ident !"x"
Command
Ident !"foo"
Ident !"foo040"
Ident !"x"
Call
Ident !"foo"
Ident !"foo050"
StmtList
DiscardStmt
Empty
Call
Ident !"foo"
Ident !"foo060"
StmtList
DiscardStmt
Empty
Call
Ident !"foo"
Ident !"foo070"
StrLit test
StmtList
DiscardStmt
Empty
Call
Ident !"foo"
Ident !"foo080"
StrLit test
StmtList
DiscardStmt
Empty
Command
Ident !"foo"
Ident !"foo090"
StrLit test
StmtList
DiscardStmt
Empty
Command
Ident !"foo"
StrLit test
StmtList
DiscardStmt
Empty
Ident !"foo100"
Call
StrLit test
StmtList
DiscardStmt
Empty
Command
Ident !"foo"
Ident !"foo101"
Call
IntLit 10
StmtList
DiscardStmt
Empty
Command
Ident !"foo110"
IntLit 1
Par
Infix
@@ -56,18 +64,19 @@ StmtList
DiscardStmt
Empty
Command
Ident !"foo"
Ident !"foo120"
IntLit 1
Par
Infix
Ident !"+"
IntLit 2
IntLit 3
StmtList
DiscardStmt
Empty
Call
Par
Infix
Ident !"+"
IntLit 2
IntLit 3
StmtList
DiscardStmt
Empty
Call
Ident !"foo"
Ident !"foo130"
Do
Empty
Empty
@@ -84,7 +93,7 @@ StmtList
DiscardStmt
Empty
Call
Ident !"foo"
Ident !"foo140"
Do
Empty
Empty
@@ -101,7 +110,7 @@ StmtList
DiscardStmt
Empty
Call
Ident !"foo"
Ident !"foo150"
Do
Empty
Empty
@@ -118,25 +127,26 @@ StmtList
DiscardStmt
Empty
Command
Ident !"foo"
Ident !"x"
Do
Empty
Empty
Empty
FormalParams
Ident !"foo160"
Call
Ident !"x"
Do
Empty
IdentDefs
Ident !"y"
Empty
Empty
Empty
Empty
StmtList
DiscardStmt
Empty
Empty
FormalParams
Empty
IdentDefs
Ident !"y"
Empty
Empty
Empty
Empty
StmtList
DiscardStmt
Empty
Call
Ident !"foo"
Ident !"foo170"
StmtList
DiscardStmt
Empty
@@ -145,7 +155,7 @@ StmtList
DiscardStmt
Empty
Call
Ident !"foo"
Ident !"foo180"
StmtList
DiscardStmt
Empty
@@ -157,62 +167,63 @@ StmtList
DiscardStmt
Empty
Command
Ident !"foo"
Ident !"x"
Do
Empty
Empty
Empty
FormalParams
Ident !"foo190"
Call
Ident !"x"
Do
Empty
IdentDefs
Ident !"y"
Empty
Empty
FormalParams
Empty
Empty
Empty
Empty
StmtList
DiscardStmt
Empty
Do
Empty
Empty
Empty
FormalParams
Ident !"int"
IdentDefs
Ident !"z"
Empty
Empty
Empty
Empty
StmtList
DiscardStmt
Empty
Do
Empty
Empty
Empty
FormalParams
Ident !"int"
IdentDefs
Ident !"w"
IdentDefs
Ident !"y"
Empty
Empty
Empty
Empty
StmtList
DiscardStmt
Empty
Do
Empty
Empty
Empty
FormalParams
Ident !"int"
Empty
Empty
Empty
StmtList
DiscardStmt
Empty
StmtList
DiscardStmt
IdentDefs
Ident !"z"
Empty
Empty
Empty
Else
Empty
StmtList
DiscardStmt
Empty
Do
Empty
Empty
Empty
FormalParams
Ident !"int"
IdentDefs
Ident !"w"
Ident !"int"
Empty
Empty
Empty
StmtList
DiscardStmt
Empty
StmtList
DiscardStmt
Empty
Else
StmtList
DiscardStmt
Empty
Call
Ident !"foo"
Ident !"foo200"
Ident !"x"
Call
Ident !"bar"
@@ -227,33 +238,33 @@ StmtList
IdentDefs
Ident !"a"
Empty
Ident !"foo"
Ident !"foo210"
VarSection
IdentDefs
Ident !"a"
Empty
Call
Ident !"foo"
Ident !"foo220"
VarSection
IdentDefs
Ident !"a"
Empty
Call
Ident !"foo"
Ident !"foo230"
Ident !"x"
VarSection
IdentDefs
Ident !"a"
Empty
Command
Ident !"foo"
Ident !"foo240"
Ident !"x"
VarSection
IdentDefs
Ident !"a"
Empty
Call
Ident !"foo"
Ident !"foo250"
StmtList
DiscardStmt
Empty
@@ -262,7 +273,7 @@ StmtList
Ident !"a"
Empty
Call
Ident !"foo"
Ident !"foo260"
StmtList
DiscardStmt
Empty
@@ -271,7 +282,7 @@ StmtList
Ident !"a"
Empty
Call
Ident !"foo"
Ident !"foo270"
StmtList
DiscardStmt
Empty
@@ -284,8 +295,78 @@ StmtList
Ident !"a"
Empty
Command
Ident !"foo"
Ident !"x"
Ident !"foo280"
Call
Ident !"x"
Do
Empty
Empty
Empty
FormalParams
Empty
IdentDefs
Ident !"y"
Empty
Empty
Empty
Empty
StmtList
DiscardStmt
Empty
Else
StmtList
DiscardStmt
Empty
Asgn
Ident !"a"
Ident !"foo290"
Asgn
Ident !"a"
Call
Ident !"foo300"
Asgn
Ident !"a"
Call
Ident !"foo310"
Ident !"x"
Asgn
Ident !"a"
Command
Ident !"foo320"
Ident !"x"
Asgn
Ident !"a"
Call
Ident !"foo330"
StmtList
DiscardStmt
Empty
Asgn
Ident !"a"
Call
Ident !"foo340"
StmtList
DiscardStmt
Empty
Asgn
Ident !"a"
Call
Ident !"foo350"
StmtList
DiscardStmt
Empty
Else
StmtList
DiscardStmt
Empty
Asgn
Ident !"a"
Command
Ident !"foo360"
Call
DotExpr
Ident !"x"
Ident !"bar"
Do
Empty
Empty
@@ -305,75 +386,18 @@ StmtList
StmtList
DiscardStmt
Empty
Asgn
Ident !"a"
Ident !"foo"
Asgn
Ident !"a"
Command
DotExpr
Ident !"foo370"
Ident !"add"
Call
Ident !"foo"
Asgn
Ident !"a"
Call
Ident !"foo"
Ident !"x"
Asgn
Ident !"a"
Command
Ident !"foo"
Ident !"x"
Asgn
Ident !"a"
Call
Ident !"foo"
Ident !"quote"
StmtList
DiscardStmt
Empty
Asgn
Ident !"a"
Call
Ident !"foo"
StmtList
DiscardStmt
Empty
Asgn
Ident !"a"
Call
Ident !"foo"
StmtList
DiscardStmt
Empty
Else
StmtList
DiscardStmt
Empty
Asgn
Ident !"a"
Command
Ident !"foo"
Ident !"x"
Do
Empty
Empty
Empty
FormalParams
Empty
IdentDefs
Ident !"y"
Empty
Empty
Empty
Empty
StmtList
DiscardStmt
Empty
Else
StmtList
DiscardStmt
Empty
Call
DotExpr
Ident !"result"
Ident !"foo380"
Ident !"add"
BracketExpr
Call
@@ -389,62 +413,65 @@ import macros
dumpTree:
# simple calls
foo
foo()
foo(x)
foo x
foo010
foo020()
foo030(x)
foo040 x
foo:
foo050:
discard
foo do:
foo060 do:
discard
foo("test"):
foo070("test"):
discard
foo("test") do:
foo080("test") do:
discard
foo "test":
foo090 "test":
discard
foo "test" do:
foo100 "test" do:
discard
foo101 10 do:
discard
# more complicated calls
foo 1, (2+3):
foo110 1, (2+3):
discard
foo 1, (2+3) do:
foo120 1, (2+3) do:
discard
foo do (x):
foo130 do (x):
discard
foo do (x: int):
foo140 do (x: int):
discard
foo do (x: int) -> int:
foo150 do (x: int) -> int:
discard
foo x do (y):
foo160 x do (y):
discard
# extra blocks
foo:
foo170:
discard
else:
discard
foo do:
foo180 do:
discard
do:
discard
else:
discard
foo x do (y):
foo190 x do (y):
discard
do (z) -> int:
discard
@@ -456,58 +483,61 @@ dumpTree:
discard
# call with blocks as a param
foo(x, bar do:
foo200(x, bar do:
discard
else:
discard
)
# introduce a variable
var a = foo
var a = foo()
var a = foo(x)
var a = foo x
var a = foo210
var a = foo220()
var a = foo230(x)
var a = foo240 x
var a = foo:
var a = foo250:
discard
var a = foo do:
var a = foo260 do:
discard
var a = foo do:
var a = foo270 do:
discard
else:
discard
var a = foo x do (y):
var a = foo280 x do (y):
discard
else:
discard
# assignments
a = foo
a = foo()
a = foo(x)
a = foo x
a = foo290
a = foo300()
a = foo310(x)
a = foo320 x
a = foo:
a = foo330:
discard
a = foo do:
a = foo340 do:
discard
a = foo do:
a = foo350 do:
discard
else:
discard
a = foo x do (y):
a = foo360 x.bar do (y):
discard
else:
discard
foo370.add quote do:
discard
# some edge cases
result.add((quote do:
foo380.add((quote do:
discard
)[0])