aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/tool/compiler/language/lux/analysis/pattern.lux
blob: f198494adb9c348ef8395709bea15f5f08f75476 (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
(.require
 [library
  [lux (.except nat int rev)
   [abstract
    [equivalence (.only Equivalence)]]
   [data
    [text
     ["%" \\format]]]
   [math
    [number
     ["n" nat]]]]]
 ["[0]" //
  ["[1][0]" simple (.only Simple)]
  ["[1][0]" complex (.only Complex)]
  [////
   [reference
    ["[1][0]" variable (.only Register)]]]])

(type: .public Pattern
  (Rec Pattern
    (.Variant
     {#Simple Simple}
     {#Complex (Complex Pattern)}
     {#Bind Register})))

(def .public equivalence
  (Equivalence Pattern)
  (implementation
   (def (= reference sample)
     (case [reference sample]
       [{#Simple reference} {#Simple sample}]
       (at //simple.equivalence = reference sample)
       
       [{#Complex reference} {#Complex sample}]
       (at (//complex.equivalence =) = reference sample)

       [{#Bind reference} {#Bind sample}]
       (n.= reference sample)

       _
       false))))

(def .public (format it)
  (%.Format Pattern)
  (case it
    {#Simple it}
    (//simple.format it)
    
    {#Complex it}
    (//complex.format format it)
    
    {#Bind it}
    (//variable.format {//variable.#Local it})))

(with_template [<name> <tag>]
  [(def .public <name>
     (template (<name> content)
       [(.<| {..#Complex}
             <tag>
             content)]))]

  [variant {//complex.#Variant}]
  [tuple   {//complex.#Tuple}]
  )

(def .public unit
  (template (unit)
    [{..#Simple {//simple.#Unit}}]))

(with_template [<name> <tag>]
  [(def .public <name>
     (template (<name> content)
       [{..#Simple {<tag> content}}]))]
  
  [bit  //simple.#Bit]
  [nat  //simple.#Nat]
  [int  //simple.#Int]
  [rev  //simple.#Rev]
  [frac //simple.#Frac]
  [text //simple.#Text]
  )

(def .public bind
  (template (bind register)
    [{..#Bind register}]))