1 | {exprEqual, compiler} = require('./kit/core')
|
2 |
|
3 | describe 'expressions translator', ->
|
4 | it 'should leave pure expressions as is', ->
|
5 | exprEqual (-> 2 + 2), (-> 2 + 2)
|
6 | it 'should treat function call as effectful', ->
|
7 | exprEqual (-> eff(2); return), (-> eff(2))
|
8 | it 'should transform expressions with effectful part to mapply', ->
|
9 | exprEqual (-> console.log(2 + eff(2)); return),
|
10 | (-> M(eff(2)).mapply((b) -> console.log(2 + b); return))
|
11 | exprEqual (-> M.option({useSpread: true}); console.log(eff(1) + eff(2)); return),
|
12 | (-> M.arr([eff(1),eff(2)]).mapply(M.spread(
|
13 | ((b1,b) -> console.log(b1 + b);return))))
|
14 | exprEqual (-> console.log(eff(1) + eff(2)); return),
|
15 | """function () {
|
16 | return M.arr([
|
17 | eff(1),
|
18 | eff(2)
|
19 | ]).mapply(function (a) {
|
20 | var b1 = a[0], b = a[1];
|
21 | console.log(b1 + b);
|
22 | });
|
23 | }"""
|
24 | it 'should transform nested effectful expressions to bind', ->
|
25 | exprEqual (-> eff(effb(2)); return), (-> M(effb(2)).mbind(eff))
|
26 | it 'should use mapply for pure function calls if possible', ->
|
27 | exprEqual(
|
28 | -> console.log(eff(1), 2); return,
|
29 | -> M(eff(1)).mapply((b) -> console.log(b, 2);return))
|
30 | exprEqual(
|
31 | -> M.option({useSpread: true}); console.log(eff(1), 2) + eff(2) * 2; return,
|
32 | -> M.arr([eff(1),eff(2)]).mapply(M.spread(
|
33 | (b1,b) -> console.log(b1, 2) + b * 2; return)))
|
34 | exprEqual(
|
35 | -> console.log(eff(1), 2) + eff(2) * 2; return,
|
36 | """function () {
|
37 | return M.arr([
|
38 | eff(1),
|
39 | eff(2)
|
40 | ]).mapply(function (a) {
|
41 | var b1 = a[0], b = a[1];
|
42 | console.log(b1, 2) + b * 2;
|
43 | });
|
44 | }""")
|
45 | exprEqual(
|
46 | -> M.option({useSpread: true}); console.log(eff(1), eff(2), 2); return,
|
47 | -> M.arr([eff(1),eff(2)]).mapply(M.spread(
|
48 | (b1, b) -> console.log(b1, b, 2); return)))
|
49 | exprEqual(
|
50 | -> console.log(eff(1), eff(2), 2); return,
|
51 | """function () {
|
52 | return M.arr([
|
53 | eff(1),
|
54 | eff(2)
|
55 | ]).mapply(function (a) {
|
56 | var b1 = a[0], b = a[1];
|
57 | console.log(b1, b, 2);
|
58 | });
|
59 | }""")
|
60 | exprEqual(
|
61 | -> M.option({useSpread: true}); console.log(eff(1) + eff(2), 2); return,
|
62 | -> M.arr([eff(1),eff(2)]).mapply(M.spread((b1, b) -> console.log(b1 + b, 2); return)))
|
63 | exprEqual(
|
64 | -> console.log(eff(1) + eff(2), 2); return,
|
65 | """function () {
|
66 | return M.arr([
|
67 | eff(1),
|
68 | eff(2)
|
69 | ]).mapply(function (a) {
|
70 | var b1 = a[0], b = a[1];
|
71 | console.log(b1 + b, 2);
|
72 | });
|
73 | }""")
|
74 | it 'should convert effectful callee into a bind', ->
|
75 | exprEqual(
|
76 | -> M.option({useSpread: true}); effC(eff(1),eff(2)); return
|
77 | """function () {
|
78 | return M.arr([
|
79 | eff(1),
|
80 | eff(2)
|
81 | ]).mbind(M.spread(effC));
|
82 | }""")
|
83 | exprEqual(
|
84 | -> effC(eff(1),eff(2)); return
|
85 | """function () {
|
86 | return M.arr([
|
87 | eff(1),
|
88 | eff(2)
|
89 | ]).mbind(M.spread(effC));
|
90 | }""")
|
91 | exprEqual(
|
92 | -> M.option({useSpread: "never"}); effC(eff(1),eff(2)); return
|
93 | """function () {
|
94 | return M.arr([
|
95 | eff(1),
|
96 | eff(2)
|
97 | ]).mbind(function (a) {
|
98 | var a1 = a[0], a2 = a[1], a3 = a[2];
|
99 | return effC(a1, a2, a3);
|
100 | });
|
101 | }""")
|
102 | exprEqual(
|
103 | -> M.option({useSpread: true}); eff(1)(eff(2)); return
|
104 | -> M.arr([eff(1),eff(2)]).mbind(M.spread((b1,b) -> b1(b))))
|
105 | exprEqual(
|
106 | -> M.option({useSpread: "never"}); eff(1)(eff(2)); return
|
107 | """function () {
|
108 | return M.arr([
|
109 | eff(1),
|
110 | eff(2)
|
111 | ]).mbind(function (a) {
|
112 | var b1 = a[0], b = a[1];
|
113 | return b1(b);
|
114 | });
|
115 | }""")
|
116 | exprEqual(
|
117 | -> eff(1)(eff(2)); return
|
118 | """function () {
|
119 | return M.arr([
|
120 | eff(1),
|
121 | eff(2)
|
122 | ]).mbind(function (a) {
|
123 | var b1 = a[0], b = a[1];
|
124 | return b1(b);
|
125 | });
|
126 | }""")
|
127 | exprEqual(
|
128 | -> M.option({useSpread: true}); eff(1)(eff(2)(eff(3))); return
|
129 | -> M.arr([eff(1),M.arr([eff(2),eff(3)]).mbind(M.spread((b1, b) -> b1(b)))]).mbind(M.spread (b3,b2) -> b3(b2)))
|
130 | exprEqual(
|
131 | -> eff(1)(eff(2)(eff(3))); return
|
132 | """function () {
|
133 | return M.arr([
|
134 | eff(1),
|
135 | M.arr([
|
136 | eff(2),
|
137 | eff(3)
|
138 | ]).mbind(function (a) {
|
139 | var b1 = a[0], b = a[1];
|
140 | return b1(b);
|
141 | })
|
142 | ]).mbind(function (a) {
|
143 | var b3 = a[0], b2 = a[1];
|
144 | return b3(b2);
|
145 | });
|
146 | }""")
|
147 | exprEqual(
|
148 | -> M.option({useSpread: true}); eff(1)(eff(2),eff(3),4); return
|
149 | -> M.arr([eff(1),eff(2),eff(3)]).mbind(M.spread((b2, b1, b) -> b2(b1, b, 4))))
|
150 | exprEqual(
|
151 | -> eff(1)(eff(2),eff(3),4); return
|
152 | """function () {
|
153 | return M.arr([
|
154 | eff(1),
|
155 | eff(2),
|
156 | eff(3)
|
157 | ]).mbind(function (a) {
|
158 | var b2 = a[0], b1 = a[1], b = a[2];
|
159 | return b2(b1, b, 4);
|
160 | });
|
161 | }""")
|
162 | it 'should combine bind in mapplys accordingly', ->
|
163 | exprEqual(
|
164 | -> M.option({useSpread: true}); 5 + eff(effb(2)) + effc(3); return
|
165 | -> M.arr([M(effb(2)).mbind(eff),effc(3)]).mapply(M.spread(
|
166 | (b2, b) -> 5 + b2 + b; return)))
|
167 | exprEqual(
|
168 | -> 5 + eff(effb(2)) + effc(3); return
|
169 | """function () {
|
170 | return M.arr([
|
171 | M(effb(2)).mbind(eff),
|
172 | effc(3)
|
173 | ]).mapply(function (a) {
|
174 | var b2 = a[0], b = a[1];
|
175 | 5 + b2 + b;
|
176 | });
|
177 | }""")
|
178 | exprEqual(
|
179 | -> M.option({useSpread: true}); eff(1)(eff(2) + 2); return
|
180 | -> M.arr([eff(1),eff(2)]).mbind(M.spread((b1, b) -> b1(b + 2))))
|
181 | exprEqual(
|
182 | -> eff(1)(eff(2) + 2); return
|
183 | """function () {
|
184 | return M.arr([
|
185 | eff(1),
|
186 | eff(2)
|
187 | ]).mbind(function (a) {
|
188 | var b1 = a[0], b = a[1];
|
189 | return b1(b + 2);
|
190 | });
|
191 | }""")
|
192 | exprEqual(
|
193 | -> M.option({useSpread: true}); 5 + effc(3) + eff(effb(2) + 4); return
|
194 | -> M.arr([effc(3),M(effb(2)).mbind((b) -> eff(b + 4))]).mapply(M.spread(
|
195 | (b2, b1) -> 5 + b2 + b1; return)))
|
196 | exprEqual(
|
197 | -> 5 + effc(3) + eff(effb(2) + 4); return
|
198 | """function () {
|
199 | return M.arr([
|
200 | effc(3),
|
201 | M(effb(2)).mbind(function (b) {
|
202 | return eff(b + 4);
|
203 | })
|
204 | ]).mapply(function (a) {
|
205 | var b2 = a[0], b1 = a[1];
|
206 | 5 + b2 + b1;
|
207 | });
|
208 | }""")
|
209 | it 'should keep pure statements block in a single function', ->
|
210 | exprEqual(
|
211 | ->
|
212 | console.log(eff("1"),3)
|
213 | console.log("2")
|
214 | console.log("3")
|
215 | ->
|
216 | M(eff("1")).mapply (b) ->
|
217 | console.log(b,3)
|
218 | console.log("2")
|
219 | console.log('3'))
|
220 | exprEqual(
|
221 | ->
|
222 | M.option({useSpread: true})
|
223 | console.log(eff("1"),eff(2),3)
|
224 | console.log("4")
|
225 | ->
|
226 | M.arr([eff("1"),eff(2)]).mapply(M.spread((b1,b)->
|
227 | console.log(b1,b,3)
|
228 | console.log("4"))))
|
229 | exprEqual(
|
230 | ->
|
231 | console.log(eff("1"),eff(2),3)
|
232 | console.log("4")
|
233 | """function () {
|
234 | return M.arr([
|
235 | eff('1'),
|
236 | eff(2)
|
237 | ]).mapply(function (a) {
|
238 | var b1 = a[0], b = a[1];
|
239 | console.log(b1, b, 3);
|
240 | return console.log('4');
|
241 | });
|
242 | }""")
|
243 | it 'should bind current scope `this`', ->
|
244 | exprEqual(
|
245 | ->
|
246 | eff(1)
|
247 | @eff(2)
|
248 | eff3(@)
|
249 | return
|
250 | """
|
251 | function () {
|
252 | var _this = this;
|
253 | return M(eff(1)).mbind(function () {
|
254 | return _this.eff(2);
|
255 | }).mbind(function () {
|
256 | return eff3(_this);
|
257 | });
|
258 | }""")
|
259 |
|
260 |
|