I'm basically trying to create a macro that automatically generates an if/else if
chain by supplying one common outcome statement for all conditions.
This is what I've tried so far (modified the code just to show as an example):
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 :("); };
}
}
Then, in theory it could be used like this:
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;
}
}
Which should generate this condition tree:
if (!doSomething()) isOK = false;
else if (!doSomethingElse()) isOK = false;
else if (!doFinalThing()) isOK = false;
Alternatively, I suppose it could output this instead:
if(!doSomething() || !doSomethingElse() || !doFinalThing()) isOK = false;
Looking back at this now, true - it may not make much sense to write a whole macro to generate code that would be easier to type out in it's raw format.
But for the sake of learning about macros, does anyone know if multiple expressions can be passed in an Array<Expr>
like I tried in the above code sample?