[project @ 1998-12-02 13:17:09 by simonm]
[ghc-hetmet.git] / ghc / compiler / main / Main.lhs
index 239ccb8..8a7feb9 100644 (file)
@@ -1,74 +1,58 @@
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1993-1996
+% (c) The GRASP/AQUA Project, Glasgow University, 1993-1998
 %
 \section[GHC_Main]{Main driver for Glasgow Haskell compiler}
 
 \begin{code}
-#include "HsVersions.h"
-
 module Main ( main ) where
 
-IMP_Ubiq(){-uitous-}
-IMPORT_1_3(IO(stderr,hPutStr,hClose,openFile,IOMode(..)))
+#include "HsVersions.h"
 
+import IO      ( IOMode(..), hPutStr, hClose, openFile, stderr )
 import HsSyn
-import RdrHsSyn                ( RdrName )
 import BasicTypes      ( NewOrData(..) )
 
 import ReadPrefix      ( rdModule )
 import Rename          ( renameModule )
-import RnMonad         ( ExportEnv )
 
 import MkIface         -- several functions
 import TcModule                ( typecheckModule )
-import Desugar         ( deSugar, pprDsWarnings
-#if __GLASGOW_HASKELL__ <= 200
-                         , DsMatchContext 
-#endif
-                       )
+import Desugar         ( deSugar )
 import SimplCore       ( core2core )
 import CoreToStg       ( topCoreBindsToStg )
-import StgSyn          ( collectFinalStgBinders, pprStgBindings )
+import StgSyn          ( collectFinalStgBinders, pprStgBindingsWithSRTs )
 import SimplStg                ( stg2stg )
 import CodeGen         ( codeGen )
 #if ! OMIT_NATIVE_CODEGEN
 import AsmCodeGen      ( dumpRealAsm, writeRealAsm )
 #endif
 
-import AbsCSyn         ( absCNop, AbstractC )
+import AbsCSyn         ( absCNop )
 import AbsCUtils       ( flattenAbsC )
-import CoreUnfold      ( Unfolding )
-import Bag             ( emptyBag, isEmptyBag )
 import CmdLineOpts
-import ErrUtils                ( pprBagOfErrors, ghcExit, doIfSet, dumpIfSet )
+import ErrUtils                ( ghcExit, doIfSet, dumpIfSet )
 import Maybes          ( maybeToBool, MaybeErr(..) )
-import Specialise      ( SpecialiseData(..) )
-import StgSyn          ( GenStgBinding )
-import TcInstUtil      ( InstInfo )
 import TyCon           ( isDataTyCon )
+import Class           ( classTyCon )
 import UniqSupply      ( mkSplitUniqSupply )
 
 import PprAbsC         ( dumpRealC, writeRealC )
-import PprCore         ( pprCoreBinding )
-import Pretty
-
-import Id              ( GenId )               -- instances
-import Name            ( Name )                -- instances
-import PprType         ( GenType, GenTyVar )   -- instances
-import TyVar           ( GenTyVar )            -- instances
-import Unique          ( Unique )              -- instances
-
-import Outputable      ( PprStyle(..), Outputable(..), pprDumpStyle, pprErrorsStyle )
+import FiniteMap       ( emptyFM )
+import Outputable
+import Char            ( isSpace )
+#if REPORT_TO_MOTHERLODE && __GLASGOW_HASKELL__ >= 303
+import SocketPrim
+import BSD
+import IOExts          ( unsafePerformIO )
+import NativeInfo       ( os, arch )
+#endif
 
 \end{code}
 
 \begin{code}
 main =
- _scc_ "main" 
- let
-    cmd_line_info = classifyOpts
- in
- doIt cmd_line_info
+ --  _scc_ "main" 
+ doIt classifyOpts
 \end{code}
 
 \begin{code}
@@ -76,20 +60,19 @@ doIt :: ([CoreToDo], [StgToDo]) -> IO ()
 
 doIt (core_cmds, stg_cmds)
   = doIfSet opt_Verbose 
