Skip to content

Instantly share code, notes, and snippets.

@skial
Last active December 17, 2015 06:18
Show Gist options
  • Select an option

  • Save skial/5563966 to your computer and use it in GitHub Desktop.

Select an option

Save skial/5563966 to your computer and use it in GitHub Desktop.
Haxe async to sync style metadata thingy, supporting auto completion. Inspired by https://github.com/koush/node/wiki/%22async%22-support-in-node.js which was inspired by C# await keyword. Using Haxe r6632
package example.inlineMeta;
import haxe.macro.Printer;
import haxe.macro.Type;
import haxe.macro.Expr;
import haxe.macro.Context;
/**
* ...
* @author Skial Bainn
*/
class Macro
{
public static function build() {
var fields = Context.getBuildFields();
for (field in fields) {
switch (field.kind) {
case FFun(method):
if (method.expr != null) {
method.expr = loop( method.expr );
}
case _:
}
}
return fields;
}
public static function loop(e:Expr, ?body:Array<Expr>) {
var pos = e.pos;
var result = e;
var printer = new Printer();
switch(e.expr) {
case EMeta(s, e):
if (s.name == ':wait' && s.params.length > 0) {
result = loop( modify( e , s.params, body ) );
}
case EBlock(exprs):
var i = 0;
for (expr in exprs) {
++i;
result = loop( expr, exprs.slice( i ) );
if ( printer.printExpr( result ) != printer.printExpr( expr ) ) {
break;
}
}
if ( printer.printExpr( result ) != printer.printExpr( e ) ) {
exprs = exprs.slice(0, i);
result = { expr:EBlock(exprs), pos:pos };
}
case ECall(e, p):
var params:Array<Expr> = [];
for (pp in p) {
params.push( loop( pp ) );
}
result = { expr:ECall( loop( e ), params ), pos:pos };
case EFunction(n, f):
f.expr = loop( f.expr );
case _:
//trace( e );
}
return result;
}
public static function modify(e:Expr, params:Array<Expr>, body:Array<Expr>) {
var pos = e.pos;
var result = e;
var printer = new Printer();
switch (e.expr) {
case ECall(e, p):
var method = Context.parse('function(${printer.printExpr( params[0] )}, ${printer.printExpr( params[1] )}) {}', e.pos);
p.push( modify( method, [], body ) );
result = { expr:ECall(e, p), pos:pos };
case EFunction(n, f):
f.expr = { expr:EBlock( body ), pos:f.expr.pos };
result = { expr:EFunction(n, f), pos:pos };
case _:
}
return result;
}
}
package example.inlineMeta;
/**
* ...
* @author Skial Bainn
*/
@:build( example.inlineMeta.Macro.build() )
class Main {
public static function main() {
var a:Int, b:Int, c:Int;
@:wait( success1, _ ) foo( 'Hello ' );
trace( success1 );
var d:Int, e:Int, f:Int;
@:wait( success2, _ ) foo( 'World' );
success1 += success2;
trace( success1 );
}
public static function foo(value:String, cb:String->String->Void) {
return cb( value, 'b' );
}
}
(function () { "use strict";
var example = {}
example.inlineMeta = {}
example.inlineMeta.Main = function() { }
example.inlineMeta.Main.main = function() {
var a, b, c;
example.inlineMeta.Main.foo("Hello ",function(success1,_) {
console.log(success1);
var d, e, f;
example.inlineMeta.Main.foo("World",function(success2,_1) {
success1 += success2;
console.log(success1);
});
});
}
example.inlineMeta.Main.foo = function(value,cb) {
return cb(value,"b");
}
example.inlineMeta.Main.main();
})();
@npretto
Copy link
Copy Markdown

npretto commented Nov 25, 2015

Hi, am i wrong or this cannot be used if we want to return the value we set via @:wait?

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