[project @ 1997-03-17 20:34:25 by simonpj]
authorsimonpj <unknown>
Mon, 17 Mar 1997 20:35:30 +0000 (20:35 +0000)
committersimonpj <unknown>
Mon, 17 Mar 1997 20:35:30 +0000 (20:35 +0000)
More small changes towards 2.02

35 files changed:
Makefile
docs/Makefile
docs/installing.lit
ghc/Makefile
ghc/compiler/Makefile
ghc/compiler/absCSyn/AbsCSyn.lhs
ghc/compiler/absCSyn/PprAbsC.lhs
ghc/compiler/basicTypes/Unique.lhs
ghc/compiler/deSugar/DsMonad.lhs
ghc/compiler/prelude/PrelInfo.lhs
ghc/compiler/prelude/PrimOp.lhs
ghc/compiler/reader/Lex.lhs
ghc/compiler/rename/RnIfaces.lhs
ghc/compiler/rename/RnMonad.lhs
ghc/compiler/specialise/Specialise.lhs
ghc/compiler/typecheck/TcGenDeriv.lhs
ghc/compiler/utils/FastString.lhs
ghc/docs/Makefile
ghc/driver/ghc-asm.lprl
ghc/includes/StgMacros.lh
ghc/lib/Makefile
ghc/lib/cbits/stgio.h
ghc/lib/ghc/GHC.hi-boot
ghc/lib/ghc/IOBase.lhs
ghc/lib/ghc/IOHandle.lhs
ghc/lib/glaExts/Foreign.lhs
ghc/lib/required/Directory.lhs
ghc/lib/required/IO.lhs
ghc/lib/required/Time.lhs
ghc/mk/boilerplate.mk
ghc/mk/paths.mk
ghc/runtime/Makefile
ghc/runtime/prims/PrimMisc.lc
mk/config.mk.in
mk/target.mk

index eca7ef4..204d5ec 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -65,28 +65,3 @@ dist :: dist-pre
 include $(TOP)/mk/target.mk
 dist :: dist-post
 
-#
-# Automatically remake update configuration files
-# (from autoconf manual)
-#
-configure: configure.in
-       autoconf
-#     
-# autoheader might not change config.h.in, so touch a stamp file.
-#
-mk/config.h.in: mk/stamp-h.in
-mk/stamp-h.in: configure.in
-       autoheader
-       echo timestamp > mk/stamp-h.in
-
-mk/config.h: mk/stamp-h
-mk/stamp-h: mk/config.h.in config.status
-       ./config.status
-     
-config.status: configure
-       ./config.status --recheck
-
-.PHONY: config
-
-config: config.status
-       @:
index 851469d..b2164c4 100644 (file)
@@ -1,7 +1,7 @@
 TOP = ..
 include $(TOP)/mk/boilerplate.mk
 
-DOC_SRCS = installing.lit release.lit
+DOC_SRCS = installing.lit
 
 SRC_TEXI2HTML_OPTS += -number -monolithic -invisible xbm
 
index 81bdeee..d2d9bb3 100644 (file)
@@ -784,6 +784,19 @@ and you're on the road again.
 You need to be a bit careful, though, that any new files you create
 (if you do any development work) are in the source tree, not a build tree!
 
+Remember, that the source files in the build tree are {\em symbolic
+links} to the files in the source tree.  (The build tree soon
+accumulates lots of built files like @Foo.o@, as well.)  You can {\em
+delete} a source file from the build tree without affecting the source
+tree (though it's an odd thing to do).  On the other hand, if you {\em
+edit} a source file from the build tree, you'll edit the source-tree
+file directly.  (You can set up Emacs so that if you edit a source
+file from the build tree, Emacs will silently create an edited copy of
+the source file in the build tree, leaving the source file unchanged;
+but the danger is that you think you've edited the source file whereas
+actually all you've done is edit the build-tree copy.  More commonly
+you do want to edit the source file.)
+
 Like the source tree, the top level of your build tree must (a linked copy of)
 the root directory of the @fptools@ suite.
 Inside Makefiles, the root of your build tree is called @$(FPTOOLS_TOP)@.
@@ -813,27 +826,32 @@ Or, you might want to compile it with debugging on (so that
 extra consistency-checking code gets included) or off.  And so on.
 
 All of this stuff is called the {\em configuration} of your build.
-You set the configuration using an exciting two-step process.
+You set the configuration using an exciting three-step process.
 \begin{description}
-\item[Step 1: system configuration.]  This is easy, provided you
-have the programs mentioned in Section~\ref{sect_std-utils}.  Just
-@cd@ to @$(FPTOOLS)@ and say @gmake configure@.  This 
-command does three things:
-\begin{itemize}
-\item
-It runs a GNU program called @autoconf@, which
+\item[Step 1: get ready for configuration.]
+Change directory to @$(FPTOOLS)@ and issue the following two commands (with no arguments):
+\begin{enumerate}
+\item @autoconf@. This GNU program
 converts @$(FPTOOLS)/configure.in@ to a shell script 
 called @$(FPTOOLS)/configure@.
 
-This step is completely platform-independent; it just means
+\item @autoheader@.  This second GNU program converts
+@$(FPTOOLS)/configure.in@ to @$(FPTOOLS)/mk/config.h.in@.
+\end{enumerate}
+Both these steps are completely platform-independent; they just mean
 that the human-written file (@configure.in@) can be short, although
-the resulting shell script, @configure@ is long. 
+the resulting shell script, @configure@, and @mk/config.h.in@, are long.
 
-\item It runs a second GNU program called @autoheader@, which converts
-@$(FPTOOLS)/configure.in@ to @$(FPTOOLS)/mk/config.h.in@.
-Again, this step is platform-independent.
+In case you don't have @autoconf@ and @autoheader@ we distribute
+the results, @configure@, and @mk/config.h.in@, with the source distribution.
+They aren't kept in the repository, though.
 
-\item It then runs the newly-created @configure@ script.  @configure@'s mission
+\item[Step 2: system configuration.]
+Runs the newly-created @configure@ script, thus:
+\begin{verbatim}
+  ./configure
+\end{verbatim}
+@configure@'s mission
 is to scurry round your computer working out what architecture it has,
 what operating system, whether it has the @vfork@ system call,
 where @yacc@ is kept, whether @gcc@ is available, where various
@@ -853,10 +871,9 @@ all Makefiles.
 The latter is @#include@d by various C programs, which
 can thereby make use of configuration information.
 \end{itemize}
-\end{itemize}
 
 
-\item[Step 2: build configuration.] Next, you say how this build
+\item[Step 3: build configuration.] Next, you say how this build
 of @fptools@ is to differ from the standard defaults by creating a new 
 file @mk/build.mk@
 {\em in the build tree}.  This file is the one and only
@@ -883,18 +900,18 @@ want to change.  (The override occurs because the main boilerplate file,
 
 For example, @config.mk.in@ contains the definition:
 \begin{verbatim}
-  SUBDIRS = glafp-utils literate ghc
+  ProjectsToBuild = glafp-utils literate ghc hslibs
 \end{verbatim}
 The accompanying comment explains that this is the list of enabled
 projects; that is, if (after configuring) you type @gmake all@
 in @FPTOOLS_TOP@ three specified projects will be made.
 If you want to add @happy@, you can add this line to @build.mk@:
 \begin{verbatim}
-  SUBDIRS += happy
+  ProjectsToBuild += happy
 \end{verbatim}
 or, if you prefer,
 \begin{verbatim}
-  SUBDIRS = glafp-utils literate ghc happy
+  ProjectsToBuild = glafp-utils literate ghc hslibs happy
 \end{verbatim}
 (GNU @make@ allows existing definitions to have new text appended using
 the ``@+=@'' operator, which is quite a convenient feature.)
@@ -941,10 +958,19 @@ to happen there now.
 \begin{verbatim}
     cd /scratch/joe-bloggs/myfptools-sun4
 \end{verbatim}
+\item Prepare for system configuration:
+\begin{verbatim}
+    autoconf
+    autoheader
+\end{verbatim}
+(You can skip this step if you are starting from a source distribution,
+and you already have @configure@ and @mk/config.h.in@.)
+
 \item Do system configuration:
 \begin{verbatim}
-    gmake configure
+    ./configure
 \end{verbatim}
+
 \item Create the file @mk/build.mk@, 
 adding definitions for your desired configuration options.
 \begin{verbatim}
index 3876e1b..42b121c 100644 (file)
@@ -1,5 +1,5 @@
 #-----------------------------------------------------------------------------
-# $Id: Makefile,v 1.3 1997/03/14 07:53:55 simonpj Exp $
+# $Id: Makefile,v 1.4 1997/03/17 20:34:29 simonpj Exp $
 #
 
 TOP=.
@@ -49,7 +49,7 @@ boot ::
        $(line)
        @echo "Booting Prelude libraries"
        $(line)
-       @$(MAKE) -C compiler boot
+       @$(MAKE) -C lib boot
 
 
 # "CONTRIB" is also a SUBDIR, but there is nothing to build there.
index b0b54d0..972a8ca 100644 (file)
@@ -1,5 +1,5 @@
 # -----------------------------------------------------------------------------
-# $Id: Makefile,v 1.8 1997/03/14 07:55:43 simonpj Exp $
+# $Id: Makefile,v 1.9 1997/03/17 20:34:30 simonpj Exp $
 
 TOP = ..
 include $(TOP)/mk/boilerplate.mk
@@ -226,6 +226,7 @@ all :: hsp
 hsp: parser/printtree.o parser/main.o libhsp.a 
        $(CC) -o $@ $(CC_OPTS) $^
 
+CLEAN_FILES += hsp
 #-----------------------------------------------------------------------------
 #              Interface files
 
index be099d0..28cab79 100644 (file)
@@ -433,7 +433,7 @@ data MagicId
 
   -- Argument and return registers
   | VanillaReg         -- pointers, unboxed ints and chars
-       PrimRep -- PtrRep, IntRep, CharRep, StablePtrRep or ForeignObjRep
+       PrimRep         -- PtrRep, IntRep, CharRep, StablePtrRep or ForeignObjRep
                        --      (in case we need to distinguish)
        FAST_INT        -- its number (1 .. mAX_Vanilla_REG)
 
index b2e60c4..7fba22e 100644 (file)
@@ -747,20 +747,22 @@ ppr_casm_results sty [r] liveness
 
        (result_type, assign_result)
          = case r_kind of
-{- @ForeignObj@s replaces MallocPtrs and are *not* CReturnable.
-   Instead, external references have to be turned into ForeignObjs
+{- 
+   @ForeignObj@s replaces MallocPtrs and are *not* CReturnable.
+   Instead, external references have to explicitly turned into ForeignObjs
    using the primop makeForeignObj#. Benefit: Multiple finalisation
    routines can be accommodated and the below special case is not needed.
    Price is, of course, that you have to explicitly wrap `foreign objects'
    with makeForeignObj#.
-+ 
+
              ForeignObjRep ->
                (uppPStr SLIT("StgForeignObj"),
                 uppBesides [ uppPStr SLIT("constructForeignObj"),uppChar '(',
                                liveness, uppComma,
                                result_reg, uppComma,
                                local_var,
-                            pp_paren_semi ]) -}
+                            pp_paren_semi ]) 
+-}
              _ ->
                (pprPrimKind sty r_kind,
                 uppBesides [ result_reg, uppEquals, local_var, uppSemi ])
index 5f14e9f..3dbdbcd 100644 (file)
@@ -195,6 +195,7 @@ module Unique (
        stateTyConKey,
        synchVarPrimTyConKey,
        thenMClassOpKey,
+       toEnumClassOpKey,
        traceIdKey,
        trueDataConKey,
        unpackCString2IdKey,
@@ -680,4 +681,5 @@ mainPrimIoKey               = mkPreludeMiscIdUnique 67
 returnMClassOpKey      = mkPreludeMiscIdUnique 68
 -- Used for minusClassOp                       69
 otherwiseIdKey         = mkPreludeMiscIdUnique 70
+toEnumClassOpKey       = mkPreludeMiscIdUnique 71
 \end{code}
index 38e567a..c2034d7 100644 (file)
@@ -282,7 +282,7 @@ pprDsWarnings sty warns
       = ppCat [ppPStr SLIT("in the definition of function"), ppQuote (ppr sty fun)]
 
     pp_match CaseMatch pats
-      = ppHang (ppPStr SLIT("in a group of case alternative beginning:"))
+      = ppHang (ppPStr SLIT("in a group of case alternatives beginning:"))
        4 (ppSep [ppSep (map (ppr sty) pats), pp_arrow_dotdotdot])
 
     pp_match PatBindMatch pats
index 98364f2..426eb62 100644 (file)
@@ -15,7 +15,7 @@ module PrelInfo (
 
        eq_RDR, ne_RDR, le_RDR, lt_RDR, ge_RDR, gt_RDR, max_RDR, min_RDR, compare_RDR, 
        minBound_RDR, maxBound_RDR, enumFrom_RDR, enumFromTo_RDR, enumFromThen_RDR, 
-       enumFromThenTo_RDR, fromEnum_RDR,
+       enumFromThenTo_RDR, fromEnum_RDR, toEnum_RDR,
        range_RDR, index_RDR, inRange_RDR, readsPrec_RDR, readList_RDR, 
        showsPrec_RDR, showList_RDR, plus_RDR, times_RDR, ltTag_RDR, eqTag_RDR, gtTag_RDR, 
        eqH_Char_RDR, ltH_Char_RDR, eqH_Word_RDR, ltH_Word_RDR, eqH_Addr_RDR, ltH_Addr_RDR, 
@@ -299,6 +299,7 @@ knownKeyNames
     , (enumFromTo_RDR,         enumFromToClassOpKey)
     , (enumFromThenTo_RDR,     enumFromThenToClassOpKey)
     , (fromEnum_RDR,           fromEnumClassOpKey)
+    , (toEnum_RDR,             toEnumClassOpKey)
     , (eq_RDR,                 eqClassOpKey)
     , (thenM_RDR,              thenMClassOpKey)
     , (returnM_RDR,            returnMClassOpKey)
@@ -361,6 +362,7 @@ creturnableClass_RDR        = tcQual (fOREIGN,   SLIT("CReturnable"))
 fromInt_RDR       = varQual (pREL_BASE, SLIT("fromInt"))
 fromInteger_RDR           = varQual (pREL_BASE, SLIT("fromInteger"))
 minus_RDR         = varQual (pREL_BASE, SLIT("-"))
+toEnum_RDR        = varQual (pREL_BASE, SLIT("toEnum"))
 fromEnum_RDR      = varQual (pREL_BASE, SLIT("fromEnum"))
 enumFrom_RDR      = varQual (pREL_BASE, SLIT("enumFrom"))
 enumFromTo_RDR    = varQual (pREL_BASE, SLIT("enumFromTo"))
index bd24ebe..7ba7dd3 100644 (file)
@@ -154,7 +154,8 @@ data PrimOp
     | TakeMVarOp | PutMVarOp
     | ReadIVarOp | WriteIVarOp
 
-    | MakeForeignObjOp -- foreign objects (malloc pointers or any old URL)
+    | MakeForeignObjOp  -- foreign objects (malloc pointers or any old URL)
+    | WriteForeignObjOp -- modifying foreign objects [obscuro factor: 200]
     | MakeStablePtrOp | DeRefStablePtrOp
 \end{code}
 
@@ -413,26 +414,27 @@ tagOf_PrimOp PutMVarOp                        = ILIT(152)
 tagOf_PrimOp ReadIVarOp                            = ILIT(153)
 tagOf_PrimOp WriteIVarOp                   = ILIT(154)
 tagOf_PrimOp MakeForeignObjOp              = ILIT(155)
-tagOf_PrimOp MakeStablePtrOp               = ILIT(156)
-tagOf_PrimOp DeRefStablePtrOp              = ILIT(157)
-tagOf_PrimOp (CCallOp _ _ _ _ _)           = ILIT(158)
-tagOf_PrimOp ErrorIOPrimOp                 = ILIT(159)
-tagOf_PrimOp ReallyUnsafePtrEqualityOp     = ILIT(160)
-tagOf_PrimOp SeqOp                         = ILIT(161)
-tagOf_PrimOp ParOp                         = ILIT(162)
-tagOf_PrimOp ForkOp                        = ILIT(163)
-tagOf_PrimOp DelayOp                       = ILIT(164)
-tagOf_PrimOp WaitReadOp                            = ILIT(165)
-tagOf_PrimOp WaitWriteOp                   = ILIT(166)
-
-tagOf_PrimOp ParGlobalOp                   = ILIT(167)
-tagOf_PrimOp ParLocalOp                            = ILIT(168)
-tagOf_PrimOp ParAtOp                       = ILIT(169)
-tagOf_PrimOp ParAtAbsOp                            = ILIT(170)
-tagOf_PrimOp ParAtRelOp                            = ILIT(171)
-tagOf_PrimOp ParAtForNowOp                 = ILIT(172)
-tagOf_PrimOp CopyableOp                            = ILIT(173)
-tagOf_PrimOp NoFollowOp                            = ILIT(174)
+tagOf_PrimOp WriteForeignObjOp             = ILIT(156)
+tagOf_PrimOp MakeStablePtrOp               = ILIT(157)
+tagOf_PrimOp DeRefStablePtrOp              = ILIT(158)
+tagOf_PrimOp (CCallOp _ _ _ _ _)           = ILIT(159)
+tagOf_PrimOp ErrorIOPrimOp                 = ILIT(160)
+tagOf_PrimOp ReallyUnsafePtrEqualityOp     = ILIT(161)
+tagOf_PrimOp SeqOp                         = ILIT(162)
+tagOf_PrimOp ParOp                         = ILIT(163)
+tagOf_PrimOp ForkOp                        = ILIT(164)
+tagOf_PrimOp DelayOp                       = ILIT(165)
+tagOf_PrimOp WaitReadOp                            = ILIT(166)
+tagOf_PrimOp WaitWriteOp                   = ILIT(167)
+
+tagOf_PrimOp ParGlobalOp                   = ILIT(168)
+tagOf_PrimOp ParLocalOp                            = ILIT(169)
+tagOf_PrimOp ParAtOp                       = ILIT(170)
+tagOf_PrimOp ParAtAbsOp                            = ILIT(171)
+tagOf_PrimOp ParAtRelOp                            = ILIT(172)
+tagOf_PrimOp ParAtForNowOp                 = ILIT(173)
+tagOf_PrimOp CopyableOp                            = ILIT(174)
+tagOf_PrimOp NoFollowOp                            = ILIT(175)
 
 tagOf_PrimOp _ = panic# "tagOf_PrimOp: pattern-match"
 
@@ -597,6 +599,7 @@ allThePrimOps
        ReadIVarOp,
        WriteIVarOp,
        MakeForeignObjOp,
+       WriteForeignObjOp,
        MakeStablePtrOp,
        DeRefStablePtrOp,
        ReallyUnsafePtrEqualityOp,
@@ -1147,7 +1150,7 @@ primOpInfo WaitWriteOp
 
 %************************************************************************
 %*                                                                     *
-\subsubsection[PrimOps-makeForeignObj]{PrimOpInfo for Foreign Objects}
+\subsubsection[PrimOps-ForeignObj]{PrimOpInfo for Foreign Objects}
 %*                                                                     *
 %************************************************************************
 
@@ -1164,7 +1167,7 @@ When a @ForeignObj@ becomes garbage, a user-defined finalisation routine
 associated with the object is invoked (currently, each ForeignObj has a
 direct reference to its finaliser).  -- SOF
 
-The only function defined over @ForeignObj@s is:
+A @ForeignObj@ is created by the @makeForeignObj#@ primitive:
 
 \begin{pseudocode}
 makeForeignObj# :: Addr#  -- foreign object
@@ -1172,6 +1175,7 @@ makeForeignObj# :: Addr#  -- foreign object
                -> StateAndForeignObj# _RealWorld# ForeignObj#
 \end{pseudocode}
 
+
 \begin{code}
 primOpInfo MakeForeignObjOp
   = AlgResult SLIT("makeForeignObj#") [] 
@@ -1179,6 +1183,34 @@ primOpInfo MakeForeignObjOp
        stateAndForeignObjPrimTyCon [realWorldTy]
 \end{code}
 
+[Experimental--SOF]
+In addition, another @ForeignObj@ primitive is provided for destructively modifying
+the external object wrapped up inside a @ForeignObj@. This primitive is used
+when a mixed programming interface of implicit and explicit de-allocation is used,
+e.g., if @ForeignObj@s are used to implement @Handle@s, then @Handle@s can be
+released either explicitly (through @hClose@) or implicitly (via a finaliser).
+When releasing/closing the @Handle@ explicitly, care must be taken to avoid having 
+the finaliser for the embedded @ForeignObj@ attempt the same thing later.
+We deal with this situation, by allowing the programmer to destructively modify
+the data field of the @ForeignObj@ to hold a special value the finaliser recognises,
+and does not attempt to free (e.g., filling the data slot with \tr{NULL}).
+
+\begin{pseudocode}
+writeForeignObj# :: ForeignObj#  -- foreign object
+                -> Addr#        -- new data value
+               -> StateAndForeignObj# _RealWorld# ForeignObj#
+\end{pseudocode}
+
+\begin{code}
+primOpInfo WriteForeignObjOp
+ = let {
+       s = alphaTy; s_tv = alphaTyVar
+    } in
+   PrimResult SLIT("writeForeignObj#") [s_tv]
+       [foreignObjPrimTy, addrPrimTy, mkStatePrimTy s]
+       statePrimTyCon VoidRep [s]
+\end{code}
+
 %************************************************************************
 %*                                                                     *
 \subsubsection[PrimOp-stable-pointers]{PrimOpInfo for ``stable pointers''}
@@ -1411,6 +1443,7 @@ primOpHeapReq (CCallOp _ _ mayGC@True  _ _) = VariableHeapRequired
 primOpHeapReq (CCallOp _ _ mayGC@False _ _) = NoHeapRequired
 
 primOpHeapReq MakeForeignObjOp = VariableHeapRequired
+primOpHeapReq WriteForeignObjOp        = NoHeapRequired
 
 -- this occasionally has to expand the Stable Pointer table
 primOpHeapReq MakeStablePtrOp  = VariableHeapRequired
@@ -1557,7 +1590,8 @@ fragilePrimOp :: PrimOp -> Bool
 fragilePrimOp ParOp = True
 fragilePrimOp ForkOp = True
 fragilePrimOp SeqOp = True
-fragilePrimOp MakeForeignObjOp = True  -- SOF
+fragilePrimOp MakeForeignObjOp  = True  -- SOF
+fragilePrimOp WriteForeignObjOp = True  -- SOF
 fragilePrimOp MakeStablePtrOp  = True
 fragilePrimOp DeRefStablePtrOp = True  -- ??? JSM & ADR
 
@@ -1629,6 +1663,7 @@ primOpNeedsWrapper DoubleEncodeOp         = True
 primOpNeedsWrapper DoubleDecodeOp      = True
 
 primOpNeedsWrapper MakeForeignObjOp    = True
+primOpNeedsWrapper WriteForeignObjOp   = True
 primOpNeedsWrapper MakeStablePtrOp     = True
 primOpNeedsWrapper DeRefStablePtrOp    = True
 
index 32f20e9..626762d 100644 (file)
@@ -531,7 +531,7 @@ is_sym c#=
    '&'# -> True; '*'# -> True; '+'# -> True; '.'# -> True; 
    '/'# -> True; '<'# -> True; '='# -> True; '>'# -> True; 
    '?'# -> True; '\\'# -> True; '^'# -> True; '|'# -> True; 
-   '-'# -> True; '~'# -> True; _ -> False }
+   '-'# -> True; '~'# -> True; '@'# -> True; _ -> False }
 
 --isAlphanum c || c `elem` ":_'!#$%&*+./<=>?@\\^|-~" -- ToDo: add ISOgraphic
 
index 3024b8e..453fda3 100644 (file)
@@ -32,7 +32,9 @@ import HsPragmas      ( noGenPragmas )
 import RdrHsSyn                ( SYN_IE(RdrNameHsDecl), SYN_IE(RdrNameInstDecl), 
                          RdrName, rdrNameOcc
                        )
-import RnEnv           ( newGlobalName, lookupRn, addImplicitOccsRn, availName, availNames, addAvailToNameSet )
+import RnEnv           ( newGlobalName, lookupRn, addImplicitOccsRn, 
+                         availName, availNames, addAvailToNameSet, pprAvail
+                       )
 import RnSource                ( rnHsType )
 import RnMonad
 import ParseIface      ( parseIface )
@@ -275,6 +277,7 @@ importDecl :: Name -> Necessity -> RnMG (Maybe RdrNameHsDecl)
 importDecl name necessity
   = checkSlurped name                  `thenRn` \ already_slurped ->
     if already_slurped then
+       -- traceRn (ppSep [ppStr "Already slurped:", ppr PprDebug name])        `thenRn_`
        returnRn Nothing        -- Already dealt with
     else
     if isWiredInName name then
@@ -336,37 +339,45 @@ that we know just what instances to bring into scope.
        
 \begin{code}
 getWiredInDecl name
-  =    -- Force in the home module in case it has instance decls for
-       -- the thing we are interested in
-    (if not is_tycon || mod == gHC__ then
-       returnRn ()                     -- Mini hack 1: no point for non-tycons; and if we
-                                       -- do this we find PrelNum trying to import PackedString,
-                                       -- because PrelBase's .hi file mentions PackedString.unpackString
-                                       -- But PackedString.hi isn't built by that point!
-                                       --
-                                       -- Mini hack 2; GHC is guaranteed not to have
-                                       -- instance decls, so it's a waste of time
-                                       -- to read it
+  = get_wired                          `thenRn` \ avail ->
+    recordSlurp Nothing avail          `thenRn_`
+
+       -- Force in the home module in case it has instance decls for
+       -- the thing we are interested in.
+       --
+       -- Mini hack 1: no point for non-tycons/class; and if we
+       -- do this we find PrelNum trying to import PackedString,
+       -- because PrelBase's .hi file mentions PackedString.unpackString
+       -- But PackedString.hi isn't built by that point!
+       --
+       -- Mini hack 2; GHC is guaranteed not to have
+       -- instance decls, so it's a waste of time to read it
+       --
+       -- NB: We *must* look at the availName of the slurped avail, 
+       -- not the name passed to getWiredInDecl!  Why?  Because if a data constructor 
+       -- or class op is passed to getWiredInDecl we'll pull in the whole data/class
+       -- decl, and recordSlurp will record that fact.  But since the data constructor
+       -- isn't a tycon/class we won't force in the home module.  And even if the
+       -- type constructor/class comes along later, loadDecl will say that it's already
+       -- been slurped, so getWiredInDecl won't even be called.  Pretty obscure bug, this was.
+    let
+       main_name  = availName avail
+       main_is_tc = case avail of { AvailTC _ _ -> True; Avail _ -> False }
+       (mod,_)    = modAndOcc main_name
+       doc_str    = ppSep [ppPStr SLIT("Need home module for wired in thing"), ppr PprDebug name]
+    in
+    (if not main_is_tc || mod == gHC__ then
+       returnRn ()             
     else
        loadInterface doc_str mod       `thenRn_`
        returnRn ()
     )                                  `thenRn_`
 
-    get_wired                          `thenRn` \ avail ->
-    recordSlurp Nothing avail          `thenRn_`
     returnRn Nothing           -- No declaration to process further
   where
-    doc_str = ppSep [ppPStr SLIT("Need home module for wired in thing"), ppr PprDebug name]
-    (mod,_) = modAndOcc name
-    maybe_wired_in_tycon = maybeWiredInTyConName name
-    is_tycon            = maybeToBool maybe_wired_in_tycon
-    maybe_wired_in_id    = maybeWiredInIdName    name
-    Just the_tycon      = maybe_wired_in_tycon
-    Just the_id         = maybe_wired_in_id
 
     get_wired | is_tycon                       -- ... a type constructor
              = get_wired_tycon the_tycon
-             -- Else, must be a wired-in-Id
 
              | (isDataCon the_id)              -- ... a wired-in data constructor
              = get_wired_tycon (dataConTyCon the_id)
@@ -374,6 +385,12 @@ getWiredInDecl name
              | otherwise                       -- ... a wired-in non data-constructor
              = get_wired_id the_id
 
+    maybe_wired_in_tycon = maybeWiredInTyConName name
+    is_tycon            = maybeToBool maybe_wired_in_tycon
+    maybe_wired_in_id    = maybeWiredInIdName    name
+    Just the_tycon      = maybe_wired_in_tycon
+    Just the_id         = maybe_wired_in_id
+
 
 get_wired_id id
   = addImplicitOccsRn (nameSetToList id_mentioned)     `thenRn_`
@@ -406,7 +423,8 @@ checkSlurped name
     returnRn (name `elemNameSet` slurped_names)
 
 recordSlurp maybe_version avail
-  = getIfacesRn        `thenRn` \ ifaces ->
+  = -- traceRn (ppSep [ppStr "Record slurp:", pprAvail PprDebug avail])        `thenRn_`
+    getIfacesRn        `thenRn` \ ifaces ->
     let
        Ifaces this_mod mod_vers export_envs decls slurped_names imp_names insts inst_mods = ifaces
        new_slurped_names = addAvailToNameSet slurped_names avail
index 5d29108..8a3ebf6 100644 (file)
@@ -468,7 +468,6 @@ addOccurrenceName necessity name (RnDown loc names_var errs_var occs_var) l_down
 
   | otherwise
   = readMutVarSST occs_var                     `thenSST` \ occs ->
---     pprTrace "Add occurrence:" (ppr PprDebug name) $
     writeMutVarSST occs_var ((name,necessity) : occs)  `thenSST_`
     returnSST name
   where
index 0692bd8..d49604a 100644 (file)
@@ -1291,27 +1291,13 @@ specExpr :: CoreExpr
                                -- expression.
 
 specExpr (Var v) args
-  = specId v                   $ \ lookupId v                  `thenSM` \ vlookup ->
-    case vlookup of
-       Lifted vl vu
-            -> -- Binding has been lifted, need to extract un-lifted value
-               -- NB: a function binding will never be lifted => args always null
-               --     i.e. no call instance required or call to be constructed
-               ASSERT (null args)
-               returnSM (bindUnlift vl vu (Var vu), singleFvUDs (VarArg vl))
-
-       NoLift vatom@(VarArg new_v)
-            -> mapSM specOutArg args                   `thenSM` \ arg_info ->
-               mkCallInstance v new_v arg_info         `thenSM` \ call_uds ->
-               mkCall new_v arg_info                   `thenSM` \ call ->
-               let
-                   call mkGenApp (Var new_id) [arg | (arg, _, _) <- arg_infos])
-                   uds = unionUDList [call_uds,
-                                      singleFvUDs vatom,
-                                      unionUDList [uds | (_,uds,_) <- arg_info]
-                                     ]
-               in
-               returnSM (call, {- tickSpecCall speced -} uds)
+  = specId v           $ \ v_arg -> 
+    case v_arg of
+       LitArg lit -> ASSERT( null args )
+                    returnSM (Lit lit, emptyUDs)
+
+       VarArg new_v -> mkCallInstance v new_v args     `thenSM` \ uds ->
+                      returnSM (mkGenApp (Var new_v) args, uds)
 
 specExpr expr@(Lit _) null_args
   = ASSERT (null null_args)
@@ -1354,9 +1340,8 @@ specPrimOp :: PrimOp
 
 
 specExpr (App fun arg) args
-  =    -- If TyArg, arg will be processed; otherwise, left alone
-    specArg arg                        `thenSM` \ new_arg    ->
-    specExpr   fun (new_arg : args)    `thenSM` \ (expr,uds) ->
+  = specArg arg                        `thenSM` \ new_arg    ->
+    specExpr fun (new_arg : args)      `thenSM` \ (expr,uds) ->
     returnSM (expr, uds)
 
 specExpr (Lam (ValBinder binder) body) (arg : args) | isValArg arg
@@ -1564,18 +1549,18 @@ partition_args args
 
 ----------
 specId :: Id
-       -> (Id -> SpecM (CoreExpr, UsageDetails))
+       -> (CoreArg -> SpecM (CoreExpr, UsageDetails))
        -> SpecM (CoreExpr, UsageDetails)
 specId v
   = lookupId v         `thenSM` \ vlookup ->
     case vlookup of
 
       Lifted vl vu
-        -> thing_inside vu             `thenSM` \ (expr, uds) -> 
+        -> thing_inside (VarArg vu)    `thenSM` \ (expr, uds) -> 
            returnSM (bindUnlift vl vu expr, singleFvUDs (VarArg vl) `unionUDs` uds)
 
       NoLift vatom
-        -> thing_inside vatom  `thenSM` \ (expr, uds) ->
+        -> thing_inside vatom          `thenSM` \ (expr, uds) ->
            returnSM (expr, singleFvUDs vatom `unionUDs` uds)
 
 specArg :: CoreArg
@@ -1933,7 +1918,7 @@ mkOneInst do_cis@(CallInstance _ spec_tys dict_args _ _) explicit_cis
     newTyVars (length [() | Nothing <- spec_tys])      `thenSM` \ poly_tyvars ->
     let
        -- arg_tys is spec_tys with tyvars instead of the Nothing spec_tys
-       -- which correspond to unspeciailsed args
+       -- which correspond to unspecialised args
        arg_tys  :: [Type]
        (_,arg_tys) = mapAccumL do_the_wotsit poly_tyvars spec_tys
 
@@ -2060,246 +2045,53 @@ mkCallInstance :: Id
               -> [CoreArg]
               -> SpecM UsageDetails
 
-mkCallInstance id new_id []
-  = returnSM emptyUDs
-
 mkCallInstance id new_id args
-
-       -- No specialised versions for "error" and friends are req'd.
-       -- This is a special case in core lint etc.
-
-  | isBottomingId id
+  | null args            ||            -- No args at all
+    isBottomingId id      ||           -- No point in specialising "error" and friends
+                                       -- even at unboxed types
+    idWantsToBeINLINEd id ||           -- It's going to be inlined anyway
+    not enough_args       ||           -- Not enough type and dict args
+    not interesting_overloading                -- Overloaded types are just tyvars
   = returnSM emptyUDs
 
-       -- No call instances for SuperDictSelIds
-       -- These are a special case in mkCall
-
-  | maybeToBool (isSuperDictSelId_maybe id)
-  = returnSM emptyUDs
-
-       -- There are also no call instances for ClassOpIds
-       -- However, we need to process it to get any second-level call
-       -- instances for a ConstMethodId extracted from its SpecEnv
-
   | otherwise
-  = let
-       (tyvars, class_tyvar_pairs) = getIdOverloading id
-       constrained_tyvars          = map snd class_tyvar_pairs         -- May contain dups
-       constraint_vec              = [tyvar `elem` constrained_tyvars | tyvar <- tyvars]
+  = returnSM (singleCI new_id spec_tys dicts)
 
-       arg_res     = take_type_args tyvars class_tyvar_pairs args
-       enough_args = maybeToBool arg_res
-
-
-       (Just (tys, dicts, rest_args)) = arg_res
-
-       record_spec id tys
-         = (record, lookup, spec_tys)
-         where
-           spec_tys = specialiseCallTys constraint_vec tys
-
-           record = any (not . isTyVarTy) (catMaybes spec_tys)
-
-           lookup = lookupSpecEnv (getIdSpecialisation id) tys
-    in
-    if (not enough_args) then
-       pprTrace "Specialise:recordCallInst: Unsaturated Type & Dict Application:\n\t"
-                (ppCat (ppr PprDebug id : map (ppr_arg PprDebug) args)) $
-       returnSM emptyUDs
-
-    else
-    case record_spec id tys of
-       (False, _, _)
-            -> -- pprTrace "CallInst:NotReqd\n"
-               -- (ppCat [ppr PprDebug id, ppCat (map (ppr PprDebug) args)])
-               (returnSM emptyUDs)
-
-       (True, Nothing, spec_tys)
-            -> if isClassOpId id then  -- No CIs for class ops, dfun will give SPEC inst
-                   returnSM emptyUDs
-               else
-                   -- pprTrace "CallInst:Reqd\n"
-                   -- (ppAboves [ppCat [ppr PprDebug id, ppCat (map (ppr PprDebug) args)],
-                   --            ppCat [ppPStr SLIT("CI"), ppCat (map (pprMaybeTy PprDebug) spec_tys),
-                   --                               ppCat (map (ppr PprDebug) dicts)]])
-                   (returnSM (singleCI new_id spec_tys dicts))
-
-       (True, Just (spec_id, tys_left, toss), _)
-            -> if maybeToBool (isConstMethodId_maybe spec_id) then
-                       -- If we got a const method spec_id see if further spec required
-                       -- NB: const method is top-level so spec_id will not be cloned
-                   case record_spec spec_id tys_left of
-                     (False, _, _)
-                       -> -- pprTrace "CallInst:Exists\n"
-                          -- (ppAboves [ppCat [ppr PprDebug id, ppCat (map (ppr PprDebug) args)],
-                          --            ppCat [ppPStr SLIT("->"), ppr PprDebug spec_id,
-                          --                   ppr PprDebug (tys_left ++ drop toss dicts)]])
-                          (returnSM emptyUDs)
-
-                     (True, Nothing, spec_tys)
-                       -> -- pprTrace "CallInst:Exists:Reqd\n"
-                          -- (ppAboves [ppCat [ppr PprDebug id, ppCat (map (ppr PprDebug) args)],
-                          --            ppCat [ppPStr SLIT("->"), ppr PprDebug spec_id,
-                          --                   ppr PprDebug (tys_left ++ drop toss dicts)],
-                          --            ppCat [ppPStr SLIT("CI"), ppCat (map (pprMaybeTy PprDebug) spec_tys),
-                          --                               ppCat (map (ppr PprDebug) (drop toss dicts))]])
-                          (returnSM (singleCI spec_id spec_tys (drop toss dicts)))
-
-                     (True, Just (spec_spec_id, tys_left_left, toss_toss), _)
-                       -> -- pprTrace "CallInst:Exists:Exists\n"
-                          -- (ppAboves [ppCat [ppr PprDebug id, ppCat (map (ppr PprDebug) args)],
-                          --            ppCat [ppPStr SLIT("->"), ppr PprDebug spec_id,
-                          --                   ppr PprDebug (tys_left ++ drop toss dicts)],
-                          --            ppCat [ppPStr SLIT("->"), ppr PprDebug spec_spec_id,
-                          --                   ppr PprDebug (tys_left_left ++ drop (toss + toss_toss) dicts)]])
-                          (returnSM emptyUDs)
-
-               else
-                   -- pprTrace "CallInst:Exists\n"
-                   -- (ppAboves [ppCat [ppr PprDebug id, ppCat (map (ppr PprDebug) args)],
-                   --            ppCat [ppPStr SLIT("->"), ppr PprDebug spec_id,
-                   --                   ppr PprDebug (tys_left ++ drop toss dicts)]])
-                   (returnSM emptyUDs)
-
-
-take_type_args (_:tyvars) class_tyvar_pairs (TyArg ty : args)
-       = case (take_type_args tyvars class_tyvar_pairs args) of
-           Nothing               -> Nothing
+  where
+    (tyvars, class_tyvar_pairs) = getIdOverloading id
+    constrained_tyvars         = map snd class_tyvar_pairs     -- May contain dups
+    constraint_vec             = [tyvar `elem` constrained_tyvars | tyvar <- tyvars]
+    
+    arg_res                       = take_type_args tyvars class_tyvar_pairs args
+    enough_args                           = maybeToBool arg_res
+    (Just (tys, dicts, rest_args)) = arg_res
+    
+    interesting_overloading = any (not . isTyVarTy) (catMaybes spec_tys)
+    spec_tys = specialiseCallTys constraint_vec tys
+
+    ----------------- Rather a gruesome help-function ---------------
+    take_type_args (_:tyvars) (TyArg ty : args)
+       = case (take_type_args tyvars args) of
+           Nothing                   -> Nothing
            Just (tys, dicts, others) -> Just (ty:tys, dicts, others)
 
-take_type_args (_:tyvars) class_tyvar_pairs [] = Nothing
+    take_type_args (_:tyvars) [] = Nothing
 
-take_type_args [] class_tyvar_pairs args
+    take_type_args [] args
        = case (take_dict_args class_tyvar_pairs args) of
            Nothing              -> Nothing
            Just (dicts, others) -> Just ([], dicts, others)
 
-take_dict_args (_:class_tyvar_pairs) (dict : args) | isValArg dict
+    take_dict_args (_:class_tyvar_pairs) (dict : args) | isValArg dict
        = case (take_dict_args class_tyvar_pairs args) of
            Nothing              -> Nothing
            Just (dicts, others) -> Just (dict:dicts, others)
 
-take_dict_args (_:class_tyvar_pairs) [] = Nothing
+    take_dict_args (_:class_tyvar_pairs) args = Nothing
 
-take_dict_args [] args = Just ([], args)
+    take_dict_args [] args = Just ([], args)
 \end{code}
 
-\begin{code}
-mkCall :: Id
-       -> [(CoreArg, UsageDetails, CoreExpr -> CoreExpr)]
-       -> SpecM CoreExpr
-
-mkCall new_id arg_infos = returnSM (
-
-{- 
-  | maybeToBool (isSuperDictSelId_maybe new_id)
-    && any isUnboxedType ty_args
-       -- No specialisations for super-dict selectors
-       -- Specialise unboxed calls to SuperDictSelIds by extracting
-       -- the super class dictionary directly form the super class
-       -- NB: This should be dead code since all uses of this dictionary should
-       --     have been specialised. We only do this to keep core-lint happy.
-    = let
-        Just (_, super_class) = isSuperDictSelId_maybe new_id
-        super_dict_id = case lookupClassInstAtSimpleType super_class (head ty_args) of
-                        Nothing -> panic "Specialise:mkCall:SuperDictId"
-                        Just id -> id
-      in
-      returnSM (False, Var super_dict_id)
-
-  | otherwise
-    = case lookupSpecEnv (getIdSpecialisation new_id) ty_args of
-       Nothing -> checkUnspecOK new_id ty_args (
-                  returnSM (False, unspec_call)
-                  )
-
-       Just spec_1_details@(spec_id_1, tys_left_1, dicts_to_toss_1)
-               -> let
-                       -- It may be necessary to specialsie a constant method spec_id again
-                      (spec_id, tys_left, dicts_to_toss) =
-                           case (maybeToBool (isConstMethodId_maybe spec_id_1),
-                                 lookupSpecEnv (getIdSpecialisation spec_id_1) tys_left_1) of
-                                (False, _ )     -> spec_1_details
-                                (True, Nothing) -> spec_1_details
-                                (True, Just (spec_id_2, tys_left_2, dicts_to_toss_2))
-                                                -> (spec_id_2, tys_left_2, dicts_to_toss_1 + dicts_to_toss_2)
-
-                      args_left = toss_dicts dicts_to_toss val_args
-                  in
-                  checkSpecOK new_id ty_args spec_id tys_left (
-
-                       -- The resulting spec_id may be a top-level unboxed value
-                       -- This can arise for:
-                       -- 1) constant method values
-                       --    eq: class Num a where pi :: a
-                       --        instance Num Double# where pi = 3.141#
-                       -- 2) specilised overloaded values
-                       --    eq: i1 :: Num a => a
-                       --        i1 Int# d.Num.Int# ==> i1.Int#
-                       -- These top level defns should have been lifted.
-                       -- We must add code to unlift such a spec_id.
-
-                  if isUnboxedType (idType spec_id) then
-                      ASSERT (null tys_left && null args_left)
-                      if toplevelishId spec_id then
-                          liftId spec_id       `thenSM` \ (lift_spec_id, unlift_spec_id) ->
-                          returnSM (True, bindUnlift lift_spec_id unlift_spec_id
-                                                     (Var unlift_spec_id))
-                      else
-                          pprPanic "Specialise:mkCall: unboxed spec_id not top-level ...\n"
-                                   (ppCat [ppr PprDebug new_id,
-                                           ppInterleave ppNil (map (pprParendGenType PprDebug) ty_args),
-                                           ppPStr SLIT("==>"),
-                                           ppr PprDebug spec_id])
-                  else
-                  let
-                      (vals_left, _, unlifts_left) = unzip3 args_left
-                      applied_tys  = mkTyApp (Var spec_id) tys_left
-                      applied_vals = mkGenApp applied_tys vals_left
-                  in
-                  returnSM (True, applyBindUnlifts unlifts_left applied_vals)
-                  )
-  where
-    (tys_and_vals, _, unlifts) = unzip3 args
-    unspec_call = applyBindUnlifts unlifts (mkGenApp (Var new_id) tys_and_vals)
-
-
-       -- ty_args is the types at the front of the arg list
-       -- val_args is the rest of the arg-list
-
-    (ty_args, val_args) = get args
-      where
-       get ((TyArg ty,_,_) : args) = (ty : tys, rest) where (tys,rest) = get args
-       get args                    = ([],       args)
-
-
-       -- toss_dicts chucks away dict args, checking that they ain't types!
-    toss_dicts 0 args              = args
-    toss_dicts n ((a,_,_) : args)
-      | isValArg a                 = toss_dicts (n-1) args
-
-\end{code}
-
-\begin{code}
-checkUnspecOK :: Id -> [Type] -> a -> a
-checkUnspecOK check_id tys
-  = if isLocallyDefined check_id && any isUnboxedType tys
-    then pprPanic "Specialise:checkUnspecOK: unboxed instance for local id not found\n"
-                 (ppCat [ppr PprDebug check_id,
-                         ppInterleave ppNil (map (pprParendGenType PprDebug) tys)])
-    else id
-
-checkSpecOK :: Id -> [Type] -> Id -> [Type] -> a -> a
-checkSpecOK check_id tys spec_id tys_left
-  = if any isUnboxedType tys_left
-    then pprPanic "Specialise:checkSpecOK: unboxed type args in specialised application\n"
-                 (ppAboves [ppCat [ppr PprDebug check_id,
-                                   ppInterleave ppNil (map (pprParendGenType PprDebug) tys)],
-                            ppCat [ppr PprDebug spec_id,
-                                   ppInterleave ppNil (map (pprParendGenType PprDebug) tys_left)]])
-    else id
--}
-\end{code}
 
 \begin{code}
 mkTyConInstance :: Id
@@ -2374,8 +2166,7 @@ type SpecM result
   -> UniqSupply
   -> result
 
-initSM m uniqs
-  = m nullTyVarEnv nullIdEnv uniqs
+initSM m uniqs = m nullTyVarEnv nullIdEnv uniqs
 
 returnSM :: a -> SpecM a
 thenSM  :: SpecM a -> (a -> SpecM b) -> SpecM b
@@ -2404,7 +2195,7 @@ newSpecIds :: [Id]                -- The id of which to make a specialised version
 
 newSpecIds new_ids maybe_tys dicts_to_ignore tvenv idenv us
   = [ mkSpecId uniq id maybe_tys (spec_id_ty id) (selectIdInfoForSpecId id)
-      | (id,uniq) <- zipEqual "newSpecIds" new_ids uniqs ]
+    | (id,uniq) <- zipEqual "newSpecIds" new_ids uniqs ]
   where
     uniqs = getUniques (length new_ids) us
     spec_id_ty id = specialiseTy (idType id) maybe_tys dicts_to_ignore
@@ -2592,3 +2383,124 @@ mapAndUnzip4SM f (x:xs) = f x                   `thenSM` \ (r1,r2,r3,r4) ->
                          returnSM ((r1:rs1),(r2:rs2),(r3:rs3),(r4:rs4))
 -}
 \end{code}
+
+
+
+=====================  OLD CODE, scheduled for deletion  =================
+
+\begin{code}
+{- 
+mkCall :: Id
+       -> [(CoreArg, UsageDetails, CoreExpr -> CoreExpr)]
+       -> SpecM CoreExpr
+
+mkCall new_id arg_infos = returnSM (
+
+  | maybeToBool (isSuperDictSelId_maybe new_id)
+    && any isUnboxedType ty_args
+       -- No specialisations for super-dict selectors
+       -- Specialise unboxed calls to SuperDictSelIds by extracting
+       -- the super class dictionary directly form the super class
+       -- NB: This should be dead code since all uses of this dictionary should
+       --     have been specialised. We only do this to keep core-lint happy.
+    = let
+        Just (_, super_class) = isSuperDictSelId_maybe new_id
+        super_dict_id = case lookupClassInstAtSimpleType super_class (head ty_args) of
+                        Nothing -> panic "Specialise:mkCall:SuperDictId"
+                        Just id -> id
+      in
+      returnSM (False, Var super_dict_id)
+
+  | otherwise
+    = case lookupSpecEnv (getIdSpecialisation new_id) ty_args of
+       Nothing -> checkUnspecOK new_id ty_args (
+                  returnSM (False, unspec_call)
+                  )
+
+       Just spec_1_details@(spec_id_1, tys_left_1, dicts_to_toss_1)
+               -> let
+                       -- It may be necessary to specialsie a constant method spec_id again
+                      (spec_id, tys_left, dicts_to_toss) =
+                           case (maybeToBool (isConstMethodId_maybe spec_id_1),
+                                 lookupSpecEnv (getIdSpecialisation spec_id_1) tys_left_1) of
+                                (False, _ )     -> spec_1_details
+                                (True, Nothing) -> spec_1_details
+                                (True, Just (spec_id_2, tys_left_2, dicts_to_toss_2))
+                                                -> (spec_id_2, tys_left_2, dicts_to_toss_1 + dicts_to_toss_2)
+
+                      args_left = toss_dicts dicts_to_toss val_args
+                  in
+                  checkSpecOK new_id ty_args spec_id tys_left (
+
+                       -- The resulting spec_id may be a top-level unboxed value
+                       -- This can arise for:
+                       -- 1) constant method values
+                       --    eq: class Num a where pi :: a
+                       --        instance Num Double# where pi = 3.141#
+                       -- 2) specilised overloaded values
+                       --    eq: i1 :: Num a => a
+                       --        i1 Int# d.Num.Int# ==> i1.Int#
+                       -- These top level defns should have been lifted.
+                       -- We must add code to unlift such a spec_id.
+
+                  if isUnboxedType (idType spec_id) then
+                      ASSERT (null tys_left && null args_left)
+                      if toplevelishId spec_id then
+                          liftId spec_id       `thenSM` \ (lift_spec_id, unlift_spec_id) ->
+                          returnSM (True, bindUnlift lift_spec_id unlift_spec_id
+                                                     (Var unlift_spec_id))
+                      else
+                          pprPanic "Specialise:mkCall: unboxed spec_id not top-level ...\n"
+                                   (ppCat [ppr PprDebug new_id,
+                                           ppInterleave ppNil (map (pprParendGenType PprDebug) ty_args),
+                                           ppPStr SLIT("==>"),
+                                           ppr PprDebug spec_id])
+                  else
+                  let
+                      (vals_left, _, unlifts_left) = unzip3 args_left
+                      applied_tys  = mkTyApp (Var spec_id) tys_left
+                      applied_vals = mkGenApp applied_tys vals_left
+                  in
+                  returnSM (True, applyBindUnlifts unlifts_left applied_vals)
+                  )
+  where
+    (tys_and_vals, _, unlifts) = unzip3 args
+    unspec_call = applyBindUnlifts unlifts (mkGenApp (Var new_id) tys_and_vals)
+
+
+       -- ty_args is the types at the front of the arg list
+       -- val_args is the rest of the arg-list
+
+    (ty_args, val_args) = get args
+      where
+       get ((TyArg ty,_,_) : args) = (ty : tys, rest) where (tys,rest) = get args
+       get args                    = ([],       args)
+
+
+       -- toss_dicts chucks away dict args, checking that they ain't types!
+    toss_dicts 0 args              = args
+    toss_dicts n ((a,_,_) : args)
+      | isValArg a                 = toss_dicts (n-1) args
+
+\end{code}
+
+\begin{code}
+checkUnspecOK :: Id -> [Type] -> a -> a
+checkUnspecOK check_id tys
+  = if isLocallyDefined check_id && any isUnboxedType tys
+    then pprPanic "Specialise:checkUnspecOK: unboxed instance for local id not found\n"
+                 (ppCat [ppr PprDebug check_id,
+                         ppInterleave ppNil (map (pprParendGenType PprDebug) tys)])
+    else id
+
+checkSpecOK :: Id -> [Type] -> Id -> [Type] -> a -> a
+checkSpecOK check_id tys spec_id tys_left
+  = if any isUnboxedType tys_left
+    then pprPanic "Specialise:checkSpecOK: unboxed type args in specialised application\n"
+                 (ppAboves [ppCat [ppr PprDebug check_id,
+                                   ppInterleave ppNil (map (pprParendGenType PprDebug) tys)],
+                            ppCat [ppr PprDebug spec_id,
+                                   ppInterleave ppNil (map (pprParendGenType PprDebug) tys_left)]])
+    else id
+-}
+\end{code}
index e589426..4587e18 100644 (file)
@@ -366,6 +366,8 @@ we use both @con2tag_Foo@ and @tag2con_Foo@ functions, as well as a
 
 \begin{verbatim}
 instance ... Enum (Foo ...) where
+    toEnum i = tag2con_Foo i
+
     enumFrom a = map tag2con_Foo [con2tag_Foo a .. maxtag_Foo]
 
     -- or, really...
@@ -390,11 +392,17 @@ For @enumFromTo@ and @enumFromThenTo@, we use the default methods.
 gen_Enum_binds :: TyCon -> RdrNameMonoBinds
 
 gen_Enum_binds tycon
-  = enum_from          `AndMonoBinds`
+  = to_enum             `AndMonoBinds`
+    enum_from          `AndMonoBinds`
     enum_from_then     `AndMonoBinds`
     from_enum
   where
     tycon_loc = getSrcLoc tycon
+
+    to_enum
+      = mk_easy_FunMonoBind tycon_loc toEnum_RDR [a_Pat] [] $
+        mk_easy_App (tag2con_RDR tycon) [a_RDR]
+
     enum_from
       = mk_easy_FunMonoBind tycon_loc enumFrom_RDR [a_Pat] [] $
          untag_Expr tycon [(a_RDR, ah_RDR)] $
index ab54af7..21f61fd 100644 (file)
@@ -134,10 +134,10 @@ concatFS :: [FastString] -> FastString
 concatFS ls = mkFastString (concat (map (unpackFS) ls)) -- ToDo: do better
 
 headFS :: FastString -> Char
-headFS (FastString _ l# ba#) = 
- if l# ># 0# then C# (indexCharArray# ba# 0#) else error "headFS: empty FS"
-headFS (CharStr a# l#) = 
- if l# ># 0# then C# (indexCharOffAddr# a# 0#) else error "headFS: empty FS"
+headFS f@(FastString _ l# ba#) = 
+ if l# ># 0# then C# (indexCharArray# ba# 0#) else error ("headFS: empty FS: " ++ unpackFS f)
+headFS f@(CharStr a# l#) = 
+ if l# ># 0# then C# (indexCharOffAddr# a# 0#) else error ("headFS: empty FS: " ++ unpackFS f)
 
 tailFS :: FastString -> FastString
 tailFS (FastString _ l# ba#) = mkFastSubStringBA# ba# 1# (l# -# 1#)
index 2f99b93..cf8be1f 100644 (file)
@@ -6,6 +6,6 @@ include $(TOP)/mk/boilerplate.mk
 #
 export WAYS=
 
-SUBDIRS = users_guide install_guide release_notes state_interface
+SUBDIRS = users_guide
 
 include $(TOP)/mk/target.mk
index f243433..89cc4b1 100644 (file)
@@ -348,9 +348,20 @@ sub mangle_asm {
     # multi-line regexp matching:
     local($*) = 1;
     local($i, $c);
+
+
     &init_TARGET_STUFF();
     &init_FUNNY_THINGS();
 
+    # perl4 on alphas SEGVs when give ${foo} substitutions in patterns.
+    # To avoid them we declare some locals that allows to avoid using curlies.
+    local($TUS)      = ${T_US};
+    local($TPOSTLBL) = ${T_POST_LBL};
+    local($TMOVEDIRVS) = ${T_MOVE_DIRVS};
+    local($TPREAPP)    = ${T_PRE_APP};
+    local($TCOPYDIRVS) = ${T_COPY_DIRVS};
+    local($TDOTWORD)   = ${T_DOT_WORD};
+
     open(INASM, "< $in_asmf")
        || &tidy_up_and_die(1,"$Pgm: failed to open `$in_asmf' (to read)\n");
     open(OUTASM,"> $out_asmf")
@@ -374,10 +385,9 @@ sub mangle_asm {
     $i = 0; $chkcat[0] = 'misc'; $chk[0] = '';
 
     while (<INASM>) {
-       next if $T_STABBY && /^\.stab.*${T_US}__stg_split_marker/o;
+       next if $T_STABBY && /^\.stab.*$TUS[@]?__stg_split_marker/o;
        next if $T_STABBY && /^\.stab.*ghc.*c_ID/;
-       next if /${T_PRE_APP}(NO_)?APP/o;
-
+       next if /$TPREAPP(NO_)?APP/o; 
        next if /^;/ && $TargetPlatform =~ /^hppa/;
 
        next if /(^$|^\t\.file\t|^ # )/ && $TargetPlatform =~ /^(mips|powerpc)-/;
@@ -408,12 +418,12 @@ sub mangle_asm {
            $chkcat[$i]  = 'literal';
            $chksymb[$i] = $1;
 
-       } elsif ( /^${T_US}__stg_split_marker(\d+)${T_POST_LBL}$/o ) {
+       } elsif ( /^$TUS[@]?__stg_split_marker(\d+)$TPOSTLBL[@]?$/o ) {
            $chk[++$i]   = $_;
            $chkcat[$i]  = 'splitmarker';
            $chksymb[$i] = $1;
 
-       } elsif ( /^${T_US}([A-Za-z0-9_]+)_info${T_POST_LBL}$/o ) {
+       } elsif ( /^$TUS[@]?([A-Za-z0-9_]+)_info$TPOSTLBL[@]?$/o ) {
            $symb = $1;
            $chk[++$i]   = $_;
            $chkcat[$i]  = 'infotbl';
@@ -423,40 +433,40 @@ sub mangle_asm {
 
            $infochk{$symb} = $i;
 
-       } elsif ( /^${T_US}([A-Za-z0-9_]+)_entry${T_POST_LBL}$/o ) {
+       } elsif ( /^$TUS[@]?([A-Za-z0-9_]+)_entry$TPOSTLBL[@]?$/o ) {
            $chk[++$i]   = $_;
            $chkcat[$i]  = 'slow';
            $chksymb[$i] = $1;
 
            $slowchk{$1} = $i;
 
-       } elsif ( /^${T_US}([A-Za-z0-9_]+)_fast\d+${T_POST_LBL}$/o ) {
+       } elsif ( /^$TUS[@]?([A-Za-z0-9_]+)_fast\d+$TPOSTLBL[@]?$/o ) {
            $chk[++$i]   = $_;
            $chkcat[$i]  = 'fast';
            $chksymb[$i] = $1;
 
            $fastchk{$1} = $i;
 
-       } elsif ( /^${T_US}([A-Za-z0-9_]+)_closure${T_POST_LBL}$/o ) {
+       } elsif ( /^$TUS[@]?([A-Za-z0-9_]+)_closure$TPOSTLBL[@]?$/o ) {
            $chk[++$i]   = $_;
            $chkcat[$i]  = 'closure';
            $chksymb[$i] = $1;
 
            $closurechk{$1} = $i;
 
-       } elsif ( /^${T_US}ghc.*c_ID${T_POST_LBL}/o ) {
+       } elsif ( /^$TUS[@]?ghc.*c_ID$TPOSTLBL/o ) {
            $chk[++$i]  = $_;
            $chkcat[$i] = 'consist';
 
-       } elsif ( /^(${T_US}__gnu_compiled_c|gcc2_compiled\.)${T_POST_LBL}/o ) {
+       } elsif ( /^($TUS[@]?__gnu_compiled_c|gcc2_compiled\.)$TPOSTLBL/o ) {
            ; # toss it
 
-       } elsif ( /^${T_US}ErrorIO_call_count${T_POST_LBL}$/o   # HACK!!!!
-              || /^${T_US}[A-Za-z0-9_]+\.\d+${T_POST_LBL}$/o
-              || /^${T_US}.*_CAT${T_POST_LBL}$/o               # PROF: _entryname_CAT
-              || /^${T_US}CC_.*_struct${T_POST_LBL}$/o         # PROF: _CC_ccident_struct
-              || /^${T_US}.*_done${T_POST_LBL}$/o              # PROF: _module_done
-              || /^${T_US}_module_registered${T_POST_LBL}$/o   # PROF: _module_registered
+       } elsif ( /^$TUS[@]?ErrorIO_call_count$TPOSTLBL[@]?$/o  # HACK!!!!
+              || /^$TUS[A-Za-z0-9_]+\.\d+$TPOSTLBL[@]?$/o
+              || /^$TUS[@]?.*_CAT$TPOSTLBL[@]?$/o              # PROF: _entryname_CAT
+              || /^$TUS[@]?CC_.*_struct$TPOSTLBL[@]?$/o        # PROF: _CC_ccident_struct
+              || /^$TUS[@]?.*_done$TPOSTLBL[@]?$/o             # PROF: _module_done
+              || /^$TUS[@]?_module_registered$TPOSTLBL[@]?$/o  # PROF: _module_registered
               ) {
            $chk[++$i]   = $_;
            $chkcat[$i]  = 'data';
@@ -467,26 +477,26 @@ sub mangle_asm {
            $chkcat[$i]  = 'bss';
            $chksymb[$i] = $1;
 
-       } elsif ( /^${T_US}(ret_|djn_)/o ) {
+       } elsif ( /^$TUS[@]?(ret_|djn_)/o ) {
            $chk[++$i]   = $_;
            $chkcat[$i]  = 'misc';
            $chksymb[$i] = '';
 
-       } elsif ( /^${T_US}vtbl_([A-Za-z0-9_]+)${T_POST_LBL}$/o ) {
+       } elsif ( /^$TUS[@]?vtbl_([A-Za-z0-9_]+)$TPOSTLBL[@]?$/o ) {
            $chk[++$i]   = $_;
            $chkcat[$i]  = 'vector';
            $chksymb[$i] = $1;
 
            $vectorchk{$1} = $i;
 
-       } elsif ( /^${T_US}([A-Za-z0-9_]+)DirectReturn${T_POST_LBL}$/o ) {
+       } elsif ( /^$TUS[@]?([A-Za-z0-9_]+)DirectReturn$TPOSTLBL[@]?$/o ) {
            $chk[++$i]   = $_;
            $chkcat[$i]  = 'direct';
            $chksymb[$i] = $1;
 
            $directchk{$1} = $i;
 
-       } elsif ( /^${T_US}[A-Za-z0-9_]+_upd${T_POST_LBL}$/o ) {
+       } elsif ( /^$TUS[@]?[A-Za-z0-9_]+_upd$TPOSTLBL[@]?$/o ) {
            $chk[++$i]   = $_;
            $chkcat[$i]  = 'misc';
            $chksymb[$i] = '';
@@ -506,7 +516,7 @@ sub mangle_asm {
            $chkcat[$i]  = 'toss';
            $chksymb[$i] = $1;
 
-       } elsif ( /^${T_US}[A-Za-z0-9_]/o
+       } elsif ( /^$TUS[@]?[A-Za-z0-9_]/o
                && ( $TargetPlatform !~ /^hppa/ # need to avoid local labels in this case
                   || ! /^L\$\d+$/ )
                && ( $TargetPlatform !~ /^powerpc/ # ditto
@@ -515,9 +525,9 @@ sub mangle_asm {
            chop($thing = $_);
            print STDERR "Funny global thing?: $_"
                unless $KNOWN_FUNNY_THING{$thing}
-                   || /^${T_US}_(PRIn|PRStart).*${T_POST_LBL}$/o # pointer reversal GC routines
-                   || /^${T_US}CC_.*${T_POST_LBL}$/o           # PROF: _CC_ccident
-                   || /^${T_US}_reg.*${T_POST_LBL}$/o;         # PROF: __reg<module>
+                   || /^$TUS[@]?_(PRIn|PRStart).*$TPOSTLBL[@]?$/o # pointer reversal GC routines
+                   || /^$TUS[@]?CC_.*$TPOSTLBL$/o              # PROF: _CC_ccident  ([@]? is a silly hack (see above))
+                   || /^$TUS[@]?_reg.*$TPOSTLBL$/o;            # PROF: __reg<module>
            $chk[++$i]   = $_;
            $chkcat[$i]  = 'misc';
            $chksymb[$i] = '';
@@ -644,7 +654,7 @@ sub mangle_asm {
        # On Alphas, the prologue mangling is done a little later (below)
 
        # toss all calls to __DISCARD__
-       $c =~ s/^\t(call|jbsr|jal)\s+${T_US}__DISCARD__\n//go;
+       $c =~ s/^\t(call|jbsr|jal)\s+$TUS[@]?__DISCARD__\n//go;
 
        # MIPS: that may leave some gratuitous asm macros around
        # (no harm done; but we get rid of them to be tidier)
@@ -667,16 +677,18 @@ sub mangle_asm {
        # pin a funny end-thing on (for easier matching):
        $c .= 'FUNNY#END#THING';
 
-       while ( $c =~ /${T_MOVE_DIRVS}FUNNY#END#THING/o ) {
+       while ( $c =~ /$TMOVEDIRVS[@]?FUNNY#END#THING/o ) {  # [@]? is a silly hack to avoid having to use curlies for T_PRE_APP
+                                                          # (this SEGVs perl4 on alphas, you see)
+
            $to_move = $1;
            if ( $i < ($numchks - 1)
-             && ( $to_move =~ /${T_COPY_DIRVS}/
+             && ( $to_move =~ /$TCOPYDIRVS/
                || ($TargetPlatform =~ /^hppa/ && $to_move =~ /align/ && $chkcat[$i+1] eq 'literal') )) {
                $chk[$i + 1] = $to_move . $chk[$i + 1];
                # otherwise they're tossed
            }
 
-           $c =~ s/${T_MOVE_DIRVS}FUNNY#END#THING/FUNNY#END#THING/o;
+           $c =~ s/$TMOVEDIRVS[@]?FUNNY#END#THING/FUNNY#END#THING/o; # [@]? is a hack (see above)
        }
 
        if ( $TargetPlatform =~ /^alpha-/ && $c =~ /^\t\.ent\s+(\S+)/ ) {
@@ -816,7 +828,7 @@ sub mangle_asm {
                # entry code will be put here!
 
                # paranoia
-               if ( $chk[$infochk{$symb}] =~ /${T_DOT_WORD}\s+([A-Za-z0-9_]+_entry)$/o
+               if ( $chk[$infochk{$symb}] =~ /$TDOTWORD[@]?\s+([A-Za-z0-9_]+_entry)$/o
                  && $1 ne "${T_US}${symb}_entry" ) {
                    print STDERR "!!! entry point???\n",$chk[$infochk{$symb}];
                }
@@ -856,7 +868,7 @@ sub mangle_asm {
                    # references to fast-entry point.
                    # (questionable re hppa and mips...)
                    print STDERR "still has jump to fast entry point:\n$c"
-                       if $c =~ /${T_US}${symb}_fast/; # NB: paranoia
+                       if $c =~ /$TUS[@]?$symb[@]?_fast/; # NB: paranoia
                }
 
                print OUTASM $T_HDR_entry;
@@ -1218,18 +1230,24 @@ sub rev_tbl {
     local($after) = '';
     local(@lines) = split(/\n/, $tbl);
     local($i, $extra, $words_to_pad, $j);
-
-    for ($i = 0; $i <= $#lines && $lines[$i] !~ /^\t${T_DOT_WORD}\s+/o; $i++) {
+   
+    # see comment in mangleAsm as to why this silliness is needed.
+    local($TDOTWORD) = ${T_DOT_WORD};
+    local($TDOTGLOBAL) = ${T_DOT_GLOBAL};
+    local($TUS) = ${T_US};
+    local($TPOSTLBL) = ${T_POST_LBL};
+
+    for ($i = 0; $i <= $#lines && $lines[$i] !~ /^\t$TDOTWORD\s+/o; $i++) {
        $label .= $lines[$i] . "\n",
-           next if $lines[$i] =~ /^[A-Za-z0-9_]+_info${T_POST_LBL}$/o
-                || $lines[$i] =~ /${T_DOT_GLOBAL}/o
-                || $lines[$i] =~ /^${T_US}vtbl_\S+${T_POST_LBL}$/o;
+           next if $lines[$i] =~ /^[A-Za-z0-9_]+_info$TPOSTLBL[@]?$/o
+                || $lines[$i] =~ /$TDOTGLOBAL/o
+                || $lines[$i] =~ /^$TUS[@]?vtbl_\S+$TPOSTLBL[@]?$/o;
 
        $before .= $lines[$i] . "\n"; # otherwise...
     }
 
     if ( $TargetPlatform !~ /^hppa/ ) {
-       for ( ; $i <= $#lines && $lines[$i] =~ /^\t${T_DOT_WORD}\s+/o; $i++) {
+       for ( ; $i <= $#lines && $lines[$i] =~ /^\t$TDOTWORD\s+/o; $i++) {
            push(@words, $lines[$i]);
        }
     } else { # hppa weirdness
@@ -1287,6 +1305,10 @@ sub mini_mangle_asm_i386 {
 
     &init_TARGET_STUFF();
 
+    # see mangleAsm comment
+    local($TUS) = ${T_US};
+    local($TPOSTLBL)=${T_POST_LBL};
+
     open(INASM, "< $in_asmf")
        || &tidy_up_and_die(1,"$Pgm: failed to open `$in_asmf' (to read)\n");
     open(OUTASM,"> $out_asmf")
@@ -1296,7 +1318,7 @@ sub mini_mangle_asm_i386 {
        print OUTASM;
 
         next unless
-           /^${T_US}(PerformGC|StackOverflow|Yield|PerformReschedule)_wrapper${T_POST_LBL}\n/o;
+           /^$TUS[@]?(PerformGC|StackOverflow|Yield|PerformReschedule)_wrapper$TPOSTLBL\n/o;
        print OUTASM "\tmovl \%esp, ${T_US}__temp_esp\n";
        print OUTASM "\tmovl \%eax, ${T_US}__temp_eax\n";
     }
index 3732beb..56d6523 100644 (file)
@@ -2094,7 +2094,7 @@ do {                                                       \
   StorageMgrInfo.ForeignObjList = result;                         \
                                                        \
                                                        \
-/*fprintf(stderr,"DEBUG: ForeignObj(0x%x) = <0x%x, 0x%x, 0x%x, 0x%x>\n",       \
+ /*fprintf(stderr,"DEBUG: ForeignObj(0x%x) = <0x%x, 0x%x, 0x%x, 0x%x>\n",      \
       result,                                          \
       result[0],result[1],                             \
       result[2],result[3]);*/                          \
@@ -2105,6 +2105,8 @@ do {                                                       \
   (r) = (P_) result;                                   \
 } while (0)
 
+#define writeForeignObjZh(res,datum)   ((PP_) ForeignObj_CLOSURE_DATA(res)) = ((P_)datum)
+
 #else
 #define makeForeignObjZh(r, liveness, mptr, finalise)              \
 do {                                                               \
@@ -2113,6 +2115,13 @@ do {                                                                 \
     EXIT(EXIT_FAILURE);                                                    \
 } while(0)
 
+#define writeForeignObjZh(res,datum)   \
+do {                                                               \
+    fflush(stdout);                                                \
+    fprintf(stderr, "writeForeignObj#: no foreign object support.\n");\
+    EXIT(EXIT_FAILURE);                                                    \
+} while(0)
+
 #endif /* !PAR */
 \end{code}
 
index 6236c38..76e8dbf 100644 (file)
@@ -4,7 +4,7 @@
 #
 #              Makefile for building the GHC Prelude libraries umpteen ways
 #
-#      $Id: Makefile,v 1.5 1997/03/14 05:30:36 sof Exp $
+#      $Id: Makefile,v 1.6 1997/03/17 20:34:49 simonpj Exp $
 #
 #      
 #################################################################################
@@ -52,14 +52,15 @@ endif
 
 # per-module flags
 
-ghc/PackedString_HC_OPTS    = -monly-3-regs
-required/Directory_HC_OPTS  = -monly-3-regs
-concurrent/Parallel_HC_OPTS = -fglasgow-exts
+ghc/PackedString_HC_OPTS    += -monly-3-regs
+required/Directory_HC_OPTS  += -monly-3-regs 
+concurrent/Parallel_HC_OPTS += -fglasgow-exts
+required/Time_HC_OPTS       += -monly-3-regs
 
 #-----------------------------------------------------------------------------
 #      Dependency generation
 
-SRC_MKDEPENDHS_OPTS += -irequired:ghc:hbc:glaExts:concurrent
+SRC_MKDEPENDHS_OPTS += -irequired:ghc:hbc:glaExts:concurrent -I$(GHC_INCLUDE_DIR)
 
 #-----------------------------------------------------------------------------
 #      Rules
index 8c0d2cb..d6b9b02 100644 (file)
@@ -59,6 +59,10 @@ StgInt       getBufferMode PROTO((StgForeignObj));
 
 /* getClockTime.lc */
 StgInt getClockTime PROTO((StgByteArray, StgByteArray));
+StgAddr        showTime     PROTO((I_, StgByteArray, StgByteArray));
+StgAddr        toClockSec   PROTO((I_, I_, I_, I_, I_, I_, I_, StgByteArray));
+StgAddr        toLocalTime  PROTO((I_, StgByteArray, StgByteArray));
+StgAddr        toUTCTime    PROTO((I_, StgByteArray, StgByteArray));
 
 /* getCPUTime.lc */
 StgByteArray getCPUTime PROTO((StgByteArray));
index 884bba0..d751f95 100644 (file)
@@ -210,6 +210,7 @@ indexAddrOffAddr#
   
   ForeignObj#
   makeForeignObj#
+  writeForeignObj#
   
   StablePtr#
   makeStablePtr#
index 4a952f7..8f1ad25 100644 (file)
@@ -399,11 +399,19 @@ type Handle = MutableVar RealWorld Handle__
 data Handle__
   = ErrorHandle                IOError
   | ClosedHandle
+#ifndef PAR
   | SemiClosedHandle   ForeignObj (Addr, Int)
   | ReadHandle         ForeignObj (Maybe BufferMode) Bool
   | WriteHandle                ForeignObj (Maybe BufferMode) Bool
   | AppendHandle       ForeignObj (Maybe BufferMode) Bool
   | ReadWriteHandle    ForeignObj (Maybe BufferMode) Bool
+#else
+  | SemiClosedHandle   Addr (Addr, Int)
+  | ReadHandle         Addr (Maybe BufferMode) Bool
+  | WriteHandle                Addr (Maybe BufferMode) Bool
+  | AppendHandle       Addr (Maybe BufferMode) Bool
+  | ReadWriteHandle    Addr (Maybe BufferMode) Bool
+#endif
 
 -- Standard Instances as defined by the Report..
 
index 50e1300..a3f64ce 100644 (file)
@@ -23,7 +23,7 @@ import IOBase
 import PrelTup
 import PrelBase
 import GHC
-import Foreign  ( makeForeignObj )
+import Foreign  ( makeForeignObj, writeForeignObj )
 import PrelList (span)
 #if defined(__CONCURRENT_HASKELL__)
 import ConcBase
@@ -68,7 +68,11 @@ writeHandle h v = stToIO (writeVar h v)
 %*********************************************************
 
 \begin{code}
+#ifndef PAR
 filePtr :: Handle__ -> ForeignObj
+#else
+filePtr :: Handle__ -> Addr
+#endif
 filePtr (SemiClosedHandle fp _)  = fp
 filePtr (ReadHandle fp _ _)     = fp
 filePtr (WriteHandle fp _ _)    = fp
@@ -116,8 +120,13 @@ stdin = unsafePerformPrimIO (
     _ccall_ getLock (``stdin''::Addr) 0                >>= \ rc ->
     (case rc of
        0 -> new_handle ClosedHandle
-       1 -> makeForeignObj (``stdin''::Addr) (``&freeStdChannel''::Addr) >>= \ fp ->
+       1 -> 
+#ifndef PAR
+            makeForeignObj (``stdin''::Addr) (``&freeStdChannel''::Addr) >>= \ fp ->
            new_handle (ReadHandle fp Nothing False)
+#else
+           new_handle (ReadHandle ``stdin'' Nothing False)
+#endif
        _ -> constructError "stdin"             >>= \ ioError -> 
             new_handle (ErrorHandle ioError)
     )                                          >>= \ handle ->
@@ -130,8 +139,13 @@ stdout = unsafePerformPrimIO (
     _ccall_ getLock (``stdout''::Addr) 1       >>= \ rc ->
     (case rc of
        0 -> new_handle ClosedHandle
-       1 -> makeForeignObj (``stdout''::Addr) (``&freeStdChannel''::Addr) >>= \ fp ->
+       1 -> 
+#ifndef PAR
+            makeForeignObj (``stdout''::Addr) (``&freeStdChannel''::Addr) >>= \ fp ->
            new_handle (WriteHandle fp Nothing False)
+#else
+           new_handle (WriteHandle ``stdout'' Nothing False)
+#endif
        _ -> constructError "stdout"            >>= \ ioError -> 
             new_handle (ErrorHandle ioError)
     )                                          >>= \ handle ->
@@ -144,8 +158,13 @@ stderr = unsafePerformPrimIO (
     _ccall_ getLock (``stderr''::Addr) 1       >>= \ rc ->
     (case rc of
        0 -> new_handle ClosedHandle
-       1 -> makeForeignObj (``stderr''::Addr) (``&freeStdChannel''::Addr) >>= \ fp ->
+       1 -> 
+#ifndef PAR
+            makeForeignObj (``stderr''::Addr) (``&freeStdChannel''::Addr) >>= \ fp ->
             new_handle (WriteHandle fp (Just NoBuffering) False)       
+#else
+            new_handle (WriteHandle ``stderr'' (Just NoBuffering) False)       
+#endif
        _ -> constructError "stderr"            >>= \ ioError -> 
             new_handle (ErrorHandle ioError)
     )                                          >>= \ handle ->
@@ -170,8 +189,12 @@ openFile :: FilePath -> IOMode -> IO Handle
 openFile f m = 
     stToIO (_ccall_ openFile f m')                          >>= \ ptr ->
     if ptr /= ``NULL'' then
-        stToIO (makeForeignObj ptr ((``&freeFile'')::Addr))  >>= \ fp ->
+#ifndef PAR
+        makeForeignObj ptr ((``&freeFile'')::Addr)   `thenIO_Prim` \ fp ->
         newHandle (htype fp Nothing False)
+#else
+        newHandle (htype ptr Nothing False)
+#endif
     else
        stToIO (constructError "openFile")          >>= \ ioError@(IOError hn iot msg) -> 
        let
@@ -226,11 +249,12 @@ hClose :: Handle -> IO ()
 
 hClose handle =
     readHandle handle                              >>= \ htype ->
-    writeHandle handle ClosedHandle                >>
     case htype of 
       ErrorHandle ioError ->
+         writeHandle handle htype >>
          fail ioError
       ClosedHandle -> 
+          writeHandle handle htype                 >>
          ioe_closedHandle handle
       SemiClosedHandle fp (buf,_) ->
           (if buf /= ``NULL'' then
@@ -245,19 +269,30 @@ hClose handle =
                     has been performed, the ForeignObj embedded in the Handle
                      is still lying around in the heap, so care is taken
                      to avoid closing the file object when the ForeignObj
-                    is finalised. (see freeFile()) -}
+                    is finalised.  -}
                 if rc == 0 then 
-                 return ()
+#ifndef PAR
+                 -- Mark the foreign object data value as gone to the finaliser (freeFile())
+                 writeForeignObj fp ``NULL''       `thenIO_Prim` \ () ->
+#endif
+                 writeHandle handle ClosedHandle
                 else
+                 writeHandle handle htype >>
                  constructErrorAndFail "hClose"
 
               else                         
-                  return ()
+                  writeHandle handle htype
       other -> 
-          _ccall_ closeFile (filePtr other)        `thenIO_Prim` \ rc ->
+         let fp = filePtr other in
+          _ccall_ closeFile fp     `thenIO_Prim` \ rc ->
           if rc == 0 then 
-             return ()
+#ifndef PAR
+                 -- Mark the foreign object data
+                 writeForeignObj fp ``NULL''       `thenIO_Prim` \ () ->
+#endif
+             writeHandle handle ClosedHandle
           else
+             writeHandle handle htype >>
              constructErrorAndFail "hClose"
 \end{code}
 
@@ -427,7 +462,11 @@ hSetBuffering handle mode =
               BlockBuffering Nothing -> -2
               BlockBuffering (Just n) -> n
 
+#ifndef PAR
     hcon :: Handle__ -> (ForeignObj -> (Maybe BufferMode) -> Bool -> Handle__)
+#else
+    hcon :: Handle__ -> (Addr -> (Maybe BufferMode) -> Bool -> Handle__)
+#endif
     hcon (ReadHandle _ _ _) = ReadHandle
     hcon (WriteHandle _ _ _) = WriteHandle
     hcon (AppendHandle _ _ _) = AppendHandle
index 8273434..81abc4f 100644 (file)
@@ -79,12 +79,21 @@ instance CReturnable () -- Why, exactly?
 instance CCallable ForeignObj
 instance CCallable ForeignObj#
 
-eqForeignObj   :: ForeignObj -> ForeignObj -> Bool
-makeForeignObj :: Addr       -> Addr       -> PrimIO ForeignObj
+eqForeignObj    :: ForeignObj  -> ForeignObj -> Bool
+makeForeignObj  :: Addr        -> Addr       -> PrimIO ForeignObj
+writeForeignObj :: ForeignObj  -> Addr       -> PrimIO ()
 
-makeForeignObj (A# obj) (A# finaliser) = ST $ \ (S# s#) ->
+{- derived op - attaching a free() finaliser to a malloc() allocated reference. -}
+makeMallocPtr   :: Addr        -> PrimIO ForeignObj
+
+makeForeignObj (A# obj) (A# finaliser) = ST ( \ (S# s#) ->
     case makeForeignObj# obj finaliser s# of
-      StateAndForeignObj# s1# fo# -> (ForeignObj fo#, S# s1#)
+      StateAndForeignObj# s1# fo# -> (ForeignObj fo#, S# s1#))
+
+writeForeignObj (ForeignObj fo#) (A# datum#) = ST ( \ (S# s#) ->
+    case writeForeignObj# fo# datum# s# of { s1# -> ((), S# s1#) } )
+
+makeMallocPtr a = makeForeignObj a (``&free''::Addr)
 
 eqForeignObj mp1 mp2
   = unsafePerformPrimIO (_ccall_ eqForeignObj mp1 mp2) /= (0::Int)
index e9f70e9..d7fdf7d 100644 (file)
@@ -1,8 +1,7 @@
 %
 % (c) The AQUA Project, Glasgow University, 1994-1997
 %
-
-\section[Directory]{Module @Directory@}
+\section[Directory]{Directory interface}
 
 A directory contains a series of entries, each of which is a named
 reference to a file system object (file, directory etc.).  Some
@@ -18,23 +17,36 @@ some operating systems, it may also be possible to have paths which
 are relative to the current directory.
 
 \begin{code}
-module Directory ( 
---    Permissions(Permissions),
-    createDirectory, removeDirectory, removeFile, 
-    renameDirectory, renameFile, getDirectoryContents,
-    getCurrentDirectory, setCurrentDirectory
-{-
-    ,doesFileExist, doesDirectoryExist,
-    getPermissions, setPermissions,
+{-# OPTIONS -#include <sys/stat.h> #-}
+module Directory 
+   ( 
+    Permissions(Permissions),
+
+    createDirectory, 
+    removeDirectory, 
+    renameDirectory, 
+    getDirectoryContents,
+    getCurrentDirectory, 
+    setCurrentDirectory,
+
+    removeFile, 
+    renameFile, 
+
+    doesFileExist,
+    doesDirectoryExist,
+    getPermissions, 
+    setPermissions,
     getModificationTime
--}
-  ) where
+   ) where
 
-import Prelude
+import PrelBase
 import Foreign
 import IOBase
-import STBase          ( PrimIO )
-import PackedString    ( packCBytesST, unpackPS )
+import STBase
+import ArrBase
+import PackedString    ( packCBytesST, unpackPS, psToByteArrayST )
+import Time             ( ClockTime(..) )
+
 \end{code}
 
 %*********************************************************
@@ -52,6 +64,11 @@ renameFile           :: FilePath -> FilePath -> IO ()
 getDirectoryContents   :: FilePath -> IO [FilePath]
 getCurrentDirectory    :: IO FilePath
 setCurrentDirectory    :: FilePath -> IO ()
+doesFileExist           :: FilePath -> IO Bool
+doesDirectoryExist      :: FilePath -> IO Bool
+getPermissions          :: FilePath -> IO Permissions
+setPermissions          :: FilePath -> Permissions -> IO ()
+getModificationTime     :: FilePath -> IO ClockTime
 \end{code}
 
 
@@ -61,8 +78,9 @@ setCurrentDirectory   :: FilePath -> IO ()
 %*                                                     *
 %*********************************************************
 
-The @Permissions@ type is used to record whether certain operations are permissible on a
-file/directory:
+The @Permissions@ type is used to record whether certain
+operations are permissible on a file/directory:
+[to whom? - owner/group/world - the Report don't say much]
 
 \begin{code}
 data Permissions
@@ -70,7 +88,6 @@ data Permissions
     readable,   writeable, 
     executable, searchable :: Bool 
    } deriving (Eq, Ord, Read, Show)
-
 \end{code}
 
 %*********************************************************
@@ -410,25 +427,26 @@ setCurrentDirectory path =
 
 
 \begin{code}
-{-
-doesFileExist :: FilePath -> IO Bool
+--doesFileExist :: FilePath -> IO Bool
 doesFileExist name =
   psToByteArrayST name                     `thenIO_Prim` \ path ->
   _ccall_ access path (``F_OK''::Int)      `thenIO_Prim` \ rc ->
   return (rc == 0)
 
-doesDirectoryExist :: FilePath -> IO Bool
-doesDirectoryExist name =  
- (getFileStatus >>= isDirectory) `catch` (\ _ -> return False)
+--doesDirectoryExist :: FilePath -> IO Bool
+doesDirectoryExist name = 
+ (getFileStatus name >>= \ st -> return (isDirectory st))  
+   `catch` 
+ (\ _ -> return False)
 
-getModificationTime :: FilePath -> IO Bool
+--getModificationTime :: FilePath -> IO ClockTime
 getModificationTime name =
- getFileStatus >>= \ st ->
- return (modificationTime st)
+ getFileStatus name >>= \ st ->
+ modificationTime st
 
-getPermissions :: FilePath -> IO Permissions
+--getPermissions :: FilePath -> IO Permissions
 getPermissions name =
-  getFileStatus >>= \ st ->
+  getFileStatus name >>= \ st ->
   let
    fm = fileMode st
    isect v = intersectFileMode v fm == v
@@ -441,5 +459,99 @@ getPermissions name =
       searchable = not (isRegularFile st) && isect ownerExecuteMode
     }
   )
--}
+
+--setPermissions :: FilePath -> Permissions -> IO ()
+setPermissions name (Permissions r w e s) = 
+    let
+     read#  = case (if r then ownerReadMode else ``0'') of { W# x# -> x# }
+     write# = case (if w then ownerWriteMode else ``0'') of { W# x# -> x# }
+     exec#  = case (if e || s then ownerExecuteMode else ``0'') of { W# x# -> x# }
+
+     mode  = I# (word2Int# (read# `or#` write# `or#` exec#))
+    in
+    psToByteArrayST name                           `thenIO_Prim` \ path ->
+    _ccall_ chmod path mode                        `thenIO_Prim` \ rc ->
+    if rc == 0 then
+       return ()
+    else
+       fail (IOError Nothing SystemError "Directory.setPermissions")
+
+\end{code}
+
+
+(Sigh)..copied from Posix.Files to avoid dep. on posix library
+
+\begin{code}
+type FileStatus = ByteArray Int
+
+getFileStatus :: FilePath -> IO FileStatus
+getFileStatus name =
+    psToByteArrayST name                           `thenIO_Prim` \ path ->
+    newCharArray (0,``sizeof(struct stat)'')        `thenIO_Prim` \ bytes ->
+    _casm_ ``%r = stat(%0,(struct stat *)%1);'' path bytes
+                                                   `thenIO_Prim` \ rc ->
+    if rc == 0 then
+       unsafeFreezeByteArray bytes                 `thenIO_Prim` \ stat ->
+       return stat
+    else
+       fail (IOError Nothing SystemError "Directory.getFileStatus")
+
+modificationTime :: FileStatus -> IO ClockTime
+modificationTime stat =
+    malloc1                                               `thenIO_Prim` \ i1 ->
+    _casm_ ``((unsigned long *)%1)[0] = ((struct stat *)%0)->st_mtime;'' stat i1 `thenIO_Prim` \ () ->
+    cvtUnsigned i1                                         `thenIO_Prim` \ secs ->
+    return (TOD secs 0)
+  where
+    malloc1 = ST $ \ (S# s#) ->
+       case newIntArray# 1# s# of 
+          StateAndMutableByteArray# s2# barr# -> (MutableByteArray bnds barr#, S# s2#)
+
+    bnds = (0,1)
+    -- The C routine fills in an unsigned word.  We don't have `unsigned2Integer#,'
+    -- so we freeze the data bits and use them for an MP_INT structure.  Note that
+    -- zero is still handled specially, although (J# 1# 1# (ptr to 0#)) is probably
+    -- acceptable to gmp.
+
+    cvtUnsigned (MutableByteArray _ arr#) = ST $ \ (S# s#) ->
+       case readIntArray# arr# 0# s# of 
+         StateAndInt# s2# r# ->
+            if r# ==# 0# then
+                (0, S# s2#)
+            else
+                case unsafeFreezeByteArray# arr# s2# of
+                  StateAndByteArray# s3# frozen# -> (J# 1# 1# frozen#, S# s3#)
+
+isDirectory :: FileStatus -> Bool
+isDirectory stat = unsafePerformPrimIO $
+    _casm_ ``%r = S_ISDIR(((struct stat *)%0)->st_mode);'' stat >>= \ rc ->
+    return (rc /= 0)
+
+isRegularFile :: FileStatus -> Bool
+isRegularFile stat = unsafePerformPrimIO $
+    _casm_ ``%r = S_ISREG(((struct stat *)%0)->st_mode);'' stat >>= \ rc ->
+    return (rc /= 0)
+
+
+\end{code}
+
+\begin{code}
+type FileMode = Word
+ownerReadMode :: FileMode
+ownerReadMode = ``S_IRUSR''
+
+ownerWriteMode :: FileMode
+ownerWriteMode = ``S_IWUSR''
+
+ownerExecuteMode :: FileMode
+ownerExecuteMode = ``S_IXUSR''
+
+intersectFileMode :: FileMode -> FileMode -> FileMode
+intersectFileMode (W# m1#) (W# m2#) = W# (m1# `and#` m2#)
+
+fileMode :: FileStatus -> FileMode
+fileMode stat = unsafePerformPrimIO $
+    _casm_ ``%r = ((struct stat *)%0)->st_mode;'' stat >>= \ mode ->
+    return mode
+
 \end{code}
index 34d5a33..c727c00 100644 (file)
@@ -39,7 +39,7 @@ import IOHandle               -- much of the real stuff is in here
 import PackedString    ( nilPS, packCBytesST, unpackPS )
 import PrelBase
 import GHC
-import Foreign          ( makeForeignObj )
+import Foreign          ( makeForeignObj, writeForeignObj )
 \end{code}
 
 %*********************************************************
@@ -289,11 +289,14 @@ lazyReadBlock handle =
          then return nilPS
          else packCBytesST bytes buf)              >>= \ some ->
           if bytes < 0 then
-             makeForeignObj ``NULL'' ``&freeFile'' >>= \ null_fp ->
-             ioToST (writeHandle handle (SemiClosedHandle null_fp (``NULL'', 0)))
-                                                   >>
               _ccall_ free buf                     >>= \ () ->
               _ccall_ closeFile fp                 >>
+#ifndef PAR
+             writeForeignObj fp ``NULL''           >>
+             ioToST (writeHandle handle (SemiClosedHandle fp (``NULL'', 0))) >>
+#else
+             ioToST (writeHandle handle (SemiClosedHandle ``NULL'' (``NULL'', 0))) >>
+#endif
              returnPrimIO (unpackPS some)
          else
              ioToST (writeHandle handle htype)     >>
@@ -314,11 +317,14 @@ lazyReadLine handle =
          then return nilPS
          else packCBytesST bytes buf)              >>= \ some ->
           if bytes < 0 then
-             makeForeignObj ``NULL'' ``&freeFile'' >>= \ null_fp ->
-             ioToST (writeHandle handle (SemiClosedHandle null_fp (``NULL'', 0)))
-                                                   >>
               _ccall_ free buf                     >>= \ () ->
               _ccall_ closeFile fp                 >>
+#ifndef PAR
+             writeForeignObj fp ``NULL''           >>
+             ioToST (writeHandle handle (SemiClosedHandle fp (``NULL'', 0))) >>
+#else
+             ioToST (writeHandle handle (SemiClosedHandle ``NULL'' (``NULL'', 0))) >>
+#endif
              returnPrimIO (unpackPS some)
          else
              ioToST (writeHandle handle htype)     >>
@@ -336,10 +342,13 @@ lazyReadChar handle =
       SemiClosedHandle fp buf_info ->
          _ccall_ readChar fp                       >>= \ char ->
           if char == ``EOF'' then
-             makeForeignObj ``NULL'' ``&freeFile'' >>= \ null_fp ->
-             ioToST (writeHandle handle (SemiClosedHandle null_fp buf_info))
-                                                   >>
               _ccall_ closeFile fp                 >>
+#ifndef PAR
+             writeForeignObj fp ``NULL''           >>
+             ioToST (writeHandle handle (SemiClosedHandle fp (``NULL'', 0))) >>
+#else
+             ioToST (writeHandle handle (SemiClosedHandle ``NULL'' (``NULL'', 0))) >>
+#endif
              returnPrimIO ""
          else
              ioToST (writeHandle handle htype)     >>
@@ -425,10 +434,18 @@ hPutStr handle str =
           else
               constructErrorAndFail "hPutStr"
   where
+#ifndef PAR
     writeLines :: ForeignObj -> String -> PrimIO Bool
+#else
+    writeLines :: Addr -> String -> PrimIO Bool
+#endif
     writeLines = writeChunks ``BUFSIZ'' True 
 
+#ifndef PAR
     writeBlocks :: ForeignObj -> Int -> String -> PrimIO Bool
+#else
+    writeBlocks :: Addr -> Int -> String -> PrimIO Bool
+#endif
     writeBlocks fp size s = writeChunks size False fp s
  
     {-
@@ -443,8 +460,11 @@ hPutStr handle str =
       a whole lot quicker. -- SOF 3/96
     -}
 
+#ifndef PAR
     writeChunks :: Int -> Bool -> ForeignObj -> String -> PrimIO Bool
-
+#else
+    writeChunks :: Int -> Bool -> Addr -> String -> PrimIO Bool
+#endif
     writeChunks (I# bufLen) chopOnNewLine fp s =
      newCharArray (0,I# bufLen) >>= \ arr@(MutableByteArray _ arr#) ->
      let
@@ -478,7 +498,11 @@ hPutStr handle str =
      in
      shoveString 0# s
 
+#ifndef PAR
     writeChars :: ForeignObj -> String -> PrimIO Bool
+#else
+    writeChars :: Addr -> String -> PrimIO Bool
+#endif
     writeChars fp "" = returnPrimIO True
     writeChars fp (c:cs) =
        _ccall_ filePutc fp (ord c) >>= \ rc ->
index 881166d..0c172e9 100644 (file)
@@ -9,6 +9,8 @@ clock times, including timezone information (i.e, the functionality of
 its use of Coordinated Universal Time (UTC).
 
 \begin{code}
+{-# OPTIONS -#include "cbits/timezone.h" -#include "cbits/stgio.h"  #-}
+
 module Time 
        (
        CalendarTime(..),
@@ -16,20 +18,23 @@ module Time
        Day,
         CalendarTime(CalendarTime),
         TimeDiff(TimeDiff),
-       ClockTime,
+       ClockTime(..), -- non-standard, lib. report gives this as abstract
        getClockTime, addToClockTime, diffClockTimes,
        toCalendarTime, toUTCTime, toClockTime,
-        calendarToTimeString, formatCalendarTime
+        calendarTimeToString, formatCalendarTime
        ) where
 
 import PrelBase
 import ST
-import IOBase ( IOError(..), constructErrorAndFail )
+import IOBase
 import ArrBase
 import STBase
-
+import ST
+import Ix
+import Char (intToDigit)
 import PackedString (unpackPS, packCBytesST)
-import PosixUtil    (allocWords, allocChars)
+import Locale
+
 \end{code}
 
 One way to partition and give name to chunks of a year and a week:
@@ -53,8 +58,7 @@ Clock times may be compared, converted to strings, or converted to an
 external calendar time @CalendarTime@.
 
 \begin{code}
-data ClockTime = TOD Integer Integer
-                 deriving (Eq, Ord)
+data ClockTime = TOD Integer Integer deriving (Eq, Ord)
 \end{code}
 
 When a @ClockTime@ is shown, it is converted to a string of the form
@@ -244,7 +248,7 @@ toCalendarTime (TOD sec@(J# a# s# d#) psec) = unsafePerformPrimIO $
         _ccall_ strlen zone                            >>= \ len ->
         packCBytesST len zone                          >>= \ tzname ->
         returnPrimIO (CalendarTime (1900+year) mon mday hour min sec psec 
-                      wday yday (unpackPS tzname) tz (isdst /= 0))
+                      (toEnum wday) yday (unpackPS tzname) tz (isdst /= 0))
 
 toUTCTime :: ClockTime -> CalendarTime
 toUTCTime  (TOD sec@(J# a# s# d#) psec) = unsafePerformPrimIO (
@@ -265,7 +269,7 @@ toUTCTime  (TOD sec@(J# a# s# d#) psec) = unsafePerformPrimIO (
        _casm_ ``%r = ((struct tm *)%0)->tm_wday;'' tm  >>= \ wday ->
        _casm_ ``%r = ((struct tm *)%0)->tm_yday;'' tm  >>= \ yday ->
         returnPrimIO (CalendarTime (1900+year) mon mday hour min sec psec 
-                      wday yday "UTC" 0 False)
+                      (toEnum wday) yday "UTC" 0 False)
     )
 
 toClockTime :: CalendarTime -> ClockTime
@@ -287,79 +291,93 @@ toClockTime (CalendarTime year mon mday hour min sec psec wday yday tzname tz is
 
 bottom :: (Int,Int)
 bottom = error "Time.bottom"
+
+
+-- (copied from PosixUtil, for now)
+-- Allocate a mutable array of characters with no indices.
+
+allocChars :: Int -> ST s (MutableByteArray s ())
+allocChars (I# size#) = ST $ \ (S# s#) ->
+    case newCharArray# size# s# of 
+      StateAndMutableByteArray# s2# barr# -> (MutableByteArray bot barr#, S# s2#)
+  where
+    bot = error "Time.allocChars"
+
+-- Allocate a mutable array of words with no indices
+
+allocWords :: Int -> ST s (MutableByteArray s ())
+allocWords (I# size#) = ST $ \ (S# s#) ->
+    case newIntArray# size# s# of 
+      StateAndMutableByteArray# s2# barr# -> (MutableByteArray bot barr#, S# s2#)
+  where
+    bot = error "Time.allocWords"
+
 \end{code}
 
 \begin{code}
-calendarTimeToString :: CalendarTime -> String
-calendarTimeToString  =  formatCalendarTime defaultTimeLocale "%c"
-
-formatCalendarTime :: TimeLocale -> String -> CalendarTime -> String
-formatCalendarTime l 
-                  fmt 
-                  ct@(CalendarTime 
-                       year mon 
-                       day hour 
-                       min sec 
-                       sdec 
-                        wday yday tzname _ _)
- = doFmt fmt
-  where 
-   doFmt ('%':c:cs) = decode c ++ doFmt cs
-   doFmt (c:cs) = c : doFmt cs
-   doFmt "" = ""
-
-   to12 h = let h' = h `mod` 12 in if h == 0 then 12 else h
-
-   decode 'A' = fst (wdays l  !! fromEnum wday)
-   decode 'a' = snd (wdays l  !! fromEnum wday)
-   decode 'B' = fst (months l !! fromEnum mon)
-   decode 'b' = snd (months l !! fromEnum mon)
-   decode 'h' = snd (months l !! fromEnum mon)
-   decode 'C' = show2 (year `quot` 100)
-   decode 'c' = doFmt (dateTimeFmt l)
-   decode 'D' = doFmt "%m/%d/%y"
-   decode 'd' = show2 day
-   decode 'e' = show2' day
-   decode 'H' = show2 hour
-   decode 'I' = show2 (to12 hour)
-   decode 'j' = show3 yday
-   decode 'k' = show2' hour
-   decode 'l' = show2' (to12 hour)
-   decode 'M' = show2 min
-   decode 'm' = show2 (fromEnum mon+1)
-   decode 'n' = "\n"
-   decode 'p' = (if hour < 12 then fst else snd) (amPm l)
-   decode 'R' = doFmt "%H:%M"
-   decode 'r' = doFmt (time12Fmt l)
-   decode 'T' = doFmt "%H:%M:%S"
-   decode 't' = "\t"
-   decode 'S' = show2 sec
-   decode 's' = show2 sec -- Implementation-dependent, sez the lib doc..
-   decode 'U' = show2 ((yday + 7 - fromEnum wday) `div` 7)
-   decode 'u' = show (let n = fromEnum wday in if n == 0 then 7 else n)
-   decode 'V' = 
-    let (week, days) = 
-          (yday + 7 - if fromEnum wday > 0 then 
-                         fromEnum wday - 1 else 6) `divMod` 7
-    in  
-    show2 (if   days >= 4 
-           then week+1 
-           else if week == 0 then 53 else week)
-   decode 'W' = 
-    show2 ((yday + 7 - if fromEnum wday > 0 then 
-                          fromEnum wday - 1 else 6) `div` 7)
-   decode 'w' = show (fromEnum wday)
-   decode 'X' = doFmt (timeFmt l)
-   decode 'x' = doFmt (dateFmt l)
-   decode 'Y' = show year
-   decode 'y' = show2 (year `rem` 100)
-   decode 'Z' = tzname
-   decode '%' = "%"
-   decode c   = [c]
-
-show2, show2', show3 :: Int -> String
-show2 x = [intToDigit (x `quot` 10), intToDigit (x `rem` 10)]
-show2' x = if x < 10 then [ ' ', intToDigit x] else show2 x
-show3 x = intToDigit (x `quot` 100) : show2 (x `rem` 100)
-
+calendarTimeToString  :: CalendarTime -> String
+calendarTimeToString  =  formatCalendarTime defaultTimeLocale "%c"
+
+formatCalendarTime :: TimeLocale -> String -> CalendarTime -> String
+formatCalendarTime l fmt ct@(CalendarTime year mon day hour min sec sdec 
+                                           wday yday tzname _ _) =
+        doFmt fmt
+  where doFmt ('%':c:cs) = decode c ++ doFmt cs
+        doFmt (c:cs) = c : doFmt cs
+        doFmt "" = ""
+        to12 h = let h' = h `mod` 12 in if h == 0 then 12 else h
+        decode 'A' = fst (wDays l  !! fromEnum wday)
+        decode 'a' = snd (wDays l  !! fromEnum wday)
+        decode 'B' = fst (months l !! fromEnum mon)
+        decode 'b' = snd (months l !! fromEnum mon)
+        decode 'h' = snd (months l !! fromEnum mon)
+        decode 'C' = show2 (year `quot` 100)
+        decode 'c' = doFmt (dateTimeFmt l)
+        decode 'D' = doFmt "%m/%d/%y"
+        decode 'd' = show2 day
+        decode 'e' = show2' day
+        decode 'H' = show2 hour
+        decode 'I' = show2 (to12 hour)
+        decode 'j' = show3 yday
+        decode 'k' = show2' hour
+        decode 'l' = show2' (to12 hour)
+        decode 'M' = show2 min
+        decode 'm' = show2 (fromEnum mon+1)
+        decode 'n' = "\n"
+        decode 'p' = (if hour < 12 then fst else snd) (amPm l)
+        decode 'R' = doFmt "%H:%M"
+        decode 'r' = doFmt (time12Fmt l)
+        decode 'T' = doFmt "%H:%M:%S"
+        decode 't' = "\t"
+        decode 'S' = show2 sec
+        decode 's' = show2 sec -- Implementation-dependent, sez the lib doc..
+        decode 'U' = show2 ((yday + 7 - fromEnum wday) `div` 7)
+        decode 'u' = show (let n = fromEnum wday in 
+                           if n == 0 then 7 else n)
+        decode 'V' = 
+            let (week, days) = 
+                   (yday + 7 - if fromEnum wday > 0 then 
+                               fromEnum wday - 1 else 6) `divMod` 7
+            in  show2 (if days >= 4 then
+                          week+1 
+                       else if week == 0 then 53 else week)
+
+        decode 'W' = 
+            show2 ((yday + 7 - if fromEnum wday > 0 then 
+                               fromEnum wday - 1 else 6) `div` 7)
+        decode 'w' = show (fromEnum wday)
+        decode 'X' = doFmt (timeFmt l)
+        decode 'x' = doFmt (dateFmt l)
+        decode 'Y' = show year
+        decode 'y' = show2 (year `rem` 100)
+        decode 'Z' = tzname
+        decode '%' = "%"
+        decode c   = [c]
+
+show2, show2', show3 :: Int -> String
+show2 x = [intToDigit (x `quot` 10), intToDigit (x `rem` 10)]
+
+show2' x = if x < 10 then [ ' ', intToDigit x] else show2 x
+
+show3 x = intToDigit (x `quot` 100) : show2 (x `rem` 100)
 \end{code}
index 96782a0..08e36c9 100644 (file)
@@ -24,11 +24,9 @@ TOP:=$(GHC_TOP)
 # -----------------------------------------------------------------
 # Everything after this point
 # augments or overrides previously set variables.
-# (these files are optional, so `make' won't fret if
-#  cannot get to them).
 # -----------------------------------------------------------------
 
--include $(TOP)/mk/paths.mk
--include $(TOP)/mk/opts.mk
+include $(TOP)/mk/paths.mk
+include $(TOP)/mk/opts.mk
 include $(TOP)/mk/suffix.mk
 
index d7b30e7..635956a 100644 (file)
@@ -10,9 +10,13 @@ HaskellCompilerType  = $(WithGhcHcType)
 # What ways to build the RTS+libs
 WAYS=$(GhcLibWays)
 
+GCap=-optc-DGCap
+#GC2s=-optc-DGC2s
+#GC1s=-optc-DGC1s
 
 MKDEPENDHSSRC          = $(GHC_UTILS_DIR)/mkdependHS
 UNLIT                  = $(GHC_UNLIT_DIR)/unlit
+GHC_UNLIT              = $(GHC_UNLIT_DIR)/unlit
 GHC_UNLIT_DIR          = $(GHC_UTILS_DIR)/unlit
 
 #-----------------------------------------------------------------------------
@@ -29,10 +33,10 @@ endif
 # Ugen
 
 ifdef UseInstalledUtils
-UGEN           =  ugen
+UGEN           = ugen
 else
 UGEN           = $(UGEN_DIR)/ugen
-UGENSRC        = $(GHC_UTILS_DIR)/ugen
+UGEN_DIR       = $(GHC_UTILS_DIR)/ugen
 endif
 
 #-----------------------------------------------------------------------------
index ff991b0..b5713a4 100644 (file)
@@ -1,5 +1,5 @@
 #-----------------------------------------------------------------------------
-# $Id: Makefile,v 1.4 1997/03/14 05:11:52 sof Exp $
+# $Id: Makefile,v 1.5 1997/03/17 20:34:59 simonpj Exp $
 
 #  This is the Makefile for the runtime-system stuff.
 #  This stuff is written in C (and cannot be written in Haskell).
@@ -159,9 +159,9 @@ LIBOBJS = $(patsubst %.lc,%.$(way_)o,$(SRCS_RTS_LC)) \
 #
 # dependencies
 #
-SRC_HC_OPTS += -I$(GHC_INCLUDE_DIR) -O -optc-DIN_GHC_RTS=1 -I$(GHC_RUNTIME_DIR)/storage 
+SRC_HC_OPTS += -I$(GHC_INCLUDE_DIR) $(GCap) $(GC2s) $(GC1s) -O -optc-DIN_GHC_RTS=1 -I$(GHC_RUNTIME_DIR)/storage 
 
-SRC_MKDEPENDC_OPTS += $(GCap) $(GC2s) $(GC1s)
+SRC_MKDEPENDC_OPTS += -I$(GHC_INCLUDE_DIR) $(GCap) $(GC2s) $(GC1s)
 
 #-----------------------------------------------------------------------------
 # file-specific options 
index 953ed15..021e0aa 100644 (file)
@@ -43,6 +43,8 @@ stg_exit (n) /* can't call regular "exit" from Haskell
                because it has no return value */
   I_ n;
 {
+    /* Storage manager shutdown */
+    shutdownHaskell();
     EXIT(n);
     return(0); /* GCC warning food */
 }
index c8fa245..0cc939b 100644 (file)
@@ -181,6 +181,11 @@ GhcLibHcOpts= -split-objs -odir $(basename $*)
 # Build the Haskell Readline bindings?
 #
 HsLibsWithReadline=YES
+#
+# Include path to readline.h
+# (no path == in standard include path)
+#
+ReadlineIncludePath=
 
 # Build the socket libraries?
 #
@@ -192,6 +197,9 @@ HsLibsWithSockets=YES
 #
 HsLibWays=$(GhcLibWays)
 
+# Option flags for hslibs are by default the same as for the options
+# used for the prelude libs (see above).
+HsLibHcOpts=$(GhcLibHcOpts)
 
 #################################################################################
 #
@@ -265,37 +273,32 @@ NoFibHcOpts=
 #
 #################################################################################
 
-# These variables are all ":=" variables so that you can easily attach
-# extra stuff to the end of them, like this:
-#
-#      libdir := $(libdir)/ghc
-
-TMPDIR                 := /tmp
+TMPDIR                 = /tmp
 
 # FPTOOLS_TOP: the top of the fptools hierarchy, absolute path.
 
-FPTOOLS_TOP_ABS                := @hardtop@
+FPTOOLS_TOP_ABS                = @hardtop@
 
 #
 # Installation directories, we don't use half of these,
 # but since the configure script has them on offer while
 # passing through, we might as well set them.
 
-prefix                  := @prefix@
-exec_prefix             := @exec_prefix@
-bindir                  := @bindir@
-sbindir                 := @sbindir@
-libexecdir              := @libexecdir@
-datadir                 := @datadir@
-sysconfdir              := @datadir@
-sharedstatedir          := @sharedstatedir@
-localstatedir           := @localstatedir@
-libdir                  := @libdir@
-infodir                        := @infodir@
-includedir              := @includedir@
-oldincludedir           := @oldincludedir@
-mandir                 := @mandir@
-srcdir                  := @srcdir@
+prefix                  = @prefix@
+exec_prefix             = @exec_prefix@
+bindir                  = @bindir@
+sbindir                 = @sbindir@
+libexecdir              = @libexecdir@
+datadir                 = @datadir@
+sysconfdir              = @datadir@
+sharedstatedir          = @sharedstatedir@
+localstatedir           = @localstatedir@
+libdir                  = @libdir@
+infodir                        = @infodir@
+includedir              = @includedir@
+oldincludedir           = @oldincludedir@
+mandir                 = @mandir@
+srcdir                  = @srcdir@
 
 #################################################################################
 #
index 28b3d7c..d1d1129 100644 (file)
@@ -689,15 +689,16 @@ ifneq "$(filter -monolithic,$(TEXI2HTML_OPTS))" ""
        $(LIT2TEXI) -S -c $(LIT2TEXI_OPTS) -o $(patsubst %.html,%.itxi,$@) $(addsuffix .lit,$(basename $@))
        $(LIT2TEXI) -S $(LIT2TEXI_OPTS) -o $(patsubst %.html,%.texi,$@) $(addsuffix .itxi,$(basename $@))
        $(TEXI2HTML) $(TEXI2HTML_OPTS) $(patsubst %.html,%.texi,$@)
+       cp $(TEXI2HTML_PREFIX)invisible.xbm .
 else
        $(RM) html/$(basename $@)*
        $(MKDIRHIER) html
        $(LIT2TEXI) -S -c $(LIT2TEXI_OPTS) -o $(patsubst %.html,%.itxi,$@) $(addsuffix .lit,$(basename $@))
        $(LIT2TEXI) -S $(LIT2TEXI_OPTS) -o html/$(patsubst %.html,%.texi,$@) $(addsuffix .itxi,$(basename $@))
        (cd html; ../$(TEXI2HTML) $(TEXI2HTML_OPTS) $(patsubst %.html,%.texi,$@); cd ..)
+       cp $(TEXI2HTML_PREFIX)invisible.xbm html/
        @touch $@
 endif
-
 ###########################################
 #
 #      Targets: clean