From 4988fc5c0e489b708e0a6fb8b12cf35c25e83018 Mon Sep 17 00:00:00 2001 From: iko Date: Thu, 15 Jun 2023 13:51:02 +0300 Subject: [PATCH] Switched to bigint --- elm.json | 3 ++- src/BigInt/Bytes.elm | 35 +++++++++++++++++++++++++++++++++++ src/Ur/Constructor.elm | 12 +++++++----- src/Ur/Deconstructor.elm | 29 ++++++++++++----------------- src/Ur/Phonemic.elm | 14 ++------------ src/Ur/Run.elm | 8 +++++++- tests/Test/Urbit.elm | 26 ++++++++++++++++++-------- 7 files changed, 83 insertions(+), 44 deletions(-) create mode 100644 src/BigInt/Bytes.elm diff --git a/elm.json b/elm.json index 87940fa..d666a4d 100644 --- a/elm.json +++ b/elm.json @@ -11,6 +11,7 @@ "dependencies": { "TSFoster/elm-bytes-extra": "1.3.0 <= v < 1.4.0", "chelovek0v/bbase64": "1.0.1 <= v < 2.0.0", + "cmditch/elm-bigint": "2.0.1 <= v < 3.0.0", "elm/browser": "1.0.2 <= v < 2.0.0", "elm/bytes": "1.0.8 <= v < 2.0.0", "elm/core": "1.0.0 <= v < 1.0.5", @@ -20,7 +21,7 @@ "elm/url": "1.0.0 <= v < 2.0.0", "elm-community/list-extra": "8.7.0 <= v < 9.0.0", "elm-community/maybe-extra": "5.3.0 <= v < 6.0.0", - "folkertdev/elm-int64": "1.0.0 <= v < 2.0.0" + "jxxcarlson/hex": "4.0.0 <= v < 5.0.0" }, "test-dependencies": { "elm-explorations/test": "2.1.1 <= v < 3.0.0" diff --git a/src/BigInt/Bytes.elm b/src/BigInt/Bytes.elm new file mode 100644 index 0000000..c10a51b --- /dev/null +++ b/src/BigInt/Bytes.elm @@ -0,0 +1,35 @@ +module BigInt.Bytes exposing (decode, encode) + +import BigInt exposing (BigInt, toHexString) +import Bytes exposing (Bytes) +import Bytes.Extra +import Hex.Convert as Hex + + +encode : BigInt -> Bytes +encode x = + let + hexString = + toHexString x + + paddedHexString = + if modBy 2 (String.length hexString) == 0 then + hexString + + else + "0" ++ hexString + in + Hex.toBytes paddedHexString + |> Maybe.map (Bytes.Extra.toByteValues >> List.reverse >> Bytes.Extra.fromByteValues) + |> Maybe.withDefault Bytes.Extra.empty + + +decode : Bytes -> BigInt +decode bs = + bs + |> Bytes.Extra.toByteValues + |> List.reverse + |> Bytes.Extra.fromByteValues + |> Hex.toString + |> BigInt.fromHexString + |> Maybe.withDefault (BigInt.fromInt 0) diff --git a/src/Ur/Constructor.elm b/src/Ur/Constructor.elm index 7718849..ff2390c 100644 --- a/src/Ur/Constructor.elm +++ b/src/Ur/Constructor.elm @@ -1,21 +1,23 @@ module Ur.Constructor exposing ( Constructor + , bigint + , bytes , cell , cord , float32 , float64 , int - , int64 , listOf , sig , signedInt , tape ) +import BigInt exposing (BigInt) +import BigInt.Bytes import Bitwise import Bytes exposing (Bytes, Endianness(..)) import Bytes.Encode as BE -import Int64 exposing (Int64) import Ur exposing (..) @@ -44,9 +46,9 @@ int i = ) -int64 : Int64 -> Noun -int64 i = - Atom (BE.encode (Int64.encoder LE i)) +bigint : BigInt -> Noun +bigint x = + Atom (BigInt.Bytes.encode x) signedInt : Int -> Noun diff --git a/src/Ur/Deconstructor.elm b/src/Ur/Deconstructor.elm index 4a9ae82..31513b5 100644 --- a/src/Ur/Deconstructor.elm +++ b/src/Ur/Deconstructor.elm @@ -1,14 +1,15 @@ module Ur.Deconstructor exposing ( Deconstructor , alt + , bigint , bytes , cell , const , cord , float32 , float64 + , ignore , int - , int64 , list , llec , map @@ -21,12 +22,13 @@ module Ur.Deconstructor exposing , tar ) +import BigInt exposing (BigInt) +import BigInt.Bytes import Bitwise import Bytes exposing (Bytes, Endianness(..)) import Bytes.Decode as BD import Bytes.Encode as BE import Bytes.Extra -import Int64 exposing (Int64) import Ur exposing (..) @@ -111,25 +113,13 @@ int = ) -int64 : Deconstructor (Int64 -> a) a -int64 = +bigint : Deconstructor (BigInt -> a) a +bigint = Deconstructor (\x f -> case x of Atom bs -> - let - width = - Bytes.width bs - in - if width > 8 then - Nothing - - else - BD.decode (Int64.decoder LE) - (BE.encode - (BE.sequence (BE.bytes bs :: List.repeat (8 - width) (BE.unsignedInt8 0))) - ) - |> Maybe.map f + BigInt.Bytes.decode bs |> f |> Just Cell _ -> Nothing @@ -252,6 +242,11 @@ tar = Deconstructor (\noun f -> Just (f noun)) +ignore : Deconstructor a a +ignore = + Deconstructor (\_ f -> Just f) + + llec : Deconstructor a b -> Deconstructor b c -> Deconstructor a c llec (Deconstructor r) (Deconstructor l) = Deconstructor diff --git a/src/Ur/Phonemic.elm b/src/Ur/Phonemic.elm index 665e882..5ecf169 100644 --- a/src/Ur/Phonemic.elm +++ b/src/Ur/Phonemic.elm @@ -1,6 +1,7 @@ module Ur.Phonemic exposing (Ship, fromString) import BigInt exposing (toHexString) +import BigInt.Bytes import Bytes.Extra import Hex.Convert as Hex import Ur exposing (Atom, Noun(..)) @@ -23,18 +24,7 @@ fromString : Ship -> Atom fromString s = case fromPatp s of Ok atom -> - let - hexString = - toBigInt atom |> toHexString - - paddedHexString = - if modBy 2 (String.length hexString) == 0 then - hexString - - else - "0" ++ hexString - in - Hex.toBytes paddedHexString |> Maybe.withDefault Bytes.Extra.empty + toBigInt atom |> BigInt.Bytes.encode Err _ -> Bytes.Extra.empty diff --git a/src/Ur/Run.elm b/src/Ur/Run.elm index 33c67f5..a8778cb 100644 --- a/src/Ur/Run.elm +++ b/src/Ur/Run.elm @@ -192,7 +192,13 @@ update inp msg model = EventSourceMsg value -> case JD.decodeValue (JD.field "message" JD.string) value of Ok string -> - case D.runBytes (D.cell D.int (D.cell D.cord D.tar) |> D.map (\a b c -> ( a, b, c ) |> Debug.log "event")) (Ur.Uw.decode string) of + case + D.runBytes + (D.cell D.int (D.cell D.cord D.tar) + |> D.map (\a b c -> ( a, b, c )) + ) + (Ur.Uw.decode string) + of Just ( messageId, messageType, rest ) -> let ( eventId, ackReqs ) = diff --git a/tests/Test/Urbit.elm b/tests/Test/Urbit.elm index 96dc929..88700a5 100644 --- a/tests/Test/Urbit.elm +++ b/tests/Test/Urbit.elm @@ -1,12 +1,13 @@ module Test.Urbit exposing (tests) +import BigInt exposing (BigInt) +import BigInt.Bytes import BitParser import BitWriter import Bytes exposing (Bytes) import Bytes.Extra as Bytes import Expect exposing (Expectation) import Fuzz exposing (Fuzzer) -import Int64 exposing (Int64) import List.Extra as List import Test exposing (..) import Test.Utils exposing (..) @@ -83,9 +84,9 @@ tests = Expect.equal (Just "1686761906334") (D.runBytes - D.int64 + D.bigint (Bytes.fromByteValues [ 0x80, 0xC9, 0x13, 0x04, 0x5B, 0x17, 0x31 ]) - |> Maybe.map Int64.toUnsignedString + |> Maybe.map BigInt.toString ) ) , test "[4 ~[1 2 3]]" @@ -161,7 +162,7 @@ tests = (Bytes.fromByteValues [ 0xC1, 0x20, 0xE4, 0x01 ]) ) ) - , test "65.600" + , test "Int 65.600" (\() -> Expect.equal (Just 65600) @@ -170,6 +171,15 @@ tests = (Bytes.fromByteValues [ 0xC0, 0x00, 0x02, 0x08 ]) ) ) + , test "BigInt 65.600" + (\() -> + Expect.equal + (Just (BigInt.fromInt 65600)) + (D.runBytes + D.bigint + (Bytes.fromByteValues [ 0xC0, 0x00, 0x02, 0x08 ]) + ) + ) ] , describe "Constructor <-> Deconstructor" [ Test.fuzz @@ -215,7 +225,7 @@ tests = (C.tape x) ) ) - , Test.fuzz int64 "int64" (\x -> Expect.equal (Just x) (D.run D.int64 (C.int64 x))) + , Test.fuzz bigint "bigint" (\x -> Expect.equal (Just x) (D.run D.bigint (C.bigint x))) ] , Test.describe "Ur.Uw" [ Test.fuzz atom @@ -268,6 +278,6 @@ noun () = ] -int64 : Fuzzer Int64 -int64 = - Fuzz.int |> Fuzz.andThen (\a -> Fuzz.int |> Fuzz.map (Int64.fromInt32s a)) +bigint : Fuzzer BigInt +bigint = + bytes |> Fuzz.map BigInt.Bytes.decode