Got mat and rub working (I think)

This commit is contained in:
iko 2023-05-27 19:51:16 +03:00
parent 3c6e943097
commit 636da105d6
Signed by untrusted user: iko
GPG Key ID: 82C257048D1026F2
6 changed files with 138 additions and 46 deletions

View File

@ -9,11 +9,12 @@
],
"elm-version": "0.19.0 <= v < 0.20.0",
"dependencies": {
"TSFoster/elm-bytes-extra": "1.3.0 <= v < 1.4.0",
"elm/bytes": "1.0.8 <= v < 2.0.0",
"elm/core": "1.0.0 <= v < 1.0.5"
"elm/core": "1.0.0 <= v < 1.0.5",
"elm-community/list-extra": "8.7.0 <= v < 9.0.0"
},
"test-dependencies": {
"TSFoster/elm-bytes-extra": "1.3.0 <= v < 1.4.0",
"elm-explorations/test": "1.0.0 <= v < 2.0.0"
}
}

View File

@ -1,6 +1,11 @@
module BitWriter exposing (..)
module BitWriter exposing
( BitWriter
, bit
, bits
, empty
, run
)
import BitParser as BP
import Bitwise
import Bytes exposing (Bytes)
import Bytes.Encode as BE
@ -67,15 +72,12 @@ bits bs writer =
-- PERF: don't go through BitParser to not hold all bits in memory
bytes : Bytes -> BitWriter -> BitWriter
bytes bite writer =
case BP.run (BP.rawBits (Bytes.width bite * 8)) bite of
-- this is bad, but shouldn't happen
Nothing ->
writer
Just bs ->
bits bs writer
-- -- PERF: don't go through BitParser to not hold all bits in memory
-- bytes : Bytes -> BitWriter -> BitWriter
-- bytes bite writer =
-- case BP.run (BP.rawBits (Bytes.width bite * 8)) bite of
-- -- this is bad, but shouldn't happen
-- Nothing ->
-- writer
-- Just bs ->
-- bits bs writer

View File

@ -1,9 +1,11 @@
module Urbit exposing (..)
module Urbit exposing (Noun(..), mat, rub)
import BitParser as BP exposing (BitParser)
import BitWriter as BW exposing (BitWriter)
import Bitwise
import Bytes exposing (Bytes)
import Bytes.Decode as BD
import Bytes.Encode as BE
import Bytes.Extra as Bytes
import List.Extra as List
type Noun
@ -11,13 +13,39 @@ type Noun
| Atom Bytes
isSig : Bytes -> Bool
isSig bytes =
Bytes.toByteValues bytes |> List.all (\x -> x == 0)
mat : Bytes -> BitWriter -> BitWriter
mat bytes writer =
if isSig bytes then
writer |> BW.bit 1
else
let
bits =
bytesToBits bytes |> List.dropWhileRight (\x -> x == 0)
lengthBits =
bits |> List.length |> intToBits |> List.reverse |> List.drop 1 |> List.reverse
in
writer
|> BW.bit 0
|> BW.bits (List.repeat (List.length lengthBits) 0)
|> BW.bit 1
|> BW.bits lengthBits
|> BW.bits bits
rub : BitParser Bytes
rub =
BP.bit
|> BP.andThen
(\zeroBit ->
if zeroBit == 1 then
BP.succeed (BE.unsignedInt8 0 |> BE.encode)
BP.succeed Bytes.empty
else
let
@ -40,7 +68,7 @@ rub =
(\preLengthRawBits ->
let
length =
BP.bitsToInt (1 :: preLengthRawBits)
BP.bitsToInt (preLengthRawBits ++ [ 1 ])
in
BP.bits length
)
@ -48,7 +76,22 @@ rub =
)
bytesToBits : Bytes -> List Int
bytesToBits bytes =
case
BP.run (BP.rawBits (Bytes.width bytes * 8)) bytes
of
Nothing ->
[]
-- met : BitParser Bytes
-- met =
-- 1
Just bits ->
bits
intToBits : Int -> List Int
intToBits n =
if n <= 0 then
[]
else
Bitwise.and 1 n :: intToBits (Bitwise.shiftRightBy 1 n)

View File

@ -1,13 +1,11 @@
module Test.BitParser exposing (tests)
module Test.Bit exposing (tests)
import BitParser
import BitWriter
import Bytes exposing (Bytes)
import Bytes.Encode as BE
import Bytes.Extra
import Expect exposing (Expectation)
import Fuzz exposing (Fuzzer)
import Bytes
import Expect
import Test exposing (..)
import Test.Utils exposing (..)
tests : Test
@ -37,19 +35,3 @@ tests =
)
]
]
bytes : Fuzzer Bytes
bytes =
(Fuzz.intRange 0 255 |> Fuzz.list)
|> Fuzz.map (\l -> l |> List.map BE.unsignedInt8 |> BE.sequence |> BE.encode)
bytesEq : Bytes -> Bytes -> Expectation
bytesEq a b =
Expect.equal (Bytes.Extra.toByteValues a) (Bytes.Extra.toByteValues b)
maybeBytesEq : Maybe Bytes -> Maybe Bytes -> Expectation
maybeBytesEq a b =
Expect.equal (Maybe.map Bytes.Extra.toByteValues a) (Maybe.map Bytes.Extra.toByteValues b)

40
tests/Test/Urbit.elm Normal file
View File

@ -0,0 +1,40 @@
module Test.Urbit exposing (tests)
import BitParser
import BitWriter
import Bytes exposing (Bytes)
import Bytes.Extra as Bytes
import Fuzz exposing (Fuzzer)
import List.Extra as List
import Test exposing (..)
import Test.Utils exposing (..)
import Urbit exposing (..)
tests : Test
tests =
concat
[ fuzz atom
"mat <-> rub"
(\a ->
maybeBytesEq (Just a) (BitWriter.run (mat a BitWriter.empty) |> BitParser.run rub)
)
]
atom : Fuzzer Bytes
atom =
bytes
|> Fuzz.map
(\a -> a |> Bytes.toByteValues |> List.dropWhileRight (\x -> x == 0) |> Bytes.fromByteValues)
noun : Fuzzer Noun
noun =
(\() ->
Fuzz.oneOf
[ bytes |> Fuzz.map Atom
, Fuzz.map2 (\a b -> Cell ( a, b )) noun noun
]
)
()

24
tests/Test/Utils.elm Normal file
View File

@ -0,0 +1,24 @@
module Test.Utils exposing (..)
import Bytes exposing (Bytes)
import Bytes.Encode as BE
import Bytes.Extra
import Expect exposing (Expectation)
import Fuzz exposing (Fuzzer)
import Test exposing (..)
bytes : Fuzzer Bytes
bytes =
(Fuzz.intRange 0 255 |> Fuzz.list)
|> Fuzz.map (\l -> l |> List.map BE.unsignedInt8 |> BE.sequence |> BE.encode)
bytesEq : Bytes -> Bytes -> Expectation
bytesEq a b =
Expect.equal (Bytes.Extra.toByteValues a) (Bytes.Extra.toByteValues b)
maybeBytesEq : Maybe Bytes -> Maybe Bytes -> Expectation
maybeBytesEq a b =
Expect.equal (Maybe.map Bytes.Extra.toByteValues a) (Maybe.map Bytes.Extra.toByteValues b)