Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quote do now works with result in block #7343

Merged
merged 5 commits into from
Oct 31, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions compiler/semexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1812,6 +1812,7 @@ proc processQuotations(c: PContext; n: var PNode, op: string,
ids.add n
return


if n.kind == nkPrefix:
checkSonsLen(n, 2, c.config)
if n[0].kind == nkIdent:
Expand All @@ -1822,6 +1823,9 @@ proc processQuotations(c: PContext; n: var PNode, op: string,
n.sons[0] = newIdentNode(getIdent(c.cache, examinedOp.substr(op.len)), n.info)
elif n.kind == nkAccQuoted and op == "``":
returnQuote n[0]
elif n.kind == nkIdent:
if n.ident.s == "result":
n = ids[0]

for i in 0 ..< n.safeLen:
processQuotations(c, n.sons[i], op, quotes, ids)
Expand All @@ -1833,15 +1837,18 @@ proc semQuoteAst(c: PContext, n: PNode): PNode =
var
quotedBlock = n[^1]
op = if n.len == 3: expectString(c, n[1]) else: "``"
quotes = newSeq[PNode](1)
quotes = newSeq[PNode](2)
# the quotes will be added to a nkCall statement
# leave some room for the callee symbol
ids = newSeq[PNode]()
# leave some room for the callee symbol and the result symbol
ids = newSeq[PNode](1)
# this will store the generated param names
# leave some room for the result symbol

if quotedBlock.kind != nkStmtList:
localError(c.config, n.info, errXExpected, "block")

# This adds a default first field to pass the result symbol
ids[0] = newAnonSym(c, skParam, n.info).newSymNode
processQuotations(c, quotedBlock, op, quotes, ids)

var dummyTemplate = newProcNode(
Expand All @@ -1860,6 +1867,8 @@ proc semQuoteAst(c: PContext, n: PNode): PNode =

var tmpl = semTemplateDef(c, dummyTemplate)
quotes[0] = tmpl[namePos]
# This adds a call to newIdentNode("result") as the first argument to the template call
quotes[1] = newNode(nkCall, n.info, @[newIdentNode(getIdent(c.cache, "newIdentNode"), n.info), newStrNode(nkStrLit, "result")])
result = newNode(nkCall, n.info, @[
createMagic(c.graph, "getAst", mExpandToAst).newSymNode,
newNode(nkCall, n.info, quotes)])
Expand Down
17 changes: 17 additions & 0 deletions tests/macros/tquotedo.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import macros

macro mac(): untyped =
quote do:
proc test(): int =
(proc(): int = result = 123)()

mac()
echo test()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be use doAssert here instead of echo?

Copy link
Contributor Author

@PMunch PMunch Oct 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that would make sense. The original error would prevent this from compiling at all, which is probably why I didn't care to check the actual output of test. But it would be good to do it none the less.


macro foobar(arg: untyped): untyped =
result = arg
result.add quote do:
`result`

foobar:
echo "Hallo Welt"