-       (hPutStr stderr ("Glasgow Haskell Compiler, version " ++ 
-                        show PROJECTVERSION ++ 
-                        ", for Haskell 1.4\n"))                >>
+       (hPutStr stderr "Glasgow Haskell Compiler, version "    >>
+        hPutStr stderr compiler_version                        >>
+        hPutStr stderr ", for Haskell 1.4\n")                  >>
 
     -- ******* READER
     show_pass "Reader" >>
     _scc_     "Reader"
     rdModule           >>= \ (mod_name, rdr_module) ->
 
-    dumpIfSet opt_D_dump_rdr "Reader"
-       (ppr pprDumpStyle rdr_module)           >>
+    dumpIfSet opt_D_dump_rdr "Reader" (ppr rdr_module)         >>
 
     dumpIfSet opt_D_source_stats "Source Statistics"
-       (ppSourceStats rdr_module)              >>
+       (ppSourceStats False rdr_module)                >>
 
     -- UniqueSupplies for later use (these are the only lower case uniques)
 --    _scc_     "spl-rn"
@@ -118,6 +101,7 @@ doIt (core_cmds, stg_cmds)
     case maybe_rn_stuff of {
        Nothing ->      -- Hurrah!  Renamer reckons that there's no need to
                        -- go any further
+                       reportCompile (_UNPK_ mod_name) "Compilation NOT required!" >>
                        return ();
        
        Just (rn_mod, iface_file_stuff, rn_name_supply, imported_modules) ->
@@ -140,14 +124,17 @@ doIt (core_cmds, stg_cmds)
        Nothing -> ghcExit 1;   -- Type checker failed
 
        Just (all_binds,
-             local_tycons, local_classes, inst_info, pragma_tycon_specs,
-             ddump_deriv) ->
+             local_tycons, local_classes, inst_info, 
+             fo_decls,
+             ddump_deriv,
+             global_env,
+             global_ids) ->
 
 
     -- ******* DESUGARER
-    show_pass "DeSugar"                        >>
+    show_pass "DeSugar"                                            >>
     _scc_     "DeSugar"
-    deSugar ds_uniqs mod_name all_binds                >>= \ desugared ->
+    deSugar ds_uniqs global_env mod_name all_binds fo_decls >>= \ (desugared, h_code, c_code) ->
 
 
     -- ******* CORE-TO-CORE SIMPLIFICATION
@@ -157,10 +144,9 @@ doIt (core_cmds, stg_cmds)
        local_data_tycons = filter isDataTyCon local_tycons
     in
     core2core core_cmds mod_name
-             sm_uniqs local_data_tycons pragma_tycon_specs desugared
+             sm_uniqs desugared
                                                >>=
-        \ (simplified,
-           SpecData _ _ _ gen_data_tycons all_tycon_specs _ _ _) ->
+        \ simplified ->
 
 
     -- ******* STG-TO-STG SIMPLIFICATION
@@ -176,40 +162,39 @@ doIt (core_cmds, stg_cmds)
                                                >>=
        \ (stg_binds2, cost_centre_info) ->
 
-    dumpIfSet opt_D_dump_stg "STG syntax:"
-       (pprStgBindings pprDumpStyle stg_binds2)
-                                               >>
+    dumpIfSet opt_D_dump_stg "STG syntax:" 
+       (pprStgBindingsWithSRTs stg_binds2)     >>
 
        -- Dump instance decls and type signatures into the interface file
     let
-       final_ids = collectFinalStgBinders stg_binds2
+       final_ids = collectFinalStgBinders (map fst stg_binds2)
     in
     _scc_     "Interface"
     ifaceDecls if_handle local_tycons local_classes inst_info final_ids simplified     >>
     endIface if_handle                                         >>
     -- We are definitely done w/ interface-file stuff at this point:
     -- (See comments near call to "startIface".)
-    
 
     -- ******* "ABSTRACT", THEN "FLAT", THEN *REAL* C!
     show_pass "CodeGen"                        >>
     _scc_     "CodeGen"
     let
+       all_local_data_tycons = filter isDataTyCon (map classTyCon local_classes)
+                               ++ local_data_tycons
+                                       -- Generate info tables  for the data constrs arising
+                                       -- from class decls as well
+
+       all_tycon_specs       = emptyFM -- Not specialising tycons any more
+
        abstractC      = codeGen mod_name               -- module name for CC labelling
                                 cost_centre_info
                                 imported_modules       -- import names for CC registering
-                                gen_data_tycons        -- type constructors generated locally
+                                all_local_data_tycons  -- type constructors generated locally
                                 all_tycon_specs        -- tycon specialisations
                                 stg_binds2
 
        flat_abstractC = flattenAbsC fl_uniqs abstractC
     in
-    dumpIfSet opt_D_dump_absC "Abstract C"
-       (dumpRealC abstractC)                   >>
-
-    dumpIfSet opt_D_dump_flatC "Flat Abstract C"
-       (dumpRealC flat_abstractC)              >>
-
     show_pass "CodeOutput"                     >>
     _scc_     "CodeOutput"
     -- You can have C (c_output) or assembly-language (ncg_output),
@@ -224,6 +209,14 @@ doIt (core_cmds, stg_cmds)
             (False, False) -> (absCNop, absCNop)
             (True,  True)  -> error "ERROR: Can't do both .hc and .s at the same time"
 
+        -- C stubs for "foreign export"ed functions.
+       stub_c_output_d = pprCode CStyle c_code
+        stub_c_output_w = showSDoc stub_c_output_d
+
+        -- Header file protos for "foreign export"ed functions.
+       stub_h_output_d = pprCode CStyle h_code
+        stub_h_output_w = showSDoc stub_h_output_d
+
        c_output_d = dumpRealC flat_absC_c
        c_output_w = (\ f -> writeRealC f flat_absC_c)
 
@@ -239,9 +232,17 @@ doIt (core_cmds, stg_cmds)
     dumpIfSet opt_D_dump_asm "Asm code" ncg_output_d   >>
     doOutput opt_ProduceS ncg_output_w                         >>
 
+    dumpIfSet opt_D_dump_foreign "Foreign export header file" stub_h_output_d >>
+    outputHStub opt_ProduceExportHStubs stub_h_output_w        >>
+
+    dumpIfSet opt_D_dump_foreign "Foreign export stubs" stub_c_output_d >>
+    outputCStub mod_name opt_ProduceExportCStubs stub_c_output_w       >>
+
     dumpIfSet opt_D_dump_realC "Real C" c_output_d     >>
     doOutput opt_ProduceC c_output_w                   >>
 
+    reportCompile (_UNPK_ mod_name) (showSDoc (ppSourceStats True rdr_module)) >>
+
     ghcExit 0
     } }
   where
@@ -255,15 +256,32 @@ doIt (core_cmds, stg_cmds)
 
     doOutput switch io_action
       = case switch of
-         Nothing -> return ()
+         Nothing    -> return ()
          Just fname ->
            openFile fname WriteMode    >>= \ handle ->
            io_action handle            >>
            hClose handle
 
+    -- don't use doOutput for dumping the f. export stubs
+    -- since it is more than likely that the stubs file will
+    -- turn out to be empty, in which case no file should be created.
+    outputCStub mod_name switch "" = return ()
+    outputCStub mod_name switch doc_str
+      = case switch of
+         Nothing    -> return ()
+         Just fname -> writeFile fname ("#include \"Rts.h\"\n#include \"RtsAPI.h\"\n"++rest)
+           where
+            rest = "#include "++show ((_UNPK_ mod_name) ++ "_stub.h") ++ '\n':doc_str
+             
+    outputHStub switch "" = return ()
+    outputHStub switch doc_str
+      = case switch of
+         Nothing    -> return ()
+         Just fname -> writeFile fname ("#include \"Rts.h\"\n"++doc_str)
 
