Skip to content

Instantly share code, notes, and snippets.

@frabbit
Last active August 29, 2015 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save frabbit/8698596 to your computer and use it in GitHub Desktop.
Save frabbit/8698596 to your computer and use it in GitHub Desktop.
class MyMacros {
macro public static function configX (a:Expr):ExprFunc<Void->Expr> {
return function ():Expr {
return macro ($a);
}
}
macro public static function configPlus (a:Expr):ExprFunc<Expr->Expr> {
return function (x:Expr):Expr {
return macro ( $a + $x);
}
}
macro public static function configCall (a:Expr, firstArgs:Array<Expr>):ExprFunc<Array<Expr>->Expr> {
return function (restArgs:Array<Expr>):Expr {
var args = firstArgs.concat(restArgs);
return macro $a($a{args});
}
}
}
// partial application of regular macros can also be seen as an ExprFunc
// usage:
import MyMacros.*;
class Test {
public static function foo1 (a,b,c) {
return a+b+c;
}
public static function main () {
// context dependent configuration of macros
// (sum, pow and plus2 are special expr-Functions which are not generated and only
// expanded during typing. I used exprfunc (can't use macro here) to make it clear that the result is not a variable.
exprfunc sum = configX(a+b);
exprfunc pow = configX(Math.pow(a,b));
exprfunc plus2 = configPlus(2);
var a = 5;
var b = 3;
var x = sum() * pow() + plus(2) - plus(4);
// expands to var x = (a+b) * (Math.pow(a,b)) + (2 + 2) - (2 + 4);
// Alternatively ExprFuncs of type Void->Expr could also be "called" or expanded without brackets
// => var x = sum * pow + plus(2) - plus(4);
exprfunc foo1 = configCall(foo, 1, 2);
exprfunc foo2 = configCall(foo, 1);
var z = foo1(3) + foo2(1,2);
// var z = foo(1,2,3) + foo(1,1,2);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment