<commit_before>{-# LANGUAGE EmptyDataDecls, ForeignFunctionInterface, MagicHash #-}
module Haste.Prim (JSString, toJSStr, fromJSStr, round_, NumberRep,
                   JSAny, mkPtr) where
import Foreign.Ptr
import Unsafe.Coerce
import GHC.Types
import GHC.Prim

foreign import ccall _str :: JSString

type JSAny = Ptr Haste.Prim.Any
data Any
type JSString = Ptr JSChr
data JSChr

-- | We need to fake the same representation as Ptr a; FakePtr does this.
data FakePtr a = FakePtr a

-- | In normal Haskell, we use Storable for data that can be pointed to. When
--   we compile to JS, however, anything can be "pointed" to and nothing needs
--   to be stored, so we just wrap a value in another constructor and cast it
--   to a pointer.
mkPtr :: a -> Ptr a
mkPtr = unsafeCoerce . FakePtr

{-# NOINLINE toJSStr #-}
-- | Defined in lib/rts.js
toJSStr :: String -> JSString
toJSStr s = s `seq` _str

{-# NOINLINE fromJSStr #-}
-- | Defined in lib/rts.js
fromJSStr :: JSString -> String
fromJSStr s = s `seq` []

class NumberRep a where
  round_ :: a -> Int
  
instance NumberRep Double where
  round_ (D# d) = I# (jsRound d)
instance NumberRep Float where
  round_ (F# f) = I# (unsafeCoerce# (jsRound (unsafeCoerce# f)))
instance NumberRep Int where
  round_ = id<commit_msg>Add rewrite rules to avoid unnecessary String <-> JSString conversions.<commit_after>{-# LANGUAGE EmptyDataDecls, ForeignFunctionInterface, MagicHash #-}
module Haste.Prim (JSString, toJSStr, fromJSStr, round_, NumberRep,
                   JSAny, mkPtr) where
import Foreign.Ptr
import Unsafe.Coerce
import GHC.CString
import GHC.Types
import GHC.Prim

foreign import ccall _str :: JSString

type JSAny = Ptr Haste.Prim.Any
data Any
type JSString = Ptr JSChr
data JSChr

-- | We need to fake the same representation as Ptr a; FakePtr does this.
data FakePtr a = FakePtr a

-- | In normal Haskell, we use Storable for data that can be pointed to. When
--   we compile to JS, however, anything can be "pointed" to and nothing needs
--   to be stored, so we just wrap a value in another constructor and cast it
--   to a pointer.
mkPtr :: a -> Ptr a
mkPtr = unsafeCoerce . FakePtr

{-# RULES "toJSS/fromJSS" forall s. toJSStr (fromJSStr s) = s #-}
{-# RULES "fromJSS/toJSS" forall s. fromJSStr (toJSStr s) = s #-}
{-# RULES "toJSS/unCSTR" forall s. toJSStr (unpackCString# s) = mkPtr (unsafeCoerce# s) #-}
{-# RULES "toJSS/unCSTRU8" forall s. toJSStr (unpackCStringUtf8# s) = mkPtr (unsafeCoerce# s) #-}

{-# NOINLINE toJSStr #-}
-- | Defined in lib/rts.js
toJSStr :: String -> JSString
toJSStr s = s `seq` _str

{-# NOINLINE fromJSStr #-}
-- | Defined in lib/rts.js
fromJSStr :: JSString -> String
fromJSStr s = s `seq` []

class NumberRep a where
  round_ :: a -> Int
  
instance NumberRep Double where
  round_ (D# d) = I# (jsRound d)
instance NumberRep Float where
  round_ (F# f) = I# (unsafeCoerce# (jsRound (unsafeCoerce# f)))
instance NumberRep Int where
  round_ = id
{'fraction_non_alphanumeric': 0.10481682496607869, 'fraction_numerical': 0.0006784260515603799, 'mean_word_length': 3.5091743119266057, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1308857', 'n_tokens_mistral': 1078, 'n_tokens_neox': 1019, 'n_words': 385}