-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathNestedArray.hx
102 lines (85 loc) · 2.89 KB
/
NestedArray.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
package moon.data.array;
#if macro
import haxe.macro.Context;
import haxe.macro.Expr;
import haxe.macro.Type;
using haxe.macro.TypeTools;
using haxe.macro.ComplexTypeTools;
using moon.macros.FieldTools;
using moon.macros.TypeReplaceTools;
#end
/**
* NestedArray<Int, 2> ==> NestedArray2<Int> ==> Array<Array<Int>>
* This generates typedefs to create nested arrays.
* Nested arrays can be jagged. For even/fixed-sized nested arrays,
* use HyperArray or MultiArray.
*
* Usage:
* var n = new NestedArray<Int, 2>();
* // same as:
* var n = new Array<Array<Int>>();
*
* @author Munir Hussin
*/
@:genericBuild(moon.data.array.NestedArray.NestedArrayMacro.build())
class NestedArray<Rest> {}
#if macro
class NestedArrayMacro
{
public static var cache = new Map<Int, Bool>();
public static macro function build():ComplexType
{
//trace("-------");
return switch(Context.getLocalType())
{
case TInst(_.get() => { name: "NestedArray" }, params):
if (params.length != 2)
throw "Expected type parameter <Type, Depth>";
var type = params[0];
var depth:Int = switch(params[1])
{
case TInst(_.get() => { kind: KExpr({ expr: EConst(CInt(i)) }) }, _):
Std.parseInt(i);
case _:
throw "Expected an Int literal";
}
//trace(type, size);
buildClass(type, depth);
case t:
throw 'Incompatible type: $t';
}
}
public static function buildClass(type:Type, depth:Int):ComplexType
{
var pos = Context.currentPos();
var className = 'NestedArray$depth';
var selfPath = { pack: [], name: className };
var selfPathParam = { pack: [], name: className, params: [TPType(type.toComplexType())] };
var selfType = TPath(selfPathParam);
if (!cache.exists(depth))
{
var baseType = buildNestedArrayType(depth);
//var fields = Context.getBuildFields();
//trace(baseType.toString());
// typedef NestedArray3<T> = Array<Array<Array<T>>>
Context.defineType(
{
pack: [],
name: className,
pos: pos,
params: [{ name: 'T' }],
kind: TDAlias(baseType),
fields: []
});
cache[depth] = true;
}
return selfType;
}
public static function buildNestedArrayType(depth:Int):ComplexType
{
if (depth == 0) return macro:T;
var param = buildNestedArrayType(depth - 1);
return macro:Array<$param>;
}
}
#end