Macros 宏和字符串插值变量

Macros 宏和字符串插值变量,macros,haxe,string-interpolation,Macros,Haxe,String Interpolation,给出代码 class Test { static function main() { var i = 1; trace(m('some before $i some after')); // some before 1 some after } static macro function m(e: haxe.macro.Expr) { trace(e); // { expr => EConst(CString(some before $i some

给出代码

class Test {
  static function main() {
    var i = 1;
    trace(m('some before $i some after')); // some before 1 some after
  }

  static macro function m(e: haxe.macro.Expr)
  {
    trace(e); // { expr => EConst(CString(some before $i some after)), pos => #pos(Test.hx:4: characters 12-39) }

    // trace the name of referenced var
    /* 
    trace();
    */

    return macro $e;
  }
}

在插入的
字符串
表达式中使用的变量的名称,无需手动解析字符串常量,我应该在注释掉的代码中放置什么内容到
trace()
表达式中?

输入表达式是一个常量文本字符串。因此,您必须自己解析出
$i
。下面是一个使用的示例,为了获得额外点数,请在调用上下文中获取其类型

(单击
Build+run
,查看输出编译器输出选项卡)

你想要的是:


杰夫,谢谢你的完整回答(顺便说一句,我没有想到使用
Context.typeof(…)
)。但事实上,我的问题只是验证我的假设,这是唯一的方法。关于
trace(m(${Std.string(i)}之前的一些)如何()?:)是的,宏的输入只是一个字符串。不管你喜欢怎么解析它,regex是一个懒惰的快速示例。可能有库要解析$interpolation,我从来没有看过。但你可以随便看看:,这是基于。具体来说,这看起来与插值解析相关:据我所知,当在宏上下文中使用haxeparser时,它不会工作。但实际上它可能有一些代码处理,所以我只需要检查haxparse是否在宏中工作(它应该工作)。是的,我指出这些实现是比regex更好的解析示例,以及$interpolation解析的可能示例。并不是专门作为插入式解决方案。解决方案的复杂程度取决于您对输入的期望——从简单变量到可能的任意Haxe代码。假设您可能希望支持表达式,一旦解析出
${…}
内部的内容(字符串),您就可以调用
Context.parse(innerContents,Context.currentPos())
来获取内部
Expr
的AST。我想这也是不同的目标用来输出插值字符串的方法。。。这实际上回答了我最初的问题。我想我应该开始认真阅读API文档。可能还有您在github上的库的源代码整洁,谢谢Juraj,每天学习新东西。我会留下我的答案,以防人们在这个简单的解决方案中搜索关键词D至少我得到了
案例经济学(CString(str)):
感谢Mark最近的模式匹配教程。
import haxe.macro.Expr;
import haxe.macro.Context;

class Test {
  static function main() {
    var i = 1;
    trace(m('some before $i some after')); // some before 1 some after
  }

  static macro function m(e: Expr)
  {
    trace(e); // { expr => EConst(CString(some before $i some after)), pos => #pos(Test.hx:4: characters 12-39) }

    var interpolated:String = null;
    switch e.expr {
        case EConst(CString(str)):
        trace(str); // 'some before $i some after'
        var r = ~/\$\w+/;
        if (r.match(str)) { // matched(0) -> $i
          interpolated = r.matched(0).substr(1);
          trace(interpolated); // 'i'
        }
        default: throw 'Macro m expects a string literal...';
    }

    if (interpolated!=null) {
      var t = Context.typeof({expr: EConst(CIdent(interpolated)), pos:Context.currentPos()});
      trace('Got interpolated var $interpolated of type $t'); // Got interpolated var i of type TAbstract(Int,[])
    }

    return macro $e;
  }
}
class Test {
  #if !macro
  static function main() {
    var i = 1;
    trace(m('some before $i some after')); // some before 1 some after
  }
  #end
  static macro function m(e: haxe.macro.Expr)
  {
    switch e.expr {
      case EConst(CString(s)):
        trace(haxe.macro.MacroStringTools.formatString(s, e.pos));
      default:
    }
    return e; 
  }
}