IppClub / IppClub/YueScript

Backcalls in macros get incorrectly compiled

Open
#139 4 comments 0 reactions 0 assignees View on GitHub

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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.