1 module yyd.arith;
2 
3 private import yyd.y : _y;
4 
5 // Arithmatic expression evaluator templates
6 
7 template num(alias A) {
8 	import std.conv : to;
9 	enum num = A.to!double;
10 }
11 
12 template add(alias A, alias B) 
13 {
14 	enum add = A + B;
15 }
16 
17 template sub(alias A, alias B) 
18 {
19 	enum sub = A - B;
20 }
21 
22 template mul(alias A, alias B) 
23 {
24 	enum mul = A * B;
25 }
26 
27 template div(alias A, alias B) 
28 {
29 	enum div = A / B;
30 }
31 
32 
33 template booleanOr(alias A, alias B) 
34 {
35 	enum booleanOr = A | B;
36 }
37 
38 template booleanAnd(alias A, alias B) 
39 {
40 	enum booleanAnd = A & B;
41 }
42 
43 template logicalOr(alias A, alias B) 
44 {
45 	enum logicalOr = A || B;
46 }
47 
48 template logicalAnd(alias A, alias B) 
49 {
50 	enum logicalAnd = A && B;
51 }
52 
53 template concat(alias A, alias B) 
54 {
55 	enum concat = A ~ B;
56 }
57 
58 template equal(alias A, alias B) 
59 {
60 	enum equal = A == B;
61 }
62 
63 template notEqual(alias A, alias B) 
64 {
65 	enum equal = A != B;
66 }
67 
68 template condExpr(alias cond, alias _if, alias _else) 
69 {
70     enum condExpr = cond ? _if : _else;
71 }
72 
73 template sum(T...) 
74 if(T.length == 0) 
75 {}
76 
77 template sum(T...) 
78 if(T.length == 1) 
79 {
80 	enum sum = T[0];
81 }
82 
83 template sum(T...) 
84 if (T.length > 1) 
85 {
86 	enum sum = add!(T[0],sum!(T[1..$]));
87 }
88 
89 unittest {
90     static assert(sum!(1,1,1) == 3);
91 }
92 
93 template concantenate(T...) if(T.length == 0) 
94 {}
95 
96 template concantenate(T...) if(T.length == 1) 
97 {    
98 	enum concantenate = T[0];
99 }
100 
101 template concantenate(T...) if(T.length > 1) 
102 {    
103 	enum concantenate = concat!(T[0],concantenate!(T[1..$]));
104 }
105 
106 unittest {
107     static assert(concantenate!("a","a","a") == "aaa");
108 }
109 
110 
111 mixin template _add(alias A, alias B) 
112 {
113 	alias _ = add!(A,B);
114 }
115 
116 mixin template _sub(alias A, alias B) 
117 {
118 	alias _ = sub!(A,B);
119 }
120 
121 mixin template _mul(alias A, alias B) 
122 {
123 	alias _ = mul!(A,B);
124 }
125 
126 mixin template _div(alias A, alias B) 
127 {
128 	alias _ = div!(A,B);
129 }
130 
131 mixin template _concat(alias A, alias B) 
132 {
133 	alias _ = concat!(A,B);
134 }
135 
136 mixin template _sum(T...) 
137 {
138 	alias _ = sum!(T);
139 }
140 
141 mixin template _concantenate(T...) 
142 {
143 	alias _ = concantenate!(T);
144 }
145 
146 
147 unittest {
148     mixin _sum!(1,1,1) t;
149     static assert (_y!t == 3);
150 }
151 
152 unittest {
153     mixin _concantenate!("a","b","c") t;
154     static assert (_y!t == "abc");
155 }
156 
157 //alias add(A,B) = (const A a, const B b) => a + b;
158 //alias sub(A,B) = (const A a, const B b) => a - b;
159 //alias mul(A,B) = (A a, B b) => a * b;
160 //alias div(A,B) = (const A a, const B b) => a / b;
161 
162 alias num_(alias A) = ()=>num!A;
163 
164 alias add_(alias A,alias B) = () => A() + B();
165 alias sub_(alias A,alias B) = () => A() - B();
166 alias mul_(alias A,alias B) = () => A() * B();
167 alias div_(alias A,alias B) = () => A() / B();
168 /*alias add_(alias A,alias B) = () => add!(A(),B());
169 alias sub_(alias A,alias B) = () => sub!(A(),B());
170 alias mul_(alias A,alias B) = () => mul!(A(),B());
171 alias div_(alias A,alias B) = () => div!(A(),B());*/
172 
173 
174 alias booleanOr_(alias A, alias B) = () => A() | B();
175 alias booleanAnd_(alias A, alias B) = () => A() & B();
176 alias logicalOr_(alias A, alias B) = () => A() || B();
177 alias logicalAnd_(alias A, alias B) = () => A() && B();
178 
179 alias concat_(alias A, alias B) = () => A() ~ B();
180 
181 alias equal_(alias A, alias B) = () => A() == B();
182 alias notEqual_(alias A, alias B) = () => A() != B();
183 
184 alias condExpr_(alias Cond, alias _If, alias _Else) = () => Cond() ? _If() : _Else();
185 
186 
187 //>>>>>>> 1dc31e79c7b78aaf2df32d1da084fb03933134db
188 
189 //alias add(A,B) = (const A function() a,const B function() b) => add!(a,b);
190 
191 //alias sub(A,B) = (const A function() a,const B function() b) => sub!(a,b);
192 
193 //alias mul(A,B) = (const A function() a,const B function() b) => mul!(a,b);
194 
195 //alias div(A,B) = (const A function() a,const B function() b) => div!(a,b);
196 
197 template addTo(alias T) 
198 {
199 	alias addTo(V) = () => T += V;
200 }
201 
202 template addToX(alias T) 
203 {
204 	alias addToX(V) = (V v) => T += v;
205 }
206 
207 mixin template _addTo(alias T,alias V) 
208 {
209 	alias _ = addTo!(T,V);
210 }
211