Move the Integer type definition into GHC.Integer.Internals
[packages/integer-gmp.git] / GHC / Integer.lhs
index ae1a097..137eff1 100644 (file)
@@ -1,5 +1,5 @@
 \begin{code}
-{-# OPTIONS_GHC -fno-implicit-prelude #-}
+{-# OPTIONS_GHC -XNoImplicitPrelude #-}
 {-# OPTIONS_HADDOCK hide #-}
 -----------------------------------------------------------------------------
 -- |
 module GHC.Integer (
     Integer,
     smallInteger, wordToInteger, integerToWord, toInt#,
+#if WORD_SIZE_IN_BITS < 64
+    integerToWord64, word64ToInteger,
+    integerToInt64, int64ToInteger,
+#endif
     plusInteger, minusInteger, timesInteger, negateInteger,
     eqInteger, neqInteger, absInteger, signumInteger,
     leInteger, gtInteger, ltInteger, geInteger, compareInteger,
@@ -59,9 +63,24 @@ import GHC.Prim (
     decodeDouble#, decodeFloat#,
     int2Integer#, integer2Int#, word2Integer#, integer2Word#,
     andInteger#, orInteger#, xorInteger#, complementInteger#,
+#if WORD_SIZE_IN_BITS < 64
+    int64ToInteger#, word64ToInteger#,
+#endif
  )
 
+import GHC.Integer.Internals (Integer(..))
+
+#if WORD_SIZE_IN_BITS < 64
+import GHC.IntWord64 (
+            Int64#, Word64#,
+            int64ToWord64#, intToInt64#, integerToWord64#,
+            int64ToInt#, word64ToInt64#, integerToInt64#,
+            geInt64#, leInt64#, leWord64#,
+       )
+#endif
+
 import GHC.Bool
+import GHC.Ordering
 
 default ()              -- Double isn't available yet,
                         -- and we shouldn't be using defaults anyway
@@ -73,19 +92,6 @@ default ()              -- Double isn't available yet,
 %*                                                      *
 %*********************************************************
 
-\begin{code}
--- | Arbitrary-precision integers.
-data Integer
-   = S# Int#                            -- small integers
-#ifndef ILX
-   | J# Int# ByteArray#                 -- large integers
-#else
-   | J# Void BigInteger                 -- .NET big ints
-
-foreign type dotnet "BigInteger" BigInteger
-#endif
-\end{code}
-
 Convenient boxed Integer PrimOps.
 
 \begin{code}
@@ -102,6 +108,33 @@ integerToWord :: Integer -> Word#
 integerToWord (S# i) = int2Word# i
 integerToWord (J# s d) = integer2Word# s d
 
+#if WORD_SIZE_IN_BITS < 64
+{-# INLINE integerToWord64 #-}
+integerToWord64 :: Integer -> Word64#
+integerToWord64 (S# i) = int64ToWord64# (intToInt64# i)
+integerToWord64 (J# s d) = integerToWord64# s d
+
+word64ToInteger :: Word64# -> Integer
+word64ToInteger w = if w `leWord64#` int64ToWord64# (intToInt64# 0x7FFFFFFF#)
+                    then S# (int64ToInt# (word64ToInt64# w))
+                    else case word64ToInteger# w of
+                         (# s, d #) -> J# s d
+
+integerToInt64 :: Integer -> Int64#
+integerToInt64 (S# i) = intToInt64# i
+integerToInt64 (J# s d) = integerToInt64# s d
+
+int64ToInteger :: Int64# -> Integer
+int64ToInteger i = if ((i `leInt64#` intToInt64# 0x7FFFFFFF#) && 
+                       (i `geInt64#` intToInt64# -0x80000000#))
+                   then smallInteger (int64ToInt# i)
+                   else case int64ToInteger# i of
+                        (# s, d #) -> J# s d
+    where -- XXX Move the (&&) definition below us?
+          True  && x = x
+          False && _ = False
+#endif
+
 toInt# :: Integer -> Int#
 toInt# (S# i)   = i
 toInt# (J# s d) = integer2Int# s d
@@ -298,29 +331,25 @@ geInteger (J# s d)   (S# i)     = cmpIntegerInt# s d i >=# 0#
 geInteger (S# i)     (J# s d)   = cmpIntegerInt# s d i <=# 0#
 geInteger (J# s1 d1) (J# s2 d2) = (cmpInteger# s1 d1 s2 d2) >=# 0#
 
--- GT => 1
--- EQ => 0
--- LT => -1
--- XXX Should we just define Ordering higher up?
-compareInteger :: Integer -> Integer -> Int#
+compareInteger :: Integer -> Integer -> Ordering
 compareInteger (S# i)  (S# j)
-   =      if i ==# j then 0#
-     else if i <=# j then -1#
-     else                 1#
+   =      if i ==# j then EQ
+     else if i <=# j then LT
+     else                 GT
 compareInteger (J# s d) (S# i)
    = case cmpIntegerInt# s d i of { res# ->
-     if res# <# 0# then -1# else
-     if res# ># 0# then 1# else 0#
+     if res# <# 0# then LT else
+     if res# ># 0# then GT else EQ
      }
 compareInteger (S# i) (J# s d)
    = case cmpIntegerInt# s d i of { res# ->
-     if res# ># 0# then -1# else
-     if res# <# 0# then 1# else 0#
+     if res# ># 0# then LT else
+     if res# <# 0# then GT else EQ
      }
 compareInteger (J# s1 d1) (J# s2 d2)
    = case cmpInteger# s1 d1 s2 d2 of { res# ->
-     if res# <# 0# then -1# else
-     if res# ># 0# then 1# else 0#
+     if res# <# 0# then LT else
+     if res# ># 0# then GT else EQ
      }
 \end{code}