{-|
Module      : Z.Data.Vector.QQ
Description : vectors literals using QuasiQuote
Copyright   : (c) Dong Han, 2017-2018
License     : BSD
Maintainer  : winterland1989@gmail.com
Stability   : experimental
Portability : non-portable

This module provides functions for writing vector literals using 'QuasiQuote' similar to "Z.Data.Array.QQ" module.

@
> :set -XQuasiQuotes
> :t [vecASCII|asdfg|]
[vecASCII|asdfg|] :: Z.Data.Vector.Base.PrimVector GHC.Word.Word8
> [vecASCII|asdfg|]
[97,115,100,102,103]
> :t [vecI16|1,2,3,4,5|]
[vecI16|1,2,3,4,5|] :: Z.Data.Vector.Base.PrimVector GHC.Int.Int16
> [vecI16|1,2,3,4,5|]
[1,2,3,4,5]
@

-}

module Z.Data.Vector.QQ (
  -- * QuasiQuoters
    vecASCII
  , vecW8, vecW16, vecW32, vecW64, vecWord
  , vecI8, vecI16, vecI32, vecI64, vecInt
  ) where

import qualified Language.Haskell.TH.Quote      as QQ
import           Z.Data.Array.QQ                as QQ
import           Z.Data.Vector.Base

--------------------------------------------------------------------------------
-- Quoters

vecASCII :: QQ.QuasiQuoter
vecASCII :: QuasiQuoter
vecASCII = (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QQ.QuasiQuoter
    ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
asciiLiteral ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp)
-> (Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
forall a b. (a -> b) -> a -> b
$ \ Q Exp
len Q Exp
addr -> [| PrimVector (QQ.word8ArrayFromAddr $(len) $(addr)) 0 $(len) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use vecASCII as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use vecASCII as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use vecASCII as a dec")

vecW8 :: QQ.QuasiQuoter
vecW8 :: QuasiQuoter
vecW8 = (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QQ.QuasiQuoter
    ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
QQ.word8Literal ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp)
-> (Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
forall a b. (a -> b) -> a -> b
$ \ Q Exp
len Q Exp
addr -> [| PrimVector (QQ.word8ArrayFromAddr $(len) $(addr)) 0 $(len) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use vecW8 as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use vecW8 as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use vecW8 as a dec")

vecW16 :: QQ.QuasiQuoter
vecW16 :: QuasiQuoter
vecW16 = (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QQ.QuasiQuoter
    ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
QQ.word16Literal ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp)
-> (Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
forall a b. (a -> b) -> a -> b
$ \ Q Exp
len Q Exp
addr -> [| PrimVector (QQ.word16ArrayFromAddr $(len) $(addr)) 0 $(len) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use vecW16 as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use vecW16 as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use vecW16 as a dec")

vecW32 :: QQ.QuasiQuoter
vecW32 :: QuasiQuoter
vecW32 = (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QQ.QuasiQuoter
    ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
QQ.word32Literal ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp)
-> (Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
forall a b. (a -> b) -> a -> b
$ \ Q Exp
len Q Exp
addr -> [| PrimVector (QQ.word32ArrayFromAddr $(len) $(addr)) 0 $(len) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use vecW32 as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use vecW32 as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use vecW32 as a dec")

vecW64 :: QQ.QuasiQuoter
vecW64 :: QuasiQuoter
vecW64 = (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QQ.QuasiQuoter
    ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
QQ.word64Literal ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp)
-> (Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
forall a b. (a -> b) -> a -> b
$ \ Q Exp
len Q Exp
addr -> [| PrimVector (QQ.word64ArrayFromAddr $(len) $(addr)) 0 $(len) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use vecW64 as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use vecW64 as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use vecW64 as a dec")

vecWord :: QQ.QuasiQuoter
vecWord :: QuasiQuoter
vecWord = (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QQ.QuasiQuoter
    ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
QQ.wordLiteral ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp)
-> (Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
forall a b. (a -> b) -> a -> b
$ \ Q Exp
len Q Exp
addr ->
        [| PrimVector (QQ.wordArrayFromAddr $(len) $(addr)) 0 $(len) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use vecWord as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use vecWord as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use vecWord as a dec")

vecI8 :: QQ.QuasiQuoter
vecI8 :: QuasiQuoter
vecI8 = (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QQ.QuasiQuoter
    ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
QQ.int8Literal ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp)
-> (Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
forall a b. (a -> b) -> a -> b
$ \ Q Exp
len Q Exp
addr ->
        [| PrimVector (QQ.int8ArrayFromAddr $(len) $(addr)) 0 $(len) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use vecI8 as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use vecI8 as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use vecI8 as a dec")

vecI16 :: QQ.QuasiQuoter
vecI16 :: QuasiQuoter
vecI16 = (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QQ.QuasiQuoter
    ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
QQ.int16Literal ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp)
-> (Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
forall a b. (a -> b) -> a -> b
$ \ Q Exp
len Q Exp
addr ->
        [| PrimVector (QQ.int16ArrayFromAddr $(len) $(addr)) 0 $(len) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use vecI16 as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use vecI16 as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use vecI16 as a dec")

vecI32 :: QQ.QuasiQuoter
vecI32 :: QuasiQuoter
vecI32 = (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QQ.QuasiQuoter
    ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
QQ.int32Literal ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp)
-> (Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
forall a b. (a -> b) -> a -> b
$ \ Q Exp
len Q Exp
addr ->
        [| PrimVector (QQ.int32ArrayFromAddr $(len) $(addr)) 0 $(len) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use vecI32 as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use vecI32 as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use vecI32 as a dec")

vecI64 :: QQ.QuasiQuoter
vecI64 :: QuasiQuoter
vecI64 = (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QQ.QuasiQuoter
    ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
QQ.int64Literal ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp)
-> (Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
forall a b. (a -> b) -> a -> b
$ \ Q Exp
len Q Exp
addr ->
        [| PrimVector (QQ.int64ArrayFromAddr $(len) $(addr)) 0 $(len) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use vecI64 as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use vecI64 as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use vecI64 as a dec")

vecInt :: QQ.QuasiQuoter
vecInt :: QuasiQuoter
vecInt = (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QQ.QuasiQuoter
    ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
QQ.intLiteral ((Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp)
-> (Q Exp -> Q Exp -> Q Exp) -> String -> Q Exp
forall a b. (a -> b) -> a -> b
$ \ Q Exp
len Q Exp
addr ->
        [| PrimVector (QQ.intArrayFromAddr $(len) $(addr)) 0 $(len) |])
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use vecInt as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use vecInt as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use vecInt as a dec")