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