-ppSourceStats (HsModule name version exports imports fixities decls src_loc)
- = vcat (map pp_val
+ppSourceStats short (HsModule name version exports imports fixities decls src_loc)
+ = (if short then hcat else vcat)
+        (map pp_val
               [("ExportAll        ", export_all), -- 1 if no export list
                ("ExportDecls      ", export_ds),
                ("ExportModules    ", export_ms),
@@ -297,7 +315,11 @@ ppSourceStats (HsModule name version exports imports fixities decls src_loc)
               ])
   where
     pp_val (str, 0) = empty
-    pp_val (str, n) = hcat [text str, int n]
+    pp_val (str, n) 
+      | not short   = hcat [text str, int n]
+      | otherwise   = hcat [text (trim str), equals, int n, semi]
+    
+    trim ls     = takeWhile (not.isSpace) (dropWhile isSpace ls)
 
     fixity_ds   = length fixities
     type_decls         = [d | TyD d@(TySynonym _ _ _ _)    <- decls]
@@ -364,7 +386,7 @@ ppSourceStats (HsModule name version exports imports fixities decls src_loc)
     data_info (TyData _ _ _ _ constrs derivs _ _)
        = (length constrs, case derivs of {Nothing -> 0; Just ds -> length ds})
 
-    class_info (ClassDecl _ _ _ meth_sigs def_meths _ _)
+    class_info (ClassDecl _ _ _ meth_sigs def_meths _ _ _ _)
        = case count_sigs meth_sigs of
            (_,classops,_,_) ->
               (classops, addpr (count_monobinds def_meths))
@@ -382,3 +404,54 @@ ppSourceStats (HsModule name version exports imports fixities decls src_loc)
     add5 (x1,x2,x3,x4,x5) (y1,y2,y3,y4,y5) = (x1+y1,x2+y2,x3+y3,x4+y4,x5+y5)
     add6 (x1,x2,x3,x4,x5,x6) (y1,y2,y3,y4,y5,y6) = (x1+y1,x2+y2,x3+y3,x4+y4,x5+y5,x6+y6)
 \end{code}
+
+\begin{code}
+compiler_version :: String
+compiler_version =
+     case (show opt_HiVersion) of
+       [x]      -> ['0','.',x]
+       ls@[x,y] -> "0." ++ ls
+       ls       -> go ls
+ where
+  -- 10232353 => 10232.53
+  go ls@[x,y] = '.':ls
+  go (x:xs)   = x:go xs
+
+\end{code}
+
+\begin{code}
+reportCompile :: String -> String -> IO ()
+#if REPORT_TO_MOTHERLODE && __GLASGOW_HASKELL__ >= 303
+reportCompile mod_name info
+  | not opt_ReportCompile = return ()
+  | otherwise = (do 
+      sock <- udpSocket 0
+      addr <- motherShip
+      sendTo sock (mod_name++ ';': compiler_version ++ ';': os ++ ';':arch ++ '\n':' ':info ++ "\n") addr
+      return ()) `catch` (\ _ -> return ())
+
+motherShip :: IO SockAddr
+motherShip = do
+  he <- getHostByName "laysan.dcs.gla.ac.uk"
+  case (hostAddresses he) of
+    []    -> fail (userError "No address!")
+    (x:_) -> return (SockAddrInet motherShipPort x)
+
+--magick
+motherShipPort :: PortNumber
+motherShipPort = mkPortNumber 12345
+
+-- creates a socket capable of sending datagrams,
+-- binding it to a port
+--  ( 0 => have the system pick next available port no.)
+udpSocket :: Int -> IO Socket
+udpSocket p = do
+  pr <- getProtocolNumber "udp"
+  s  <- socket AF_INET Datagram pr
+  bindSocket s (SockAddrInet (mkPortNumber p) iNADDR_ANY)
+  return s
+#else
+reportCompile _ _ = return ()
+#endif
+
+\end{code}