Backcalls in macros get incorrectly compiled
Nobody has claimed this yet.
- Dominant language
- Lua
- Stars
- 613
- Forks
- 45
- PR merge metrics
- No merged PRs in 30d
Description
When defining a macro that 'returns' a backcall, it will not produce the expected code.
The given Yuescript code:
macro backcall = (fn) -> "() <- #{fn}()"
do
$backcall async_fn
print()
() <- async_fn()
print()
The above will compile to the following Lua code:
do
async_fn(function() end)
print(); --- Unrelated sidenote: Why the semicolon? Did you add it in the compiler for testing purposes and forgot to remove it?
async_fn(function()
return print()
end)
end
I would expect the macro to produce the same code as the written-out version below it.
Just in the case that a more real-world example is useful: I stumbled across this issue when using this macro:
--- The code
---
--- ```yuescript
--- $await output_stream::write("foo", "bar")
--- ```
---
--- becomes
---
--- ```yuescript
--- (_, __async_result) <- output_stream::write_async("foo", "bar", nil)
--- output_stream::write_finish(__async_result)
--- ```
macro await = (call) ->
object, method, args = call::match([[([a-zA-Z_][a-zA-Z0-9_]*)::([a-zA-Z_][a-zA-Z0-9_]*)%((.*)%)]])
"
(_, __async_result) <- #{object}::#{method}_async(#{args}, nil)
#{object}::#{method}_finish(__async_result)
"
It's intended for working with Gio, a library for asynchronous IO https://docs.gtk.org/gio/method.OutputStream.write_async.html
Each successive $await call is intended to become nested in the previous backcall. However, what happens instead is that only the #{object}::#{method}_finish(__async_result) gets nested, then the block ends.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Use the minimal backcall macro example and compare its generated Lua with the handwritten version; begin at the compiler's macro-expansion path for backcalls. Done means macro-generated backcalls preserve the explicit code's nesting and return behavior, including successive $await calls. No source file or test is named in the issue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- lua
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100