-
Notifications
You must be signed in to change notification settings - Fork 0
/
Wait.hx
155 lines (118 loc) · 4 KB
/
Wait.hx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package uhx.macro;
import haxe.macro.Type;
import haxe.macro.Expr;
import haxe.macro.Context;
import uhx.macro.KlasImp;
using Lambda;
using uhu.macro.Jumla;
using haxe.macro.ExprTools;
/**
* ...
* @author Skial Bainn
*/
class Wait {
private static function initialize() {
try {
KlasImp.initialize();
KlasImp.inlineMetadata.add( ~/@:wait\s/, Wait.handler );
} catch (e:Dynamic) {
// This assumes that `implements Klas` is not being used
// but `@:autoBuild` or `@:build` metadata is being used
// with the provided `uhx.macro.Wait.build()` method.
}
}
public static function build():Array<Field> {
var cls = Context.getLocalClass().get();
var fields = Context.getBuildFields();
for (i in 0...fields.length) {
fields[i] = handler( cls, fields[i] );
}
return fields;
}
public static function handler(cls:ClassType, field:Field):Field {
/*if (!Context.defined( 'display' )) */switch(field.kind) {
case FFun(method) if (method.expr != null): loop( method.expr );
case _:
}
return field;
}
public static var STEP:Int = 0;
public static function loop(e:Expr) {
switch (e.expr) {
case EBlock(exprs):
var nexprs = [];
var len = exprs.length;
var index = len-1;
STEP = 0;
while (index >= 0) {
var es = exprs[index];
var block = null;
switch (es) {
case macro @:wait $expr( $a { args } ):
var fargs = [];
var type = try Context.typeof( expr ) catch (e:Dynamic) expr.toString().find();
args = args.mapi( function(index, expr) {
return transformArg(expr, type == null ? null : type.args()[index], fargs);
} ).array();
block = {expr: EVars([{
name: 'block$STEP',
type: null,
expr: {
expr: EFunction( null, {
args: fargs,
ret: null,
params: [],
expr: {
expr: EBlock( nexprs.copy() ),
pos: es.pos
}
} ), pos: es.pos
}
}]), pos: es.pos };
nexprs = [];
STEP++;
case _:
es.iter( loop );
}
nexprs.unshift( es );
if (block != null) nexprs.unshift( block );
index--;
}
if (nexprs.length > 0) {
e.expr = EBlock( nexprs );
}
case _:
e.iter( loop );
}
}
public static function transformArg(arg:Expr, targ:{ name : String, opt : Bool, t : Type }, ?fargs:Array<FunctionArg>) {
switch (arg) {
case macro [$a { values } ]:
var blanks = [for (f in fargs) macro null];
for (i in 0...values.length) {
var value = values[i];
//trace( arg.toString(), targ.name, targ.t.toCType() );
// TODO for each name in array, set it's type to matching position in `targ`
// so `success` is position 0 in TFunction( [TPath( {...} )] ) and of type `String`.
// OUTPUT - [success],success,TFunction([TPath({ name => String, pack => [], params => [] })],TPath({ name => StdTypes, pack => [], params => [], sub => Void }))
var type = targ == null ? macro:Dynamic : targ.t.toCType();
switch (type) {
case TFunction(_args, _ret):
type = _args[i];
case _:
}
var fi = fargs.push( { name: value.toString(), opt: true, type: type } ) - 1;
blanks.push( macro _ );
}
var e1 = macro $i { 'block$STEP' };
// Adding cast allows it to compile. This is just wrong, but I couldnt figure out the problem... crap burgers!
var e2 = blanks.length > 0 ? macro $e1.bind($a { blanks } ) : macro $e1;
arg.expr = e2.expr;
case macro $call($a { args } ):
//args = args.map( transformArg.bind(_, targ, fargs) );
args = args.mapi( function(index, expr) return transformArg(expr, targ == null ? null : targ.t.args()[index], fargs) ).array();
case _:
}
return arg;
}
}