宏和字符串插值变量

时间:2017-09-11 15:01:38

标签: 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 after)), pos => #pos(Test.hx:4: characters 12-39) }

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

    return macro $e;
  }
}

如果没有手动解析字符串常量,我应该在注释掉的代码中放置trace()内插String表达式中使用的变量的名称?

2 个答案:

答案 0 :(得分:4)

你想要的是formatString

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; 
  }
}

答案 1 :(得分:2)

输入表达式是一个常量的文字字符串。所以你必须自己解析$i。以下是使用regular expression的示例,对于奖励积分,请在调用上下文中获取其类型。

http://try-haxe.mrcdk.com/#B0B9E(点击Build+run,查看输出编译器输出标签)

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;
  }
}