aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/lux/compiler/default/phase/synthesis/case.lux
blob: 319d4ab573f45d3da915265f26613225d1e39157 (plain)
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
(.module:
  [lux #*
   [control
    [monad (#+ do)]
    pipe]
   [data
    ["." error ("error/." functor)]]
   [compiler
    [default
     ["." reference]
     ["." phase
      ["." analysis (#+ Branch Analysis)]
      ["//" synthesis (#+ Synthesis)
       ["." expression]]
      [extension
       ["." bundle]]]]]
   [math
    ["r" random]]
   test]
  ["." //primitive])

(context: "Dummy variables."
  (<| (times 100)
      (do @
        [maskedA //primitive.primitive
         temp (|> r.nat (:: @ map (n/% 100)))
         #let [maskA (analysis.control/case
                      [maskedA
                       [[(#analysis.Bind temp)
                         (#analysis.Reference (reference.local temp))]
                        (list)]])]]
        (test "Dummy variables created to mask expressions get eliminated during synthesis."
              (|> maskA
                  expression.phase
                  (phase.run [bundle.empty //.init])
                  (error/map (//primitive.corresponds? maskedA))
                  (error.default #0))))))

(context: "Let expressions."
  (<| (times 100)
      (do @
        [registerA r.nat
         inputA //primitive.primitive
         outputA //primitive.primitive
         #let [letA (analysis.control/case
                     [inputA
                      [[(#analysis.Bind registerA)
                        outputA]
                       (list)]])]]
        (test "Can detect and reify simple 'let' expressions."
              (|> letA
                  expression.phase
                  (phase.run [bundle.empty //.init])
                  (case> (^ (#error.Success (//.branch/let [inputS registerS outputS])))
                         (and (n/= registerA registerS)
                              (//primitive.corresponds? inputA inputS)
                              (//primitive.corresponds? outputA outputS))

                         _
                         #0))))))

(context: "If expressions."
  (<| (times 100)
      (do @
        [then|else r.bit
         inputA //primitive.primitive
         thenA //primitive.primitive
         elseA //primitive.primitive
         #let [thenB (: Branch
                        [(#analysis.Simple (#analysis.Bit #1))
                         thenA])
               elseB (: Branch
                        [(#analysis.Simple (#analysis.Bit #0))
                         elseA])
               ifA (if then|else
                     (analysis.control/case [inputA [thenB (list elseB)]])
                     (analysis.control/case [inputA [elseB (list thenB)]]))]]
        (test "Can detect and reify simple 'if' expressions."
              (|> ifA
                  expression.phase
                  (phase.run [bundle.empty //.init])
                  (case> (^ (#error.Success (//.branch/if [inputS thenS elseS])))
                         (and (//primitive.corresponds? inputA inputS)
                              (//primitive.corresponds? thenA thenS)
                              (//primitive.corresponds? elseA elseS))

                         _
                         #0))))))