@@ -1,9 +1,11 @@
1−module Urbit exposing (..)
1+module Urbit exposing (Noun(..), mat, rub)
22
33import BitParser as BP exposing (BitParser)
4+import BitWriter as BW exposing (BitWriter)
5+import Bitwise
46import Bytes exposing (Bytes)
5−import Bytes.Decode as BD
6−import Bytes.Encode as BE
7+import Bytes.Extra as Bytes
8+import List.Extra as List
79
810
911type Noun
@@ -11,13 +13,39 @@ type Noun
1113 | Atom Bytes
1214
1315
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+
1442rub : BitParser Bytes
1543rub =
1644 BP.bit
1745 |> BP.andThen
1846 (\zeroBit ->
1947 if zeroBit == 1 then
20− BP.succeed (BE.unsignedInt8 0 |> BE.encode)
48+ BP.succeed Bytes.empty
2149
2250 else
2351 let
@@ -40,7 +68,7 @@ rub =
4068 (\preLengthRawBits ->
4169 let
4270 length =
43− BP.bitsToInt (1 :: preLengthRawBits)
71+ BP.bitsToInt (preLengthRawBits ++ [ 1 ])
4472 in
4573 BP.bits length
4674 )
@@ -48,7 +76,22 @@ rub =
4876 )
4977
5078
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+ []
5195
52−-- met : BitParser Bytes
53−-- met =
54−-- 1
96+ else
97+ Bitwise.and 1 n :: intToBits (Bitwise.shiftRightBy 1 n)