Macro and string interpolation variables

Code Submission

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

what should I put in the code with comments the trace()name of the variable used inside the interpolated expression Stringwithout manually parsing the string constant?

+4
source share
2 answers

Do you want 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; 
  }
}
+4
source

The expression you enter is a constant, a literal string. So, you need to disassemble $iyourself. Here's an example using a regex and for bonus points to get its type in a calling context.

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

Source: https://habr.com/ru/post/1685474/


All Articles