aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/target/jvm/encoding/signed.lux
blob: 160141e3b370209f36d77bd595cd70f1f6c3d1d7 (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
(.using
 [library
  [lux {"-" int}
   [abstract
    [equivalence {"+" Equivalence}]
    [order {"+" Order}]]
   [control
    ["[0]" try {"+" Try}]
    ["[0]" exception {"+" exception:}]]
   [data
    [text
     ["%" format {"+" format}]]
    ["[0]" format "_"
     ["[1]" binary {"+" Writer}]]]
   [macro
    ["[0]" template]]
   [math
    [number
     ["[0]" i64]
     ["n" nat]
     ["i" int]]]
   [type
    [abstract {"-" pattern}]]]])

(abstract: .public (Signed brand)
  Int

  (def: .public value
    (-> (Signed Any) Int)
    (|>> representation))

  (implementation: .public equivalence
    (All (_ brand) (Equivalence (Signed brand)))
    (def: (= reference sample)
      (i.= (representation reference) (representation sample))))

  (implementation: .public order
    (All (_ brand) (Order (Signed brand)))
    
    (def: &equivalence ..equivalence)
    (def: (< reference sample)
      (i.< (representation reference) (representation sample))))

  (exception: .public (value_exceeds_the_scope [value Int
                                                scope Nat])
    (exception.report
     "Value" (%.int value)
     "Scope (in bytes)" (%.nat scope)))

  (template [<bytes> <name> <size> <constructor> <maximum> <minimum> <+> <->]
    [(with_expansions [<raw> (template.symbol [<name> "'"])]
       (abstract: <raw> Any)
       (type: .public <name> (Signed <raw>)))

     (def: .public <size> <bytes>)
     
     (def: .public <maximum>
       <name>
       (|> <bytes> (n.* i64.bits_per_byte) -- i64.mask abstraction))

     (def: .public <minimum>
       <name>
       (let [it (representation <maximum>)]
         (abstraction (-- (i.- it +0)))))
     
     (def: .public <constructor>
       (-> Int (Try <name>))
       (let [positive (representation <maximum>)
             negative (i64.not positive)]
         (function (_ value)
           (if (i.= (if (i.< +0 value)
                      (i64.or negative value)
                      (i64.and positive value))
                    value)
             {try.#Success (abstraction value)}
             (exception.except ..value_exceeds_the_scope [value <size>])))))

     (template [<abstract_operation> <concrete_operation>]
       [(def: .public (<abstract_operation> parameter subject)
          (-> <name> <name> (Try <name>))
          (<constructor>
           (<concrete_operation> (representation parameter)
                                 (representation subject))))]

       [<+> i.+]
       [<-> i.-]
       )]

    [1 S1 bytes/1 s1 maximum/1 minimum/1 +/1 -/1]
    [2 S2 bytes/2 s2 maximum/2 minimum/2 +/2 -/2]
    [4 S4 bytes/4 s4 maximum/4 minimum/4 +/4 -/4]
    )

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

    [lifted/2 S1 S2]
    [lifted/4 S2 S4]
    )

  (template [<writer_name> <type> <writer>]
    [(def: .public <writer_name>
       (Writer <type>)
       (|>> representation <writer>))]

    [writer/1 S1 format.bits_8]
    [writer/2 S2 format.bits_16]
    [writer/4 S4 format.bits_32]
    )
  )