【发布时间】:2016-04-01 17:42:44
【问题描述】:
我基本上是在尝试创建一个宏,通过为所有条件提供一个通用结果语句来自动生成if/else if 链。
这是我迄今为止尝试过的(修改代码仅作为示例):
import haxe.macro.Expr;
class LazyUtils {
public macro static function tryUntilFalse( xBool:Expr, xConds:Array<Expr> ) {
var con1, con2, con3, con4, con5;
/*
* Here's a switch to handle specific # of conditions, because for-loops
* don't seem to be allowed here (at least in the ways I've tried so far).
*
* If you know how to use for-loop for this, PLEASE do tell!
*/
switch(xConds.length) {
case 1: {
con1 = conds[0];
return macro {
if (!$con1) $xBool;
}
}
case 2: {
con1 = conds[0];
con2 = conds[1];
return macro {
if (!$con1) $xBool;
else if (!$con2) $xBool;
}
}
case 3: {
con1 = conds[0];
con2 = conds[1];
con3 = conds[2];
return macro {
if (!$con1) $xBool;
else if (!$con2) $xBool;
else if (!$con3) $xBool;
}
}
// ... so on and so forth
}
return macro { trace("Unhandled length of conditions :("); };
}
}
那么,理论上可以这样使用:
class Main {
static function main() {
var isOK = true;
LazyUtils.tryUntilFalse( isOK = false, [
doSomething(),
doSomethingElse(), //Returns false, so should stop here.
doFinalThing()
]);
}
static function doSomething():Bool {
// ???
return true;
}
static function doSomethingElse():Bool {
// ???
return false;
}
static function doFinalThing():Bool {
return true;
}
}
应该生成这个条件树:
if (!doSomething()) isOK = false;
else if (!doSomethingElse()) isOK = false;
else if (!doFinalThing()) isOK = false;
或者,我想它可以输出这个:
if(!doSomething() || !doSomethingElse() || !doFinalThing()) isOK = false;
现在回想起来,确实如此 - 编写一个完整的宏来生成更容易以原始格式输入的代码可能没有多大意义。
但是为了学习宏,有没有人知道是否可以像我在上面的代码示例中尝试的那样在Array<Expr> 中传递多个表达式?
【问题讨论】:
标签: arrays syntax macros expression haxe