[project @ 2000-03-09 06:14:38 by andy]
[ghc-hetmet.git] / ghc / lib / hugs / Prelude.hs
index ce05049..1937a12 100644 (file)
@@ -4,7 +4,7 @@ __   __ __  __  ____   ___    _______________________________________________
 ||___|| ||__|| ||__||  __||   Copyright (c) 1994-1999
 ||---||         ___||         World Wide Web: http://haskell.org/hugs
 ||   ||                       Report bugs to: hugs-bugs@haskell.org
-||   || Version: January 1999 _______________________________________________
+||   || Version: STG Hugs     _______________________________________________
 
  This is the Hugs 98 Standard Prelude, based very closely on the Standard
  Prelude for Haskell 98.
@@ -60,7 +60,7 @@ module Prelude (
 --  module Ratio,
     Ratio, Rational, (%), numerator, denominator, approxRational,
 --  Non-standard exports
-    IO(..), IOResult(..), Addr, StablePtr,
+    IO, IOResult(..), Addr, StablePtr,
     makeStablePtr, freeStablePtr, deRefStablePtr,
 
     Bool(False, True),
@@ -84,8 +84,7 @@ module Prelude (
     Real(toRational),
 --  Integral(quot, rem, div, mod, quotRem, divMod, toInteger),
     Integral(quot, rem, div, mod, quotRem, divMod, even, odd, toInteger, toInt),
---  Fractional((/), recip, fromRational),
-    Fractional((/), recip, fromRational, fromDouble),
+    Fractional((/), recip, fromRational), fromDouble,
     Floating(pi, exp, log, sqrt, (**), logBase, sin, cos, tan,
              asin, acos, atan, sinh, cosh, tanh, asinh, acosh, atanh),
     RealFrac(properFraction, truncate, round, ceiling, floor),
@@ -103,39 +102,6 @@ module Prelude (
     asTypeOf, error, undefined,
     seq, ($!)
 
-    , MVar, newEmptyMVar, newMVar, putMVar, takeMVar, readMVar, swapMVar
-    , ThreadId, forkIO
-    ,trace
-
-    , STRef, newSTRef, readSTRef, writeSTRef
-    , IORef, newIORef, readIORef, writeIORef
-
-    -- This lot really shouldn't be exported, but are needed to
-    -- implement various libs.
-    ,primCompAux,PrimArray,primRunST,primNewArray,primWriteArray
-    ,primUnsafeFreezeArray,primIndexArray,primGetRawArgs,primGetEnv
-    ,nh_stdin,nh_stdout,nh_stderr,copy_String_to_cstring,nh_open
-    ,nh_free,nh_close,nh_errno,nh_flush,nh_read,primIntToChar
-    ,unsafeInterleaveIO,nh_write,primCharToInt,
-    nullAddr, incAddr, isNullAddr, 
-    nh_filesize, nh_iseof, nh_system, nh_exitwith, nh_getPID,
-    nh_getCPUtime, nh_getCPUprec, prelCleanupAfterRunAction,
-
-    Word,
-    primGtWord, primGeWord, primEqWord, primNeWord,
-    primLtWord, primLeWord, primMinWord, primMaxWord,
-    primPlusWord, primMinusWord, primTimesWord, primQuotWord,
-    primRemWord, primQuotRemWord, primNegateWord, primAndWord,
-    primOrWord, primXorWord, primNotWord, primShiftLWord,
-    primShiftRAWord, primShiftRLWord, primIntToWord, primWordToInt,
-
-    primAndInt, primOrInt, primXorInt, primNotInt,
-    primShiftLInt, primShiftRAInt,  primShiftRLInt,
-
-    primAddrToInt, primIntToAddr,
-
-    primDoubleToFloat, primFloatToDouble,
-
   ) where
 
 -- Standard value bindings {Prelude} ----------------------------------------
@@ -227,13 +193,13 @@ class (Num a) => Fractional a where
     (/)          :: a -> a -> a
     recip        :: a -> a
     fromRational :: Rational -> a
-    fromDouble   :: Double -> a
 
     -- Minimal complete definition: fromRational and ((/) or recip)
     recip x       = 1 / x
-    fromDouble    = fromRational . toRational
     x / y         = x * recip y
 
+fromDouble :: Fractional a => Double -> a
+fromDouble n = fromRational (toRational n)
 
 class (Fractional a) => Floating a where
     pi                  :: a
@@ -632,7 +598,7 @@ instance Ord a => Ord [a] where
     compare []     (_:_)  = LT
     compare []     []     = EQ
     compare (_:_)  []     = GT
-    compare (x:xs) (y:ys) = primCompAux x y (compare xs ys)
+    compare (x:xs) (y:ys) = hugsprimCompAux x y (compare xs ys)
 
 instance Functor [] where
     fmap = map
@@ -851,13 +817,10 @@ realFloatToRational x = (m%1)*(b%1)^^n
 instance Fractional Float where
     (/)           = primDivideFloat
     fromRational  = rationalToRealFloat
-    fromDouble    = primDoubleToFloat
-
 
 instance Fractional Double where
     (/)          = primDivideDouble
     fromRational = rationalToRealFloat
-    fromDouble x = x
 
 rationalToRealFloat x = x'
  where x'    = f e
@@ -1039,7 +1002,6 @@ instance Integral a => Fractional (Ratio a) where
     (x:%y) / (x':%y')   = (x*y') % (y*x')
     recip (x:%y)        = if x < 0 then (-y) :% (-x) else y :% x
     fromRational (x:%y) = fromInteger x :% fromInteger y
-    fromDouble                 = doubleToRatio
 
 -- Hugs optimises code of the form fromRational (doubleToRatio x)
 doubleToRatio :: Integral a => Double -> Ratio a
@@ -1337,8 +1299,8 @@ showString    = (++)
 showParen    :: Bool -> ShowS -> ShowS
 showParen b p = if b then showChar '(' . p . showChar ')' else p
 
-showField    :: Show a => String -> a -> ShowS
-showField m v = showString m . showChar '=' . shows v
+hugsprimShowField    :: Show a => String -> a -> ShowS
+hugsprimShowField m v = showString m . showChar '=' . shows v
 
 readParen    :: Bool -> ReadS a -> ReadS a
 readParen b g = if b then mandatory else optional
@@ -1348,10 +1310,10 @@ readParen b g = if b then mandatory else optional
                                             (")",u) <- lex t    ]
 
 
-readField    :: Read a => String -> ReadS a
-readField m s0 = [ r | (t,  s1) <- lex s0, t == m,
-                       ("=",s2) <- lex s1,
-                       r        <- reads s2 ]
+hugsprimReadField    :: Read a => String -> ReadS a
+hugsprimReadField m s0 = [ r | (t,  s1) <- lex s0, t == m,
+                               ("=",s2) <- lex s1,
+                               r        <- reads s2 ]
 
 lex                    :: ReadS String
 lex ""                  = [("","")]
@@ -1545,8 +1507,11 @@ readFloat r    = [(fromRational ((n%1)*10^^(k-d)),t) | (n,d,s) <- readFix r,
 -- Hooks for primitives: -----------------------------------------------------
 -- Do not mess with these!
 
-primCompAux      :: Ord a => a -> a -> Ordering -> Ordering
-primCompAux x y o = case compare x y of EQ -> o; LT -> LT; GT -> GT
+hugsprimCompAux      :: Ord a => a -> a -> Ordering -> Ordering
+hugsprimCompAux x y o = case compare x y of EQ -> o; LT -> LT; GT -> GT
+
+hugsprimEqChar       :: Char -> Char -> Bool
+hugsprimEqChar c1 c2  = primEqChar c1 c2
 
 hugsprimPmInt        :: Num a => Int -> a -> Bool
 hugsprimPmInt n x     = fromInt n == x
@@ -1554,16 +1519,21 @@ hugsprimPmInt n x     = fromInt n == x
 hugsprimPmInteger    :: Num a => Integer -> a -> Bool
 hugsprimPmInteger n x = fromInteger n == x
 
-primPmDouble     :: Fractional a => Double -> a -> Bool
-primPmDouble n x  = fromDouble n == x
+hugsprimPmDouble     :: Fractional a => Double -> a -> Bool
+hugsprimPmDouble n x  = fromDouble n == x
 
 -- ToDo: make the message more informative.
-primPmFail       :: a
-primPmFail        = error "Pattern Match Failure"
+hugsprimPmFail       :: a
+hugsprimPmFail        = error "Pattern Match Failure"
 
 -- used in desugaring Foreign functions
+-- Note: hugsprimMkIO is used as a wrapper to translate a Hugs-created
+-- bit of code of type   RealWorld -> (a,RealWorld)   into a proper IO value.
+-- What follows is the version for standalone mode.  ghc/lib/std/PrelHugs.lhs
+-- contains a version used in combined mode.  That version takes care of
+-- switching between the GHC and Hugs IO representations, which are different.
 hugsprimMkIO :: (RealWorld -> (a,RealWorld)) -> IO a
-hugsprimMkIO = ST
+hugsprimMkIO = IO
 
 hugsprimCreateAdjThunk :: (a -> b) -> String -> Char -> IO Addr
 hugsprimCreateAdjThunk fun typestr callconv
@@ -1590,8 +1560,8 @@ hugsprimPmLe x y         = x <= y
 -- 
 -- ToDo: change this (and Hugs code generator) to use ByteArrays
 
-primUnpackString :: Addr -> String
-primUnpackString a = unpack 0
+hugsprimUnpackString :: Addr -> String
+hugsprimUnpackString a = unpack 0
  where
   -- The following decoding is based on evalString in the old machine.c
   unpack i
@@ -1624,7 +1594,7 @@ userError s = primRaise (ErrorCall s)
 
 catch :: IO a -> (IOError -> IO a) -> IO a
 catch m k 
-  = ST (\s -> unST m s `primCatch` \ err -> unST (k (e2ioe err)) s)
+  = IO (\s -> unIO m s `primCatch` \ err -> unIO (k (e2ioe err)) s)
     where
        e2ioe (IOExcept s) = IOError s
        e2ioe other        = IOError (show other)
@@ -1645,11 +1615,9 @@ print :: Show a => a -> IO ()
 print = putStrLn . show
 
 getChar :: IO Char
-getChar = unsafeInterleaveIO (
-          nh_stdin  >>= \h -> 
+getChar = nh_stdin  >>= \h -> 
           nh_read h >>= \ci -> 
           return (primIntToChar ci)
-          )
 
 getLine :: IO String
 getLine    = do c <- getChar
@@ -1798,29 +1766,31 @@ primGetEnv v
      nh_getenv ptr                >>= \ptr2 ->
      nh_free ptr                  >>
      if   isNullAddr ptr2
-     then return []
+     then ioError (IOError "getEnv failed")
      else
      copy_cstring_to_String ptr2  >>= \result ->
      return result
 
 
 ------------------------------------------------------------------------------
--- ST, IO --------------------------------------------------------------------
+-- ST ------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 newtype ST s a = ST (s -> (a,s))
-
+unST (ST a) = a
 data RealWorld
-type IO a = ST RealWorld a
 
---primRunST :: (forall s. ST s a) -> a
-primRunST :: ST RealWorld a -> a
-primRunST m = fst (unST m theWorld)
+runST :: (__forall s . ST s a) -> a
+runST m = fst (unST m alpha)
    where
-      theWorld :: RealWorld
-      theWorld = error "primRunST: entered the RealWorld"
+      alpha = error "runST: entered the RealWorld"
 
-unST (ST a) = a
+fixST :: (a -> ST s a) -> ST s a
+fixST m = ST (\ s -> 
+               let 
+                  (r,s) = unST (m r) s
+               in
+                  (r,s))
 
 instance Functor (ST s) where
    fmap f x  = x >>= (return . f)
@@ -1830,6 +1800,35 @@ instance Monad (ST s) where
    return x  = ST (\s -> (x,s))
    m >>= k   = ST (\s -> case unST m s of { (a,s') -> unST (k a) s' })
 
+unsafeInterleaveST :: ST s a -> ST s a
+unsafeInterleaveST m = ST (\ s -> (fst (unST m s), s))
+
+------------------------------------------------------------------------------
+-- IO ------------------------------------------------------------------------
+------------------------------------------------------------------------------
+
+newtype IO a = IO (RealWorld -> (a,RealWorld))
+unIO (IO a) = a
+
+stToIO       :: ST RealWorld a -> IO a
+stToIO (ST fn) = IO fn
+
+ioToST       :: IO a -> ST RealWorld a
+ioToST (IO fn) = ST fn
+
+unsafePerformIO :: IO a -> a
+unsafePerformIO m = fst (unIO m theWorld)
+   where
+      theWorld :: RealWorld
+      theWorld = error "unsafePerformIO: entered the RealWorld"
+
+instance Functor IO where
+   fmap f x  = x >>= (return . f)
+
+instance Monad IO where
+   m >> k    = IO (\s -> case unIO m s of { (a,s') -> unIO k s' })
+   return x  = IO (\s -> (x,s))
+   m >>= k   = IO (\s -> case unIO m s of { (a,s') -> unIO (k a) s' })
 
 -- Library IO has a global variable which accumulates Handles
 -- as they are opened.  We keep here a second global variable
@@ -1839,12 +1838,12 @@ instance Monad (ST s) where
 -- Doing it like this means the Prelude does not have to know
 -- anything about the grotty details of the Handle implementation.
 prelCleanupAfterRunAction :: IORef (Maybe (IO ()))
-prelCleanupAfterRunAction = primRunST (newIORef Nothing)
+prelCleanupAfterRunAction = unsafePerformIO (newIORef Nothing)
 
 -- used when Hugs invokes top level function
 hugsprimRunIO_toplevel :: IO a -> ()
 hugsprimRunIO_toplevel m
-   = protect 5 (fst (unST composite_action realWorld))
+   = protect 5 (fst (unIO composite_action realWorld))
      where
         composite_action
            = do writeIORef prelCleanupAfterRunAction Nothing
@@ -1860,20 +1859,10 @@ hugsprimRunIO_toplevel m
            = comp
         protect n comp
            = primCatch (protect (n-1) comp)
-                       (\e -> fst (unST (putStr (show e ++ "\n")) realWorld))
-
-trace, trace_quiet :: String -> a -> a
-trace s x
-   = trace_quiet ("trace: " ++ s) x
-trace_quiet s x
-   = (primRunST (putStr (s ++ "\n"))) `seq` x
-
-unsafeInterleaveST :: ST s a -> ST s a
-unsafeInterleaveST m = ST (\ s -> (fst (unST m s), s))
+                       (\e -> fst (unIO (putStr (show e ++ "\n")) realWorld))
 
 unsafeInterleaveIO :: IO a -> IO a
-unsafeInterleaveIO = unsafeInterleaveST
-
+unsafeInterleaveIO m = IO (\ s -> (fst (unIO m s), s))
 
 ------------------------------------------------------------------------------
 -- Word, Addr, StablePtr, Prim*Array -----------------------------------------
@@ -1931,13 +1920,13 @@ readSTRef   = primReadRef
 writeSTRef :: STRef s a -> a -> ST s ()
 writeSTRef  = primWriteRef
 
-type IORef a = STRef RealWorld a
+newtype IORef a = IORef (STRef RealWorld a)
 newIORef   :: a -> IO (IORef a)
-newIORef    = primNewRef
+newIORef   a = stToIO (primNewRef a >>= \ ref ->return (IORef ref))
 readIORef  :: IORef a -> IO a
-readIORef   = primReadRef
+readIORef  (IORef ref) = stToIO (primReadRef ref)
 writeIORef :: IORef a -> a -> IO ()
-writeIORef  = primWriteRef
+writeIORef  (IORef ref) a = stToIO (primWriteRef ref a)
 
 
 ------------------------------------------------------------------------------
@@ -1954,7 +1943,7 @@ putMVar = primPutMVar
 
 takeMVar :: MVar a -> IO a
 takeMVar m
-   = ST (\world -> primTakeMVar m cont world)
+   = IO (\world -> primTakeMVar m cont world)
      where
         -- cont :: a -> RealWorld -> (a,RealWorld)
         -- where 'a' is as in the top-level signature
@@ -2013,17 +2002,19 @@ instance Ord ThreadId where
 forkIO :: IO a -> IO ThreadId
 -- Simple version; doesn't catch exceptions in computation
 -- forkIO computation 
---    = primForkIO (primRunST computation)
+--    = primForkIO (unsafePerformIO computation)
 
 forkIO computation
    = primForkIO (
         primCatch
-           (unST computation realWorld `primSeq` ())
+           (unIO computation realWorld `primSeq` ())
            (\e -> trace_quiet ("forkIO: uncaught exception: " ++ show e) ())
      )
      where
         realWorld = error "primForkIO: entered the RealWorld"
 
+trace_quiet s x
+   = (unsafePerformIO (putStr (s ++ "\n"))) `seq` x
 
 -- showFloat ------------------------------------------------------------------