Skip to content

Commit

Permalink
Introduce Pine_kernel.bit_and to optimize encoding and decoding
Browse files Browse the repository at this point in the history
Enable more compact reference representations of functions for encoding and decoding Bytes.
  • Loading branch information
Viir committed Oct 6, 2024
1 parent 8925d3c commit b9a3e82
Show file tree
Hide file tree
Showing 13 changed files with 163 additions and 11 deletions.
58 changes: 58 additions & 0 deletions implement/Pine.Core/KernelFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,64 @@ public static PineValue is_sorted_ascending_int(PineValue value)
throw new NotImplementedException("Unexpected value type: " + value.GetType().FullName);
}

public static PineValue bit_and(PineValue value)
{
if (value is not PineValue.ListValue argumentsList)
{
return PineValue.EmptyList;
}

if (argumentsList.Elements.Count is 0)
{
return PineValue.EmptyList;
}

if (argumentsList.Elements[0] is not PineValue.BlobValue firstBlob)
{
return PineValue.EmptyList;
}

if (argumentsList.Elements.Count is 1)
{
return firstBlob;
}

var workspace = firstBlob.Bytes.ToArray();

var remainingLength = workspace.Length;

for (var i = 1; i < argumentsList.Elements.Count; ++i)
{
if (argumentsList.Elements[i] is not PineValue.BlobValue blobValue)
{
return PineValue.EmptyList;
}

var currentLength = blobValue.Bytes.Length;

if (remainingLength < currentLength)
{
currentLength = remainingLength;
}

for (var j = 0; j < currentLength; ++j)
{
workspace[j] &= blobValue.Bytes.Span[j];
}

remainingLength = currentLength;
}

var truncated = workspace;

if (remainingLength < truncated.Length)
{
truncated = truncated[..remainingLength];
}

return PineValue.Blob(truncated);
}

private static PineValue KernelFunctionExpectingListOfBigIntAndProducingBigInt(
Func<IReadOnlyList<BigInteger>, BigInteger> aggregate,
PineValue value) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2984,5 +2984,17 @@ partition isGood (Set_elm_builtin dict) =
in
(Set_elm_builtin dict1, Set_elm_builtin dict2)
"""
, """
module Bitwise exposing
( and, or, xor, complement
, shiftLeftBy, shiftRightBy, shiftRightZfBy
)
and : Int -> Int -> Int
and a b =
Pine_kernel.bit_and [ a, b ]
"""
]
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,10 @@ sequence builders =
string : String -> Encoder
string (String chars)=
string (String chars) =
let
blob =
encodeCharsAsBlob chars
blob =
encodeCharsAsBlob chars
in
BytesEncoder (Bytes.Elm_Bytes blob)
Expand Down Expand Up @@ -150,10 +150,16 @@ encodeCharsAsBlobRec prefix chars =
-- 2-byte encoding
let
byte1 =
0xC0 + (code // 64)
Pine_kernel.add_int
[ 0xC0
, code // 64
]
byte2 =
0x80 + modBy 64 code
Pine_kernel.add_int
[ 0x80
, Pine_kernel.bit_and [ 63, code ]
]
in
Pine_kernel.concat
[ Pine_kernel.take [ 1, Pine_kernel.reverse byte1 ]
Expand All @@ -167,10 +173,16 @@ encodeCharsAsBlobRec prefix chars =
0xE0 + (code // 4096)
byte2 =
0x80 + modBy 64 (code // 64)
Pine_kernel.add_int
[ 0x80
, Pine_kernel.bit_and [ 63, code // 64 ]
]
byte3 =
0x80 + modBy 64 code
Pine_kernel.add_int
[ 0x80
, Pine_kernel.bit_and [ 63, code ]
]
in
Pine_kernel.concat
[ Pine_kernel.take [ 1, Pine_kernel.reverse byte1 ]
Expand All @@ -182,16 +194,28 @@ encodeCharsAsBlobRec prefix chars =
-- 4-byte encoding for code points >= 0x10000
let
byte1 =
0xF0 + (code // 262144)
Pine_kernel.add_int
[ 0xF0
, code // 262144
]
byte2 =
0x80 + modBy 64 (code // 4096)
Pine_kernel.add_int
[ 0x80
, Pine_kernel.bit_and [ 63, code // 4096 ]
]
byte3 =
0x80 + modBy 64 (code // 64)
Pine_kernel.add_int
[ 0x80
, Pine_kernel.bit_and [ 63, code // 64 ]
]
byte4 =
0x80 + modBy 64 code
Pine_kernel.add_int
[ 0x80
, Pine_kernel.bit_and [ 63, code ]
]
in
Pine_kernel.concat
[ Pine_kernel.take [ 1, Pine_kernel.reverse byte1 ]
Expand Down
47 changes: 47 additions & 0 deletions implement/pine/ElmTime/compile-elm-program/src/Pine.elm
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ module Pine exposing
)

import BigInt
import Bitwise
import Dict
import Hex

Expand Down Expand Up @@ -235,6 +236,9 @@ kernelFunctions =
, ( "is_sorted_ascending_int"
, kernelFunction_is_sorted_ascending_int
)
, ( "bit_and"
, kernelFunction_bit_and
)
]


Expand Down Expand Up @@ -467,6 +471,49 @@ kernelFunction_is_sorted_ascending_int value =
is_sorted_ascending_int_recursive rest firstInt


kernelFunction_bit_and : Value -> Value
kernelFunction_bit_and value =
case value of
ListValue ((BlobValue first) :: rest) ->
kernelFunction_bit_and_recursive first rest

_ ->
listValue_Empty


kernelFunction_bit_and_recursive : List Int -> List Value -> Value
kernelFunction_bit_and_recursive blob arguments =
case arguments of
next :: rest ->
case next of
BlobValue nextBlob ->
kernelFunction_bit_and_recursive (bit_and_tuple [] blob nextBlob) rest

_ ->
listValue_Empty

[] ->
BlobValue blob


bit_and_tuple : List Int -> List Int -> List Int -> List Int
bit_and_tuple merged first second =
case first of
[] ->
List.reverse merged

firstFirst :: firstRest ->
case second of
[] ->
[]

secondFirst :: secondRest ->
bit_and_tuple
(Bitwise.and firstFirst secondFirst :: merged)
firstRest
secondRest


list_all_same : a -> List a -> Bool
list_all_same item list =
case list of
Expand Down
3 changes: 3 additions & 0 deletions implement/pine/Pine/PineVM/PineVM.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2100,6 +2100,9 @@ public static PineValue EvaluateKernelApplicationGeneric(
nameof(KernelFunction.is_sorted_ascending_int) =>
KernelFunction.is_sorted_ascending_int(inputValue),

nameof(KernelFunction.bit_and) =>
KernelFunction.bit_and(inputValue),

_ =>
throw new ParseExpressionException(
"Did not find kernel function '" + function + "'")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Bitwise.and 0 0
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1234
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Bitwise.and 1234 1234
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
11
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Bitwise.and 255 11
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
13090
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Bitwise.and 46903 15274

0 comments on commit b9a3e82

Please sign in to comment.