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 (-> 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 | it 'should transform nested effectful expressions to bind', ->
|
15 | exprEqual (-> eff(effb(2)); return), (-> M(effb(2)).mbind(eff))
|
16 | it 'should use mapply for pure function calls if possible', ->
|
17 | exprEqual(
|
18 | -> console.log(eff(1), 2); return,
|
19 | -> M(eff(1)).mapply((b) -> console.log(b, 2);return))
|
20 | exprEqual(
|
21 | -> console.log(eff(1), 2) + eff(2) * 2; return,
|
22 | -> M.arr([eff(1),eff(2)]).mapply(M.spread(
|
23 | (b1,b) -> console.log(b1, 2) + b * 2; return)))
|
24 | exprEqual(
|
25 | -> console.log(eff(1), eff(2), 2); return,
|
26 | -> M.arr([eff(1),eff(2)]).mapply(M.spread(
|
27 | (b1, b) -> console.log(b1, b, 2); return)))
|
28 | exprEqual(
|
29 | -> console.log(eff(1) + eff(2), 2); return,
|
30 | -> M.arr([eff(1),eff(2)]).mapply(M.spread((b1, b) -> console.log(b1 + b, 2); return)))
|
31 | it 'should convert effectful callee into a bind', ->
|
32 | exprEqual(
|
33 | -> eff(1)(eff(2)); return
|
34 | -> M.arr([eff(1),eff(2)]).mbind(M.spread((b1,b) -> b1(b))))
|
35 | exprEqual(
|
36 | -> eff(1)(eff(2)(eff(3))); return
|
37 | -> M.arr([eff(1),M.arr([eff(2),eff(3)]).mbind(M.spread((b1, b) -> b1(b)))]).mbind(M.spread (b3,b2) -> b3(b2)))
|
38 | exprEqual(
|
39 | -> eff(1)(eff(2),eff(3),4); return
|
40 | -> M.arr([eff(1),eff(2),eff(3)]).mbind(M.spread((b2, b1, b) -> b2(b1, b, 4))))
|
41 | it 'should combine bind in mapplys accordingly', ->
|
42 | exprEqual(
|
43 | -> 5 + eff(effb(2)) + effc(3); return
|
44 | -> M.arr([M(effb(2)).mbind(eff),effc(3)]).mapply(M.spread(
|
45 | (b2, b) -> 5 + b2 + b; return)))
|
46 | exprEqual(
|
47 | -> eff(1)(eff(2) + 2); return
|
48 | -> M.arr([eff(1),eff(2)]).mbind(M.spread((b1, b) -> b1(b + 2))))
|
49 | exprEqual(
|
50 | -> 5 + effc(3) + eff(effb(2) + 4); return
|
51 | -> M.arr([effc(3),M(effb(2)).mbind((b) -> eff(b + 4))]).mapply(M.spread(
|
52 | (b2, b1) -> 5 + b2 + b1; return)))
|
53 | it 'should keep pure statements block in a single function', ->
|
54 | exprEqual(
|
55 | ->
|
56 | console.log(eff("1"),3)
|
57 | console.log("2")
|
58 | console.log("3")
|
59 | ->
|
60 | M(eff("1")).mapply (b) ->
|
61 | console.log(b,3)
|
62 | console.log("2")
|
63 | console.log('3'))
|
64 | exprEqual(
|
65 | ->
|
66 | console.log(eff("1"),eff(2),3)
|
67 | console.log("4")
|
68 | ->
|
69 | M.arr([eff("1"),eff(2)]).mapply(M.spread((b1,b)->
|
70 | console.log(b1,b,3)
|
71 | console.log("4"))))
|
72 | it 'should bind current scope `this`', ->
|
73 | exprEqual(
|
74 | ->
|
75 | eff(1)
|
76 | @eff(2)
|
77 | eff3(@)
|
78 | return
|
79 | """
|
80 | function () {
|
81 | var _this = this;
|
82 | return M(eff(1)).mbind(function () {
|
83 | return _this.eff(2);
|
84 | }).mbind(function () {
|
85 | return eff3(_this);
|
86 | });
|
87 | }""")
|
88 |
|
89 |
|