Can I generate code from string with macros?

56 views
Skip to first unread message

Joaquin Bello

unread,
Dec 27, 2014, 4:11:50 PM12/27/14
to haxe...@googlegroups.com
Hi, I'm tired of writing dumb fill code, so I'm trying to create something that generates code like this

createNode(aEntity:Entity):Node
{
var node:MotionNode=new MotionNode();

node.position=cast(aEntitiy.get(Position.ID)); //assigns a property 
node.motion=cast(aEntity.get(Motion.ID));

return node;
}

I don't want to create a generic function using RTTI for speed reasons.

I want to create a macro with a firm like this
 
autoNodeCreation(aEntity:Entity, node:String or class)


The first trouble I have is that Position.ID is a static Int generated  with a @:autoBuild , I can't find a way to reference the class inside the macro without an error.
 Inside the macro I manage to find the fields(name and type) of the Node.

 So I was wondering if there's a way to use macros to just insert code(string) so at runtime I know Position.ID is generated.

Hope it's not too confusing what I want to do.

Thanks and any help would be great!

Joaquin Bello

unread,
Dec 28, 2014, 1:20:49 AM12/28/14
to haxe...@googlegroups.com
So I made a working demo, apparently the code is working and the js result code looks right.  

Here my ugly copy paste from many examples from the web, I post it for future references.

macro public static function generateExtraMethods(nodeType:String):Array<Field> {
 
 var code:String;
 var exp:Array<Expr> = new Array();
  switch (haxe.macro.Context.getType(nodeType))
{
 case TInst(cl, _)://couldn't find another way to RTTI the class without an instance

 code = "var _node:" + nodeType+" = new " + nodeType+"()"; //example: var node:MotionNode=new MotionNode();
exp.push(Context.parseInlineString(code, Context.currentPos()));
var array = cl.get().fields.get();
for (i in array) 
{
code = "_node." + i.name+" = cast(aEntity.get(" + i.type.getParameters()[0].toString() + ".ID)) ";   //example: node.position=cast(aEntitiy.get(Position.ID));
exp.push(Context.parseInlineString(code, Context.currentPos()));
}
 code = "return _node";    //return node
 exp.push(Context.parseInlineString(code, Context.currentPos()));
 
 case _: 
 trace("Macro error wrong type, look at : " + Context.currentPos);
}

var c = macro : {
public function createNode(aEntity:Entity):PropertyNode{  //need to import Entity and PropertyNode in the class that use @build
$b { exp } //this turns the array into a single expr
}
}
switch (c) {
case TAnonymous(fields):
return Context.getBuildFields().concat(fields);
default:
throw 'unreachable';
Reply all
Reply to author
Forward
0 new messages