src/digits.bend
bend-trace-context@0.2.0.0 · 137 lines · 16 definitions
1
2
3
4
5
6
7
8
9
10
11
12import Base
13import bend-trace-context@0.2.0.0/src/hex.bend as Hex
14
15
16
17
18
19type Digits.Nil is Data:
20 DNil{}
21
22
23type Digits.Con<-p: Nat> is Data:
24 DCon{head: Hex.Digit, tail: Digits(p)}
25
26
27
28def Digits(n: Nat) -> Data:
29 match n:
30 case 0n:
31 Digits.Nil
32 case 1n+p:
33 Digits.Con<p>
34
35
36def Digits.to_string(n: Nat, digits: Digits(n)) -> String:
37 match n:
38 case 0n:
39 ""
40 case 1n+p:
41 match digits:
42 case DCon{head, tail}:
43 SCon{Hex.Digit.to_char(head), Digits.to_string(p, tail)}
44
45
46def Digits.is_zero(n: Nat, digits: Digits(n)) -> Bool:
47 match n:
48 case 0n:
49 True{}
50 case 1n+p:
51 match digits:
52 case DCon{head, tail}:
53 Bool.and(Hex.Digit.is_zero(head), Digits.is_zero(p, tail))
54
55
56
57def Digits.of_u32(word: U32) -> Digits(8n):
58 match word:
59 case U32{WCon{b0, WCon{b1, WCon{b2, WCon{b3, WCon{b4, WCon{b5, WCon{b6, WCon{b7, WCon{b8, WCon{b9, WCon{b10, WCon{b11, WCon{b12, WCon{b13, WCon{b14, WCon{b15, WCon{b16, WCon{b17, WCon{b18, WCon{b19, WCon{b20, WCon{b21, WCon{b22, WCon{b23, WCon{b24, WCon{b25, WCon{b26, WCon{b27, WCon{b28, WCon{b29, WCon{b30, WCon{b31, WNil{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}:
60 DCon{Hex.Digit.from_bits(b28, b29, b30, b31), DCon{Hex.Digit.from_bits(b24, b25, b26, b27), DCon{Hex.Digit.from_bits(b20, b21, b22, b23), DCon{Hex.Digit.from_bits(b16, b17, b18, b19), DCon{Hex.Digit.from_bits(b12, b13, b14, b15), DCon{Hex.Digit.from_bits(b8, b9, b10, b11), DCon{Hex.Digit.from_bits(b4, b5, b6, b7), DCon{Hex.Digit.from_bits(b0, b1, b2, b3), DNil{}}}}}}}}}
61
62
63def Digits.to_u32(digits: Digits(8n)) -> U32:
64 match digits:
65 case DCon{+d7, DCon{+d6, DCon{+d5, DCon{+d4, DCon{+d3, DCon{+d2, DCon{+d1, DCon{+d0, DNil{}}}}}}}}}:
66 U32{WCon{Hex.Digit.is_odd(d0), WCon{Hex.Digit.has_bit1(d0), WCon{Hex.Digit.has_bit2(d0), WCon{Hex.Digit.has_bit3(d0), WCon{Hex.Digit.is_odd(d1), WCon{Hex.Digit.has_bit1(d1), WCon{Hex.Digit.has_bit2(d1), WCon{Hex.Digit.has_bit3(d1), WCon{Hex.Digit.is_odd(d2), WCon{Hex.Digit.has_bit1(d2), WCon{Hex.Digit.has_bit2(d2), WCon{Hex.Digit.has_bit3(d2), WCon{Hex.Digit.is_odd(d3), WCon{Hex.Digit.has_bit1(d3), WCon{Hex.Digit.has_bit2(d3), WCon{Hex.Digit.has_bit3(d3), WCon{Hex.Digit.is_odd(d4), WCon{Hex.Digit.has_bit1(d4), WCon{Hex.Digit.has_bit2(d4), WCon{Hex.Digit.has_bit3(d4), WCon{Hex.Digit.is_odd(d5), WCon{Hex.Digit.has_bit1(d5), WCon{Hex.Digit.has_bit2(d5), WCon{Hex.Digit.has_bit3(d5), WCon{Hex.Digit.is_odd(d6), WCon{Hex.Digit.has_bit1(d6), WCon{Hex.Digit.has_bit2(d6), WCon{Hex.Digit.has_bit3(d6), WCon{Hex.Digit.is_odd(d7), WCon{Hex.Digit.has_bit1(d7), WCon{Hex.Digit.has_bit2(d7), WCon{Hex.Digit.has_bit3(d7), WNil{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
67
68
69
70
71def Digits.to_byte(digits: Digits(2n)) -> U32:
72 match digits:
73 case DCon{+high, DCon{+low, DNil{}}}:
74 U32{WCon{Hex.Digit.is_odd(low), WCon{Hex.Digit.has_bit1(low), WCon{Hex.Digit.has_bit2(low), WCon{Hex.Digit.has_bit3(low), WCon{Hex.Digit.is_odd(high), WCon{Hex.Digit.has_bit1(high), WCon{Hex.Digit.has_bit2(high), WCon{Hex.Digit.has_bit3(high), Word.zero(24n)}}}}}}}}}
75
76
77
78
79def Digits.of_byte(byte: U32) -> Digits(2n):
80 match byte:
81 case U32{WCon{b0, WCon{b1, WCon{b2, WCon{b3, WCon{b4, WCon{b5, WCon{b6, WCon{b7, rest}}}}}}}}}:
82 DCon{Hex.Digit.from_bits(b4, b5, b6, b7), DCon{Hex.Digit.from_bits(b0, b1, b2, b3), DNil{}}}
83
84
85
86def Digits.to_bytes(n: Nat, digits: Digits(Nat.double(n))) -> List<&2, U32>:
87 match n:
88 case 0n:
89 Nil{}
90 case 1n+p:
91 match digits:
92 case DCon{high, DCon{low, rest}}:
93 Con{Digits.to_byte(DCon{high, DCon{low, DNil{}}}), Digits.to_bytes(p, rest)}
94
95
96
97def Digits.append(m: Nat, -n: Nat, left: Digits(m), right: Digits(n)) -> Digits(Nat.add(m, n)):
98 match m:
99 case 0n:
100 match left:
101 case DNil{}:
102 right
103 case 1n+p:
104 match left:
105 case DCon{head, tail}:
106 DCon{head, Digits.append(p, n, tail, right)}
107
108
109
110
111
112type NonZero<-n: Nat> is Data:
113 NonZero{digits: Digits(n), evidence: {Digits.is_zero(n, digits) == False{} : Bool}}
114
115
116
117def NonZero.new.checked(-n: Nat, digits: Digits(n), status: Bool,
118 evidence: {Digits.is_zero(n, digits) == status : Bool}) -> Maybe<&2, NonZero<n>>:
119 match status:
120 case True{}:
121 None{}
122 case False{}:
123 Some{NonZero{digits, evidence}}
124
125
126def NonZero.new(+n: Nat, +digits: Digits(n)) -> Maybe<&2, NonZero<n>>:
127 NonZero.new.checked(n, digits, Digits.is_zero(n, digits), {==})
128
129
130def NonZero.digits(-n: Nat, value: NonZero<n>) -> Digits(n):
131 match value:
132 case NonZero{digits, evidence}:
133 digits
134
135
136def NonZero.to_string(n: Nat, value: NonZero<n>) -> String:
137 Digits.to_string(n, NonZero.digits(n, value))