使用 LeMP 生成字符串
Generating Strings with LeMP
我正在尝试使用 LeMP 为 C++ 库生成一些 C# 绑定,作为其中的一部分,我需要生成一个字符串,该字符串将 LeMP 宏中的一些参数组合在一起以用于 DllImport EntryPoint 值。查看文档,似乎 concatId 和 stringify 的组合应该可以完成这项工作,但我无法让它工作。这是相关代码的稍微简化版本:
define TypedIndexer2D($CONTAINER_TYPE, $T1, $T2)
{
replace(MethodName => concatId(Buffer, $CONTAINER_TYPE, GetExpr_, $T1, $T2));
replace(CFunction => concatId(buffer_, $CONTAINER_TYPE, _getexpr__, $T1, $T2));
[DllImport(Constants.LibName, EntryPoint = CFunction)]
public static extern IntPtr MethodName(IntPtr obj, IntPtr x, IntPtr y);
}
TypedIndexer2D(Int, Var, Var);
这会发出以下内容:
[DllImport(Constants.LibName, EntryPoint = buffer_Int_getexpr__VarVar)]
public static extern IntPtr BufferIntGetExpr_VarVar(IntPtr obj, IntPtr x, IntPtr y);
但是,我需要这个:
[DllImport(Constants.LibName, EntryPoint = "buffer_Int_getexpr__VarVar")]
public static extern IntPtr BufferIntGetExpr_VarVar(IntPtr obj, IntPtr x, IntPtr y);
(注意引用的入口点)。
我以为会是这样的:
replace(CFunction => stringify(concatId(buffer_, $CONTAINER_TYPE, _getexpr__, $T1, $T2)));
然而,它只会发出以下内容:
[DllImport(Constants.LibName, EntryPoint = "concatId(buffer_, Int, _getexpr__, Var, Var)")]
如何说服 LeMP 在这里生成我需要的字符串?谢谢!
concatId
的输出结果确实是运行stringify
,但是有一个技巧。
困难是执行顺序造成的。宏通常 运行 "outside-in",首先是最外层的宏,这与 运行 "inside-out" 的普通函数相反。因此
stringify(concatId(Tea, ring, Cot, ton));
产生 "concatId(Tea, ring, Cot, ton)"
。目前还没有一种超级优雅的方式来反转顺序 - 在自定义 define
宏中,您可以使用 [ProcessChildrenBefore]
属性,但这不允许您修改 [=13= 的现有行为].这是一种有效的技术:
replacePP(xx => concatId(Tea, ring, Cot, ton)) { stringify(xx); }
// Output: "TearingCotton";
与正常的 replace
不同,replacePP
预处理匹配和替换表达式,因此 concatId
发生在 stringify
之前。将此解决方案应用于您的 TypedIndexer2D
,我们得到
define TypedIndexer2D($CONTAINER_TYPE, $T1, $T2)
{
replace(MethodName => concatId(Buffer, $CONTAINER_TYPE, GetExpr_, $T1, $T2));
replacePP(CFunction => concatId(buffer_, $CONTAINER_TYPE, _getexpr__, $T1, $T2));
[DllImport(Constants.LibName, EntryPoint = stringify(CFunction))]
public static extern IntPtr MethodName(IntPtr obj, IntPtr x, IntPtr y);
}
我正在尝试使用 LeMP 为 C++ 库生成一些 C# 绑定,作为其中的一部分,我需要生成一个字符串,该字符串将 LeMP 宏中的一些参数组合在一起以用于 DllImport EntryPoint 值。查看文档,似乎 concatId 和 stringify 的组合应该可以完成这项工作,但我无法让它工作。这是相关代码的稍微简化版本:
define TypedIndexer2D($CONTAINER_TYPE, $T1, $T2)
{
replace(MethodName => concatId(Buffer, $CONTAINER_TYPE, GetExpr_, $T1, $T2));
replace(CFunction => concatId(buffer_, $CONTAINER_TYPE, _getexpr__, $T1, $T2));
[DllImport(Constants.LibName, EntryPoint = CFunction)]
public static extern IntPtr MethodName(IntPtr obj, IntPtr x, IntPtr y);
}
TypedIndexer2D(Int, Var, Var);
这会发出以下内容:
[DllImport(Constants.LibName, EntryPoint = buffer_Int_getexpr__VarVar)]
public static extern IntPtr BufferIntGetExpr_VarVar(IntPtr obj, IntPtr x, IntPtr y);
但是,我需要这个:
[DllImport(Constants.LibName, EntryPoint = "buffer_Int_getexpr__VarVar")]
public static extern IntPtr BufferIntGetExpr_VarVar(IntPtr obj, IntPtr x, IntPtr y);
(注意引用的入口点)。
我以为会是这样的:
replace(CFunction => stringify(concatId(buffer_, $CONTAINER_TYPE, _getexpr__, $T1, $T2)));
然而,它只会发出以下内容:
[DllImport(Constants.LibName, EntryPoint = "concatId(buffer_, Int, _getexpr__, Var, Var)")]
如何说服 LeMP 在这里生成我需要的字符串?谢谢!
concatId
的输出结果确实是运行stringify
,但是有一个技巧。
困难是执行顺序造成的。宏通常 运行 "outside-in",首先是最外层的宏,这与 运行 "inside-out" 的普通函数相反。因此
stringify(concatId(Tea, ring, Cot, ton));
产生 "concatId(Tea, ring, Cot, ton)"
。目前还没有一种超级优雅的方式来反转顺序 - 在自定义 define
宏中,您可以使用 [ProcessChildrenBefore]
属性,但这不允许您修改 [=13= 的现有行为].这是一种有效的技术:
replacePP(xx => concatId(Tea, ring, Cot, ton)) { stringify(xx); }
// Output: "TearingCotton";
与正常的 replace
不同,replacePP
预处理匹配和替换表达式,因此 concatId
发生在 stringify
之前。将此解决方案应用于您的 TypedIndexer2D
,我们得到
define TypedIndexer2D($CONTAINER_TYPE, $T1, $T2)
{
replace(MethodName => concatId(Buffer, $CONTAINER_TYPE, GetExpr_, $T1, $T2));
replacePP(CFunction => concatId(buffer_, $CONTAINER_TYPE, _getexpr__, $T1, $T2));
[DllImport(Constants.LibName, EntryPoint = stringify(CFunction))]
public static extern IntPtr MethodName(IntPtr obj, IntPtr x, IntPtr y);
}