Skip to content

Instantly share code, notes, and snippets.

@nadako
Last active August 29, 2015 14:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nadako/8785a249fd67e95b00aa to your computer and use it in GitHub Desktop.
Save nadako/8785a249fd67e95b00aa to your computer and use it in GitHub Desktop.
import js.html.ArrayBuffer;
import js.html.DataView;
import DataTypes;
@:dce
@:build(DataMacro.build())
abstract Data(DataView) {
var byte:Uint8;
var int:Int32;
var float:Float32;
public inline function new(buf:ArrayBuffer) {
this = new DataView(buf);
}
}
#if macro
import haxe.macro.Context;
import haxe.macro.Expr;
import haxe.macro.Type;
using haxe.macro.Tools;
class DataMacro {
static function build():Array<Field> {
var fields = Context.getBuildFields();
var ofs = 0;
for (f in fields.copy()) {
switch (f.kind) {
case FVar(t, null):
var getFn = null;
var setFn = null;
var ofsExpr = macro $v{ofs};
var type = t.toType().follow();
switch (type) {
case TAbstract(_.get() => ab, []) if (ab.module == "DataTypes"):
getFn = "get" + ab.name;
setFn = "set" + ab.name;
switch (ab.meta.extract(":size")) {
case [{params: [{expr: EConst(CInt(s))}]}]:
ofs += Std.parseInt(s);
default:
throw new Error("Invalid @:size meta", ab.pos);
}
default:
throw new Error("Unsupported type " + type.toString(), f.pos);
}
f.kind = FProp("get", "set", t);
f.access = [APublic];
fields.push({
pos: f.pos,
name: "get_" + f.name,
access: [AInline],
kind: FFun({
ret: t,
args: [],
expr: macro return this.$getFn($ofsExpr),
})
});
fields.push({
pos: f.pos,
name: "set_" + f.name,
access: [AInline],
kind: FFun({
ret: t,
args: [{name: "value", type: t}],
expr: macro {
this.$setFn($ofsExpr, value);
return value;
},
})
});
default:
}
}
return fields;
}
}
#end
@:size(1) abstract Int8(Int) from Int to Int {}
@:size(1) abstract Uint8(Int) from Int to Int {}
@:size(2) abstract Int16(Int) from Int to Int {}
@:size(2) abstract Uint16(Int) from Int to Int {}
@:size(4) abstract Int32(Int) from Int to Int {}
@:size(4) abstract Uint32(Int) from Int to Int {}
@:size(4) abstract Float32(Float) from Float to Float {}
@:size(8) abstract Float64(Float) from Float to Float {}
class Main {
static function main() {
}
static function doStuff(data:Data) {
var b:Int = data.byte;
var i:Int = data.int;
data.float = b + i;
}
}
// Generated by Haxe
(function () { "use strict";
var Main = function() { };
Main.main = function() {
};
Main.doStuff = function(data) {
var b = data.getUint8(0);
var i = data.getInt32(1);
var value = b + i;
data.setFloat32(5,value);
};
Main.main();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment