diff options
author | Marvin Borner | 2023-02-24 15:36:59 +0100 |
---|---|---|
committer | Marvin Borner | 2023-02-24 15:39:24 +0100 |
commit | 1fcb81203e886b6b1e851a94c5fb301c9d33ec89 (patch) | |
tree | 492158ebbabf6fda933a969373fdf5b5d55a92ed /std/Binary.bruijn | |
parent | c371838c15ab245bd9b1db3947747c431a95040e (diff) |
Moved number implementations
Diffstat (limited to 'std/Binary.bruijn')
-rw-r--r-- | std/Binary.bruijn | 252 |
1 files changed, 0 insertions, 252 deletions
diff --git a/std/Binary.bruijn b/std/Binary.bruijn deleted file mode 100644 index ec62e60..0000000 --- a/std/Binary.bruijn +++ /dev/null @@ -1,252 +0,0 @@ -# MIT License, Copyright (c) 2023 Marvin Borner -# TODO: Use abstract representation for logic instead of listifying - -:import std/Combinator . -:import std/List . -:import std/Logic . - -# bit indicating a one, compatible with std/Logic -b¹ true ⧗ Bit - -# bit indicating a zero, compatible with std/Logic -b⁰ false ⧗ Bit - -# returns true if a bit is set -b¹? i ⧗ Bit → Boolean - -:test (b¹? b¹) (true) -:test (b¹? b⁰) (false) - -# returns true if a bit is unset -b⁰? not! ⧗ Bit → Boolean - -:test (b⁰? b⁰) (true) -:test (b⁰? b¹) (false) - -# shifts a one into a binary number -↑¹‣ [[[[1 (3 2 1 0)]]]] ⧗ Binary → Binary - -:test (↑¹[[[0 2]]]) ([[[1 (0 2)]]]) - -# shifts a zero into a binary number -↑⁰‣ [[[[0 (3 2 1 0)]]]] ⧗ Binary → Binary - -:test (↑⁰(+1b)) ((+2b)) - -# shifts a specified bit into a binary number -up [[[[[4 1 0 (3 2 1 0)]]]]] ⧗ Bit → Binary → Binary - -:test (up b¹ [[[0 2]]]) ([[[1 (0 2)]]]) -:test (up b⁰ (+1b)) ((+2b)) - -# converts a binary number to a list of bits -list! [0 z a¹ a⁰] ⧗ Binary → (List Bit) - z empty - a¹ [b¹ : 0] - a⁰ [b⁰ : 0] - -:test (list! (+0b)) (empty) -:test (list! (+6b)) (b⁰ : (b¹ : (b¹ : empty))) - -# converts a list of bits to a binary number -binary! foldr up (+0b) ⧗ (List Bit) → Binary - -:test (binary! (list! (+0b))) ((+0b)) -:test (binary! (list! (+42b))) ((+42b)) - -# strips leading 0s from a binary number -strip [^(0 z a¹ a⁰)] ⧗ Binary → Binary - z (+0b) : true - a¹ [0 [[↑¹1 : false]]] - a⁰ [0 [[(0 (+0b) ↑⁰1) : 0]]] - -%‣ strip - -:test (%[[[0 2]]]) ((+0b)) -:test (%[[[1 (0 (0 (0 (0 2))))]]]) ((+1b)) -:test (%(+2b)) ((+2b)) - -# returns true if a binary number is zero -zero? [0 true [false] i] ⧗ Binary → Boolean - -=?‣ zero? - -:test (=?(+0b)) (true) -:test (=?[[[0 (0 2)]]]) (true) -:test (=?(+1b)) (false) - -# extracts least significant bit from a binary number -lst [0 b⁰ [b¹] [b⁰]] ⧗ Binary → Bit - -:test (lst (+0b)) (b⁰) -:test (lst (+1b)) (b¹) -:test (lst (+42b)) (b⁰) - -# extracts most significant bit from a binary number -# not really useful for binary numbers, but part of interface -mst [=?0 b⁰ ^(<~>(list! %0))] ⧗ Binary → Bit - -:test (mst (+0b)) (b⁰) -:test (mst (+1b)) (b¹) -:test (mst (+42b)) (b¹) - -# extracts nth bit from a binary number -nth …!!… ∘ list! ⧗ Binary → Number → Bit - -# logical and on two binary numbers -and! binary! ∘∘ (ψ* zip-with …⋀?… list!) ⧗ Binary → Binary → Binary - -…⋀!… and! - -:test (and! (+1b) (+0b)) ((+0b)) -:test (and! (+5b) (+4b)) ((+4b)) -:test (and! (+10b) (+12b)) ((+8b)) - -# logical or on two binary numbers -# TODO: Fix for numbers with different length (→ zero padding?) -or! binary! ∘∘ (ψ* zip-with …⋁?… list!) ⧗ Binary → Binary → Binary - -…⋁!… or! - -:test (or! (+10b) (+12b)) ((+14b)) - -# :test (or! (+1b) (+0b)) ((+1b)) -# :test (or! (+5b) (+3b)) ((+7b)) - -# converts the normal binary representation into abstract -abstract! [0 z a¹ a⁰] ⧗ Binary → AbstractBinary - z (+0b) - a¹ [[[[1 3]]]] - a⁰ [[[[0 3]]]] - -→^‣ abstract! - -:test (→^(+2b)) ([[[0 [[[1 [[[2]]]]]]]]]) - -# converts the abstracted binary representation back to normal -normal! ω [[0 z a¹ a⁰]] ⧗ AbstractBinary → Binary - z (+0b) - a¹ [↑¹([3 3 0] 0)] - a⁰ [↑⁰([3 3 0] 0)] - -→_‣ normal! - -:test (→_[[[0 [[[1 [[[2]]]]]]]]]) ((+2b)) - -# returns true if two binary numbers are equal -# → ignores leading 0s! -# also: ⋀?‣ ∘∘ (ψ* zip-with xnor? list!) -eq? [[abs 1 →^0]] ⧗ Binary → Binary → Boolean - abs [0 z a¹ a⁰] - z [=?(→_0)] - a¹ [[0 false [2 0] [false]]] - a⁰ [[0 (1 0) [false] [2 0]]] - -…=?… eq? - -:test ((+0b) =? (+0b)) (true) -:test ([[[1 (0 2)]]] =? [[[1 (0 2)]]]) (true) -:test ([[[1 2]]] =? (+2b)) (false) - -# returns true if two binary numbers are not equal -not-eq? not! ∘∘ eq? ⧗ Binary → Binary → Boolean - -…≠?… not-eq? - -:test ((+0b) ≠? (+0b)) (false) -:test ([[[1 (0 2)]]] ≠? [[[1 (0 2)]]]) (false) -:test ([[[1 (0 2)]]] ≠? (+2b)) (true) - -# adds 1 to a binary number (can introduce leading 0s) -inc [~(0 z a¹ a⁰)] ⧗ Binary → Binary - z (+0b) : (+1b) - a¹ [0 [[↑¹1 : ↑⁰0]]] - a⁰ [0 [[↑⁰1 : ↑¹1]]] - -++‣ inc - -:test (++(+0b)) ((+1b)) -:test (++(+2b)) ((+3b)) - -# subs 1 from a binary number (can introduce leading 0s) -dec [~(0 z a¹ a⁰)] ⧗ Binary → Binary - z (+0b) : (+0b) - a¹ [0 [[↑¹1 : ↑⁰1]]] - a⁰ [0 [[↑⁰1 : ↑¹0]]] - ---‣ dec - -:test (--(+0b)) ((+0b)) -:test (--(+1b)) ([[[0 2]]]) -:test (--(+3b)) ((+2b)) - -# flips the bits of a binary number (1's complement) -complement [[[[3 2 0 1]]]] ⧗ Binary → Binary - -~‣ complement - -:test (~(+0b) =? (+0b)) (true) -:test (~(+1b) =? (+0b)) (true) -:test (~(+42b)) ([[[1 (0 (1 (0 (1 (0 2)))))]]]) - -# inverts a binary number by complementing and incrementing (2's complement) -# don't forget to pad the number with zeroes if needed -invert ++‣ ∘ ~‣ ⧗ Binary → Binary - --‣ invert - -:test (-(+0b)) ((+1b)) -:test (-(+1b)) ((+1b)) - -# pads a binary number with zeroes until its as long a another binary number -# TODO: this could probably be done without list magic -pad [[binary! (pad-right ∀(list! %1) b⁰ (list! 0))]] ⧗ Binary → Binary → Binary - -:test (pad (+5b) [[[1 2]]]) ([[[1 (0 (0 2))]]]) - -# adds two binary numbers (can introduce leading 0s) -# second argument gets abstracted (performance) -add [[abs 1 →^0]] ⧗ Binary → Binary → Binary - abs [c (0 z a¹ a⁰)] - c¹ [1 ↑⁰(3 0 b¹) ↑¹(3 0 b⁰)] - a¹ [[[1 (c¹ 1) c¹' c¹]]] - c¹' [up 1 (3 0 b¹)] - a⁰ [[[1 (c⁰ 1) c¹ c⁰]]] - c⁰ [up 1 (3 0 b⁰)] - z [[0 ++(→_1) →_1]] - c [[1 0 b⁰]] - -…+… add - -:test ((+0b) + (+0b) =? (+0b)) (true) -:test ((+0b) + (+3b) =? (+3b)) (true) -:test ((+1b) + (+2b) =? (+3b)) (true) -:test ((+42b) + (+1b) =? (+43b)) (true) -:test ((+1b) + (+42b) =? (+43b)) (true) - -# subs two binary numbers (can introduce leading 0s) -# second argument gets abstracted (performance) -# TODO: fix sub*; implementation is completely wrong -sub* [[abs 1 →^0]] ⧗ Binary → Binary → Binary - abs [c (0 z a¹ a⁰)] - c¹ [1 ↑¹(3 0 b⁰) ↑¹(3 0 b⁰)] - a¹ [[[1 (c¹ 1) c¹' c¹]]] - c¹ [1 ↑⁰(3 0 b¹) ↑¹(3 0 b⁰)] - c¹' [1 ↑¹(3 0 b⁰) ↑¹(3 0 b⁰)] - a⁰ [[[1 (c⁰ 1) c⁰' c⁰]]] - c⁰ [1 ↑¹(3 0 b⁰) ↑⁰(3 0 b⁰)] - c⁰' [1 (3 0 b⁰) ↑¹(3 0 b¹)] - z [[0 --(→_1) →_1]] - c [[1 0 b⁰]] - -# subs two binary numbers -# uses addition but with two's complement -# TODO: isn't very performant ⇒ replace with sub* -# TODO: gives wrong results if b>=a in a-b -sub [[-((pad 1 0) + -(pad 0 1))]] ⧗ Binary → Binary → Binary - -…-… sub - -:test ((+42b) - (+12b) =? (+30b)) (true) -:test ((+3b) - (+0b) =? (+3b)) (true) -:test ((+3b) - (+2b) =? (+1b)) (true) |