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", "elm-version": "0.19.0 <= v < 0.20.0",
"dependencies": { "dependencies": {
"TSFoster/elm-bytes-extra": "1.3.0 <= v < 1.4.0",
"elm/bytes": "1.0.8 <= v < 2.0.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": { "test-dependencies": {
"TSFoster/elm-bytes-extra": "1.3.0 <= v < 1.4.0",
"elm-explorations/test": "1.0.0 <= v < 2.0.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 Bitwise
import Bytes exposing (Bytes) import Bytes exposing (Bytes)
import Bytes.Encode as BE 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 -- -- PERF: don't go through BitParser to not hold all bits in memory
-- bytes : Bytes -> BitWriter -> BitWriter
-- bytes bite writer =
bytes : Bytes -> BitWriter -> BitWriter -- case BP.run (BP.rawBits (Bytes.width bite * 8)) bite of
bytes bite writer = -- -- this is bad, but shouldn't happen
case BP.run (BP.rawBits (Bytes.width bite * 8)) bite of -- Nothing ->
-- this is bad, but shouldn't happen -- writer
Nothing -> -- Just bs ->
writer -- bits bs 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 BitParser as BP exposing (BitParser)
import BitWriter as BW exposing (BitWriter)
import Bitwise
import Bytes exposing (Bytes) import Bytes exposing (Bytes)
import Bytes.Decode as BD import Bytes.Extra as Bytes
import Bytes.Encode as BE import List.Extra as List
type Noun type Noun
@ -11,13 +13,39 @@ type Noun
| Atom Bytes | 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 : BitParser Bytes
rub = rub =
BP.bit BP.bit
|> BP.andThen |> BP.andThen
(\zeroBit -> (\zeroBit ->
if zeroBit == 1 then if zeroBit == 1 then
BP.succeed (BE.unsignedInt8 0 |> BE.encode) BP.succeed Bytes.empty
else else
let let
@ -40,7 +68,7 @@ rub =
(\preLengthRawBits -> (\preLengthRawBits ->
let let
length = length =
BP.bitsToInt (1 :: preLengthRawBits) BP.bitsToInt (preLengthRawBits ++ [ 1 ])
in in
BP.bits length 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 Just bits ->
-- met = bits
-- 1
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 BitParser
import BitWriter import BitWriter
import Bytes exposing (Bytes) import Bytes
import Bytes.Encode as BE import Expect
import Bytes.Extra
import Expect exposing (Expectation)
import Fuzz exposing (Fuzzer)
import Test exposing (..) import Test exposing (..)
import Test.Utils exposing (..)
tests : Test 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)