Sweet.js - Expand token as a string

536 views Asked by At

I want to expand a token to a string. For example, I have this macro:

macro String {
  rule {
    $x
  } => {
    "$x"
  }
}

I would expect String 1 to expand to "1", however it expands to just 1;

How can I accomplish this?

EDIT: This seems imposible to do with a declarative approach, but should be possible with an imperative approach (see this comment):

macro String {
  case {_ $x } => {        
    return #{"$x"}
  }
}

But that still expands with quotes.

2

There are 2 answers

3
Chuck On BEST ANSWER

As noted in this issue thread, you can do it with an imperative approach, but it's a bit awkward and not well-documented. Basically, you do it like this:

macro String {
  case {_ $x} => {
    var pattern = #{$x};
    var tokenString = pattern[0].token.value.toString();
    var stringValue = makeValue(tokenString, #{$here});
    return withSyntax($val = [stringValue]) {
      return #{$val};
    }
  }
}

BTW, I wouldn't call this macro "String" — it conflicts with the existing String that's natively part of JavaScript.

0
ShawnFumo On

While you still need to use a case macro, it can be more terse than Chuck's answer using unwrapSyntax and letstx:

macro makeStr1 {
  case {_ $x} => {
    var pattern = #{$x};
    var asStr = unwrapSyntax(pattern).toString();
    letstx $xStr = [makeValue(asStr, pattern)];
    return #{$xStr};
  }
}

We can do better, though. How about macros in macros?

macro syntaxToStr {
  rule {$x} => {
    [makeValue(unwrapSyntax($x).toString(), $x)]
  }
}

macro makeStr {
  case {_ $x} => {
    letstx $xStr = syntaxToStr(#{$x});
    return #{$xStr}
  }
}