Skip to content

Instantly share code, notes, and snippets.

@miyaokamarina
Last active September 25, 2020 09:34
Show Gist options
  • Save miyaokamarina/0129f0349278b76fb8f1b451deceda65 to your computer and use it in GitHub Desktop.
Save miyaokamarina/0129f0349278b76fb8f1b451deceda65 to your computer and use it in GitHub Desktop.
Type-level 16-bit ALU in TS.

Type-level binary arithmetics in TS.

  • Utilities:
    • 4-bit parsers:
      • Bin.
      • Dec.
      • Hex.
    • 4-bit formatters:
      • Bin.
      • Dec.
      • Hex.
    • 16-bit parsers:
      • Bin.
      • Unsigned dec.
      • Signed dec.
      • Hex.
    • 16-bit formatters:
      • Bin.
      • Unsigned dec.
      • Signed dec.
      • Hex.
  • Bitwise operations:
    • 4-bit.
    • 16-bit.
  • Additive operations:
    • 4-bit:
      • Addition.
      • Subtraction.
      • Increment.
      • Decrement.
      • Negation.
      • Sign.
    • 16-bit:
      • Addition.
      • Subtraction.
      • Increment.
      • Decrement.
      • Negation.
      • Sign.
  • Shifts:
    • 4-bit:
      • Unsigned left.
      • Unsigned right.
      • Signed shifts.
      • Rotations.
    • 16-bit:
      • Unsigned shifts.
      • Signed shifts.
      • Rotations.
  • Comparisons.
  • Multiplicative operations.
  • Floats.

License

GPL-3.0-or-later

