aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/tool/compiler/phase/generation/reference.lux
blob: 878d96e83714ef0d3de8d5265943d48c50e18387 (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
(.module:
  [lux #*
   [control
    pipe]
   [data
    [text
     format]]
   [type (#+ :share)]]
  ["." //
   ["/." // ("#/." monad)
    [//
     [synthesis (#+ Synthesis)]
     ["." reference (#+ Register Variable Reference)]]]])

(signature: #export (System expression)
  (: (-> Register expression)
     local)
  (: (-> Register expression)
     foreign)
  (: (All [anchor statement]
       (-> Variable (//.Operation anchor expression statement)))
     variable)
  (: (All [anchor statement]
       (-> Name (//.Operation anchor expression statement)))
     constant)
  (: (All [anchor statement]
       (-> Reference (//.Operation anchor expression statement)))
     reference))

(def: (variable-maker prefix variable)
  (All [expression]
    (-> Text (-> Text expression)
        (-> Register expression)))
  (|>> %n (format prefix) variable))

(def: #export foreign
  (All [expression]
    (-> (-> Text expression)
        (-> Register expression)))
  (variable-maker "f"))

(def: #export local
  (All [expression]
    (-> (-> Text expression)
        (-> Register expression)))
  (variable-maker "l"))

(def: #export (system constant variable)
  (All [expression]
    (-> (-> Text expression) (-> Text expression)
        (System expression)))
  (let [local (..local variable)
        foreign (..foreign variable)
        variable (:share [expression]
                         {(-> Text expression)
                          variable}
                         {(All [anchor statement]
                            (-> Variable (//.Operation anchor expression statement)))
                          (|>> (case> (#reference.Local register)
                                      (local register)
                                      
                                      (#reference.Foreign register)
                                      (foreign register))
                               ////wrap)})
        constant (:share [expression]
                         {(-> Text expression)
                          constant}
                         {(All [anchor statement]
                            (-> Name (//.Operation anchor expression statement)))
                          (|>> //.remember (////map constant))})]
    (structure
     (def: local local)
     (def: foreign foreign)
     (def: variable variable)
     (def: constant constant)
     (def: reference
       (|>> (case> (#reference.Constant value)
                   (constant value)
                   
                   (#reference.Variable value)
                   (variable value)))))))