aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/target/jvm/type.lux
blob: d8b21a829e58945fcc37358cb7c61636a20582e6 (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
161
162
163
164
165
166
(.module:
  [lux (#- Type int char)
   [abstract
    [equivalence (#+ Equivalence)]]
   [data
    ["." maybe]
    ["." text]
    [number
     ["n" nat]]
    [collection
     ["." list ("#@." functor)]]]
   [type
    abstract]]
  ["." // #_
   [encoding
    ["#." name (#+ External)]]]
  ["." / #_
   [category (#+ Void Value Return Method Primitive Object Class Array Var Parameter)]
   ["#." signature (#+ Signature)]
   ["#." descriptor (#+ Descriptor)]
   ["#." reflection (#+ Reflection)]])

(abstract: #export (Type category)
  {}

  [(Signature category) (Descriptor category) (Reflection category)]

  (type: #export Argument
    [Text (Type Value)])

  (type: #export (Typed a)
    [(Type Value) a])

  (type: #export Constraint
    {#name Text
     #super-class (Type Class)
     #super-interfaces (List (Type Class))})
  
  (template [<name> <style>]
    [(def: #export (<name> type)
       (All [category] (-> (Type category) (<style> category)))
       (let [[signature descriptor reflection] (:representation type)]
         <name>))]

    [signature Signature]
    [descriptor Descriptor]
    [reflection Reflection]
    )

  (template [<category> <name> <signature> <descriptor> <reflection>]
    [(def: #export <name>
       (Type <category>)
       (:abstraction [<signature> <descriptor> <reflection>]))]

    [Void void /signature.void /descriptor.void /reflection.void]
    [Primitive boolean /signature.boolean /descriptor.boolean /reflection.boolean]
    [Primitive byte /signature.byte /descriptor.byte /reflection.byte]
    [Primitive short /signature.short /descriptor.short /reflection.short]
    [Primitive int /signature.int /descriptor.int /reflection.int]
    [Primitive long /signature.long /descriptor.long /reflection.long]
    [Primitive float /signature.float /descriptor.float /reflection.float]
    [Primitive double /signature.double /descriptor.double /reflection.double]
    [Primitive char /signature.char /descriptor.char /reflection.char]
    )

  (def: #export (array type)
    (-> (Type Value) (Type Array))
    (:abstraction
     [(/signature.array (..signature type))
      (/descriptor.array (..descriptor type))
      (/reflection.array (..reflection type))]))

  (def: #export (class name parameters)
    (-> External (List (Type Parameter)) (Type Class))
    (:abstraction
     [(/signature.class name (list@map ..signature parameters))
      (/descriptor.class name)
      (/reflection.class name)]))

  (def: #export wildcard
    (Type Parameter)
    (:abstraction
     [/signature.wildcard
      /descriptor.wildcard
      /reflection.wildcard]))

  (def: #export (var name)
    (-> Text (Type Var))
    (:abstraction
     [(/signature.var name)
      /descriptor.var
      /reflection.var]))

  (def: #export (lower bound)
    (-> (Type Class) (Type Parameter))
    (:abstraction
     [(/signature.lower (..signature bound))
      (/descriptor.lower (..descriptor bound))
      (/reflection.lower (..reflection bound))]))

  (def: #export (upper bound)
    (-> (Type Class) (Type Parameter))
    (:abstraction
     [(/signature.upper (..signature bound))
      (/descriptor.upper (..descriptor bound))
      (/reflection.upper (..reflection bound))]))

  (def: #export (method [inputs output exceptions])
    (-> [(List (Type Value))
         (Type Return)
         (List (Type Class))]
        [(Signature Method)
         (Descriptor Method)])
    [(/signature.method [(list@map ..signature inputs)
                         (..signature output)
                         (list@map ..signature exceptions)])
     (/descriptor.method [(list@map ..descriptor inputs)
                          (..descriptor output)])])

  (structure: #export equivalence
    (All [category] (Equivalence (Type category)))

    (def: (= parameter subject)
      (:: /signature.equivalence =
          (..signature parameter)
          (..signature subject))))

  (def: #export (primitive? type)
    (-> (Type Value) (Either (Type Object)
                             (Type Primitive)))
    (if (`` (or (~~ (template [<type>]
                      [(:: ..equivalence = (: (Type Value) <type>) type)]
                      
                      [..boolean]
                      [..byte]
                      [..short]
                      [..int]
                      [..long]
                      [..float]
                      [..double]
                      [..char]))))
      (|> type (:coerce (Type Primitive)) #.Right)
      (|> type (:coerce (Type Object)) #.Left)))

  (def: #export (void? type)
    (-> (Type Return) (Either (Type Value)
                              (Type Void)))
    (if (`` (or (~~ (template [<type>]
                      [(:: ..equivalence = (: (Type Return) <type>) type)]
                      
                      [..void]))))
      (|> type (:coerce (Type Void)) #.Right)
      (|> type (:coerce (Type Value)) #.Left)))
  )

(def: #export (class? type)
  (-> (Type Value) (Maybe External))
  (let [repr (|> type ..descriptor /descriptor.descriptor)]
    (if (and (text.starts-with? /descriptor.class-prefix repr)
             (text.ends-with? /descriptor.class-suffix repr))
      (|> repr
          (text.clip (text.size /descriptor.class-prefix)
                     (n.- (text.size /descriptor.class-suffix)
                          (text.size repr)))
          (:: maybe.monad map (|>> //name.internal //name.external)))
      #.None)))