// Basic types and tables
type bin = 0 | 1;
type dec = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
type hex = keyof HexDigits;
type i16 = [hex, hex, hex, hex];
type BinDigit = keyof BinValues;
type DecDigit = keyof DecValues;
type HexDigit = keyof HexValues;
type BinValues = { '0': 0x0; '1': 0x1; }
type DecValues = { '0': 0x0; '1': 0x1; '2': 0x2; '3': 0x3;
'4': 0x4; '5': 0x5; '6': 0x6; '7': 0x7;
'8': 0x8; '9': 0x9; }
type HexValues = { '0': 0x0; '1': 0x1; '2': 0x2; '3': 0x3;
'4': 0x4; '5': 0x5; '6': 0x6; '7': 0x7;
'8': 0x8; '9': 0x9; 'a': 0xa; 'b': 0xb;
'c': 0xc; 'd': 0xd; 'e': 0xe; 'f': 0xf; }
type HexDigits = { 0x0: '0'; 0x1: '1'; 0x2: '2'; 0x3: '3';
0x4: '4'; 0x5: '5'; 0x6: '6'; 0x7: '7';
0x8: '8'; 0x9: '9'; 0xa: 'a'; 0xb: 'b';
0xc: 'c'; 0xd: 'd'; 0xe: 'e'; 0xf: 'f'; }
//
// Parsers
type ParseBinDigit<s> = s extends BinDigit ? BinValues[s] : never;
type HexParseBinTable<h,
_ = h extends [0, 0, 0, 0] ? 0b0000
: h extends [0, 0, 0, 1] ? 0b0001
: h extends [0, 0, 1, 0] ? 0b0010
: h extends [0, 0, 1, 1] ? 0b0011
: h extends [0, 1, 0, 0] ? 0b0100
: h extends [0, 1, 0, 1] ? 0b0101
: h extends [0, 1, 1, 0] ? 0b0110
: h extends [0, 1, 1, 1] ? 0b0111
: h extends [1, 0, 0, 0] ? 0b1000
: h extends [1, 0, 0, 1] ? 0b1001
: h extends [1, 0, 1, 0] ? 0b1010
: h extends [1, 0, 1, 1] ? 0b1011
: h extends [1, 1, 0, 0] ? 0b1100
: h extends [1, 1, 0, 1] ? 0b1101
: h extends [1, 1, 1, 0] ? 0b1110
: h extends [1, 1, 1, 1] ? 0b1111
: never
> = _;
type HexParseBin<s,
_ = s extends `${infer b0}${infer b1}${infer b2}${infer b3}`
? HexParseBinTable<[ParseBinDigit<b0>, ParseBinDigit<b1>, ParseBinDigit<b2>, ParseBinDigit<b3>]>
: never
> = _;
type HexParseDec<s> = s extends DecDigit ? DecValues[s] : never;
type HexParseHex<s> = s extends HexDigit ? HexValues[s] : never;
type I16ParseBin<s,
_ = s extends `0b${infer h0}_${infer h1}_${infer h2}_${infer h3}`
? [HexParseBin<h0>, HexParseBin<h1>, HexParseBin<h2>, HexParseBin<h3>]
: never
> = _;
// TODO: Dec.
type I16ParseHex<s,
_ = s extends `0x${infer h0}${infer h1}${infer h2}${infer h3}`
? [HexParseHex<h0>, HexParseHex<h1>, HexParseHex<h2>, HexParseHex<h3>]
: never
> = _;
//
// Parsers test
// const parse_bin_digit_0: ParseBinDigit<'0'> = 0b0;
// const parse_bin_digit_1: ParseBinDigit<'1'> = 0b1;
// const hex_parse_bin_0000: HexParseBin<'0000'> = 0b0000;
// const hex_parse_bin_0001: HexParseBin<'0001'> = 0b0001;
// const hex_parse_bin_0010: HexParseBin<'0010'> = 0b0010;
// const hex_parse_bin_0011: HexParseBin<'0011'> = 0b0011;
// const hex_parse_bin_0100: HexParseBin<'0100'> = 0b0100;
// const hex_parse_bin_0101: HexParseBin<'0101'> = 0b0101;
// const hex_parse_bin_0110: HexParseBin<'0110'> = 0b0110;
// const hex_parse_bin_0111: HexParseBin<'0111'> = 0b0111;
// const hex_parse_bin_1000: HexParseBin<'1000'> = 0b1000;
// const hex_parse_bin_1001: HexParseBin<'1001'> = 0b1001;
// const hex_parse_bin_1010: HexParseBin<'1010'> = 0b1010;
// const hex_parse_bin_1011: HexParseBin<'1011'> = 0b1011;
// const hex_parse_bin_1100: HexParseBin<'1100'> = 0b1100;
// const hex_parse_bin_1101: HexParseBin<'1101'> = 0b1101;
// const hex_parse_bin_1110: HexParseBin<'1110'> = 0b1110;
// const hex_parse_bin_1111: HexParseBin<'1111'> = 0b1111;
// const hex_parse_dec_0: HexParseDec<'0'> = 0;
// const hex_parse_dec_1: HexParseDec<'1'> = 1;
// const hex_parse_dec_2: HexParseDec<'2'> = 2;
// const hex_parse_dec_3: HexParseDec<'3'> = 3;
// const hex_parse_dec_4: HexParseDec<'4'> = 4;
// const hex_parse_dec_5: HexParseDec<'5'> = 5;
// const hex_parse_dec_6: HexParseDec<'6'> = 6;
// const hex_parse_dec_7: HexParseDec<'7'> = 7;
// const hex_parse_dec_8: HexParseDec<'8'> = 8;
// const hex_parse_dec_9: HexParseDec<'9'> = 9;
// const hex_parse_hex_0: HexParseHex<'0'> = 0x0;
// const hex_parse_hex_1: HexParseHex<'1'> = 0x1;
// const hex_parse_hex_2: HexParseHex<'2'> = 0x2;
// const hex_parse_hex_3: HexParseHex<'3'> = 0x3;
// const hex_parse_hex_4: HexParseHex<'4'> = 0x4;
// const hex_parse_hex_5: HexParseHex<'5'> = 0x5;
// const hex_parse_hex_6: HexParseHex<'6'> = 0x6;
// const hex_parse_hex_7: HexParseHex<'7'> = 0x7;
// const hex_parse_hex_8: HexParseHex<'8'> = 0x8;
// const hex_parse_hex_9: HexParseHex<'9'> = 0x9;
// const hex_parse_hex_a: HexParseHex<'a'> = 0xa;
// const hex_parse_hex_b: HexParseHex<'b'> = 0xb;
// const hex_parse_hex_c: HexParseHex<'c'> = 0xc;
// const hex_parse_hex_d: HexParseHex<'d'> = 0xd;
// const hex_parse_hex_e: HexParseHex<'e'> = 0xe;
// const hex_parse_hex_f: HexParseHex<'f'> = 0xf;
// const i16_parse_bin_5432: I16ParseBin<'0b0101_0100_0011_0010'> = [0x5, 0x4, 0x3, 0x2];
// // TODO: Dec.
// const i16_parse_hex_5432: I16ParseHex<'0x5432'> = [0x5, 0x4, 0x3, 0x2];
//
// Formatters
type HexFormatBinTable = {
0b0000: [0, 0, 0, 0];
0b0001: [0, 0, 0, 1];
0b0010: [0, 0, 1, 0];
0b0011: [0, 0, 1, 1];
0b0100: [0, 1, 0, 0];
0b0101: [0, 1, 0, 1];
0b0110: [0, 1, 1, 0];
0b0111: [0, 1, 1, 1];
0b1000: [1, 0, 0, 0];
0b1001: [1, 0, 0, 1];
0b1010: [1, 0, 1, 0];
0b1011: [1, 0, 1, 1];
0b1100: [1, 1, 0, 0];
0b1101: [1, 1, 0, 1];
0b1110: [1, 1, 1, 0];
0b1111: [1, 1, 1, 1];
};
type HexFormatBin<x extends hex,
t0 extends [bin, bin, bin, bin] = HexFormatBinTable[x],
_ = `${t0[0]}${t0[1]}${t0[2]}${t0[3]}`
> = _;
// TODO: Dec.
type HexFormatHex<x extends hex> = HexDigits[x];
type I16FormatBin<x extends i16> = `0b${HexFormatBin<x[0]>}_${HexFormatBin<x[1]>}_${HexFormatBin<x[2]>}_${HexFormatBin<x[3]>}`;
// TODO: Dec.
type I16FormatHex<x extends i16> = `0x${HexDigits[x[0]]}${HexDigits[x[1]]}${HexDigits[x[2]]}${HexDigits[x[3]]}`;
//
// Formatters test
// const hex_format_bin_0000: HexFormatBin<0b0000> = '0000';
// const hex_format_bin_0001: HexFormatBin<0b0001> = '0001';
// const hex_format_bin_1110: HexFormatBin<0b1110> = '1110';
// const hex_format_bin_1111: HexFormatBin<0b1111> = '1111';
// // TODO: Dec.
// const hex_format_hex_0: HexFormatHex<0x0> = '0';
// const hex_format_hex_1: HexFormatHex<0x1> = '1';
// const hex_format_hex_e: HexFormatHex<0xe> = 'e';
// const hex_format_hex_f: HexFormatHex<0xf> = 'f';
// const i16_format_bin_5432: I16FormatBin<[0x5, 0x4, 0x3, 0x2]> = '0b0101_0100_0011_0010';
// // TODO: Dec.
// const i16_format_hex_5432: I16FormatHex<[0x5, 0x4, 0x3, 0x2]> = '0x5432';
//
// Bitwise operations
type HexNot = [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0];
type HexXor = [
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], [ 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14],
[ 2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13], [ 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12],
[ 4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11], [ 5, 4, 7, 6, 1, 0, 3, 2, 13, 12, 15, 14, 9, 8, 11, 10],
[ 6, 7, 4, 5, 2, 3, 0, 1, 14, 15, 12, 13, 10, 11, 8, 9], [ 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8],
[ 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7], [ 9, 8, 11, 10, 13, 12, 15, 14, 1, 0, 3, 2, 5, 4, 7, 6],
[10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 5], [11, 10, 9, 8, 15, 14, 13, 12, 3, 2, 1, 0, 7, 6, 5, 4],
[12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3], [13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2],
[14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1], [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0],
];
type HexAnd = [
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[ 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2], [ 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3],
[ 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4], [ 0, 1, 0, 1, 4, 5, 4, 5, 0, 1, 0, 1, 4, 5, 4, 5],
[ 0, 0, 2, 2, 4, 4, 6, 6, 0, 0, 2, 2, 4, 4, 6, 6], [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7],
[ 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8], [ 0, 1, 0, 1, 0, 1, 0, 1, 8, 9, 8, 9, 8, 9, 8, 9],
[ 0, 0, 2, 2, 0, 0, 2, 2, 8, 8, 10, 10, 8, 8, 10, 10], [ 0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11],
[ 0, 0, 0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, 12, 12, 12], [ 0, 1, 0, 1, 4, 5, 4, 5, 8, 9, 8, 9, 12, 13, 12, 13],
[ 0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
];
type HexOr = [
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], [ 1, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11, 11, 13, 13, 15, 15],
[ 2, 3, 2, 3, 6, 7, 6, 7, 10, 11, 10, 11, 14, 15, 14, 15], [ 3, 3, 3, 3, 7, 7, 7, 7, 11, 11, 11, 11, 15, 15, 15, 15],
[ 4, 5, 6, 7, 4, 5, 6, 7, 12, 13, 14, 15, 12, 13, 14, 15], [ 5, 5, 7, 7, 5, 5, 7, 7, 13, 13, 15, 15, 13, 13, 15, 15],
[ 6, 7, 6, 7, 6, 7, 6, 7, 14, 15, 14, 15, 14, 15, 14, 15], [ 7, 7, 7, 7, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15, 15, 15],
[ 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15], [ 9, 9, 11, 11, 13, 13, 15, 15, 9, 9, 11, 11, 13, 13, 15, 15],
[10, 11, 10, 11, 14, 15, 14, 15, 10, 11, 10, 11, 14, 15, 14, 15], [11, 11, 11, 11, 15, 15, 15, 15, 11, 11, 11, 11, 15, 15, 15, 15],
[12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15], [13, 13, 15, 15, 13, 13, 15, 15, 13, 13, 15, 15, 13, 13, 15, 15],
[14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15], [15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15],
];
type I16Not<x extends i16> = [HexNot[x[0]], HexNot[x[1]], HexNot[x[2]], HexNot[x[3]]];
type I16Xor<x extends i16, y extends i16> = [HexXor[x[0]][y[0]], HexXor[x[1]][y[1]], HexXor[x[2]][y[2]], HexXor[x[3]][y[3]]];
type I16And<x extends i16, y extends i16> = [HexAnd[x[0]][y[0]], HexAnd[x[1]][y[1]], HexAnd[x[2]][y[2]], HexAnd[x[3]][y[3]]];
type I16Or <x extends i16, y extends i16> = [HexOr [x[0]][y[0]], HexOr [x[1]][y[1]], HexOr [x[2]][y[2]], HexOr [x[3]][y[3]]];
//
// Bitwise test
// const hex_not_0: HexNot[0b0000] = 0b1111;
// const hex_not_1: HexNot[0b0001] = 0b1110;
// const hex_not_e: HexNot[0b1110] = 0b0001;
// const hex_not_f: HexNot[0b1111] = 0b0000;
// const hex_xor_0000_0000: HexXor[0b0000][0b0000] = 0b0000;
// const hex_xor_0000_0101: HexXor[0b0000][0b0101] = 0b0101;
// const hex_xor_0101_0000: HexXor[0b0101][0b0000] = 0b0101;
// const hex_xor_0101_0101: HexXor[0b0101][0b0101] = 0b0000;
// const hex_and_0000_0000: HexAnd[0b0000][0b0000] = 0b0000;
// const hex_and_0000_0101: HexAnd[0b0000][0b0101] = 0b0000;
// const hex_and_0101_0000: HexAnd[0b0101][0b0000] = 0b0000;
// const hex_and_0101_0101: HexAnd[0b0101][0b0101] = 0b0101;
// const hex_or__0000_0000: HexOr [0b0000][0b0000] = 0b0000;
// const hex_or__0000_0101: HexOr [0b0000][0b0101] = 0b0101;
// const hex_or__0101_0000: HexOr [0b0101][0b0000] = 0b0101;
// const hex_or__0101_0101: HexOr [0b0101][0b0101] = 0b0101;
// // TODO: I16.
//
// Additive operations
type HexAddTable = [
[[[ 0, 0], [ 1, 0], [ 2, 0], [ 3, 0], [ 4, 0], [ 5, 0], [ 6, 0], [ 7, 0], [ 8, 0], [ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0]],
[[ 1, 0], [ 2, 0], [ 3, 0], [ 4, 0], [ 5, 0], [ 6, 0], [ 7, 0], [ 8, 0], [ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1]],
[[ 2, 0], [ 3, 0], [ 4, 0], [ 5, 0], [ 6, 0], [ 7, 0], [ 8, 0], [ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1]],
[[ 3, 0], [ 4, 0], [ 5, 0], [ 6, 0], [ 7, 0], [ 8, 0], [ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1]],
[[ 4, 0], [ 5, 0], [ 6, 0], [ 7, 0], [ 8, 0], [ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1]],
[[ 5, 0], [ 6, 0], [ 7, 0], [ 8, 0], [ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1]],
[[ 6, 0], [ 7, 0], [ 8, 0], [ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1]],
[[ 7, 0], [ 8, 0], [ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1]],
[[ 8, 0], [ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1], [ 7, 1]],
[[ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1], [ 7, 1], [ 8, 1]],
[[10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1], [ 7, 1], [ 8, 1], [ 9, 1]],
[[11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1], [ 7, 1], [ 8, 1], [ 9, 1], [10, 1]],
[[12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1], [ 7, 1], [ 8, 1], [ 9, 1], [10, 1], [11, 1]],
[[13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1], [ 7, 1], [ 8, 1], [ 9, 1], [10, 1], [11, 1], [12, 1]],
[[14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1], [ 7, 1], [ 8, 1], [ 9, 1], [10, 1], [11, 1], [12, 1], [13, 1]],
[[15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1], [ 7, 1], [ 8, 1], [ 9, 1], [10, 1], [11, 1], [12, 1], [13, 1], [14, 1]]],
[[[ 1, 0], [ 2, 0], [ 3, 0], [ 4, 0], [ 5, 0], [ 6, 0], [ 7, 0], [ 8, 0], [ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1]],
[[ 2, 0], [ 3, 0], [ 4, 0], [ 5, 0], [ 6, 0], [ 7, 0], [ 8, 0], [ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1]],
[[ 3, 0], [ 4, 0], [ 5, 0], [ 6, 0], [ 7, 0], [ 8, 0], [ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1]],
[[ 4, 0], [ 5, 0], [ 6, 0], [ 7, 0], [ 8, 0], [ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1]],
[[ 5, 0], [ 6, 0], [ 7, 0], [ 8, 0], [ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1]],
[[ 6, 0], [ 7, 0], [ 8, 0], [ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1]],
[[ 7, 0], [ 8, 0], [ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1]],
[[ 8, 0], [ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1], [ 7, 1]],
[[ 9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1], [ 7, 1], [ 8, 1]],
[[10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1], [ 7, 1], [ 8, 1], [ 9, 1]],
[[11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1], [ 7, 1], [ 8, 1], [ 9, 1], [10, 1]],
[[12, 0], [13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1], [ 7, 1], [ 8, 1], [ 9, 1], [10, 1], [11, 1]],
[[13, 0], [14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1], [ 7, 1], [ 8, 1], [ 9, 1], [10, 1], [11, 1], [12, 1]],
[[14, 0], [15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1], [ 7, 1], [ 8, 1], [ 9, 1], [10, 1], [11, 1], [12, 1], [13, 1]],
[[15, 0], [ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1], [ 7, 1], [ 8, 1], [ 9, 1], [10, 1], [11, 1], [12, 1], [13, 1], [14, 1]],
[[ 0, 1], [ 1, 1], [ 2, 1], [ 3, 1], [ 4, 1], [ 5, 1], [ 6, 1], [ 7, 1], [ 8, 1], [ 9, 1], [10, 1], [11, 1], [12, 1], [13, 1], [14, 1], [15, 1]]],
];
type HexSubTable = [
[[[ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1], [ 8, 1], [ 7, 1], [ 6, 1], [ 5, 1], [ 4, 1], [ 3, 1], [ 2, 1], [ 1, 1]],
[[ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1], [ 8, 1], [ 7, 1], [ 6, 1], [ 5, 1], [ 4, 1], [ 3, 1], [ 2, 1]],
[[ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1], [ 8, 1], [ 7, 1], [ 6, 1], [ 5, 1], [ 4, 1], [ 3, 1]],
[[ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1], [ 8, 1], [ 7, 1], [ 6, 1], [ 5, 1], [ 4, 1]],
[[ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1], [ 8, 1], [ 7, 1], [ 6, 1], [ 5, 1]],
[[ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1], [ 8, 1], [ 7, 1], [ 6, 1]],
[[ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1], [ 8, 1], [ 7, 1]],
[[ 7, 0], [ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1], [ 8, 1]],
[[ 8, 0], [ 7, 0], [ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1]],
[[ 9, 0], [ 8, 0], [ 7, 0], [ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1]],
[[10, 0], [ 9, 0], [ 8, 0], [ 7, 0], [ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1]],
[[11, 0], [10, 0], [ 9, 0], [ 8, 0], [ 7, 0], [ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1]],
[[12, 0], [11, 0], [10, 0], [ 9, 0], [ 8, 0], [ 7, 0], [ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1]],
[[13, 0], [12, 0], [11, 0], [10, 0], [ 9, 0], [ 8, 0], [ 7, 0], [ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1]],
[[14, 0], [13, 0], [12, 0], [11, 0], [10, 0], [ 9, 0], [ 8, 0], [ 7, 0], [ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1]],
[[15, 0], [14, 0], [13, 0], [12, 0], [11, 0], [10, 0], [ 9, 0], [ 8, 0], [ 7, 0], [ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0]]],
[[[15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1], [ 8, 1], [ 7, 1], [ 6, 1], [ 5, 1], [ 4, 1], [ 3, 1], [ 2, 1], [ 1, 1], [ 0, 1]],
[[ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1], [ 8, 1], [ 7, 1], [ 6, 1], [ 5, 1], [ 4, 1], [ 3, 1], [ 2, 1], [ 1, 1]],
[[ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1], [ 8, 1], [ 7, 1], [ 6, 1], [ 5, 1], [ 4, 1], [ 3, 1], [ 2, 1]],
[[ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1], [ 8, 1], [ 7, 1], [ 6, 1], [ 5, 1], [ 4, 1], [ 3, 1]],
[[ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1], [ 8, 1], [ 7, 1], [ 6, 1], [ 5, 1], [ 4, 1]],
[[ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1], [ 8, 1], [ 7, 1], [ 6, 1], [ 5, 1]],
[[ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1], [ 8, 1], [ 7, 1], [ 6, 1]],
[[ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1], [ 8, 1], [ 7, 1]],
[[ 7, 0], [ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1], [ 8, 1]],
[[ 8, 0], [ 7, 0], [ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1], [ 9, 1]],
[[ 9, 0], [ 8, 0], [ 7, 0], [ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1], [10, 1]],
[[10, 0], [ 9, 0], [ 8, 0], [ 7, 0], [ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1], [11, 1]],
[[11, 0], [10, 0], [ 9, 0], [ 8, 0], [ 7, 0], [ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1], [12, 1]],
[[12, 0], [11, 0], [10, 0], [ 9, 0], [ 8, 0], [ 7, 0], [ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1], [13, 1]],
[[13, 0], [12, 0], [11, 0], [10, 0], [ 9, 0], [ 8, 0], [ 7, 0], [ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1], [14, 1]],
[[14, 0], [13, 0], [12, 0], [11, 0], [10, 0], [ 9, 0], [ 8, 0], [ 7, 0], [ 6, 0], [ 5, 0], [ 4, 0], [ 3, 0], [ 2, 0], [ 1, 0], [ 0, 0], [15, 1]]],
];
type HexAdd<x extends hex, y extends hex> = HexAddTable[0][x][y][0];
type HexSub<x extends hex, y extends hex> = HexSubTable[0][x][y][0];
type HexInc<x extends hex> = HexAdd<x, 1>;
type HexDec<x extends hex> = HexSub<x, 1>;
type HexNeg<x extends hex> = HexSub<0, x>;
type HexSgn<x extends hex> = HexAnd[x][8] extends 8 ? 1 : 0;
type I16Add<x extends i16, y extends i16,
t0 extends [hex, bin] = HexAddTable[ 0 ][x[3]][y[3]],
t1 extends [hex, bin] = HexAddTable[t0[1]][x[2]][y[2]],
t2 extends [hex, bin] = HexAddTable[t1[1]][x[1]][y[1]],
t3 extends [hex, bin] = HexAddTable[t2[1]][x[0]][y[0]],
_ = [t3[0], t2[0], t1[0], t0[0]]
> = _;
type I16Sub<x extends i16, y extends i16,
t0 extends [hex, bin] = HexSubTable[ 0 ][x[3]][y[3]],
t1 extends [hex, bin] = HexSubTable[t0[1]][x[2]][y[2]],
t2 extends [hex, bin] = HexSubTable[t1[1]][x[1]][y[1]],
t3 extends [hex, bin] = HexSubTable[t2[1]][x[0]][y[0]],
_ = [t3[0], t2[0], t1[0], t0[0]]
> = _;
type I16Inc<x extends i16> = I16Add<x, [0, 0, 0, 1]>;
type I16Dec<x extends i16> = I16Sub<x, [0, 0, 0, 1]>;
type I16Neg<x extends i16> = I16Sub<[0, 0, 0, 0], x>;
type I16Sgn<x extends i16> = HexAnd[x[0]][8] extends 8 ? 1 : 0;
//
// Additive test
// const hex_add_0_0: HexAdd<0x0, 0x0> = 0x0;
// const hex_add_0_1: HexAdd<0x0, 0x1> = 0x1;
// const hex_add_1_0: HexAdd<0x1, 0x0> = 0x1;
// const hex_add_2_3: HexAdd<0x2, 0x3> = 0x5;
// const hex_add_3_2: HexAdd<0x3, 0x2> = 0x5;
// const hex_add_e_e: HexAdd<0xe, 0xe> = 0xc;
// const hex_sub_0_0: HexSub<0x0, 0x0> = 0x0;
// const hex_sub_0_1: HexSub<0x0, 0x1> = 0xf;
// const hex_sub_1_0: HexSub<0x1, 0x0> = 0x1;
// const hex_sub_2_3: HexSub<0x2, 0x3> = 0xf;
// const hex_sub_3_2: HexSub<0x3, 0x2> = 0x1;
// const hex_sub_e_e: HexSub<0xe, 0xe> = 0x0;
// const hex_inc_0: HexInc<0x0> = 0x1;
// const hex_inc_1: HexInc<0x1> = 0x2;
// const hex_inc_e: HexInc<0xe> = 0xf;
// const hex_inc_f: HexInc<0xf> = 0x0;
// const hex_dec_0: HexDec<0x0> = 0xf;
// const hex_dec_1: HexDec<0x1> = 0x0;
// const hex_dec_e: HexDec<0xe> = 0xd;
// const hex_dec_f: HexDec<0xf> = 0xe;
// const hex_neg_0: HexNeg<0x0> = 0x0;
// const hex_neg_1: HexNeg<0x1> = 0xf;
// const hex_neg_2: HexNeg<0x2> = 0xe;
// const hex_nex_e: HexNeg<0xe> = 0x2;
// const hex_neg_f: HexNeg<0xf> = 0x1;
// const hex_sgn_0: HexSgn<0x0> = 0x0;
// const hex_sgn_1: HexSgn<0x1> = 0x0;
// const hex_sgn_2: HexSgn<0x2> = 0x0;
// const hex_sgn_e: HexSgn<0xe> = 0x1;
// const hex_sgn_f: HexSgn<0xf> = 0x1;
// const i16_add_0000_0000: I16FormatHex<I16Add<[0x0, 0x0, 0x0, 0x0], [0x0, 0x0, 0x0, 0x0]>> = '0x0000';
// const i16_add_0000_0001: I16FormatHex<I16Add<[0x0, 0x0, 0x0, 0x0], [0x0, 0x0, 0x0, 0x1]>> = '0x0001';
// const i16_add_0001_0000: I16FormatHex<I16Add<[0x0, 0x0, 0x0, 0x1], [0x0, 0x0, 0x0, 0x0]>> = '0x0001';
// const i16_add_1234_9abc: I16FormatHex<I16Add<[0x1, 0x2, 0x3, 0x4], [0x9, 0xa, 0xb, 0xc]>> = '0xacf0';
// const i16_add_9abc_1234: I16FormatHex<I16Add<[0x9, 0xa, 0xb, 0xc], [0x1, 0x2, 0x3, 0x4]>> = '0xacf0';
// const i16_add_9abc_9abc: I16FormatHex<I16Add<[0x9, 0xa, 0xb, 0xc], [0x9, 0xa, 0xb, 0xc]>> = '0x3578';
// const i16_inc_0000: I16FormatHex<I16Inc<[0x0, 0x0, 0x0, 0x0]>> = '0x0001';
// const i16_inc_0001: I16FormatHex<I16Inc<[0x0, 0x0, 0x0, 0x1]>> = '0x0002';
// const i16_inc_fffe: I16FormatHex<I16Inc<[0xf, 0xf, 0xf, 0xe]>> = '0xffff';
// const i16_inc_ffff: I16FormatHex<I16Inc<[0xf, 0xf, 0xf, 0xf]>> = '0x0000';
// const i16_dec_0000: I16FormatHex<I16Dec<[0x0, 0x0, 0x0, 0x0]>> = '0xffff';
// const i16_dec_0001: I16FormatHex<I16Dec<[0x0, 0x0, 0x0, 0x1]>> = '0x0000';
// const i16_dec_fffe: I16FormatHex<I16Dec<[0xf, 0xf, 0xf, 0xe]>> = '0xfffd';
// const i16_dec_ffff: I16FormatHex<I16Dec<[0xf, 0xf, 0xf, 0xf]>> = '0xfffe';
// const i16_neg_0000: I16FormatHex<I16Neg<[0x0, 0x0, 0x0, 0x0]>> = '0x0000';
// const i16_neg_0001: I16FormatHex<I16Neg<[0x0, 0x0, 0x0, 0x1]>> = '0xffff';
// const i16_neg_0002: I16FormatHex<I16Neg<[0x0, 0x0, 0x0, 0x2]>> = '0xfffe';
// const i16_nex_fffe: I16FormatHex<I16Neg<[0xf, 0xf, 0xf, 0xe]>> = '0x0002';
// const i16_neg_ffff: I16FormatHex<I16Neg<[0xf, 0xf, 0xf, 0xf]>> = '0x0001';
// const i16_sgn_0000: I16Sgn<[0x0, 0x0, 0x0, 0x0]> = 0;
// const i16_sgn_0001: I16Sgn<[0x0, 0x0, 0x0, 0x1]> = 0;
// const i16_sgn_0002: I16Sgn<[0x0, 0x0, 0x0, 0x2]> = 0;
// const i16_sgn_000e: I16Sgn<[0x0, 0x0, 0x0, 0xe]> = 0;
// const i16_sgn_000f: I16Sgn<[0x0, 0x0, 0x0, 0xf]> = 0;
// const i16_sgn_e000: I16Sgn<[0xe, 0x0, 0x0, 0x0]> = 1;
// const i16_sgn_f000: I16Sgn<[0xf, 0x0, 0x0, 0x0]> = 1;
//
// Shift operations
type HexUShl = [
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
[ 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6, 8, 10, 12, 14],
[ 0, 4, 8, 12, 0, 4, 8, 12, 0, 4, 8, 12, 0, 4, 8, 12],
[ 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8],
];
type HexUShr = [
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
[ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7],
[ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
[ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1],
];
//
@notpushkin
Copy link

Ебанутый

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment