Skip to content

Instantly share code, notes, and snippets.

@jasononeil
Last active December 18, 2015 03:38
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 jasononeil/5719274 to your computer and use it in GitHub Desktop.
Save jasononeil/5719274 to your computer and use it in GitHub Desktop.
Using a macro as the initialization of one field, and having it base itself on an existing member variable.
import haxe.macro.Expr;
import haxe.macro.Context;
class F
{
macro public static function f(a : Expr, b : Int) : Expr
{
// get the field name as a string, use Pattern Matching or tink macros probably...
var fieldName = switch (a.expr) {
case EConst(CIdent(name)): name;
case _: throw "First argument must be a variable name";
}
// Get the local class, and find the field that was asked for
var fields = Context.getLocalClass().get().statics.get();
var myField = fields.filter( function(f) { return f.name == fieldName; }).shift();
if (myField == null) throw 'Field $fieldName not found';
// Extract the value
if (myField.expr() == null) throw 'Field $fieldName had no initialization value...';
var expr = Context.getTypedExpr(myField.expr());
var fieldVal = switch(expr.expr) {
case EConst(CInt(v)): Std.parseInt(v);
case _: throw 'Was expecting $fieldName to be initialized as an Int';
}
// Do something with it
var newVal = fieldVal * b;
// Return an expression to use in it's place
return macro $v{newVal};
}
}
class MacroHelpTest
{
public static var a = 4;
public static var b = F.f(a, 2);
public static var c = F.f(a, 35);
static function main()
{
trace (a);
trace (b);
trace (c);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment