{-# LINE 1 "src/Quickjs/Types.hsc" #-}
{-# LANGUAGE QuasiQuotes, TemplateHaskell, OverloadedStrings, MultiParamTypeClasses, FlexibleInstances, GeneralizedNewtypeDeriving #-}

module Quickjs.Types where

import qualified Data.Map                  as Map
import           Data.Bits                 (Bits)
import           Foreign.C.Types
import           Foreign.Ptr               (plusPtr)
import           Foreign.Storable          (Storable(..))
import           Language.C.Inline
import           Language.C.Inline.Context (Context(..), TypesTable)
import qualified Language.C.Types          as C



data JSValue = JSValue
  { u :: {-# UNPACK #-} !CDouble
  , tag :: {-# UNPACK #-} !CLong
  } deriving (Show, Eq)

instance Storable JSValue where
  sizeOf _ = (16)
{-# LINE 23 "src/Quickjs/Types.hsc" #-}
  alignment _ = 8
{-# LINE 24 "src/Quickjs/Types.hsc" #-}
  peek ptr = do
    u <- peek ((\hsc_ptr -> hsc_ptr `plusPtr` 0) ptr)
{-# LINE 26 "src/Quickjs/Types.hsc" #-}
    tag <- peek ((\hsc_ptr -> hsc_ptr `plusPtr` 8) ptr)
{-# LINE 27 "src/Quickjs/Types.hsc" #-}
    Prelude.pure (JSValue u tag)
  poke ptr (JSValue u tag) = do
    poke ((\hsc_ptr -> hsc_ptr `plusPtr` 0) ptr) u
{-# LINE 30 "src/Quickjs/Types.hsc" #-}
    poke ((\hsc_ptr -> hsc_ptr `plusPtr` 8) ptr) tag
{-# LINE 31 "src/Quickjs/Types.hsc" #-}

type JSValueConst = JSValue

newtype JSRuntime = JSRuntime { _unusedRuntime :: CUChar }

newtype JSContext = JSContext { _unusedContext :: CUChar }


type JSBool = CInt

type JSAtom = CUInt


data JSPropertyEnum = JSPropertyEnum
  { is_enumerable :: {-# UNPACK #-} !JSBool
  , atom :: {-# UNPACK #-} !JSAtom
  } deriving (Show, Eq)

instance Storable JSPropertyEnum where
  sizeOf _ = (8)
{-# LINE 51 "src/Quickjs/Types.hsc" #-}
  alignment _ = 4
{-# LINE 52 "src/Quickjs/Types.hsc" #-}
  peek ptr = do
    is_enumerable <- peek ((\hsc_ptr -> hsc_ptr `plusPtr` 0) ptr)
{-# LINE 54 "src/Quickjs/Types.hsc" #-}
    atom <- peek ((\hsc_ptr -> hsc_ptr `plusPtr` 4) ptr)
{-# LINE 55 "src/Quickjs/Types.hsc" #-}
    Prelude.pure (JSPropertyEnum is_enumerable atom)
  poke ptr (JSPropertyEnum is_enumerable atom) = do
    poke ((\hsc_ptr -> hsc_ptr `plusPtr` 0) ptr) is_enumerable
{-# LINE 58 "src/Quickjs/Types.hsc" #-}
    poke ((\hsc_ptr -> hsc_ptr `plusPtr` 4) ptr) atom
{-# LINE 59 "src/Quickjs/Types.hsc" #-}



data JSRefCountHeader = JSRefCountHeader
  { ref_count :: {-# UNPACK #-} !CInt
  } deriving (Show, Eq)

instance Storable JSRefCountHeader where
  sizeOf _ = (4)
{-# LINE 68 "src/Quickjs/Types.hsc" #-}
  alignment _ = 4
{-# LINE 69 "src/Quickjs/Types.hsc" #-}
  peek ptr = do
    ref_count <- peek ((\hsc_ptr -> hsc_ptr `plusPtr` 0) ptr)
{-# LINE 71 "src/Quickjs/Types.hsc" #-}
    Prelude.pure (JSRefCountHeader ref_count)
  poke ptr (JSRefCountHeader ref_count) = do
    poke ((\hsc_ptr -> hsc_ptr `plusPtr` 0) ptr) ref_count
{-# LINE 74 "src/Quickjs/Types.hsc" #-}



class ToCType ty cty where
  toCType :: ty -> cty


class FromCType ty cty where
  fromCType :: cty -> Maybe ty


data JSTagEnum = JSTagFirst
               | JSTagBigDecimal
               | JSTagBigInt
               | JSTagBigFloat
               | JSTagSymbol
               | JSTagString
               | JSTagModule
               | JSTagFunctionBytecode
               | JSTagObject
               | JSTagInt
               | JSTagBool
               | JSTagNull
               | JSTagUndefined
               | JSTagUninitialized
               | JSTagCatchOffset
               | JSTagException
               | JSTagFloat64
  deriving (Show, Eq)

instance Num a => ToCType JSTagEnum a where
  toCType JSTagFirst            = -11
{-# LINE 106 "src/Quickjs/Types.hsc" #-}
  toCType JSTagBigDecimal       = -11
{-# LINE 107 "src/Quickjs/Types.hsc" #-}
  toCType JSTagBigInt           = -10
{-# LINE 108 "src/Quickjs/Types.hsc" #-}
  toCType JSTagBigFloat         = -9
{-# LINE 109 "src/Quickjs/Types.hsc" #-}
  toCType JSTagSymbol           = -8
{-# LINE 110 "src/Quickjs/Types.hsc" #-}
  toCType JSTagString           = -7
{-# LINE 111 "src/Quickjs/Types.hsc" #-}
  toCType JSTagModule           = -3
{-# LINE 112 "src/Quickjs/Types.hsc" #-}
  toCType JSTagFunctionBytecode = -2
{-# LINE 113 "src/Quickjs/Types.hsc" #-}
  toCType JSTagObject           = -1
{-# LINE 114 "src/Quickjs/Types.hsc" #-}
  toCType JSTagInt              = 0
{-# LINE 115 "src/Quickjs/Types.hsc" #-}
  toCType JSTagBool             = 1
{-# LINE 116 "src/Quickjs/Types.hsc" #-}
  toCType JSTagNull             = 2
{-# LINE 117 "src/Quickjs/Types.hsc" #-}
  toCType JSTagUndefined        = 3
{-# LINE 118 "src/Quickjs/Types.hsc" #-}
  toCType JSTagUninitialized    = 4
{-# LINE 119 "src/Quickjs/Types.hsc" #-}
  toCType JSTagCatchOffset      = 5
{-# LINE 120 "src/Quickjs/Types.hsc" #-}
  toCType JSTagException        = 6
{-# LINE 121 "src/Quickjs/Types.hsc" #-}
  toCType JSTagFloat64          = 7
{-# LINE 122 "src/Quickjs/Types.hsc" #-}


instance (Eq a, Num a) => FromCType JSTagEnum a where
  fromCType (-11) = Just JSTagBigDecimal
{-# LINE 126 "src/Quickjs/Types.hsc" #-}
  fromCType (-10) = Just JSTagBigInt
{-# LINE 127 "src/Quickjs/Types.hsc" #-}
  fromCType (-9) = Just JSTagBigFloat
{-# LINE 128 "src/Quickjs/Types.hsc" #-}
  fromCType (-8) = Just JSTagSymbol
{-# LINE 129 "src/Quickjs/Types.hsc" #-}
  fromCType (-7) = Just JSTagString
{-# LINE 130 "src/Quickjs/Types.hsc" #-}
  fromCType (-3) = Just JSTagModule
{-# LINE 131 "src/Quickjs/Types.hsc" #-}
  fromCType (-2) = Just JSTagFunctionBytecode
{-# LINE 132 "src/Quickjs/Types.hsc" #-}
  fromCType (-1) = Just JSTagObject
{-# LINE 133 "src/Quickjs/Types.hsc" #-}
  fromCType (0) = Just JSTagInt
{-# LINE 134 "src/Quickjs/Types.hsc" #-}
  fromCType (1) = Just JSTagBool
{-# LINE 135 "src/Quickjs/Types.hsc" #-}
  fromCType (2) = Just JSTagNull
{-# LINE 136 "src/Quickjs/Types.hsc" #-}
  fromCType (3) = Just JSTagUndefined
{-# LINE 137 "src/Quickjs/Types.hsc" #-}
  fromCType (4) = Just JSTagUninitialized
{-# LINE 138 "src/Quickjs/Types.hsc" #-}
  fromCType (5) = Just JSTagCatchOffset
{-# LINE 139 "src/Quickjs/Types.hsc" #-}
  fromCType (6) = Just JSTagException
{-# LINE 140 "src/Quickjs/Types.hsc" #-}
  fromCType (7) = Just JSTagFloat64
{-# LINE 141 "src/Quickjs/Types.hsc" #-}
  fromCType _ = Nothing

data JSTypeEnum = JSTypeFromTag JSTagEnum
                | JSIsNumber
                | JSIsArray
                | JSIsDate
                | JSIsError
  deriving Show

data JSEvalType = Global | Module


instance Num a => ToCType JSEvalType a where
  toCType Global = 0
{-# LINE 155 "src/Quickjs/Types.hsc" #-}
  toCType Module = 1
{-# LINE 156 "src/Quickjs/Types.hsc" #-}


newtype JSGPNMask = JSGPNMask { unJSGPNMask :: CInt }
  deriving (Eq, Bits)

jsGPNStringMask   :: JSGPNMask
jsGPNStringMask   = JSGPNMask 1
jsGPNSymbolMask   :: JSGPNMask
jsGPNSymbolMask   = JSGPNMask 2
jsGPNPrivateMask  :: JSGPNMask
jsGPNPrivateMask  = JSGPNMask 4
jsGPNEnumOnly     :: JSGPNMask
jsGPNEnumOnly     = JSGPNMask 16
jsGPNSetEnum      :: JSGPNMask
jsGPNSetEnum      = JSGPNMask 32

{-# LINE 168 "src/Quickjs/Types.hsc" #-}


quickjsCtx :: Context
quickjsCtx = baseCtx <> fptrCtx <> ctx
  where
    ctx = mempty
      { ctxTypesTable = quickjsTypesTable
      }

quickjsTypesTable :: TypesTable
quickjsTypesTable = Map.fromList
  [
    (C.TypeName "JSValue", [t| JSValue |])
  , (C.TypeName "JSValueConst", [t| JSValueConst |])
  , (C.TypeName "JSRuntime", [t| JSRuntime |])
  , (C.TypeName "JSContext", [t| JSContext |])
  , (C.TypeName "JSBool", [t| JSBool |])
  , (C.TypeName "JSAtom", [t| JSAtom |])
  , (C.TypeName "JSPropertyEnum", [t| JSPropertyEnum |])
  ]