1 module yyd.tool;
2 
3 public import yyd.y;
4 public import yyd.alg;
5 public import yyd.mashup;
6 
7 // Compilation primitives and mixin combinators
8 
9 
10 mixin template assertion (alias T) 
11 {
12     static assert (T);
13     enum _ = true;
14     enum toString = "static assert (" ~ __toString!T ~ ")";
15 }
16 
17 unittest {
18     mixin assertion!true;
19     //mixin assertion!false;
20     //static assert(is(typeof(_)));
21     //static assert(_);
22     static assert (toString == "static assert (\x01)" );
23 }
24 
25 
26 mixin template _version (
27         alias Fnc = _identity,
28         alias N = _identity,
29         V ...
30 ) {
31     version (V) {
32         mixin Fnc;
33     } else {
34         mixin N;
35     }
36 }
37 
38 template version_ (
39         string V,
40         alias Fnc = identity,
41         alias N = identity
42 ) {
43     mixin(q{
44         version ( } ~ V ~ q{ ) {
45             alias version_ = Fnc;
46         } else {
47             alias version_ = N;       
48         }
49     });
50 }
51 
52 unittest {
53     alias r = version_!("unittest",true,false);
54     static assert (r);
55 }
56 
57 /*mixin template _tryCatch(alias _try, _catchType, alias _catchBody, alias _finally)
58 {
59     try {
60         mixin _try!();
61     } catch (_catchType e) {
62         mixin _catchBody!(e);
63     } finally {
64         mixin _finally!();
65     }
66 }*/
67 
68 mixin template _public(alias T=_identity,V...) 
69 {
70     public {
71         mixin T!(V);
72     }
73 }
74 
75 mixin template _protected(alias T=_identity,V...) 
76 {
77     protected {
78         mixin T!(V);
79     }
80 }
81 
82 mixin template _private(alias T=_identity,V...) 
83 {
84     private {
85         mixin T!(V);
86     }
87 }
88 
89 mixin template _package(alias T=_identity,V...) 
90 {
91     package {
92         mixin T!(V);
93     }
94 }
95 
96 mixin template _synchronized(alias T=_identity,V...) 
97 {
98     synchronized {
99         mixin T!(V);
100     }
101 }
102 
103 // Class elements
104 
105 mixin template _aliasThis(alias T=_identitiy) {
106     //import std.array : replace;
107     mixin template _aliasThis_(alias T=_identity)
108     {
109         mixin ("alias T this;".replace("T",__identifier!T));
110     }
111     mixin _import!("std.array : replace",_aliasThis_,T);
112 }
113 
114 mixin template _field(string ident,alias T=identity,alias V=identity) {
115     enum toString = (T.stringof ~ " "~ident~" = "~V.stringof~";");
116     mixin(toString);
117 }
118 
119 mixin template _intField(string ident,alias T=__identity!(0)) {
120     mixin _field!(ident,int,T);
121 }
122 mixin template _longField(string ident,alias T=__identity!(0)) {
123     mixin _field!(ident,long,T);
124 }
125 mixin template _stringField(string ident,alias T=__identity!("")) {
126     mixin _field!(ident,string,T);
127 }
128 mixin template _doubleField(string ident,alias T=__identity!("")) {
129     mixin _field!(ident,double,T);
130 }
131 
132 
133 
134 mixin template _interface(alias T=_identity,V...) 
135 {
136     interface _ {
137         mixin T!(V);
138     }
139 }
140 
141 mixin template _interface(alias T=_identity,interfaces ...) 
142 {
143     interface _ : interfaces {
144         mixin T!();
145     }
146 }
147 
148 mixin template _struct(alias T=_identity) 
149 {
150     struct _ {
151         mixin T!();
152     }
153 }
154 
155 mixin template _enum(alias T=_identity) 
156 {
157     enum _ = {
158         mixin T!();
159     };
160 }
161 
162 mixin template _class(alias T=_identity) 
163 {
164     class _ {
165         mixin T!() _this;
166         mixin _aliasThis!_this;
167         
168         static if(is(typeof(_this.toString))) {
169             enum _toString_ = _this.toString;            
170         } else {
171             enum _toString_ = __identifier!T;            
172         }
173 
174     }
175     static if(is(typeof(_._toString_))) {
176         auto toString() {
177             import std.array : replace;
178             return q{class _ {T}}.replace("T",_._toString_);
179         } 
180     }
181 }
182 
183 mixin template _class(alias T=_indentity,alias superClass) 
184 if(is(superClass == class) || is(superClass == interface))
185 {
186     class _ : superClass {
187         mixin T!() _;
188         mixin _aliasThis!_;
189         static if(isConstant!(_.toString)) {
190             enum _toString_ = _.toString;            
191         } else {
192             //
193         }
194     }
195     
196     static if (typeof(_._toString_)) {
197         import std.array : replace;
198         enum toString = q{class _ : superClass { T }}
199                 .replace("T",_._toString_).replace("superClass",__identifier!superClass);        
200     }
201 }
202 
203 template isInterface(alias T) {
204     enum isInterface = is(T == interface);
205 }
206 
207 mixin template _class(alias T=_indentity,alias superClass,interfaces ...) 
208 if(
209     is(superClass == class) || is(superClass == interface) 
210     && interfaces.length > 1 
211     && allSatisfy!(isInterface,interfaces)
212 ) {
213     class _ : superClass, interfaces {
214         mixin T!() _;
215         mixin _aliasThis!_;
216         static if(isConstant!(_.toString)) {
217             enum _toString_ = _.toString;            
218         } else {
219             //
220         }
221     }
222     /*static if (__traits(compiles,_._toString_)) {
223         import std.array : replace,array;
224         import std.string : join;
225         import std.meta : aliasSeqOf, staticMap;
226         enum toString = q{class _ : superClass, interfaces {T}}
227                 .replace("T",_._toString_)
228                 .replace("superClass",__identifier!superClass)
229                 .replace("interfaces",staticMap!(__identifier,interfaces).array
230         );
231     }*/
232 }
233 
234 
235 unittest {
236     mixin template _body() {
237         enum i = 10;
238         enum toString = q{enum i = 10;};
239     }
240     mixin _class!(_body) c;
241     
242     //c._ _c = new c._;
243     alias c_ = _y!c;
244     c_ _c = new c_;
245     
246     static assert (_c.i == 10);
247     mixin __msg!(c.toString);
248     static assert (c.toString == q{class _ {enum i = 10;}});
249 }
250 
251 unittest {
252     mixin template ten() {
253         enum _ = 10;
254     }
255     mixin template _body() {
256         mixin ten!() _i;
257         alias i = _y!_i;
258         
259         mixin ten!() _j;
260         alias j = _y!_j;
261         
262         mixin ten!() _k;
263         alias k = _y!_k;
264     }
265     mixin _class!(_body) c;
266     c._ _c;
267     static assert (_c.i == 10);
268     static assert (_c.j == 10);
269     static assert (_c.k == 10);
270 }
271 
272 
273 unittest {
274     mixin template _body() {
275         enum i = 10;
276         enum toString = q{enum i = 10;};
277     }
278     
279     class myBaseClass {
280         enum j = 10;
281     }
282     
283     interface myInterface0 {
284         
285     }
286     interface myInterface1 {
287         
288     }
289     mixin _class!(_body,myBaseClass,myInterface0,myInterface1) c;
290     //alias __c = c._;
291     alias __c = _y!c;
292     //c._ _c = new c._;
293     __c _c = new __c;
294     static assert (_c.i == 10);
295     static assert (_c.j == 10);
296     
297     assert (cast(myBaseClass)_c);
298     assert (cast(myInterface0)_c);
299     assert (cast(myInterface1)_c);
300 
301     //mixin __msg!(c.toString);
302 //    static assert (c.toString == q{class _ {enum i = 10;}});
303 }
304 
305 
306 
307 mixin template _constructor(alias T=_identity,V...) {
308     this(V v) {
309         mixin T!v _;
310         static if (__traits(compiles,mixin("_." ~ __identifier!T ~ "()"))) {
311             mixin("_." ~ __identifier!T ~ "();");
312         } else static if(__traits(compiles,_._)) {
313             _._();
314         }
315     };
316 }
317 
318 unittest {
319     /*mixin*/ template ten() {
320         enum _ = 10;
321     }
322     
323     mixin template __this0(alias int A,alias long B,alias string C) {
324         alias __this0 = {
325             a = A;
326             b = B;
327             c = C;
328         };
329     }
330 
331     mixin template __this1(alias int A) {
332         alias __this1 = {
333             a = A;
334         };
335     }
336 
337     mixin template _body() {
338         mixin ten!() i;
339         mixin ten!() j;
340         mixin ten!() k;
341         
342         mixin _intField!("a",5);
343         mixin _longField!("b",5);
344         mixin _stringField!("c","5");
345         //mixin _stringField!("d","7");
346         mixin _mixin_t!(_stringField,"d","7");
347         mixin _longField!("e");
348         mixin _intField!("f");
349         
350         mixin _constructor!(__this0,int,long,string);
351         mixin _constructor!(__this1,int);
352     }
353     
354     mixin _class!(_body) c;
355     
356     c._ _c = new c._(6,7,"8");
357     static assert (_c.i._ == 10);
358     static assert (_y!(_c.i) == 10);
359     static assert (_y!(_c.j) == 10);
360     static assert (_y!(_c.k) == 10);
361 
362     static assert (is(typeof(_c.a) == int));
363     static assert (is(typeof(_c.b) == long));
364     static assert (is(typeof(_c.c) == string));
365     static assert (is(typeof(_c.d) == string));
366 
367     assert (_c.a == 6);
368     assert (_c.b == 7);
369     assert (_c.c == "8");
370     assert (_c.d == "7");
371 
372     _c = new c._(7);
373     assert (_c.a == 7);
374 
375 }
376 
377 unittest {
378     /*mixin*/ template ten() {
379         enum _ = 10;
380     }
381     
382     /*mixin*/ template __this(alias int A,alias long B,alias string C) {
383         alias _ = {
384             a = A;
385             b = B;
386             c = C;
387         };
388     }
389 
390     mixin template _body() {
391         mixin ten!() i;
392         mixin ten!() j;
393         mixin ten!() k;
394         
395         mixin _intField!("a",5);
396         mixin _longField!("b",5);
397         mixin _stringField!("c","5");
398         mixin _stringField!("d");
399         mixin _longField!("e");
400         mixin _intField!("f");
401         
402         mixin _constructor!(__this,int,long,string);
403     }
404     
405     mixin _class!(_body) c;
406     
407     c._ _c = new c._(6,7,"8");
408     static assert (_c.i._ == 10);
409     static assert (_y!(_c.i) == 10);
410     static assert (_y!(_c.j) == 10);
411     static assert (_y!(_c.k) == 10);
412 
413     static assert (is(typeof(_c.a) == int));
414     static assert (is(typeof(_c.b) == long));
415     static assert (is(typeof(_c.c) == string));
416     static assert (is(typeof(_c.d) == string));
417 
418     assert (_c.a == 6);
419     assert (_c.b == 7);
420     assert (_c.c == "8");
421 }
422 
423 mixin template _fnc(alias T=_identity,U ...)
424 {
425     alias _ = (U u) {
426         mixin T!(u);
427     };
428 }
429 
430 mixin template template_(alias T=_identity,U ...)
431 {
432     alias _ = T!(U);
433 }
434 
435 
436 mixin template _template(alias T=_identity,U ...)
437 {
438     template _ (U) {
439         mixin T!();
440     }
441 }
442 
443 mixin template _mtemplate(alias T=_identity,U ...)
444 {
445     mixin template _ (U) {
446         mixin T!();
447     }
448 }
449 
450 mixin template _exitScope(alias T=_identity,alias V=_identity)
451 {
452     alias _ = () {
453         scope(exit) {
454             mixin V!();
455         }
456         mixin T!();
457     };
458 }
459 
460 mixin template exitScope(alias T=_identity,alias V=_identity)
461 {
462     alias _ = () {
463         scope(exit) {
464             V!();
465         }
466         T!();
467     };
468 }
469 
470 
471 mixin template aliasOf(string ident,alias T=identity)
472 {
473     mixin("alias " ~ ident ~ " = T;");
474 }
475 
476 unittest {
477     enum a = 0;
478     mixin aliasOf!("b",a);
479     static assert(is(typeof(b) == typeof(a)));
480     static assert(b is a);
481 }
482 
483 mixin template enumOf(string ident,alias T=identity)
484 {
485     mixin("enum " ~ ident ~ " = T;");
486     //enum toString = "enum " ~ label ~ " = " ~ __identifier!T ~ ")";
487 }
488 
489 unittest {
490     enum a = 0;
491     mixin enumOf!("b",a);
492     static assert(is(typeof(b) == typeof(a)));
493     static assert(b is a);
494 }
495 
496 mixin template enumOf(string ident,string _body)
497 {
498     mixin("enum "~ident~ " = {" ~ _body ~ "};");
499 }
500 
501 mixin template structOf(string ident,string _body) {
502     mixin("struct "~ident~ "{" ~ _body ~ "};");
503 }
504 
505 mixin template unionOf(string ident,string _body) {
506     mixin("union "~ident~ "{" ~ _body ~ "};");
507 }
508 
509 mixin template classOf(string ident,string _body) {
510     mixin("class "~ident~ "{" ~ _body ~ "};");
511 }
512