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

What to do about "do macrocalls" #319

Closed
c42f opened this issue Jun 27, 2023 · 2 comments · Fixed by #322
Closed

What to do about "do macrocalls" #319

c42f opened this issue Jun 27, 2023 · 2 comments · Fixed by #322
Labels

Comments

@c42f
Copy link
Member

c42f commented Jun 27, 2023

"do macrocalls" have an expression representation which is the same as do function calls. But the macrocall in this case acts not only on the its children, but on the body of the do block.

It seems pretty weird for a macro expansion to act outside its child list in the expression tree, and this is the only such case.

Currently we have the following representation

julia> parsestmt(SyntaxNode, "@f(x, y) do a, b\n body\n end")
line:col│ tree                                   │ file_name
   1:1  │[do]
   1:1  │  [macrocall-p]
   1:2  │    @f
   1:4  │    x
   1:7  │    y
   1:12 │  [tuple]
   1:13 │    a
   1:16 │    b
   1:17 │  [block]
   2:2  │    body

Is there a neat alternative AST we could use to fix this special case?

@c42f c42f added the AST label Jun 27, 2023
@c42f
Copy link
Member Author

c42f commented Jun 28, 2023

Desirable features of an alternative AST:

  1. Macro can detect when it's being passed do syntax rather than lambda syntax
  2. Macro is passed the syntax as-is rather than the macro expander rearranging syntax before passing it to the macro
  3. do head is still used somehow and is as similar as possible to the form used for function-based do blocks

With these in mind, could we change the @f(x, y) do a, b\n body\n end parsing to

(macrocall @f (do (tuple x y) (tuple a b) (block body)))

To satisfy point (3) we could even consider changing the representation of normal function calls with do syntax as well? So without the @ we'd have

(call f (do (tuple x y) (tuple a b) (block body)))

But. A tricky point about this idea is that swapping the call and do means deferring emitting the call until much later and implementing this might be quite painful with the current way things are set up.

@c42f
Copy link
Member Author

c42f commented Jun 30, 2023

Or maybe we should have @f(x, y) do a, b\n body\n end and f(x, y) do a, b\n body\n endparsing as

(macrocall @f x y (do (tuple a b) body))
(call f x y (do (tuple a b) body))

It turns out that this is very natural in the parser because do is parsed as part of parsing function calls. That is, do binds with the same precedence as everything else in parse_call_chain.

This AST is also pretty natural for macros to process, I think. And it's very naturally source-ordered in a similar way to the way that we order parameters blocks in the SyntaxNode AST.

The downside is that checking for the presence of do on the tail of function call arguments seems a bit fiddly I guess? But semantically, the arguments to do are passed to the call or macrocall, so this layout of the AST does seem a lot better in that respect.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant