X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2Fmain%2FMain.lhs;h=e9827b4b50603dff3b81cc0d4a67db78044ce0e0;hb=1b7a99e3e7f64c6f402e8aece32ba0b9a3703bfa;hp=803a798b352ba4db56f37ba5f3444e025113178c;hpb=fda89b29c748c6cd2fe1fdb477d5c0e8f7d32b90;p=ghc-hetmet.git diff --git a/ghc/compiler/main/Main.lhs b/ghc/compiler/main/Main.lhs index 803a798..e9827b4 100644 --- a/ghc/compiler/main/Main.lhs +++ b/ghc/compiler/main/Main.lhs @@ -1,286 +1,227 @@ % -% (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(hGetContents,stdin,stderr,hPutStr,hClose,openFile,IOMode(..))) +#include "HsVersions.h" +import IO ( hPutStr, stderr ) import HsSyn -import RdrHsSyn ( RdrName ) import BasicTypes ( NewOrData(..) ) -import ReadPrefix ( rdModule ) +import RdrHsSyn ( RdrNameHsModule ) +import FastString ( mkFastCharString, unpackFS ) +import StringBuffer ( hGetStringBuffer ) +import Parser ( parse ) +import Lex ( PState(..), P, ParseResult(..) ) +import SrcLoc ( mkSrcLoc ) + import Rename ( renameModule ) -import RnMonad ( ExportEnv ) -import MkIface -- several functions -import TcModule ( typecheckModule ) -import Desugar ( deSugar, pprDsWarnings -#if __GLASGOW_HASKELL__ <= 200 - , DsMatchContext, DsWarnFlavour -#endif - ) +import MkIface ( writeIface ) +import TcModule ( TcResults(..), typecheckModule ) +import Desugar ( deSugar ) import SimplCore ( core2core ) +import OccurAnal ( occurAnalyseBinds ) +import CoreLint ( endPass ) +import CoreUtils ( coreBindsSize ) +import CoreTidy ( tidyCorePgm ) import CoreToStg ( topCoreBindsToStg ) -import StgSyn ( collectFinalStgBinders ) +import StgSyn ( collectFinalStgBinders, pprStgBindings ) import SimplStg ( stg2stg ) import CodeGen ( codeGen ) -#if ! OMIT_NATIVE_CODEGEN -import AsmCodeGen ( dumpRealAsm, writeRealAsm ) -#endif +import CodeOutput ( codeOutput ) -import AbsCSyn ( absCNop, AbstractC ) -import AbsCUtils ( flattenAbsC ) -import CoreUnfold ( Unfolding ) -import Bag ( emptyBag, isEmptyBag ) +import Module ( ModuleName, moduleNameUserString ) +import AbsCSyn ( absCNop ) import CmdLineOpts -import ErrUtils ( pprBagOfErrors, ghcExit ) +import ErrUtils ( ghcExit, doIfSet, dumpIfSet ) import Maybes ( maybeToBool, MaybeErr(..) ) -import Specialise ( SpecialiseData(..) ) -import StgSyn ( pprPlainStgBinding, GenStgBinding ) -import TcInstUtil ( InstInfo ) import TyCon ( isDataTyCon ) +import Class ( classTyCon ) import UniqSupply ( mkSplitUniqSupply ) -import PprAbsC ( dumpRealC, writeRealC ) -import PprCore ( pprCoreBinding ) -import Outputable ( PprStyle(..), Outputable(..) ) -import Pretty +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} -import Id ( GenId ) -- instances -import Name ( Name ) -- instances -import PprType ( GenType, GenTyVar ) -- instances -import TyVar ( GenTyVar ) -- instances -import Unique ( Unique ) -- instances +\begin{code} +main = stderr `seq` -- Bug fix. Sigh + -- _scc_ "main" + doIt classifyOpts \end{code} \begin{code} -main = - _scc_ "main" - hGetContents stdin >>= \ input_pgm -> - let - cmd_line_info = classifyOpts - in - doIt cmd_line_info input_pgm +parseModule :: IO (ModuleName, RdrNameHsModule) +parseModule = do + buf <- hGetStringBuffer True{-expand tabs-} (unpackFS src_filename) + case parse buf PState{ bol = 0#, atbol = 1#, + context = [], glasgow_exts = glaexts, + loc = mkSrcLoc src_filename 1 } of + + PFailed err -> do + printErrs err + ghcExit 1 + return (error "parseModule") -- just to get the types right + + POk _ m@(HsModule mod _ _ _ _ _ _) -> + return (mod, m) + where + glaexts | opt_GlasgowExts = 1# + | otherwise = 0# \end{code} \begin{code} -doIt :: ([CoreToDo], [StgToDo]) -> String -> IO () +doIt :: ([CoreToDo], [StgToDo]) -> IO () -doIt (core_cmds, stg_cmds) input_pgm - = doDump opt_Verbose "Glasgow Haskell Compiler, version 2.04, for Haskell 1.4" "" >> +doIt (core_cmds, stg_cmds) + = doIfSet opt_Verbose + (hPutStr stderr "Glasgow Haskell Compiler, version " >> + hPutStr stderr compiler_version >> + hPutStr stderr ", for Haskell 98, compiled by GHC version " >> + hPutStr stderr booter_version >> + hPutStr stderr "\n") >> - -- ******* READER - show_pass "Reader" >> - _scc_ "Reader" - rdModule >>= \ (mod_name, rdr_module) -> + -------------------------- Reader ---------------- + show_pass "Parser" >> + _scc_ "Parser" + parseModule >>= \ (mod_name, rdr_module) -> - doDump opt_D_dump_rdr "Reader:" - (pp_show (ppr pprStyle rdr_module)) >> + dumpIfSet opt_D_dump_parsed "Parser" (ppr rdr_module) >> - doDump opt_D_source_stats "\nSource Statistics:" - (pp_show (ppSourceStats rdr_module)) >> + dumpIfSet opt_D_source_stats "Source Statistics" + (ppSourceStats False rdr_module) >> -- UniqueSupplies for later use (these are the only lower case uniques) --- _scc_ "spl-rn" mkSplitUniqSupply 'r' >>= \ rn_uniqs -> -- renamer --- _scc_ "spl-tc" mkSplitUniqSupply 'a' >>= \ tc_uniqs -> -- typechecker --- _scc_ "spl-ds" mkSplitUniqSupply 'd' >>= \ ds_uniqs -> -- desugarer --- _scc_ "spl-sm" - mkSplitUniqSupply 's' >>= \ sm_uniqs -> -- core-to-core simplifier --- _scc_ "spl-c2s" + mkSplitUniqSupply 'r' >>= \ ru_uniqs -> -- rules mkSplitUniqSupply 'c' >>= \ c2s_uniqs -> -- core-to-stg --- _scc_ "spl-st" + mkSplitUniqSupply 'u' >>= \ tidy_uniqs -> -- tidy up mkSplitUniqSupply 'g' >>= \ st_uniqs -> -- stg-to-stg passes --- _scc_ "spl-absc" - mkSplitUniqSupply 'f' >>= \ fl_uniqs -> -- absC flattener --- _scc_ "spl-ncg" mkSplitUniqSupply 'n' >>= \ ncg_uniqs -> -- native-code generator - -- ******* RENAMER + -------------------------- Rename ---------------- show_pass "Renamer" >> _scc_ "Renamer" - renameModule rn_uniqs rdr_module >>= - \ (maybe_rn_stuff, rn_errs_bag, rn_warns_bag) -> - - checkErrors rn_errs_bag rn_warns_bag >> + renameModule rn_uniqs rdr_module >>= \ maybe_rn_stuff -> case maybe_rn_stuff of { Nothing -> -- Hurrah! Renamer reckons that there's no need to -- go any further - hPutStr stderr "No recompilation required!\n" >> - ghcExit 0 ; - - -- Oh well, we've got to recompile for real - Just (rn_mod, iface_file_stuff, rn_name_supply, imported_modules) -> - - - - doDump opt_D_dump_rn "Renamer:" - (pp_show (ppr pprStyle rn_mod)) >> + reportCompile mod_name "Compilation NOT required!" >> + return (); + + Just (this_mod, rn_mod, + old_iface, new_iface, + rn_name_supply, fixity_env, + imported_modules) -> + -- Oh well, we've got to recompile for real + + + -------------------------- Typechecking ---------------- + show_pass "TypeCheck" >> + _scc_ "TypeCheck" + typecheckModule tc_uniqs rn_name_supply + fixity_env rn_mod >>= \ maybe_tc_stuff -> + case maybe_tc_stuff of { + Nothing -> ghcExit 1; -- Type checker failed - -- Safely past renaming: we can start the interface file: - -- (the iface file is produced incrementally, as we have - -- the information that we need...; we use "iface") - -- "endIface" finishes the job. - startIface mod_name >>= \ if_handle -> - ifaceMain if_handle iface_file_stuff >> + Just (tc_results@(TcResults {tc_tycons = local_tycons, + tc_classes = local_classes, + tc_insts = inst_info })) -> - -- ******* TYPECHECKER - show_pass "TypeCheck" >> - _scc_ "TypeCheck" - case (case (typecheckModule tc_uniqs {-idinfo_fm-} rn_name_supply rn_mod) of - Succeeded (stuff, warns) - -> (emptyBag, warns, stuff) - Failed (errs, warns) - -> (errs, warns, error "tc_results")) - - of { (tc_errs_bag, tc_warns_bag, tc_results) -> + -------------------------- Desugaring ---------------- + _scc_ "DeSugar" + deSugar this_mod ds_uniqs tc_results >>= \ (desugared, rules, h_code, c_code, fe_binders) -> - checkErrors tc_errs_bag tc_warns_bag >> - case tc_results - of { (all_binds, - local_tycons, local_classes, inst_info, pragma_tycon_specs, - ddump_deriv) -> + -------------------------- Main Core-language transformations ---------------- + _scc_ "Core2Core" + core2core core_cmds desugared rules >>= \ (simplified, orphan_rules) -> - doDump opt_D_dump_tc "Typechecked:" - (pp_show (ppr pprStyle all_binds)) >> + -- Do the final tidy-up + tidyCorePgm tidy_uniqs this_mod + simplified orphan_rules >>= \ (tidy_binds, tidy_orphan_rules) -> - doDump opt_D_dump_deriv "Derived instances:" - (pp_show (ddump_deriv pprStyle)) >> + -- Run the occurrence analyser one last time, so that + -- dead binders get dead-binder info. This is exploited by + -- code generators to avoid spitting out redundant bindings. + -- The occurrence-zapping in Simplify.simplCaseBinder means + -- that the Simplifier nukes useful dead-var stuff especially + -- in case patterns. + let occ_anal_tidy_binds = occurAnalyseBinds tidy_binds in - -- ******* DESUGARER - show_pass "DeSugar" >> - _scc_ "DeSugar" - let - (desugared,ds_warnings) - = deSugar ds_uniqs mod_name all_binds - in - (if isEmptyBag ds_warnings then - return () - else - hPutStr stderr (pp_show (pprDsWarnings pprErrorsStyle ds_warnings)) - >> hPutStr stderr "\n" - ) >> - - doDump opt_D_dump_ds "Desugared:" (pp_show (vcat - (map (pprCoreBinding pprStyle) desugared))) - >> - - -- ******* CORE-TO-CORE SIMPLIFICATION (NB: I/O op) - show_pass "Core2Core" >> - _scc_ "Core2Core" - let - local_data_tycons = filter isDataTyCon local_tycons - in - core2core core_cmds mod_name pprStyle - sm_uniqs local_data_tycons pragma_tycon_specs desugared - >>= + coreBindsSize occ_anal_tidy_binds `seq` +-- TEMP: the above call zaps some space usage allocated by the +-- simplifier, which for reasons I don't understand, persists +-- thoroughout code generation - \ (simplified, - SpecData _ _ _ gen_data_tycons all_tycon_specs _ _ _) -> - doDump opt_D_dump_simpl "Simplified:" (pp_show (vcat - (map (pprCoreBinding pprStyle) simplified))) - >> - -- ******* STG-TO-STG SIMPLIFICATION + -------------------------- Convert to STG code ------------------------------- show_pass "Core2Stg" >> _scc_ "Core2Stg" let - stg_binds = topCoreBindsToStg c2s_uniqs simplified + stg_binds = topCoreBindsToStg c2s_uniqs occ_anal_tidy_binds in + -------------------------- Simplify STG code ------------------------------- show_pass "Stg2Stg" >> _scc_ "Stg2Stg" - stg2stg stg_cmds mod_name pprStyle st_uniqs stg_binds - >>= - - \ (stg_binds2, cost_centre_info) -> + stg2stg stg_cmds this_mod st_uniqs stg_binds >>= \ (stg_binds2, cost_centre_info) -> - doDump opt_D_dump_stg "STG syntax:" - (pp_show (vcat (map (pprPlainStgBinding pprStyle) stg_binds2))) - >> + -------------------------- Interface file ------------------------------- -- Dump instance decls and type signatures into the interface file + _scc_ "Interface" 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".) - + writeIface this_mod old_iface new_iface + local_tycons local_classes inst_info + final_ids occ_anal_tidy_binds tidy_orphan_rules >> + - -- ******* "ABSTRACT", THEN "FLAT", THEN *REAL* C! + -------------------------- Code generation ------------------------------- show_pass "CodeGen" >> _scc_ "CodeGen" - let - 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_tycon_specs -- tycon specialisations - stg_binds2 - - flat_abstractC = flattenAbsC fl_uniqs abstractC - in - doDump opt_D_dump_absC "Abstract C:" - (dumpRealC abstractC) >> + codeGen this_mod imported_modules + cost_centre_info + fe_binders + local_tycons local_classes + stg_binds2 >>= \ abstractC -> - doDump opt_D_dump_flatC "Flat Abstract C:" - (dumpRealC flat_abstractC) >> + -------------------------- Code output ------------------------------- + show_pass "CodeOutput" >> _scc_ "CodeOutput" - -- You can have C (c_output) or assembly-language (ncg_output), - -- but not both. [Allowing for both gives a space leak on - -- flat_abstractC. WDP 94/10] - let - (flat_absC_c, flat_absC_ncg) = - case (maybeToBool opt_ProduceC || opt_D_dump_realC, - maybeToBool opt_ProduceS || opt_D_dump_asm) of - (True, False) -> (flat_abstractC, absCNop) - (False, True) -> (absCNop, flat_abstractC) - (False, False) -> (absCNop, absCNop) - (True, True) -> error "ERROR: Can't do both .hc and .s at the same time" - - c_output_d = dumpRealC flat_absC_c - c_output_w = (\ f -> writeRealC f flat_absC_c) - -#if OMIT_NATIVE_CODEGEN - ncg_output_d = error "*** GHC not built with a native-code generator ***" - ncg_output_w = ncg_output_d -#else - ncg_output_d = dumpRealAsm flat_absC_ncg ncg_uniqs - ncg_output_w = (\ f -> writeRealAsm f flat_absC_ncg ncg_uniqs) -#endif - in + codeOutput this_mod local_tycons local_classes + occ_anal_tidy_binds stg_binds2 + c_code h_code abstractC + ncg_uniqs >> - doDump opt_D_dump_asm "" ncg_output_d >> - doOutput opt_ProduceS ncg_output_w >> - doDump opt_D_dump_realC "" c_output_d >> - doOutput opt_ProduceC c_output_w >> + -------------------------- Final report ------------------------------- + reportCompile mod_name (showSDoc (ppSourceStats True rdr_module)) >> ghcExit 0 - } } } + } } where ------------------------------------------------------------- - -- ****** printing styles and column width: - - - ------------------------------------------------------------- -- ****** help functions: show_pass @@ -288,50 +229,9 @@ doIt (core_cmds, stg_cmds) input_pgm then \ what -> hPutStr stderr ("*** "++what++":\n") else \ what -> return () - doOutput switch io_action - = case switch of - Nothing -> return () - Just fname -> - openFile fname WriteMode >>= \ handle -> - io_action handle >> - hClose handle - - doDump switch hdr string - = if switch - then hPutStr stderr ("\n\n" ++ (take 80 $ repeat '=')) >> - hPutStr stderr ('\n': hdr) >> - hPutStr stderr ('\n': string) >> - hPutStr stderr "\n" - else return () - - -pprCols = (80 :: Int) -- could make configurable - -(pprStyle, pprErrorsStyle) - | opt_PprStyle_All = (PprShowAll, PprShowAll) - | opt_PprStyle_Debug = (PprDebug, PprDebug) - | opt_PprStyle_User = (PprQuote, PprQuote) - | otherwise = (PprDebug, PprQuote) - -pp_show p = show p -- ToDo: use pprCols - -checkErrors errs_bag warns_bag - | not (isEmptyBag errs_bag) - = hPutStr stderr (pp_show (pprBagOfErrors pprErrorsStyle errs_bag)) - >> hPutStr stderr "\n" >> - hPutStr stderr (pp_show (pprBagOfErrors pprErrorsStyle warns_bag)) - >> hPutStr stderr "\n" >> - ghcExit 1 - - | not (isEmptyBag warns_bag) - = hPutStr stderr (pp_show (pprBagOfErrors pprErrorsStyle warns_bag)) >> - hPutStr stderr "\n" - - | otherwise = return () - - -ppSourceStats (HsModule name version exports imports fixities decls src_loc) - = vcat (map pp_val +ppSourceStats short (HsModule name version exports imports 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), @@ -365,17 +265,19 @@ 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] - - fixity_ds = length fixities - type_decls = [d | TyD d@(TySynonym _ _ _ _) <- decls] - data_decls = [d | TyD d@(TyData DataType _ _ _ _ _ _ _) <- decls] - newt_decls = [d | TyD d@(TyData NewType _ _ _ _ _ _ _) <- decls] - type_ds = length type_decls - data_ds = length data_decls - newt_ds = length newt_decls - class_decls = [d | ClD d <- decls] - class_ds = length class_decls + 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 [() | FixD d <- decls] + -- NB: this omits fixity decls on local bindings and + -- in class decls. ToDo + + tycl_decls = [d | TyClD d <- decls] + (class_ds, data_ds, newt_ds, type_ds) = countTyClDecls tycl_decls + inst_decls = [d | InstD d <- decls] inst_ds = length inst_decls default_ds = length [() | DefD _ <- decls] @@ -393,9 +295,9 @@ ppSourceStats (HsModule name version exports imports fixities decls src_loc) (import_no, import_qual, import_as, import_all, import_partial, import_hiding) = foldr add6 (0,0,0,0,0,0) (map import_info imports) (data_constrs, data_derivs) - = foldr add2 (0,0) (map data_info (newt_decls ++ data_decls)) + = foldr add2 (0,0) (map data_info tycl_decls) (class_method_ds, default_method_ds) - = foldr add2 (0,0) (map class_info class_decls) + = foldr add2 (0,0) (map class_info tycl_decls) (inst_method_ds, method_specs, method_inlines) = foldr add3 (0,0,0) (map inst_info inst_decls) @@ -405,21 +307,22 @@ ppSourceStats (HsModule name version exports imports fixities decls src_loc) count_binds (MonoBind b sigs _) = case (count_monobinds b, count_sigs sigs) of ((vs,fs),(ts,_,ss,is)) -> (vs,fs,ts,ss,is) - count_monobinds EmptyMonoBinds = (0,0) - count_monobinds (AndMonoBinds b1 b2) = count_monobinds b1 `add2` count_monobinds b2 + count_monobinds EmptyMonoBinds = (0,0) + count_monobinds (AndMonoBinds b1 b2) = count_monobinds b1 `add2` count_monobinds b2 count_monobinds (PatMonoBind (VarPatIn n) r _) = (1,0) - count_monobinds (PatMonoBind p r _) = (0,1) - count_monobinds (FunMonoBind f _ m _) = (0,1) + count_monobinds (PatMonoBind p r _) = (0,1) + count_monobinds (FunMonoBind f _ m _) = (0,1) count_sigs sigs = foldr add4 (0,0,0,0) (map sig_info sigs) - sig_info (Sig _ _ _) = (1,0,0,0) - sig_info (ClassOpSig _ _ _ _) = (0,1,0,0) - sig_info (SpecSig _ _ _ _) = (0,0,1,0) - sig_info (InlineSig _ _) = (0,0,0,1) - sig_info _ = (0,0,0,0) + sig_info (Sig _ _ _) = (1,0,0,0) + sig_info (ClassOpSig _ _ _ _ _) = (0,1,0,0) + sig_info (SpecSig _ _ _) = (0,0,1,0) + sig_info (InlineSig _ _ _) = (0,0,0,1) + sig_info (NoInlineSig _ _ _) = (0,0,0,1) + sig_info _ = (0,0,0,0) - import_info (ImportDecl _ qual _ as spec _) + import_info (ImportDecl _ _ qual as spec _) = add6 (1, qual_info qual, as_info as, 0,0,0) (spec_info spec) qual_info False = 0 qual_info True = 1 @@ -429,19 +332,29 @@ ppSourceStats (HsModule name version exports imports fixities decls src_loc) spec_info (Just (False, _)) = (0,0,0,0,1,0) spec_info (Just (True, _)) = (0,0,0,0,0,1) - data_info (TyData _ _ _ _ constrs derivs _ _) - = (length constrs, case derivs of {Nothing -> 0; Just ds -> length ds}) + data_info (TyData _ _ _ _ _ nconstrs derivs _ _) + = (nconstrs, case derivs of {Nothing -> 0; Just ds -> length ds}) + data_info other = (0,0) - 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)) + class_info other = (0,0) inst_info (InstDecl _ inst_meths inst_sigs _ _) = case count_sigs inst_sigs of (_,_,ss,is) -> (addpr (count_monobinds inst_meths), ss, is) + addpr :: (Int,Int) -> Int + add1 :: Int -> Int -> Int + add2 :: (Int,Int) -> (Int,Int) -> (Int, Int) + add3 :: (Int,Int,Int) -> (Int,Int,Int) -> (Int, Int, Int) + add4 :: (Int,Int,Int,Int) -> (Int,Int,Int,Int) -> (Int, Int, Int, Int) + add5 :: (Int,Int,Int,Int,Int) -> (Int,Int,Int,Int,Int) -> (Int, Int, Int, Int, Int) + add6 :: (Int,Int,Int,Int,Int,Int) -> (Int,Int,Int,Int,Int,Int) -> (Int, Int, Int, Int, Int, Int) + addpr (x,y) = x+y add1 x1 y1 = x1+y1 add2 (x1,x2) (y1,y2) = (x1+y1,x2+y2) @@ -450,3 +363,60 @@ 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 + +booter_version + = case "\ + \ __GLASGOW_HASKELL__" of + ' ':n:ns -> n:'.':ns + ' ':m -> m +\end{code} + +\begin{code} +reportCompile :: ModuleName -> 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 (moduleNameUserString 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 + [] -> IOERROR (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}