Skip to content

Instantly share code, notes, and snippets.

@Simn
Created May 7, 2014 16:48
Show Gist options
  • Save Simn/fda5c649062271d705c6 to your computer and use it in GitHub Desktop.
Save Simn/fda5c649062271d705c6 to your computer and use it in GitHub Desktop.
Tuple<Const>
@:genericBuild(MyMacro.buildTuple())
class Tuple<Const> { }
class Main {
static public function main() {
var t = new Tuple<3>(1, "foo", true);
trace(t.v0);
trace(t.v1);
trace(t.v2);
}
}
import haxe.macro.Expr;
import haxe.macro.Context;
import haxe.macro.Type;
using haxe.macro.Tools;
class MyMacro {
static var tupleMap = new Map();
macro static public function buildTuple():Type {
var t = Context.getLocalType();
switch(t) {
case TInst(c, [TInst(_.get().kind => KExpr(macro $v{(s:Int)}),_)]):
var arity = Std.parseInt(s);
if (tupleMap.exists(arity)) {
return tupleMap[arity];
}
var t = buildTupleType(c.get(), Context.getBuildFields(), arity);
tupleMap[arity] = t;
return t;
case _:
return Context.error("Class expected", Context.currentPos());
}
}
static function buildTupleType(c:ClassType, fields:Array<Field>, arity:Int) {
var typeParams = [];
var tupleFields = [];
for (i in 0...arity) {
var fieldName = 'v$i';
var typeParamName = 'T$i';
var typeParam = {
TPath({
pack: [],
name: typeParamName,
sub: null,
params: []
});
}
typeParams.push({
name: typeParamName,
constraints: [],
params: []
});
var field = (macro class X {
public var $fieldName:$typeParam;
}).fields[0];
tupleFields.push(field);
}
var constructor = {
name: "new",
pos: c.pos,
access: [APublic, AInline],
kind: FFun({
ret: null,
expr: macro $b{tupleFields.map(function(field) {
var name = field.name;
return macro this.$name = $i{name};
})},
params: [],
args: tupleFields.map(function(field) {
return {
name: field.name,
type: null,
opt: false,
value: null
}
})
})
}
var name = c.name + "_" + arity;
var tDef = {
pack: c.pack,
name: name,
pos: c.pos,
kind: TDClass(),
params: typeParams,
fields: fields.concat(tupleFields).concat([constructor])
}
Context.defineType(tDef);
return Context.getType(haxe.macro.MacroStringTools.toDotPath(c.pack, name));
}
}
@jcward
Copy link

jcward commented Aug 25, 2017

Hey Simon, was this just an idea / prototype thinking, or something that should work?

It's not compiling in Haxe 3.4.2 today. Here's the compiler output: https://hastebin.com/esonedaqah.vbs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment