aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/meta/compiler/target/jvm/encoding/unsigned.lux
blob: afd21a166d7421be8065b79cb3eb357ebe8ba794 (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
(.require
 [library
  [lux (.except nat)
   [abstract
    [equivalence (.only Equivalence)]
    [order (.only Order)]]
   [control
    ["[0]" try (.only Try)]
    ["[0]" exception (.only Exception)]]
   [data
    [text
     ["%" \\format (.only format)]]
    [binary
     ["[0]" \\format (.only Format)]]]
   [math
    [number
     ["n" nat]
     ["[0]" i64]]]
   [meta
    [macro
     ["[0]" template]]
    [type
     ["[0]" nominal (.except def)]]]]])

(nominal.def .public (Unsigned brand)
  Nat

  (def .public value
    (-> (Unsigned Any) Nat)
    (|>> representation))

  (def .public equivalence
    (All (_ brand) (Equivalence (Unsigned brand)))
    (implementation
     (def (= reference sample)
       (n.= (representation reference)
            (representation sample)))))

  (def .public order
    (All (_ brand) (Order (Unsigned brand)))
    (implementation
     (def equivalence ..equivalence)
     (def (< reference sample)
       (n.< (representation reference)
            (representation sample)))))

  (exception.def .public (value_exceeds_the_maximum [type value maximum])
    (Exception [Symbol Nat (Unsigned Any)])
    (exception.report
     (list ["Type" (%.symbol type)]
           ["Value" (%.nat value)]
           ["Maximum" (%.nat (representation maximum))])))

  (exception.def .public (subtraction_cannot_yield_negative_value [type parameter subject])
    (All (_ brand) (Exception [Symbol (Unsigned brand) (Unsigned brand)]))
    (exception.report
     (list ["Type" (%.symbol type)]
           ["Parameter" (%.nat (representation parameter))]
           ["Subject" (%.nat (representation subject))])))

  (with_template [<bytes> <name> <size> <constructor> <maximum> <+> <-> <max>]
    [(with_expansions [<raw> (template.symbol [<name> "'"])]
       (nominal.def .public <raw> Any)
       (type .public <name> (Unsigned <raw>)))

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

     (def .public (<+> parameter subject)
       (-> <name> <name> (Try <name>))
       (<constructor>
        (n.+ (representation parameter)
             (representation subject))))

     (def .public (<-> parameter subject)
       (-> <name> <name> (Try <name>))
       (let [parameter' (representation parameter)
             subject' (representation subject)]
         (if (n.> subject' parameter')
           (exception.except ..subtraction_cannot_yield_negative_value [(symbol <name>) parameter subject])
           {try.#Success (abstraction (n.- parameter' subject'))})))

     (def .public (<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]
    )

  (with_template [<name> <from> <to>]
    [(def .public <name>
       (-> <from> <to>)
       (|>> transmutation))]

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

  (with_template [<format_name> <type> <format>]
    [(def .public <format_name>
       (Format <type>)
       (|>> representation <format>))]

    [format/1 U1 \\format.bits_8]
    [format/2 U2 \\format.bits_16]
    [format/4 U4 \\format.bits_32]
    )
  )