[JuliaSyntax] Allow macros enclosed in parens to treat newlines as whitespace#60181
[JuliaSyntax] Allow macros enclosed in parens to treat newlines as whitespace#60181MasonProtter wants to merge 8 commits into
Conversation
|
This change would make long @plot(settings,
{title = Q"Two sinusoids", key = "columns 1", key = "box outside right top"},
x, y,
plotline, {title = "'sin'"})whereas the proposed change would allow: (@plot settings
{title = Q"Two sinusoids", key = "columns 1", key = "box outside right top"}
x y
plotline {title = "'sin'"})It's not a big difference but I think the additional convenience is worth it. |
|
Hey, I think the general approach makes sense. Compatibility is tricky as always.
# old,new: parsed as vcat?
[@foo x
y]
# old: syntax error. new: parsed as `vect`?
[x,
@foo y
z]It may be best to only allow |
|
Ah good point @c42f. I've fixed that and added a test-case for it. |
|
I'm a fan of the syntax! I'm not sure we can have macrocall parsing continue eagerly in all round parens, though, since I can find contexts where nightly treats the newline as the end of the macrocall without any parse error: There's also this, but IMO this is a JuliaSyntax bug given the ambiguity (flisp produces a parse error). I see you've written a test for this case: but should we consider having |
|
Ah okay, good catches @mlechu. I have fixed points 1. and 3. that you raised and added tests for them. Should the 2nd case you rasied just be its own PR, or should that be handled here? |
|
|
||
| # newline macro calls | ||
| "(@foo x\n y)" => "(parens (macrocall (macro_name foo) x y))" | ||
| "(1 + @foo x\n y)" => "(parens (call-i 1 + (macrocall (macro_name foo) x y)))" |
There was a problem hiding this comment.
I think we also want to stop parsing the macrocall at the end of the line here, even if it would be an error in this case, since these similar expressions parse on nightly:
(1 + @foo x
+ 2)
(1 +
@foo x
+ 2)
# parse to (+ 1 (@foo x) 2)
Would it be reasonable to have the new behaviour only apply to macrocalls whose immediate container is K"("?
There was a problem hiding this comment.
sorry @mlechu, I wrote a fix and then forgot to commit and send it 🤦.
That seems more or less sensible to me. I've updated it to behave as you say:
julia> parsestmt(Expr, "(1 + @foo x\n + y)")
:(1 + #= line 1 =# @foo(x) + y)and added some tests for it.
Closes #52842
Supersedes JuliaLang/JuliaSyntax.jl#475. cc @c42f and @JeffBezanson who I discussed this with previously.
Macros currently have an restriction that I always found very annoying: If you want newlines in a macro call currently, you need to switch from e.g.
to
which requires ugly commas separating the arguments, and a
call-like syntax for@info. I would prefer to at least have the option to write this aswhich is currently a syntax error, but now works with this PR:
I see this feature as directly analogous to how we allow infix function calls to span multiple lines if they're in parens:
It took me a couple years, but I finally figured out how to make this work in a backwards compatible way without breaking cases like
and this doozy which the mocking tests generated
but in this revision of the PR these now correctly parse, and I'm seeing all the tests pass locally at least.
Easter egg
A silly side-effect of this change is that you can now write lispy s-expression syntax in julia with no
endin sight!: