[project @ 1999-11-23 11:43:25 by simonpj]
[ghc-hetmet.git] / ghc / interpreter / lib / Prelude.hs
index 77e7883..3ada1bc 100644 (file)
@@ -106,14 +106,20 @@ module Prelude (
     , MVar, newEmptyMVar, newMVar, putMVar, takeMVar, readMVar, swapMVar
     , ThreadId, forkIO
     ,trace
-    -- Arrrggghhh!!! Help! Help! Help!
-    -- What?!  Prelude.hs doesn't even _define_ most of these things!
+
+    , 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,
+    nullAddr, incAddr, isNullAddr, 
+    nh_filesize, nh_iseof, nh_system, nh_exitwith, nh_getPID,
+    nh_getCPUtime, nh_getCPUprec, prelCleanupAfterRunAction,
 
     Word,
     primGtWord, primGeWord, primEqWord, primNeWord,
@@ -129,11 +135,7 @@ module Prelude (
     primAddrToInt, primIntToAddr,
 
     primDoubleToFloat, primFloatToDouble,
-    -- debugging hacks
-    --,ST(..)
-    --,primIntToAddr
-    --,primGetArgc
-    --,primGetArgv
+
   ) where
 
 -- Standard value bindings {Prelude} ----------------------------------------
@@ -1713,21 +1715,29 @@ data IOResult  = IOResult  deriving (Show)
 
 type FILE_STAR = Addr   -- FILE *
 
-foreign import "nHandle" "nh_stdin"  nh_stdin  :: IO FILE_STAR
-foreign import "nHandle" "nh_stdout" nh_stdout :: IO FILE_STAR
-foreign import "nHandle" "nh_stderr" nh_stderr :: IO FILE_STAR
-foreign import "nHandle" "nh_write"  nh_write  :: FILE_STAR -> Char -> IO ()
-foreign import "nHandle" "nh_read"   nh_read   :: FILE_STAR -> IO Int
-foreign import "nHandle" "nh_open"   nh_open   :: Addr -> Int -> IO FILE_STAR
-foreign import "nHandle" "nh_flush"  nh_flush  :: FILE_STAR -> IO ()
-foreign import "nHandle" "nh_close"  nh_close  :: FILE_STAR -> IO ()
-foreign import "nHandle" "nh_errno"  nh_errno  :: IO Int
-
-foreign import "nHandle" "nh_malloc" nh_malloc :: Int -> IO Addr
-foreign import "nHandle" "nh_free"   nh_free   :: Addr -> IO ()
-foreign import "nHandle" "nh_store"  nh_store  :: Addr -> Char -> IO ()
-foreign import "nHandle" "nh_load"   nh_load   :: Addr -> IO Char
-foreign import "nHandle" "nh_getenv" nh_getenv :: Addr -> IO Addr
+foreign import "nHandle" "nh_stdin"    nh_stdin    :: IO FILE_STAR
+foreign import "nHandle" "nh_stdout"   nh_stdout   :: IO FILE_STAR
+foreign import "nHandle" "nh_stderr"   nh_stderr   :: IO FILE_STAR
+foreign import "nHandle" "nh_write"    nh_write    :: FILE_STAR -> Char -> IO ()
+foreign import "nHandle" "nh_read"     nh_read     :: FILE_STAR -> IO Int
+foreign import "nHandle" "nh_open"     nh_open     :: Addr -> Int -> IO FILE_STAR
+foreign import "nHandle" "nh_flush"    nh_flush    :: FILE_STAR -> IO ()
+foreign import "nHandle" "nh_close"    nh_close    :: FILE_STAR -> IO ()
+foreign import "nHandle" "nh_errno"    nh_errno    :: IO Int
+
+foreign import "nHandle" "nh_malloc"   nh_malloc   :: Int -> IO Addr
+foreign import "nHandle" "nh_free"     nh_free     :: Addr -> IO ()
+foreign import "nHandle" "nh_store"    nh_store    :: Addr -> Char -> IO ()
+foreign import "nHandle" "nh_load"     nh_load     :: Addr -> IO Char
+foreign import "nHandle" "nh_getenv"   nh_getenv   :: Addr -> IO Addr
+foreign import "nHandle" "nh_filesize" nh_filesize :: FILE_STAR -> IO Int
+foreign import "nHandle" "nh_iseof"    nh_iseof    :: FILE_STAR -> IO Int
+foreign import "nHandle" "nh_system"   nh_system   :: Addr -> IO Int
+foreign import "nHandle" "nh_exitwith" nh_exitwith :: Int -> IO ()
+foreign import "nHandle" "nh_getPID"   nh_getPID   :: IO Int
+
+foreign import "nHandle" "nh_getCPUtime" nh_getCPUtime :: IO Double
+foreign import "nHandle" "nh_getCPUprec" nh_getCPUprec :: IO Double
 
 copy_String_to_cstring :: String -> IO Addr
 copy_String_to_cstring s
@@ -1796,7 +1806,6 @@ newtype ST s a = ST (s -> (a,s))
 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)
@@ -1815,15 +1824,36 @@ instance Monad (ST s) where
    m >>= k   = ST (\s -> case unST m s of { (a,s') -> unST (k a) s' })
 
 
+-- Library IO has a global variable which accumulates Handles
+-- as they are opened.  We keep here a second global variable
+-- into which a cleanup action may be specified.  When evaluation
+-- finishes, either normally or as a result of System.exitWith,
+-- this cleanup action is run, closing all known-about Handles.
+-- 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)
+
 -- used when Hugs invokes top level function
-primRunIO :: IO () -> ()
-primRunIO m
-   = protect (fst (unST m realWorld))
+primRunIO_hugs_toplevel :: IO () -> ()
+primRunIO_hugs_toplevel m
+   = protect 5 (fst (unST composite_action realWorld))
      where
+        composite_action
+           = do writeIORef prelCleanupAfterRunAction Nothing
+                m
+                cleanup_handles <- readIORef prelCleanupAfterRunAction
+                case cleanup_handles of
+                   Nothing -> return ()
+                   Just xx -> xx
+
         realWorld = error "primRunIO: entered the RealWorld"
-        protect :: () -> ()
-        protect comp 
-           = primCatch comp (\e -> fst (unST (putStr (show e ++ "\n")) realWorld))
+        protect :: Int -> () -> ()
+        protect 0 comp
+           = 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
@@ -1883,10 +1913,25 @@ freeStablePtr    = primFreeStablePtr
 data PrimArray              a -- immutable arrays with Int indices
 data PrimByteArray
 
-data Ref                  s a -- mutable variables
+data STRef                s a -- mutable variables
 data PrimMutableArray     s a -- mutable arrays with Int indices
 data PrimMutableByteArray s
 
+newSTRef   :: a -> ST s (STRef s a)
+newSTRef    = primNewRef
+readSTRef  :: STRef s a -> ST s a
+readSTRef   = primReadRef
+writeSTRef :: STRef s a -> a -> ST s ()
+writeSTRef  = primWriteRef
+
+type IORef a = STRef RealWorld a
+newIORef   :: a -> IO (IORef a)
+newIORef    = primNewRef
+readIORef  :: IORef a -> IO a
+readIORef   = primReadRef
+writeIORef :: IORef a -> a -> IO ()
+writeIORef  = primWriteRef
+
 
 ------------------------------------------------------------------------------
 -- ThreadId, MVar, concurrency stuff -----------------------------------------