{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module PlutusCore.Arrays
( multiIndexArray
, maximumIndexCount
) where
import PlutusCore.Builtin.Result (BuiltinResult, builtinResultFailure, emit)
import Data.Text (pack)
import Data.Vector.Strict (Vector)
import Data.Vector.Strict qualified as Vector
maximumIndexCount :: Int
maximumIndexCount :: Int
maximumIndexCount = Int
1024
{-# INLINE maximumIndexCount #-}
multiIndexArray :: forall a. Vector a -> [Integer] -> BuiltinResult [a]
multiIndexArray :: forall a. Vector a -> [Integer] -> BuiltinResult [a]
multiIndexArray Vector a
vec = Int -> [Integer] -> BuiltinResult [a]
go Int
0
where
!len :: Integer
len = Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Vector a -> Int
forall a. Vector a -> Int
Vector.length Vector a
vec)
go :: Int -> [Integer] -> BuiltinResult [a]
go :: Int -> [Integer] -> BuiltinResult [a]
go !Int
_ [] = [a] -> BuiltinResult [a]
forall a. a -> BuiltinResult a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
go !Int
n (Integer
i : [Integer]
is)
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
maximumIndexCount = do
Text -> BuiltinResult ()
emit (Text -> BuiltinResult ())
-> ([Char] -> Text) -> [Char] -> BuiltinResult ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Text
pack ([Char] -> BuiltinResult ()) -> [Char] -> BuiltinResult ()
forall a b. (a -> b) -> a -> b
$
[Char]
"multiIndexArray: too many indices (maximum is "
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
maximumIndexCount
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
")"
BuiltinResult [a]
forall a. BuiltinResult a
builtinResultFailure
| Integer
0 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
i Bool -> Bool -> Bool
&& Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
len = do
let !x :: a
x = Vector a -> Int -> a
forall a. Vector a -> Int -> a
Vector.unsafeIndex Vector a
vec (Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
i)
(a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
:) ([a] -> [a]) -> BuiltinResult [a] -> BuiltinResult [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> [Integer] -> BuiltinResult [a]
go (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) [Integer]
is
| Bool
otherwise = do
Text -> BuiltinResult ()
emit Text
"multiIndexArray: array index out of bounds"
Text -> BuiltinResult ()
emit (Text -> BuiltinResult ()) -> Text -> BuiltinResult ()
forall a b. (a -> b) -> a -> b
$ Text
"Index: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ([Char] -> Text
pack ([Char] -> Text) -> (Integer -> [Char]) -> Integer -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> [Char]
forall a. Show a => a -> [Char]
show (Integer -> Text) -> Integer -> Text
forall a b. (a -> b) -> a -> b
$ Integer
i)
BuiltinResult [a]
forall a. BuiltinResult a
builtinResultFailure
{-# INLINE multiIndexArray #-}