Created
February 24, 2012 00:06
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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