aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/generation/js/host.lux
blob: edc4e2321afd7cef8fe20fb32ceffac428bb5655 (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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
(.module:
  [library
   [lux #*
    [abstract
     ["." monad (#+ do)]]
    [control
     ["." function]
     ["<>" parser
      ["<s>" synthesis (#+ Parser)]]]
    [data
     [collection
      ["." dictionary]
      ["." list]]]
    [target
     ["_" js (#+ Var Expression)]]]]
  ["." // #_
   ["#." common (#+ custom)]
   ["//#" /// #_
    ["/" bundle]
    ["/#" // #_
     ["." extension]
     [generation
      [extension (#+ Nullary Unary Binary Trinary
                     nullary unary binary trinary)]
      ["//" js #_
       ["#." runtime (#+ Operation Phase Handler Bundle
                         with_vars)]]]
     ["/#" // #_
      ["." generation]
      ["//#" /// #_
       ["#." phase]]]]]])

(def: array::new
  (Unary Expression)
  (|>> (_.the //runtime.i64_low_field) list (_.new (_.var "Array"))))

(def: array::length
  (Unary Expression)
  (|>> (_.the "length") //runtime.i64//from_number))

(def: (array::read [indexG arrayG])
  (Binary Expression)
  (_.at (_.the //runtime.i64_low_field indexG)
        arrayG))

(def: (array::write [indexG valueG arrayG])
  (Trinary Expression)
  (//runtime.array//write indexG valueG arrayG))

(def: (array::delete [indexG arrayG])
  (Binary Expression)
  (//runtime.array//delete indexG arrayG))

(def: array
  Bundle
  (<| (/.prefix "array")
      (|> /.empty
          (/.install "new" (unary array::new))
          (/.install "length" (unary array::length))
          (/.install "read" (binary array::read))
          (/.install "write" (trinary array::write))
          (/.install "delete" (binary array::delete))
          )))

(def: object::new
  (custom
   [($_ <>.and <s>.any (<>.some <s>.any))
    (function (_ extension phase archive [constructorS inputsS])
      (do {! ////////phase.monad}
        [constructorG (phase archive constructorS)
         inputsG (monad.map ! (phase archive) inputsS)]
        (wrap (_.new constructorG inputsG))))]))

(def: object::get
  Handler
  (custom
   [($_ <>.and <s>.text <s>.any)
    (function (_ extension phase archive [fieldS objectS])
      (do ////////phase.monad
        [objectG (phase archive objectS)]
        (wrap (_.the fieldS objectG))))]))

(def: object::do
  Handler
  (custom
   [($_ <>.and <s>.text <s>.any (<>.some <s>.any))
    (function (_ extension phase archive [methodS objectS inputsS])
      (do {! ////////phase.monad}
        [objectG (phase archive objectS)
         inputsG (monad.map ! (phase archive) inputsS)]
        (wrap (_.do methodS inputsG objectG))))]))

(template [<!> <?> <unit>]
  [(def: <!> (Nullary Expression) (function.constant <unit>))
   (def: <?> (Unary Expression) (_.= <unit>))]

  [object::null object::null? _.null]
  [object::undefined object::undefined? _.undefined]
  )

(def: object
  Bundle
  (<| (/.prefix "object")
      (|> /.empty
          (/.install "new" object::new)
          (/.install "get" object::get)
          (/.install "do" object::do)
          (/.install "null" (nullary object::null))
          (/.install "null?" (unary object::null?))
          (/.install "undefined" (nullary object::undefined))
          (/.install "undefined?" (unary object::undefined?))
          )))

(def: js::constant
  (custom
   [<s>.text
    (function (_ extension phase archive name)
      (\ ////////phase.monad wrap (_.var name)))]))

(def: js::apply
  (custom
   [($_ <>.and <s>.any (<>.some <s>.any))
    (function (_ extension phase archive [abstractionS inputsS])
      (do {! ////////phase.monad}
        [abstractionG (phase archive abstractionS)
         inputsG (monad.map ! (phase archive) inputsS)]
        (wrap (_.apply/* abstractionG inputsG))))]))

(def: js::function
  (custom
   [($_ <>.and <s>.i64 <s>.any)
    (function (_ extension phase archive [arity abstractionS])
      (do {! ////////phase.monad}
        [abstractionG (phase archive abstractionS)
         #let [variable (: (-> Text (Operation Var))
                           (|>> generation.gensym
                                (\ ! map _.var)))]
         g!inputs (monad.map ! (function (_ _) (variable "input"))
                             (list.repeat (.nat arity) []))
         g!abstraction (variable "abstraction")]
        (wrap (_.closure g!inputs
                         ($_ _.then
                             (_.define g!abstraction abstractionG)
                             (_.return (case (.nat arity)
                                         0 (_.apply/1 g!abstraction //runtime.unit)
                                         1 (_.apply/* g!abstraction g!inputs)
                                         _ (_.apply/1 g!abstraction (_.array g!inputs)))))))))]))

(def: #export bundle
  Bundle
  (<| (/.prefix "js")
      (|> /.empty
          (dictionary.merge ..array)
          (dictionary.merge ..object)

          (/.install "constant" js::constant)
          (/.install "apply" js::apply)
          (/.install "type-of" (unary _.type_of))
          (/.install "function" js::function)
          )))