Search code examples
sweet.js

sweet.js: transforming occurrences of a repeated token


I want to define a sweet macro that transforms

{ a, b } # o

into

{ o.a, o.b }

My current attempt is

macro (#) {  
  case infix { { $prop:ident (,) ... } | _ $o } => {
    return #{ { $prop: $o.$prop (,) ... } }
  }
}

However, this give me

SyntaxError: [patterns] Ellipses level does not match in the template

I suspect I don't really understand how ... works, and may need to somehow loop over the values of $prop and build syntax objects for each and somehow concatenate them, but I'm at a loss as to how to do that.


Solution

  • The problem is the syntax expander thinks you're trying to expand $o.$prop instead of $prop: $o.$prop. Here's the solution:

    macro (#) {  
      rule infix { { $prop:ident (,) ... } | $o:ident } => {
        { $($prop: $o.$prop) (,) ... }
      }
    }
    

    Notice that I placed the unit of code in a $() block of its own to disambiguate the ellipse expansion.

    Example: var x = { a, b } # o; becomes var x = { a: o.a, b: o.b };.