{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE JavaScriptFFI #-}
{-# LANGUAGE UnliftedFFITypes #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE GHCForeignImportPrim #-}
module Data.JSString.Int
( decimal
, hexadecimal
) where
import Data.JSString
import Data.Monoid
import GHC.Int
import GHC.Word
import GHC.Exts ( ByteArray#
, Int(..), Int#, Int64#
, Word(..), Word#, Word64#
, (<#), (<=#), isTrue# )
import GHC.Integer.GMP.Internals
import Unsafe.Coerce
import GHCJS.Prim
decimal :: Integral a => a -> JSString
decimal i = decimal' i
{-# RULES "decimal/Int" decimal = decimalI :: Int -> JSString #-}
{-# RULES "decimal/Int8" decimal = decimalI8 :: Int8 -> JSString #-}
{-# RULES "decimal/Int16" decimal = decimalI16 :: Int16 -> JSString #-}
{-# RULES "decimal/Int32" decimal = decimalI32 :: Int32 -> JSString #-}
{-# RULES "decimal/Int64" decimal = decimalI64 :: Int64 -> JSString #-}
{-# RULES "decimal/Word" decimal = decimalW :: Word -> JSString #-}
{-# RULES "decimal/Word8" decimal = decimalW8 :: Word8 -> JSString #-}
{-# RULES "decimal/Word16" decimal = decimalW16 :: Word16 -> JSString #-}
{-# RULES "decimal/Word32" decimal = decimalW32 :: Word32 -> JSString #-}
{-# RULES "decimal/Word64" decimal = decimalW64 :: Word64 -> JSString #-}
{-# RULES "decimal/Integer" decimal = decimalInteger :: Integer -> JSString #-}
{-# SPECIALIZE decimal :: Integer -> JSString #-}
{-# SPECIALIZE decimal :: Int -> JSString #-}
{-# SPECIALIZE decimal :: Int8 -> JSString #-}
{-# SPECIALIZE decimal :: Int16 -> JSString #-}
{-# SPECIALIZE decimal :: Int32 -> JSString #-}
{-# SPECIALIZE decimal :: Int64 -> JSString #-}
{-# SPECIALIZE decimal :: Word -> JSString #-}
{-# SPECIALIZE decimal :: Word8 -> JSString #-}
{-# SPECIALIZE decimal :: Word16 -> JSString #-}
{-# SPECIALIZE decimal :: Word32 -> JSString #-}
{-# SPECIALIZE decimal :: Word64 -> JSString #-}
{-# INLINE [1] decimal #-}
decimalI :: Int -> JSString
decimalI (I# x) = js_decI x
{-# INLINE decimalI #-}
decimalI8 :: Int8 -> JSString
decimalI8 (I8# x) = js_decI x
{-# INLINE decimalI8 #-}
decimalI16 :: Int16 -> JSString
decimalI16 (I16# x) = js_decI x
{-# INLINE decimalI16 #-}
decimalI32 :: Int32 -> JSString
decimalI32 (I32# x) = js_decI x
{-# INLINE decimalI32 #-}
decimalI64 :: Int64 -> JSString
decimalI64 (I64# x) = js_decI64 x
{-# INLINE decimalI64 #-}
decimalW8 :: Word8 -> JSString
decimalW8 (W8# x) = js_decW x
{-# INLINE decimalW8 #-}
decimalW16 :: Word16 -> JSString
decimalW16 (W16# x) = js_decW x
{-# INLINE decimalW16 #-}
decimalW32 :: Word32 -> JSString
decimalW32 (W32# x) = js_decW32 x
{-# INLINE decimalW32 #-}
decimalW64 :: Word64 -> JSString
decimalW64 (W64# x) = js_decW64 x
{-# INLINE decimalW64 #-}
decimalW :: Word -> JSString
decimalW (W# x) = js_decW32 x
{-# INLINE decimalW #-}
data MyI = MyS Int# | MyJ Int# ByteArray#
decimalInteger :: Integer -> JSString
decimalInteger !i = js_decInteger (unsafeCoerce i)
{-# INLINE decimalInteger #-}
decimal' :: Integral a => a -> JSString
decimal' i = decimalInteger (toInteger i)
{-# NOINLINE decimal' #-}
hexadecimal :: Integral a => a -> JSString
hexadecimal i = hexadecimal' i
{-# RULES "hexadecimal/Int" hexadecimal = hexI :: Int -> JSString #-}
{-# RULES "hexadecimal/Int8" hexadecimal = hexI8 :: Int8 -> JSString #-}
{-# RULES "hexadecimal/Int16" hexadecimal = hexI16 :: Int16 -> JSString #-}
{-# RULES "hexadecimal/Int32" hexadecimal = hexI32 :: Int32 -> JSString #-}
{-# RULES "hexadecimal/Int64" hexadecimal = hexI64 :: Int64 -> JSString #-}
{-# RULES "hexadecimal/Word" hexadecimal = hexW :: Word -> JSString #-}
{-# RULES "hexadecimal/Word8" hexadecimal = hexW8 :: Word8 -> JSString #-}
{-# RULES "hexadecimal/Word16" hexadecimal = hexW16 :: Word16 -> JSString #-}
{-# RULES "hexadecimal/Word32" hexadecimal = hexW32 :: Word32 -> JSString #-}
{-# RULES "hexadecimal/Word64" hexadecimal = hexW64 :: Word64 -> JSString #-}
{-# RULES "hexadecimal/Integer" hexadecimal = hexInteger :: Integer -> JSString #-}
{-# SPECIALIZE hexadecimal :: Integer -> JSString #-}
{-# SPECIALIZE hexadecimal :: Int -> JSString #-}
{-# SPECIALIZE hexadecimal :: Int8 -> JSString #-}
{-# SPECIALIZE hexadecimal :: Int16 -> JSString #-}
{-# SPECIALIZE hexadecimal :: Int32 -> JSString #-}
{-# SPECIALIZE hexadecimal :: Int64 -> JSString #-}
{-# SPECIALIZE hexadecimal :: Word -> JSString #-}
{-# SPECIALIZE hexadecimal :: Word8 -> JSString #-}
{-# SPECIALIZE hexadecimal :: Word16 -> JSString #-}
{-# SPECIALIZE hexadecimal :: Word32 -> JSString #-}
{-# SPECIALIZE hexadecimal :: Word64 -> JSString #-}
{-# INLINE [1] hexadecimal #-}
hexadecimal' :: Integral a => a -> JSString
hexadecimal' i
| i < 0 = error hexErrMsg
| otherwise = hexInteger (toInteger i)
{-# NOINLINE hexadecimal' #-}
hexInteger :: Integer -> JSString
hexInteger !i
| i < 0 = error hexErrMsg
| otherwise = js_hexInteger (unsafeCoerce i)
{-# INLINE hexInteger #-}
hexI :: Int -> JSString
hexI (I# x) = if isTrue# (x <# 0#)
then error hexErrMsg
else js_hexI x
{-# INLINE hexI #-}
hexI8 :: Int8 -> JSString
hexI8 (I8# x) =
if isTrue# (x <# 0#)
then error hexErrMsg
else js_hexI x
{-# INLINE hexI8 #-}
hexI16 :: Int16 -> JSString
hexI16 (I16# x) =
if isTrue# (x <# 0#)
then error hexErrMsg
else js_hexI x
{-# INLINE hexI16 #-}
hexI32 :: Int32 -> JSString
hexI32 (I32# x) =
if isTrue# (x <# 0#)
then error hexErrMsg
else js_hexI x
{-# INLINE hexI32 #-}
hexI64 :: Int64 -> JSString
hexI64 i@(I64# x) =
if i < 0
then error hexErrMsg
else js_hexI64 x
{-# INLINE hexI64 #-}
hexW :: Word -> JSString
hexW (W# x) = js_hexW32 x
{-# INLINE hexW #-}
hexW8 :: Word8 -> JSString
hexW8 (W8# x) = js_hexW x
{-# INLINE hexW8 #-}
hexW16 :: Word16 -> JSString
hexW16 (W16# x) = js_hexW x
{-# INLINE hexW16 #-}
hexW32 :: Word32 -> JSString
hexW32 (W32# x) = js_hexW32 x
{-# INLINE hexW32 #-}
hexW64 :: Word64 -> JSString
hexW64 (W64# x) = js_hexW64 x
{-# INLINE hexW64 #-}
hexErrMsg :: String
hexErrMsg = "Data.JSString.Int.hexadecimal: applied to negative number"
foreign import javascript unsafe
"''+$1"
js_decI :: Int# -> JSString
foreign import javascript unsafe
"h$jsstringDecI64"
js_decI64 :: Int64# -> JSString
foreign import javascript unsafe
"''+$1"
js_decW :: Word# -> JSString
foreign import javascript unsafe
"''+(($1>=0)?$1:($1+4294967296))"
js_decW32 :: Word# -> JSString
foreign import javascript unsafe
"h$jsstringDecW64($1_1, $1_2)"
js_decW64 :: Word64# -> JSString
foreign import javascript unsafe
"h$jsstringDecInteger($1)"
js_decInteger :: Any -> JSString
foreign import javascript unsafe
"$1.toString(16)"
js_hexI :: Int# -> JSString
foreign import javascript unsafe
"h$jsstringHexI64"
js_hexI64 :: Int64# -> JSString
foreign import javascript unsafe
"$1.toString(16)"
js_hexW :: Word# -> JSString
foreign import javascript unsafe
"(($1>=0)?$1:($1+4294967296)).toString(16)"
js_hexW32 :: Word# -> JSString
foreign import javascript unsafe
"h$jsstringHexW64($1_1, $1_2)"
js_hexW64 :: Word64# -> JSString
foreign import javascript unsafe
"h$jsstringHexInteger($1)"
js_hexInteger :: Any -> JSString
foreign import javascript unsafe
"'-'+$1+(-$2)"
js_minusDigit :: JSString -> Int# -> JSString
foreign import javascript unsafe
"'-'+$1"
js_minus :: JSString -> JSString
foreign import javascript unsafe
"h$jsstringDecIPadded9"
js_decIPadded9 :: Int# -> JSString
foreign import javascript unsafe
"h$jsstringHexIPadded8"
js_hexIPadded8 :: Int# -> JSString