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

(abstract: #export (Signed brand)
  Int

  (def: #export value
    (-> (Signed Any) Int)
    (|>> :representation))

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

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

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

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

     (def: #export <size> <bytes>)
     
     (def: #export <maximum>
       <name>
       (|> <bytes> (n.* i64.bits_per_byte) dec i64.mask :abstraction))
     
     (def: #export <constructor>
       (-> Int (Try <name>))
       (let [positive (|> <bytes> (n.* i64.bits_per_byte) i64.mask)
             negative (|> positive .int (i.right_shift 1) i64.not)]
         (function (_ value)
           (if (i.= (if (i.< +0 value)
                      (i64.or negative value)
                      (i64.and positive value))
                    value)
             (#try.Success (:abstraction value))
             (exception.throw ..value_exceeds_the_scope [value <size>])))))

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

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

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

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

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

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

    [writer/1 S1 format.bits/8]
    [writer/2 S2 format.bits/16]
    [writer/4 S4 format.bits/32]
    )
  )