aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/tool/compiler/phase/translation/common/reference.lux
blob: af676ad854656d5a354f50a52525d6cf350f44b5 (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
(.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)))))))