Skip to content

Instantly share code, notes, and snippets.

@AxGord
Created June 9, 2018 15:35
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 AxGord/29b0061cc08855c825300b55dbbd2bf0 to your computer and use it in GitHub Desktop.
Save AxGord/29b0061cc08855c825300b55dbbd2bf0 to your computer and use it in GitHub Desktop.
Generic macro abstract function!
import haxe.macro.TypeTools;
import haxe.macro.Expr;
import haxe.macro.Context;
import haxe.macro.Type;
class GenericBuildMacro {
static public function build():ComplexType {
var pos = Context.currentPos();
var fields = new Array<Field>();
switch (Context.getLocalType()) {
case TInst(_,[TInst(_.get() => { kind: KExpr(_.expr=>EArrayDecl(a)) },_)]):
fields.push({
name: 'new',
kind: FFun({
args: [{
name: 'fn',
type: TFunction(
a.map(e -> switch e.expr {
case EConst(CIdent(c)):
TypeTools.toComplexType(Context.getType(c));
case _: throw 'error';
}),
macro:Void
),
}],
ret: null,
expr: macro this = fn
}),
pos: pos,
access: [APublic]
});
var n:Int = 0;
fields.push({
name: 'call',
kind: FFun({
args: a.map(e -> switch e.expr {
case EConst(CIdent(c)): {
name: 'arg${n++}',
type: TypeTools.toComplexType(Context.getType(c)),
opt: false,
value: null,
meta: null
}
case _: throw 'error';
}),
ret: null,
expr: {expr: ECall(macro this, [for (v in 0...n) macro $i{'arg$v'}]), pos: pos}
}),
pos: pos,
access: [APublic]
});
case t:
Context.error("Class expected", Context.currentPos());
}
var classPath = {pack : ['gen'], name:"AbstractFn"}
var typeDefinition : TypeDefinition = {
pos : pos,
pack : classPath.pack,
name : classPath.name,
kind :TDAbstract(macro :haxe.Constraints.Function),
fields: fields
}
Context.defineType(typeDefinition);
return TPath(classPath);
}
}
class Main {
private static function main():Void {
var c:String = '';
var x = new Fn<[String, Int]>((a, b) -> c = a + b);
x.call('a', 3);
trace(c);
x.call('c', 8);
trace(c);
}
}
@:genericBuild(GenericBuildMacro.build())
class Fn<Const> {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment