Created
April 23, 2015 12:26
-
-
Save nadako/97c51fb829202cd33103 to your computer and use it in GitHub Desktop.
Poor man's enum
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
#if macro | |
import haxe.macro.Context; | |
import haxe.macro.Expr; | |
import haxe.macro.Type; | |
using haxe.macro.Tools; | |
#end | |
abstract Choice<T>(T) from T { | |
public macro function match(self, match) { | |
switch (match.expr) { | |
case ESwitch(_, origCases, def): | |
var ctors = new Map(); | |
var ctorsOrder = []; | |
for (c in origCases) { | |
switch (c.values) { | |
case [macro $i{ctor}($a{args})]: | |
var ctorCases = ctors[ctor]; | |
if (ctorCases == null) | |
{ | |
ctorCases = ctors[ctor] = []; | |
ctorsOrder.push(ctor); | |
} | |
ctorCases.push({ | |
arg: args[0], | |
guard: c.guard, | |
expr: c.expr | |
}); | |
default: | |
throw false; | |
} | |
} | |
var switchElems = [macro Reflect.fields(v)[0]]; | |
var cases:Array<Case> = []; | |
for (i in 0...ctorsOrder.length) { | |
var ctor = ctorsOrder[i]; | |
switchElems.push(macro v.$ctor); | |
for (c in ctors[ctor]) { | |
var values = [macro $v{ctor}]; | |
for (j in 0...ctorsOrder.length) { | |
if (j == i) | |
values.push(c.arg); | |
else | |
values.push(macro _); | |
} | |
cases.push({ | |
values: [macro $a{values}], | |
expr: c.expr, | |
guard: c.guard | |
}); | |
} | |
} | |
var switchExpr = { | |
pos: match.pos, | |
expr: ESwitch(macro $a{switchElems}, cases, def) | |
}; | |
var ct = switch (Context.typeof(self).follow()) { | |
case TAbstract(_, [t]): t.toComplexType(); | |
default: throw false; | |
} | |
trace(switchExpr.toString()); | |
return macro { | |
var v:$ct = cast $self; | |
$switchExpr; | |
}; | |
default: | |
throw false; | |
} | |
} | |
} |
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
typedef MyEnum = Choice<{ | |
?a:Int, | |
?b:Array<String>, | |
}>; | |
class Main { | |
static function main () { | |
var a:MyEnum = {a: 10}; | |
a.match(switch _ { | |
case a(v): | |
trace(v); | |
case b(v): | |
trace(v); | |
default: | |
trace("hello"); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
generated js: