{-|
Module      : Z.Data.Array.QQ
Description : Extra stuff for PrimArray related literals
Copyright   : (c) Dong Han, 2017-2018
License     : BSD
Maintainer  : winterland1989@gmail.com
Stability   : experimental
Portability : non-portable

This module provides functions for writing 'PrimArray' related literals 'QuasiQuote'.

@
> :set -XQuasiQuotes
> :t [arrASCII|asdfg|]
[arrASCII|asdfg|] :: PrimArray GHC.Word.Word8
> [arrASCII|asdfg|]
fromListN 5 [97,115,100,102,103]
> :t [arrI16|1,2,3,4,5|]
[arrI16|1,2,3,4,5|] :: PrimArray GHC.Int.Int16
> [arrI16|1,2,3,4,5|]
fromListN 5 [1,2,3,4,5]
@

-}

module Z.Data.Array.QQ
  ( -- * PrimArray literal quoters
    arrASCII
  , arrW8, arrW16, arrW32, arrW64, arrWord
  , arrI8, arrI16, arrI32, arrI64, arrInt
   -- * quoter helpers
  , asciiLiteral
  , utf8Literal
  , arrayLiteral
  , word8Literal
  , word16Literal
  , word32Literal
  , word64Literal
  , wordLiteral
  , int8Literal
  , int16Literal
  , int32Literal
  , int64Literal
  , intLiteral
  , word8ArrayFromAddr
  , word16ArrayFromAddr
  , word32ArrayFromAddr
  , word64ArrayFromAddr
  , wordArrayFromAddr
  , int8ArrayFromAddr
  , int16ArrayFromAddr
  , int32ArrayFromAddr
  , int64ArrayFromAddr
  , intArrayFromAddr
  ) where

#include "MachDeps.h"

import           Control.Monad
import           Data.Bits
import           Data.Char                 (ord)
import           Data.Primitive.PrimArray
import           GHC.Exts
import           Data.Word
import           Data.Int
import           Language.Haskell.TH
import           Language.Haskell.TH.Quote
import           Z.Data.Array
import           Control.Monad.ST

-- $asciiLiteralExample
-- @
-- arrASCII :: QuasiQuoter
-- arrASCII = QuasiQuoter
--     (asciiLiteral $ \ len addr -> [| word8ArrayFromAddr $(len) $(addr) |])
--     ...
--
-- word8ArrayFromAddr :: Int -> Addr# -> PrimArray Word8
-- {-# INLINE word8ArrayFromAddr #-}
-- word8ArrayFromAddr l addr# = runST $ do
--     mba <- newPrimArray (I# l)
--     copyPtrToMutablePrimArray mba 0 (Ptr addr#) l
--     unsafeFreezePrimArray mba
-- @

-- | Construct data with ASCII encoded literals.
--
-- Provide a packing function, return a packing expression. Example usage:
--
-- $asciiLiteralExample
asciiLiteral :: (ExpQ -> ExpQ -> ExpQ) -- ^ Construction function which receive a byte
                                       --   length 'Int' and a 'Addr#' 'LitE' expression.
             -> String                 -- ^ Quoter input
             -> ExpQ                   -- ^ Final Quoter
asciiLiteral :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
asciiLiteral ExpQ -> ExpQ -> ExpQ
k String
str = ExpQ -> ExpQ -> ExpQ
k (Exp -> ExpQ
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp -> ExpQ) -> (Int -> Exp) -> Int -> ExpQ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Lit -> Exp
LitE  (Lit -> Exp) -> (Int -> Lit) -> Int -> Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Lit
IntegerL (Integer -> Lit) -> (Int -> Integer) -> Int -> Lit
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> ExpQ) -> Int -> ExpQ
forall a b. (a -> b) -> a -> b
$ String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
str)
                       ((Lit -> Exp
LitE (Lit -> Exp) -> ([Word8] -> Lit) -> [Word8] -> Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> Lit
StringPrimL) ([Word8] -> Exp) -> Q [Word8] -> ExpQ
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` String -> Q [Word8]
check String
str)
  where
    check :: String -> Q [Word8]
    check :: String -> Q [Word8]
check [] = [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    check (Char
c:String
cs) = do
        Bool -> Q () -> Q ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Char -> Int
ord Char
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0xFF) (Q () -> Q ()) -> Q () -> Q ()
forall a b. (a -> b) -> a -> b
$
            String -> Q ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Q ()) -> String -> Q ()
forall a b. (a -> b) -> a -> b
$ String
"character '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
c] String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' is have out of range in ASCII literal:" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str
        [Word8]
cs' <- String -> Q [Word8]
check String
cs
        [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Char -> Int
ord Char
c)Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:[Word8]
cs')


-- | @[arrASCII|asdfg|] :: PrimArray Word8@
arrASCII :: QuasiQuoter
arrASCII :: QuasiQuoter
arrASCII = (String -> ExpQ)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter
    ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
asciiLiteral ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ)
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
forall a b. (a -> b) -> a -> b
$ \ ExpQ
len ExpQ
addr -> [| word8ArrayFromAddr $(len) $(addr) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use arrASCII as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use arrASCII as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use arrASCII as a dec")

word8ArrayFromAddr :: Int -> Addr# -> PrimArray Word8
{-# INLINE word8ArrayFromAddr #-}
word8ArrayFromAddr :: Int -> Addr# -> PrimArray Word8
word8ArrayFromAddr Int
l Addr#
addr# = (forall s. ST s (PrimArray Word8)) -> PrimArray Word8
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (PrimArray Word8)) -> PrimArray Word8)
-> (forall s. ST s (PrimArray Word8)) -> PrimArray Word8
forall a b. (a -> b) -> a -> b
$ do
    MutablePrimArray s Word8
mba <- Int -> ST s (MutablePrimArray (PrimState (ST s)) Word8)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
l
    MutablePrimArray (PrimState (ST s)) Word8
-> Int -> Ptr Word8 -> Int -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a -> Int -> Ptr a -> Int -> m ()
copyPtrToMutablePrimArray MutablePrimArray s Word8
MutablePrimArray (PrimState (ST s)) Word8
mba Int
0 (Addr# -> Ptr Word8
forall a. Addr# -> Ptr a
Ptr Addr#
addr#) Int
l
    MutablePrimArray (PrimState (ST s)) Word8 -> ST s (PrimArray Word8)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray s Word8
MutablePrimArray (PrimState (ST s)) Word8
mba

int8ArrayFromAddr :: Int -> Addr# -> PrimArray Int8
int8ArrayFromAddr :: Int -> Addr# -> PrimArray Int8
int8ArrayFromAddr Int
l Addr#
addr# = PrimArray Word8 -> PrimArray Int8
forall (arr :: * -> *) a b. (Arr arr a, Cast a b) => arr a -> arr b
castArray (Int -> Addr# -> PrimArray Word8
word8ArrayFromAddr Int
l Addr#
addr#)


-- | Construct data with UTF8 encoded literals.
--
-- See 'asciiLiteral'
utf8Literal :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
utf8Literal :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
utf8Literal ExpQ -> ExpQ -> ExpQ
k String
str = ExpQ -> ExpQ -> ExpQ
k (Exp -> ExpQ
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp -> ExpQ) -> (Int -> Exp) -> Int -> ExpQ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Lit -> Exp
LitE  (Lit -> Exp) -> (Int -> Lit) -> Int -> Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Lit
IntegerL (Integer -> Lit) -> (Int -> Integer) -> Int -> Lit
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> ExpQ) -> Int -> ExpQ
forall a b. (a -> b) -> a -> b
$ String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
str)
                      ((Lit -> Exp
LitE (Lit -> Exp) -> ([Word8] -> Lit) -> [Word8] -> Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> Lit
StringPrimL) ([Word8] -> Exp) -> Q [Word8] -> ExpQ
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` String -> Q [Word8]
check String
str)
  where
    check :: String -> Q [Word8]
    check :: String -> Q [Word8]
check [] = [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    check (Char
c:String
cs) = case Char -> Int
ord Char
c of
        Int
n
            | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0x0000007F -> do
                let w :: Word8
w = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n
                [Word8]
ws <- String -> Q [Word8]
check String
cs
                [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
wWord8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:[Word8]
ws)
            | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0x000007FF -> do
                let w1 :: Word8
w1 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int
0xC0 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
6)
                    w2 :: Word8
w2 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int
0x80 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. (Int
n Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3F)
                [Word8]
ws <- String -> Q [Word8]
check String
cs
                [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
w1Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w2Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:[Word8]
ws)
            | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0x0000D7FF -> do
                let w1 :: Word8
w1 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int
0xE0 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
12)
                    w2 :: Word8
w2 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int
0x80 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
6 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3F)
                    w3 :: Word8
w3 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int
0x80 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. (Int
n Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3F)
                [Word8]
ws <- String -> Q [Word8]
check String
cs
                [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
w1Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w2Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w3Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:[Word8]
ws)
            | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0x0000DFFF -> do
                String -> Q [Word8]
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Q [Word8]) -> String -> Q [Word8]
forall a b. (a -> b) -> a -> b
$ String
"character '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
c] String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' is have out of range in UTF-8 literal:" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str
            | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0x0000FFFF -> do
                let w1 :: Word8
w1 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int
0xE0 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
12)
                    w2 :: Word8
w2 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int
0x80 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
6 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3F)
                    w3 :: Word8
w3 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int
0x80 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. (Int
n Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3F)
                [Word8]
ws <- String -> Q [Word8]
check String
cs
                [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
w1Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w2Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w3Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:[Word8]
ws)
            | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0x0010FFFF -> do
                let w1 :: Word8
w1 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int
0xF0 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
18)
                    w2 :: Word8
w2 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int
0x80 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
12 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3F)
                    w3 :: Word8
w3 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int
0x80 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
6 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3F)
                    w4 :: Word8
w4 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int
0x80 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. (Int
n Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3F)
                [Word8]
ws <- String -> Q [Word8]
check String
cs
                [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
w1Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w2Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w3Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w4Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:[Word8]
ws)
            | Bool
otherwise ->
                String -> Q [Word8]
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Q [Word8]) -> String -> Q [Word8]
forall a b. (a -> b) -> a -> b
$ String
"character '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
c] String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' is have out of range in UTF-8 literal:" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str


-- | Construct data with array literals @e.g. 1,2,3@.
arrayLiteral :: ([Integer] -> Q [Word8])
              -> (ExpQ -> ExpQ -> ExpQ)
              -> String -> ExpQ
arrayLiteral :: ([Integer] -> Q [Word8])
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
arrayLiteral [Integer] -> Q [Word8]
f ExpQ -> ExpQ -> ExpQ
k String
str = do
    (Int
len, [Word8]
ws) <- String -> Q (Int, [Word8])
parse String
str
    ExpQ -> ExpQ -> ExpQ
k (Exp -> ExpQ
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp -> ExpQ) -> (Int -> Exp) -> Int -> ExpQ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Lit -> Exp
LitE  (Lit -> Exp) -> (Int -> Lit) -> Int -> Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Lit
IntegerL (Integer -> Lit) -> (Int -> Integer) -> Int -> Lit
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> ExpQ) -> Int -> ExpQ
forall a b. (a -> b) -> a -> b
$ Int
len) (ExpQ -> ExpQ) -> ExpQ -> ExpQ
forall a b. (a -> b) -> a -> b
$ (Exp -> ExpQ
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp -> ExpQ) -> ([Word8] -> Exp) -> [Word8] -> ExpQ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Lit -> Exp
LitE (Lit -> Exp) -> ([Word8] -> Lit) -> [Word8] -> Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> Lit
StringPrimL) [Word8]
ws
  where
    parse :: String -> Q (Int, [Word8])
    parse :: String -> Q (Int, [Word8])
