Skip to content

Instantly share code, notes, and snippets.

@jdonaldson
Created February 24, 2012 00:06
Show Gist options
  • Save jdonaldson/1895962 to your computer and use it in GitHub Desktop.
Save jdonaldson/1895962 to your computer and use it in GitHub Desktop.
MacroLambda: Automatically return new lists or arrays depending on the map argument type.
import haxe.macro.Expr;
import haxe.macro.Context;
class MacroLambda
{
public static function main(): Void
{
trace('Hello World');
var arr = new Array<Int>();
arr.push(1); arr.push(2); arr.push(3);
var l = new List<Int>();
l.add(1); l.add(2); l.add(3);
var res = macroMap(arr,function(x:Int) return x + '!');
trace(res);
var res2 = macroMap(l,function(x:Int) return x + '!');
trace(res2);
// errors
/* var res3 = macroMap(4,function(x:Int) return x + '!');
trace(res3);
*/
/* var res4 = macroMap('hi!',function(x:Int) return x + '!');
trace(res4);*/
// Fast list has different insertion behavior... exercise for the reader!
/* var fl = new haxe.FastList();
fl.add(1); fl.add(2); fl.add(3);
var res5 = macroMap(fl,function(x:Int) return x + '!');
trace(res5);*/
}
@:macro public static function macroMap<A,B>(it:ExprRequire<Iterable<A>>, f:ExprRequire<A->B>) {
switch(Context.typeof(it)){
case TInst(cl,params): {
var type_name = cl.toString();
var pos = it.pos;
var cons:Expr;
var call_func:Expr;
if (type_name == 'Array'){
call_func = {expr:EField({expr:EConst(CType("MacroLambda")), pos:pos },'arrayMap'), pos:pos};
}else {
call_func = {expr:EField({expr:EConst(CType("Lambda")), pos:pos },'map'), pos:pos};
}
var res = { expr:ECall(call_func,[it,f]), pos:pos};
return res;
}
default: throw 'must be a List or Array instance';
}
}
private static function arrayMap<A,B>(arr:Array<A>, f:A->B):Array<B>{
var res = new Array<B>();
res[arr.length-1] = null;
for (i in 0...arr.length){
res[i] = f(arr[i]);
}
return res;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment