Skip to content

Instantly share code, notes, and snippets.

@back2dos
Created June 17, 2015 15:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save back2dos/2785f42c5a52a7f2369a to your computer and use it in GitHub Desktop.
Save back2dos/2785f42c5a52a7f2369a to your computer and use it in GitHub Desktop.
Anonymous enums \o/
#if macro
import haxe.macro.Expr;
import haxe.macro.Type;
import haxe.macro.Context.*;
#else
@:genericBuild(AnonEnum.build())
#end
class AnonEnum<Const> {
macro static function build():Type {
return
switch getLocalType() {
case TInst(_, [TInst(_.get() => { kind: KExpr(e) }, _)]):
switch e.expr {
case EArrayDecl(values):
var def = macro class { };
def.kind = TDEnum;
for (v in values)
switch v {
case macro $i{name}:
def.fields.push({
name: name,
pos: v.pos,
kind: FVar(null, null)
});
case macro $i{name}($a{args}):
def.fields.push( {
name: name,
pos: v.pos,
kind: FFun({
ret: null,
expr: null,
args: [for (a in args) switch a {
case macro var $name:$t:
{
name: name,
type: t,
}
default:
error('Variable declaration expected', a.pos);
}]
})
});
default:
error('enum constructor expected', v.pos);
}
def.name = 'Either_'+[for (f in def.fields) f.name].join('_or_');
defineType(def);
getType(def.name);
default:
error('Should be an array literal', e.pos);
}
default:
throw 'assert';
}
}
}
class Usage {
static function main() {
var t:AnonEnum<[foo(var i:Int, var j:Float), bar]> = foo(3, 4);//TADAAAA!
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment