aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/target/jvm/encoding/unsigned.lux
blob: 546d4f5167944fd127bb4d6380e60c7028e72237 (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
(.module:
  [library
   [lux (#- nat)
    [abstract
     [equivalence (#+ Equivalence)]
     [order (#+ Order)]]
    [control
     ["." try (#+ Try)]
     ["." exception (#+ exception:)]]
    [data
     [text
      ["%" format (#+ format)]]
     ["." format #_
      ["#" binary (#+ Writer)]]]
    [macro
     ["." template]]
    [math
     [number
      ["n" nat]
      ["." i64]]]
    [type
     abstract]]])

(abstract: #export (Unsigned brand)
  Nat

  (def: #export value
    (-> (Unsigned Any) Nat)
    (|>> :representation))

  (implementation: #export equivalence
    (All [brand] (Equivalence (Unsigned brand)))
    (def: (= reference sample)
      (n.= (:representation reference)
           (:representation sample))))

  (implementation: #export order
    (All [brand] (Order (Unsigned brand)))
    
    (def: &equivalence ..equivalence)
    (def: (< reference sample)
      (n.< (:representation reference)
           (:representation sample))))

  (exception: #export (value_exceeds_the_maximum {type Name}
                                                 {value Nat}
                                                 {maximum (Unsigned Any)})
    (exception.report
     ["Type" (%.name type)]
     ["Value" (%.nat value)]
     ["Maximum" (%.nat (:representation maximum))]))

  (exception: #export [brand] (subtraction_cannot_yield_negative_value
                               {type Name}
                               {parameter (Unsigned brand)}
                               {subject (Unsigned brand)})
    (exception.report
     ["Type" (%.name type)]
     ["Parameter" (%.nat (:representation parameter))]
     ["Subject" (%.nat (:representation subject))]))

  (template [<bytes> <name> <size> <constructor> <maximum> <+> <-> <max>]
    [(with_expansions [<raw> (template.identifier [<name> "'"])]
       (abstract: #export <raw> Any)
       (type: #export <name> (Unsigned <raw>)))

     (def: #export <size> <bytes>)
     
     (def: #export <maximum>
       <name>
       (|> <bytes> (n.* i64.bits_per_byte) i64.mask :abstraction))
     
     (def: #export (<constructor> value)
       (-> Nat (Try <name>))
       (if (n.<= (:representation <maximum>) value)
         (#try.Success (:abstraction value))
         (exception.except ..value_exceeds_the_maximum [(name_of <name>) value <maximum>])))

     (def: #export (<+> parameter subject)
       (-> <name> <name> (Try <name>))
       (<constructor>
        (n.+ (:representation parameter)
             (:representation subject))))

     (def: #export (<-> parameter subject)
       (-> <name> <name> (Try <name>))
       (let [parameter' (:representation parameter)
             subject' (:representation subject)]
         (if (n.<= subject' parameter')
           (#try.Success (:abstraction (n.- parameter' subject')))
           (exception.except ..subtraction_cannot_yield_negative_value [(name_of <name>) parameter subject]))))

     (def: #export (<max> left right)
       (-> <name> <name> <name>)
       (:abstraction (n.max (:representation left)
                            (:representation right))))]

    [1 U1 bytes/1 u1 maximum/1 +/1 -/1 max/1]
    [2 U2 bytes/2 u2 maximum/2 +/2 -/2 max/2]
    [4 U4 bytes/4 u4 maximum/4 +/4 -/4 max/4]
    )

  (template [<name> <from> <to>]
    [(def: #export <name>
       (-> <from> <to>)
       (|>> :transmutation))]

    [lift/2 U1 U2]
    [lift/4 U2 U4]
    )

  (template [<writer_name> <type> <writer>]
    [(def: #export <writer_name>
       (Writer <type>)
       (|>> :representation <writer>))]

    [writer/1 U1 format.bits/8]
    [writer/2 U2 format.bits/16]
    [writer/4 U4 format.bits/32]
    )
  )