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

Variable binding (hygiene, gensym) not working in 2-level macros #760

Open
HeatherSoron opened this issue Nov 28, 2019 · 2 comments
Open

Comments

@HeatherSoron
Copy link

Variable binding in a 2-layer macro (i.e., a macro that calls another macro) is broken, in several cases I've tested.

Here's a fairly simple one (simpler than what I was using, but still clearly demonstrates the problem):

syntax shallow = function(ctx) {
    let name = ctx.next().value
    let val = ctx.next().value
    return #`let ${name} = ${val}`
}

syntax deep = function(ctx) {
    let name = ctx.next().value
    return #`shallow ${name} 42`
}

shallow foo 42
deep bar

console.log(foo)
console.log(bar)

This should result in the value "42" being printed twice to stdout, but will actually result in a ReferenceError on the second console.log. The reason for this, is that Sweet.js expands it to the following code:

let foo_13 = 42;
let bar_14 = 42;
console.log(foo_13);
console.log(bar);

That deep bar appears to be misbehaving, as the identifier bar is not picked up later on, during the console.log(bar) call.

@HeatherSoron
Copy link
Author

If anyone wants a pointer on where this is in the codebase, the function reduceBindingIdentifier in sweet-js/core/token-expander.js is what adds the _14.

However, I suspect there's a parsing error earlier in the compilation process, because after doing some research, I discovered that "hygienic macros" seem to be distinguished by the user not having to explicitly call gensym-like functions (this detail isn't in the Sweet.js documentation itself, but is mentioned by other resources online).

@DET171
Copy link

DET171 commented Sep 23, 2022

Any updates on how to solve this?

I've recently came across this problem as well.

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

No branches or pull requests

2 participants