Skip to content

Instantly share code, notes, and snippets.

@acutmore
Last active September 19, 2019 11:51
Show Gist options
  • Select an option

  • Save acutmore/a9e09be531f565ba3415200400a0ce31 to your computer and use it in GitHub Desktop.

Select an option

Save acutmore/a9e09be531f565ba3415200400a0ce31 to your computer and use it in GitHub Desktop.
logic in typescript
// ASHEMBLER
type ADD_8<
regA extends [B, B, B, B, B, B, B, B],
regB extends [B, B, B, B, B, B, B, B],
/* variables: */
a extends [B, B] = FULL_ADDER<0, regA[0], regB[0]>,
b extends [B, B] = FULL_ADDER<a[1], regA[1], regB[1]>,
c extends [B, B] = FULL_ADDER<b[1], regA[2], regB[2]>,
d extends [B, B] = FULL_ADDER<c[1], regA[3], regB[3]>,
e extends [B, B] = FULL_ADDER<d[1], regA[4], regB[4]>,
f extends [B, B] = FULL_ADDER<e[1], regA[5], regB[5]>,
g extends [B, B] = FULL_ADDER<f[1], regA[6], regB[6]>,
h extends [B, B] = FULL_ADDER<g[1], regA[7], regB[7]>
> = [a[0], b[0], c[0], d[0], e[0], f[0], g[0], h[0]];
type N_34 = [0, 1, 0, 0, 0, 1, 0, 0];
type N_101 = [1, 0, 1, 0, 0, 1, 1, 0];
type N_135 = [1, 1, 1, 0, 0, 0, 0, 1];
assertTrue<equals<ADD_8<N_34, N_101>, /* expected: */ N_135>>();
type ADD_2<
regA extends [B, B],
regB extends [B, B],
/* variables */
a extends [B, B] = FULL_ADDER<0, regA[0], regB[0]>,
b extends [B, B] = FULL_ADDER<a[1], regA[1], regB[1]>
> = [a[0], b[0]];
assertTrue<equals<ADD_2<[0, 0], [0, 0]>, /* expected: */ [0, 0]>>();
assertTrue<equals<ADD_2<[1, 0], [1, 0]>, /* expected: */ [0, 1]>>();
assertTrue<equals<ADD_2<[0, 1], [1, 0]>, /* expected: */ [1, 1]>>();
assertTrue<equals<ADD_2<[1, 1], [1, 0]>, /* expected: */ [0, 0]>>(); // overflows
type FULL_ADDER<
carry extends B,
a extends B,
b extends B,
/* variables: */
adder1 extends [B, B] = HALF_ADDER<a, b>,
adder2 extends [B, B] = HALF_ADDER<carry, adder1[0]>
> = [adder2[0], OR<adder2[1], adder1[1]>];
assertTrue<equals<FULL_ADDER<0, 0, 0>, [0, 0]>>();
assertTrue<equals<FULL_ADDER<1, 0, 0>, [1, 0]>>();
assertTrue<equals<FULL_ADDER<0, 1, 0>, [1, 0]>>();
assertTrue<equals<FULL_ADDER<0, 0, 1>, [1, 0]>>();
assertTrue<equals<FULL_ADDER<1, 1, 0>, [0, 1]>>();
assertTrue<equals<FULL_ADDER<1, 0, 1>, [0, 1]>>();
assertTrue<equals<FULL_ADDER<0, 1, 1>, [0, 1]>>();
assertTrue<equals<FULL_ADDER<1, 1, 1>, [1, 1]>>();
type HALF_ADDER<a extends B, b extends B> = [XOR<a, b>, AND<a, b>];
assertTrue<equals<HALF_ADDER<0, 0>, [0, 0]>>();
assertTrue<equals<HALF_ADDER<1, 0>, [1, 0]>>();
assertTrue<equals<HALF_ADDER<0, 1>, [1, 0]>>();
assertTrue<equals<HALF_ADDER<1, 1>, [0, 1]>>();
type equals<a extends B[], b extends B[]> = a extends b ? 1 : 0;
assertTrue<equals<[0, 1], [0, 1]>>();
assertFalse<equals<[0, 1], [1, 1]>>();
type XOR<a extends B, b extends B> = AND<NAND<a, b>, OR<a, b>>;
assertTrue<XOR<1, 0>>();
assertTrue<XOR<0, 1>>();
assertFalse<XOR<1, 1>>();
assertFalse<XOR<0, 0>>();
type NOR<a extends B, b extends B> = NOT<OR<a, b>>;
assertTrue<NOR<0, 0>>();
assertFalse<NOR<1, 0>>();
assertFalse<NOR<0, 1>>();
assertFalse<NOR<1, 1>>();
type OR<a extends B, b extends B> = NAND<NOT<a>, NOT<b>>;
assertTrue<OR<1, 1>>();
assertTrue<OR<1, 0>>();
assertTrue<OR<0, 1>>();
assertFalse<OR<0, 0>>();
type AND<a extends B, b extends B> = NOT<NAND<a, b>>;
assertTrue<AND<1, 1>>();
assertFalse<AND<1, 0>>();
assertFalse<AND<0, 1>>();
assertFalse<AND<0, 0>>();
type NOT<a extends B> = NAND<a, a>;
assertTrue<NOT<0>>();
assertFalse<NOT<1>>();
type NAND<b1 extends B, b2 extends B> = b1 extends 1
? b2 extends 1 ? 0 : 1
: 1;
assertTrue<NAND<0, 0>>();
assertTrue<NAND<1, 0>>();
assertTrue<NAND<0, 1>>();
assertFalse<NAND<1, 1>>();
declare function assertFalse<B extends 0>(): void;
declare function assertTrue<B extends 1>(): void;
assertFalse<0>();
assertTrue<1>();
type B = 1 | 0;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment