[project @ 1996-01-08 20:28:12 by partain]
[ghc-hetmet.git] / ghc / compiler / main / MainMonad.lhs
diff --git a/ghc/compiler/main/MainMonad.lhs b/ghc/compiler/main/MainMonad.lhs
new file mode 100644 (file)
index 0000000..4d0960b
--- /dev/null
@@ -0,0 +1,258 @@
+%
+% (c) The GRASP/AQUA Project, Glasgow University, 1993-1995
+%
+\section[MainMonad]{I/O monad used in @Main@ module of the compiler}
+
+\begin{code}
+#include "HsVersions.h"
+
+module MainMonad (
+       MainIO(..),
+#ifndef __GLASGOW_HASKELL__
+       mainIOtoDialogue,
+       appendFileMn,
+#endif
+       returnMn,
+       thenMn,
+       thenMn_,
+--     foldlMn, INLINEd at its two (important) uses...
+       readMn,
+       writeMn,
+       getArgsMn,
+       getSplitUniqSupplyMn,
+       exitMn,
+#if __GLASGOW_HASKELL__ >= 23
+       fopen, fclose, fwrite, _FILE(..),
+#endif
+
+       SplitUniqSupply
+       IF_ATTACK_PRAGMAS(COMMA getArgsPrimIO)
+       IF_ATTACK_PRAGMAS(COMMA appendFilePrimIO)
+       IF_ATTACK_PRAGMAS(COMMA appendChanPrimIO)
+       IF_ATTACK_PRAGMAS(COMMA readChanPrimIO)
+       IF_ATTACK_PRAGMAS(COMMA mkSplitUniqSupply) -- profiling only, really
+    ) where
+
+#ifdef __GLASGOW_HASKELL__
+
+# if __GLASGOW_HASKELL__ < 26
+import PreludePrimIO
+# endif
+import PreludeGlaST
+
+#endif
+
+import SplitUniq
+import Outputable
+import Util
+
+infixr 9 `thenMn`      -- right-associative, please
+infixr 9 `thenMn_`
+\end{code}
+
+For Glasgow Haskell, we'll eventually be able to use the underlying
+Glasgow I/O {\em directly}.  However, for now we do the business
+through regular a @Dialogue@.
+
+A value of type @MainIO a@ represents an I/O-performing computation
+returning a value of type @a@.  It is a function from the whole list
+of responses-to-the-rest-of-the-program, to a triple consisting of:
+\begin{enumerate}
+\item
+the value of type @a@;
+\item
+a function which prefixes the requests for the computation to
+the front of a supplied list of requests; using a function here
+avoids an expensive append operation in @thenMn@;
+\item
+the depleted list of responses.
+\end{enumerate}
+
+\begin{code}
+returnMn    :: a -> MainIO a
+thenMn     :: MainIO a -> (a -> MainIO b) -> MainIO b
+thenMn_            :: MainIO a -> MainIO b -> MainIO b
+--foldlMn          :: (a -> b -> MainIO a) -> a -> [b] -> MainIO a
+
+readMn     :: String{-channel-} -> MainIO String
+writeMn            :: String{-channel-} -> String -> MainIO ()
+#ifndef __GLASGOW_HASKELL__
+appendFileMn:: String{-filename-} -> String -> MainIO ()
+#endif
+getArgsMn   :: MainIO [String]
+getSplitUniqSupplyMn :: Char -> MainIO SplitUniqSupply
+exitMn     :: Int -> MainIO ()
+
+#ifdef __GLASGOW_HASKELL__
+{-# INLINE returnMn #-}
+{-# INLINE thenMn   #-}
+{-# INLINE thenMn_  #-}
+#endif
+
+{- INLINEd at its uses
+foldlMn f z []     = returnMn z
+foldlMn f z (x:xs) = f z x     `thenMn` \ zz ->
+                    foldlMn f zz xs
+-}
+
+exitMn val
+  = -- trace ("exitMn:"++(show val)) (
+    if val /= 0
+    then error "Compilation had errors\n"
+    else returnMn ()
+    -- )
+
+#ifdef __GLASGOW_HASKELL__
+
+type MainIO a = PrimIO a
+
+returnMn    = returnPrimIO
+thenMn     = thenPrimIO
+thenMn_            = seqPrimIO
+
+readMn chan                = readChanPrimIO chan
+writeMn chan str           = appendChanPrimIO chan str
+getArgsMn                  = getArgsPrimIO
+
+getSplitUniqSupplyMn char = mkSplitUniqSupply char
+\end{code}
+
+\begin{code}
+#else {- ! __GLASGOW_HASKELL -}
+
+type MainIO a = (a -> Dialogue) -> Dialogue
+
+-- returnMn :: x -> MainIO x
+returnMn x cont = cont x
+
+-- thenMn :: MainIO a -> (a -> MainIO b) -> MainIO b
+thenMn m k cont = m (\ a -> k a cont)
+
+-- thenMn_ :: MainIO a -> MainIO b -> MainIO b
+thenMn_ m k cont = m (\ _ -> k cont)
+\end{code}
+
+\begin{code}
+mainIOtoDialogue :: MainIO () -> Dialogue
+
+mainIOtoDialogue io = io (\ _ _ -> [])
+
+readMn chan            = readChanIO chan
+writeMn chan str       = appendChanIO chan str
+appendFileMn fname str = appendFileIO fname str
+getArgsMn              = getArgsIO
+
+getSplitUniqSupplyMn char = returnMn (mkSplitUniqSupply char)
+\end{code}
+
+\begin{code}
+processRequestIO   :: Request -> MainIO Response
+processRequestIO req cont ~(resp:resps) = req : cont resp resps
+
+doneIO :: MainIO a
+doneIO cont = \ _ -> []
+
+data IoResult a = IoSucc a
+                | IoFail IOError
+
+type IOE a = MainIO (IoResult a)         
+
+processRequestIOUnit :: Request -> IOE ()
+processRequestIOUnit req =
+        processRequestIO req                           `thenMn` \ resp -> 
+        case resp of
+          Success       -> returnMn (IoSucc ())
+          Str str       -> error "funny Response, expected a Success"
+          StrList strl  -> error "funny Response, expected a Success" 
+          Failure ioerr -> returnMn (IoFail ioerr)
+
+processRequestIOString :: Request -> IOE String
+processRequestIOString req =
+        processRequestIO req                           `thenMn` \ resp -> 
+        case resp of
+          Success       -> error "funny Response, expected a String"
+          Str str       -> returnMn (IoSucc str)
+          StrList strl  -> error "funny Response, expected a String" 
+          Failure ioerr -> returnMn (IoFail ioerr)
+
+processRequestIOStringList :: Request -> IOE [String]
+processRequestIOStringList req =
+        processRequestIO req                           `thenMn` \ resp -> 
+        case resp of
+          Success       -> error "funny Response, expected a [String]"
+          Str str       -> error "funny Response, expected a [String]" 
+          StrList strl  -> returnMn (IoSucc strl)
+          Failure ioerr -> returnMn (IoFail ioerr)
+
+readFileIOE     :: String ->           IOE String
+writeFileIOE    :: String -> String -> IOE ()
+appendFileIOE   :: String -> String -> IOE ()
+deleteFileIOE   :: String ->           IOE ()
+statusFileIOE   :: String ->           IOE String
+readChanIOE     :: String ->           IOE String
+appendChanIOE   :: String -> String -> IOE ()
+statusChanIOE   :: String ->           IOE String
+echoIOE         :: Bool   ->           IOE ()
+getArgsIOE      ::                     IOE [String]
+getEnvIOE       :: String ->           IOE String
+setEnvIOE       :: String -> String -> IOE ()
+sigActionIOE    :: Int    -> SigAct -> IOE ()
+
+readFileIOE    file     = processRequestIOString     ( ReadFile file )
+writeFileIOE   file str = processRequestIOUnit       ( WriteFile file str )
+appendFileIOE  file str = processRequestIOUnit       ( AppendFile file str )
+deleteFileIOE  file     = processRequestIOUnit       ( DeleteFile file )
+statusFileIOE  file     = processRequestIOString     ( StatusFile file )
+readChanIOE    chan     = processRequestIOString     ( ReadChan chan )
+appendChanIOE  chan str = processRequestIOUnit       ( AppendChan chan str )
+statusChanIOE  chan     = processRequestIOString     ( StatusChan chan )
+echoIOE        bool     = processRequestIOUnit       ( Echo bool )
+getArgsIOE              = processRequestIOStringList ( GetArgs )
+getEnvIOE      var      = processRequestIOString     ( GetEnv var )
+setEnvIOE      var obj  = processRequestIOUnit       ( SetEnv var obj )
+sigActionIOE   sig act  = processRequestIOUnit       ( SigAction sig act )
+
+handleErrIO :: IoResult a -> MainIO a 
+handleErrIO (IoSucc a)     = returnMn a
+handleErrIO (IoFail ioerr) = exitIO   ioerr
+
+readFileIO      :: String ->           MainIO String
+writeFileIO     :: String -> String -> MainIO ()
+appendFileIO    :: String -> String -> MainIO ()
+deleteFileIO    :: String ->           MainIO ()
+statusFileIO    :: String ->           MainIO String
+readChanIO      :: String ->           MainIO String
+appendChanIO    :: String -> String -> MainIO ()
+statusChanIO    :: String ->           MainIO String
+echoIO          :: Bool   ->           MainIO ()
+getArgsIO       ::                     MainIO [String]
+getEnvIO        :: String ->           MainIO String
+setEnvIO        :: String -> String -> MainIO ()
+sigActionIO     :: Int    -> SigAct -> MainIO ()
+
+readFileIO      file       = readFileIOE file           `thenMn` handleErrIO
+writeFileIO     file str   = writeFileIOE file str      `thenMn` handleErrIO
+appendFileIO    file str   = appendFileIOE file str     `thenMn` handleErrIO
+deleteFileIO    file       = deleteFileIOE file         `thenMn` handleErrIO
+statusFileIO    file       = statusFileIOE file         `thenMn` handleErrIO
+readChanIO      chan       = readChanIOE chan           `thenMn` handleErrIO
+appendChanIO    chan str   = appendChanIOE chan str     `thenMn` handleErrIO
+statusChanIO    chan       = statusChanIOE chan         `thenMn` handleErrIO
+echoIO          bool       = echoIOE bool               `thenMn` handleErrIO
+getArgsIO                  = getArgsIOE                 `thenMn` handleErrIO
+getEnvIO        var        = getEnvIOE var              `thenMn` handleErrIO
+setEnvIO        var obj    = setEnvIOE var obj          `thenMn` handleErrIO
+sigActionIO     sig act    = sigActionIOE sig act       `thenMn` handleErrIO
+
+exitIO     :: IOError -> MainIO a
+
+exitIO (ReadError s)   = error s
+exitIO (WriteError s)  = error s
+exitIO (SearchError s) = error s
+exitIO (FormatError s) = error s
+exitIO (OtherError s)  = error s
+\end{code}
+
+\begin{code}
+#endif {- ! __GLASGOW_HASKELL -}
+\end{code}