-
Notifications
You must be signed in to change notification settings - Fork 0
/
Int.ts
132 lines (113 loc) · 2.75 KB
/
Int.ts
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
122
123
124
125
126
127
128
129
130
131
132
import { Bit, And as BitAnd, Xor as BitXor } from "./Bit"
import * as List from "./List"
export type Int16 = List.From<Bit, 16>
export type Int = Bit[]
export type _0 = List.From<0, 16>
export type _1 = List.Set<1, 15, _0>
// stops working around N = 45
export type FromIntConst<
N,
Acc extends Int16[] = [_1]
> = Acc["length"] extends N
? Acc[0]
: FromIntConst<N, [Add16<Acc[0], _1>, ...Acc]>
export type Xor<X, Y> = {
[k in keyof X]: k extends keyof Y & `${number}` ? BitXor<X[k], Y[k]> : X[k]
}
export type And<X, Y> = {
[k in keyof X]: k extends keyof Y & `${number}` ? BitAnd<X[k], Y[k]> : X[k]
}
/**
* @description
* Truncates an int to its leftmost 16 bits
* @param X - the int to truncate
*
* @returns Int16
*/
type Trunc<X extends Int> = X extends { length: 16 }
? X
: X extends [any, ...infer Rest extends Int]
? Trunc<Rest>
: never
export type Mult<
X extends Int,
Y,
Res extends Int = _0,
Pow extends Int = []
> = Y extends [...infer Rest, infer P]
? P extends 0
? Mult<X, Rest, Res, [...Pow, 0]>
: Add<Trunc<[...X, ...Pow]>, Res> extends Int
? Mult<X, Rest, Add<Trunc<[...X, ...Pow]>, Res>, [...Pow, 0]>
: never
: Res
type ShiftLeft1<X> = X extends [infer x, ...infer xs] ? [...xs, 0] : never
export type Add<X, Y> = 1 extends Y[keyof Y]
? Add<Xor<X, Y>, ShiftLeft1<And<X, Y>>>
: X
export type Add16<X extends Int16, Y extends Int16> = Add<X, Y> extends Int16
? Add<X, Y>
: never
type Flip<X> = {
[k in keyof X]: k extends `${number}` ? (X[k] extends 0 ? 1 : 0) : X[k]
}
export type Subtr<X, Y> = 1 extends Y[keyof Y]
? Subtr<Xor<X, Y>, ShiftLeft1<And<Flip<X>, Y>>>
: X
export type LT<X, Y> = [X, Y] extends [
[infer x, ...infer xs],
[infer y, ...infer ys]
]
? x extends y
? LT<xs, ys>
: 1 extends y
? true
: false
: false
export type LTE<X, Y> = Y extends X ? true : LT<X, Y>
export type GT<X, Y> = LTE<X, Y> extends true ? false : true
export type GTE<X, Y> = Y extends X ? true : GT<X, Y>
export type ShowBin<X extends Bit[]> = X["length"] extends 0
? ``
: `${X[0]}${ShowBin<List.Tail<X>>}`
type HexMap = {
0: {
0: {
0: { 0: "0"; 1: "1" }
1: { 0: "2"; 1: "3" }
}
1: {
0: { 0: "4"; 1: "5" }
1: { 0: "6"; 1: "7" }
}
}
1: {
0: {
0: { 0: "8"; 1: "9" }
1: { 0: "a"; 1: "b" }
}
1: {
0: { 0: "c"; 1: "d" }
1: { 0: "e"; 1: "f" }
}
}
}
export type ShowHex<X extends Bit[]> = X extends [
infer A,
infer B,
infer C,
infer D,
...infer Bits
]
? A extends Bit
? B extends Bit
? C extends Bit
? D extends Bit
? Bits extends Bit[]
? `${HexMap[A][B][C][D]}${ShowHex<Bits>}`
: never
: never
: never
: never
: never
: ``