parse String
str' = do
        case (ReadS [Integer]
forall a. Read a => ReadS [a]
readList :: ReadS [Integer]) (String
"[" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str' String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"]") of
            [([Integer]
is, String
"")] -> ([Integer] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Integer]
is, ) ([Word8] -> (Int, [Word8])) -> Q [Word8] -> Q (Int, [Word8])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` [Integer] -> Q [Word8]
f [Integer]
is
            [([Integer], String)]
_ -> do Any
_ <- String -> Q Any
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Q Any) -> String -> Q Any
forall a b. (a -> b) -> a -> b
$ String
"can't parse vector literal:" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str'
                    (Int, [Word8]) -> Q (Int, [Word8])
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
0, [])

--------------------------------------------------------------------------------

#define ARRAY_LITERAL_DOC(T)  \
-- | Construct 'PrimArray' 'T' with array literals @e.g. 1,2,3@. See 'asciiLiteral'

ARRAY_LITERAL_DOC(Word8)
word8Literal :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
word8Literal :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
word8Literal ExpQ -> ExpQ -> ExpQ
k String
str = ([Integer] -> Q [Word8])
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
arrayLiteral [Integer] -> Q [Word8]
checkW8 ExpQ -> ExpQ -> ExpQ
k String
str
  where
    checkW8 :: [Integer] -> Q [Word8]
    checkW8 :: [Integer] -> Q [Word8]
checkW8 [] = [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    checkW8 (Integer
i:[Integer]
is) = do
        Bool -> Q () -> Q ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Integer
iInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<Integer
0 Bool -> Bool -> Bool
|| Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0xFF) (Q () -> Q ()) -> Q () -> Q ()
forall a b. (a -> b) -> a -> b
$
            String -> Q ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Q ()) -> String -> Q ()
forall a b. (a -> b) -> a -> b
$ String
"integer " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Integer -> String
forall a. Show a => a -> String
show Integer
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is out of Word8 range in literal:" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str
        [Word8]
ws <- [Integer] -> Q [Word8]
checkW8 [Integer]
is
        let w :: Word8
w = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
        [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
wWord8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:[Word8]
ws)

-- | @[arrW8|1,2,3,4,5|] :: PrimArray Word8@
arrW8 :: QuasiQuoter
arrW8 :: QuasiQuoter
arrW8 = (String -> ExpQ)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter
    ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
word8Literal ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ)
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
forall a b. (a -> b) -> a -> b
$ \ ExpQ
len ExpQ
addr -> [| word8ArrayFromAddr $(len) $(addr) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use arrW8 as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use arrW8 as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use arrW8 as a dec")

ARRAY_LITERAL_DOC(Int8)
int8Literal :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
int8Literal :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
int8Literal ExpQ -> ExpQ -> ExpQ
k String
str = ([Integer] -> Q [Word8])
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
arrayLiteral [Integer] -> Q [Word8]
checkI8 ExpQ -> ExpQ -> ExpQ
k String
str
  where
    checkI8 :: [Integer] -> Q [Word8]
    checkI8 :: [Integer] -> Q [Word8]
checkI8 [] = [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    checkI8 (Integer
i:[Integer]
is) = do
        Bool -> Q () -> Q ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Integer
iInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< (-Integer
0x80) Bool -> Bool -> Bool
|| Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0x7F) (Q () -> Q ()) -> Q () -> Q ()
forall a b. (a -> b) -> a -> b
$
            String -> Q ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Q ()) -> String -> Q ()
forall a b. (a -> b) -> a -> b
$ String
"integer " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Integer -> String
forall a. Show a => a -> String
show Integer
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is out of Int8 range in literal:" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str
        [Word8]
ws <- [Integer] -> Q [Word8]
checkI8 [Integer]
is
        let w :: Word8
w = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
        [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
wWord8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:[Word8]
ws)

-- | @[arrW8|1,2,3,4,5|] :: PrimArray Int8@
arrI8 :: QuasiQuoter
arrI8 :: QuasiQuoter
arrI8 = (String -> ExpQ)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter
    ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
int8Literal ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ)
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
forall a b. (a -> b) -> a -> b
$ \ ExpQ
len ExpQ
addr -> [| int8ArrayFromAddr $(len) $(addr) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use arrI8 as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use arrI8 as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use arrI8 as a dec")

--------------------------------------------------------------------------------

ARRAY_LITERAL_DOC(Word16)
word16Literal :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
word16Literal :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
word16Literal ExpQ -> ExpQ -> ExpQ
k String
str = ([Integer] -> Q [Word8])
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
arrayLiteral [Integer] -> Q [Word8]
checkW16 ExpQ -> ExpQ -> ExpQ
k String
str
  where
    checkW16 :: [Integer] -> Q [Word8]
    checkW16 :: [Integer] -> Q [Word8]
checkW16 [] = [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    checkW16 (Integer
i:[Integer]
is) = do
        Bool -> Q () -> Q ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Integer
iInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<Integer
0 Bool -> Bool -> Bool
|| Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0xFFFF) (Q () -> Q ()) -> Q () -> Q ()
forall a b. (a -> b) -> a -> b
$
            String -> Q ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Q ()) -> String -> Q ()
forall a b. (a -> b) -> a -> b
$ String
"integer " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Integer -> String
forall a. Show a => a -> String
show Integer
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is out of Word16 range in literal:" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str
        [Word8]
ws <- [Integer] -> Q [Word8]
checkW16 [Integer]
is
        let w1 :: Word8
w1 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w2 :: Word8
w2 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
8 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
#ifdef WORDS_BIGENDIAN
        return (w2:w1:ws)
#else
        [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
w1Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w2Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:[Word8]
ws)
#endif

-- | @[arrW16|1,2,3,4,5|] :: PrimArray Word16@
arrW16 :: QuasiQuoter
arrW16 :: QuasiQuoter
arrW16 = (String -> ExpQ)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter
    ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
word16Literal ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ)
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
forall a b. (a -> b) -> a -> b
$ \ ExpQ
len ExpQ
addr -> [| word16ArrayFromAddr $(len) $(addr) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use arrW16 as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use arrW16 as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use arrW16 as a dec")

word16ArrayFromAddr :: Int -> Addr# -> PrimArray Word16
{-# INLINE word16ArrayFromAddr #-}
word16ArrayFromAddr :: Int -> Addr# -> PrimArray Word16
word16ArrayFromAddr Int
l Addr#
addr# = (forall s. ST s (PrimArray Word16)) -> PrimArray Word16
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (PrimArray Word16)) -> PrimArray Word16)
-> (forall s. ST s (PrimArray Word16)) -> PrimArray Word16
forall a b. (a -> b) -> a -> b
$ do
    MutablePrimArray s Word16
mba <- Int -> ST s (MArr PrimArray s Word16)
forall (arr :: * -> *) a (m :: * -> *) s.
(Arr arr a, PrimMonad m, PrimState m ~ s) =>
Int -> m (MArr arr s a)
newArr Int
l
    MutablePrimArray (PrimState (ST s)) Word16
-> Int -> Ptr Word16 -> Int -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a -> Int -> Ptr a -> Int -> m ()
copyPtrToMutablePrimArray MutablePrimArray s Word16
MutablePrimArray (PrimState (ST s)) Word16
mba Int
0 (Addr# -> Ptr Word16
forall a. Addr# -> Ptr a
Ptr Addr#
addr#) Int
l
    MutablePrimArray (PrimState (ST s)) Word16
-> ST s (PrimArray Word16)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray s Word16
MutablePrimArray (PrimState (ST s)) Word16
mba

int16ArrayFromAddr :: Int -> Addr# -> PrimArray Int16
int16ArrayFromAddr :: Int -> Addr# -> PrimArray Int16
int16ArrayFromAddr Int
l Addr#
addr# = PrimArray Word16 -> PrimArray Int16
forall (arr :: * -> *) a b. (Arr arr a, Cast a b) => arr a -> arr b
castArray (Int -> Addr# -> PrimArray Word16
word16ArrayFromAddr Int
l Addr#
addr#)

ARRAY_LITERAL_DOC(Int16)
int16Literal :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
int16Literal :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
int16Literal ExpQ -> ExpQ -> ExpQ
k String
str = ([Integer] -> Q [Word8])
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
arrayLiteral [Integer] -> Q [Word8]
checkI16 ExpQ -> ExpQ -> ExpQ
k String
str
  where
    checkI16 :: [Integer] -> Q [Word8]
    checkI16 :: [Integer] -> Q [Word8]
checkI16 [] = [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    checkI16 (Integer
i:[Integer]
is) = do
        Bool -> Q () -> Q ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Integer
iInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<(-Integer
0x8000) Bool -> Bool -> Bool
|| Integer
iInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>Integer
0x7FFF) (Q () -> Q ()) -> Q () -> Q ()
forall a b. (a -> b) -> a -> b
$
            String -> Q ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Q ()) -> String -> Q ()
forall a b. (a -> b) -> a -> b
$ String
"integer " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Integer -> String
forall a. Show a => a -> String
show Integer
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is out of Int16 range in literal:" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str
        [Word8]
ws <- [Integer] -> Q [Word8]
checkI16 [Integer]
is
        let w1 :: Word8
w1 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w2 :: Word8
w2 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
8 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
#ifdef WORDS_BIGENDIAN
        return (w2:w1:ws)
#else
        [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
w1Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w2Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:[Word8]
ws)
#endif

-- | @[arrI16|1,2,3,4,5|] :: PrimArray Int16@
arrI16 :: QuasiQuoter
arrI16 :: QuasiQuoter
arrI16 = (String -> ExpQ)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter
    ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
word16Literal ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ)
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
forall a b. (a -> b) -> a -> b
$ \ ExpQ
len ExpQ
addr -> [| int16ArrayFromAddr $(len) $(addr) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use arrI16 as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use arrI16 as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use arrI16 as a dec")
--------------------------------------------------------------------------------

ARRAY_LITERAL_DOC(Word32)
word32Literal :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
word32Literal :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
word32Literal ExpQ -> ExpQ -> ExpQ
k String
str = ([Integer] -> Q [Word8])
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
arrayLiteral [Integer] -> Q [Word8]
checkW32 ExpQ -> ExpQ -> ExpQ
k String
str
  where
    checkW32 :: [Integer] -> Q [Word8]
    checkW32 :: [Integer] -> Q [Word8]
checkW32 [] = [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    checkW32 (Integer
i:[Integer]
is) = do
        Bool -> Q () -> Q ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Integer
iInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<Integer
0 Bool -> Bool -> Bool
|| Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0xFFFFFFFF) (Q () -> Q ()) -> Q () -> Q ()
forall a b. (a -> b) -> a -> b
$
            String -> Q ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Q ()) -> String -> Q ()
forall a b. (a -> b) -> a -> b
$ String
"integer " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Integer -> String
forall a. Show a => a -> String
show Integer
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is out of Word32 range in literal:" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str
        [Word8]
ws <- [Integer] -> Q [Word8]
checkW32 [Integer]
is
        let w1 :: Word8
w1 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w2 :: Word8
w2 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
8 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w3 :: Word8
w3 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
16 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w4 :: Word8
w4 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
24 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
#ifdef WORDS_BIGENDIAN
        return (w4:w3:w2:w1:ws)
#else
        [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
w1Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w2Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w3Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w4Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:[Word8]
ws)
#endif

-- | @[arrW32|1,2,3,4,5|] :: PrimArray Word32@
arrW32 :: QuasiQuoter
arrW32 :: QuasiQuoter
arrW32 = (String -> ExpQ)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter
    ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
word32Literal ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ)
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
forall a b. (a -> b) -> a -> b
$ \ ExpQ
len ExpQ
addr -> [| word32ArrayFromAddr $(len) $(addr) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use arrW32 as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use arrW32 as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use arrW32 as a dec")

word32ArrayFromAddr :: Int -> Addr# -> PrimArray Word32
{-# INLINE word32ArrayFromAddr #-}
word32ArrayFromAddr :: Int -> Addr# -> PrimArray Word32
word32ArrayFromAddr Int
l Addr#
addr# = (forall s. ST s (PrimArray Word32)) -> PrimArray Word32
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (PrimArray Word32)) -> PrimArray Word32)
-> (forall s. ST s (PrimArray Word32)) -> PrimArray Word32
forall a b. (a -> b) -> a -> b
$ do
    MutablePrimArray s Word32
mba <- Int -> ST s (MArr PrimArray s Word32)
forall (arr :: * -> *) a (m :: * -> *) s.
(Arr arr a, PrimMonad m, PrimState m ~ s) =>
Int -> m (MArr arr s a)
newArr Int
l
    MutablePrimArray (PrimState (ST s)) Word32
-> Int -> Ptr Word32 -> Int -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a -> Int -> Ptr a -> Int -> m ()
copyPtrToMutablePrimArray MutablePrimArray s Word32
MutablePrimArray (PrimState (ST s)) Word32
mba Int
0 (Addr# -> Ptr Word32
forall a. Addr# -> Ptr a
Ptr Addr#
addr#) Int
l
    MutablePrimArray (PrimState (ST s)) Word32
-> ST s (PrimArray Word32)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray s Word32
MutablePrimArray (PrimState (ST s)) Word32
mba

int32ArrayFromAddr :: Int -> Addr# -> PrimArray Int32
int32ArrayFromAddr :: Int -> Addr# -> PrimArray Int32
int32ArrayFromAddr Int
l Addr#
addr# = PrimArray Word32 -> PrimArray Int32
forall (arr :: * -> *) a b. (Arr arr a, Cast a b) => arr a -> arr b
castArray (Int -> Addr# -> PrimArray Word32
word32ArrayFromAddr Int
l Addr#
addr#)

ARRAY_LITERAL_DOC(Int32)
int32Literal :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
int32Literal :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
int32Literal ExpQ -> ExpQ -> ExpQ
k String
str = ([Integer] -> Q [Word8])
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
arrayLiteral [Integer] -> Q [Word8]
checkI32 ExpQ -> ExpQ -> ExpQ
k String
str
  where
    checkI32 :: [Integer] -> Q [Word8]
    checkI32 :: [Integer] -> Q [Word8]
checkI32 [] = [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    checkI32 (Integer
i:[Integer]
is) = do
        Bool -> Q () -> Q ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Integer
iInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<(-Integer
0x80000000) Bool -> Bool -> Bool
|| Integer
iInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>Integer
0x7FFFFFFF) (Q () -> Q ()) -> Q () -> Q ()
forall a b. (a -> b) -> a -> b
$
            String -> Q ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Q ()) -> String -> Q ()
forall a b. (a -> b) -> a -> b
$ String
"integer " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Integer -> String
forall a. Show a => a -> String
show Integer
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is out of Int32 range in literal:" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str
        [Word8]
ws <- [Integer] -> Q [Word8]
checkI32 [Integer]
is
        let w1 :: Word8
w1 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w2 :: Word8
w2 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
8 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w3 :: Word8
w3 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
16 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w4 :: Word8
w4 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
24 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
#ifdef WORDS_BIGENDIAN
        return (w4:w3:w2:w1:ws)
#else
        [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
w1Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w2Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w3Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w4Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:[Word8]
ws)
#endif

-- | @[arrI32|1,2,3,4,5|] :: PrimArray Int32@
arrI32 :: QuasiQuoter
arrI32 :: QuasiQuoter
arrI32 = (String -> ExpQ)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter
    ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
int32Literal ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ)
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
forall a b. (a -> b) -> a -> b
$ \ ExpQ
len ExpQ
addr -> [| int32ArrayFromAddr $(len) $(addr) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use arrI32 as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use arrI32 as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use arrI32 as a dec")

--------------------------------------------------------------------------------

ARRAY_LITERAL_DOC(Word64)
word64Literal :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
word64Literal :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
word64Literal ExpQ -> ExpQ -> ExpQ
k String
str = ([Integer] -> Q [Word8])
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
arrayLiteral [Integer] -> Q [Word8]
checkW64 ExpQ -> ExpQ -> ExpQ
k String
str
  where
    checkW64 :: [Integer] -> Q [Word8]
    checkW64 :: [Integer] -> Q [Word8]
checkW64 [] = [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    checkW64 (Integer
i:[Integer]
is) = do
        Bool -> Q () -> Q ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Integer
iInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<Integer
0 Bool -> Bool -> Bool
|| Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0xFFFFFFFFFFFFFFFF) (Q () -> Q ()) -> Q () -> Q ()
forall a b. (a -> b) -> a -> b
$
            String -> Q ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Q ()) -> String -> Q ()
forall a b. (a -> b) -> a -> b
$ String
"integer " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Integer -> String
forall a. Show a => a -> String
show Integer
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is out of Word64 range in literal:" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str
        [Word8]
ws <- [Integer] -> Q [Word8]
checkW64 [Integer]
is
        let w1 :: Word8
w1 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w2 :: Word8
w2 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
8 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w3 :: Word8
w3 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
16 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w4 :: Word8
w4 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
24 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w5 :: Word8
w5 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
32 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w6 :: Word8
w6 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
40 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w7 :: Word8
w7 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
48 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w8 :: Word8
w8 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
56 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
#ifdef WORDS_BIGENDIAN
        return (w8:w7:w6:w5:w4:w3:w2:w1:ws)
#else
        [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
w1Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w2Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w3Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w4Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w5Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w6Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w7Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w8Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:[Word8]
ws)
#endif

-- | @[arrW64|1,2,3,4,5|] :: PrimArray Word64@
arrW64 :: QuasiQuoter
arrW64 :: QuasiQuoter
arrW64 = (String -> ExpQ)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter
    ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
word64Literal ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ)
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
forall a b. (a -> b) -> a -> b
$ \ ExpQ
len ExpQ
addr -> [| word64ArrayFromAddr $(len) $(addr) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use arrW64 as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use arrW64 as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use arrW64 as a dec")

word64ArrayFromAddr :: Int -> Addr# -> PrimArray Word64
{-# INLINE word64ArrayFromAddr #-}
word64ArrayFromAddr :: Int -> Addr# -> PrimArray Word64
word64ArrayFromAddr Int
l Addr#
addr# = (forall s. ST s (PrimArray Word64)) -> PrimArray Word64
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (PrimArray Word64)) -> PrimArray Word64)
-> (forall s. ST s (PrimArray Word64)) -> PrimArray Word64
forall a b. (a -> b) -> a -> b
$ do
    MutablePrimArray s Word64
mba <- Int -> ST s (MArr PrimArray s Word64)
forall (arr :: * -> *) a (m :: * -> *) s.
(Arr arr a, PrimMonad m, PrimState m ~ s) =>
Int -> m (MArr arr s a)
newArr Int
l
    MutablePrimArray (PrimState (ST s)) Word64
-> Int -> Ptr Word64 -> Int -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a -> Int -> Ptr a -> Int -> m ()
copyPtrToMutablePrimArray MutablePrimArray s Word64
MutablePrimArray (PrimState (ST s)) Word64
mba Int
0 (Addr# -> Ptr Word64
forall a. Addr# -> Ptr a
Ptr Addr#
addr#) Int
l
    MutablePrimArray (PrimState (ST s)) Word64
-> ST s (PrimArray Word64)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray s Word64
MutablePrimArray (PrimState (ST s)) Word64
mba

int64ArrayFromAddr :: Int -> Addr# -> PrimArray Int64
int64ArrayFromAddr :: Int -> Addr# -> PrimArray Int64
int64ArrayFromAddr Int
l Addr#
addr# = PrimArray Word64 -> PrimArray Int64
forall (arr :: * -> *) a b. (Arr arr a, Cast a b) => arr a -> arr b
castArray (Int -> Addr# -> PrimArray Word64
word64ArrayFromAddr Int
l Addr#
addr#)

ARRAY_LITERAL_DOC(Int64)
int64Literal :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
int64Literal :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
int64Literal ExpQ -> ExpQ -> ExpQ
k String
str = ([Integer] -> Q [Word8])
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
arrayLiteral [Integer] -> Q [Word8]
checkI64 ExpQ -> ExpQ -> ExpQ
k String
str
  where
    checkI64 :: [Integer] -> Q [Word8]
    checkI64 :: [Integer] -> Q [Word8]
checkI64 [] = [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    checkI64 (Integer
i:[Integer]
is) = do
        Bool -> Q () -> Q ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Integer
iInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<(-Integer
0x8000000000000000) Bool -> Bool -> Bool
|| Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0x7FFFFFFFFFFFFFFF) (Q () -> Q ()) -> Q () -> Q ()
forall a b. (a -> b) -> a -> b
$
            String -> Q ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Q ()) -> String -> Q ()
forall a b. (a -> b) -> a -> b
$ String
"integer " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Integer -> String
forall a. Show a => a -> String
show Integer
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is out of Int64 range in literal:" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str
        [Word8]
ws <- [Integer] -> Q [Word8]
checkI64 [Integer]
is
        let w1 :: Word8
w1 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w2 :: Word8
w2 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
8 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w3 :: Word8
w3 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
16 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w4 :: Word8
w4 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
24 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w5 :: Word8
w5 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
32 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w6 :: Word8
w6 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
40 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w7 :: Word8
w7 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
48 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
            w8 :: Word8
w8 = Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
56 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xFF)
#ifdef WORDS_BIGENDIAN
        return (w8:w7:w6:w5:w4:w3:w2:w1:ws)
#else
        [Word8] -> Q [Word8]
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
w1Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w2Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w3Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w4Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w5Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w6Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w7Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:Word8
w8Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:[Word8]
ws)
#endif

-- | @[arrI64|1,2,3,4,5|] :: PrimArray Int64@
arrI64 :: QuasiQuoter
arrI64 :: QuasiQuoter
arrI64 = (String -> ExpQ)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter
    ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
int64Literal ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ)
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
forall a b. (a -> b) -> a -> b
$ \ ExpQ
len ExpQ
addr -> [| int64ArrayFromAddr $(len) $(addr) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use arrI64 as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use arrI64 as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use arrI64 as a dec")

--------------------------------------------------------------------------------

wordArrayFromAddr :: Int -> Addr# -> PrimArray Word
wordArrayFromAddr :: Int -> Addr# -> PrimArray Word
wordArrayFromAddr Int
l Addr#
addr# =
#if SIZEOF_HSWORD == 8
    PrimArray Word64 -> PrimArray Word
unsafeCoerce# (Int -> Addr# -> PrimArray Word64
word64ArrayFromAddr Int
l Addr#
addr#)
#else
    unsafeCoerce# (word32ArrayFromAddr l addr#)
#endif

intArrayFromAddr :: Int -> Addr# -> PrimArray Int
intArrayFromAddr :: Int -> Addr# -> PrimArray Int
intArrayFromAddr Int
l Addr#
addr# =
#if SIZEOF_HSWORD == 8
    PrimArray Int64 -> PrimArray Int
unsafeCoerce# (Int -> Addr# -> PrimArray Int64
int64ArrayFromAddr Int
l Addr#
addr#)
#else
    unsafeCoerce# (int32ArrayFromAddr l addr#)
#endif

ARRAY_LITERAL_DOC(Word)
wordLiteral :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
wordLiteral :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
wordLiteral =
#if SIZEOF_HSWORD == 8
    (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
word64Literal
#else
    word32Literal
#endif

ARRAY_LITERAL_DOC(Int)
intLiteral :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
intLiteral :: (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
intLiteral =
#if SIZEOF_HSWORD == 8
    (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
int64Literal
#else
    int32Literal
#endif

-- | @[arrWord|1,2,3,4,5|] :: PrimArray Word@
arrWord :: QuasiQuoter
arrWord :: QuasiQuoter
arrWord = (String -> ExpQ)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter
    ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
wordLiteral ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ)
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
forall a b. (a -> b) -> a -> b
$ \ ExpQ
len ExpQ
addr -> [| wordArrayFromAddr $(len) $(addr) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use arrWord as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use arrWord as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use arrWord as a dec")

-- | @[arrInt|1,2,3,4,5|] :: PrimArray Int@
arrInt :: QuasiQuoter
arrInt :: QuasiQuoter
arrInt = (String -> ExpQ)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter
    ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
intLiteral ((ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ)
-> (ExpQ -> ExpQ -> ExpQ) -> String -> ExpQ
forall a b. (a -> b) -> a -> b
$ \ ExpQ
len ExpQ
addr -> [| intArrayFromAddr $(len) $(addr) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use arrInt as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use arrInt as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use arrInt as a dec")

--------------------------------------------------------------------------------