on master help sign in
Got mat and rub working (I think)
636da10iko
elm.json+3−2
@@ -9,11 +9,12 @@
9 ],
9 ],
10 "elm-version": "0.19.0 <= v < 0.20.0",
10 "elm-version": "0.19.0 <= v < 0.20.0",
11 "dependencies": {
11 "dependencies": {
12+ "TSFoster/elm-bytes-extra": "1.3.0 <= v < 1.4.0",
12 "elm/bytes": "1.0.8 <= v < 2.0.0",
13 "elm/bytes": "1.0.8 <= v < 2.0.0",
13− "elm/core": "1.0.0 <= v < 1.0.5"
14+ "elm/core": "1.0.0 <= v < 1.0.5",
15+ "elm-community/list-extra": "8.7.0 <= v < 9.0.0"
14 },
16 },
15 "test-dependencies": {
17 "test-dependencies": {
16− "TSFoster/elm-bytes-extra": "1.3.0 <= v < 1.4.0",
17 "elm-explorations/test": "1.0.0 <= v < 2.0.0"
18 "elm-explorations/test": "1.0.0 <= v < 2.0.0"
18 }
19 }
19}
20}
src/BitWriter.elm+16−14
@@ -1,6 +1,11 @@
1−module BitWriter exposing (..)
1+module BitWriter exposing
2+ ( BitWriter
3+ , bit
4+ , bits
5+ , empty
6+ , run
7+ )
2
8
3−import BitParser as BP
4import Bitwise
9import Bitwise
5import Bytes exposing (Bytes)
10import Bytes exposing (Bytes)
6import Bytes.Encode as BE
11import Bytes.Encode as BE
@@ -67,15 +72,12 @@ bits bs writer =
67
72
68
73
69
74
70−-- PERF: don't go through BitParser to not hold all bits in memory
75+-- -- PERF: don't go through BitParser to not hold all bits in memory
71−
72−
73−bytes : Bytes -> BitWriter -> BitWriter
76+-- bytes : Bytes -> BitWriter -> BitWriter
74−bytes bite writer =
77+-- bytes bite writer =
75− case BP.run (BP.rawBits (Bytes.width bite * 8)) bite of
78+-- case BP.run (BP.rawBits (Bytes.width bite * 8)) bite of
76− -- this is bad, but shouldn't happen
79+-- -- this is bad, but shouldn't happen
77− Nothing ->
80+-- Nothing ->
78− writer
81+-- writer
79−
80− Just bs ->
82+-- Just bs ->
81− bits bs writer
83+-- bits bs writer
src/Urbit.elm+51−8
@@ -1,9 +1,11 @@
1−module Urbit exposing (..)
1+module Urbit exposing (Noun(..), mat, rub)
2
2
3import BitParser as BP exposing (BitParser)
3import BitParser as BP exposing (BitParser)
4+import BitWriter as BW exposing (BitWriter)
5+import Bitwise
4import Bytes exposing (Bytes)
6import Bytes exposing (Bytes)
5−import Bytes.Decode as BD
7+import Bytes.Extra as Bytes
6−import Bytes.Encode as BE
8+import List.Extra as List
7
9
8
10
9type Noun
11type Noun
@@ -11,13 +13,39 @@ type Noun
11 | Atom Bytes
13 | Atom Bytes
12
14
13
15
16+isSig : Bytes -> Bool
17+isSig bytes =
18+ Bytes.toByteValues bytes |> List.all (\x -> x == 0)
19+
20+
21+mat : Bytes -> BitWriter -> BitWriter
22+mat bytes writer =
23+ if isSig bytes then
24+ writer |> BW.bit 1
25+
26+ else
27+ let
28+ bits =
29+ bytesToBits bytes |> List.dropWhileRight (\x -> x == 0)
30+
31+ lengthBits =
32+ bits |> List.length |> intToBits |> List.reverse |> List.drop 1 |> List.reverse
33+ in
34+ writer
35+ |> BW.bit 0
36+ |> BW.bits (List.repeat (List.length lengthBits) 0)
37+ |> BW.bit 1
38+ |> BW.bits lengthBits
39+ |> BW.bits bits
40+
41+
14rub : BitParser Bytes
42rub : BitParser Bytes
15rub =
43rub =
16 BP.bit
44 BP.bit
17 |> BP.andThen
45 |> BP.andThen
18 (\zeroBit ->
46 (\zeroBit ->
19 if zeroBit == 1 then
47 if zeroBit == 1 then
20− BP.succeed (BE.unsignedInt8 0 |> BE.encode)
48+ BP.succeed Bytes.empty
21
49
22 else
50 else
23 let
51 let
@@ -40,7 +68,7 @@ rub =
40 (\preLengthRawBits ->
68 (\preLengthRawBits ->
41 let
69 let
42 length =
70 length =
43− BP.bitsToInt (1 :: preLengthRawBits)
71+ BP.bitsToInt (preLengthRawBits ++ [ 1 ])
44 in
72 in
45 BP.bits length
73 BP.bits length
46 )
74 )
@@ -48,7 +76,22 @@ rub =
48 )
76 )
49
77
50
78
79+bytesToBits : Bytes -> List Int
80+bytesToBits bytes =
81+ case
82+ BP.run (BP.rawBits (Bytes.width bytes * 8)) bytes
83+ of
84+ Nothing ->
85+ []
86+
87+ Just bits ->
88+ bits
89+
90+
91+intToBits : Int -> List Int
92+intToBits n =
93+ if n <= 0 then
94+ []
51
95
52−-- met : BitParser Bytes
96+ else
53−-- met =
97+ Bitwise.and 1 n :: intToBits (Bitwise.shiftRightBy 1 n)
54−-- 1
tests/Test/BitParser.elm → tests/Test/Bit.elmrenamed+4−22
@@ -1,13 +1,11 @@
1−module Test.BitParser exposing (tests)
1+module Test.Bit exposing (tests)
2
2
3import BitParser
3import BitParser
4import BitWriter
4import BitWriter
5−import Bytes exposing (Bytes)
5+import Bytes
6−import Bytes.Encode as BE
7−import Bytes.Extra
8−import Expect exposing (Expectation)
6+import Expect
9−import Fuzz exposing (Fuzzer)
10import Test exposing (..)
7import Test exposing (..)
8+import Test.Utils exposing (..)
11
9
12
10
13tests : Test
11tests : Test
@@ -37,19 +35,3 @@ tests =
37 )
35 )
38 ]
36 ]
39 ]
37 ]
40−
41−
42−bytes : Fuzzer Bytes
43−bytes =
44− (Fuzz.intRange 0 255 |> Fuzz.list)
45− |> Fuzz.map (\l -> l |> List.map BE.unsignedInt8 |> BE.sequence |> BE.encode)
46−
47−
48−bytesEq : Bytes -> Bytes -> Expectation
49−bytesEq a b =
50− Expect.equal (Bytes.Extra.toByteValues a) (Bytes.Extra.toByteValues b)
51−
52−
53−maybeBytesEq : Maybe Bytes -> Maybe Bytes -> Expectation
54−maybeBytesEq a b =
55− Expect.equal (Maybe.map Bytes.Extra.toByteValues a) (Maybe.map Bytes.Extra.toByteValues b)
tests/Test/Urbit.elmnew file+40
@@ -0,0 +1,40 @@
1+module Test.Urbit exposing (tests)
2+
3+import BitParser
4+import BitWriter
5+import Bytes exposing (Bytes)
6+import Bytes.Extra as Bytes
7+import Fuzz exposing (Fuzzer)
8+import List.Extra as List
9+import Test exposing (..)
10+import Test.Utils exposing (..)
11+import Urbit exposing (..)
12+
13+
14+tests : Test
15+tests =
16+ concat
17+ [ fuzz atom
18+ "mat <-> rub"
19+ (\a ->
20+ maybeBytesEq (Just a) (BitWriter.run (mat a BitWriter.empty) |> BitParser.run rub)
21+ )
22+ ]
23+
24+
25+atom : Fuzzer Bytes
26+atom =
27+ bytes
28+ |> Fuzz.map
29+ (\a -> a |> Bytes.toByteValues |> List.dropWhileRight (\x -> x == 0) |> Bytes.fromByteValues)
30+
31+
32+noun : Fuzzer Noun
33+noun =
34+ (\() ->
35+ Fuzz.oneOf
36+ [ bytes |> Fuzz.map Atom
37+ , Fuzz.map2 (\a b -> Cell ( a, b )) noun noun
38+ ]
39+ )
40+ ()
tests/Test/Utils.elmnew file+24
@@ -0,0 +1,24 @@
1+module Test.Utils exposing (..)
2+
3+import Bytes exposing (Bytes)
4+import Bytes.Encode as BE
5+import Bytes.Extra
6+import Expect exposing (Expectation)
7+import Fuzz exposing (Fuzzer)
8+import Test exposing (..)
9+
10+
11+bytes : Fuzzer Bytes
12+bytes =
13+ (Fuzz.intRange 0 255 |> Fuzz.list)
14+ |> Fuzz.map (\l -> l |> List.map BE.unsignedInt8 |> BE.sequence |> BE.encode)
15+
16+
17+bytesEq : Bytes -> Bytes -> Expectation
18+bytesEq a b =
19+ Expect.equal (Bytes.Extra.toByteValues a) (Bytes.Extra.toByteValues b)
20+
21+
22+maybeBytesEq : Maybe Bytes -> Maybe Bytes -> Expectation
23+maybeBytesEq a b =
24+ Expect.equal (Maybe.map Bytes.Extra.toByteValues a) (Maybe.map Bytes.Extra.toByteValues b)