[project @ 1999-02-03 17:08:25 by sewardj]
authorsewardj <unknown>
Wed, 3 Feb 1999 17:08:44 +0000 (17:08 +0000)
committersewardj <unknown>
Wed, 3 Feb 1999 17:08:44 +0000 (17:08 +0000)
Preliminary results of the merge of STG hugs and 990121.  These files
will compile and link, but don't work yet.

31 files changed:
ghc/interpreter/Makefile
ghc/interpreter/codegen.c
ghc/interpreter/command.h
ghc/interpreter/compiler.c
ghc/interpreter/connect.h
ghc/interpreter/derive.c
ghc/interpreter/dynamic.c
ghc/interpreter/errors.h
ghc/interpreter/free.c
ghc/interpreter/hugs.c
ghc/interpreter/input.c
ghc/interpreter/lift.c
ghc/interpreter/link.c
ghc/interpreter/link.h
ghc/interpreter/machdep.c
ghc/interpreter/optimise.c
ghc/interpreter/output.c
ghc/interpreter/parser.y
ghc/interpreter/preds.c
ghc/interpreter/prelude.h
ghc/interpreter/scc.c
ghc/interpreter/static.c
ghc/interpreter/stg.c
ghc/interpreter/stgSubst.c
ghc/interpreter/storage.c
ghc/interpreter/storage.h
ghc/interpreter/subst.c
ghc/interpreter/subst.h
ghc/interpreter/timer.c
ghc/interpreter/translate.c
ghc/interpreter/type.c

index 07af3ab..b5c074a 100644 (file)
@@ -1,6 +1,6 @@
 
 # ----------------------------------------------------------------------------- #
-# $Id: Makefile,v 1.3 1999/01/14 18:08:26 sewardj Exp $                        #
+# $Id: Makefile,v 1.4 1999/02/03 17:08:25 sewardj Exp $                        #
 # ----------------------------------------------------------------------------- #
 
 TOP = ../..
@@ -13,21 +13,26 @@ RTS_DIR = $(TOP)/ghc/rts
 # interpreter and relevant .a/.so files                                 #
 # --------------------------------------------------------------------- #
 
+YACC = bison -y
+%.c: %.y
+       -$(YACC) $<
+       mv y.tab.c $@
+
+
 HS_SRCS =
 
-C_SRCS = \
-  charset.c codegen.c compiler.c connect.c derive.c desugar.c \
-  dynamic.c free.c hugs.c input.c interface.c lift.c link.c \
-  machdep.c modules.c optimise.c output.c pat.c pmc.c pp.c static.c \
-  stg.c stgSubst.c storage.c subst.c translate.c type.c
+Y_SRCS = parser.y
+C_SRCS = link.c type.c static.c storage.c derive.c input.c compiler.c subst.c \
+     translate.c codegen.c lift.c free.c stgSubst.c optimise.c output.c   \
+     hugs.c dynamic.c stg.c
 
-SRC_CC_OPTS = -g -I$(GHC_DIR)/includes -D__HUGS__ -Wall -Wno-unused
+SRC_CC_OPTS = -g -I$(GHC_DIR)/includes -I$(GHC_DIR)/rts -D__HUGS__ -Wall -Wno-unused
 
 GHC_LIBS_NEEDED = $(TOP)/ghc/rts/libHSrts.a $(TOP)/ghc/rts/gmp/libgmp.a
 GHC_DYN_CBITS_DIR = $(TOP)/ghc/lib/std/cbits
 GHC_DYN_CBITS = $(GHC_DYN_CBITS_DIR)/libHS_cbits.so
 
-all :: $(GHC_LIBS_NEEDED) $(GHC_DYN_CBITS) hugs Prelude.hs
+all :: parser.c $(GHC_LIBS_NEEDED) $(GHC_DYN_CBITS) hugs Prelude.hs
 
 hugs: $(C_OBJS)
        $(CC) -rdynamic -o $@ $(CC_OPTS) $^ $(GHC_LIBS_NEEDED) -lbfd -liberty -ldl -lm
@@ -41,7 +46,6 @@ $(TOP)/ghc/rts/libHSrts.a:
 $(TOP)/ghc/rts/gmp/libgmp.a:
        (cd $(TOP)/ghc/rts/gmp ; make clean ; make)
 
-
 # --------------------------------------------------------------------- #
 # Prelude                                                               #
 # --------------------------------------------------------------------- #
@@ -153,6 +157,7 @@ checkrun: all
 CLEAN_FILES += hugs libHS_cbits.so $(GHC_DYN_CBITS) $(GHC_DYN_CBITS_DIR)/*.o 
 CLEAN_FILES += $(TOP)/ghc/rts/libHSrts.a $(TOP)/ghc/rts/*.o
 CLEAN_FILES += $(TOP)/ghc/rts/gmp/libgmp.a  $(TOP)/ghc/rts/gmp/*.o $(TOP)/ghc/rts/gmp/*/*.o
+CLEAN_FILES += parser.c
 
 INSTALL_LIBEXECS = hugs
 
index 9bc719e..f396cdd 100644 (file)
@@ -1,4 +1,4 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Code generator
  *
@@ -7,20 +7,18 @@
  * Hugs version 1.4, December 1997
  *
  * $RCSfile: codegen.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:21:59 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:25 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
 #include "storage.h"
+#include "backend.h"
 #include "connect.h"
 #include "errors.h"
-#include "stg.h"
 #include "Assembler.h"
-#include "lift.h"
 #include "link.h"
-#include "pp.h"
-#include "codegen.h"
+
 
 /* --------------------------------------------------------------------------
  * Local function prototypes:
@@ -193,7 +191,7 @@ static AsmBCO cgAlts( AsmSp root, AsmSp sp, List alts )
                 setPos(hd(vs),asmUnbox(bco,boxingConRep(con)));
             } else {
                 asmBeginUnpack(bco);
-                map1Proc(cgBind,bco,reverse(vs));
+                map1Proc(cgBind,bco,rev(vs));
                 asmEndUnpack(bco);
             }
             cgExpr(bco,root,body);
@@ -237,7 +235,7 @@ static AsmBCO cgLambda( StgExpr e )
     AsmBCO bco = asmBeginBCO();
 
     AsmSp root = asmBeginArgCheck(bco);
-    map1Proc(cgBind,bco,reverse(stgLambdaArgs(e)));
+    map1Proc(cgBind,bco,rev(stgLambdaArgs(e)));
     asmEndArgCheck(bco,root);
 
     /* ppStgExpr(e); */
@@ -296,7 +294,7 @@ static Void cgExpr( AsmBCO bco, AsmSp root, StgExpr e )
 
                 /* No need to use return address or to Slide */
                 AsmSp beginPrim = asmBeginPrim(bco);
-                map1Proc(pushAtom,bco,reverse(stgPrimArgs(scrut)));
+                map1Proc(pushAtom,bco,rev(stgPrimArgs(scrut)));
                 asmEndPrim(bco,(AsmPrim*)name(stgPrimOp(scrut)).primop,beginPrim);
 
                 for(; nonNull(alts); alts=tl(alts)) {
@@ -304,7 +302,7 @@ static Void cgExpr( AsmBCO bco, AsmSp root, StgExpr e )
                     List    pats = stgPrimAltPats(alt);
                     StgExpr body = stgPrimAltBody(alt);
                     AsmSp altBegin = asmBeginAlt(bco);
-                    map1Proc(cgBind,bco,reverse(pats));
+                    map1Proc(cgBind,bco,rev(pats));
                     testPrimPats(bco,root,pats,body);
                     asmEndAlt(bco,altBegin);
                 }
@@ -343,7 +341,7 @@ static Void cgExpr( AsmBCO bco, AsmSp root, StgExpr e )
     case STGAPP: /* Tail call */
         {
             AsmSp env = asmBeginEnter(bco);
-            map1Proc(pushAtom,bco,reverse(stgAppArgs(e)));
+            map1Proc(pushAtom,bco,rev(stgAppArgs(e)));
             pushAtom(bco,stgAppFun(e));
             asmEndEnter(bco,env,root);
             break;
@@ -378,7 +376,7 @@ static Void cgExpr( AsmBCO bco, AsmSp root, StgExpr e )
     case STGPRIM: /* Tail call again */
         {
             AsmSp beginPrim = asmBeginPrim(bco);
-            map1Proc(pushAtom,bco,reverse(stgPrimArgs(e)));
+            map1Proc(pushAtom,bco,rev(stgPrimArgs(e)));
             asmEndPrim(bco,(AsmPrim*)name(e).primop,beginPrim);
             /* map1Proc(cgBind,bco,rs_vars); */
             assert(0); /* asmReturn_retty(); */
@@ -435,7 +433,7 @@ static Void build( AsmBCO bco, StgVar v )
                 doNothing();  /* already done in alloc */
             } else {
                 AsmSp start = asmBeginPack(bco);
-                map1Proc(pushAtom,bco,reverse(args));
+                map1Proc(pushAtom,bco,rev(args));
                 asmEndPack(bco,getPos(v),start,stgConInfo(con));
             }
             return;
@@ -451,12 +449,12 @@ static Void build( AsmBCO bco, StgVar v )
                 && whatIs(stgVarBody(fun)) == LAMBDA 
                 && length(stgLambdaArgs(stgVarBody(fun))) > length(args)) {
                 AsmSp  start = asmBeginMkPAP(bco);
-                map1Proc(pushAtom,bco,reverse(args));
+                map1Proc(pushAtom,bco,rev(args));
                 pushAtom(bco,fun);
                 asmEndMkPAP(bco,getPos(v),start); /* optimisation */
             } else {
                 AsmSp  start = asmBeginMkAP(bco);
-                map1Proc(pushAtom,bco,reverse(args));
+                map1Proc(pushAtom,bco,rev(args));
                 pushAtom(bco,fun);
                 asmEndMkAP(bco,getPos(v),start);
             }
@@ -575,7 +573,7 @@ static void endTop( StgVar v )
             /* ToDo: merge this code with cgLambda */
             AsmBCO bco = (AsmBCO)getObj(v);
             AsmSp root = asmBeginArgCheck(bco);
-            map1Proc(cgBind,bco,reverse(stgLambdaArgs(rhs)));
+            map1Proc(cgBind,bco,rev(stgLambdaArgs(rhs)));
             asmEndArgCheck(bco,root);
             
             cgExpr(bco,root,stgLambdaBody(rhs));
index 80753ba..d709554 100644 (file)
@@ -1,13 +1,14 @@
 /* --------------------------------------------------------------------------
  * Interpreter command structure
  *
- * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
- * All rights reserved. See NOTICE for details and conditions of use etc...
- * Hugs version 1.4, December 1997
+ * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
+ * Haskell Group 1994-99, and is distributed as Open Source software
+ * under the Artistic License; see the file "Artistic" that is included
+ * in the distribution for details.
  *
  * $RCSfile: command.h,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:01 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:26 $
  * ------------------------------------------------------------------------*/
 
 typedef Int Command;
@@ -37,7 +38,6 @@ extern Command readCommand Args((struct cmd *, Char, Char));
 #define INFO    15
 #define COLLECT 16
 #define SETMODULE 17
-#define SHOWVERSION 18
-#define NOCMD   19
+#define NOCMD   18
 
 /*-------------------------------------------------------------------------*/
index 3ca136f..cc9b536 100644 (file)
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * This is the Hugs compiler, handling translation of typechecked code to
  * `kernel' language, elimination of pattern matching and translation to
  * super combinators (lambda lifting).
  *
- * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
- * All rights reserved. See NOTICE for details and conditions of use etc...
- * Hugs version 1.4, December 1997
+ * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
+ * Haskell Group 1994-99, and is distributed as Open Source software
+ * under the Artistic License; see the file "Artistic" that is included
+ * in the distribution for details.
  *
  * $RCSfile: compiler.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:01 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:26 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
 #include "storage.h"
+#include "backend.h"
 #include "connect.h"
-#include "input.h"
-#include "compiler.h"
-#include "hugs.h"  /* for target */
 #include "errors.h"
+#include "Rts.h"                       /* for rts_eval and related stuff   */
+#include "RtsAPI.h"                    /* for rts_eval and related stuff   */
+#include "Schedule.h"
+#include "link.h"
 
-#include "desugar.h"
-#include "pmc.h"
-
-#include "optimise.h"
-
-#include "Rts.h"    /* for rts_eval and related stuff */
-#include "RtsAPI.h" /* for rts_eval and related stuff */
+/*#define DEBUG_SHOWSC*/               /* Must also be set in output.c     */
 
-Name currentName;                      /* Top level name being processed   */
+Addr inputCode;                        /* Addr of compiled code for expr   */
+static Name currentName;               /* Top level name being processed   */
 #if DEBUG_CODE
-Bool   debugCode     = FALSE;           /* TRUE => print G-code to screen  */
+Bool   debugCode     = FALSE;          /* TRUE => print G-code to screen   */
 #endif
 
+
+
 /* --------------------------------------------------------------------------
  * Local function prototypes:
  * ------------------------------------------------------------------------*/
 
-static List local addGlobals( List binds );
+static Cell local translate             Args((Cell));
+static Void local transPair             Args((Pair));
+static Void local transTriple           Args((Triple));
+static Void local transAlt              Args((Cell));
+static Void local transCase             Args((Cell));
+static List local transBinds            Args((List));
+static Cell local transRhs              Args((Cell));
+static Cell local mkConsList            Args((List));
+static Cell local expandLetrec          Args((Cell));
+static Cell local transComp             Args((Cell,List,Cell));
+static Cell local transDo               Args((Cell,Cell,List));
+static Cell local transConFlds          Args((Cell,List));
+static Cell local transUpdFlds          Args((Cell,List,List));
+
+static Cell local refutePat             Args((Cell));
+static Cell local refutePatAp           Args((Cell));
+static Cell local matchPat              Args((Cell));
+static List local remPat                Args((Cell,Cell,List));
+static List local remPat1               Args((Cell,Cell,List));
+
+static Cell local pmcTerm               Args((Int,List,Cell));
+static Cell local pmcPair               Args((Int,List,Pair));
+static Cell local pmcTriple             Args((Int,List,Triple));
+static Cell local pmcVar                Args((List,Text));
+static Void local pmcLetrec             Args((Int,List,Pair));
+static Cell local pmcVarDef             Args((Int,List,List));
+static Void local pmcFunDef             Args((Int,List,Triple));
+static List local altsMatch             Args((Int,Int,List,List));
+static Cell local match                 Args((Int,List));
+static Cell local joinMas               Args((Int,List));
+static Bool local canFail               Args((Cell));
+static List local addConTable           Args((Cell,Cell,List));
+static Void local advance               Args((Int,Int,Cell));
+static Bool local emptyMatch            Args((Cell));
+static Cell local maDiscr               Args((Cell));
+static Bool local isNumDiscr            Args((Cell));
+static Bool local eqNumDiscr            Args((Cell,Cell));
+#if TREX
+static Bool local isExtDiscr            Args((Cell));
+static Bool local eqExtDiscr            Args((Cell,Cell));
+#endif
+
+static Cell local lift                  Args((Int,List,Cell));
+static Void local liftPair              Args((Int,List,Pair));
+static Void local liftTriple            Args((Int,List,Triple));
+static Void local liftAlt               Args((Int,List,Cell));
+static Void local liftNumcase           Args((Int,List,Triple));
+static Cell local liftVar               Args((List,Cell));
+static Cell local liftLetrec            Args((Int,List,Cell));
+static Void local liftFundef            Args((Int,List,Triple));
+static Void local solve                 Args((List));
+
+static Cell local preComp               Args((Cell));
+static Cell local preCompPair           Args((Pair));
+static Cell local preCompTriple         Args((Triple));
+static Void local preCompCase           Args((Pair));
+static Cell local preCompOffset         Args((Int));
+
 static Void local compileGlobalFunction Args((Pair));
 static Void local compileGenFunction    Args((Name));
 static Name local compileSelFunction    Args((Pair));
+static Void local newGlobalFunction     Args((Name,Int,List,Int,Cell));
 
 /* --------------------------------------------------------------------------
- * STG stuff
+ * Translation:    Convert input expressions into a less complex language
+ *                 of terms using only LETREC, AP, constants and vars.
+ *                 Also remove pattern definitions on lhs of eqns.
+ * ------------------------------------------------------------------------*/
+
+static Cell local translate(e)         /* Translate expression:            */
+Cell e; {
+    switch (whatIs(e)) {
+        case LETREC     : snd(snd(e)) = translate(snd(snd(e)));
+                          return expandLetrec(e);
+
+        case COND       : transTriple(snd(e));
+                          return e;
+
+        case AP         : fst(e) = translate(fst(e));
+
+                          if (fst(e)==nameId || fst(e)==nameInd)
+                              return translate(snd(e));
+#if EVAL_INSTANCES
+                          if (fst(e)==nameStrict)
+                              return nameIStrict;
+                          if (fst(e)==nameSeq)
+                              return nameISeq;
+#endif
+                          if (isName(fst(e)) &&
+                              isMfun(fst(e)) &&
+                              mfunOf(fst(e))==0)
+                              return translate(snd(e));
+
+                          snd(e) = translate(snd(e));
+                          return e;
+
+#if BIGNUMS
+        case POSNUM     :
+        case ZERONUM    :
+        case NEGNUM     : return e;
+#endif
+        case NAME       : if (e==nameOtherwise)
+                              return nameTrue;
+                          if (isCfun(e)) {
+                              if (isName(name(e).defn))
+                                  return name(e).defn;
+                              if (isPair(name(e).defn))
+                                  return snd(name(e).defn);
+                          }
+                          return e;
+
+#if TREX
+        case RECSEL     : return nameRecSel;
+
+        case EXT        :
+#endif
+        case TUPLE      :
+        case VAROPCELL  :
+        case VARIDCELL  :
+        case DICTVAR    :
+        case INTCELL    :
+        case FLOATCELL  :
+        case STRCELL    :
+        case CHARCELL   : return e;
+
+        case FINLIST    : mapOver(translate,snd(e));
+                          return mkConsList(snd(e));
+
+        case DOCOMP     : {   Cell m = translate(fst(snd(e)));
+                              Cell r = translate(fst(snd(snd(e))));
+                              return transDo(m,r,snd(snd(snd(e))));
+                          }
+
+        case MONADCOMP  : {   Cell m  = translate(fst(snd(e)));
+                              Cell r  = translate(fst(snd(snd(e))));
+                              Cell qs = snd(snd(snd(e)));
+                              if (m == nameListMonad)
+                                  return transComp(r,qs,nameNil);
+                              else {
+#if MONAD_COMPS
+                                  r = ap(ap(nameReturn,m),r);
+                                  return transDo(m,r,qs);
+#else
+                                  internal("translate: monad comps");
+#endif
+                              }
+                          }
+
+        case CONFLDS    : return transConFlds(fst(snd(e)),snd(snd(e)));
+
+        case UPDFLDS    : return transUpdFlds(fst3(snd(e)),
+                                              snd3(snd(e)),
+                                              thd3(snd(e)));
+
+        case CASE       : {   Cell nv = inventVar();
+                              mapProc(transCase,snd(snd(e)));
+                              return ap(LETREC,
+                                        pair(singleton(pair(nv,snd(snd(e)))),
+                                             ap(nv,translate(fst(snd(e))))));
+                          }
+
+        case LAMBDA     : {   Cell nv = inventVar();
+                              transAlt(snd(e));
+                              return ap(LETREC,
+                                        pair(singleton(pair(
+                                                        nv,
+                                                        singleton(snd(e)))),
+                                             nv));
+                          }
+
+        default         : internal("translate");
+    }
+    return e;
+}
+
+static Void local transPair(pr)        /* Translate each component in a    */
+Pair pr; {                             /* pair of expressions.             */
+    fst(pr) = translate(fst(pr));
+    snd(pr) = translate(snd(pr));
+}
+
+static Void local transTriple(tr)      /* Translate each component in a    */
+Triple tr; {                           /* triple of expressions.           */
+    fst3(tr) = translate(fst3(tr));
+    snd3(tr) = translate(snd3(tr));
+    thd3(tr) = translate(thd3(tr));
+}
+
+static Void local transAlt(e)          /* Translate alt:                   */
+Cell e; {                              /* ([Pat], Rhs) ==> ([Pat], Rhs')   */
+    snd(e) = transRhs(snd(e));
+}
+
+static Void local transCase(c)         /* Translate case:                  */
+Cell c; {                              /* (Pat, Rhs) ==> ([Pat], Rhs')     */
+    fst(c) = singleton(fst(c));
+    snd(c) = transRhs(snd(c));
+}
+
+static List local transBinds(bs)        /* Translate list of bindings:     */
+List bs; {                              /* eliminating pattern matching on */
+    List newBinds = NIL;                /* lhs of bindings.                */
+    for (; nonNull(bs); bs=tl(bs)) {
+        if (isVar(fst(hd(bs)))) {
+            mapProc(transAlt,snd(hd(bs)));
+            newBinds = cons(hd(bs),newBinds);
+        }
+        else
+            newBinds = remPat(fst(snd(hd(bs))),
+                              snd(snd(hd(bs)))=transRhs(snd(snd(hd(bs)))),
+                              newBinds);
+    }
+    return newBinds;
+}
+
+static Cell local transRhs(rhs)        /* Translate rhs: removing line nos */
+Cell rhs; {
+    switch (whatIs(rhs)) {
+        case LETREC  : snd(snd(rhs)) = transRhs(snd(snd(rhs)));
+                       return expandLetrec(rhs);
+
+        case GUARDED : mapOver(snd,snd(rhs));       /* discard line number */
+                       mapProc(transPair,snd(rhs));
+                       return rhs;
+
+        default      : return translate(snd(rhs));  /* discard line number */
+    }
+}
+
+static Cell local mkConsList(es)       /* Construct expression for list es */
+List es; {                             /* using nameNil and nameCons       */
+    if (isNull(es))
+        return nameNil;
+    else
+        return ap(ap(nameCons,hd(es)),mkConsList(tl(es)));
+}
+
+static Cell local expandLetrec(root)   /* translate LETREC with list of    */
+Cell root; {                           /* groups of bindings (from depend. */
+    Cell e   = snd(snd(root));         /* analysis) to use nested LETRECs  */
+    List bss = fst(snd(root));
+    Cell temp;
+
+    if (isNull(bss))                   /* should never happen, but just in */
+        return e;                      /* case:  LETREC [] IN e  ==>  e    */
+
+    mapOver(transBinds,bss);           /* translate each group of bindings */
+
+    for (temp=root; nonNull(tl(bss)); bss=tl(bss)) {
+        fst(snd(temp)) = hd(bss);
+        snd(snd(temp)) = ap(LETREC,pair(NIL,e));
+        temp           = snd(snd(temp));
+    }
+    fst(snd(temp)) = hd(bss);
+
+    return root;
+}
+
+/* --------------------------------------------------------------------------
+ * Translation of list comprehensions is based on the description in
+ * `The Implementation of Functional Programming Languages':
+ *
+ * [ e | qs ] ++ l            => transComp e qs l
+ * transComp e []           l => e : l
+ * transComp e ((p<-xs):qs) l => LETREC _h []      = l
+ *                                      _h (p:_xs) = transComp e qs (_h _xs)
+ *                                      _h (_:_xs) = _h _xs --if p !failFree
+ *                               IN _h xs
+ * transComp e (b:qs)       l => if b then transComp e qs l else l
+ * transComp e (decls:qs)   l => LETREC decls IN transComp e qs l
+ * ------------------------------------------------------------------------*/
+
+static Cell local transComp(e,qs,l)    /* Translate [e | qs] ++ l          */
+Cell e;
+List qs;
+Cell l; {
+    if (nonNull(qs)) {
+        Cell q   = hd(qs);
+        Cell qs1 = tl(qs);
+
+        switch (fst(q)) {
+            case FROMQUAL : {   Cell ld    = NIL;
+                                Cell hVar  = inventVar();
+                                Cell xsVar = inventVar();
+
+                                if (!failFree(fst(snd(q))))
+                                    ld = cons(pair(singleton(
+                                                    ap(ap(nameCons,
+                                                          WILDCARD),
+                                                          xsVar)),
+                                                   ap(hVar,xsVar)),
+                                              ld);
+
+                                ld = cons(pair(singleton(
+                                                ap(ap(nameCons,
+                                                      fst(snd(q))),
+                                                      xsVar)),
+                                               transComp(e,
+                                                         qs1,
+                                                         ap(hVar,xsVar))),
+                                          ld);
+                                ld = cons(pair(singleton(nameNil),
+                                               l),
+                                          ld);
+
+                                return ap(LETREC,
+                                          pair(singleton(pair(hVar,
+                                                              ld)),
+                                               ap(hVar,
+                                                  translate(snd(snd(q))))));
+                            }
+
+            case QWHERE   : return
+                                expandLetrec(ap(LETREC,
+                                                pair(snd(q),
+                                                     transComp(e,qs1,l))));
+
+            case BOOLQUAL : return ap(COND,
+                                      triple(translate(snd(q)),
+                                             transComp(e,qs1,l),
+                                             l));
+        }
+    }
+
+    return ap(ap(nameCons,e),l);
+}
+
+/* --------------------------------------------------------------------------
+ * Translation of monad comprehensions written using do-notation:
+ *
+ * do { e }               =>  e
+ * do { p <- exp; qs }    =>  LETREC _h p = do { qs }
+ *                                   _h _ = fail m "match fails"
+ *                            IN bind m exp _h
+ * do { LET decls; qs }   =>  LETREC decls IN do { qs }
+ * do { IF guard; qs }    =>  if guard then do { qs } else fail m  "guard fails"
+ * do { e; qs }           =>  LETREC _h _ = [ e | qs ] in bind m exp _h
+ *
+ * where m :: Monad f
+ * ------------------------------------------------------------------------*/
+
+static Cell local transDo(m,e,qs)       /* Translate do { qs ; e }         */
+Cell m;
+Cell e;
+List qs; {
+    if (nonNull(qs)) {
+        Cell q   = hd(qs);
+        Cell qs1 = tl(qs);
+
+        switch (fst(q)) {
+            case FROMQUAL : {   Cell ld   = NIL;
+                                Cell hVar = inventVar();
+
+                                if (!failFree(fst(snd(q)))) {
+                                    Cell str = mkStr(findText("match fails"));
+                                    ld = cons(pair(singleton(WILDCARD),
+                                                   ap2(nameMFail,m,str)),
+                                              ld);
+                                }
+
+                                ld = cons(pair(singleton(fst(snd(q))),
+                                               transDo(m,e,qs1)),
+                                          ld);
+
+                                return ap(LETREC,
+                                          pair(singleton(pair(hVar,ld)),
+                                               ap(ap(ap(nameBind,
+                                                        m),
+                                                     translate(snd(snd(q)))),
+                                                  hVar)));
+                            }
+
+            case DOQUAL :   {   Cell hVar = inventVar();
+                                Cell ld   = cons(pair(singleton(WILDCARD),
+                                                      transDo(m,e,qs1)),
+                                                 NIL);
+                                return ap(LETREC,
+                                          pair(singleton(pair(hVar,ld)),
+                                               ap(ap(ap(nameBind,
+                                                        m),
+                                                     translate(snd(q))),
+                                                  hVar)));
+                            }
+
+            case QWHERE   : return
+                                expandLetrec(ap(LETREC,
+                                                pair(snd(q),
+                                                     transDo(m,e,qs1))));
+
+            case BOOLQUAL : return
+                                ap(COND,
+                                   triple(translate(snd(q)),
+                                          transDo(m,e,qs1),
+                                          ap2(nameMFail,m,
+                                            mkStr(findText("guard fails")))));
+        }
+    }
+    return e;
+}
+
+/* --------------------------------------------------------------------------
+ * Translation of named field construction and update:
+ *
+ * Construction is implemented using the following transformation:
+ *
+ *   C{x1=e1, ..., xn=en} =  C v1 ... vm
+ * where:
+ *   vi = e1,        if the ith component of C is labelled with x1
+ *       ...
+ *      = en,        if the ith component of C is labelled with xn
+ *      = undefined, otherwise
+ *
+ * Update is implemented using the following transformation:
+ *
+ *   e{x1=e1, ..., xn=en}
+ *      =  let nv (C a1 ... am) v1 ... vn = C a1' .. am'
+ *             nv (D b1 ... bk) v1 ... vn = D b1' .. bk
+ *             ...
+ *             nv _             v1 ... vn = error "failed update"
+ *         in nv e e1 ... en
+ * where:
+ *   nv, v1, ..., vn, a1, ..., am, b1, ..., bk, ... are new variables,
+ *   C,D,... = { K | K is a constr fun s.t. {x1,...,xn} subset of sels(K)}
+ * and:
+ *   ai' = v1,   if the ith component of C is labelled with x1
+ *       ...
+ *       = vn,   if the ith component of C is labelled with xn
+ *       = ai,   otherwise
+ *  etc...
+ *
+ * The error case may be omitted if C,D,... is an enumeration of all of the
+ * constructors for the datatype concerned.  Strictly speaking, error case
+ * isn't needed at all -- the only benefit of including it is that the user
+ * will get a "failed update" message rather than a cryptic {v354 ...}.
+ * So, for now, we'll go with the second option!
+ *
+ * For the time being, code for each update operation is generated
+ * independently of any other updates.  However, if updates are used
+ * frequently, then we might want to consider changing the implementation
+ * at a later stage to cache definitions of functions like nv above.  This
+ * would create a shared library of update functions, indexed by a set of
+ * constructors {C,D,...}.
+ * ------------------------------------------------------------------------*/
+
+static Cell local transConFlds(c,flds)  /* Translate C{flds}               */
+Name c;
+List flds; {
+    Cell e = c;
+    Int  m = name(c).arity;
+    Int  i;
+    for (i=m; i>0; i--)
+        e = ap(e,nameUndefined);
+    for (; nonNull(flds); flds=tl(flds)) {
+        Cell a = e;
+        for (i=m-sfunPos(fst(hd(flds)),c); i>0; i--)
+            a = fun(a);
+        arg(a) = translate(snd(hd(flds)));
+    }
+    return e;
+}
+
+static Cell local transUpdFlds(e,cs,flds)/* Translate e{flds}              */
+Cell e;                                 /* (cs is corresp list of constrs) */
+List cs;
+List flds; {
+    Cell nv   = inventVar();
+    Cell body = ap(nv,translate(e));
+    List fs   = flds;
+    List args = NIL;
+    List alts = NIL;
+
+    for (; nonNull(fs); fs=tl(fs)) {    /* body = nv e1 ... en             */
+        Cell b = hd(fs);                /* args = [v1, ..., vn]            */
+        body   = ap(body,translate(snd(b)));
+        args   = cons(inventVar(),args);
+    }
+
+    for (; nonNull(cs); cs=tl(cs)) {    /* Loop through constructors to    */
+        Cell c   = hd(cs);              /* build up list of alts.          */
+        Cell pat = c;
+        Cell rhs = c;
+        List as  = args;
+        Int  m   = name(c).arity;
+        Int  i;
+
+        for (i=m; i>0; i--) {           /* pat  = C a1 ... am              */
+            Cell a = inventVar();       /* rhs  = C a1 ... am              */
+            pat    = ap(pat,a);
+            rhs    = ap(rhs,a);
+        }
+
+        for (fs=flds; nonNull(fs); fs=tl(fs), as=tl(as)) {
+            Name s = fst(hd(fs));       /* Replace approp ai in rhs with   */
+            Cell r = rhs;               /* vars from [v1,...,vn]           */
+            for (i=m-sfunPos(s,c); i>0; i--)
+                r = fun(r);
+            arg(r) = hd(as);
+        }
+
+        alts     = cons(pair(cons(pat,args),rhs),alts);
+    }
+    return ap(LETREC,pair(singleton(pair(nv,alts)),body));
+}
+
+/* --------------------------------------------------------------------------
+ * Elimination of pattern bindings:
+ *
+ * The following code adopts the definition of failure free patterns as given
+ * in the Haskell 1.3 report; the term "irrefutable" is also used there for
+ * a subset of the failure free patterns described here, but has no useful
+ * role in this implementation.  Basically speaking, the failure free patterns
+ * are:         variable, wildcard, ~apat
+ *              var@apat,               if apat is failure free
+ *              C apat1 ... apatn       if C is a product constructor
+ *                                      (i.e. an only constructor) and
+ *                                      apat1,...,apatn are failure free
+ * Note that the last case automatically covers the case where C comes from
+ * a newtype construction.
+ * ------------------------------------------------------------------------*/
+
+Bool failFree(pat)                /* is pattern failure free? (do we need  */
+Cell pat; {                       /* a conformality check?)                */
+    Cell c = getHead(pat);
+
+    switch (whatIs(c)) {
+        case ASPAT     : return failFree(snd(snd(pat)));
+
+        case NAME      : if (!isCfun(c) || cfunOf(c)!=0)
+                             return FALSE;
+                         /*intentional fall-thru*/
+        case TUPLE     : for (; isAp(pat); pat=fun(pat))
+                             if (!failFree(arg(pat)))
+                                return FALSE;
+                         /*intentional fall-thru*/
+        case LAZYPAT   :
+        case VAROPCELL :
+        case VARIDCELL :
+        case DICTVAR   :
+        case WILDCARD  : return TRUE;
+
+#if TREX
+        case EXT       : return failFree(extField(pat)) &&
+                                failFree(extRow(pat));
+#endif
+
+        case CONFLDS   : if (cfunOf(fst(snd(c)))==0) {
+                             List fs = snd(snd(c));
+                             for (; nonNull(fs); fs=tl(fs))
+                                 if (!failFree(snd(hd(fs))))
+                                     return FALSE;
+                             return TRUE;
+                         }
+                         /*intentional fall-thru*/
+        default        : return FALSE;
+    }
+}
+
+static Cell local refutePat(pat)  /* find pattern to refute in conformality*/
+Cell pat; {                       /* test with pat.                        */
+                                  /* e.g. refPat  (x:y) == (_:_)           */
+                                  /*      refPat ~(x:y) == _      etc..    */
+
+    switch (whatIs(pat)) {
+        case ASPAT     : return refutePat(snd(snd(pat)));
+
+        case FINLIST   : {   Cell ys = snd(pat);
+                             Cell xs = NIL;
+                             for (; nonNull(ys); ys=tl(ys))
+                                 xs = ap(ap(nameCons,refutePat(hd(ys))),xs);
+                             return revOnto(xs,nameNil);
+                         }
+
+        case CONFLDS   : {   Cell ps = NIL;
+                             Cell fs = snd(snd(pat));
+                             for (; nonNull(fs); fs=tl(fs)) {
+                                 Cell p = refutePat(snd(hd(fs)));
+                                 ps     = cons(pair(fst(hd(fs)),p),ps);
+                             }
+                             return pair(CONFLDS,pair(fst(snd(pat)),rev(ps)));
+                         }
+
+        case VAROPCELL :
+        case VARIDCELL :
+        case DICTVAR   :
+        case WILDCARD  :
+        case LAZYPAT   : return WILDCARD;
+
+        case STRCELL   :
+        case CHARCELL  :
+#if NPLUSK
+        case ADDPAT    :
+#endif
+        case TUPLE     :
+        case NAME      : return pat;
+
+        case AP        : return refutePatAp(pat);
+
+        default        : internal("refutePat");
+                         return NIL; /*NOTREACHED*/
+    }
+}
+
+static Cell local refutePatAp(p)  /* find pattern to refute in conformality*/
+Cell p; {
+    Cell h = getHead(p);
+    if (h==nameFromInt || h==nameFromInteger || h==nameFromDouble)
+        return p;
+#if NPLUSK
+    else if (whatIs(h)==ADDPAT)
+        return ap(fun(p),refutePat(arg(p)));
+#endif
+#if TREX
+    else if (isExt(h)) {
+        Cell pf = refutePat(extField(p));
+        Cell pr = refutePat(extRow(p));
+        return ap(ap(fun(fun(p)),pf),pr);
+    }
+#endif
+    else {
+        List as = getArgs(p);
+        mapOver(refutePat,as);
+        return applyToArgs(h,as);
+    }
+}
+
+static Cell local matchPat(pat) /* find pattern to match against           */
+Cell pat; {                     /* replaces parts of pattern that do not   */
+                                /* include variables with wildcards        */
+    switch (whatIs(pat)) {
+        case ASPAT     : {   Cell p = matchPat(snd(snd(pat)));
+                             return (p==WILDCARD) ? fst(snd(pat))
+                                                  : ap(ASPAT,
+                                                       pair(fst(snd(pat)),p));
+                         }
+
+        case FINLIST   : {   Cell ys = snd(pat);
+                             Cell xs = NIL;
+                             for (; nonNull(ys); ys=tl(ys))
+                                 xs = cons(matchPat(hd(ys)),xs);
+                             while (nonNull(xs) && hd(xs)==WILDCARD)
+                                 xs = tl(xs);
+                             for (ys=nameNil; nonNull(xs); xs=tl(xs))
+                                 ys = ap(ap(nameCons,hd(xs)),ys);
+                             return ys;
+                         }
+
+        case CONFLDS   : {   Cell ps   = NIL;
+                             Name c    = fst(snd(pat));
+                             Cell fs   = snd(snd(pat));
+                             Bool avar = FALSE;
+                             for (; nonNull(fs); fs=tl(fs)) {
+                                 Cell p = matchPat(snd(hd(fs)));
+                                 ps     = cons(pair(fst(hd(fs)),p),ps);
+                                 if (p!=WILDCARD)
+                                     avar = TRUE;
+                             }
+                             return avar ? pair(CONFLDS,pair(c,rev(ps)))
+                                         : WILDCARD;
+                         }
+
+        case VAROPCELL :
+        case VARIDCELL :
+        case DICTVAR   : return pat;
+
+        case LAZYPAT   : {   Cell p = matchPat(snd(pat));
+                             return (p==WILDCARD) ? WILDCARD : ap(LAZYPAT,p);
+                         }
+
+        case WILDCARD  :
+        case STRCELL   :
+        case CHARCELL  : return WILDCARD;
+
+        case TUPLE     :
+        case NAME      :
+        case AP        : {   Cell h = getHead(pat);
+                             if (h==nameFromInt     ||
+                                 h==nameFromInteger || h==nameFromDouble)
+                                 return WILDCARD;
+#if NPLUSK
+                             else if (whatIs(h)==ADDPAT)
+                                 return pat;
+#endif
+#if TREX
+                             else if (isExt(h)) {
+                                 Cell pf = matchPat(extField(pat));
+                                 Cell pr = matchPat(extRow(pat));
+                                 return (pf==WILDCARD && pr==WILDCARD)
+                                          ? WILDCARD
+                                          : ap(ap(fun(fun(pat)),pf),pr);
+                             }
+#endif
+                             else {
+                                 List args = NIL;
+                                 Bool avar = FALSE;
+                                 for (; isAp(pat); pat=fun(pat)) {
+                                     Cell p = matchPat(arg(pat));
+                                     if (p!=WILDCARD)
+                                         avar = TRUE;
+                                     args = cons(p,args);
+                                 }
+                                 return avar ? applyToArgs(pat,args)
+                                             : WILDCARD;
+                             }
+                         }
+
+        default        : internal("matchPat");
+                         return NIL; /*NOTREACHED*/
+    }
+}
+
+#define addEqn(v,val,lds)  cons(pair(v,singleton(pair(NIL,val))),lds)
+
+static List local remPat(pat,expr,lds)
+Cell pat;                         /* Produce list of definitions for eqn   */
+Cell expr;                        /* pat = expr, including a conformality  */
+List lds; {                       /* check if required.                    */
+
+    /* Conformality test (if required):
+     *   pat = expr  ==>    nv = LETREC confCheck nv@pat = nv
+     *                           IN confCheck expr
+     *                      remPat1(pat,nv,.....);
+     */
+
+    if (!failFree(pat)) {
+        Cell confVar = inventVar();
+        Cell nv      = inventVar();
+        Cell locfun  = pair(confVar,         /* confVar [([nv@refPat],nv)] */
+                            singleton(pair(singleton(ap(ASPAT,
+                                                        pair(nv,
+                                                             refutePat(pat)))),
+                                           nv)));
+
+        if (whatIs(expr)==GUARDED) {         /* A spanner ... special case */
+            lds  = addEqn(nv,expr,lds);      /* for guarded pattern binding*/
+            expr = nv;
+            nv   = inventVar();
+        }
+
+        if (whatIs(pat)==ASPAT) {            /* avoid using new variable if*/
+            nv   = fst(snd(pat));            /* a variable is already given*/
+            pat  = snd(snd(pat));            /* by an as-pattern           */
+        }
+
+        lds = addEqn(nv,                                /* nv =            */
+                     ap(LETREC,pair(singleton(locfun),  /* LETREC [locfun] */
+                                    ap(confVar,expr))), /* IN confVar expr */
+                     lds);
+
+        return remPat1(matchPat(pat),nv,lds);
+    }
+
+    return remPat1(matchPat(pat),expr,lds);
+}
+
+static List local remPat1(pat,expr,lds)
+Cell pat;                         /* Add definitions for: pat = expr to    */
+Cell expr;                        /* list of local definitions in lds.     */
+List lds; {
+    Cell c = getHead(pat);
+
+    switch (whatIs(c)) {
+        case WILDCARD  :
+        case STRCELL   :
+        case CHARCELL  : break;
+
+        case ASPAT     : return remPat1(snd(snd(pat)),     /* v@pat = expr */
+                                        fst(snd(pat)),
+                                        addEqn(fst(snd(pat)),expr,lds));
+
+        case LAZYPAT   : {   Cell nv;
+
+                             if (isVar(expr) || isName(expr))
+                                 nv  = expr;
+                             else {
+                                 nv  = inventVar();
+                                 lds = addEqn(nv,expr,lds);
+                             }
+
+                             return remPat(snd(pat),nv,lds);
+                         }
+
+#if NPLUSK
+        case ADDPAT    : return remPat1(arg(pat),       /* n + k = expr */
+                                        ap(ap(ap(namePmSub,
+                                                 arg(fun(pat))),
+                                                 mkInt(snd(fun(fun(pat))))),
+                                                 expr),
+                                        lds);
+#endif
+
+        case FINLIST   : return remPat1(mkConsList(snd(pat)),expr,lds);
+
+        case CONFLDS   : {   Name h  = fst(snd(pat));
+                             Int  m  = name(h).arity;
+                             Cell p  = h;
+                             List fs = snd(snd(pat));
+                             Int  i  = m;
+                             while (0<i--)
+                                 p = ap(p,WILDCARD);
+                             for (; nonNull(fs); fs=tl(fs)) {
+                                 Cell r = p;
+                                 for (i=m-sfunPos(fst(hd(fs)),h); i>0; i--)
+                                     r = fun(r);
+                                 arg(r) = snd(hd(fs));
+                             }
+                             return remPat1(p,expr,lds);
+                         }
+
+        case DICTVAR   : /* shouldn't really occur */
+                         assert(0); /* so let's test for it then! ADR */
+        case VARIDCELL :
+        case VAROPCELL : return addEqn(pat,expr,lds);
+
+        case NAME      : if (c==nameFromInt || c==nameFromInteger
+                                            || c==nameFromDouble) {
+                             if (argCount==2)
+                                 arg(fun(pat)) = translate(arg(fun(pat)));
+                             break;
+                         }
+
+                         if (argCount==1 && isCfun(c)       /* for newtype */
+                             && cfunOf(c)==0 && name(c).defn==nameId)
+                             return remPat1(arg(pat),expr,lds);
+
+                         /* intentional fall-thru */
+        case TUPLE     : {   List ps = getArgs(pat);
+
+                             if (nonNull(ps)) {
+                                 Cell nv, sel;
+                                 Int  i;
+
+                                 if (isVar(expr) || isName(expr))
+                                     nv  = expr;
+                                 else {
+                                     nv  = inventVar();
+                                     lds = addEqn(nv,expr,lds);
+                                 }
+
+                                 sel = ap(ap(nameSel,c),nv);
+                                 for (i=1; nonNull(ps); ++i, ps=tl(ps))
+                                      lds = remPat1(hd(ps),
+                                                    ap(sel,mkInt(i)),
+                                                    lds);
+                             }
+                         }
+                         break;
+
+#if TREX
+        case EXT       : {   Cell nv = inventVar();
+                             arg(fun(fun(pat)))
+                                 = translate(arg(fun(fun(pat))));
+                             lds = addEqn(nv,
+                                          ap(ap(nameRecBrk,
+                                                arg(fun(fun(pat)))),
+                                             expr),
+                                          lds);
+                             lds = remPat1(extField(pat),ap(nameFst,nv),lds);
+                             lds = remPat1(extRow(pat),ap(nameSnd,nv),lds);
+                         }
+                         break;
+#endif
+
+        default        : internal("remPat1");
+                         break;
+    }
+    return lds;
+}
+
+/* --------------------------------------------------------------------------
+ * Eliminate pattern matching in function definitions -- pattern matching
+ * compiler:
+ *
+ * The original Gofer/Hugs pattern matching compiler was based on Wadler's
+ * algorithms described in `Implementation of functional programming
+ * languages'.  That should still provide a good starting point for anyone
+ * wanting to understand this part of the system.  However, the original
+ * algorithm has been generalized and restructured in order to implement
+ * new features added in Haskell 1.3.
+ *
+ * During the translation, in preparation for later stages of compilation,
+ * all local and bound variables are replaced by suitable offsets, and
+ * locally defined function symbols are given new names (which will
+ * eventually be their names when lifted to make top level definitions).
+ * ------------------------------------------------------------------------*/
+
+static Offset freeBegin; /* only variables with offset <= freeBegin are of */
+static List   freeVars;  /* interest as `free' variables                   */
+static List   freeFuns;  /* List of `free' local functions                 */
+
+static Cell local pmcTerm(co,sc,e)     /* apply pattern matching compiler  */
+Int  co;                               /* co = current offset              */
+List sc;                               /* sc = scope                       */
+Cell e;  {                             /* e  = expr to transform           */
+    switch (whatIs(e)) {
+        case GUARDED  : map2Over(pmcPair,co,sc,snd(e));
+                        break;
+
+        case LETREC   : pmcLetrec(co,sc,snd(e));
+                        break;
+
+        case VARIDCELL:
+        case VAROPCELL:
+        case DICTVAR  : return pmcVar(sc,textOf(e));
+
+        case COND     : return ap(COND,pmcTriple(co,sc,snd(e)));
+
+        case AP       : return pmcPair(co,sc,e);
+
+#if BIGNUMS
+        case POSNUM   :
+        case ZERONUM  :
+        case NEGNUM   :
+#endif
+#if NPLUSK
+        case ADDPAT   :
+#endif
+#if TREX
+        case EXT      :
+#endif
+        case TUPLE    :
+        case NAME     :
+        case CHARCELL :
+        case INTCELL  :
+        case FLOATCELL:
+        case STRCELL  : break;
+
+        default       : internal("pmcTerm");
+                        break;
+    }
+    return e;
+}
+
+static Cell local pmcPair(co,sc,pr)    /* apply pattern matching compiler  */
+Int  co;                               /* to a pair of exprs               */
+List sc;
+Pair pr; {
+    return pair(pmcTerm(co,sc,fst(pr)),
+                pmcTerm(co,sc,snd(pr)));
+}
+
+static Cell local pmcTriple(co,sc,tr)  /* apply pattern matching compiler  */
+Int    co;                             /* to a triple of exprs             */
+List   sc;
+Triple tr; {
+    return triple(pmcTerm(co,sc,fst3(tr)),
+                  pmcTerm(co,sc,snd3(tr)),
+                  pmcTerm(co,sc,thd3(tr)));
+}
+
+static Cell local pmcVar(sc,t)         /* find translation of variable     */
+List sc;                               /* in current scope                 */
+Text t; {
+    List xs;
+    Name n;
+
+    for (xs=sc; nonNull(xs); xs=tl(xs)) {
+        Cell x = hd(xs);
+        if (t==textOf(fst(x))) {
+            if (isOffset(snd(x))) {                  /* local variable ... */
+                if (snd(x)<=freeBegin && !cellIsMember(snd(x),freeVars))
+                    freeVars = cons(snd(x),freeVars);
+                return snd(x);
+            }
+            else {                                   /* local function ... */
+                if (!cellIsMember(snd(x),freeFuns))
+                    freeFuns = cons(snd(x),freeFuns);
+                return fst3(snd(x));
+            }
+        }
+    }
+
+    if (isNull(n=findName(t)))         /* Lookup global name - the only way*/
+        n = newName(t,currentName);    /* this (should be able to happen)  */
+                                       /* is with new global var introduced*/
+                                       /* after type check; e.g. remPat1   */
+    return n;
+}
+
+static Void local pmcLetrec(co,sc,e)   /* apply pattern matching compiler  */
+Int  co;                               /* to LETREC, splitting decls into  */
+List sc;                               /* two sections                     */
+Pair e; {
+    List fs = NIL;                     /* local function definitions       */
+    List vs = NIL;                     /* local variable definitions       */
+    List ds;
+
+    for (ds=fst(e); nonNull(ds); ds=tl(ds)) {      /* Split decls into two */
+        Cell v     = fst(hd(ds));
+        Int  arity = length(fst(hd(snd(hd(ds)))));
+
+        if (arity==0) {                            /* Variable declaration */
+            vs = cons(snd(hd(ds)),vs);
+            sc = cons(pair(v,mkOffset(++co)),sc);
+        }
+        else {                                     /* Function declaration */
+            fs = cons(triple(inventVar(),mkInt(arity),snd(hd(ds))),fs);
+            sc = cons(pair(v,hd(fs)),sc);
+        }
+    }
+    vs       = rev(vs);                /* Put declaration lists back in    */
+    fs       = rev(fs);                /* original order                   */
+    fst(e)   = pair(vs,fs);            /* Store declaration lists          */
+    map2Over(pmcVarDef,co,sc,vs);      /* Translate variable definitions   */
+    map2Proc(pmcFunDef,co,sc,fs);      /* Translate function definitions   */
+    snd(e)   = pmcTerm(co,sc,snd(e));  /* Translate LETREC body            */
+    freeFuns = diffList(freeFuns,fs);  /* Delete any `freeFuns' bound in fs*/
+}
+
+static Cell local pmcVarDef(co,sc,vd)  /* apply pattern matching compiler  */
+Int  co;                               /* to variable definition           */
+List sc;
+List vd; {                             /* vd :: [ ([], rhs) ]              */
+    Cell d = snd(hd(vd));
+    if (nonNull(tl(vd)) && canFail(d))
+        return ap(FATBAR,pair(pmcTerm(co,sc,d),
+                              pmcVarDef(co,sc,tl(vd))));
+    return pmcTerm(co,sc,d);
+}
+
+static Void local pmcFunDef(co,sc,fd)  /* apply pattern matching compiler  */
+Int    co;                             /* to function definition           */
+List   sc;
+Triple fd; {                           /* fd :: (Var, Arity, [Alt])        */
+    Offset saveFreeBegin = freeBegin;
+    List   saveFreeVars  = freeVars;
+    List   saveFreeFuns  = freeFuns;
+    Int    arity         = intOf(snd3(fd));
+    Cell   temp          = altsMatch(co+1,arity,sc,thd3(fd));
+    Cell   xs;
+
+    freeBegin = mkOffset(co);
+    freeVars  = NIL;
+    freeFuns  = NIL;
+    temp      = match(co+arity,temp);
+    thd3(fd)  = triple(freeVars,freeFuns,temp);
+
+    for (xs=freeVars; nonNull(xs); xs=tl(xs))
+        if (hd(xs)<=saveFreeBegin && !cellIsMember(hd(xs),saveFreeVars))
+            saveFreeVars = cons(hd(xs),saveFreeVars);
+
+    for (xs=freeFuns; nonNull(xs); xs=tl(xs))
+        if (!cellIsMember(hd(xs),saveFreeFuns))
+            saveFreeFuns = cons(hd(xs),saveFreeFuns);
+
+    freeBegin = saveFreeBegin;
+    freeVars  = saveFreeVars;
+    freeFuns  = saveFreeFuns;
+}
+
+/* ---------------------------------------------------------------------------
+ * Main part of pattern matching compiler: convert [Alt] to case constructs
+ *
+ * This section of Hugs has been almost completely rewritten to be more
+ * general, in particular, to allow pattern matching in orders other than the
+ * strictly left-to-right approach of the previous version.  This is needed
+ * for the implementation of the so-called Haskell 1.3 `record' syntax.
+ *
+ * At each stage, the different branches for the cases to be considered
+ * are represented by a list of values of type:
+ *   Match ::= { maPats :: [Pat],       patterns to match
+ *               maOffs :: [Offs],      offsets of corresponding values
+ *               maSc   :: Scope,       mapping from vars to offsets
+ *               maRhs  :: Rhs }        right hand side
+ * [Implementation uses nested pairs, ((pats,offs),(sc,rhs)).]
+ *
+ * The Scope component has type:
+ *   Scope  ::= [(Var,Expr)]
+ * and provides a mapping from variable names to offsets used in the matching
+ * process.
+ *
+ * Matches can be normalized by reducing them to a form in which the list
+ * of patterns is empty (in which case the match itself is described as an
+ * empty match), or in which the list is non-empty and the first pattern is
+ * one that requires either a CASE or NUMCASE (or EXTCASE) to decompose.
  * ------------------------------------------------------------------------*/
 
-#include "stg.h"
-#include "translate.h"
-#include "codegen.h"
+#define mkMatch(ps,os,sc,r)     pair(pair(ps,os),pair(sc,r))
+#define maPats(ma)              fst(fst(ma))
+#define maOffs(ma)              snd(fst(ma))
+#define maSc(ma)                fst(snd(ma))
+#define maRhs(ma)               snd(snd(ma))
+#define extSc(v,o,ma)           maSc(ma) = cons(pair(v,o),maSc(ma))
+
+static List local altsMatch(co,n,sc,as) /* Make a list of matches from list*/
+Int  co;                                /* of Alts, with initial offsets   */
+Int  n;                                 /* reverse (take n [co..])         */
+List sc;
+List as; {
+    List mas = NIL;
+    List us  = NIL;
+    for (; n>0; n--)
+        us = cons(mkOffset(co++),us);
+    for (; nonNull(as); as=tl(as))      /* Each Alt is ([Pat], Rhs)        */
+        mas = cons(mkMatch(fst(hd(as)),us,sc,snd(hd(as))),mas);
+    return rev(mas);
+}
+
+static Cell local match(co,mas) /* Generate case statement for Matches mas */
+Int  co;                        /* at current offset co                    */
+List mas; {                     /* N.B. Assumes nonNull(mas).              */
+    Cell srhs = NIL;            /* Rhs for selected matches                */
+    List smas = mas;            /* List of selected matches                */
+    mas       = tl(mas);
+    tl(smas)  = NIL;
+
+    if (emptyMatch(hd(smas))) {         /* The case for empty matches:     */
+        while (nonNull(mas) && emptyMatch(hd(mas))) {
+            List temp = tl(mas);
+            tl(mas)   = smas;
+            smas      = mas;
+            mas       = temp;
+        }
+        srhs = joinMas(co,rev(smas));
+    }
+    else {                              /* Non-empty match                 */
+        Int  o = offsetOf(hd(maOffs(hd(smas))));
+        Cell d = maDiscr(hd(smas));
+        if (isNumDiscr(d)) {            /* Numeric match                   */
+            Int  da = discrArity(d);
+            Cell d1 = pmcTerm(co,maSc(hd(smas)),d);
+            while (nonNull(mas) && !emptyMatch(hd(mas))
+                                && o==offsetOf(hd(maOffs(hd(mas))))
+                                && isNumDiscr(d=maDiscr(hd(mas)))
+                                && eqNumDiscr(d,d1)) {
+                List temp = tl(mas);
+                tl(mas)   = smas;
+                smas      = mas;
+                mas       = temp;
+            }
+            smas = rev(smas);
+            map2Proc(advance,co,da,smas);
+            srhs = ap(NUMCASE,triple(mkOffset(o),d1,match(co+da,smas)));
+        }
+#if TREX
+        else if (isExtDiscr(d)) {       /* Record match                    */
+            Int  da = discrArity(d);
+            Cell d1 = pmcTerm(co,maSc(hd(smas)),d);
+            while (nonNull(mas) && !emptyMatch(hd(mas))
+                                && o==offsetOf(hd(maOffs(hd(mas))))
+                                && isExtDiscr(d=maDiscr(hd(mas)))
+                                && eqExtDiscr(d,d1)) {
+                List temp = tl(mas);
+                tl(mas)   = smas;
+                smas      = mas;
+                mas       = temp;
+            }
+            smas = rev(smas);
+            map2Proc(advance,co,da,smas);
+            srhs = ap(EXTCASE,triple(mkOffset(o),d1,match(co+da,smas)));
+        }
+#endif
+        else {                          /* Constructor match               */
+            List tab = addConTable(d,hd(smas),NIL);
+            Int  da;
+            while (nonNull(mas) && !emptyMatch(hd(mas))
+                                && o==offsetOf(hd(maOffs(hd(mas))))
+                                && !isNumDiscr(d=maDiscr(hd(mas)))) {
+                tab = addConTable(d,hd(mas),tab);
+                mas = tl(mas);
+            }
+            for (tab=rev(tab); nonNull(tab); tab=tl(tab)) {
+                d    = fst(hd(tab));
+                smas = snd(hd(tab));
+                da   = discrArity(d);
+                map2Proc(advance,co,da,smas);
+                srhs = cons(pair(d,match(co+da,smas)),srhs);
+            }
+            srhs = ap(CASE,pair(mkOffset(o),srhs));
+        }
+    }
+    return nonNull(mas) ? ap(FATBAR,pair(srhs,match(co,mas))) : srhs;
+}
+
+static Cell local joinMas(co,mas)       /* Combine list of matches into rhs*/
+Int  co;                                /* using FATBARs as necessary      */
+List mas; {                             /* Non-empty list of empty matches */
+    Cell ma  = hd(mas);
+    Cell rhs = pmcTerm(co,maSc(ma),maRhs(ma));
+    if (nonNull(tl(mas)) && canFail(rhs))
+        return ap(FATBAR,pair(rhs,joinMas(co,tl(mas))));
+    else
+        return rhs;
+}
+
+static Bool local canFail(rhs)         /* Determine if expression (as rhs) */
+Cell rhs; {                            /* might ever be able to fail       */
+    switch (whatIs(rhs)) {
+        case LETREC  : return canFail(snd(snd(rhs)));
+        case GUARDED : return TRUE;    /* could get more sophisticated ..? */
+        default      : return FALSE;
+    }
+}
+
+/* type Table a b = [(a, [b])]
+ *
+ * addTable                 :: a -> b -> Table a b -> Table a b
+ * addTable x y []           = [(x,[y])]
+ * addTable x y (z@(n,sws):zs)
+ *              | n == x     = (n,sws++[y]):zs
+ *              | otherwise  = (n,sws):addTable x y zs
+ */
+
+static List local addConTable(x,y,tab) /* add element (x,y) to table       */
+Cell x, y;
+List tab; {
+    if (isNull(tab))
+        return singleton(pair(x,singleton(y)));
+    else if (fst(hd(tab))==x)
+        snd(hd(tab)) = appendOnto(snd(hd(tab)),singleton(y));
+    else
+        tl(tab) = addConTable(x,y,tl(tab));
+
+    return tab;
+}
+
+static Void local advance(co,a,ma)      /* Advance non-empty match by      */
+Int  co;                                /* processing head pattern         */
+Int  a;                                 /* discriminator arity             */
+Cell ma; {
+    Cell p  = hd(maPats(ma));
+    List ps = tl(maPats(ma));
+    List us = tl(maOffs(ma));
+    if (whatIs(p)==CONFLDS) {           /* Special case for record syntax  */
+        Name c  = fst(snd(p));
+        List fs = snd(snd(p));
+        List qs = NIL;
+        List vs = NIL;
+        for (; nonNull(fs); fs=tl(fs)) {
+            vs = cons(mkOffset(co+a+1-sfunPos(fst(hd(fs)),c)),vs);
+            qs = cons(snd(hd(fs)),qs);
+        }
+        ps = revOnto(qs,ps);
+        us = revOnto(vs,us);
+    }
+    else                                /* Normally just spool off patterns*/
+        for (; a>0; --a) {              /* and corresponding offsets ...   */
+            us = cons(mkOffset(++co),us);
+            ps = cons(arg(p),ps);
+            p  = fun(p);
+        }
+
+    maPats(ma) = ps;
+    maOffs(ma) = us;
+}
+
+/* --------------------------------------------------------------------------
+ * Normalize and test for empty match:
+ * ------------------------------------------------------------------------*/
+
+static Bool local emptyMatch(ma)/* Normalize and test to see if a given    */
+Cell ma; {                      /* match, ma, is empty.                    */
+
+    while (nonNull(maPats(ma))) {
+        Cell p;
+tidyHd: switch (whatIs(p=hd(maPats(ma)))) {
+            case LAZYPAT   : {   Cell nv   = inventVar();
+                                 maRhs(ma) = ap(LETREC,
+                                                pair(remPat(snd(p),nv,NIL),
+                                                     maRhs(ma)));
+                                 p         = nv;
+                             }
+                             /* intentional fall-thru */
+            case VARIDCELL :
+            case VAROPCELL :
+            case DICTVAR   : extSc(p,hd(maOffs(ma)),ma);
+            case WILDCARD  : maPats(ma) = tl(maPats(ma));
+                             maOffs(ma) = tl(maOffs(ma));
+                             continue;
+
+            /* So-called "as-patterns"are really just pattern intersections:
+             *    (p1@p2:ps, o:os, sc, e) ==> (p1:p2:ps, o:o:os, sc, e)
+             * (But the input grammar probably doesn't let us take
+             * advantage of this, so we stick with the special case
+             * when p1 is a variable.)
+             */
+            case ASPAT     : extSc(fst(snd(p)),hd(maOffs(ma)),ma);
+                             hd(maPats(ma)) = snd(snd(p));
+                             goto tidyHd;
+
+            case FINLIST   : hd(maPats(ma)) = mkConsList(snd(p));
+                             return FALSE;
+
+            case STRCELL   : {   String s = textToStr(textOf(p));
+                                 for (p=NIL; *s!='\0'; ++s)
+                                     if (*s!='\\' || *++s=='\\')
+                                         p = ap(consChar(*s),p);
+                                     else
+                                         p = ap(consChar('\0'),p);
+                                 hd(maPats(ma)) = revOnto(p,nameNil);
+                             }
+                             return FALSE;
+
+            case AP        : if (isName(fun(p)) && isCfun(fun(p))
+                                 && cfunOf(fun(p))==0
+                                 && name(fun(p)).defn==nameId) {
+                                  hd(maPats(ma)) = arg(p);
+                                  goto tidyHd;
+                             }
+                             /* intentional fall-thru */
+            case CHARCELL  :
+            case NAME      :
+            case CONFLDS   :
+                             return FALSE;
+
+            default        : internal("emptyMatch");
+        }
+    }
+    return TRUE;
+}
+
+/* --------------------------------------------------------------------------
+ * Discriminators:
+ * ------------------------------------------------------------------------*/
+
+static Cell local maDiscr(ma)   /* Get the discriminator for a non-empty   */
+Cell ma; {                      /* match, ma.                              */
+    Cell p = hd(maPats(ma));
+    Cell h = getHead(p);
+    switch (whatIs(h)) {
+        case CONFLDS : return fst(snd(p));
+#if NPLUSK
+        case ADDPAT  : arg(fun(p)) = translate(arg(fun(p)));
+                       return fun(p);
+#endif
+#if TREX
+        case EXT     : h      = fun(fun(p));
+                       arg(h) = translate(arg(h));
+                       return h;
+#endif
+        case NAME    : if (h==nameFromInt || h==nameFromInteger
+                                          || h==nameFromDouble) {
+                           if (argCount==2)
+                               arg(fun(p)) = translate(arg(fun(p)));
+                           return p;
+                       }
+    }
+    return h;
+}
+
+static Bool local isNumDiscr(d) /* TRUE => numeric discriminator           */
+Cell d; {
+    switch (whatIs(d)) {
+        case NAME      :
+        case TUPLE     :
+        case CHARCELL  : return FALSE;
+
+#if TREX
+        case AP        : return !isExt(fun(d));
+#else
+        case AP        : return TRUE;   /* must be a literal or (n+k)      */
+#endif
+    }
+    internal("isNumDiscr");
+    return 0;/*NOTREACHED*/
+}
+
+Int discrArity(d)                      /* Find arity of discriminator      */
+Cell d; {
+    switch (whatIs(d)) {
+        case NAME      : return name(d).arity;
+        case TUPLE     : return tupleOf(d);
+        case CHARCELL  : return 0;
+#if TREX
+        case AP        : switch (whatIs(fun(d))) {
+#if NPLUSK
+                             case ADDPAT : return 1;
+#endif
+                             case EXT    : return 2;
+                             default     : return 0;
+                         }
+#else
+#if NPLUSK
+        case AP        : return (whatIs(fun(d))==ADDPAT) ? 1 : 0;
+#else
+        case AP        : return 0;      /* must be an Int or Float lit     */
+#endif
+#endif
+    }
+    internal("discrArity");
+    return 0;/*NOTREACHED*/
+}
+
+static Bool local eqNumDiscr(d1,d2)     /* Determine whether two numeric   */
+Cell d1, d2; {                          /* descriptors have same value     */
+#if NPLUSK
+    if (whatIs(fun(d1))==ADDPAT)
+        return whatIs(fun(d2))==ADDPAT && snd(fun(d1))==snd(fun(d2));
+#endif
+    if (isInt(arg(d1)))
+        return isInt(arg(d2)) && intOf(arg(d1))==intOf(arg(d2));
+    if (isFloat(arg(d1)))
+        return isFloat(arg(d2)) && floatOf(arg(d1))==floatOf(arg(d2));
+#if BIGNUMS
+    if (isBignum(arg(d1)))
+        return isBignum(arg(d2)) && bigCmp(arg(d1),arg(d2))==0;
+#endif
+    internal("eqNumDiscr");
+    return FALSE;/*NOTREACHED*/
+}
+
+#if TREX
+static Bool local isExtDiscr(d)         /* Test of extension discriminator */
+Cell d; {
+    return isAp(d) && isExt(fun(d));
+}
+
+static Bool local eqExtDiscr(d1,d2)     /* Determine whether two extension */
+Cell d1, d2; {                          /* discriminators have same label  */
+    return fun(d1)==fun(d2);
+}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+
+
+/* --------------------------------------------------------------------------
+ * STG stuff
+ * ------------------------------------------------------------------------*/
 
 static Void local stgCGBinds( List );
 
@@ -74,28 +1481,12 @@ static List addGlobals( List binds )
     return binds;
 }
 
-#if 0
-/* This is a hack to see if "show [1..1000]" will go any faster if I
- * code primShowInt in C
- */
-char* prim_showInt(int x)
-{
-    char buffer[50];
-    sprintf(buffer,"%d",x);
-    return buffer;
-}
-
-void prim_flush_stdout(void)
-{
-    fflush(stdout);
-}
-#endif
 
 Void evalExp() {                    /* compile and run input expression    */
     /* ToDo: this name (and other names generated during pattern match?)
      * get inserted in the symbol table but never get removed.
      */
-    Name n = newName(inventText());
+    Name n = newName(inventText(),NIL);
     StgVar v = mkStgVar(NIL,NIL);
     name(n).stgVar = v;
     compiler(RESET);
@@ -108,6 +1499,7 @@ Void evalExp() {                    /* compile and run input expression    */
 
     /* Re-initialise the scheduler - ToDo: do I need this? */
     initScheduler();
+    /* ToDo: don't really initScheduler every time.  fix */
     {
         HaskellObj result; /* ignored */
         SchedulerStatus status = rts_eval_(closureOfVar(v),10000,&result);
@@ -145,7 +1537,7 @@ static List local addStgVar( List binds, Pair bind )
     Name   n  = findName(t);
 
     if (isNull(n)) {                   /* Lookup global name - the only way*/
-        n = newName(t);                /* this (should be able to happen)  */
+        n = newName(t,NIL);            /* this (should be able to happen)  */
     }                                  /* is with new global var introduced*/
                                        /* after type check; e.g. remPat1   */
     name(n).stgVar = nv;
@@ -223,6 +1615,7 @@ Name n; {                               /* generated function              */
     Int  arity = length(fst(hd(defs)));
 
     compiler(RESET);
+    currentName = n;
     mapProc(transAlt,defs);
     stgDefn(n,arity,match(arity,altsMatch(1,arity,NIL,defs)));
     name(n).defn = NIL;
@@ -240,6 +1633,33 @@ Pair p; {                               /* Should be merged with genDefns, */
     return s;
 }
 
+
+#if 0
+I think this is 98-specific.
+static Void local newGlobalFunction(n,arity,fvs,co,e)
+Name n;
+Int  arity;
+List fvs;
+Int  co;
+Cell e; {
+#ifdef DEBUG_SHOWSC
+    extern Void printSc Args((FILE*, Text, Int, Cell));
+#endif
+    extraVars     = fvs;
+    numExtraVars  = length(extraVars);
+    localOffset   = co;
+    localArity    = arity;
+    name(n).arity = arity+numExtraVars;
+    e             = preComp(e);
+#ifdef DEBUG_SHOWSC
+    if (debugCode) {
+        printSc(stdout,name(n).text,name(n).arity,e);
+    }
+#endif
+    name(n).code  = codeGen(n,name(n).arity,e);
+}
+#endif
+
 /* --------------------------------------------------------------------------
  * Compiler control:
  * ------------------------------------------------------------------------*/
@@ -248,8 +1668,19 @@ Void compiler(what)
 Int what; {
     switch (what) {
         case INSTALL :
-        case RESET   : break;
-        case MARK    : break;
+        case RESET   : freeVars      = NIL;
+                       freeFuns      = NIL;
+                       freeBegin     = mkOffset(0);
+                       //extraVars     = NIL;
+                       //numExtraVars  = 0;
+                       //localOffset   = 0;
+                       //localArity    = 0;
+                       break;
+
+        case MARK    : mark(freeVars);
+                       mark(freeFuns);
+                       //mark(extraVars);
+                       break;
     }
 }
 
index b80ebfd..2f3ccc6 100644 (file)
-/* -*- mode: hugs-c; -*- */
 /* --------------------------------------------------------------------------
  * Connections between components of the Hugs system
  *
- * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
- * All rights reserved. See NOTICE for details and conditions of use etc...
- * Hugs version 1.4, December 1997
+ * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
+ * Haskell Group 1994-99, and is distributed as Open Source software
+ * under the Artistic License; see the file "Artistic" that is included
+ * in the distribution for details.
  *
  * $RCSfile: connect.h,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:03 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:27 $
  * ------------------------------------------------------------------------*/
 
 /* --------------------------------------------------------------------------
  * Standard data:
  * ------------------------------------------------------------------------*/
 
+extern Bool   haskell98;                /* TRUE => Haskell 98 compatibility*/
+extern Module modulePrelude;
+extern Module modulePreludeHugs;
+
+/* --------------------------------------------------------------------------
+ * Primitive constructor functions 
+ * ------------------------------------------------------------------------*/
+
+extern Name  nameFalse, nameTrue;
+extern Name  nameNil,   nameCons;
+extern Name  nameJust,  nameNothing;
+extern Name  nameLeft,  nameRight;
+extern Name  nameUnit;
+
+extern Name  nameLT,      nameEQ;
+extern Name  nameGT;
+extern Name  nameFst,     nameSnd;      /* standard combinators            */
+extern Name  nameId,      nameOtherwise;
+extern Name  nameNegate,  nameFlip;     /* primitives reqd for parsing     */
+extern Name  nameFrom,    nameFromThen;
+extern Name  nameFromTo,  nameFromThenTo;
+extern Name  nameFatbar,  nameFail;     /* primitives reqd for translation */
+extern Name  nameIf,      nameSel;
+extern Name  nameCompAux;
+extern Name  namePmInt,   namePmFlt;    /* primitives for pattern matching */
+extern Name  namePmInteger;
+#if NPLUSK
+extern Name  namePmNpk,   namePmSub;    /* primitives for (n+k) patterns   */
+#endif
+extern Name  nameError;                 /* For runtime error messages      */
+extern Name  nameUndefined;             /* A generic undefined value       */
+extern Name  nameBlackHole;             /* For GC-detected black hole      */
+extern Name  nameInd;                   /* For dict indirection            */
+extern Name  nameAnd,     nameOr;       /* For optimisation of && and ||   */
+extern Name  nameFromInt, nameFromDouble;/*coercion of numerics            */
+extern Name  nameFromInteger;
+extern Name  nameEq,      nameCompare;  /* names used for deriving         */
+extern Name  nameMinBnd,  nameMaxBnd;
+extern Name  nameIndex,   nameInRange;
+extern Name  nameRange;
+extern Name  nameLe,      nameGt;
+extern Name  nameShowsPrec, nameReadsPrec;
+extern Name  nameMult,    namePlus;
+extern Name  nameConCmp,  nameEnRange;
+extern Name  nameEnIndex, nameEnInRng;
+extern Name  nameEnToEn,  nameEnFrEn;
+extern Name  nameEnFrom,  nameEnFrTh;
+extern Name  nameEnFrTo;
+extern Name  nameComp,    nameApp;      /* composition and append          */
+extern Name  nameShowField;             /* display single field            */
+extern Name  nameShowParen;             /* wrap with parens                */
+extern Name  nameReadField;             /* read single field               */
+extern Name  nameReadParen;             /* unwrap from parens              */
+extern Name  nameLex;                   /* lexer                           */
+extern Name  nameRangeSize;             /* calculate size of index range   */
+extern Class classMonad;                /* Monads                          */
+extern Name  nameReturn,  nameBind;     /* for translating monad comps     */
+extern Name  nameMFail;
+extern Name  nameListMonad;             /* builder function for List Monad */
+
+#if EVAL_INSTANCES
+extern Name  nameStrict,  nameSeq;      /* Members of class Eval           */
+extern Name  nameIStrict, nameISeq;     /* ... and their implementations   */
+#endif
+
+extern Name  namePrint;                 /* printing primitive              */
+
+#if    IO_MONAD
+extern Type   typeProgIO;               /* For the IO monad, IO ()         */
+extern Name   nameIORun;                /* IO monad executor               */
+extern Name   namePutStr;               /* Prelude.putStr                  */
+extern Name   nameUserErr;              /* primitives required for IOError */
+extern Name   nameNameErr,  nameSearchErr;
+#endif
+
+#if IO_HANDLES
+extern Name   nameWriteErr, nameIllegal;/* primitives required for IOError */
+extern Name   nameEOFErr;
+#endif
+
+extern Text  textPrelude;
+extern Text  textNum;                   /* used to process default decls   */
+#if    NPLUSK
+extern Text  textPlus;                  /* Used to recognise n+k patterns  */
+#endif
+#if TREX
+extern Name  nameNoRec;                 /* The empty record                */
+extern Type  typeNoRow;                 /* The empty row                   */
+extern Type  typeRec;                   /* Record formation                */
+extern Kind  extKind;                   /* Kind of extension, *->row->row  */
+extern Name  nameRecExt;                /* Extend a record                 */
+extern Name  nameRecBrk;                /* Break a record                  */
+extern Name  nameAddEv;                 /* Addition of evidence values     */
+extern Name  nameRecSel;                /* Select a record                 */
+extern Name  nameRecShw;                /* Show a record                   */
+extern Name  nameShowRecRow;            /* Used to output rows             */
+extern Name  nameRecEq;                 /* Compare records                 */
+extern Name  nameEqRecRow;              /* Used to compare rows            */
+extern Name  nameInsFld;                /* Field insertion routine         */
+#endif
+
+extern String repeatStr;                /* Repeat last command string      */
+extern String hugsEdit;                 /* String for editor command       */
+extern String hugsPath;                 /* String for file search path     */
+extern String projectPath;              /* String for project search path  */
+
+extern Type  typeArrow;                 /* Builtin type constructors       */
+extern Type  typeList;
+extern Type  typeUnit;
+
+#define fn(from,to)  ap(ap(typeArrow,from),to)  /* make type: from -> to   */
+
+extern List  stdDefaults;               /* List of standard default types  */
+
+extern Class classEq;                   /* `standard' classes              */
+extern Class classOrd;
+extern Class classShow;
+extern Class classRead;
+extern Class classIx;
+extern Class classEnum;
+#if EVAL_INSTANCES
+extern Class classEval;
+#endif
+extern Class classBounded;
+
+extern Class classReal;                 /* `numeric' classes               */
+extern Class classIntegral;
+extern Class classRealFrac;
+extern Class classRealFloat;
+extern Class classFractional;
+extern Class classFloating;
+extern Class classNum;
+
+extern Cell  *CStackBase;               /* pointer to base of C stack      */
+
+extern List  tyconDefns;                /* list of type constructor defns  */
+extern List  typeInDefns;               /* list of synonym restrictions    */
+extern List  valDefns;                  /* list of value definitions       */
+extern List  classDefns;                /* list of class definitions       */
+extern List  instDefns;                 /* list of instance definitions    */
+extern List  selDefns;                  /* list of selector lists          */
+extern List  genDefns;                  /* list of generated defns         */
+extern List  primDefns;                 /* list of primitive definitions   */
+extern List  unqualImports;             /* unqualified import list         */
+extern List  defaultDefns;              /* default definitions (if any)    */
+extern Int   defaultLine;               /* line in which default defs occur*/
+extern List  evalDefaults;              /* defaults for evaluator          */
+extern Cell  inputExpr;                 /* evaluator input expression      */
+extern Addr  inputCode;                 /* Code for compiled input expr    */
+
+extern Int   whnfArgs;                  /* number of args of term in whnf  */
+extern Cell  whnfHead;                  /* head of term in whnf            */
+extern Int   whnfInt;                   /* integer value of term in whnf   */
+extern Float whnfFloat;                 /* float value of term in whnf     */
+/*ToDo?? extern Long  numReductions;*/             /* number of reductions used       */
+extern Long  numCells;                  /* number of cells allocated       */
+extern Int   numGcs;                    /* number of garbage collections   */
+extern Bool  broken;                    /* indicates interrupt received    */
+/*ToDo?? extern Bool  preludeLoaded;*/             /* TRUE => prelude has been loaded */
+
+extern Bool  gcMessages;                /* TRUE => print GC messages       */
+extern Bool  literateScripts;           /* TRUE => default lit scripts     */
+extern Bool  literateErrors;            /* TRUE => report errs in lit scrs */
+/*ToDo?? extern Bool  failOnError;*/              /* TRUE => error produces immediate*/
+                                        /*         termination             */
+
+extern Int   cutoff;                    /* Constraint Cutoff depth         */
+
+#if USE_PREPROCESSOR
+extern String preprocessor;             /* preprocessor command            */
+#endif
+
+#if DEBUG_CODE
+extern Bool  debugCode;                 /* TRUE => print G-code to screen  */
+#endif
+extern Bool  kindExpert;                /* TRUE => display kind errors in  */
+                                        /*         full detail             */
+extern Bool  allowOverlap;              /* TRUE => allow overlapping insts */
+
 /* --------------------------------------------------------------------------
  * Function prototypes etc...
  * ------------------------------------------------------------------------*/
 
+extern Void everybody Args((Int));
+
 #define RESET   1               /* reset subsystem                         */
 #define MARK    2               /* mark parts of graph in use by subsystem */
 #define INSTALL 3               /* install subsystem (executed once only)  */
 #define EXIT    4               /* Take action immediately before exit()   */
 #define BREAK   5               /* Take action after program break         */
 
-extern  Void   everybody        Args((Int));
-extern  Void   machdep          Args((Int));
+typedef long   Target;
+extern  Void   setGoal          Args((String, Target));
+extern  Void   soFar            Args((Target));
+extern  Void   done             Args((Void));
+extern  String fromEnv          Args((String,String));
+extern  Bool   chase            Args((List));
+
 extern  Void   storage          Args((Int));
-extern  Void   linkControl      Args((Int));
-extern  Void   translateControl Args((Int));
-extern  Void   staticAnalysis   Args((Int));
-extern  Void   interface        Args((Int));
-extern  Void   deriveControl    Args((Int));
+
 extern  Void   input            Args((Int));
+extern  Void   consoleInput     Args((String));
+extern  Void   projInput        Args((String));
+extern  Void   stringInput      Args((String));
+extern  Void   parseScript      Args((String,Long));
+extern  Void   parseExp         Args((Void));
+extern  String readFilename     Args((Void));
+extern  String readLine         Args((Void));
+extern  Syntax defaultSyntax    Args((Text));
+extern  Syntax syntaxOf         Args((Name));
+extern  String unlexChar        Args((Char,Char));
+extern  Void   printString      Args((String));
+
+extern  Void   substitution     Args((Int));
+
+extern  Void   staticAnalysis   Args((Int));
+#if IGNORE_MODULES
+#define startModule(m)       doNothing()
+#define setExportList(l)     doNothing()
+#define setExports(l)        doNothing()
+#define addQualImport(m,as)  doNothing()
+#define addUnqualImport(m,l) doNothing()
+#else
+extern  Void   startModule      Args((Cell));
+extern  Void   setExportList    Args((List));
+extern  Void   setExports       Args((List));
+extern  Void   addQualImport    Args((Text,Text));
+extern  Void   addUnqualImport  Args((Text,List));
+#endif
+extern  Void   tyconDefn        Args((Int,Cell,Cell,Cell));
+extern  Void   setTypeIns       Args((List));
+extern  Void   clearTypeIns     Args((Void));
+extern  Type   fullExpand       Args((Type));
+extern  Bool   isAmbiguous      Args((Type));
+extern  Void   ambigError       Args((Int,String,Cell,Type));
+extern  Void   classDefn        Args((Int,Cell,Cell));
+extern  Void   instDefn         Args((Int,Cell,Cell));
+extern  Void   addTupInst       Args((Class,Int));
+#if EVAL_INSTANCES
+extern  Void   addEvalInst      Args((Int,Cell,Int,List));
+#endif
+#if TREX
+extern  Inst   addRecShowInst   Args((Class,Ext));
+extern  Inst   addRecEqInst     Args((Class,Ext));
+#endif
+extern  Void   primDefn         Args((Cell,List,Cell));
+extern  Void   defaultDefn      Args((Int,List));
+extern  Void   checkExp         Args((Void));
+extern  Void   checkDefns       Args((Void));
+extern  Bool   h98Pred          Args((Bool,Cell));
+extern  Cell   h98Context       Args((Bool,List));
+extern  Void   h98CheckCtxt     Args((Int,String,Bool,List,Inst));
+extern  Void   h98CheckType     Args((Int,String,Cell,Type));
+extern  Void   h98DoesntSupport Args((Int,String));
+
 extern  Void   typeChecker      Args((Int));
-extern  Void   desugarControl   Args((Int));
-extern  Void   codegen          Args((Int));
+extern  Type   typeCheckExp     Args((Bool));
+extern  Void   typeCheckDefns   Args((Void));
+extern  Cell   provePred        Args((Kinds,List,Cell));
+extern  List   simpleContext    Args((List,Int));
+extern  Cell   rhsExpr          Args((Cell));
+extern  Int    rhsLine          Args((Cell));
+extern  Bool   isProgType       Args((List,Type));
+extern  Cell   superEvid        Args((Cell,Class,Class));
+extern  Void   linkPreludeTC    Args((Void));
+extern  Void   linkPreludeCM    Args((Void));
+
 extern  Void   compiler         Args((Int));
-extern  Void   substitution     Args((Int));
-extern  Void   stgTranslate     Args((Int));
-extern  Void   codegen          Args((Int));
+extern  Void   compileDefns     Args((Void));
+extern  Void   compileExp       Args((Void));
+extern  Bool   failFree         Args((Cell));
+extern  Int    discrArity       Args((Cell));
+
+extern  Addr   codeGen          Args((Name,Int,Cell));
+extern  Void   implementCfun    Args((Name,List));
+#if TREX
+extern  Name   implementRecShw  Args((Text,Cell));
+extern  Name   implementRecEq   Args((Text,Cell));
+#endif
+extern  Void   addCfunTable     Args((Tycon));
+extern  Name   succCfun         Args((Name));
+extern  Name   nextCfun         Args((Name,Name));
+extern  Name   cfunByNum        Args((Name,Int));
+extern  Void   unwind           Args((Cell));
+extern  Void   run              Args((Addr,StackPtr));
+
+extern  Void   eval             Args((Cell));
+extern  Cell   evalWithNoError  Args((Cell));
+extern  Void   evalFails        Args((StackPtr));
+
+#if BYTECODE_PRIMS
+extern Int     IntAt            Args((Addr));
+#if !BREAK_FLOATS
+extern Float   FloatAt          Args((Addr));
+#endif
+extern Cell    CellAt           Args((Addr));
+extern Text    TextAt           Args((Addr));
+extern Addr    AddrAt           Args((Addr));
+extern Int     InstrAt          Args((Addr));
+#endif /* BYTECODE_PRIMS */
+
+extern  Void   abandon          Args((String,Cell));
+extern  Void   outputString     Args((FILE *));
+extern  Void   dialogue         Args((Cell));
+#define consChar(c) ap(conCons,mkChar(c))
+
+#if BIGNUMS
+extern  Bignum bigInt           Args((Int));
+extern  Bignum bigDouble        Args((double));
+extern  Bignum bigNeg           Args((Bignum));
+extern  Cell   bigToInt         Args((Bignum));
+extern  Cell   bigToFloat       Args((Bignum));
+extern  Bignum bigStr           Args((String));
+extern  Cell   bigOut           Args((Bignum,Cell,Bool));
+extern  Bignum bigShift         Args((Bignum,Int,Int));
+extern  Int    bigCmp           Args((Bignum,Bignum));
+#endif
+#if IO_MONAD
+extern Void   setHugsArgs       Args((Int,String[]));
+#endif
+
+#if PROFILING
+extern  String timeString       Args((Void));
+#endif
+
+extern  Int    shellEsc         Args((String));
+extern  Int    getTerminalWidth Args((Void));
+extern  Void   normalTerminal   Args((Void));
+extern  Void   noechoTerminal   Args((Void));
+extern  Int    readTerminalChar Args((Void));
+extern  Void   gcStarted        Args((Void));
+extern  Void   gcScanning       Args((Void));
+extern  Void   gcRecovered      Args((Int));
+extern  Void   gcCStack         Args((Void));
+extern  Void   needPrims        Args((Int)); 
+
+extern Type primType( Int /*AsmMonad*/ monad, String a_kinds, String r_kinds );
+#define aVar            mkOffset(0)     /* Simple skeleton for type var    */
+
+/*-------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+ * Interrupting execution (signals, allowBreak):
+ *-------------------------------------------------------------------------*/
+
+extern Bool breakOn      Args((Bool));
+
+extern Bool  broken;                    /* indicates interrupt received    */
+
+#ifndef SIGBREAK /* Sigh, not defined in cygwin32 beta release 16 */
+# define SIGBREAK 21
+#endif
+
+/* allowBreak: call to allow user to interrupt computation
+ * ctrlbrk:    set control break handler
+ */
+
+#if HUGS_FOR_WINDOWS
+#  define ctrlbrk(bh) 
+#  define allowBreak()  kbhit()
+#else /* !HUGS_FOR_WINDOWS */
+#  define ctrlbrk(bh)   signal(SIGINT,bh); signal(SIGBREAK,bh)
+#  define allowBreak()  if (broken) { broken=FALSE; sigRaise(breakHandler); }
+#endif /* !HUGS_FOR_WINDOWS */
+
+/*---------------------------------------------------------------------------
+ * Environment variables and the registry
+ *-------------------------------------------------------------------------*/
+
+/* On Win32 we can use the registry to supplement info in environment 
+ * variables.
+ */
+#define USE_REGISTRY (HAVE_WINDOWS_H && !__MSDOS__)
+
+#ifdef USE_REGISTRY
+Bool   writeRegString Args((String var, String val));
+String         readRegString  Args((String var, String def));
+Int    readRegInt     Args((String var, Int def));
+Bool   writeRegInt    Args((String var, Int val));
+#endif
+
+/*---------------------------------------------------------------------------
+ * File operations:
+ *-------------------------------------------------------------------------*/
+
+#if HAVE_UNISTD_H
+# include <sys/types.h>
+# include <unistd.h>
+#elif !HUGS_FOR_WINDOWS
+extern int      chdir      Args((const char*));
+#endif
+
+#if HAVE_STDLIB_H
+# include <stdlib.h>
+#else
+extern int      system     Args((const char *));
+extern double   atof       Args((const char *));
+extern void     exit       Args((int));
+#endif
+
+#ifndef FILENAME_MAX       /* should already be defined in an ANSI compiler*/
+#define FILENAME_MAX 256
+#else
+#if     FILENAME_MAX < 256
+#undef  FILENAME_MAX
+#define FILENAME_MAX 256
+#endif
+#endif
+
+/* Hack, hack: if you have dos.h, you probably have a DOS filesystem */
+#define DOS_FILENAMES              HAVE_DOS_H
+/* ToDo: can we replace this with a feature test? */
+#define MAC_FILENAMES              SYMANTEC_C
+
+#define CASE_INSENSITIVE_FILENAMES (DOS_FILENAMES | RISCOS)
+
+#if CASE_INSENSITIVE_FILENAMES
+# if HAVE_STRCASECMP
+#  define filenamecmp(s1,s2) strcasecmp(s1,s2)
+# elif HAVE__STRICMP
+#  define filenamecmp(s1,s2) _stricmp(s1,s2)
+# elif HAVE_STRICMP
+#  define filenamecmp(s1,s2) stricmp(s1,s2)
+# elif HAVE_STRCMPI
+#  define filenamecmp(s1,s2) strcmpi(s1,s2)
+# endif
+#else
+# define filenamecmp(s1,s2) strcmp(s1,s2)
+#endif
+
+/*---------------------------------------------------------------------------
+ * Pipe-related operations:
+ *
+ * On Windows, many standard Unix names acquire a leading underscore.
+ * Irritating, but easy to work around.
+ *-------------------------------------------------------------------------*/
+
+#if !defined(HAVE_POPEN) && defined(HAVE__POPEN)
+#define popen(x,y) _popen(x,y)
+#endif
+#if !defined(HAVE_PCLOSE) && defined(HAVE__PCLOSE)
+#define pclose(x) _pclose(x)
+#endif
+
+/*---------------------------------------------------------------------------
+ * Bit manipulation:
+ *-------------------------------------------------------------------------*/
+
+#define bitArraySize(n)    ((n)/bitsPerWord + 1)
+#define placeInSet(n)      ((-(n)-1)>>wordShift)
+#define maskInSet(n)       (1<<((-(n)-1)&wordMask))
+
+/*---------------------------------------------------------------------------
+ * Function prototypes for code in machdep.c
+ *-------------------------------------------------------------------------*/
+
+extern  String findMPathname    Args((String,String,String));
+extern  String findPathname     Args((String,String));
+
+extern  Int    shellEsc         Args((String));
+extern  Int    getTerminalWidth Args((Void));
+extern  Void   normalTerminal   Args((Void));
+extern  Void   noechoTerminal   Args((Void));
+extern  Int    readTerminalChar Args((Void));
+extern  Void   gcStarted        Args((Void));
+extern  Void   gcScanning       Args((Void));
+extern  Void   gcRecovered      Args((Int));
+extern  Void   gcCStack         Args((Void));
 
 /*-------------------------------------------------------------------------*/
+
+extern Type typeInt64;
+extern Type typeWord;
+extern Type typeFloat;
+extern Type typePrimArray;
+extern Type typePrimByteArray;
+extern Type typeRef;
+extern Type typePrimMutableArray;
+extern Type typePrimMutableByteArray;
+extern Type typeStable;
+extern Type typeWeak;
+extern Type typeIO;
+extern Type typeForeign;
+extern Type typeMVar;
+extern Type typeThreadId;
+extern Type typeException;
+extern Type typeIO;
+extern Type typeST;
+
+extern  Void   foreignImport    Args((Cell,Pair,Cell,Cell));
+extern List  foreignImports;            /* foreign import declarations     */
+extern  Void   implementForeignImport Args((Name));
+extern  Void   foreignExport   Args((Cell,Cell,Cell,Cell));
+extern List  foreignExports;            /* foreign export declarations     */
+extern  Void   implementForeignExport Args((Name));
+
+extern List diVars;
+extern Int  diNum;
+
+Int     userArity           Args((Name));
+
+
+extern List    deriveEq            Args((Tycon));
+extern List    deriveOrd           Args((Tycon));
+extern List    deriveEnum          Args((Tycon));
+extern List    deriveIx            Args((Tycon));
+extern List    deriveShow          Args((Tycon));
+extern List    deriveRead          Args((Cell));
+extern List    deriveBounded       Args((Tycon));
+extern List    checkPrimDefn       Args((Triple));
+
+extern Bool  typeMatches        Args((Type,Type));
+extern  Void   evalExp           Args((Void));
+extern  Void   linkControl      Args((Int));
+extern  Void   deriveControl    Args((Int));
+extern  Void   translateControl Args((Int));
+extern  Void   codegen          Args((Int));
index 3f2f234..e6698c2 100644 (file)
@@ -1,4 +1,4 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Deriving
  *
@@ -7,16 +7,15 @@
  * Hugs version 1.4, December 1997
  *
  * $RCSfile: derive.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:03 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:27 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
 #include "storage.h"
+#include "backend.h"
 #include "connect.h"
 #include "errors.h"
-#include "translate.h" /* for implementConTag */
-#include "derive.h"
 
 static Cell varTrue;
 static Cell varFalse;
@@ -47,7 +46,7 @@ static Cell varMinBound;
 static Cell varMaxBound;
 #endif
 #if DERIVE_SHOW
-static Cell conCons;
+       Cell conCons;
 static Cell varShowField;              /* display single field            */
 static Cell varShowParen;              /* wrap with parens                */
 static Cell varCompose;                /* function composition            */
@@ -88,12 +87,29 @@ static List  local makeDPats2           Args((Cell,Int));
 static Bool  local isEnumType           Args((Tycon));
 #endif
 
+static Pair   local mkAltEq             Args((Int,List));
+static Pair   local mkAltOrd            Args((Int,List));
+static Cell   local prodRange           Args((Int,List,Cell,Cell,Cell));
+static Cell   local prodIndex           Args((Int,List,Cell,Cell,Cell));
+static Cell   local prodInRange         Args((Int,List,Cell,Cell,Cell));
+static List   local mkIxBinds           Args((Int,Cell,Int));
+static Cell   local mkAltShow           Args((Int,Cell,Int));
+static Cell   local showsPrecRhs        Args((Cell,Cell,Int));
+static Cell   local mkReadCon           Args((Name,Cell,Cell));
+static Cell   local mkReadPrefix        Args((Cell));
+static Cell   local mkReadInfix         Args((Cell));
+static Cell   local mkReadTuple         Args((Cell));
+static Cell   local mkReadRecord        Args((Cell,List));
+static List   local mkBndBinds          Args((Int,Cell,Int));
+
+
+
 /* --------------------------------------------------------------------------
  * Deriving Utilities
  * ------------------------------------------------------------------------*/
 
-static List diVars = NIL;               /* Acts as a cache of invented vars*/
-static Int  diNum  = 0;
+List diVars = NIL;                      /* Acts as a cache of invented vars*/
+Int  diNum  = 0;
 
 static List local getDiVars(n)          /* get list of at least n vars for */
 Int n; {                                /* derived instance generation     */
@@ -115,45 +131,6 @@ Cell r; {
     return singleton(pair(NIL,pair(mkInt(line),r)));
 }
 
-#if DERIVE_EQ || DERIVE_ORD
-static List local makeDPats2(h,n)       /* generate pattern list           */
-Cell h;                                 /* by putting two new patterns with*/
-Int  n; {                               /* head h and new var components   */
-    List us = getDiVars(2*n);
-    List vs = NIL;
-    Cell p;
-    Int  i;
-
-    for (i=0, p=h; i<n; ++i) {          /* make first version of pattern   */
-        p  = ap(p,hd(us));
-        us = tl(us);
-    }
-    vs = cons(p,vs);
-
-    for (i=0, p=h; i<n; ++i) {          /* make second version of pattern  */
-        p  = ap(p,hd(us));
-        us = tl(us);
-    }
-    return cons(p,vs);
-}
-#endif
-
-#if DERIVE_ORD || DERIVE_ENUM || DERIVE_IX || DERIVE_BOUNDED
-static Bool local isEnumType(t) /* Determine whether t is an enumeration   */
-Tycon t; {                      /* type (i.e. all constructors arity == 0) */
-    if (isTycon(t) && (tycon(t).what==DATATYPE || tycon(t).what==NEWTYPE)) {
-        List cs = tycon(t).defn;
-        for (; hasCfun(cs); cs=tl(cs)) {
-            if (name(hd(cs)).arity!=0) {
-                return FALSE;
-            }
-        }
-        return TRUE;
-    }
-    return FALSE;
-}
-#endif
-
 /* --------------------------------------------------------------------------
  * Given a datatype:   data T a b = A a b | B Int | C  deriving (Eq, Ord)
  * The derived definitions of equality and ordering are given by:
@@ -172,26 +149,25 @@ Tycon t; {                      /* type (i.e. all constructors arity == 0) */
  * constructors in the datatype definition.
  * ------------------------------------------------------------------------*/
 
-#if DERIVE_EQ
-
-static Pair  local mkAltEq              Args((Int,List));
+#define ap2(f,x,y) ap(ap(f,x),y)
 
-List deriveEq(t)                        /* generate binding for derived == */
+List local deriveEq(t)                  /* generate binding for derived == */
 Type t; {                               /* for some TUPLE or DATATYPE t    */
     List alts = NIL;
     if (isTycon(t)) {                   /* deal with type constrs          */
         List cs = tycon(t).defn;
         for (; hasCfun(cs); cs=tl(cs)) {
             alts = cons(mkAltEq(tycon(t).line,
-                                makeDPats2(hd(cs),name(hd(cs)).arity)),
+                                makeDPats2(hd(cs),userArity(hd(cs)))),
                         alts);
         }
         if (cfunOf(hd(tycon(t).defn))!=0) {
             alts = cons(pair(cons(WILDCARD,cons(WILDCARD,NIL)),
-                             pair(mkInt(tycon(t).line),varFalse)),alts);
+                             pair(mkInt(tycon(t).line),nameFalse)),alts);
         }
         alts = rev(alts);
-    } else {                            /* special case for tuples         */
+    }
+    else {                              /* special case for tuples         */
         alts = singleton(mkAltEq(0,makeDPats2(t,tupleOf(t))));
     }
     return singleton(mkBind("==",alts));
@@ -202,55 +178,35 @@ Int  line;                              /* using patterns in pats for lhs  */
 List pats; {                            /* arguments                       */
     Cell p = hd(pats);
     Cell q = hd(tl(pats));
-    Cell e = varTrue;
+    Cell e = nameTrue;
 
     if (isAp(p)) {
-        e = ap2(varEq,arg(p),arg(q));
+        e = ap2(nameEq,arg(p),arg(q));
         for (p=fun(p), q=fun(q); isAp(p); p=fun(p), q=fun(q)) {
-            e = ap2(varAnd,ap2(varEq,arg(p),arg(q)),e);
+            e = ap2(nameAnd,ap2(nameEq,arg(p),arg(q)),e);
         }
     }
     return pair(pats,pair(mkInt(line),e));
 }
-#endif /* DERIVE_EQ */
-
-#if DERIVE_ORD
-
-static Pair  local mkAltOrd             Args((Int,List));
 
 List deriveOrd(t)                       /* make binding for derived compare*/
 Type t; {                               /* for some TUPLE or DATATYPE t    */
     List alts = NIL;
     if (isEnumType(t)) {                /* special case for enumerations   */
-        Cell u = inventVar();
-        Cell w = inventVar();
-        Cell rhs = NIL;
-        if (cfunOf(hd(tycon(t).defn))!=0) {
-            implementConToTag(t);
-            rhs = ap2(varCompare,
-                      ap(tycon(t).conToTag,u),
-                      ap(tycon(t).conToTag,w));
-        } else {
-            rhs = varEQ;
-        }
-        alts = singleton(pair(doubleton(u,w),pair(mkInt(tycon(t).line),rhs)));
+        alts = mkVarAlts(tycon(t).line,nameConCmp);
     } else if (isTycon(t)) {            /* deal with type constrs          */
         List cs = tycon(t).defn;
         for (; hasCfun(cs); cs=tl(cs)) {
             alts = cons(mkAltOrd(tycon(t).line,
-                                 makeDPats2(hd(cs),name(hd(cs)).arity)),
+                                 makeDPats2(hd(cs),userArity(hd(cs)))),
                         alts);
         }
         if (cfunOf(hd(tycon(t).defn))!=0) {
             Cell u = inventVar();
             Cell w = inventVar();
-            implementConToTag(t);
-            alts   = cons(pair(doubleton(u,w),
+            alts   = cons(pair(cons(u,singleton(w)),
                                pair(mkInt(tycon(t).line),
-                                    ap2(varCompare,
-                                        ap(tycon(t).conToTag,u),
-                                        ap(tycon(t).conToTag,w)))),
-                          alts);
+                                    ap2(nameConCmp,u,w))),alts);
         }
         alts = rev(alts);
     } else {                            /* special case for tuples         */
@@ -264,72 +220,72 @@ Int  line;                              /* using patterns in pats for lhs  */
 List pats; {                            /* arguments                       */
     Cell p = hd(pats);
     Cell q = hd(tl(pats));
-    Cell e = varEQ;
+    Cell e = nameEQ;
 
     if (isAp(p)) {
-        e = ap2(varCompare,arg(p),arg(q));
+        e = ap2(nameCompare,arg(p),arg(q));
         for (p=fun(p), q=fun(q); isAp(p); p=fun(p), q=fun(q)) {
-            e = ap3(varCompAux,arg(p),arg(q),e);
+            e = ap(ap2(nameCompAux,arg(p),arg(q)),e);
         }
     }
 
     return pair(pats,pair(mkInt(line),e));
 }
-#endif /* DERIVE_ORD */
+
+static List local makeDPats2(h,n)       /* generate pattern list           */
+Cell h;                                 /* by putting two new patterns with*/
+Int  n; {                               /* head h and new var components   */
+    List us = getDiVars(2*n);
+    List vs = NIL;
+    Cell p;
+    Int  i;
+
+    for (i=0, p=h; i<n; ++i) {          /* make first version of pattern   */
+        p  = ap(p,hd(us));
+        us = tl(us);
+    }
+    vs = cons(p,vs);
+
+    for (i=0, p=h; i<n; ++i) {          /* make second version of pattern  */
+        p  = ap(p,hd(us));
+        us = tl(us);
+    }
+    return cons(p,vs);
+}
 
 /* --------------------------------------------------------------------------
  * Deriving Ix and Enum:
  * ------------------------------------------------------------------------*/
 
-#if DERIVE_ENUM
 List deriveEnum(t)              /* Construct definition of enumeration     */
 Tycon t; {
-    Int  l    = tycon(t).line;
-    Cell x    = inventVar();
-    Cell y    = inventVar();
-    Cell first = hd(tycon(t).defn);
-    Cell last = tycon(t).defn;
+    Int l = tycon(t).line;
 
     if (!isEnumType(t)) {
         ERRMSG(l) "Can only derive instances of Enum for enumeration types"
         EEND;
     }
-    while (hasCfun(tl(last))) {
-        last = tl(last);
-    }
-    last = hd(last);
-    implementConToTag(t);
-    implementTagToCon(t);
-    return cons(mkBind("toEnum",      mkVarAlts(l,tycon(t).tagToCon)),
-           cons(mkBind("fromEnum",    mkVarAlts(l,tycon(t).conToTag)),
-           cons(mkBind("enumFrom",    singleton(pair(singleton(x),  pair(mkInt(l),ap2(varEnumFromTo,x,last))))),
-           /* default instance of enumFromTo is good */
-           cons(mkBind("enumFromThen",singleton(pair(doubleton(x,y),pair(mkInt(l),ap3(varEnumFromThenTo,x,y,ap(COND,triple(ap2(varLe,x,y),last,first))))))),
-           /* default instance of enumFromThenTo is good */
-           NIL))));
-}
-#endif /* DERIVE_ENUM */
 
-#if DERIVE_IX
-static List  local mkIxBindsEnum        Args((Tycon));
-static List  local mkIxBinds            Args((Int,Cell,Int));
-static Cell  local prodRange            Args((Int,List,Cell,Cell,Cell));
-static Cell  local prodIndex            Args((Int,List,Cell,Cell,Cell));
-static Cell  local prodInRange          Args((Int,List,Cell,Cell,Cell));
+    return cons(mkBind("toEnum",mkVarAlts(l,ap(nameEnToEn,hd(tycon(t).defn)))),
+            cons(mkBind("fromEnum",mkVarAlts(l,nameEnFrEn)),
+             cons(mkBind("enumFrom",mkVarAlts(l,nameEnFrom)),
+              cons(mkBind("enumFromTo",mkVarAlts(l,nameEnFrTo)),
+               cons(mkBind("enumFromThen",mkVarAlts(l,nameEnFrTh)),NIL)))));
+}
 
 List deriveIx(t)                /* Construct definition of indexing        */
 Tycon t; {
-    Int l = tycon(t).line;
     if (isEnumType(t)) {        /* Definitions for enumerations            */
-        implementConToTag(t);
-        implementTagToCon(t);
-        return mkIxBindsEnum(t);
+        return cons(mkBind("range",mkVarAlts(tycon(t).line,nameEnRange)),
+                cons(mkBind("index",mkVarAlts(tycon(t).line,nameEnIndex)),
+                 cons(mkBind("inRange",mkVarAlts(tycon(t).line,nameEnInRng)),
+                  NIL)));
     } else if (isTuple(t)) {    /* Definitions for product types           */
         return mkIxBinds(0,t,tupleOf(t));
     } else if (isTycon(t) && cfunOf(hd(tycon(t).defn))==0) {
         return mkIxBinds(tycon(t).line,
                          hd(tycon(t).defn),
-                         name(hd(tycon(t).defn)).arity);
+                         userArity(hd(tycon(t).defn)));
     }
     ERRMSG(tycon(t).line)
         "Can only derive instances of Ix for enumeration or product types"
@@ -337,30 +293,19 @@ Tycon t; {
     return NIL;/* NOTREACHED*/
 }
 
-/* instance  Ix T  where
- *     range (c1,c2)       =  map tagToCon [conToTag c1 .. conToTag c2]
- *     index b@(c1,c2) ci
- *        | inRange b ci  =  conToTag ci - conToTag c1
- *        | otherwise     =  error "Ix.index.T: Index out of range."
- *     inRange (c1,c2) ci  =  conToTag c1 <= i && i <= conToTag c2
- *                           where i = conToTag ci
- */
-static List local mkIxBindsEnum(t)
-Tycon t; {
-    Int l = tycon(t).line;
-    Name tagToCon = tycon(t).tagToCon;
-    Name conToTag = tycon(t).conToTag;
-    Cell b  = inventVar();
-    Cell c1 = inventVar();
-    Cell c2 = inventVar();
-    Cell ci = inventVar();
-    return cons(mkBind("range",  singleton(pair(singleton(ap2(mkTuple(2),c1,c2)), pair(mkInt(l),ap2(varMap,tagToCon,ap2(varEnumFromTo,ap(conToTag,c1),ap(conToTag,c2))))))),
-           cons(mkBind("index",  singleton(pair(doubleton(ap(ASPAT,pair(b,ap2(mkTuple(2),c1,c2))),ci), 
-                                                pair(mkInt(l),ap(COND,triple(ap2(varInRange,b,ci),
-                                                                             ap2(varMinus,ap(conToTag,ci),ap(conToTag,c1)),
-                                                                             ap(varError,mkStr(findText("Ix.index: Index out of range"))))))))),
-           cons(mkBind("inRange",singleton(pair(doubleton(ap2(mkTuple(2),c1,c2),ci), pair(mkInt(l),ap2(varAnd,ap2(varLe,ap(conToTag,c1),ap(conToTag,ci)),ap2(varLe,ap(conToTag,ci),ap(conToTag,c2))))))), /* ToDo: share conToTag ci */
-           NIL)));
+static Bool local isEnumType(t) /* Determine whether t is an enumeration   */
+Tycon t; {                      /* type (i.e. all constructors arity == 0) */
+    if (isTycon(t) && (tycon(t).what==DATATYPE || tycon(t).what==NEWTYPE)) {
+        List cs = tycon(t).defn;
+        for (; hasCfun(cs); cs=tl(cs)) {
+            if (name(hd(cs)).arity!=0) {
+                return FALSE;
+            }
+        }
+        /* ToDo: correct?  addCfunTable(t); */
+        return TRUE;
+    }
+    return FALSE;
 }
 
 static List local mkIxBinds(line,h,n)   /* build bindings for derived Ix on*/
@@ -384,9 +329,8 @@ Int  n; {
     pats = cons(pr,cons(is,NIL));       /* Build [(ls,us),is]              */
 
     return cons(prodRange(line,singleton(pr),ls,us,is),
-           cons(prodIndex(line,pats,ls,us,is),
-           cons(prodInRange(line,pats,ls,us,is),
-           NIL)));
+                cons(prodIndex(line,pats,ls,us,is),
+                     cons(prodInRange(line,pats,ls,us,is),NIL)));
 }
 
 static Cell local prodRange(line,pats,ls,us,is)
@@ -401,7 +345,7 @@ Cell ls, us, is; {
     List e   = NIL;
     for (; isAp(ls); ls=fun(ls), us=fun(us), is=fun(is)) {
         e = cons(ap(FROMQUAL,pair(arg(is),
-                                  ap(varRange,ap2(mkTuple(2),
+                                  ap(nameRange,ap2(mkTuple(2),
                                                    arg(ls),
                                                    arg(us))))),e);
     }
@@ -423,11 +367,11 @@ Cell ls, us, is; {
     List xs = NIL;
     Cell e  = NIL;
     for (; isAp(ls); ls=fun(ls), us=fun(us), is=fun(is)) {
-        xs = cons(ap2(varIndex,ap2(mkTuple(2),arg(ls),arg(us)),arg(is)),xs);
+        xs = cons(ap2(nameIndex,ap2(mkTuple(2),arg(ls),arg(us)),arg(is)),xs);
     }
     for (e=hd(xs); nonNull(xs=tl(xs));) {
         Cell x = hd(xs);
-        e = ap2(varPlus,x,ap2(varMult,ap(varRangeSize,arg(fun(x))),e));
+        e = ap2(namePlus,x,ap2(nameMult,ap(nameRangeSize,arg(fun(x))),e));
     }
     e = singleton(pair(pats,pair(mkInt(line),e)));
     return mkBind("index",e);
@@ -441,33 +385,27 @@ Cell ls, us, is; {
      * inRange (X a b c, X p q r) (X x y z)
      *          = inRange (a,p) x && inRange (b,q) y && inRange (c,r) z
      */
-    Cell e = ap2(varInRange,ap2(mkTuple(2),arg(ls),arg(us)),arg(is));
+    Cell e = ap2(nameInRange,ap2(mkTuple(2),arg(ls),arg(us)),arg(is));
     while (ls=fun(ls), us=fun(us), is=fun(is), isAp(ls)) {
-        e = ap2(varAnd,
-                ap2(varInRange,ap2(mkTuple(2),arg(ls),arg(us)),arg(is)),
+        e = ap2(nameAnd,
+                ap2(nameInRange,ap2(mkTuple(2),arg(ls),arg(us)),arg(is)),
                 e);
     }
     e = singleton(pair(pats,pair(mkInt(line),e)));
     return mkBind("inRange",e);
 }
-#endif /* DERIVE_IX */
 
 /* --------------------------------------------------------------------------
  * Deriving Show:
  * ------------------------------------------------------------------------*/
 
-#if DERIVE_SHOW
-
-static Cell  local mkAltShow            Args((Int,Cell,Int));
-static Cell  local showsPrecRhs         Args((Cell,Cell));
-
 List deriveShow(t)              /* Construct definition of text conversion */
 Tycon t; {
     List alts = NIL;
     if (isTycon(t)) {                   /* deal with type constrs          */
         List cs = tycon(t).defn;
         for (; hasCfun(cs); cs=tl(cs)) {
-            alts = cons(mkAltShow(tycon(t).line,hd(cs),name(hd(cs)).arity),
+            alts = cons(mkAltShow(tycon(t).line,hd(cs),userArity(hd(cs))),
                         alts);
         }
         alts = rev(alts);
@@ -484,26 +422,29 @@ Int  a; {
     List vs   = getDiVars(a+1);
     Cell d    = hd(vs);
     Cell pat  = h;
-    while (vs=tl(vs), 0<a--) {
+    List pats = NIL;
+    Int  i    = 0;
+    for (vs=tl(vs); i<a; i++) {
         pat = ap(pat,hd(vs));
+        vs  = tl(vs);
     }
-    return pair(doubleton(d,pat),
-                pair(mkInt(line),showsPrecRhs(d,pat)));
+    pats = cons(d,cons(pat,NIL));
+    return pair(pats,pair(mkInt(line),showsPrecRhs(d,pat,a)));
 }
 
-#define consChar(c) ap(conCons,mkChar(c))
-#define shows0   ap(varShowsPrec,mkInt(0))
-#define shows10  ap(varShowsPrec,mkInt(10))
-#define showsOP  ap(varCompose,consChar('('))
-#define showsOB  ap(varCompose,consChar('{'))
-#define showsCM  ap(varCompose,consChar(','))
-#define showsSP  ap(varCompose,consChar(' '))
-#define showsBQ  ap(varCompose,consChar('`'))
+#define shows0   ap(nameShowsPrec,mkInt(0))
+#define shows10  ap(nameShowsPrec,mkInt(10))
+#define showsOP  ap(nameComp,consChar('('))
+#define showsOB  ap(nameComp,consChar('{'))
+#define showsCM  ap(nameComp,consChar(','))
+#define showsSP  ap(nameComp,consChar(' '))
+#define showsBQ  ap(nameComp,consChar('`'))
 #define showsCP  consChar(')')
 #define showsCB  consChar('}')
 
-static Cell local showsPrecRhs(d,pat)   /* build a rhs for showsPrec for a */
-Cell d, pat; {                          /* given pattern, pat              */
+static Cell local showsPrecRhs(d,pat,a) /* build a rhs for showsPrec for a */
+Cell d, pat;                            /* given pattern, pat              */
+Int  a; {
     Cell h   = getHead(pat);
     List cfs = cfunSfuns;
 
@@ -518,10 +459,10 @@ Cell d, pat; {                          /* given pattern, pat              */
         Int  i   = tupleOf(h);
         Cell rhs = showsCP;
         for (; i>1; --i) {
-            rhs = ap(showsCM,ap2(varCompose,ap(shows0,arg(pat)),rhs));
+            rhs = ap(showsCM,ap2(nameComp,ap(shows0,arg(pat)),rhs));
             pat = fun(pat);
         }
-        return ap(showsOP,ap2(varCompose,ap(shows0,arg(pat)),rhs));
+        return ap(showsOP,ap2(nameComp,ap(shows0,arg(pat)),rhs));
     }
 
     for (; nonNull(cfs) && h!=fst(hd(cfs)); cfs=tl(cfs)) {
@@ -536,11 +477,11 @@ Cell d, pat; {                          /* given pattern, pat              */
          *      = showString lab . showChar '=' . shows val
          */
         Cell rhs     = showsCB;
-        List vs      = revDupOnto(snd(hd(cfs)),NIL);
+        List vs      = dupOnto(snd(hd(cfs)),NIL);
         if (isAp(pat)) {
             for (;;) {
-                rhs = ap2(varCompose,
-                          ap2(varShowField,
+                rhs = ap2(nameComp,
+                          ap2(nameShowField,
                               mkStr(textOf(hd(vs))),
                               arg(pat)),
                           rhs);
@@ -553,16 +494,17 @@ Cell d, pat; {                          /* given pattern, pat              */
                 }
             }
         }
-        rhs = ap2(varCompose,ap(varAppend,mkStr(name(h).text)),ap(showsOB,rhs));
+        rhs = ap2(nameComp,ap(nameApp,mkStr(name(h).text)),ap(showsOB,rhs));
         return rhs;
-    } else if (name(h).arity==0) {
+    }
+    else if (a==0) {
         /* To display a nullary constructor:
          *    showsPrec d Foo = showString "Foo"
          */
-        return ap(varAppend,mkStr(name(h).text));
+        return ap(nameApp,mkStr(name(h).text));
     } else {
-        Syntax s = syntaxOf(name(h).text);
-        if (name(h).arity==2 && assocOf(s)!=APPLIC) {
+        Syntax s = syntaxOf(h);
+        if (a==2 && assocOf(s)!=APPLIC) {
             /* For a binary constructor with prec p:
              * showsPrec d (a :* b) = showParen (d > p)
              *                          (showsPrec lp a . showChar ' ' .
@@ -572,21 +514,23 @@ Cell d, pat; {                          /* given pattern, pat              */
             Int  p   = precOf(s);
             Int  lp  = (assocOf(s)==LEFT_ASS)  ? p : (p+1);
             Int  rp  = (assocOf(s)==RIGHT_ASS) ? p : (p+1);
-            Cell rhs = ap(showsSP,ap2(varShowsPrec,mkInt(rp),arg(pat)));
+            Cell rhs = ap(showsSP,ap2(nameShowsPrec,mkInt(rp),arg(pat)));
             if (defaultSyntax(name(h).text)==APPLIC) {
                 rhs = ap(showsBQ,
-                         ap2(varCompose,
-                             ap(varAppend,mkStr(name(h).text)),
+                         ap2(nameComp,
+                             ap(nameApp,mkStr(name(h).text)),
                              ap(showsBQ,rhs)));
             } else {
-                rhs = ap2(varCompose,ap(varAppend,mkStr(name(h).text)),rhs);
+                rhs = ap2(nameComp,ap(nameApp,mkStr(name(h).text)),rhs);
             }
-            rhs = ap2(varCompose,
-                      ap2(varShowsPrec,mkInt(lp),arg(fun(pat))),
+
+            rhs = ap2(nameComp,
+                      ap2(nameShowsPrec,mkInt(lp),arg(fun(pat))),
                       ap(showsSP,rhs));
-            rhs = ap2(varShowParen,ap2(varLe,mkInt(p+1),d),rhs);
+            rhs = ap2(nameShowParen,ap2(nameLe,mkInt(p+1),d),rhs);
             return rhs;
-        } else {
+        }
+        else {
             /* To display a non-nullary constructor with applicative syntax:
              *    showsPrec d (Foo x y) = showParen (d>=10)
              *                             (showString "Foo" .
@@ -595,10 +539,10 @@ Cell d, pat; {                          /* given pattern, pat              */
              */
             Cell rhs = ap(showsSP,ap(shows10,arg(pat)));
             for (pat=fun(pat); isAp(pat); pat=fun(pat)) {
-                rhs = ap(showsSP,ap2(varCompose,ap(shows10,arg(pat)),rhs));
+                rhs = ap(showsSP,ap2(nameComp,ap(shows10,arg(pat)),rhs));
             }
-            rhs = ap2(varCompose,ap(varAppend,mkStr(name(h).text)),rhs);
-            rhs = ap2(varShowParen,ap2(varLe,mkInt(10),d),rhs);
+            rhs = ap2(nameComp,ap(nameApp,mkStr(name(h).text)),rhs);
+            rhs = ap2(nameShowParen,ap2(nameLe,mkInt(10),d),rhs);
             return rhs;
         }
     }
@@ -612,31 +556,20 @@ Cell d, pat; {                          /* given pattern, pat              */
 #undef  showsBQ
 #undef  showsCP
 #undef  showsCB
-#undef  consChar
-
-#endif /* DERIVE_SHOW */
 
 /* --------------------------------------------------------------------------
  * Deriving Read:
  * ------------------------------------------------------------------------*/
 
-#if DERIVE_READ
-
-static Cell  local mkReadCon            Args((Name,Cell,Cell));
-static Cell  local mkReadPrefix         Args((Cell));
-static Cell  local mkReadInfix          Args((Cell));
-static Cell  local mkReadTuple          Args((Cell));
-static Cell  local mkReadRecord         Args((Cell,List));
-
 #define Tuple2(f,s)      ap2(mkTuple(2),f,s)
-#define Lex(r)           ap(varLex,r)  
+#define Lex(r)           ap(nameLex,r)  
 #define ZFexp(h,q)       ap(FROMQUAL, pair(h,q))
-#define ReadsPrec(n,e)   ap2(varReadsPrec,n,e)
+#define ReadsPrec(n,e)   ap2(nameReadsPrec,n,e)
 #define Lambda(v,e)      ap(LAMBDA,pair(v, pair(mkInt(0),e)))
-#define ReadParen(a,b,c) ap3(varReadParen,a,b,c)
-#define ReadField(f,s)   ap2(varReadField,f,s)
-#define GT(l,r)          ap2(varGt,l,r)
-#define Append(a,b)      ap2(varAppend,a,b)      
+#define ReadParen(a,b,c) ap(ap2(nameReadParen,a,b),c)
+#define ReadField(f,s)   ap2(nameReadField,f,s)
+#define GT(l,r)          ap2(nameGt,l,r)
+#define Append(a,b)      ap2(nameApp,a,b)      
 
 /*  Construct the readsPrec function of the form:
  *
@@ -645,7 +578,7 @@ static Cell  local mkReadRecord         Args((Cell,List));
  *                    ...
  *                    (readParen (d>pn) (\r -> [ (Cn ...,s) | ... ]) r) ... ))
  */
-List deriveRead(t)               /* construct definition of text reader    */
+List deriveRead(t)              /* construct definition of text reader     */
 Cell t; {
     Cell alt  = NIL;
     Cell exp  = NIL;
@@ -657,16 +590,17 @@ Cell t; {
     if (isTycon(t)) {
         List cs = tycon(t).defn;
         List exps = NIL;
-        for(; hasCfun(cs); cs=tl(cs)) {
+        for (; hasCfun(cs); cs=tl(cs)) {
             exps = cons(mkReadCon(hd(cs),d,r),exps);
         }
         /* reverse concatenate list of subexpressions */
         exp = hd(exps);
-        for(exps=tl(exps); nonNull(exps); exps=tl(exps)) {
-            exp = ap2(varAppend,hd(exps),exp);
+        for (exps=tl(exps); nonNull(exps); exps=tl(exps)) {
+            exp = ap2(nameApp,hd(exps),exp);
         }
         line = tycon(t).line;
-    } else { /* Tuples */
+    }
+    else { /* Tuples */
         exp = ap(mkReadTuple(t),r);
     }
     /* printExp(stdout,exp); putc('\n',stdout); */
@@ -680,29 +614,30 @@ Cell t; {
  *
  * for a (non-tuple) constructor "con" of precedence "p".
  */
+
 static Cell local mkReadCon(con, d, r) /* generate reader for a constructor */
 Name con;
 Cell d;
 Cell r; {
     Cell exp = NIL;
     Int  p   = 0;
-    Syntax s = syntaxOf(name(con).text);
+    Syntax s = syntaxOf(con);
     List cfs = cfunSfuns;
     for (; nonNull(cfs) && con!=fst(hd(cfs)); cfs=tl(cfs)) {
     }
     if (nonNull(cfs)) {
         exp = mkReadRecord(con,snd(hd(cfs)));
-        p   = 9;
-    } else if (name(con).arity==2 && assocOf(s)!=APPLIC) {
+        return ReadParen(nameFalse, exp, r);
+    }
+
+    if (userArity(con)==2 && assocOf(s)!=APPLIC) {
         exp = mkReadInfix(con);
         p   = precOf(s);
     } else {
         exp = mkReadPrefix(con);
         p   = 9;
     }
-    return ReadParen(name(con).arity==0 ? varFalse : GT(d,mkInt(p)), 
-                     exp, 
-                     r);
+    return ReadParen(userArity(con)==0 ? nameFalse : GT(d,mkInt(p)), exp, r);
 }
 
 /* Given an n-ary prefix constructor, generate a single lambda
@@ -721,7 +656,7 @@ Cell r; {
  */
 static Cell local mkReadPrefix(con)    /* readsPrec for prefix constructor */
 Cell con; {
-    Int  arity  = name(con).arity;
+    Int  arity  = userArity(con);
     Cell cn     = mkStr(name(con).text);
     Cell r      = inventVar();
     Cell prev_s = inventVar();
@@ -758,7 +693,7 @@ Cell con; {
 static Cell local mkReadInfix( con )
 Cell con;
 {
-    Syntax s  = syntaxOf(name(con).text);
+    Syntax s  = syntaxOf(con);
     Int    p  = precOf(s); 
     Int    lp = assocOf(s)==LEFT_ASS  ? p : (p+1);
     Int    rp = assocOf(s)==RIGHT_ASS ? p : (p+1);
@@ -884,17 +819,13 @@ List fs; {
 #undef GT
 #undef Append
 
-#endif /* DERIVE_READ */
-
 /* --------------------------------------------------------------------------
  * Deriving Bounded:
  * ------------------------------------------------------------------------*/
 
 #if DERIVE_BOUNDED
 
-static List  local mkBndBinds           Args((Int,Cell,Int));
-
-List deriveBounded(t)               /* construct definition of bounds      */
+List deriveBounded(t)             /* construct definition of bounds        */
 Tycon t; {
     if (isEnumType(t)) {
         Cell last  = tycon(t).defn;
@@ -905,12 +836,12 @@ Tycon t; {
         return cons(mkBind("minBound",mkVarAlts(tycon(t).line,first)),
                 cons(mkBind("maxBound",mkVarAlts(tycon(t).line,hd(last))),
                  NIL));
-    } else if (isTuple(t)) {        /* Definitions for product types       */
+    } else if (isTuple(t)) {    /* Definitions for product types           */
         return mkBndBinds(0,t,tupleOf(t));
     } else if (isTycon(t) && cfunOf(hd(tycon(t).defn))==0) {
         return mkBndBinds(tycon(t).line,
                           hd(tycon(t).defn),
-                          name(hd(tycon(t).defn)).arity);
+                          userArity(hd(tycon(t).defn)));
     }
     ERRMSG(tycon(t).line)
      "Can only derive instances of Bounded for enumeration and product types"
@@ -925,18 +856,18 @@ Int  n; {
     Cell minB = h;
     Cell maxB = h;
     while (n-- > 0) {
-        minB = ap(minB,varMinBound);
-        maxB = ap(maxB,varMaxBound);
+        minB = ap(minB,nameMinBnd);
+        maxB = ap(maxB,nameMaxBnd);
     }
     return cons(mkBind("minBound",mkVarAlts(line,minB)),
-           cons(mkBind("maxBound",mkVarAlts(line,maxB)),
-           NIL));
+            cons(mkBind("maxBound",mkVarAlts(line,maxB)),
+             NIL));
 }
-
 #endif /* DERIVE_BOUNDED */
 
+
 /* --------------------------------------------------------------------------
- * Static Analysis control:
+ * Derivation control:
  * ------------------------------------------------------------------------*/
 
 Void deriveControl(what)
index f6d7fdd..843aa92 100644 (file)
@@ -1,4 +1,4 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Dynamic loading (of .dll or .so files) for Hugs
  *
@@ -7,8 +7,8 @@
  * Hugs version 1.4, December 1997
  *
  * $RCSfile: dynamic.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:06 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:28 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
@@ -29,7 +29,7 @@ String fn; {
 void* lookupSymbol(file,symbol)
 ObjectFile file;
 String symbol; {
-    return dlsym(file,symbol)
+    return dlsym(file,symbol);
 }
 
 void* getDLLSymbol(dll,symbol)  /* load dll and lookup symbol */
index 5bfd966..98bb6ca 100644 (file)
@@ -1,18 +1,19 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Error handling support functions
  *
- * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
- * All rights reserved. See NOTICE for details and conditions of use etc...
- * Hugs version 1.4, December 1997
+ * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
+ * Haskell Group 1994-99, and is distributed as Open Source software
+ * under the Artistic License; see the file "Artistic" that is included
+ * in the distribution for details.
  *
  * $RCSfile: errors.h,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:07 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:28 $
  * ------------------------------------------------------------------------*/
 
-extern Void internal   Args((String)) HUGS_noreturn;
-extern Void fatal      Args((String)) HUGS_noreturn;
+extern Void internal     Args((String)) HUGS_noreturn;
+extern Void fatal        Args((String)) HUGS_noreturn;
 
 #if HUGS_FOR_WINDOWS
 #define Hilite()         WinTextcolor(hWndText,RED);
@@ -41,6 +42,13 @@ extern Void errAbort     Args((Void));
 
 extern sigProto(breakHandler);
 
-#include "output.h"
+extern Bool breakOn      Args((Bool));             /* in machdep.c         */
+
+extern Void printExp     Args((FILE *,Cell));      /* in output.c          */
+extern Void printType    Args((FILE *,Cell));
+extern Void printContext Args((FILE *,List));
+extern Void printPred    Args((FILE *,Cell));
+extern Void printKind    Args((FILE *,Kind));
+extern Void printKinds   Args((FILE *,Kinds));
 
 /*-------------------------------------------------------------------------*/
index 2d7344c..59eb322 100644 (file)
@@ -1,4 +1,4 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Free variable analysis
  *
@@ -7,16 +7,16 @@
  * Hugs version 1.4, December 1997
  *
  * $RCSfile: free.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:08 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:29 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
 #include "storage.h"
+#include "backend.h"
 #include "connect.h"
 #include "errors.h"
-#include "stg.h"
-#include "free.h"
+
 
 /* --------------------------------------------------------------------------
  * Local functions
index 5f6a368..f456db3 100644 (file)
@@ -1,37 +1,36 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Command interpreter
  *
- * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
- * All rights reserved. See NOTICE for details and conditions of use etc...
- * Hugs version 1.4, December 1997
+ * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
+ * Haskell Group 1994-99, and is distributed as Open Source software
+ * under the Artistic License; see the file "Artistic" that is included
+ * in the distribution for details.
  *
  * $RCSfile: hugs.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:09 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:29 $
  * ------------------------------------------------------------------------*/
 
+#include <setjmp.h>
+#include <ctype.h>
+#include <stdio.h>
+
 #include "prelude.h"
-#include "version.h"
 #include "storage.h"
 #include "command.h"
+#include "backend.h"
 #include "connect.h"
-#include "charset.h"
-#include "input.h"
-#include "type.h"
-#include "subst.h"  /* for typeMatches                        */
-#include "link.h"   /* for classShow, nameRunIO and namePrint */
-#include "static.h"
-#include "compiler.h"
-#include "interface.h"
-#include "hugs.h"
 #include "errors.h"
-#include <setjmp.h>
-#include <ctype.h>
+#include "version.h"
+#include "link.h"
+
+#include "Rts.h"
+#include "RtsAPI.h"
+#include "Schedule.h"
 
-#include <stdio.h>
 
-#include "machdep.h"
+Bool haskell98 = TRUE;                  /* TRUE => Haskell 98 compatibility*/
 
 /* --------------------------------------------------------------------------
  * Local function prototypes:
@@ -51,12 +50,20 @@ static Void   local readScripts       Args((Int));
 static Void   local whatScripts       Args((Void));
 static Void   local editor            Args((Void));
 static Void   local find              Args((Void));
+static Bool   local startEdit         Args((Int,String));
 static Void   local runEditor         Args((Void));
+#if IGNORE_MODULES
+#define findEvalModule() doNothing()
+#else
 static Void   local setModule         Args((Void));
 static Module local findEvalModule    Args((Void));
+#endif
 static Void   local evaluator         Args((Void));
+static Void   local stopAnyPrinting   Args((Void));
 static Void   local showtype          Args((Void));
+static String local objToStr          Args((Module, Cell));
 static Void   local info              Args((Void));
+static Void   local printSyntax       Args((Name));
 static Void   local showInst          Args((Inst));
 static Void   local describe          Args((Text));
 static Void   local listNames         Args((Void));
@@ -85,6 +92,7 @@ static String local strCopy           Args((String));
  * Machine dependent code for Hugs interpreter:
  * ------------------------------------------------------------------------*/
 
+#include "machdep.c"
 #ifdef WANT_TIMER
 #include "timer.c"
 #endif
@@ -93,8 +101,11 @@ static String local strCopy           Args((String));
  * Local data areas:
  * ------------------------------------------------------------------------*/
 
+static Bool   printing     = FALSE;     /* TRUE => currently printing value*/
+static Bool   showStats    = FALSE;     /* TRUE => print stats after eval  */
 static Bool   listScripts  = TRUE;      /* TRUE => list scripts after loading*/
-static Bool   addType     = FALSE;     /* TRUE => print type with value   */
+static Bool   addType      = FALSE;     /* TRUE => print type with value   */
+static Bool   useShow      = TRUE;      /* TRUE => use Text/show printer   */
 static Bool   chaseImports = TRUE;      /* TRUE => chase imports on load   */
 static Bool   useDots      = RISCOS;    /* TRUE => use dots in progress    */
 static Bool   quiet        = FALSE;     /* TRUE => don't show progress     */
@@ -154,39 +165,13 @@ char *argv[]; {
 
     CStackBase = &argc;                 /* Save stack base for use in gc   */
 
-    /* The startup banner now includes my name.  Hugs is provided free of  */
-    /* charge.  I ask however that you show your appreciation for the many */
-    /* hours of work involved by retaining my name in the banner.  Thanks! */
+    Printf("__   __ __  __  ____   ___     _______________________________________________\n");
+    Printf("||   || ||  || ||  || ||__     Hugs 98: The Nottingham and Yale Haskell system\n");
+    Printf("||___|| ||__|| ||__||  __||    Copyright (c) 1994-1999\n");
+    Printf("||---||         ___||          World Wide Web: http://haskell.org/hugs\n");
+    Printf("||   ||                        Report bugs to: hugs-bugs@haskell.org\n");
+    Printf("||   || Version: %s _______________________________________________\n\n",HUGS_VERSION);
 
-#if SMALL_BANNER
-    Printf("Hugs 1.4, %s release.\n", HUGS_VERSION);
-    Printf("Copyright (c) The University of Nottingham and Yale University, 1994-1998.\n");
-    Printf("Home page: http://haskell.org/hugs.  Bug reports: hugs-bugs@haskell.org.\n");
-#else
-#ifdef OLD_LOGO
-    Printf("      ___    ___   ___    ___   __________   __________                        \n");
-    Printf("     /  /   /  /  /  /   /  /  /  _______/  /  _______/         Hugs 1.4       \n");
-    Printf("    /  /___/  /  /  /   /  /  /  / _____   /  /______                          \n"); 
-    Printf("   /  ____   /  /  /   /  /  /  / /_   /  /______   /  The Nottingham and Yale\n");
-    Printf("  /  /   /  /  /  /___/  /  /  /___/  /  _______/  /    Haskell User's System \n");     
-    Printf(" /__/   /__/  /_________/  /_________/  /_________/         %s\n\n", HUGS_VERSION);
-    Printf("Copyright (c) The University of Nottingham and Yale University, 1994-1998.\n");
-    Printf("Home page: http://haskell.org/hugs.  Bug reports: hugs-bugs@haskell.org.\n");
-#else
-    /* There is now a new banner, designed to draw attention to the fact   */
-    /* that the version of Hugs being used is substantially different from */
-    /* previous releases (and to correct the mistaken view that Hugs is    */
-    /* written in capitals).  If you really prefer the old style banner,   */
-    /* you can still get it by compiling with -DOLD_LOGO.                  */
-
-    printf("  __   __ __  __  ____   ___     __________________________________________\n");
-    printf("  ||   || ||  || ||  || ||__     Hugs 1.4: The Haskell User's Gofer System\n");
-    printf("  ||___|| ||__|| ||__||  __||    (c) The University of Nottingham\n");
-    printf("  ||---||         ___||              and Yale University, 1994-1998.\n");
-    printf("  ||   ||                        Report bugs to hugs-bugs@haskell.org\n");
-    printf("  ||   ||     "HUGS_VERSION"      __________________________________________\n\n");
-#endif
-#endif
 #if SYMANTEC_C
     Printf("   Ported to Macintosh by Hans Aberg, compiled " __DATE__ ".\n\n");
 #endif
@@ -217,7 +202,6 @@ String argv[]; {
     scriptFile    = 0;
     numScripts    = 0;
     namesUpto     = 1;
-    initCharTab();
 
 #if HUGS_FOR_WINDOWS
     hugsEdit      = strCopy(fromEnv("EDITOR","c:\\windows\notepad.exe"));
@@ -226,11 +210,13 @@ String argv[]; {
 #else
     hugsEdit      = strCopy(fromEnv("EDITOR",NULL));
 #endif
-    hugsPath      = strCopy(HUGSPATH);
-    readOptions("-p\"%s> \" -r$$");
+    hugsPath      = strCopy(HUGSPATH); readOptions("-p\"%s> \" -r$$");
 #if USE_REGISTRY
-    readOptions(readRegString("Options",""));
-#endif
+    projectPath   = strCopy(readRegChildStrings(HKEY_LOCAL_MACHINE,ProjectRoot,
+                                                "HUGSPATH", PATHSEP, ""));
+    readOptions(readRegString(HKEY_LOCAL_MACHINE,HugsRoot,"Options",""));
+    readOptions(readRegString(HKEY_CURRENT_USER, HugsRoot,"Options",""));
+#endif /* USE_REGISTRY */
     readOptions(fromEnv("HUGSFLAGS",""));
 
     for (i=1; i<argc; ++i) {            /* process command line arguments  */
@@ -241,7 +227,8 @@ String argv[]; {
             } else {
                 proj = argv[++i];
             }
-        } else if (!processOption(argv[i])) {
+        } else if (argv[i] && argv[i][0]/* workaround for /bin/sh silliness*/
+                 && !processOption(argv[i])) {
             addScriptName(argv[i],TRUE);
         }
     }
@@ -254,13 +241,19 @@ String argv[]; {
     DEBUG_LoadSymbols(argv[0]);
 #endif
 
-    scriptName[0] = strCopy(findMPathname(NULL,STD_PRELUDE));
+    scriptName[0] = strCopy(findMPathname(NULL,STD_PRELUDE,hugsPath));
     if (!scriptName[0]) {
         Printf("Prelude not found on current path: \"%s\"\n",
                hugsPath ? hugsPath : "");
         fatal("Unable to load prelude");
     }
 
+    if (haskell98) {
+        Printf("Haskell 98 mode: Restart with command line option -98 to enable extensions\n\n");
+    } else {
+        Printf("Hugs mode: Restart with command line option +98 for Haskell 98 mode\n\n");
+    }
     everybody(INSTALL);
     evalModule = findText("");      /* evaluate wrt last module by default */
     if (proj) {
@@ -328,9 +321,13 @@ static Void local optionInfo() {        /* Print information about command */
     Printf(fmts,"rstr","Set repeat last expression string to str");
     Printf(fmts,"Pstr","Set search path for modules to str");
     Printf(fmts,"Estr","Use editor setting given by str");
+    Printf(fmts,"cnum","Set constraint cutoff limit");
 #if USE_PREPROCESSOR  && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
     Printf(fmts,"Fstr","Set preprocessor filter to str");
 #endif
+#if PROFILING
+    Printf(fmts,"dnum","Gather profiling statistics every <num> reductions\n");
+#endif
 
     Printf("\nCurrent settings: ");
     togglesIn(TRUE);
@@ -340,14 +337,26 @@ static Void local optionInfo() {        /* Print information about command */
     printString(prompt);
     Printf(" -r");
     printString(repeatStr);
+    Printf(" -c%d",cutoff);
     Printf("\nSearch path     : -P");
     printString(hugsPath);
+#if 0
+ToDo
+    if (projectPath!=NULL) {
+        Printf("\nProject Path    : %s",projectPath);
+    }
+#endif
     Printf("\nEditor setting  : -E");
     printString(hugsEdit);
 #if USE_PREPROCESSOR  && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
     Printf("\nPreprocessor    : -F");
     printString(preprocessor);
 #endif
+#if PROFILING
+    Printf("\nProfile interval: -d%d", profiling ? profInterval : 0);
+#endif
+    Printf("\nCompatibility   : %s", haskell98 ? "Haskell 98"
+                                               : "Hugs Extensions");
     Putchar('\n');
 }
 
@@ -400,9 +409,13 @@ static String local optionsToStr() {          /* convert options to string */
     PUTStr('r',repeatStr);
     PUTStr('P',hugsPath);
     PUTStr('E',hugsEdit);
+    PUTInt('c',cutoff);  PUTC(' ');
 #if USE_PREPROCESSOR  && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
     PUTStr('F',preprocessor);
 #endif
+#if PROFILING
+    PUTInt('d',profiling ? profInterval : 0);
+#endif
     PUTC('\0');
     return buffer;
 }
@@ -479,7 +492,17 @@ String s; {                             /* return FALSE if none found.     */
                     return TRUE;
                 }
 
-            default  : toggleSet(*s,state);
+            default  : if (strcmp("98",s)==0) {
+                           if (heapBuilt() && ((state && !haskell98) ||
+                                               (!state && haskell98))) {
+                               FPrintf(stderr,"Haskell 98 compatibility cannot be changed while the interpreter is running\n");
+                           } else {
+                               haskell98 = state;
+                           }
+                           return TRUE;
+                       } else {
+                           toggleSet(*s,state);
+                       }
                        break;
         }
     return TRUE;
@@ -574,8 +597,9 @@ static struct cmd cmds[] = {
  {":reload", RELOAD}, {":gc",   COLLECT}, {":edit",    EDIT},
  {":quit",   QUIT},   {":set",  SET},     {":find",    FIND},
  {":names",  NAMES},  {":info", INFO},    {":project", PROJECT},
- {":module", SETMODULE}, 
- {":version", SHOWVERSION}, 
+#if !IGNORE_MODULES
+ {":module",SETMODULE}, 
+#endif
  {"",      EVAL},
  {0,0}
 };
@@ -590,10 +614,11 @@ static Void local menu() {
     Printf(":project <filename> use project file\n");
     Printf(":edit <filename>    edit file\n");
     Printf(":edit               edit last module\n");
+#if !IGNORE_MODULES
     Printf(":module <module>    set module for evaluating expressions\n");
+#endif
     Printf("<expr>              evaluate expression\n");
     Printf(":type <expr>        print type of expression\n");
-    Printf(":version            show Hugs version\n");
     Printf(":?                  display this list of commands\n");
     Printf(":set <options>      set command line options\n");
     Printf(":set                help on command line options\n");
@@ -619,8 +644,10 @@ static Void local forHelp() {
  * Setting of command line options:
  * ------------------------------------------------------------------------*/
 
-struct options toggle[] = {             /* List of command line toggles    */ 
-    {'t', "Print type after evaluation",          &addType},
+struct options toggle[] = {             /* List of command line toggles    */
+    {'s', "Print no. reductions/cells after eval", &showStats},
+    {'t', "Print type after evaluation",           &addType},
+    /*ToDo??    {'f', "Terminate evaluation on first error",   &failOnError},*/
     {'g', "Print no. cells recovered after gc",    &gcMessages},
     {'l', "Literate modules as default",           &literateScripts},
     {'e', "Warn about errors in literate modules", &literateErrors},
@@ -722,9 +749,13 @@ Long   len; {                           /* length of script file           */
     Printf("Reading file \"%s\":\n",fname);
     setLastEdit(fname,0);
 
+#if 0
+ToDo: reinstate
     if (isInterfaceFile(fname)) {
         loadInterface(fname);
-    } else {
+    } else
+#else
+           {
         needsImports = FALSE;
         parseScript(fname,len);         /* process script file             */
         if (needsImports)
@@ -733,6 +764,7 @@ Long   len; {                           /* length of script file           */
         typeCheckDefns();
         compileDefns();
     }
+#endif
     scriptFile = 0;
     return TRUE;
 }
@@ -944,6 +976,7 @@ Int    line; {
  * Read and evaluate an expression:
  * ------------------------------------------------------------------------*/
 
+#if !IGNORE_MODULES
 static Void local setModule(){/*set module in which to evaluate expressions*/
     String s = readFilename();
     if (!s) s = "";              /* :m clears the current module selection */
@@ -953,15 +986,16 @@ static Void local setModule(){/*set module in which to evaluate expressions*/
 
 static Module local findEvalModule() { /*Module in which to eval expressions*/
     Module m = findModule(evalModule); 
-    if (isNull(m)) {
+    if (isNull(m))
         m = lastModule();
-    }
     return m;
 }
+#endif
 
 static Void local evaluator() {        /* evaluate expr and print value    */
     Type  type, bd;
-    Kinds ks = NIL;
+    Kinds ks   = NIL;
+    Cell  temp = NIL;
 
     setCurrModule(findEvalModule());
     scriptFile = 0;
@@ -980,13 +1014,18 @@ static Void local evaluator() {        /* evaluate expr and print value    */
 
     if (whatIs(bd)==QUAL) {
         ERRMSG(0) "Unresolved overloading" ETHEN
-        ERRTEXT   "\n*** type       : "    ETHEN ERRTYPE(type);
-        ERRTEXT   "\n*** expression : "    ETHEN ERREXPR(inputExpr);
+        ERRTEXT   "\n*** Type       : "    ETHEN ERRTYPE(type);
+        ERRTEXT   "\n*** Expression : "    ETHEN ERREXPR(inputExpr);
         ERRTEXT   "\n"
         EEND;
     }
-    
-    /* ToDo: restore the code to print types, use show, etc */
+  
+#if PROFILING
+    if (profiling)
+        profilerLog("profile.hp");
+    numReductions = 0;
+    garbageCollect();
+#endif
 
 #ifdef WANT_TIMER
     updateTimers();
@@ -1015,6 +1054,24 @@ static Void local evaluator() {        /* evaluate expr and print value    */
     }
 }
 
+static Void local stopAnyPrinting() {  /* terminate printing of expression,*/
+    if (printing) {                    /* after successful termination or  */
+        printing = FALSE;              /* runtime error (e.g. interrupt)   */
+        Putchar('\n');
+        if (showStats) {
+#define plural(v)   v, (v==1?"":"s")
+         /* Printf("(%lu reduction%s, ",plural(numReductions)); */
+            Printf("%lu cell%s",plural(numCells));
+            if (numGcs>0)
+                Printf(", %u garbage collection%s",plural(numGcs));
+            Printf(")\n");
+#undef plural
+        }
+        FlushStdout();
+        garbageCollect();
+    }
+}
+
 /* --------------------------------------------------------------------------
  * Print type of input expression:
  * ------------------------------------------------------------------------*/
@@ -1040,47 +1097,55 @@ static Void local showtype() {         /* print type of expression (if any)*/
  * about an object.
  * ------------------------------------------------------------------------*/
 
-static String local objToStr Args((Module, Cell));
-
 static String local objToStr(m,c)
 Module m;
 Cell   c; {
-#if DISPLAY_QUANTIFIERS
+#if 1 || DISPLAY_QUANTIFIERS
     static char newVar[60];
     switch (whatIs(c)) {
-    case NAME  : if (m == name(c).mod) {
-                     sprintf(newVar,"%s",   textToStr(name(c).text));
-                 } else {
-                     sprintf(newVar,"%s.%s",textToStr(module(name(c).mod).text),
-                                            textToStr(name(c).text));
-                 }
-                 break;
-    case TYCON : if (m == tycon(c).mod) {
-                     sprintf(newVar,"%s",   textToStr(tycon(c).text));
-                 } else {
-                     sprintf(newVar,"%s.%s",textToStr(module(tycon(c).mod).text),
-                                            textToStr(tycon(c).text));
-                 }
-                 break;
-    case CLASS : if (m == cclass(c).mod) {
-                     sprintf(newVar,"%s",   textToStr(cclass(c).text));
-                 } else {
-                     sprintf(newVar,"%s.%s",textToStr(module(cclass(c).mod).text),
-                                            textToStr(cclass(c).text));
-                 }
-                 break;
-    default    : internal("objToStr");
+        case NAME  : if (m == name(c).mod) {
+                         sprintf(newVar,"%s", textToStr(name(c).text));
+                     } else {
+                         sprintf(newVar,"%s.%s",
+                                        textToStr(module(name(c).mod).text),
+                                        textToStr(name(c).text));
+                     }
+                     break;
+
+        case TYCON : if (m == tycon(c).mod) {
+                         sprintf(newVar,"%s", textToStr(tycon(c).text));
+                     } else {
+                         sprintf(newVar,"%s.%s",
+                                        textToStr(module(tycon(c).mod).text),
+                                        textToStr(tycon(c).text));
+                     }
+                     break;
+
+        case CLASS : if (m == cclass(c).mod) {
+                         sprintf(newVar,"%s", textToStr(cclass(c).text));
+                     } else {
+                         sprintf(newVar,"%s.%s",
+                                        textToStr(module(cclass(c).mod).text),
+                                        textToStr(cclass(c).text));
+                     }
+                     break;
+
+        default    : internal("objToStr");
     }
     return newVar;
 #else
     static char newVar[33];
     switch (whatIs(c)) {
-    case NAME  : sprintf(newVar,"%s",   textToStr(name(c).text));
-                 break;
-    case TYCON : sprintf(newVar,"%s",   textToStr(tycon(c).text));
-                 break;
-    case CLASS : sprintf(newVar,"%s",   textToStr(cclass(c).text));
-    default    : internal("objToStr");
+        case NAME  : sprintf(newVar,"%s", textToStr(name(c).text));
+                     break;
+
+        case TYCON : sprintf(newVar,"%s", textToStr(tycon(c).text));
+                     break;
+
+        case CLASS : sprintf(newVar,"%s", textToStr(cclass(c).text));
+                     break;
+
+        default    : internal("objToStr");
     }
     return newVar;
 #endif
@@ -1102,17 +1167,17 @@ static Void local info() {              /* describe objects                */
 
 static Void local describe(t)           /* describe an object              */
 Text t; {
-    Tycon tc = findTycon(t);
-    Class cl = findClass(t);
-    Name  nm = findName(t);
+    Tycon  tc  = findTycon(t);
+    Class  cl  = findClass(t);
+    Name   nm  = findName(t);
     Module mod = findEvalModule();
 
     if (nonNull(tc)) {                  /* as a type constructor           */
-        Type ty = tc;
+        Type t = tc;
         Int  i;
         Inst in;
         for (i=0; i<tycon(tc).arity; ++i) {
-            ty = ap(ty,mkOffset(i));
+            t = ap(t,mkOffset(i));
         }
         Printf("-- type constructor");
         if (kindExpert) {
@@ -1122,7 +1187,7 @@ Text t; {
         Putchar('\n');
         switch (tycon(tc).what) {
             case SYNONYM      : Printf("type ");
-                                printType(stdout,ty);
+                                printType(stdout,t);
                                 Printf(" = ");
                                 printType(stdout,tycon(tc).defn);
                                 break;
@@ -1134,9 +1199,11 @@ Text t; {
                                     } else {
                                         Printf("newtype ");
                                     }
-                                    printType(stdout,ty);
+                                    printType(stdout,t);
+                                    Putchar('\n');
+                                    mapProc(printSyntax,cs);
                                     if (hasCfun(cs)) {
-                                        Printf("\n\n-- constructors:");
+                                        Printf("\n-- constructors:");
                                     }
                                     for (; hasCfun(cs); cs=tl(cs)) {
                                         Putchar('\n');
@@ -1145,7 +1212,7 @@ Text t; {
                                         printType(stdout,name(hd(cs)).type);
                                     }
                                     if (nonNull(cs)) {
-                                        Printf("\n\n-- selectors:");
+                                        Printf("\n-- selectors:");
                                     }
                                     for (; nonNull(cs); cs=tl(cs)) {
                                         Putchar('\n');
@@ -1157,7 +1224,7 @@ Text t; {
                                 break;
 
             case RESTRICTSYN  : Printf("type ");
-                                printType(stdout,ty);
+                                printType(stdout,t);
                                 Printf(" = <restricted>");
                                 break;
         }
@@ -1176,28 +1243,30 @@ Text t; {
         List  ins = cclass(cl).instances;
         Kinds ks  = cclass(cl).kinds;
         if (nonNull(ks) && isNull(tl(ks)) && hd(ks)==STAR) {
-            printf("-- type class");
+            Printf("-- type class");
         } else {
-            printf("-- constructor class");
+            Printf("-- constructor class");
             if (kindExpert) {
-                printf(" with arity ");
+                Printf(" with arity ");
                 printKinds(stdout,ks);
             }
         }
-        printf("\nclass ");
+        Putchar('\n');
+        mapProc(printSyntax,cclass(cl).members);
+        Printf("class ");
         if (nonNull(cclass(cl).supers)) {
             printContext(stdout,cclass(cl).supers);
-            printf(" => ");
+            Printf(" => ");
         }
         printPred(stdout,cclass(cl).head);
         if (nonNull(cclass(cl).members)) {
             List ms = cclass(cl).members;
-            printf(" where");
+            Printf(" where");
             do {
                 Type t = monotypeOf(name(hd(ms)).type);
-                printf("\n  ");
+                Printf("\n  ");
                 printExp(stdout,hd(ms));
-                printf(" :: ");
+                Printf(" :: ");
                 if (isNull(tl(fst(snd(t))))) {
                     t = snd(snd(t));
                 } else {
@@ -1207,37 +1276,41 @@ Text t; {
                 ms = tl(ms);
             } while (nonNull(ms));
         }
-        putchar('\n');
+        Putchar('\n');
         if (nonNull(ins)) {
-            printf("\n-- instances:\n");
+            Printf("\n-- instances:\n");
             do {
                 showInst(hd(ins));
                 ins = tl(ins);
             } while (nonNull(ins));
         }
-        putchar('\n');
+        Putchar('\n');
     }
 
     if (nonNull(nm)) {                  /* as a function/name              */
+        printSyntax(nm);
         printExp(stdout,nm);
-        printf(" :: ");
+        Printf(" :: ");
         if (nonNull(name(nm).type)) {
             printType(stdout,name(nm).type);
         } else {
-            printf("<unknown type>");
+            Printf("<unknown type>");
         }
 
         if (isCfun(nm)) {
-            printf("  -- data constructor");
+            Printf("  -- data constructor");
         } else if (isMfun(nm)) {
-            printf("  -- class member");
+            Printf("  -- class member");
         } else if (isSfun(nm)) {
-            printf("  -- selector function");
+            Printf("  -- selector function");
         }
-        if (name(nm).primop) {
-            printf("   -- primitive");
+#if 0
+    ToDo: reinstate
+        if (name(nm).primDef) {
+            Printf("   -- primitive");
         }
-        printf("\n\n");
+#endif
+        Printf("\n\n");
     }
 
     if (isNull(tc) && isNull(cl) && isNull(nm)) {
@@ -1245,15 +1318,37 @@ Text t; {
     }
 }
 
+static Void local printSyntax(nm)
+Name nm; {
+    Syntax sy = syntaxOf(nm);
+    Text   t  = name(nm).text;
+    String s  = textToStr(t);
+    if (sy != defaultSyntax(t)) {
+        Printf("infix");
+        switch (assocOf(sy)) {
+            case LEFT_ASS  : Putchar('l'); break;
+            case RIGHT_ASS : Putchar('r'); break;
+            case NON_ASS   : break;
+        }
+        Printf(" %i ",precOf(sy));
+        if (isascii(*s) && isalpha(*s)) {
+            Printf("`%s`",s);
+        } else {
+            Printf("%s",s);
+        }
+        Putchar('\n');
+    }
+}
+
 static Void local showInst(in)          /* Display instance decl header    */
 Inst in; {
-    printf("instance ");
+    Printf("instance ");
     if (nonNull(inst(in).specifics)) {
         printContext(stdout,inst(in).specifics);
-        printf(" => ");
+        Printf(" => ");
     }
     printPred(stdout,inst(in).head);
-    putchar('\n');
+    Putchar('\n');
 }
 
 /* --------------------------------------------------------------------------
@@ -1367,12 +1462,11 @@ String argv[]; {
                           break;
             case PROJECT: project();
                           break;
+#if !IGNORE_MODULES
             case SETMODULE :
                           setModule();
                           break;
-            case SHOWVERSION :
-                          Printf("Hugs 1.4, %s release.\n", HUGS_VERSION);
-                          break;
+#endif
             case EVAL   : evaluator();
                           break;
             case TYPEOF : showtype();
@@ -1385,7 +1479,7 @@ String argv[]; {
                           break;
             case SET    : set();
                           break;
-            case SYSTEM : if (shellEsc(readLine())) 
+            case SYSTEM : if (shellEsc(readLine()))
                               Printf("Warning: Shell escape terminated abnormally\n");
                           break;
             case CHGDIR : changeDir();
@@ -1407,6 +1501,7 @@ String argv[]; {
                millisecs(userElapsed), millisecs(systElapsed));
 #endif
     }
+    breakOn(FALSE);
 }
 
 /* --------------------------------------------------------------------------
@@ -1487,6 +1582,7 @@ static Void local failed() {           /* Goal cannot be reached due to    */
 Void errHead(l)                        /* print start of error message     */
 Int l; {
     failed();                          /* failed to reach target ...       */
+    stopAnyPrinting();
     FPrintf(errorStream,"ERROR");
 
     if (scriptFile) {
@@ -1507,7 +1603,8 @@ Void errFail() {                        /* terminate error message and     */
 
 Void errAbort() {                       /* altern. form of error handling  */
     failed();                           /* used when suitable error message*/
-    errFail();                          /* has already been printed        */
+    stopAnyPrinting();                  /* has already been printed        */
+    errFail();
 }
 
 Void internal(msg)                      /* handle internal error           */
@@ -1518,6 +1615,7 @@ String msg; {
     MessageBox(hWndMain, buf, appName, MB_ICONHAND | MB_OK);
 #endif
     failed();
+    stopAnyPrinting();
     Printf("INTERNAL ERROR: %s\n",msg);
     FlushStdout();
     longjmp(catch_error,1);
@@ -1543,9 +1641,11 @@ sigHandler(breakHandler) {              /* respond to break interrupt      */
     Hilite();
     Printf("{Interrupted!}\n");
     Lolite();
-    breakOn(TRUE);
+    breakOn(TRUE);  /* reinstall signal handler - redundant on BSD systems */
+                    /* but essential on POSIX (and other?) systems         */
     everybody(BREAK);
     failed();
+    stopAnyPrinting();
     FlushStdout();
     clearerr(stdin);
     longjmp(catch_error,1);
@@ -1745,6 +1845,25 @@ FILE* fp; {
 }
     
 #endif /* REDIRECT_OUTPUT && !HUGS_FOR_WINDOWS */
+/* --------------------------------------------------------------------------
+ * Send message to each component of system:
+ * ------------------------------------------------------------------------*/
+
+Void everybody(what)            /* send command `what' to each component of*/
+Int what; {                     /* system to respond as appropriate ...    */
+    machdep(what);              /* The order of calling each component is  */
+    storage(what);              /* important for the INSTALL command       */
+    substitution(what);
+    input(what);
+    linkControl(what);
+    staticAnalysis(what);
+    deriveControl(what);
+    typeChecker(what);
+    translateControl(what);
+    compiler(what);   
+    codegen(what);
+}
+
 
 /* --------------------------------------------------------------------------
  * Hugs for Windows code (WinMain and related functions)
index 94e8542..5294b35 100644 (file)
@@ -1,34 +1,28 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Input functions, lexical analysis parsing etc...
  *
- * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
- * All rights reserved. See NOTICE for details and conditions of use etc...
- * Hugs version 1.4, December 1997
+ * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
+ * Haskell Group 1994-99, and is distributed as Open Source software
+ * under the Artistic License; see the file "Artistic" that is included
+ * in the distribution for details.
  *
  * $RCSfile: input.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:12 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:30 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
 #include "storage.h"
+#include "backend.h"
 #include "connect.h"
-#include "charset.h"
-#include "input.h"
-#include "static.h"
-#include "interface.h"
 #include "command.h"
 #include "errors.h"
-#include "link.h"
-#include "hugs.h"    /* for target */
 #include <ctype.h>
 #if HAVE_GETDELIM_H
 #include "getdelim.h"
 #endif
 
-#include "machdep.h" /* for findPathname */
-
 #if HUGS_FOR_WINDOWS
 #undef IN
 #endif
@@ -40,7 +34,6 @@
 List tyconDefns      = NIL;             /* type constructor definitions    */
 List typeInDefns     = NIL;             /* type synonym restrictions       */
 List valDefns        = NIL;             /* value definitions in script     */
-List opDefns         = NIL;             /* operator defns in script        */
 List classDefns      = NIL;             /* class defns in script           */
 List instDefns       = NIL;             /* instance defns in script        */
 List selDefns        = NIL;             /* list of selector lists          */
@@ -66,6 +59,7 @@ String preprocessor  = 0;
  * Local function prototypes:
  * ------------------------------------------------------------------------*/
 
+static Void local initCharTab     Args((Void));
 static Void local fileInput       Args((String,Long));
 static Bool local literateMode    Args((String));
 static Bool local linecmp         Args((String,String));
@@ -122,41 +116,106 @@ static Text textBar,     textMinus,    textFrom,   textArrow,  textLazy;
 static Text textBang,    textDot,      textAll,    textImplies;
 static Text textWildcard;
 
-static Text textModule,  textImport,    textPrelude, textPreludeHugs;
+static Text textModule,  textImport;
 static Text textHiding,  textQualified, textAsMod;
 static Text textExport,  textInterface, textRequires, textUnsafe;
 
-#if    NPLUSK
+Text   textNum;                         /* Num                             */
+Text   textPrelude;                     /* Prelude                         */
 Text   textPlus;                        /* (+)                             */
-#endif
-Cell   conPrelude;                      /* Prelude                         */
 
 static Cell conMain;                    /* Main                            */
 static Cell varMain;                    /* main                            */
 
-static Cell conUnit;                    /* ()                              */
-static Cell conList;                    /* []                              */
-static Cell conNil;                     /* []                              */
-static Cell conPreludeUnit;             /* Prelude.()                      */
-static Cell conPreludeList;             /* Prelude.[]                      */
-static Cell conPreludeNil;              /* Prelude.[]                      */
-
 static Cell varMinus;                   /* (-)                             */
+static Cell varPlus;                    /* (+)                             */
 static Cell varBang;                    /* (!)                             */
 static Cell varDot;                     /* (.)                             */
 static Cell varHiding;                  /* hiding                          */
 static Cell varQualified;               /* qualified                       */
 static Cell varAsMod;                   /* as                              */
 
-static Cell varNegate;
-static Cell varFlip;        
-static Cell varEnumFrom;
-static Cell varEnumFromThen;
-static Cell varEnumFromTo;
-static Cell varEnumFromThenTo;
-
 static List imps;                       /* List of imports to be chased    */
 
+
+/* --------------------------------------------------------------------------
+ * Character set handling:
+ *
+ * Hugs follows Haskell 1.3 in assuming that input uses the ISO-8859-1
+ * character set.  The following code provides methods for classifying
+ * input characters according to the lexical structure specified by the
+ * report.  Hugs should still accept older programs because ASCII is
+ * essentially just a subset of the ISO character set.
+ *
+ * Notes: If you want to port Hugs to a machine that uses something
+ * substantially different from the ISO character set, then you will need
+ * to insert additional code to map between character sets.
+ *
+ * At some point, the following data structures may be exported in a .h
+ * file to allow the information contained here to be picked up in the
+ * implementation of LibChar is* primitives.
+ *
+ * Relies, implicitly but for this comment, on assumption that NUM_CHARS=256.
+ * ------------------------------------------------------------------------*/
+
+static  Bool            charTabBuilt;
+static  unsigned char   ctable[NUM_CHARS];
+#define isIn(c,x)       (ctable[(unsigned char)(c)]&(x))
+#define isISO(c)        (0<=(c) && (c)<NUM_CHARS)
+
+#define DIGIT           0x01
+#define SMALL           0x02
+#define LARGE           0x04
+#define SYMBOL          0x08
+#define IDAFTER         0x10
+#define SPACE           0x20
+#define PRINT           0x40
+
+static Void local initCharTab() {       /* Initialize char decode table    */
+#define setRange(x,f,t) {Int i=f;   while (i<=t) ctable[i++] |=x;}
+#define setChar(x,c)    ctable[c] |= (x)
+#define setChars(x,s)   {char *p=s; while (*p)   ctable[(Int)*p++]|=x;}
+#define setCopy(x,c)    {Int i;                         \
+                         for (i=0; i<NUM_CHARS; ++i)    \
+                             if (isIn(i,c))             \
+                                 ctable[i]|=x;          \
+                        }
+
+    setRange(DIGIT,     '0','9');       /* ASCII decimal digits            */
+
+    setRange(SMALL,     'a','z');       /* ASCII lower case letters        */
+    setRange(SMALL,     223,246);       /* ISO lower case letters          */
+    setRange(SMALL,     248,255);       /* (omits division symbol, 247)    */
+    setChar (SMALL,     '_');
+
+    setRange(LARGE,     'A','Z');       /* ASCII upper case letters        */
+    setRange(LARGE,     192,214);       /* ISO upper case letters          */
+    setRange(LARGE,     216,222);       /* (omits multiplication, 215)     */
+
+    setRange(SYMBOL,    161,191);       /* Symbol characters + ':'         */
+    setRange(SYMBOL,    215,215);
+    setChar (SYMBOL,    247);
+    setChars(SYMBOL,    ":!#$%&*+./<=>?@\\^|-~");
+
+    setChar (IDAFTER,   '\'');          /* Characters in identifier        */
+    setCopy (IDAFTER,   (DIGIT|SMALL|LARGE));
+
+    setChar (SPACE,     ' ');           /* ASCII space character           */
+    setChar (SPACE,     160);           /* ISO non breaking space          */
+    setRange(SPACE,     9,13);          /* special whitespace: \t\n\v\f\r  */
+
+    setChars(PRINT,     "(),;[]_`{}");  /* Special characters              */
+    setChars(PRINT,     " '\"");        /* Space and quotes                */
+    setCopy (PRINT,     (DIGIT|SMALL|LARGE|SYMBOL));
+
+    charTabBuilt = TRUE;
+#undef setRange
+#undef setChar
+#undef setChars
+#undef setCopy
+}
+
+
 /* --------------------------------------------------------------------------
  * Single character input routines:
  *
@@ -186,11 +245,11 @@ static String nextStringChar;          /* next char in string buffer       */
 #if     USE_READLINE                   /* for command line editors         */
 static  String currentLine;            /* editline or GNU readline         */
 static  String nextChar;
-#define nextConsoleChar()   (unsigned char)(*nextChar=='\0' ? '\n' : *nextChar++)
-extern  Void add_history    Args((String));
-extern  String readline     Args((String));
+#define nextConsoleChar() (unsigned char)(*nextChar=='\0' ? '\n' : *nextChar++)
+extern  Void add_history  Args((String));
+extern  String readline   Args((String));
 #else
-#define nextConsoleChar()   getc(stdin)
+#define nextConsoleChar() getc(stdin)
 #endif
 
 static  Int litLines;                  /* count defn lines in lit script   */
@@ -266,12 +325,17 @@ String nm;                              /* named file (specified length is */
 Long   len; {                           /* used to set target for reading) */
 #if USE_PREPROCESSOR && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
     if (preprocessor) {
-        char cmd[100];
-        strncpy(cmd,preprocessor,100);
-        strncat(cmd," ",100);
-        strncat(cmd,nm,100);
-        cmd[99] = '\0'; /* paranoia */
+        Int reallen = strlen(preprocessor) + 1 + strlen(nm) + 1;
+        char *cmd = malloc(reallen);
+        if (cmd == NULL) {
+            ERRMSG(0) "Unable to allocate memory for filter command."
+            EEND;
+        }
+        strcpy(cmd,preprocessor);
+        strcat(cmd," ");
+        strcat(cmd,nm);
         inputStream = popen(cmd,"r");
+        free(cmd);
     } else {
         inputStream = fopen(nm,"r");
     }
@@ -312,9 +376,11 @@ String s; {
     row          = 1;
 
     nextStringChar = s;
+    if (!charTabBuilt)
+        initCharTab();
 }
 
-static Bool local literateMode(nm)      /* select literate mode for file   */
+static Bool local literateMode(nm)      /* Select literate mode for file   */
 String nm; {
     char *dot = strrchr(nm,'.');        /* look for last dot in file name  */
     if (dot) {
@@ -327,12 +393,6 @@ String nm; {
     return literateScripts;             /* otherwise, use the default      */
 }
 
-Bool isInterfaceFile(nm)                /* is nm an interface file?        */
-String nm; {
-    char *dot = strrchr(nm,'.');        /* look for last dot in file name  */
-    return (dot && filenamecmp(dot+1,"myhi")==0);
-}
-
 
 /* This code originally came from Sigbjorn Finne (sof@dcs.gla.ac.uk).
  * I've removed the loop (since newLineSkip contains a loop too) and
@@ -508,7 +568,7 @@ static Void local newlineSkip() {      /* skip `\n' (supports lit scripts) */
                 litLines++;
                 return;
             }
-            while (c0==' ' || c0=='\t')/* maybe line is blank?             */
+            while (c0 != '\n' && isIn(c0,SPACE)) /* maybe line is blank?   */
                 skip();
             if (c0=='\n' || c0==EOF)
                 thisLineIs(BLANKLINE);
@@ -566,7 +626,7 @@ static Void local closeAnyInput() {    /* Close input stream, if open,     */
  * entry to the routine.
  * ------------------------------------------------------------------------*/
 
-#define MAX_TOKEN           500
+#define MAX_TOKEN           4000
 #define startToken()        tokPos = 0
 #define saveTokenChar(c)    if (tokPos<=MAX_TOKEN) saveChar(c); else ++tokPos
 #define saveChar(c)         tokenStr[tokPos++]=(char)(c)
@@ -610,29 +670,43 @@ static Text local readIdent() {        /* read identifier                  */
 static Cell local readRadixNumber(r)   /* Read literal in specified radix  */
 Int r; {                               /* from input of the form 0c{digs}  */
     Int d;                                                                 
-    startToken();
-    saveTokenChar(c0);
     skip();                            /* skip leading zero                */
-    if ((d=readHexDigit(c1))<0 || d>=r) {
-        /* Special case; no digits, lex as  */
-        /* if it had been written "0 c..."  */
-        saveTokenChar('0');
-    } else {
+    if ((d=readHexDigit(c1))<0 || d>=r)/* Special case; no digits, lex as  */
+        return mkInt(0);               /* if it had been written "0 c..."  */
+    else {
         Int  n = 0;
-        saveTokenChar(c0);
+#if BIGNUMS
+        Cell big = NIL;
+#endif
         skip();
         do {
-            saveTokenChar(c0);
+#if BIGNUMS
+            if (nonNull(big))
+                big = bigShift(big,d,r);
+            else if (overflows(n,r,d,MAXPOSINT))
+                big = bigShift(bigInt(n),d,r);
+            else
+#else
+            if (overflows(n,r,d,MAXPOSINT)) {
+                ERRMSG(row) "Integer literal out of range"
+                EEND;
+            }
+            else
+#endif
+                n = r*n + d;
             skip();
             d = readHexDigit(c0);
         } while (d>=0 && d<r);
+#if BIGNUMS
+        return nonNull(big) ? big : mkInt(n);
+#else
+        return mkInt(n);
+#endif
     }
-    endToken();
-    /* ToDo: return an INTCELL if small enough */
-    return stringToBignum(tokenStr);
 }
 
 static Cell local readNumber() {        /* read numeric constant           */
+    Int   n           = 0;
     Bool  intTooLarge = FALSE;
 
     if (c0=='0') {
@@ -644,14 +718,23 @@ static Cell local readNumber() {        /* read numeric constant           */
 
     startToken();
     do {
+        if (overflows(n,10,(c0-'0'),MAXPOSINT))
+            intTooLarge = TRUE;
+        n  = 10*n  + (c0-'0');
         saveTokenChar(c0);
         skip();
     } while (isISO(c0) && isIn(c0,DIGIT));
 
     if (c0!='.' || !isISO(c1) || !isIn(c1,DIGIT)) {
         endToken();
-        /* ToDo: return an INTCELL if small enough */
-        return stringToBignum(tokenStr);
+        if (!intTooLarge)
+            return mkInt(n);
+#if BIGNUMS
+        return bigStr(tokenStr);
+#else
+        ERRMSG(row) "Integer literal out of range"
+        EEND;
+#endif
     }
 
     saveTokenChar(c0);                  /* save decimal point              */
@@ -684,7 +767,12 @@ static Cell local readNumber() {        /* read numeric constant           */
     }
 
     endToken();
-    return stringToFloat(tokenStr);
+#ifndef HAVE_LIBM
+    ERRMSG(row) "No floating point numbers in this implementation"
+    EEND;
+#endif
+
+    return mkFloat(stringToFloat(tokenStr));
 }
 
 static Cell local readChar() {         /* read character constant          */
@@ -984,7 +1072,8 @@ String s; {                            /* escapes if any parts need them   */
     if (s) {                           
         String t = s;                  
         Char   c;                      
-        while ((c = *t)!=0 && isISO(c) && isIn(c,PRINT) && c!='"' && !isIn(c,SPACE)) {
+        while ((c = *t)!=0 && isISO(c)
+                           && isIn(c,PRINT) && c!='"' && !isIn(c,SPACE)) {
             t++;                       
         }
         if (*t) {                      
@@ -999,7 +1088,7 @@ String s; {                            /* escapes if any parts need them   */
 }                                      
                                        
 /* -------------------------------------------------------------------------
- * Handle special types of input for us in interpreter:
+ * Handle special types of input for use in interpreter:
  * -----------------------------------------------------------------------*/
                                        
 Command readCommand(cmds,start,sys)    /* read command at start of input   */
@@ -1056,8 +1145,9 @@ String readFilename() {                /* Read filename from input (if any)*/
             skip();
             while (c0!=EOF && c0!='\"') {
                 Cell c = readAChar(TRUE);
-                if (nonNull(c))
+                if (nonNull(c)) {
                     saveTokenChar(charOf(c));
+                }
             }
             if (c0=='"')
                 skip();
@@ -1211,10 +1301,11 @@ static Int local yylex() {             /* Read next input token ...        */
     push(yylval = mkInt(row));         /* default token value is line no.  */
     /* subsequent changes to yylval must also set top() to the same value  */
 
-    if (indentDepth>=0)                /* layout rule(s) active ?          */
+    if (indentDepth>=0) {              /* layout rule(s) active ?          */
         if (insertedToken)             /* avoid inserting multiple `;'s    */
             insertedToken = FALSE;     /* or putting `;' after `{'         */
-        else if (layout[indentDepth]!=HARD)
+        else
+        if (layout[indentDepth]!=HARD) {
             if (column<layout[indentDepth]) {
                 unOffside();
                 return '}';
@@ -1223,6 +1314,8 @@ static Int local yylex() {             /* Read next input token ...        */
                 insertedToken = TRUE;
                 return ';';
             }
+        }
+    }
 
     /* ----------------------------------------------------------------------
      * Now try to identify token type:
@@ -1260,8 +1353,8 @@ static Int local yylex() {             /* Read next input token ...        */
     }
 
 #if TREX
-    if (c0=='#' && isIn(c1,SMALL)) {    /* Look for record selector name   */
-        Text it;
+    if (c0=='#' && isIn(c1,SMALL) && !haskell98) {
+        Text it;                        /* Look for record selector name   */
         skip();
         it    = readIdent();
         top() = yylval = ap(RECSEL,mkExt(it));
@@ -1295,9 +1388,9 @@ static Int local yylex() {             /* Read next input token ...        */
         } else {
             top() = yylval = mkCon(it);
             return identType;
-        }                               /* We could easily keep a record of*/
-    }                                   /* the qualifying name here ...    */
-    if (isIn(c0,(SMALL|LARGE)) || c0 == '_') {
+        }
+    }
+    if (isIn(c0,(SMALL|LARGE))) {
         Text it = readIdent();
 
         if (it==textCase)              return CASEXP;
@@ -1310,7 +1403,7 @@ static Int local yylex() {             /* Read next input token ...        */
         if (it==textWhere)             lookAhead(WHERE);
         if (it==textLet)               lookAhead(LET);
         if (it==textIn)                return IN;
-        if (it==textInfix)             return INFIX;
+        if (it==textInfix)             return INFIXN;
         if (it==textInfixl)            return INFIXL;
         if (it==textInfixr)            return INFIXR;
         if (it==textForeign)           return FOREIGN;
@@ -1321,16 +1414,14 @@ static Int local yylex() {             /* Read next input token ...        */
         if (it==textDo)                lookAhead(DO);
         if (it==textClass)             return TCLASS;
         if (it==textInstance)          return TINSTANCE;
-        if (it==textModule)            return MODULETOK;
-        if (it==textInterface)         return INTERFACE;
-        if (it==textRequires)          return REQUIRES;
+        if (it==textModule)            return TMODULE;
         if (it==textImport)            return IMPORT;
         if (it==textExport)            return EXPORT;
         if (it==textHiding)            return HIDING;
         if (it==textQualified)         return QUALIFIED;
         if (it==textAsMod)             return ASMOD;
         if (it==textWildcard)          return '_';
-        if (it==textAll)              return ALL;
+        if (it==textAll && !haskell98) return ALL;
         if (it==textRepeat && reading==KEYBOARD)
             return repeatLast();
 
@@ -1349,6 +1440,7 @@ static Int local yylex() {             /* Read next input token ...        */
         if (it==textBar)     return '|';
         if (it==textFrom)    return FROM;
         if (it==textMinus)   return '-';
+        if (it==textPlus)    return '+';
         if (it==textBang)    return '!';
         if (it==textDot)     return '.';
         if (it==textArrow)   return ARROW;
@@ -1379,6 +1471,19 @@ static Int local repeatLast() {         /* Obtain last expression entered  */
     return REPEAT;
 }
 
+Syntax defaultSyntax(t)                 /* Find default syntax of var named*/
+Text t; {                               /* by t ...                        */
+    String s = textToStr(t);
+    return isIn(s[0],SYMBOL) ? DEF_OPSYNTAX : APPLIC;
+}
+
+Syntax syntaxOf(n)                      /* Find syntax for name            */
+Name n; {
+    if (name(n).syntax==NO_SYNTAX)      /* Return default if no syntax set */
+        return defaultSyntax(name(n).text);
+    return name(n).syntax;
+}
+
 /* --------------------------------------------------------------------------
  * main entry points to parser/lexer:
  * ------------------------------------------------------------------------*/
@@ -1394,24 +1499,57 @@ Int startWith; {                       /* determining whether to read a    */
         EEND;                          /* in the parser...                 */
     }
     drop();
-    assert(stackEmpty());              /* stack should now be empty        */
+    if (!stackEmpty())                 /* stack should now be empty        */
+        internal("parseInput");
 }
 
-Void parseScript(nm,len)               /* Read a script                    */
-String nm;
-Long   len; {                          /* Used to set a target for reading */
+#ifdef HSCRIPT
+static String memPrefix = "@mem@";
+static Int lenMemPrefix = 5;   /* strlen(memPrefix)*/
+
+Void makeMemScript(mem,fname)
+String mem;
+String fname; {     
+   strcat(fname,memPrefix);
+   itoa((int)mem, fname+strlen(fname), 10); 
+}
+
+Bool isMemScript(fname)
+String fname; {
+   return (strstr(fname,memPrefix) != NULL);
+}
+
+String memScriptString(fname)
+String fname; { 
+    String p = strstr(fname,memPrefix);
+    if (p) {
+        return (String)atoi(p+lenMemPrefix);
+    } else {
+        return NULL;
+    }
+}
+
+Void parseScript(fname,len)             /* Read a script, possibly from mem */
+String fname;
+Long len; {
     input(RESET);
-    fileInput(nm,len);
+    if (isMemScript(fname)) {
+        char* s = memScriptString(fname);
+        stringInput(s);
+    } else {
+        fileInput(fname,len);
+    }
     parseInput(SCRIPT);
 }
-
-Void parseInterface(nm,len)            /* Read a GHC interface file        */
+#else
+Void parseScript(nm,len)               /* Read a script                    */
 String nm;
 Long   len; {                          /* Used to set a target for reading */
     input(RESET);
     fileInput(nm,len);
-    parseInput(INTERFACE);
+    parseInput(SCRIPT);
 }
+#endif
 
 Void parseExp() {                      /* Read an expression to evaluate   */
     parseInput(EXPR);
@@ -1454,26 +1592,24 @@ Int what; {
                        textLambda     = findText("\\");
                        textBar        = findText("|");
                        textMinus      = findText("-");
+                       textPlus       = findText("+");
                        textFrom       = findText("<-");
                        textArrow      = findText("->");
                        textLazy       = findText("~");
                        textBang       = findText("!");
                        textDot        = findText(".");
                        textImplies    = findText("=>");
-#if NPLUSK
-                       textPlus       = findText("+");
-#endif
+                       textPrelude    = findText("Prelude");
+                       textNum        = findText("Num");
                        textModule     = findText("module");
-                       textInterface  = findText("__interface");
-                       textRequires   = findText("__requires");
                        textImport     = findText("import");
-                       textExport     = findText("__export");
                        textHiding     = findText("hiding");
                        textQualified  = findText("qualified");
                        textAsMod      = findText("as");
                        textWildcard   = findText("_");
                        textAll        = findText("forall");
                        varMinus       = mkVar(textMinus);
+                       varPlus        = mkVar(textPlus);
                        varBang        = mkVar(textBang);
                        varDot         = mkVar(textDot);
                        varHiding      = mkVar(textHiding);
@@ -1481,22 +1617,6 @@ Int what; {
                        varAsMod       = mkVar(textAsMod);
                        conMain        = mkCon(findText("Main"));
                        varMain        = mkVar(findText("main"));
-                       textPrelude    = findText("Prelude");
-                       textPreludeHugs= findText("PreludeBuiltin");
-                       conPrelude     = mkCon(textPrelude);
-                       conNil         = mkCon(findText("[]"));
-                       conList        = mkCon(findText("[]"));
-                       conUnit        = mkCon(findText("()"));
-                       conPreludeNil  = mkQCon(textPreludeHugs,findText("[]"));
-                       conPreludeList = mkQCon(textPreludeHugs,findText("[]"));
-                       conPreludeUnit = mkQCon(textPreludeHugs,findText("()"));
-                       varNegate      = mkQVar(textPreludeHugs,findText("negate"));
-                       varFlip        = mkQVar(textPreludeHugs,findText("flip"));
-                       varEnumFrom        = mkQVar(textPreludeHugs,findText("enumFrom"));
-                       varEnumFromThen    = mkQVar(textPreludeHugs,findText("enumFromThen"));
-                       varEnumFromTo      = mkQVar(textPreludeHugs,findText("enumFromTo"));
-                       varEnumFromThenTo  = mkQVar(textPreludeHugs,findText("enumFromThenTo"));
-
                        evalDefaults   = NIL;
 
                        input(RESET);
@@ -1505,11 +1625,11 @@ Int what; {
         case RESET   : tyconDefns   = NIL;
                        typeInDefns  = NIL;
                        valDefns     = NIL;
-                       opDefns      = NIL;
                        classDefns   = NIL;
                        instDefns    = NIL;
                        selDefns     = NIL;
                        genDefns     = NIL;
+                       //primDefns    = NIL;
                        unqualImports= NIL;
                        foreignImports= NIL;
                        foreignExports= NIL;
@@ -1527,11 +1647,11 @@ Int what; {
         case MARK    : mark(tyconDefns);
                        mark(typeInDefns);
                        mark(valDefns);
-                       mark(opDefns);
                        mark(classDefns);
                        mark(instDefns);
                        mark(selDefns);
                        mark(genDefns);
+                       //mark(primDefns);
                        mark(unqualImports);
                        mark(foreignImports);
                        mark(foreignExports);
@@ -1539,26 +1659,14 @@ Int what; {
                        mark(evalDefaults);
                        mark(inputExpr);
                        mark(varMinus);
-                       mark(varNegate);      
-                       mark(varFlip);        
-                       mark(varEnumFrom);          
-                       mark(varEnumFromThen);    
-                       mark(varEnumFromTo);      
-                       mark(varEnumFromThenTo);  
+                       mark(varPlus);
                        mark(varBang);
                        mark(varDot);
                        mark(varHiding);
                        mark(varQualified);
                        mark(varAsMod);
                        mark(varMain);
-                       mark(conPrelude);
                        mark(conMain);
-                       mark(conNil);
-                       mark(conList);
-                       mark(conUnit);
-                       mark(conPreludeNil);
-                       mark(conPreludeList);
-                       mark(conPreludeUnit);
                        mark(imps);
                        break;
     }
index 3ea95d8..4649901 100644 (file)
@@ -1,4 +1,4 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Lambda Lifter
  *
  * Hugs version 1.4, December 1997
  *
  * $RCSfile: lift.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:17 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:31 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
 #include "storage.h"
+#include "backend.h"
 #include "connect.h"
 #include "errors.h"
-#include "stg.h"
-#include "lift.h"
-#include "free.h"
-#include "stgSubst.h"
-/* #include "pp.h" */
+
 
 /* --------------------------------------------------------------------------
  * Local function prototypes:
index 13af689..79d2bc6 100644 (file)
@@ -7,16 +7,14 @@
  * Hugs version 1.4, December 1997
  *
  * $RCSfile: link.c,v $
- * $Revision: 1.3 $
- * $Date: 1999/01/13 16:47:27 $
+ * $Revision: 1.4 $
+ * $Date: 1999/02/03 17:08:31 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
 #include "storage.h"
+#include "backend.h"
 #include "connect.h"
-#include "static.h"
-#include "translate.h"
-#include "type.h"
 #include "errors.h"
 #include "Assembler.h" /* for asmPrimOps and AsmReps */
 
@@ -91,7 +89,7 @@ Class classFloating;
 Class classNum;
 
 Class classMonad;                       /* Monads and monads with a zero   */
-Class classMonad0;
+/*Class classMonad0;*/
 
 List stdDefaults;                       /* standard default values         */
 
@@ -138,6 +136,33 @@ Name nameInd;
 
 Name nameForce;
 
+Name nameAnd;
+Name nameHw;
+Name nameConCmp;
+Name nameCompAux;
+Name nameEnFrTh;
+Name nameEnFrTo;
+Name nameEnFrom;
+Name nameEnFrEn;
+Name nameEnToEn;
+Name nameEnInRng;
+Name nameEnIndex;
+Name nameEnRange;
+Name nameRangeSize;
+Name nameComp;
+Name nameShowField;
+Name nameApp;
+Name nameShowParen;
+Name nameReadParen;
+Name nameLex;
+Name nameReadField;
+Name nameFlip;
+Name nameFromTo;
+Name nameFromThen;
+Name nameFrom;
+Name nameFromThenTo;
+Name nameNegate;
+
 /* these names are required before we've had a chance to do the right thing */
 Name nameSel;
 Name nameUnsafeUnpackCString;
@@ -184,9 +209,11 @@ Name nameMkMVar;                        /* MVar#        -> MVar            */
  * 
  * ------------------------------------------------------------------------*/
 
-static Tycon linkTycon( String s );
-static Tycon linkClass( String s );
-static Name  linkName ( String s );
+static Tycon linkTycon ( String s );
+static Tycon linkClass ( String s );
+static Name  linkName  ( String s );
+static Void  mkTypes   ();
+
 
 static Tycon linkTycon( String s )
 {
@@ -222,7 +249,7 @@ static Name linkName( String s )
 static Name  predefinePrim ( String s );
 static Name  predefinePrim ( String s )
 {
-    Name nm = newName(findText(s)); 
+    Name nm = newName(findText(s),NIL); 
     name(nm).defn=PREDEFINED;
     return nm;
 }
@@ -297,7 +324,7 @@ Void linkPreludeTC() {                  /* Hook to tycons and classes in   */
         classFloating   = linkClass("Floating");
         classNum        = linkClass("Num");
         classMonad      = linkClass("Monad");
-        classMonad0     = linkClass("MonadZero");
+        /*classMonad0     = linkClass("MonadZero");*/
 
         stdDefaults     = NIL;
         stdDefaults     = cons(typeDouble,stdDefaults);
@@ -376,6 +403,17 @@ Void linkPreludeTC() {                  /* Hook to tycons and classes in   */
     }
 }
 
+static Void mkTypes()
+{
+    arrow          = fn(aVar,mkOffset(1));
+    listof         = ap(typeList,aVar);
+    predNum        = ap(classNum,aVar);
+    predFractional = ap(classFractional,aVar);
+    predIntegral   = ap(classIntegral,aVar);
+    predMonad      = ap(classMonad,aVar);
+    /*predMonad0     = ap(classMonad0,aVar);*/
+}
+
 Void linkPreludeCM() {                  /* Hook to cfuns and mfuns in      */
     static Bool initialised = FALSE;    /* prelude when first loaded       */
     if (!initialised) {
@@ -421,11 +459,13 @@ Void linkPreludeNames() {               /* Hook to names defined in Prelude */
             Text t = findText(asmPrimOps[i].name);
             Name n = findName(t);
             if (isNull(n)) {
-                n = newName(t);
+                n = newName(t,NIL);
             }
             name(n).line   = 0;
             name(n).defn   = NIL;
-            name(n).type   = primType(asmPrimOps[i].monad,asmPrimOps[i].args,asmPrimOps[i].results);
+            name(n).type   = primType(asmPrimOps[i].monad,
+                                      asmPrimOps[i].args,
+                                      asmPrimOps[i].results);
             name(n).arity  = strlen(asmPrimOps[i].args);
             name(n).primop = &(asmPrimOps[i]);
             implementPrim(n);
@@ -503,3 +543,189 @@ Int what; {
 }
 
 /*-------------------------------------------------------------------------*/
+
+
+#if 0
+--## this stuff from 98
+--## 
+--## 
+--## Void linkPreludeTC() {                  /* Hook to tycons and classes in   */
+--##     if (isNull(typeBool)) {             /* prelude when first loaded       */
+--##         Int i;
+--## 
+--##         typeBool     = findTycon(findText("Bool"));
+--##         typeChar     = findTycon(findText("Char"));
+--##         typeString   = findTycon(findText("String"));
+--##         typeInt      = findTycon(findText("Int"));
+--##         typeInteger  = findTycon(findText("Integer"));
+--##         typeDouble   = findTycon(findText("Double"));
+--##         typeAddr     = findTycon(findText("Addr"));
+--##         typeMaybe    = findTycon(findText("Maybe"));
+--##         typeOrdering = findTycon(findText("Ordering"));
+--##         if (isNull(typeBool) || isNull(typeChar)   || isNull(typeString)  ||
+--##             isNull(typeInt)  || isNull(typeDouble) || isNull(typeInteger) ||
+--##             isNull(typeAddr) || isNull(typeMaybe)  || isNull(typeOrdering)) {
+--##             ERRMSG(0) "Prelude does not define standard types"
+--##             EEND;
+--##         }
+--##         stdDefaults  = cons(typeInteger,cons(typeDouble,NIL));
+--## 
+--##         classEq      = findClass(findText("Eq"));
+--##         classOrd     = findClass(findText("Ord"));
+--##         classIx      = findClass(findText("Ix"));
+--##         classEnum    = findClass(findText("Enum"));
+--##         classShow    = findClass(findText("Show"));
+--##         classRead    = findClass(findText("Read"));
+--## #if EVAL_INSTANCES
+--##         classEval    = findClass(findText("Eval"));
+--## #endif
+--##         classBounded = findClass(findText("Bounded"));
+--##         if (isNull(classEq)   || isNull(classOrd) || isNull(classRead) ||
+--##             isNull(classShow) || isNull(classIx)  || isNull(classEnum) ||
+--## #if EVAL_INSTANCES
+--##             isNull(classEval) ||
+--## #endif
+--##             isNull(classBounded)) {
+--##             ERRMSG(0) "Prelude does not define standard classes"
+--##             EEND;
+--##         }
+--## 
+--##         classReal       = findClass(findText("Real"));
+--##         classIntegral   = findClass(findText("Integral"));
+--##         classRealFrac   = findClass(findText("RealFrac"));
+--##         classRealFloat  = findClass(findText("RealFloat"));
+--##         classFractional = findClass(findText("Fractional"));
+--##         classFloating   = findClass(findText("Floating"));
+--##         classNum        = findClass(findText("Num"));
+--##         if (isNull(classReal)       || isNull(classIntegral)  ||
+--##             isNull(classRealFrac)   || isNull(classRealFloat) ||
+--##             isNull(classFractional) || isNull(classFloating)  ||
+--##             isNull(classNum)) {
+--##             ERRMSG(0) "Prelude does not define numeric classes"
+--##             EEND;
+--##         }
+--##         predNum         = ap(classNum,aVar);
+--##         predFractional  = ap(classFractional,aVar);
+--##         predIntegral    = ap(classIntegral,aVar);
+--## 
+--##         classMonad  = findClass(findText("Monad"));
+--##         if (isNull(classMonad)) {
+--##             ERRMSG(0) "Prelude does not define Monad class"
+--##             EEND;
+--##         }
+--##         predMonad  = ap(classMonad,aVar);
+--## 
+--## #if IO_MONAD
+--##         {   Type typeIO = findTycon(findText("IO"));
+--##             if (isNull(typeIO)) {
+--##                 ERRMSG(0) "Prelude does not define IO monad constructor"
+--##                 EEND;
+--##             }
+--##             typeProgIO = ap(typeIO,aVar);
+--##         }
+--## #endif
+--## 
+--##         /* The following primitives are referred to in derived instances and
+--##          * hence require types; the following types are a little more general
+--##          * than we might like, but they are the closest we can get without a
+--##          * special datatype class.
+--##          */
+--##         name(nameConCmp).type
+--##             = mkPolyType(starToStar,fn(aVar,fn(aVar,typeOrdering)));
+--##         name(nameEnRange).type
+--##             = mkPolyType(starToStar,fn(boundPair,listof));
+--##         name(nameEnIndex).type
+--##             = mkPolyType(starToStar,fn(boundPair,fn(aVar,typeInt)));
+--##         name(nameEnInRng).type
+--##             = mkPolyType(starToStar,fn(boundPair,fn(aVar,typeBool)));
+--##         name(nameEnToEn).type
+--##             = mkPolyType(starToStar,fn(aVar,fn(typeInt,aVar)));
+--##         name(nameEnFrEn).type
+--##             = mkPolyType(starToStar,fn(aVar,typeInt));
+--##         name(nameEnFrom).type
+--##             = mkPolyType(starToStar,fn(aVar,listof));
+--##         name(nameEnFrTo).type
+--##             = name(nameEnFrTh).type
+--##             = mkPolyType(starToStar,fn(aVar,fn(aVar,listof)));
+--## 
+--## #if EVAL_INSTANCES
+--##         addEvalInst(0,typeArrow,2,NIL); /* Add Eval instances for builtins */
+--##         addEvalInst(0,typeList,1,NIL);
+--##         addEvalInst(0,typeUnit,0,NIL);
+--## #endif
+--##         for (i=2; i<=NUM_DTUPLES; i++) {/* Add derived instances of tuples */
+--## #if EVAL_INSTANCES
+--##             addEvalInst(0,mkTuple(i),i,NIL);
+--## #endif
+--##             addTupInst(classEq,i);
+--##             addTupInst(classOrd,i);
+--##             addTupInst(classShow,i);
+--##             addTupInst(classRead,i);
+--##             addTupInst(classIx,i);
+--##         }
+--##     }
+--## }
+--## 
+--## 
+--## static Void linkPreludeCM() {           /* Hook to cfuns and mfuns in      */
+--##     if (isNull(nameFalse)) {            /* prelude when first loaded       */
+--##         nameFalse   = findName(findText("False"));
+--##         nameTrue    = findName(findText("True"));
+--##         nameJust    = findName(findText("Just"));
+--##         nameNothing = findName(findText("Nothing"));
+--##         nameLeft    = findName(findText("Left"));
+--##         nameRight   = findName(findText("Right"));
+--##         nameLT      = findName(findText("LT"));
+--##         nameEQ      = findName(findText("EQ"));
+--##         nameGT      = findName(findText("GT"));
+--##         if (isNull(nameFalse) || isNull(nameTrue)    ||
+--##             isNull(nameJust)  || isNull(nameNothing) ||
+--##             isNull(nameLeft)  || isNull(nameRight)   ||
+--##             isNull(nameLT)    || isNull(nameEQ)      || isNull(nameGT)) {
+--##             ERRMSG(0) "Prelude does not define standard constructors"
+--##             EEND;
+--##         }
+--## 
+--##         nameFromInt     = findName(findText("fromInt"));
+--##         nameFromInteger = findName(findText("fromInteger"));
+--##         nameFromDouble  = findName(findText("fromDouble"));
+--##         nameEq          = findName(findText("=="));
+--##         nameCompare     = findName(findText("compare"));
+--##         nameLe          = findName(findText("<="));
+--##         nameGt          = findName(findText(">"));
+--##         nameShowsPrec   = findName(findText("showsPrec"));
+--##         nameReadsPrec   = findName(findText("readsPrec"));
+--##         nameIndex       = findName(findText("index"));
+--##         nameInRange     = findName(findText("inRange"));
+--##         nameRange       = findName(findText("range"));
+--##         nameMult        = findName(findText("*"));
+--##         namePlus        = findName(findText("+"));
+--##         nameMinBnd      = findName(findText("minBound"));
+--##         nameMaxBnd      = findName(findText("maxBound"));
+--## #if EVAL_INSTANCES
+--##         nameStrict      = findName(findText("strict"));
+--##         nameSeq         = findName(findText("seq"));
+--## #endif
+--##         nameReturn      = findName(findText("return"));
+--##         nameBind        = findName(findText(">>="));
+--##         nameMFail       = findName(findText("fail"));
+--##         if (isNull(nameFromInt)   || isNull(nameFromDouble)  ||
+--##             isNull(nameEq)        || isNull(nameCompare)     ||
+--##             isNull(nameLe)        || isNull(nameGt)          ||
+--##             isNull(nameShowsPrec) || isNull(nameReadsPrec)   ||
+--##             isNull(nameIndex)     || isNull(nameInRange)     ||
+--##             isNull(nameRange)     || isNull(nameMult)        ||
+--##             isNull(namePlus)      || isNull(nameFromInteger) ||
+--##             isNull(nameMinBnd)    || isNull(nameMaxBnd)      ||
+--## #if EVAL_INSTANCES
+--##             isNull(nameStrict)    || isNull(nameSeq)         ||
+--## #endif
+--##             isNull(nameReturn)    || isNull(nameBind)        ||
+--##             isNull(nameMFail)) {
+--##             ERRMSG(0) "Prelude does not define standard members"
+--##             EEND;
+--##         }
+--##     }
+--## }
+--## 
+#endif
index c4cc542..228e5b4 100644 (file)
@@ -1,38 +1,8 @@
-/* -*- mode: hugs-c; -*- */
-extern  Void   linkPreludeTC    Args((Void));
-extern  Void   linkPreludeCM    Args((Void));
-extern  Void   linkPreludeNames Args((Void));
 
-extern Module modulePreludeHugs;
-
-/* --------------------------------------------------------------------------
- * Primitive constructor functions 
- * ------------------------------------------------------------------------*/
-
-extern Name  nameFalse, nameTrue;
-extern Name  nameNil,   nameCons;
-extern Name  nameUnit;
-
-extern Name  nameFromInt, nameFromDouble;/*coercion of numerics            */
-extern Name  nameFromInteger;
-extern Name  nameReturn,  nameBind;     /* for translating monad comps     */
-extern Name  nameZero;                  /* for monads with a zero          */
-#if EVAL_INSTANCES
-extern Name  nameStrict,  nameSeq;      /* Members of class Eval           */
-#endif
-
-extern Name  nameId;
-extern Name  nameRunIO;
-extern Name  namePrint;
+extern Cell conCons;
 
 extern Name nameForce;
-
-#if TREX
-extern Name  nameInsFld;                /* Field insertion routine         */
-extern Type  typeRec;                   /* Record formation                */
-extern Name  nameNoRec;                 /* The empty record                */
-extern Type  typeNoRow;                 /* The empty row                   */
-#endif
+extern Name nameRunIO;
 
 /* The following data constructors are used to box unboxed
  * arguments and are treated differently by the code generator.
@@ -83,10 +53,6 @@ extern Name nameMkThreadId;
 extern Name nameMkMVar;  
 #endif
 
-extern Type typeArrow;                  /* Builtin type constructors       */
-
-#define fn(from,to)  ap2(typeArrow,from,to)     /* make type:  from -> to  */
-
 /* For every primitive type provided by the runtime system,
  * we construct a Haskell type using a declaration of the form:
  *
@@ -149,34 +115,6 @@ extern Type typeException;
 #warning BIGNUMTYPE undefined
 #endif
 
-extern List  stdDefaults;               /* List of standard default types  */
-
-extern Class classEq;                   /* `standard' classes              */
-extern Class classOrd;
-extern Class classShow;
-extern Class classRead;
-extern Class classIx;
-extern Class classEnum;
-extern Class classBounded;
-#if EVAL_INSTANCES
-extern Class classEval;
-#endif
-
-extern Class classReal;                 /* `numeric' classes               */
-extern Class classIntegral;
-extern Class classRealFrac;
-extern Class classRealFloat;
-extern Class classFractional;
-extern Class classFloating;
-extern Class classNum;
-
-extern Class classMonad;                /* Monads and monads with a zero   */
-extern Class classMonad0;
-
-/* used in typechecker */
-extern Name nameError;
-extern Name nameInd;
-
 /* used while desugaring */
 extern Name nameId;
 extern Name nameOtherwise;
@@ -204,3 +142,10 @@ extern Name namePmFromInteger;
 extern Name nameMkIO;
 extern Name nameUnpackString;
 
+extern Type  arrow;                     /* mkOffset(0) -> mkOffset(1)      */
+extern Type  listof;                    /* [ mkOffset(0) ]                 */
+extern Cell  predNum;                   /* Num (mkOffset(0))               */
+extern Cell  predFractional;            /* Fractional (mkOffset(0))        */
+extern Cell  predIntegral;              /* Integral (mkOffset(0))          */
+extern Cell  predMonad;                 /* Monad (mkOffset(0))             */
+
index 25cef1f..7b5bbb2 100644 (file)
@@ -1,28 +1,21 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Machine dependent code
  * RISCOS specific code provided by Bryan Scatergood, JBS
  * Macintosh specific code provided by Hans Aberg (haberg@matematik.su.se)
+ * HaskellScript code and recursive directory search provided by
+ *  Daan Leijen (leijen@fwi.uva.nl)
  *
- * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
- * All rights reserved. See NOTICE for details and conditions of use etc...
- * Hugs version 1.4, December 1997
+ * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
+ * Haskell Group 1994-99, and is distributed as Open Source software
+ * under the Artistic License; see the file "Artistic" that is included
+ * in the distribution for details.
  *
  * $RCSfile: machdep.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:20 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:32 $
  * ------------------------------------------------------------------------*/
 
-#include "prelude.h"
-#include "storage.h"
-#include "connect.h"
-#include "hugs.h"  /* for fromEnv */
-#include "errors.h"
-#include "version.h"
-
-#include "machdep.h"
-
-#include <stdio.h>
 #ifdef HAVE_SIGNAL_H
 # include <signal.h>
 #endif
@@ -108,12 +101,48 @@ extern unsigned _stklen = 8000;         /* Allocate an 8k stack segment    */
 #endif
 
 /* --------------------------------------------------------------------------
+ * Prototypes for registry reading
+ * ------------------------------------------------------------------------*/
+
+#if USE_REGISTRY
+
+/* where have we hidden things in the registry? */
+#if HSCRIPT
+#define HScriptRoot ("SOFTWARE\\Haskell\\HaskellScript\\")
+#endif
+
+#define HugsRoot ("SOFTWARE\\Haskell\\Hugs\\" HUGS_VERSION "\\")
+#define ProjectRoot ("SOFTWARE\\Haskell\\Hugs\\Projects\\")
+
+static Bool   local createKey      Args((HKEY, String, PHKEY, REGSAM));
+static Bool   local queryValue     Args((HKEY, String, String, LPDWORD, LPBYTE, DWORD));
+static Bool   local setValue       Args((HKEY, String, String, DWORD, LPBYTE, DWORD));
+static String local readRegString  Args((HKEY, String, String, String));
+static Int    local readRegInt     Args((String,Int));
+static Bool   local writeRegString Args((String,String));
+static Bool   local writeRegInt    Args((String,Int));
+
+static String local readRegChildStrings Args((HKEY, String, String, Char, String));
+#endif /* USE_REGISTRY */
+
+/* --------------------------------------------------------------------------
  * Find information about a file:
  * ------------------------------------------------------------------------*/
 
+#if RISCOS
+typedef struct { unsigned hi, lo; } Time;
+#define timeChanged(now,thn)    (now.hi!=thn.hi || now.lo!=thn.lo)
+#define timeSet(var,tm)         var.hi = tm.hi; var.lo = tm.lo
+#else
+typedef time_t Time;
+#define timeChanged(now,thn)    (now!=thn)
+#define timeSet(var,tm)         var = tm
+#endif
+
+static Void local getFileInfo   Args((String, Time *, Long *));
 static Bool local readable      Args((String));
 
-Void getFileInfo(f,tm,sz)  /* find time stamp and size of file*/
+static Void local getFileInfo(f,tm,sz)  /* find time stamp and size of file*/
 String f;
 Time   *tm;
 Long   *sz; {
@@ -201,7 +230,11 @@ String f; {
  * ------------------------------------------------------------------------*/
 
 static String local hugsdir       Args((Void));
+#if HSCRIPT
+static String local hscriptDir    Args((Void));
+#endif
 static String local RealPath      Args((String));
+static int    local pathCmp       Args((String, String));
 static String local normPath      Args((String));
 static Void   local searchChr     Args((Int));
 static Void   local searchStr     Args((String));
@@ -226,7 +259,18 @@ static Bool   local tryEndings    Args((String));
 #endif
 
 static String local hugsdir() {     /* directory containing lib/Prelude.hs */
-#if HAVE_GETMODULEFILENAME && !DOS
+#if HSCRIPT
+    /* In HaskellScript (Win32 only), we lookup InstallDir in the registry. */
+    static char dir[FILENAME_MAX+1] = "";
+    if (dir[0] == '\0') { /* not initialised yet */
+        String s = readRegString(HKEY_LOCAL_MACHINE,HugsRoot,"InstallDir", 
+                                 HUGSDIR);
+        if (s) { 
+            strcpy(dir,s); 
+        }
+    }
+    return dir;
+#elif HAVE_GETMODULEFILENAME && !DOS
     /* On Windows, we can find the binary we're running and it's
      * conventional to put the libraries in the same place.
      */
@@ -251,7 +295,21 @@ static String local hugsdir() {     /* directory containing lib/Prelude.hs */
     return HUGSDIR;
 #endif
 }
-    
+
+#if HSCRIPT    
+static String local hscriptDir() {  /* directory containing ?? what Daan?  */
+    static char dir[FILENAME_MAX+1] = "";
+    if (dir[0] == '\0') { /* not initialised yet */
+        String s = readRegString(HKEY_LOCAL_MACHINE,HScriptRoot,"InstallDir","");
+        if (s) {
+            strcpy(dir,s);
+        }
+    }
+    return dir;
+}
+#endif
+
+
 static String local RealPath(s)         /* Find absolute pathname of file  */
 String s; {
 #if HAVE__FULLPATH  /* eg DOS */
@@ -267,7 +325,7 @@ String s; {
     return path;
 }
 
-int pathCmp(p1,p2)                    /* Compare paths after normalisation */
+static int local pathCmp(p1,p2)       /* Compare paths after normalisation */
 String p1;
 String p2; {
 #if HAVE__FULLPATH  /* eg DOS */
@@ -306,7 +364,11 @@ String s; {                     /* a pathname in some appropriate manner.  */
 #endif /* ! PATH_CANONICALIZATION */
 }
 
-static String endings[] = { "", ".myhi", ".hs", ".lhs", 0 };
+#if HSCRIPT
+static String endings[] = { "", ".hs", ".lhs", ".hsx", ".hash", 0 };
+#else
+static String endings[] = { "", ".hs", ".lhs", 0 };
+#endif
 static char   searchBuf[FILENAME_MAX+1];
 static Int    searchPos;
 
@@ -315,7 +377,7 @@ static Int    searchPos;
 static Void local searchChr(c)  /* Add single character to search buffer   */
 Int c; {
     if (searchPos<FILENAME_MAX) {
-        searchBuf[searchPos++] = c;
+        searchBuf[searchPos++] = (char)c;
         searchBuf[searchPos]   = '\0';
     }
 }
@@ -341,17 +403,123 @@ String s; {
     return FALSE;
 }
 
+
+
+#if SEARCH_DIR
+
+/* scandir, June 98 Daan Leijen
+   searches the base directory and its direct subdirectories for a file
+
+   input: searchbuf contains SLASH terminated base directory
+              argument s contains the (base) filename
+   output: TRUE: searchBuf contains the full filename
+                   FALSE: searchBuf is garbage, file not found
+*/
+          
+
+#ifdef HAVE_WINDOWS_H
+
+static Bool scanSubDirs(s)
+String s;
+{
+    struct _finddata_t findInfo;
+    long handle;
+    int  save;
+    
+    save = searchPos;
+    /* is it in the current directory ? */
+    if (tryEndings(s)) return TRUE;
+
+    searchReset(save);
+    searchStr("*");
+    
+    /* initiate the search */
+    handle = _findfirst( searchBuf, &findInfo );
+    if (handle==-1) { errno = 0; return FALSE; }
+    
+    /* search all subdirectories */
+    do {
+        /* if we have a valid sub directory */
+        if (((findInfo.attrib & _A_SUBDIR) == _A_SUBDIR) &&
+            (findInfo.name[0] != '.')) {
+            searchReset(save);
+            searchStr(findInfo.name);
+            searchChr(SLASH);
+            if (tryEndings(s)) {
+                return TRUE;
+            }
+        }
+    } while (_findnext( handle, &findInfo ) == 0);
+    
+    _findclose( handle );
+    return FALSE;
+}
+
+#elif defined(HAVE_FTW_H)
+
+#include <ftw.h>
+
+static char baseFile[FILENAME_MAX+1];
+static char basePath[FILENAME_MAX+1];
+static int  basePathLen;
+
+static int scanitem( const char* path, 
+                     const struct stat* statinfo, 
+                     int info )
+{
+    if (info == FTW_D) { /* is it a directory */
+        searchReset(0);
+        searchStr(path);
+        searchChr(SLASH);
+        if (tryEndings(baseFile)) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+static Bool scanSubDirs(s)
+String s;
+{
+    int r;
+    strcpy(baseFile,s);
+    strcpy(basePath,searchBuf);
+    basePathLen = strlen(basePath);
+
+    /* is it in the current directory ? */
+    if (tryEndings(s)) return TRUE;
+    
+    /* otherwise scan the subdirectories */
+    r = ftw( basePath, scanitem, 2 );
+    errno = 0;
+    return (r > 0);
+}
+
+#endif /* HAVE_WINDOWS_H || HAVE_FTW_H */
+#endif /* SEARCH_DIR */
+
 String findPathname(along,nm)   /* Look for a file along specified path    */
 String along;                   /* Return NULL if file does not exist      */ 
 String nm; {
-    String s = findMPathname(along,nm);
+    /* AC, 1/21/99: modified to search hugsPath first, then projectPath */
+    String s = findMPathname(along,nm,hugsPath);
+#if USE_REGISTRY
+#if 0
+ ToDo:
+    if (s==NULL) {
+        s = findMPathname(along,nm,projectPath);
+    }
+#endif /* 0 */
+#endif /* USE_REGISTRY */
     return s ? s : normPath(searchBuf);
 }
 
-String findMPathname(along,nm)  /* Look for a file along specified path    */
+/* AC, 1/21/99: modified to pass in path to search explicitly */
+String findMPathname(along,nm,path)/* Look for a file along specified path   */
 String along;                   /* If nonzero, a path prefix from along is */
-String nm; {                    /* used as the first prefix in the search. */
-    String pathpt = hugsPath;
+String nm;                      /* used as the first prefix in the search. */
+String path; {
+    String pathpt = path;
 
     searchReset(0);
     if (along) {                /* Was a path for an existing file given?  */
@@ -370,6 +538,7 @@ String nm; {                    /* used as the first prefix in the search. */
     if (pathpt && *pathpt) {    /* Otherwise, we look along the HUGSPATH   */
         Bool more = TRUE;
         do {
+            Bool recurse = FALSE;   /* DL: shall we recurse ? */
             searchReset(0);
             if (*pathpt) {
                 if (*pathpt!=PATHSEP) {
@@ -378,20 +547,37 @@ String nm; {                    /* used as the first prefix in the search. */
                         searchStr(hugsdir());
                         pathpt += 6;
                     }
-                    do
+#if HSCRIPT
+                    /* And another - we ought to generalise this stuff */
+                    else if (strncmp(pathpt,"{HScript}",9)==0) {
+                        searchStr(hscriptDir());
+                        pathpt += 9;
+                    }
+#endif
+                    do {
                         searchChr(*pathpt++);
-                    while (*pathpt && *pathpt!=PATHSEP);
-                    searchChr(SLASH);
+                    } while (*pathpt && *pathpt!=PATHSEP);
+                    recurse = (pathpt[-1] == SLASH);
+                    if (!recurse) {
+                        searchChr(SLASH);
+                    }
                 }
                 if (*pathpt==PATHSEP)
                     pathpt++;
                 else
                     more = FALSE;
-            }
-            else
+            } else {
                 more = FALSE;
-            if (tryEndings(nm))
+            }
+#if SEARCH_DIR
+            if (recurse ? scanSubDirs(nm) : tryEndings(nm)) {
+                return normPath(searchBuf);
+            }
+#else   
+            if (tryEndings(nm)) {
                 return normPath(searchBuf);
+            }
+#endif
         } while (more);
     }
 
@@ -404,7 +590,9 @@ String nm; {                    /* used as the first prefix in the search. */
  * eg substPath("a:b:c::d:e","x:y:z") = "a:b:c:x:y:z:d:e"
  * ------------------------------------------------------------------------*/
 
-String substPath(new,sub)              /* substitute sub path into new path*/
+static String local substPath Args((String,String));
+
+static String local substPath(new,sub) /* substitute sub path into new path*/
 String new;
 String sub; {
     Bool   substituted = FALSE;            /*   only allow one replacement */
@@ -434,33 +622,45 @@ String sub; {
 
 
 /* --------------------------------------------------------------------------
+ * Get time/date stamp for inclusion in compiled files:
+ * ------------------------------------------------------------------------*/
+
+#if PROFILING
+String timeString() {                   /* return time&date string         */
+    time_t clock;                       /* must end with '\n' character    */
+    time(&clock);
+    return(ctime(&clock));
+}
+#endif
+
+/* --------------------------------------------------------------------------
  * Garbage collection notification:
  * ------------------------------------------------------------------------*/
 
 Bool gcMessages = FALSE;                /* TRUE => print GC messages       */
 
-Void gcStarted() {                      /* notify garbage collector start  */
+Void gcStarted() {                      /* Notify garbage collector start  */
 #if HUGS_FOR_WINDOWS
     SaveCursor = SetCursor(GarbageCursor);
 #endif
     if (gcMessages) {
-        printf("{{Gc");
+        Printf("{{Gc");
         FlushStdout();
     }
 }
 
-Void gcScanning() {                     /* notify garbage collector scans  */
+Void gcScanning() {                     /* Notify garbage collector scans  */
     if (gcMessages) {
         Putchar(':');
         FlushStdout();
     }
 }
 
-Void gcRecovered(recovered)             /* notify garbage collection done  */
+Void gcRecovered(recovered)             /* Notify garbage collection done  */
 Int recovered; {
     if (gcMessages) {
-        printf("%d}}",recovered);
-        fflush(stdout);
+        Printf("%d}}",recovered);
+        FlushStdout();
     }
 #if HUGS_FOR_WINDOWS
     SetCursor(SaveCursor);
@@ -571,7 +771,7 @@ Void gcCStack() {                       /* Garbage collect elements off    */
 
 #if (HAVE_TERMIO_H | HAVE_SGTTY_H | HAVE_TERMIOS_H)
 
-/* This is believed to be redundant! ADR */
+/* grab the varargs prototype for ioctl */
 #if HAVE_SYS_IOCTL_H
 # include <sys/ioctl.h>
 #endif
@@ -735,8 +935,13 @@ Bool reqd; {                            /* or off otherwise, returning old */
         if (broken) {                   /* repond to break signal received */
             broken = FALSE;             /* whilst break trap disabled      */
             sigRaise(breakHandler);
+            /* not reached */
         }
+#if HANDLERS_CANT_LONGJMP
         ctrlbrk(ignoreBreak);
+#else
+        ctrlbrk(breakHandler);
+#endif
     } else {
         ctrlbrk(ignoreBreak);
     }
@@ -744,7 +949,9 @@ Bool reqd; {                            /* or off otherwise, returning old */
 }
 
 static sigHandler(ignoreBreak) {        /* record but don't respond to break*/
-    ctrlbrk(ignoreBreak);
+    ctrlbrk(ignoreBreak);         /* reinstall signal handler               */
+                                  /* redundant on BSD systems but essential */
+                                  /* on POSIX and other systems             */
     broken = TRUE;
     interruptStgRts();
     sigResume;
@@ -794,7 +1001,7 @@ static Void local installHandlers() { /* Install handlers for all fatal    */
  * Shell escapes:
  * ------------------------------------------------------------------------*/
 
-Bool startEdit(line,nm)                 /* Start editor on file name at    */
+static Bool local startEdit(line,nm)    /* Start editor on file name at    */
 Int    line;                            /* given line.  Both name and line */
 String nm; {                            /* or just line may be zero        */
     static char editorCmd[FILENAME_MAX+1];
@@ -977,15 +1184,16 @@ REGSAM  samDesired; {
            == ERROR_SUCCESS;
 }
 
-static Bool local queryValue(hKey, var, type, buf, bufSize)
+static Bool local queryValue(hKey, regPath, var, type, buf, bufSize)
 HKEY    hKey;
+String  regPath;
 String  var;
 LPDWORD type;
 LPBYTE  buf;
 DWORD   bufSize; {
     HKEY hRootKey;
 
-    if (!createKey(hKey, &hRootKey, KEY_READ)) {
+    if (!createKey(hKey, regPath, &hRootKey, KEY_READ)) {
         return FALSE;
     } else {
         LONG res = RegQueryValueEx(hRootKey, var, NULL, type, buf, &bufSize);
@@ -994,15 +1202,16 @@ DWORD   bufSize; {
     }
 }
 
-static Bool local setValue(hKey, var, type, buf, bufSize)
+static Bool local setValue(hKey, regPath, var, type, buf, bufSize)
 HKEY   hKey;
+String regPath;
 String var;
 DWORD  type;
 LPBYTE buf;
 DWORD  bufSize; {
     HKEY hRootKey;
 
-    if (!createKey(hKey, &hRootKey, KEY_WRITE)) {
+    if (!createKey(hKey, regPath, &hRootKey, KEY_WRITE)) {
         return FALSE;
     } else {
         LONG res = RegSetValueEx(hRootKey, var, 0, type, buf, bufSize);
@@ -1011,34 +1220,32 @@ DWORD  bufSize; {
     }
 }
 
-String readRegString(var,def)    /* read String from registry */
+static String local readRegString(key,regPath,var,def) /* read String from registry */
+HKEY   key;
+String regPath;
 String var; 
 String def; {
     static char  buf[300];
     DWORD type;
-
-    if (queryValue(HKEY_CURRENT_USER, var, &type, buf, sizeof(buf))
+    if (queryValue(key, regPath,var, &type, buf, sizeof(buf))
         && type == REG_SZ) {
         return (String)buf;
-    } else if (queryValue(HKEY_LOCAL_MACHINE, var, &type, buf, sizeof(buf))
-               && type == REG_SZ) {
-        return (String)buf;
     } else {
-        return NULL;
+        return def;
     }
 }
-Int readRegInt(var, def)            /* read Int from registry */
+
+static Int local readRegInt(var, def)            /* read Int from registry */
 String var;
 Int    def; {
     DWORD buf;
     DWORD type;
 
-    if (queryValue(HKEY_CURRENT_USER, var, &type, 
+    if (queryValue(HKEY_CURRENT_USER, HugsRoot, var, &type, 
                    (LPBYTE)&buf, sizeof(buf))
         && type == REG_DWORD) {
         return (Int)buf;
-    } else if (queryValue(HKEY_LOCAL_MACHINE, var, &type, 
+    } else if (queryValue(HKEY_LOCAL_MACHINE, HugsRoot, var, &type, 
                           (LPBYTE)&buf, sizeof(buf))
                && type == REG_DWORD) {
         return (Int)buf;
@@ -1047,20 +1254,20 @@ Int    def; {
     }
 }
 
-Bool writeRegString(var,val)      /* write String to registry */
+static Bool local writeRegString(var,val)      /* write String to registry */
 String var;                        
 String val; {
     if (NULL == val) {
         val = "";
     }
-    return setValue(HKEY_CURRENT_USER, var, 
+    return setValue(HKEY_CURRENT_USER, HugsRoot, var, 
                     REG_SZ, (LPBYTE)val, lstrlen(val)+1);
 }
 
-Bool writeRegInt(var,val)         /* write String to registry */
+static Bool local writeRegInt(var,val)         /* write String to registry */
 String var;                        
 Int    val; {
-    return setValue(HKEY_CURRENT_USER, var, 
+    return setValue(HKEY_CURRENT_USER, HugsRoot, var, 
                     REG_DWORD, (LPBYTE)&val, sizeof(val));
 }
 
index f16d284..170a0c6 100644 (file)
@@ -1,4 +1,4 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Optimiser
  *
@@ -7,16 +7,15 @@
  * Hugs version 1.4, December 1997
  *
  * $RCSfile: optimise.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:23 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:33 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
 #include "storage.h"
+#include "backend.h"
 #include "connect.h"
 #include "errors.h"
-#include "stg.h"
-#include "optimise.h"
 
 /* --------------------------------------------------------------------------
  * Local functions
index 471dd51..b5ced32 100644 (file)
@@ -1,25 +1,26 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Unparse expressions and types - for use in error messages, type checker
  * and for debugging.
  *
- * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
- * All rights reserved. See NOTICE for details and conditions of use etc...
- * Hugs version 1.4, December 1997
+ * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
+ * Haskell Group 1994-99, and is distributed as Open Source software
+ * under the Artistic License; see the file "Artistic" that is included
+ * in the distribution for details.
  *
  * $RCSfile: output.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:24 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:33 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
 #include "storage.h"
 #include "connect.h"
-#include "input.h"  /* for textPlus */
 #include "errors.h"
-#include "link.h"
 #include <ctype.h>
 
+/*#define DEBUG_SHOWSC*/                /* Must also be set in compiler.c  */
+
 #define DEPTH_LIMIT     15
 
 /* --------------------------------------------------------------------------
@@ -48,7 +49,7 @@ static Void local unlexCharConst Args((Cell));
 static Void local unlexStrConst  Args((Text));
 
 static Void local putSigType     Args((Cell));
-static Void local putContext     Args((List,Int));
+static Void local putContext     Args((List,List,Int));
 static Void local putPred        Args((Cell,Int));
 static Void local putType        Args((Cell,Int,Int));
 static Void local putTyVar       Args((Int));
@@ -63,6 +64,9 @@ static Void local putKinds       Args((Kinds));
  * ------------------------------------------------------------------------*/
 
 static FILE *outputStream;             /* current output stream            */
+#ifdef DEBUG_SHOWSC                                                    
+static Int  outColumn = 0;             /* current output column number     */
+#endif                                                                 
                                                                        
 #define OPEN(b)    if (b) putChr('(');                                 
 #define CLOSE(b)   if (b) putChr(')');                                 
@@ -70,12 +74,18 @@ static FILE *outputStream;             /* current output stream            */
 static Void local putChr(c)            /* print single character           */
 Int c; {                                                               
     Putc(c,outputStream);                                              
+#ifdef DEBUG_SHOWSC                                                    
+    outColumn++;                                                       
+#endif                                                                 
 }                                                                      
                                                                        
 static Void local putStr(s)            /* print string                     */
 String s; {                                                            
     for (; *s; s++) {                                                  
         Putc(*s,outputStream);                                         
+#ifdef DEBUG_SHOWSC                                                    
+        outColumn++;                                                   
+#endif                                                                 
     }                                                                  
 }                                                                      
                                                                        
@@ -175,16 +185,33 @@ Cell e; {
         case COMP       : putComp(fst(snd(e)),snd(snd(e)));
                           break;
 
+        case MONADCOMP  : putComp(fst(snd(snd(e))),snd(snd(snd(e))));
+                          break;
+
         case CHARCELL   : unlexCharConst(charOf(e));
                           break;
 
-        case INTCELL    : putInt(intOf(e));
+        case INTCELL    : {   Int i = intOf(e);
+                              if (i<0 && d>=UMINUS_PREC) putChr('(');
+                              putInt(i);
+                              if (i<0 && d>=UMINUS_PREC) putChr(')');
+                          }
                           break;
 
-        case BIGCELL    : putStr(bignumToString(e));
+#if BIGNUMS
+        case NEGNUM     :
+        case ZERONUM    :
+        case POSNUM     : xs = bigOut(e,NIL,d>=UMINUS_PREC);
+                          for (; nonNull(xs); xs=tl(xs))
+                              putChr(charOf(arg(hd(xs))));
                           break;
+#endif
 
-        case FLOATCELL  : putStr(floatToString(e));
+        case FLOATCELL  : {   Float f = floatOf(e);
+                              if (f<0 && d>=UMINUS_PREC) putChr('(');
+                              putStr(floatToString(f));
+                              if (f<0 && d>=UMINUS_PREC) putChr(')');
+                          }
                           break;
 
         case STRCELL    : unlexStrConst(textOf(e));
@@ -214,7 +241,7 @@ Cell e; {
 
         case LAMBDA     : xs = fst(snd(e));
                           if (whatIs(xs)==BIGLAM)
-                              xs = snd(snd(e));
+                              xs = snd(snd(xs));
                           while (nonNull(xs) && isDictVal(hd(xs)))
                               xs = tl(xs);
                           if (isNull(xs)) {
@@ -270,7 +297,7 @@ Cell e; {
     putDepth--;
 }
 
-static Void local putFlds(exp,fs)         /* Output exp using labelled fields*/
+static Void local putFlds(exp,fs)       /* Output exp using labelled fields*/
 Cell exp;
 List fs; {
     put(ALWAYS,exp);
@@ -288,7 +315,7 @@ List fs; {
                      isVar(e)  ? textOf(e)    : inventText();
 
             put(NEVER,f);
-            if (s!=t) {
+            if (haskell98 || s!=t) {
                 putStr(" = ");
                 put(NEVER,e);
             }
@@ -336,8 +363,8 @@ Cell e; {
 #if !DEBUG_CODE
     Cell h = getHead(e);
     switch (whatIs(h)) {
-        case DICTVAR  : return TRUE;
-        case NAME     : return isDfun(h);
+        case DICTVAR : return TRUE;
+        case NAME    : return isDfun(h);
     }
 #endif
     return FALSE;
@@ -370,8 +397,8 @@ Cell e; {
     switch (whatIs(h)) {
 #if NPLUSK
         case ADDPAT     : if (args==1)
-                              putInfix(d,textPlus,syntaxOf(textPlus),
-                                         arg(e),snd(h));
+                              putInfix(d,textPlus,syntaxOf(namePlus),
+                                         arg(e),mkInt(intValOf(fun(e))));
                           else
                               putStr("ADDPAT");
                           return;
@@ -384,19 +411,22 @@ Cell e; {
 
         case NAME       : if (args==1 &&
                               ((h==nameFromInt     && isInt(arg(e)))    ||
+#if BIGNUMS
                                (h==nameFromInteger && isBignum(arg(e))) ||
+#endif
                                (h==nameFromDouble  && isFloat(arg(e))))) {
                               put(d,arg(e));
                               return;
                           }
-                          sy = syntaxOf(t = name(h).text);
+                          t  = name(h).text;
+                          sy = syntaxOf(h);
                           break;
 
         case VARIDCELL  :
         case VAROPCELL  :
         case DICTVAR    :
         case CONIDCELL  :
-        case CONOPCELL  : sy = syntaxOf(t = textOf(h));
+        case CONOPCELL  : sy = defaultSyntax(t = textOf(h));
                           break;
 
 #if TREX
@@ -603,20 +633,29 @@ Cell t; {
     putType(t,NEVER,fr);                /* Finally, print rest of type ... */
 }
 
-static Void local putContext(qs,fr)     /* print context list              */
+static Void local putContext(ps,qs,fr)  /* print context list              */
+List ps;
 List qs;
 Int  fr; {
-    if (isNull(qs))
-        putStr("()");
-    else {
-        Int nq = length(qs);
-        if (nq!=1) putChr('(');
+    Int len = length(ps) + length(qs);
+    Int c   = len;
+    if (len!=1) {
+        putChr('(');
+    }
+    for (; nonNull(ps); ps=tl(ps)) {
+        putPred(hd(ps),fr);
+        if (--c > 0) {
+            putStr(", ");
+        }
+    }
+    for (; nonNull(qs); qs=tl(qs)) {
         putPred(hd(qs),fr);
-        while (nonNull(qs=tl(qs))) {
+        if (--c > 0) {
             putStr(", ");
-            putPred(hd(qs),fr);
         }
-        if (nq!=1) putChr(')');
+    }
+    if (len!=1) {
+        putChr(')');
     }
 }
 
@@ -649,16 +688,16 @@ Cell t;
 Int  prec;
 Int  fr; {
     switch(whatIs(t)) {
-        case TYCON   : putStr(textToStr(tycon(t).text));
-                       break;
+        case TYCON     : putStr(textToStr(tycon(t).text));
+                         break;
 
-        case TUPLE   : {   Int n = tupleOf(t);
-                           putChr('(');
-                           while (--n > 0)
-                               putChr(',');
-                           putChr(')');
-                       }
-                       break;
+        case TUPLE     : {   Int n = tupleOf(t);
+                             putChr('(');
+                             while (--n > 0)
+                                 putChr(',');
+                             putChr(')');
+                         }
+                         break;
 
         case POLYTYPE  : {   Kinds ks = polySigOf(t);
                              OPEN(prec>=ARROW_PREC);
@@ -674,10 +713,17 @@ Int  fr; {
                          }
                          break;
 
+        case CDICTS    :
         case QUAL      : OPEN(prec>=ARROW_PREC);
-                         putContext(fst(snd(t)),fr);
-                         putStr(" => ");
-                         putType(snd(snd(t)),NEVER,fr);
+                         if (whatIs(snd(snd(t)))==CDICTS) {
+                             putContext(fst(snd(t)),fst(snd(snd(snd(t)))),fr);
+                             putStr(" => ");
+                             putType(snd(snd(snd(snd(t)))),NEVER,fr);
+                         } else {
+                             putContext(fst(snd(t)),NIL,fr);
+                             putStr(" => ");
+                             putType(snd(snd(t)),NEVER,fr);
+                         }
                          CLOSE(prec>=ARROW_PREC);
                          break;
 
@@ -685,61 +731,56 @@ Int  fr; {
         case RANK2     : putType(snd(snd(t)),prec,fr);
                          break;
 
-        case OFFSET  : putTyVar(offsetOf(t));
-                       break;
+        case OFFSET    : putTyVar(offsetOf(t));
+                         break;
 
         case VARIDCELL :
         case VAROPCELL : putChr('_');
                          unlexVar(textOf(t));
                          break;
 
-        case INTCELL : putChr('_');
-                       putInt(intOf(t));
-                       break;
+        case INTCELL   : putChr('_');
+                         putInt(intOf(t));
+                         break;
 
-/* #ifdef DEBUG_TYPES */
-        case STAR    : putChr('*');
-                       break;
-/* #endif */
-
-        case AP      : {   Cell typeHead = getHead(t);
-                           Bool brackets = (argCount!=0 && prec>=ALWAYS);
-                           Int  args     = argCount;
-
-                           if (typeHead==typeList) {
-                               if (argCount==1) {
-                                   putChr('[');
-                                   putType(arg(t),NEVER,fr);
-                                   putChr(']');
-                                   return;
-                               }
-                           }
-                           else if (typeHead==typeArrow) {
-                               if (argCount==2) {
-                                   OPEN(prec>=ARROW_PREC);
-                                   putType(arg(fun(t)),ARROW_PREC,fr);
-                                   putStr(" -> ");
-                                   putType(arg(t),NEVER,fr);
-                                   CLOSE(prec>=ARROW_PREC);
-                                   return;
-                               }
-                               else if (argCount==1) {
-                                   putChr('(');
-                                   putType(arg(t),ARROW_PREC,fr);
-                                   putStr("->)");
-                                   return;
-                               }
-                           }
-                           else if (isTuple(typeHead)) {
-                               if (argCount==tupleOf(typeHead)) {
-                                   putChr('(');
-                                   putTupleType(t,fr);
-                                   putChr(')');
-                                   return;
-                               }
-                           }
+        case AP       : {   Cell typeHead = getHead(t);
+                            Bool brackets = (argCount!=0 && prec>=ALWAYS);
+                            Int  args    = argCount;
+
+                            if (typeHead==typeList) {
+                                if (argCount==1) {
+                                    putChr('[');
+                                    putType(arg(t),NEVER,fr);
+                                    putChr(']');
+                                    return;
+                                }
+                            }
+                            else if (typeHead==typeArrow) {
+                                if (argCount==2) {
+                                    OPEN(prec>=ARROW_PREC);
+                                    putType(arg(fun(t)),ARROW_PREC,fr);
+                                    putStr(" -> ");
+                                    putType(arg(t),NEVER,fr);
+                                    CLOSE(prec>=ARROW_PREC);
+                                    return;
+                                }
+                                else if (argCount==1) {
+                                    putChr('(');
+                                    putType(arg(t),ARROW_PREC,fr);
+                                    putStr("->)");
+                                    return;
+                                }
+                            }
+                            else if (isTuple(typeHead)) {
+                                if (argCount==tupleOf(typeHead)) {
+                                    putChr('(');
+                                    putTupleType(t,fr);
+                                    putChr(')');
+                                    return;
+                                }
+                            }
 #if TREX
-                           else if (isExt(typeHead)) {
+                            else if (isExt(typeHead)) {
                                 if (args==2) {
                                     String punc = "(";
                                     do {
@@ -764,13 +805,13 @@ Int  fr; {
                                     args-=2;
                             }
 #endif
-                           OPEN(brackets);
-                           putApType(t,args,fr);
-                           CLOSE(brackets);
-                       }
-                       break;
+                            OPEN(brackets);
+                            putApType(t,args,fr);
+                            CLOSE(brackets);
+                        }
+                        break;
 
-        default      : putStr("(bad type)");
+        default       : putStr("(bad type)");
     }
 }
 
@@ -885,7 +926,7 @@ Void printContext(fp,qs)                /* print context on spec. stream   */
 FILE *fp;
 List qs; {
     outputStream = fp;
-    putContext(qs,0);
+    putContext(qs,NIL,0);
 }
 
 Void printPred(fp,pi)                   /* print predicate pi on stream    */
@@ -903,7 +944,7 @@ Kind k; {
 }
 
 Void printKinds(fp,ks)                  /* print list of kinds on stream   */
-FILE *fp;
+FILE  *fp;
 Kinds ks; {
     outputStream = fp;
     putKinds(ks);
index f816a16..69f1a28 100644 (file)
@@ -1,17 +1,18 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Hugs parser (included as part of input.c)
  *
- * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
- * All rights reserved. See NOTICE for details and conditions of use etc...
- * Hugs version 1.4, December 1997
+ * Expect 6 shift/reduce conflicts when passing this grammar through yacc,
+ * but don't worry; they should all be resolved in an appropriate manner.
  *
- * Expect 24 shift/reduce conflicts when passing this grammar through yacc,
- * but don't worry; they will all be resolved in an appropriate manner.
+ * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
+ * Haskell Group 1994-99, and is distributed as Open Source software
+ * under the Artistic License; see the file "Artistic" that is included
+ * in the distribution for details.
  *
  * $RCSfile: parser.y,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:26 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:34 $
  * ------------------------------------------------------------------------*/
 
 %{
 #endif
 #define defTycon(n,l,lhs,rhs,w)  tyconDefn(intOf(l),lhs,rhs,w); sp-=n
 #define sigdecl(l,vs,t)          ap(SIGDECL,triple(l,vs,t))
+#define fixdecl(l,ops,a,p)       ap(FIXDECL,\
+                                    triple(l,ops,mkInt(mkSyntax(a,intOf(p)))))
 #define grded(gs)                ap(GUARDED,gs)
 #define bang(t)                  ap(BANG,t)
 #define only(t)                  ap(ONLY,t)
 #define letrec(bs,e)             (nonNull(bs) ? ap(LETREC,pair(bs,e)) : e)
+#define qualify(ps,t)            (nonNull(ps) ? ap(QUAL,pair(ps,t)) : t)
+#if IGNORE_MODULES
+#define exportSelf()             NIL
+#else
 #define exportSelf()             singleton(ap(MODULEENT,mkCon(module(currentModule).text)))
+#endif
 #define yyerror(s)               /* errors handled elsewhere */
 #define YYSTYPE                  Cell
 
@@ -32,8 +40,6 @@ static Cell   local gcShadow     Args((Int,Cell));
 static Void   local syntaxError  Args((String));
 static String local unexpected   Args((Void));
 static Cell   local checkPrec    Args((Cell));
-static Void   local fixDefn      Args((Syntax,Cell,Cell,List));
-static Void   local setSyntax    Args((Int,Syntax,Cell));
 static Cell   local buildTuple   Args((List));
 static List   local checkContext Args((List));
 static Cell   local checkPred    Args((Cell));
@@ -42,7 +48,6 @@ static Cell   local checkTyLhs   Args((Cell));
 #if !TREX
 static Void   local noTREX       Args((String));
 #endif
-static Cell   local tidyInfix    Args((Cell));
 
 /* For the purposes of reasonably portable garbage collection, it is
  * necessary to simulate the YACC stack on the Hugs stack to keep
@@ -52,32 +57,31 @@ static Cell   local tidyInfix    Args((Cell));
  * taking account of look-ahead tokens as described by gcShadow()
  * below.
  *
- * Of the non-terminals used below, only start, topDecl, fixDecl & begin
+ * Of the non-terminals used below, only start, topDecl & begin
  * do not leave any values on the Hugs stack.  The same is true for the
  * terminals EXPR and SCRIPT.  At the end of a successful parse, there
  * should only be one element left on the stack, containing the result
  * of the parse.
  */
 
-#define gc0(e)                   gcShadow(0,e)
-#define gc1(e)                   gcShadow(1,e)
-#define gc2(e)                   gcShadow(2,e)
-#define gc3(e)                   gcShadow(3,e)
-#define gc4(e)                   gcShadow(4,e)
-#define gc5(e)                   gcShadow(5,e)
-#define gc6(e)                   gcShadow(6,e)
-#define gc7(e)                   gcShadow(7,e)
+#define gc0(e)                  gcShadow(0,e)
+#define gc1(e)                  gcShadow(1,e)
+#define gc2(e)                  gcShadow(2,e)
+#define gc3(e)                  gcShadow(3,e)
+#define gc4(e)                  gcShadow(4,e)
+#define gc5(e)                  gcShadow(5,e)
+#define gc6(e)                  gcShadow(6,e)
+#define gc7(e)                  gcShadow(7,e)
 
 %}
 
 %token EXPR       SCRIPT
 %token CASEXP     OF         DATA       TYPE       IF
 %token THEN       ELSE       WHERE      LET        IN
-%token INFIX      INFIXL     INFIXR     FOREIGN    TNEWTYPE
+%token INFIXN     INFIXL     INFIXR     FOREIGN    TNEWTYPE
 %token DEFAULT    DERIVING   DO         TCLASS     TINSTANCE
-%token REPEAT     ALL
-%token VAROP      VARID      NUMLIT     CHARLIT    STRINGLIT
-%token CONOP      CONID
+%token REPEAT     ALL        NUMLIT     CHARLIT    STRINGLIT
+%token VAROP      VARID      CONOP      CONID
 %token QVAROP     QVARID     QCONOP     QCONID
 /*#if TREX*/
 %token RECSELID
@@ -86,273 +90,22 @@ static Cell   local tidyInfix    Args((Cell));
 %token '|'        '-'        FROM       ARROW      '~'
 %token '!'        IMPLIES    '('        ','        ')'
 %token '['        ';'        ']'        '`'        '.'
-%token MODULETOK  IMPORT     HIDING     QUALIFIED  ASMOD
-%token EXPORT     INTERFACE  REQUIRES   UNSAFE
+%token TMODULE    IMPORT     HIDING     QUALIFIED  ASMOD
+%token EXPORT     UNSAFE
 
 %%
-/*- Top level script/module structure: ------------------------------------*/
+/*- Top level script/module structure -------------------------------------*/
 
 start     : EXPR exp wherePart          {inputExpr = letrec($3,$2); sp-=2;}
           | SCRIPT topModule            {valDefns  = $2;            sp-=1;}
-          | INTERFACE iface             {sp-=1;}
           | error                       {syntaxError("input");}
           ;
 
-/*- GHC interface file parsing: -------------------------------------------*/
-
-/* Reading in an interface file is surprisingly like reading
- * a normal Haskell module: we read in a bunch of declarations,
- * construct symbol table entries, etc.  The "only" differences
- * are that there's no syntactic sugar to deal with and we don't
- * have to read in expressions.
- */
-
-iface     : INTERFACE ifaceName NUMLIT checkVersion ifaceDecls { $$ = gc5(NIL); }
-          | INTERFACE error             {syntaxError("interface file");}
-          ;
-
-ifaceName : CONID                       {openGHCIface(textOf($1)); $$ = gc1(NIL);}
-          ;
-
-ifaceDecls:                             {$$=gc0(NIL);}
-          | ifaceDecl ';' ifaceDecls    {$$=gc3(cons($1,$2));}
-          ;
-
-/* We use ifaceData in data decls so as to include () */
-ifaceDecl : IMPORT CONID NUMLIT         { extern String scriptFile;
-                                          String fileName = findPathname(scriptFile,textToStr(textOf($2)));
-                                          addGHCImport(intOf($1),textOf($2),fileName);                 
-                                          $$ = gc3(NIL); 
-                                        }
-          | EXPORT CONID ifaceEntities  {}                                                          
-          | REQUIRES STRINGLIT          { extern String scriptFile;
-                                          String fileName = findPathname(scriptFile,textToStr(textOf($2)));
-                                          loadSharedLib(fileName);                  
-                                          $$ = gc2(NIL); 
-                                        }
-          | INFIXL optdigit op                                                   { fixDefn(LEFT_ASS,$1,$2,$3);                 $$ = gc3(NIL); }
-          | INFIXR optdigit op                                                   { fixDefn(RIGHT_ASS,$1,$2,$3);                $$ = gc3(NIL); }
-          | INFIX  optdigit op                                                   { fixDefn(NON_ASS,$1,$2,$3);                  $$ = gc3(NIL); }
-          | TINSTANCE ifaceQuant ifaceClass '=' ifaceVar                         { addGHCInstance(intOf($1),$2,$3,textOf($5)); $$ = gc5(NIL); }
-          | NUMLIT TYPE     ifaceTCName ifaceTVBndrs '=' ifaceType               { addGHCSynonym(intOf($2),$3,$4,$6);          $$ = gc6(NIL); }
-          | NUMLIT DATA     ifaceData   ifaceTVBndrs ifaceConstrs ifaceSels      { addGHCDataDecl(intOf($2),$3,$4,$5,$6);      $$ = gc6(NIL); }
-          | NUMLIT TNEWTYPE ifaceTCName ifaceTVBndrs ifaceNewTypeConstr          { addGHCNewType(intOf($2),$3,$4,$5);          $$ = gc5(NIL); }
-          | NUMLIT TCLASS   ifaceDeclContext ifaceTCName ifaceTVBndrs ifaceCSigs { addGHCClass(intOf($2),$3,$4,$5,$6);         $$ = gc6(NIL); }
-          | NUMLIT ifaceVar COCO ifaceType                                       { addGHCVar(intOf($3),textOf($2),$4);         $$ = gc4(NIL); }
-          | error                                                                { syntaxError("interface declaration"); }
-          ;
-
-checkVersion
-          : NUMLIT                      { $$ = gc1(NIL); }
-          ;
-
-ifaceSels /* [(VarId,Type)] */
-          :                             { $$ = gc0(NIL); }
-          | WHERE '{' ifaceSels1 '}'    { $$ = gc4($3); }
-          ;
-
-ifaceSels1 /* [(VarId,Type)] */
-          : ifaceSel                    { $$ = gc1(singleton($1)); }
-          | ifaceSel ';' ifaceSels1     { $$ = gc3(cons($1,$3)); }
-          ;
-
-ifaceSel /* (VarId,Type) */
-          : ifaceVarName COCO ifaceType { $$ = gc3(pair($1,$3)); }
-          ;
-
-ifaceCSigs /* [(VarId,Type)] */
-          :                             { $$ = gc0(NIL); }
-          | WHERE '{' ifaceCSigs1 '}'   { $$ = gc4($3); }
-          ;
-
-ifaceCSigs1 /* [(VarId,Type)] */
-          : ifaceCSig                   { $$ = gc1(singleton($1)); }
-          | ifaceCSig ';' ifaceCSigs1   { $$ = gc3(cons($1,$3));    }
-          ;
-
-ifaceCSig /* (VarId,Type) */
-          : ifaceVarName     COCO ifaceType { $$ = gc3(pair($1,$3)); }
-          | ifaceVarName '=' COCO ifaceType { $$ = gc4(pair($1,$4)); } /* has default method */
-          ;
-
-ifaceConstrs /* [(ConId,[VarId],Type)] */
-          :                             { $$ = gc0(NIL); }
-          | '=' ifaceConstrs1           { $$ = gc2($2);  }
-          ;
-
-ifaceConstrs1 /* [(ConId,[VarId],Type)] */
-          : ifaceConstr                   { $$ = gc1(singleton($1)); }
-          | ifaceConstr '|' ifaceConstrs1 { $$ = gc3(cons($1,$3));   }
-          ;
-
-/* We use ifaceData so as to include () */
-ifaceConstr /* (ConId,[VarId],Type) */
-          : ifaceData                        COCO ifaceType { $$ = gc3(triple($1,NIL,$3)); }
-          | ifaceData '{' ifaceVarNames1 '}' COCO ifaceType { $$ = gc6(triple($1,$3,$6));  }  
-          ;
-
-ifaceNewTypeConstr /* (ConId,Type) */
-          :                                   { $$ = gc0(NIL);         }
-          | '=' ifaceDataName COCO ifaceType  { $$ = gc4(pair($2,$4)); }
-          ;
-
-ifaceQuant /* Maybe ([(VarId,Kind)],[(ConId, [Type])]) */ 
-          :                                      { $$ = gc0(NIL); }
-          | ALL ifaceForall ifaceContext IMPLIES { $$ = gc4(pair($2,$3)); }
-          ;
-
-ifaceType
-          : ALL ifaceForall ifaceContext IMPLIES ifaceType { $$ = gc5(ap(POLYTYPE,triple($2,$3,$5))); }
-          | ifaceBType ARROW ifaceType          { $$ = gc3(fn($1,$3)); }
-          | ifaceBType                          { $$ = gc1($1); }
-          ;                                    
-                                               
-ifaceForall /* [(VarId,Kind)] */
-          : '[' ifaceTVBndrs ']'                { $$ = gc3($2); }
-          ;                                    
-                                               
-ifaceDeclContext /* [(ConId, [Type])] */ 
-          :                                     { $$ = gc0(NIL); }
-          | '{' ifaceContextList1 '}' IMPLIES   { $$ = gc4($2);  }
-          ;                                    
-                                               
-ifaceContext /* [(ConId, [Type])] */                           
-          :                                     { $$ = gc0(NIL); }
-          | '{' ifaceContextList1 '}'           { $$ = gc3($2);  }
-          ;                                    
-                                               
-ifaceContextList1 /* [(ConId, [Type])] */                      
-          : ifaceClass                          { $$ = gc1(singleton($1)); }
-          | ifaceClass ',' ifaceContextList1    { $$ = gc3(cons($1,$3));   }
-          ;
-
-ifaceClass /* (ConId, [Type]) */
-          : ifaceQTCName ifaceATypes            { $$ = gc2(pair($1,$2)); }
-          ;                                    
-
-ifaceTypes2
-          : ifaceType ',' ifaceType             { $$ = gc3(doubleton($1,$3)); }
-          | ifaceType ',' ifaceTypes2           { $$ = gc3(cons($1,$3));      }
-          ;
-                                               
-ifaceBType                                     
-          : ifaceAType                          { $$ = gc1($1);        } 
-          | ifaceBType ifaceAType               { $$ = gc2(ap($1,$2)); }
-          ;
-
-ifaceAType                                     
-          : ifaceQTCName                        { $$ = gc1($1); }
-          | ifaceTVName                         { $$ = gc1($1); }
-          | '(' ')'                             { $$ = gc2(conPreludeUnit); }
-          | '(' ifaceTypes2 ')'                 { $$ = gc3(buildTuple($2)); }
-          | '[' ifaceType ']'                   { $$ = gc3(ap(conPreludeList,$2));}
-          | '{' ifaceQTCName ifaceATypes '}'    { $$ = gc4(ap(DICTAP,pair($2,$3))); }
-          | '(' ifaceType ')'                   { $$ = gc3($2); }
-          ;
-
-ifaceATypes
-          :                                     { $$ = gc0(NIL);         }
-          | ifaceAType ifaceATypes              { $$ = gc2(cons($1,$2)); }
-          ;
-
-ifaceEntities                                  
-          :                                     { $$ = gc0(NIL);         }
-          | ifaceEntity ifaceEntities           { $$ = gc2(cons($1,$2)); }
-          ;
-
-ifaceEntity
-          : ifaceEntityOcc                      {}
-          | ifaceEntityOcc ifaceStuffInside     {}
-| ifaceEntityOcc '|' ifaceStuffInside {} /* exporting datacons but not tycon */
-          ;
-
-ifaceEntityOcc
-          : ifaceVar                    { $$ = gc1($1); }
-          | ifaceData                   { $$ = gc1($1); }
-          | ARROW                       { $$ = gc3(typeArrow); }
-          | '(' ARROW ')'               { $$ = gc3(typeArrow); }  /* why allow both? */
-          ;
-
-ifaceStuffInside
-          : '{' ifaceValOccs '}'        { $$ = gc1($1); }
-          ;
-
-
-ifaceValOccs
-          : ifaceValOcc                 { $$ = gc1(singleton($1)); }
-          | ifaceValOcc ifaceValOccs    { $$ = gc2(cons($1,$2));   }
-          ;
-
-ifaceValOcc
-          : ifaceVar                    {$$ = gc1($1); }
-          | ifaceData                   {$$ = gc1($1); }
-          ;
-
-ifaceVar  : VARID                       {$$ = gc1($1);      }
-          | VAROP                       {$$ = gc1($1);      }
-          | '!'                         {$$ = gc1(varBang); }
-          | '.'                         {$$ = gc1(varDot);  }
-          | '-'                         {$$ = gc1(varMinus);}
-          ;
-
-ifaceData /* ConId | QualConId */
-          : CONID                       {$$ = gc1($1);}
-          | CONOP                       {$$ = gc1($1);}
-          | '(' ')'                     {$$ = gc2(conPreludeUnit);}
-          | '[' ']'                     {$$ = gc2(conPreludeList);}
-          ;
-
-ifaceVarName /* VarId */
-          : ifaceVar                    { $$ = gc1($1); }
-          ;
-
-ifaceDataName /* ConId|QualConId */
-          : ifaceData                   { $$ = gc1($1); }
-          ;
-
-ifaceVarNames1 /* [VarId] */
-          : ifaceVarName                { $$ = gc1(singleton($1)); }
-          | ifaceVarName ifaceVarNames1 { $$ = gc2(cons($1,$2));   }
-          ;
-
-ifaceTVName /* VarId */
-          : VARID                       { $$ = gc1($1); }
-          ; 
-
-ifaceTVBndrs /* [(VarId,Kind)] */
-          :                             { $$ = gc0(NIL);         }
-          | ifaceTVBndr ifaceTVBndrs    { $$ = gc2(cons($1,$2)); }
-          ;
-
-ifaceTVBndr /* (VarId,Kind) */
-          : ifaceTVName                 { $$ = gc1(pair($1,STAR)); }
-          | ifaceTVName COCO ifaceAKind { $$ = gc3(pair($1,$3));   }
-          ; 
-
-ifaceKind
-          : ifaceAKind                  { $$ = gc1($1);        }
-          | ifaceAKind ARROW ifaceKind  { $$ = gc3(fn($1,$3)); }
-          ;
-
-ifaceAKind
-          : VAROP                       { $$ = gc1(STAR); } /* should be '*' */
-          | '(' ifaceKind ')'           { $$ = gc1($1);   }
-          ;
-
-ifaceTCName
-          : CONID                       { $$ = gc1($1); }
-          | CONOP                       { $$ = gc1($1); }
-          | '(' ARROW ')'               { $$ = gc3(typeArrow); }
-          | '[' ']'                     { $$ = gc1(conPreludeList);  }
-          ; 
-
-ifaceQTCName
-          : ifaceTCName                 { $$ = gc1($1); }
-          | QCONID                      { $$ = gc1($1); }
-          | QCONOP                      { $$ = gc1($1); }
-          ; 
-
-/*- Haskell module header/import parsing: ---------------------------------*/
+/*- Haskell module header/import parsing: -----------------------------------
+ * Syntax for Haskell modules (module headers and imports) is parsed but
+ * most of it is ignored.  However, module names in import declarations
+ * are used, of course, if import chasing is turned on.
+ *-------------------------------------------------------------------------*/
 
 /* In Haskell 1.2, the default module header was "module Main where"
  * In 1.3, this changed to "module Main(main) where".
@@ -362,9 +115,9 @@ topModule : startMain begin modBody end {
                                          setExportList(singleton(ap(MODULEENT,mkCon(module(currentModule).text))));
                                          $$ = gc3($3);
                                         }
-          | MODULETOK modname expspec WHERE '{' modBody end
+          | TMODULE modname expspec WHERE '{' modBody end
                                         {setExportList($3);   $$ = gc7($6);}
-          | MODULETOK error             {syntaxError("module definition");}
+          | TMODULE error               {syntaxError("module definition");}
           ;
 /* To implement the Haskell module system, we have to keep track of the
  * current module.  We rely on the use of LALR parsing to ensure that this 
@@ -375,7 +128,7 @@ startMain : /* empty */                 {startModule(conMain);
           ;
 modname   : CONID                       {startModule($1); $$ = gc1(NIL);}
           ;
-modid     : CONID                       {$$ = gc1($1);}
+modid     : CONID                       {$$ = $1;}
           | STRINGLIT                   { extern String scriptFile;
                                           String modName = findPathname(scriptFile,textToStr(textOf($1)));
                                           if (modName) { /* fillin pathname if known */
@@ -385,12 +138,9 @@ modid     : CONID                       {$$ = gc1($1);}
                                           }
                                         }
           ;
-modBody   : topDecls                    {$$ = gc1($1);}
-          | fixDecls ';' topDecls       {$$ = gc3($3);}
+modBody   : topDecls                    {$$ = $1;}
           | impDecls chase              {$$ = gc2(NIL);}
           | impDecls ';' chase topDecls {$$ = gc4($4);}
-          | impDecls ';' chase fixDecls ';' topDecls
-                                        {$$ = gc6($6);}
           ;
 
 /*- Exports: --------------------------------------------------------------*/
@@ -406,28 +156,22 @@ exports   : exports ',' export          {$$ = gc3(cons($3,$1));}
 /* The qcon should be qconid.  
  * Relaxing the rule lets us explicitly export (:) from the Prelude.
  */
-export    : qvar                        {$$ = gc1($1);}
-          | qcon                        {$$ = gc1($1);}
-          | qcon2 '(' UPTO ')'          {$$ = gc4(pair($1,DOTDOT));}
-          | qcon2 '(' qnames ')'        {$$ = gc4(pair($1,$3));}
-          | MODULETOK modid             {$$ = gc2(ap(MODULEENT,$2));}
+export    : qvar                        {$$ = $1;}
+          | qcon                        {$$ = $1;}
+          | qconid '(' UPTO ')'         {$$ = gc4(pair($1,DOTDOT));}
+          | qconid '(' qnames ')'       {$$ = gc4(pair($1,$3));}
+          | TMODULE modid               {$$ = gc2(ap(MODULEENT,$2));}
           ;
 qnames    : /* empty */                 {$$ = gc0(NIL);}
           | ','                         {$$ = gc1(NIL);}
-          | qnames1                     {$$ = gc1($1);}
+          | qnames1                     {$$ = $1;}
           | qnames1 ','                 {$$ = gc2($1);}
           ;
 qnames1   : qnames1 ',' qname           {$$ = gc3(cons($3,$1));}
           | qname                       {$$ = gc1(singleton($1));}
           ;
-qname     : qvar                        {$$ = gc1($1);}
-          | qcon                        {$$ = gc1($1);}
-          | '(' ')'                     {$$ = gc2(conPreludeUnit);}
-          | '[' ']'                     {$$ = gc2(conPreludeList);}
-          ;
-qcon2     : '(' ')'                     {$$ = gc2(conPreludeUnit);}
-          | '[' ']'                     {$$ = gc2(conPreludeList);}
-          | qconid                      {$$ = gc1($1);}
+qname     : qvar                        {$$ = $1;}
+          | qcon                        {$$ = $1;}
           ;
 
 /*- Import declarations: --------------------------------------------------*/
@@ -467,50 +211,34 @@ impspec   : /* empty */                 {$$ = gc0(DOTDOT);}
           ;
 imports   : /* empty */                 {$$ = gc0(NIL);}
           | ','                         {$$ = gc1(NIL);}
-          | imports1                    {$$ = gc1($1);}
+          | imports1                    {$$ = $1;}
           | imports1 ','                {$$ = gc2($1);}
           ;
 imports1  : imports1 ',' import         {$$ = gc3(cons($3,$1));}
           | import                      {$$ = gc1(singleton($1));}
           ;
-import    : var                         {$$ = gc1($1);}
-          | CONID                       {$$ = gc1($1);}
+import    : var                         {$$ = $1;}
+          | CONID                       {$$ = $1;}
           | CONID '(' UPTO ')'          {$$ = gc4(pair($1,DOTDOT));}
           | CONID '(' names ')'         {$$ = gc4(pair($1,$3));}
           ;
 names     : /* empty */                 {$$ = gc0(NIL);}
           | ','                         {$$ = gc1(NIL);}
-          | names1                      {$$ = gc1($1);}
+          | names1                      {$$ = $1;}
           | names1 ','                  {$$ = gc2($1);}
           ;
 names1    : names1 ',' name             {$$ = gc3(cons($3,$1));}
           | name                        {$$ = gc1(singleton($1));}
           ;
-name      : var                         {$$ = gc1($1);}
-          | con                       {$$ = gc1($1);}
-          ;
-
-/*- Fixity declarations: --------------------------------------------------*/
-
-fixDecls  : fixDecls ';' fixDecl        {$$ = gc2(NIL);}
-          | fixDecl                     {$$ = gc0(NIL);}
-          ;
-fixDecl   : INFIXL optdigit ops         {fixDefn(LEFT_ASS,$1,$2,$3); sp-=3;}
-          | INFIXR optdigit ops         {fixDefn(RIGHT_ASS,$1,$2,$3);sp-=3;}
-          | INFIX  optdigit ops         {fixDefn(NON_ASS,$1,$2,$3);  sp-=3;}
-          ;
-optdigit  : NUMLIT                      {$$ = gc1(checkPrec($1));}
-          | /* empty */                 {$$ = gc0(mkInt(DEF_PREC));}
-          ;
-ops       : ops ',' op                  {$$ = gc3(cons($3,$1));}
-          | op                          {$$ = gc1(cons($1,NIL));}
+name      : var                         {$$ = $1;}
+          | con                         {$$ = $1;}
           ;
 
 /*- Top-level declarations: -----------------------------------------------*/
 
 topDecls  : /* empty */                 {$$ = gc0(NIL);}
           | ';'                         {$$ = gc1(NIL);}
-          | topDecls1                   {$$ = gc1($1);}
+          | topDecls1                   {$$ = $1;}
           | topDecls1 ';'               {$$ = gc2($1);}
           ;
 topDecls1 : topDecls1 ';' topDecl       {$$ = gc2($1);}
@@ -525,54 +253,59 @@ topDecl   : TYPE tyLhs '=' type         {defTycon(4,$3,$2,$4,SYNONYM);}
           | TYPE tyLhs '=' type IN invars
                                         {defTycon(6,$3,$2,
                                                     ap($4,$6),RESTRICTSYN);}
+          | TYPE error                  {syntaxError("type definition");}
           | DATA btype2 '=' constrs deriving
                                         {defTycon(5,$3,checkTyLhs($2),
                                                     ap(rev($4),$5),DATATYPE);}
           | DATA context IMPLIES tyLhs '=' constrs deriving
                                         {defTycon(7,$5,$4,
-                                                  ap(ap(QUAL,pair($2,rev($6))),
+                                                  ap(qualify($2,rev($6)),
                                                      $7),DATATYPE);}
           | DATA btype2                 {defTycon(2,$1,checkTyLhs($2),
                                                     ap(NIL,NIL),DATATYPE);}
           | DATA context IMPLIES tyLhs  {defTycon(4,$1,$4,
-                                                  ap(ap(QUAL,pair($2,NIL)),
+                                                  ap(qualify($2,NIL),
                                                      NIL),DATATYPE);}
+          | DATA error                  {syntaxError("data definition");}
           | TNEWTYPE btype2 '=' nconstr deriving
                                         {defTycon(5,$3,checkTyLhs($2),
                                                     ap($4,$5),NEWTYPE);}
           | TNEWTYPE context IMPLIES tyLhs '=' nconstr deriving
                                         {defTycon(7,$5,$4,
-                                                  ap(ap(QUAL,pair($2,$6)),
+                                                  ap(qualify($2,$6),
                                                      $7),NEWTYPE);}
+          | TNEWTYPE error              {syntaxError("newtype definition");}
           ;
-tyLhs     : tyLhs varid1                {$$ = gc2(ap($1,$2));}
-          | CONID                       {$$ = gc1($1);}
-          | '[' type ']'                {$$ = gc3(ap(conList,$2));}
-          | '(' ')'                     {$$ = gc2(conUnit);}
-          | '(' typeTuple ')'           {$$ = gc3(buildTuple($2));}
+tyLhs     : tyLhs varid                 {$$ = gc2(ap($1,$2));}
+          | CONID                       {$$ = $1;}
           | error                       {syntaxError("type defn lhs");}
           ;
 invars    : invars ',' invar            {$$ = gc3(cons($3,$1));}
           | invar                       {$$ = gc1(cons($1,NIL));}
           ;
-invar     : qvar COCO topType           {$$ = gc3(sigdecl($2,singleton($1),
-                                                             $3));}
-          | qvar                        {$$ = gc1($1);}
+invar     : var COCO topType            {$$ = gc3(sigdecl($2,singleton($1),
+                                                                        $3));}
+          | var                         {$$ = $1;}
           ;
-constrs   : constrs '|' constr          {$$ = gc3(cons($3,$1));}
-          | constr                      {$$ = gc1(cons($1,NIL));}
+constrs   : constrs '|' pconstr         {$$ = gc3(cons($3,$1));}
+          | pconstr                     {$$ = gc1(cons($1,NIL));}
           ;
-constr    : '!' btype conop bbtype      {$$ = gc4(ap2($3,bang($2),$4));}
-          | btype1    conop bbtype      {$$ = gc3(ap2($2,$1,$3));}
-          | btype2    conop bbtype      {$$ = gc3(ap2($2,$1,$3));}
-          | bpolyType conop bbtype      {$$ = gc3(ap2($2,$1,$3));}
-          | btype2                      {$$ = gc1($1);}
-          | btype3                      {$$ = gc1($1);}
-          | btype4                      {$$ = gc1($1);}
+pconstr   : ALL varids '.' qconstr      {$$ = gc4(ap(POLYTYPE,
+                                                     pair(rev($2),$4)));}
+          | qconstr                     {$$ = $1;}
+          ;
+qconstr   : context IMPLIES constr      {$$ = gc3(qualify($1,$3));}
+          | constr                      {$$ = $1;}
+          ;
+constr    : '!' btype conop bbtype      {$$ = gc4(ap(ap($3,bang($2)),$4));}
+          | btype1    conop bbtype      {$$ = gc3(ap(ap($2,$1),$3));}
+          | btype2    conop bbtype      {$$ = gc3(ap(ap($2,$1),$3));}
+          | bpolyType conop bbtype      {$$ = gc3(ap(ap($2,$1),$3));}
+          | btype2                      {$$ = $1;}
+          | btype3                      {$$ = $1;}
+          | btype4                      {$$ = $1;}
           | con '{' fieldspecs '}'      {$$ = gc4(ap(LABC,pair($1,rev($3))));}
-          | '[' ']'                     {$$ = gc2(conNil);}
-          | '(' ')'                     {$$ = gc2(conUnit);}
-          | '(' typeTuple ')'           {$$ = gc3(buildTuple($2));}
+          | con '{' '}'                 {$$ = gc3(ap(LABC,pair($1,NIL)));}
           | error                       {syntaxError("data type definition");}
           ;
 btype3    : btype2 '!' atype            {$$ = gc3(ap($1,bang($3)));}
@@ -586,17 +319,17 @@ btype4    : btype2 bpolyType            {$$ = gc2(ap($1,$2));}
           | btype4 '!' atype            {$$ = gc3(ap($1,bang($3)));}
           ;
 bbtype    : '!' btype                   {$$ = gc2(bang($2));}
-          | btype                       {$$ = gc1($1);}
-          | bpolyType                   {$$ = gc1($1);}
+          | btype                       {$$ = $1;}
+          | bpolyType                   {$$ = $1;}
+          ;
+nconstr   : pconstr                     {$$ = gc1(singleton($1));}
           ;
 fieldspecs: fieldspecs ',' fieldspec    {$$ = gc3(cons($3,$1));}
           | fieldspec                   {$$ = gc1(cons($1,NIL));}
           ;
 fieldspec : vars COCO polyType          {$$ = gc3(pair(rev($1),$3));}
           | vars COCO type              {$$ = gc3(pair(rev($1),$3));}
-          ;
-nconstr   : con atype                   {$$ = gc2(singleton(ap($1,$2)));}
-          | con bpolyType               {$$ = gc2(singleton(ap($1,$2)));}
+          | vars COCO '!' type          {$$ = gc4(pair(rev($1),bang($4)));}
           ;
 deriving  : /* empty */                 {$$ = gc0(NIL);}
           | DERIVING qconid             {$$ = gc2(singleton($2));}
@@ -633,6 +366,9 @@ unsafe_flag: /* empty */         {$$ = gc0(NIL);}
 topDecl   : TCLASS crule wherePart      {classDefn(intOf($1),$2,$3); sp-=3;}
           | TINSTANCE irule wherePart   {instDefn(intOf($1),$2,$3);  sp-=3;}
           | DEFAULT '(' dtypes ')'      {defaultDefn(intOf($1),$3);  sp-=4;}
+          | TCLASS error                {syntaxError("class declaration");}
+          | TINSTANCE error             {syntaxError("instance declaration");}
+          | DEFAULT error               {syntaxError("default declaration");}
           ;
 crule     : context IMPLIES btype2      {$$ = gc3(pair($1,checkPred($3)));}
           | btype2                      {$$ = gc1(pair(NIL,checkPred($1)));}
@@ -649,35 +385,35 @@ dtypes1   : dtypes1 ',' type            {$$ = gc3(cons($3,$1));}
 
 /*- Type expressions: -----------------------------------------------------*/
 
-sigType   : context IMPLIES type        {$$ = gc3(ap(QUAL,pair($1,$3)));}
-          | type                        {$$ = gc1($1);}
-          ;
-topType   : context IMPLIES topType1    {$$ = gc3(ap(QUAL,pair($1,$3)));}
-          | topType1                    {$$ = gc1($1);}
+topType   : context IMPLIES topType1    {$$ = gc3(qualify($1,$3));}
+          | topType1                    {$$ = $1;}
           ;
 topType1  : bpolyType ARROW topType1    {$$ = gc3(fn($1,$3));}
           | btype1    ARROW topType1    {$$ = gc3(fn($1,$3));}
           | btype2    ARROW topType1    {$$ = gc3(fn($1,$3));}
-          | btype                       {$$ = gc1($1);}
+          | btype                       {$$ = $1;}
           ;
-polyType  : ALL varid1s '.' sigType     {$$ = gc4(ap(POLYTYPE,
+polyType  : ALL varids '.' sigType      {$$ = gc4(ap(POLYTYPE,
                                                      pair(rev($2),$4)));}
-          | bpolyType                   {$$ = gc1($1);}
+          | bpolyType                   {$$ = $1;}
           ;
 bpolyType : '(' polyType ')'            {$$ = gc3($2);}
           ;
-varid1s   : varid1s ',' varid1          {$$ = gc3(cons($3,$1));}
-          | varid1                      {$$ = gc1(cons($1,NIL));}
+varids    : varids ',' varid            {$$ = gc3(cons($3,$1));}
+          | varid                       {$$ = gc1(singleton($1));}
+          ;
+sigType   : context IMPLIES type        {$$ = gc3(qualify($1,$3));}
+          | type                        {$$ = $1;}
           ;
 context   : '(' ')'                     {$$ = gc2(NIL);}
           | btype2                      {$$ = gc1(singleton(checkPred($1)));}
           | '(' btype2 ')'              {$$ = gc3(singleton(checkPred($2)));}
-          | '(' btypes2 ')'             {$$ = gc3(checkContext($2));}
+          | '(' btypes2 ')'             {$$ = gc3(checkContext(rev($2)));}
 /*#if TREX*/
           | lacks                       {$$ = gc1(singleton($1));}
-          | '(' lacks1 ')'              {$$ = gc3(checkContext($2));}
+          | '(' lacks1 ')'              {$$ = gc3(checkContext(rev($2)));}
           ;
-lacks     : varid1 '\\' varid1          {
+lacks     : varid '\\' varid            {
 #if TREX
                                          $$ = gc3(ap(mkExt(textOf($3)),$1));
 #else
@@ -693,28 +429,28 @@ lacks1    : btypes2 ',' lacks           {$$ = gc3(cons($3,$1));}
           ;
 /*#endif*/
 
-type      : type1                       {$$ = gc1($1);}
-          | btype2                      {$$ = gc1($1);}
+type      : type1                       {$$ = $1;}
+          | btype2                      {$$ = $1;}
           ;
-type1     : btype1                      {$$ = gc1($1);}
+type1     : btype1                      {$$ = $1;}
           | btype1 ARROW type           {$$ = gc3(fn($1,$3));}
           | btype2 ARROW type           {$$ = gc3(fn($1,$3));}
           | error                       {syntaxError("type expression");}
           ;
-btype     : btype1                      {$$ = gc1($1);}
-          | btype2                      {$$ = gc1($1);}
+btype     : btype1                      {$$ = $1;}
+          | btype2                      {$$ = $1;}
           ;
 btype1    : btype1 atype                {$$ = gc2(ap($1,$2));}
-          | atype1                      {$$ = gc1($1);}
+          | atype1                      {$$ = $1;}
           ;
 btype2    : btype2 atype                {$$ = gc2(ap($1,$2));}
-          | qconid                      {$$ = gc1($1);}
+          | qconid                      {$$ = $1;}
           ;
-atype     : atype1                      {$$ = gc1($1);}
-          | qconid                      {$$ = gc1($1);}
+atype     : atype1                      {$$ = $1;}
+          | qconid                      {$$ = $1;}
           ;
-atype1    : varid1                      {$$ = gc1($1);}
-          | '(' ')'                     {$$ = gc2(conPreludeUnit);}
+atype1    : varid                       {$$ = $1;}
+          | '(' ')'                     {$$ = gc2(typeUnit);}
           | '(' ARROW ')'               {$$ = gc3(typeArrow);}
           | '(' type1 ')'               {$$ = gc3($2);}
           | '(' btype2 ')'              {$$ = gc3($2);}
@@ -731,13 +467,10 @@ atype1    : varid1                      {$$ = gc1($1);}
                                         }
           | '(' tfields '|' type ')'    {$$ = gc5(revOnto($2,$4));}
 /*#endif*/
-          | '[' type ']'                {$$ = gc3(ap(conPreludeList,$2));}
-          | '[' ']'                     {$$ = gc2(conPreludeList);}
+          | '[' type ']'                {$$ = gc3(ap(typeList,$2));}
+          | '[' ']'                     {$$ = gc2(typeList);}
           | '_'                         {$$ = gc1(inventVar());}
           ;
-tupCommas : tupCommas ','               {$$ = gc2(mkTuple(tupleOf($1)+1));}
-          | ','                         {$$ = gc1(mkTuple(2));}
-          ;
 btypes2   : btypes2 ',' btype2          {$$ = gc3(cons($3,$1));}
           | btype2  ',' btype2          {$$ = gc3(cons($3,cons($1,NIL)));}
           ;
@@ -756,155 +489,224 @@ tfield    : varid COCO type             {$$ = gc3(ap(mkExt(textOf($1)),$3));}
 
 /*- Value declarations: ---------------------------------------------------*/
 
-decllist  : '{' decls end               {$$ = gc3($2);}
+gendecl   : INFIXN optDigit ops         {$$ = gc3(fixdecl($1,$3,NON_ASS,$2));}
+          | INFIXN error                {syntaxError("fixity decl");}
+          | INFIXL optDigit ops         {$$ = gc3(fixdecl($1,$3,LEFT_ASS,$2));}
+          | INFIXL error                {syntaxError("fixity decl");}
+          | INFIXR optDigit ops         {$$ = gc3(fixdecl($1,$3,RIGHT_ASS,$2));}
+          | INFIXR error                {syntaxError("fixity decl");}
+          | vars COCO topType           {$$ = gc3(sigdecl($2,$1,$3));}
+          | vars COCO error             {syntaxError("type signature");}
           ;
-decls     : /* empty */                 {$$ = gc0(NIL);}
-          | ';'                         {$$ = gc1(NIL);}
-          | decls1                      {$$ = gc1($1);}
+optDigit  : NUMLIT                      {$$ = gc1(checkPrec($1));}
+          | /* empty */                 {$$ = gc0(mkInt(DEF_PREC));}
+          ;
+ops       : ops ',' op                  {$$ = gc3(cons($3,$1));}
+          | op                          {$$ = gc1(singleton($1));}
+          ;
+vars      : vars ',' var                {$$ = gc3(cons($3,$1));}
+          | var                         {$$ = gc1(singleton($1));}
+          ;
+decls     : '{' decls0 end              {$$ = gc3($2);}
+          | '{' decls1 end              {$$ = gc3($2);}
+          ;
+decls0    : /* empty */                 {$$ = gc0(NIL);}
+          | decls0 ';'                  {$$ = gc2($1);}
           | decls1 ';'                  {$$ = gc2($1);}
           ;
-decls1    : decls1 ';' decl             {$$ = gc3(cons($3,$1));}
-          | decl                        {$$ = gc1(cons($1,NIL));}
+decls1    : decls0 decl                 {$$ = gc2(cons($2,$1));}
+          ;
+decl      : gendecl                     {$$ = $1;}
+          | funlhs rhs                  {$$ = gc2(ap(FUNBIND,pair($1,$2)));}
+          | funlhs COCO type rhs        {$$ = gc4(ap(FUNBIND,
+                                                     pair($1,ap(RSIGN,
+                                                                ap($4,$3)))));}
+          | pat0 rhs                    {$$ = gc2(ap(PATBIND,pair($1,$2)));}
+          ;
+funlhs    : funlhs0                     {$$ = $1;}
+          | funlhs1                     {$$ = $1;}
+          | npk                         {$$ = $1;}
+          ;
+funlhs0   : pat10_vI varop    pat0      {$$ = gc3(ap2($2,$1,$3));}
+          | infixPat varop    pat0      {$$ = gc3(ap2($2,$1,$3));}
+          | NUMLIT   varop    pat0      {$$ = gc3(ap2($2,$1,$3));}
+          | var      varop_pl pat0      {$$ = gc3(ap2($2,$1,$3));}
+          | var      '+'      pat0_INT  {$$ = gc3(ap2(varPlus,$1,$3));}
           ;
-/* Sneakily using qvars to eliminate a conflict... */
-decl      : qvars COCO topType          {$$ = gc3(sigdecl($2,$1,$3));}
-          | opExp rhs                   {$$ = gc2(pair($1,$2));}
+funlhs1   : '(' funlhs0 ')' apat        {$$ = gc4(ap($2,$4));}
+          | '(' funlhs1 ')' apat        {$$ = gc4(ap($2,$4));}
+          | '(' npk     ')' apat        {$$ = gc4(ap($2,$4));}
+          | var     apat                {$$ = gc2(ap($1,$2));}
+          | funlhs1 apat                {$$ = gc2(ap($1,$2));}
           ;
 rhs       : rhs1 wherePart              {$$ = gc2(letrec($2,$1));}
           | error                       {syntaxError("declaration");}
           ;
 rhs1      : '=' exp                     {$$ = gc2(pair($1,$2));}
-          | gdefs                       {$$ = gc1(grded(rev($1)));}
+          | gdrhs                       {$$ = gc1(grded(rev($1)));}
           ;
-wherePart : WHERE decllist              {$$ = gc2($2);}
-          | /*empty*/                   {$$ = gc0(NIL);}
+gdrhs     : gdrhs gddef                 {$$ = gc2(cons($2,$1));}
+          | gddef                       {$$ = gc1(singleton($1));}
           ;
-gdefs     : gdefs gdef                  {$$ = gc2(cons($2,$1));}
-          | gdef                        {$$ = gc1(cons($1,NIL));}
+gddef     : '|' exp0 '=' exp            {$$ = gc4(pair($3,pair($2,$4)));}
           ;
-gdef      : '|' exp '=' exp             {$$ = gc4(pair($3,pair($2,$4)));}
+wherePart : /* empty */                 {$$ = gc0(NIL);}
+          | WHERE decls                 {$$ = gc2($2);}
           ;
-vars      : vars ',' var                {$$ = gc3(cons($3,$1));}
-          | var                         {$$ = gc1(cons($1,NIL));}
-          ;
-qvars     : qvars ',' qvar              {$$ = gc3(cons($3,$1));}
-          | qvar                        {$$ = gc1(cons($1,NIL));}
-          ;
-
 
+/*- Patterns: -------------------------------------------------------------*/
 
-var       : varid                       {$$ = gc1($1);}
-          | '(' '-' ')'                 {$$ = gc3(varMinus);}
+pat       : npk                         {$$ = $1;}
+          | pat_npk                     {$$ = $1;}
           ;
-varid     : varid1                      {$$ = gc1($1);}
-          | '(' VAROP ')'               {$$ = gc3($2);}
-          | '(' '!' ')'                 {$$ = gc3(varBang);}
-          | '(' '.' ')'                 {$$ = gc3(varDot);}
+pat_npk   : pat0 COCO type              {$$ = gc3(ap(ESIGN,pair($1,$3)));}
+          | pat0                        {$$ = $1;}
           ;
-varid1    : VARID                       {$$ = gc1($1);}
-          | HIDING                      {$$ = gc1(varHiding);}
-          | QUALIFIED                   {$$ = gc1(varQualified);}
-          | ASMOD                       {$$ = gc1(varAsMod);}
+npk       : var '+' NUMLIT              {$$ = gc3(ap2(varPlus,$1,$3));}
           ;
-qvar      : qvarid                      {$$ = gc1($1);}
-          | '(' qvarsym ')'             {$$ = gc3($2);}
-          | '(' '.' ')'                 {$$ = gc3(varDot);}
-          | '(' '!' ')'                 {$$ = gc3(varBang);}
-          | '(' '-' ')'                 {$$ = gc3(varMinus);}
+pat0      : var                         {$$ = $1;}
+          | NUMLIT                      {$$ = $1;}
+          | pat0_vI                     {$$ = $1;}
           ;
-qvarid    : varid1                      {$$ = gc1($1);}
-          | QVARID                      {$$ = gc1($1);}
+pat0_INT  : var                         {$$ = $1;}
+          | pat0_vI                     {$$ = $1;}
           ;
-
-op        : varop                       {$$ = gc1($1);}
-          | conop                       {$$ = gc1($1);}
-          | '-'                         {$$ = gc1(varMinus);}
+pat0_vI   : pat10_vI                    {$$ = $1;}
+          | infixPat                    {$$ = gc1(ap(INFIX,$1));}
           ;
-qop       : qvarop                      {$$ = gc1($1);}
-          | qconop                      {$$ = gc1($1);}
-          | '-'                         {$$ = gc1(varMinus);}
+infixPat  : '-' pat10                   {$$ = gc2(ap(NEG,only($2)));}
+          | var qconop pat10            {$$ = gc3(ap(ap($2,only($1)),$3));}
+          | var qconop '-' pat10        {$$ = gc4(ap(NEG,ap2($2,only($1),$4)));}
+          | NUMLIT qconop pat10         {$$ = gc3(ap(ap($2,only($1)),$3));}
+          | NUMLIT qconop '-' pat10     {$$ = gc4(ap(NEG,ap2($2,only($1),$4)));}
+          | pat10_vI qconop pat10       {$$ = gc3(ap(ap($2,only($1)),$3));}
+          | pat10_vI qconop '-' pat10   {$$ = gc4(ap(NEG,ap2($2,only($1),$4)));}
+          | infixPat qconop pat10       {$$ = gc3(ap(ap($2,$1),$3));}
+          | infixPat qconop '-' pat10   {$$ = gc4(ap(NEG,ap(ap($2,$1),$4)));}
           ;
-
-varop     : VAROP                       {$$ = gc1($1);}
-          | '!'                         {$$ = gc1(varBang);}
-          | '.'                         {$$ = gc1(varDot);}
-          | '`' varid1 '`'              {$$ = gc3($2);}
+pat10     : fpat                        {$$ = $1;}
+          | apat                        {$$ = $1;}
           ;
-qvarop    : qvarsym                     {$$ = gc1($1);}
-          | '!'                         {$$ = gc1(varBang);}
-          | '.'                         {$$ = gc1(varDot);}
-          | '`' qvarid '`'              {$$ = gc3($2);}
+pat10_vI  : fpat                        {$$ = $1;}
+          | apat_vI                     {$$ = $1;}
           ;
-qvarsym   : VAROP                       {$$ = gc1($1);}
-          | QVAROP                      {$$ = gc1($1);}
+fpat      : fpat apat                   {$$ = gc2(ap($1,$2));}
+          | gcon apat                   {$$ = gc2(ap($1,$2));}
           ;
-
-con       : CONID                       {$$ = gc1($1);}
-          | '(' CONOP ')'               {$$ = gc3($2);}
+apat      : NUMLIT                      {$$ = $1;}
+          | var                         {$$ = $1;}
+          | apat_vI                     {$$ = $1;}
           ;
-qcon      : qconid                      {$$ = gc1($1);}
-          | '(' qconsym ')'             {$$ = gc3($2);}
+apat_vI   : var '@' apat                {$$ = gc3(ap(ASPAT,pair($1,$3)));}
+          | gcon                        {$$ = $1;}
+          | qcon '{' patbinds '}'       {$$ = gc4(ap(CONFLDS,pair($1,$3)));}
+          | CHARLIT                     {$$ = $1;}
+          | STRINGLIT                   {$$ = $1;}
+          | '_'                         {$$ = gc1(WILDCARD);}
+          | '(' pat_npk ')'             {$$ = gc3($2);}
+          | '(' npk ')'                 {$$ = gc3($2);}
+          | '(' pats2 ')'               {$$ = gc3(buildTuple($2));}
+          | '[' pats1 ']'               {$$ = gc3(ap(FINLIST,rev($2)));}
+          | '~' apat                    {$$ = gc2(ap(LAZYPAT,$2));}
+/*#if TREX*/
+          | '(' patfields ')'           {
+#if TREX
+                                         $$ = gc3(revOnto($2,nameNoRec));
+#else
+                                         $$ = gc3(NIL);
+#endif
+                                        }
+          | '(' patfields '|' pat ')'   {$$ = gc5(revOnto($2,$4));}
+/*#endif TREX*/
           ;
-qconid    : CONID                       {$$ = gc1($1);}
-          | QCONID                      {$$ = gc1($1);}
+pats2     : pats2 ',' pat               {$$ = gc3(cons($3,$1));}
+          | pat ',' pat                 {$$ = gc3(cons($3,singleton($1)));}
           ;
-qconsym   : CONOP                       {$$ = gc1($1);}
-          | QCONOP                      {$$ = gc1($1);}
+pats1     : pats1 ',' pat               {$$ = gc3(cons($3,$1));}
+          | pat                         {$$ = gc1(singleton($1));}
           ;
-
-conop     : CONOP                       {$$ = gc1($1);}
-          | '`' CONID '`'               {$$ = gc3($2);}
+patbinds  : /* empty */                 {$$ = gc0(NIL);}
+          | patbinds1                   {$$ = gc1(rev($1));}
+          ;
+patbinds1 : patbinds1 ',' patbind       {$$ = gc3(cons($3,$1));}
+          | patbind                     {$$ = gc1(singleton($1));}
           ;
-qconop    : qconsym                     {$$ = gc1($1);}
-          | '`' qconid '`'              {$$ = gc3($2);}
+patbind   : qvar '=' pat                {$$ = gc3(pair($1,$3));}
+          | var                         {$$ = $1;}
+          ;
+/*#if TREX*/
+patfields : patfields ',' patfield      {$$ = gc3(cons($3,$1));}
+          | patfield                    {$$ = gc1(singleton($1));}
           ;
+patfield  : varid '=' pat               {
+#if TREX
+                                         $$ = gc3(ap(mkExt(textOf($1)),$3));
+#else
+                                         noTREX("a pattern");
+#endif
+                                        }
+          ;
+/*#endif TREX*/
 
 /*- Expressions: ----------------------------------------------------------*/
 
-exp       : exp1                        {$$ = gc1($1);}
+exp       : exp_err                     {$$ = $1;}
           | error                       {syntaxError("expression");}
           ;
-exp1      : opExp COCO sigType          {$$ = gc3(ap(ESIGN,pair($1,$3)));}
-          | opExp                       {$$ = gc1($1);}
+exp_err   : exp0a COCO sigType          {$$ = gc3(ap(ESIGN,pair($1,$3)));}
+          | exp0                        {$$ = $1;}
+          ;
+exp0      : exp0a                       {$$ = $1;}
+          | exp0b                       {$$ = $1;}
+          ;
+exp0a     : infixExpa                   {$$ = gc1(ap(INFIX,$1));}
+          | exp10a                      {$$ = $1;}
           ;
-opExp     : opExp0                      {$$ = gc1(tidyInfix($1));}
-          | pfxExp                      {$$ = gc1($1);}
+exp0b     : infixExpb                   {$$ = gc1(ap(INFIX,$1));}
+          | exp10b                      {$$ = $1;}
           ;
-opExp0    : opExp0 qop '-' pfxExp       {$$ = gc4(ap(NEG,ap(ap($2,$1),$4)));}
-          | opExp0 qop pfxExp           {$$ = gc3(ap2($2,$1,$3));}
-          | '-' pfxExp                  {$$ = gc2(ap(NEG,only($2)));}
-          | pfxExp qop pfxExp           {$$ = gc3(ap(ap($2,only($1)),$3));}
-          | pfxExp qop '-' pfxExp       {$$ = gc4(ap(NEG,
+infixExpa : infixExpa qop '-' exp10a    {$$ = gc4(ap(NEG,ap(ap($2,$1),$4)));}
+          | infixExpa qop exp10a        {$$ = gc3(ap(ap($2,$1),$3));}
+          | '-' exp10a                  {$$ = gc2(ap(NEG,only($2)));}
+          | exp10a qop '-' exp10a       {$$ = gc4(ap(NEG,
                                                      ap(ap($2,only($1)),$4)));}
+          | exp10a qop exp10a           {$$ = gc3(ap(ap($2,only($1)),$3));}
+          ;
+infixExpb : infixExpa qop '-' exp10b    {$$ = gc4(ap(NEG,ap(ap($2,$1),$4)));}
+          | infixExpa qop exp10b        {$$ = gc3(ap(ap($2,$1),$3));}
+          | '-' exp10b                  {$$ = gc2(ap(NEG,only($2)));}
+          | exp10a qop '-' exp10b       {$$ = gc4(ap(NEG,
+                                                     ap(ap($2,only($1)),$4)));}
+          | exp10a qop exp10b           {$$ = gc3(ap(ap($2,only($1)),$3));}
+          ;
+exp10a    : CASEXP exp OF '{' alts end  {$$ = gc6(ap(CASE,pair($2,rev($5))));}
+          | DO '{' stmts end            {$$ = gc4(ap(DOCOMP,checkDo($3)));}
+          | appExp                      {$$ = $1;}
           ;
-pfxExp    : '\\' pats ARROW exp         {$$ = gc4(ap(LAMBDA,      
+exp10b    : '\\' pats ARROW exp         {$$ = gc4(ap(LAMBDA,      
                                                      pair(rev($2),
                                                           pair($3,$4))));}
-          | LET decllist IN exp         {$$ = gc4(letrec($2,$4));}
+          | LET decls IN exp            {$$ = gc4(letrec($2,$4));}
           | IF exp THEN exp ELSE exp    {$$ = gc6(ap(COND,triple($2,$4,$6)));}
-          | CASEXP exp OF '{' alts end  {$$ = gc6(ap(CASE,pair($2,rev($5))));}
-          | DO '{' stmts end            {$$ = gc4(ap(DOCOMP,checkDo($3)));}
-          | appExp                      {$$ = gc1($1);}
           ;
-pats      : pats atomic                 {$$ = gc2(cons($2,$1));}
-          | atomic                      {$$ = gc1(cons($1,NIL));}
+pats      : pats apat                   {$$ = gc2(cons($2,$1));}
+          | apat                        {$$ = gc1(cons($1,NIL));}
           ;
-appExp    : appExp atomic               {$$ = gc2(ap($1,$2));}
-          | atomic                      {$$ = gc1($1);}
+appExp    : appExp aexp                 {$$ = gc2(ap($1,$2));}
+          | aexp                        {$$ = $1;}
           ;
-atomic    : qvar                        {$$ = gc1($1);}
-          | qvar '@' atomic             {$$ = gc3(ap(ASPAT,pair($1,$3)));}
-          | '~' atomic                  {$$ = gc2(ap(LAZYPAT,$2));}
+aexp      : qvar                        {$$ = $1;}
+          | qvar '@' aexp               {$$ = gc3(ap(ASPAT,pair($1,$3)));}
+          | '~' aexp                    {$$ = gc2(ap(LAZYPAT,$2));}
           | '_'                         {$$ = gc1(WILDCARD);}
-          | qcon                        {$$ = gc1($1);}
+          | gcon                        {$$ = $1;}
           | qcon '{' fbinds '}'         {$$ = gc4(ap(CONFLDS,pair($1,$3)));}
-          | atomic '{' fbinds '}'       {$$ = gc4(ap(UPDFLDS,
+          | aexp '{' fbinds '}'         {$$ = gc4(ap(UPDFLDS,
                                                      triple($1,NIL,$3)));}
-          | '(' ')'                     {$$ = gc2(conPreludeUnit);}
-          | NUMLIT                      {$$ = gc1($1);}
-          | CHARLIT                     {$$ = gc1($1);}
-          | STRINGLIT                   {$$ = gc1($1);}
-          | REPEAT                      {$$ = gc1($1);}
+          | NUMLIT                      {$$ = $1;}
+          | CHARLIT                     {$$ = $1;}
+          | STRINGLIT                   {$$ = $1;}
+          | REPEAT                      {$$ = $1;}
           | '(' exp ')'                 {$$ = gc3($2);}
           | '(' exps2 ')'               {$$ = gc3(buildTuple($2));}
 /*#if TREX*/
@@ -916,13 +718,12 @@ atomic    : qvar                        {$$ = gc1($1);}
 #endif
                                         }
           | '(' vfields '|' exp ')'     {$$ = gc5(revOnto($2,$4));}
-          | RECSELID                    {$$ = gc1($1);}
+          | RECSELID                    {$$ = $1;}
 /*#endif*/
           | '[' list ']'                {$$ = gc3($2);}
-          | '(' pfxExp qop ')'          {$$ = gc4(ap($3,$2));}
-          | '(' qvarop atomic ')'       {$$ = gc4(ap2(varFlip,$2,$3));}
-          | '(' qconop atomic ')'       {$$ = gc4(ap2(varFlip,$2,$3));}
-          | '(' tupCommas ')'           {$$ = gc3($2);}
+          | '(' exp10a qop ')'          {$$ = gc4(ap($3,$2));}
+          | '(' qvarop_mi exp0 ')'      {$$ = gc4(ap(ap(nameFlip,$2),$3));}
+          | '(' qconop exp0 ')'         {$$ = gc4(ap(ap(nameFlip,$2),$3));}
           ;
 exps2     : exps2 ',' exp               {$$ = gc3(cons($3,$1));}
           | exp ',' exp                 {$$ = gc3(cons($3,cons($1,NIL)));}
@@ -931,7 +732,7 @@ exps2     : exps2 ',' exp               {$$ = gc3(cons($3,$1));}
 vfields   : vfields ',' vfield          {$$ = gc3(cons($3,$1));}
           | vfield                      {$$ = gc1(singleton($1));}
           ;
-vfield    : qvarid '=' exp              {
+vfield    : varid '=' exp               {
 #if TREX
                                          $$ = gc3(ap(mkExt(textOf($1)),$3));
 #else
@@ -940,13 +741,13 @@ vfield    : qvarid '=' exp              {
                                         }
           ;
 /*#endif*/
-alts      : alts1                       {$$ = gc1($1);}
+alts      : alts1                       {$$ = $1;}
           | alts1 ';'                   {$$ = gc2($1);}
           ;
 alts1     : alts1 ';' alt               {$$ = gc3(cons($3,$1));}
           | alt                         {$$ = gc1(cons($1,NIL));}
           ;
-alt       : opExp altRhs wherePart      {$$ = gc3(pair($1,letrec($3,$2)));}
+alt       : pat altRhs wherePart        {$$ = gc3(pair($1,letrec($3,$2)));}
           ;
 altRhs    : guardAlts                   {$$ = gc1(grded(rev($1)));}
           | ARROW exp                   {$$ = gc2(pair($1,$2));}
@@ -955,18 +756,18 @@ altRhs    : guardAlts                   {$$ = gc1(grded(rev($1)));}
 guardAlts : guardAlts guardAlt          {$$ = gc2(cons($2,$1));}
           | guardAlt                    {$$ = gc1(cons($1,NIL));}
           ;
-guardAlt  : '|' opExp ARROW exp         {$$ = gc4(pair($3,pair($2,$4)));}
+guardAlt  : '|' exp0 ARROW exp          {$$ = gc4(pair($3,pair($2,$4)));}
           ;
 stmts     : stmts1 ';'                  {$$ = gc2($1);}
-          | stmts1                      {$$ = gc1($1);}
+          | stmts1                      {$$ = $1;}
           ;
 stmts1    : stmts1 ';' stmt             {$$ = gc3(cons($3,$1));}
           | stmt                        {$$ = gc1(cons($1,NIL));}
           ;
-stmt      : exp1 FROM exp               {$$ = gc3(ap(FROMQUAL,pair($1,$3)));}
-          | LET decllist                {$$ = gc2(ap(QWHERE,$2));}
-          | IF exp                      {$$ = gc2(ap(BOOLQUAL,$2));}
-          | exp1                        {$$ = gc1(ap(DOQUAL,$1));}
+stmt      : exp_err FROM exp            {$$ = gc3(ap(FROMQUAL,pair($1,$3)));}
+          | LET decls                   {$$ = gc2(ap(QWHERE,$2));}
+/*        | IF exp                      {$$ = gc2(ap(BOOLQUAL,$2));}*/
+          | exp_err                     {$$ = gc1(ap(DOQUAL,$1));}
           ;
 fbinds    : /* empty */                 {$$ = gc0(NIL);}
           | fbinds1                     {$$ = gc1(rev($1));}
@@ -974,28 +775,111 @@ fbinds    : /* empty */                 {$$ = gc0(NIL);}
 fbinds1   : fbinds1 ',' fbind           {$$ = gc3(cons($3,$1));}
           | fbind                       {$$ = gc1(singleton($1));}
           ;
-fbind     : var                         {$$ = gc1($1);}
+fbind     : var                         {$$ = $1;}
           | qvar '=' exp                {$$ = gc3(pair($1,$3));}
           ;
 
 /*- List Expressions: -------------------------------------------------------*/
 
-list      : /* empty */                 {$$ = gc0(conPreludeNil);}
-          | exp                         {$$ = gc1(ap(FINLIST,cons($1,NIL)));}
+list      : exp                         {$$ = gc1(ap(FINLIST,cons($1,NIL)));}
           | exps2                       {$$ = gc1(ap(FINLIST,rev($1)));}
           | exp '|' quals               {$$ = gc3(ap(COMP,pair($1,rev($3))));}
-          | exp         UPTO exp        {$$ = gc3(ap2(varEnumFromTo,$1,$3));}
-          | exp ',' exp UPTO            {$$ = gc4(ap2(varEnumFromThen,$1,$3));}
-          | exp         UPTO            {$$ = gc2(ap1(varEnumFrom,$1));}
-          | exp ',' exp UPTO exp        {$$ = gc5(ap3(varEnumFromThenTo,
-                                                      $1,$3,$5));}
+          | exp         UPTO exp        {$$ = gc3(ap(ap(nameFromTo,$1),$3));}
+          | exp ',' exp UPTO            {$$ = gc4(ap(ap(nameFromThen,$1),$3));}
+          | exp         UPTO            {$$ = gc2(ap(nameFrom,$1));}
+          | exp ',' exp UPTO exp        {$$ = gc5(ap(ap(ap(nameFromThenTo,
+                                                                $1),$3),$5));}
           ;
 quals     : quals ',' qual              {$$ = gc3(cons($3,$1));}
           | qual                        {$$ = gc1(cons($1,NIL));}
           ;
 qual      : exp FROM exp                {$$ = gc3(ap(FROMQUAL,pair($1,$3)));}
           | exp                         {$$ = gc1(ap(BOOLQUAL,$1));}
-          | LET decllist                {$$ = gc2(ap(QWHERE,$2));}
+          | LET decls                   {$$ = gc2(ap(QWHERE,$2));}
+          ;
+
+/*- Identifiers and symbols: ----------------------------------------------*/
+
+gcon      : qcon                        {$$ = $1;}
+          | '(' ')'                     {$$ = gc2(nameUnit);}
+          | '[' ']'                     {$$ = gc2(nameNil);}
+          | '(' tupCommas ')'           {$$ = gc3($2);}
+          ;
+tupCommas : tupCommas ','               {$$ = gc2(mkTuple(tupleOf($1)+1));}
+          | ','                         {$$ = gc1(mkTuple(2));}
+          ;
+varid     : VARID                       {$$ = $1;}
+          | HIDING                      {$$ = gc1(varHiding);}
+          | QUALIFIED                   {$$ = gc1(varQualified);}
+          | ASMOD                       {$$ = gc1(varAsMod);}
+          ;
+qconid    : QCONID                      {$$ = $1;}
+          | CONID                       {$$ = $1;}
+          ;
+var       : varid                       {$$ = $1;}
+          | '(' VAROP ')'               {$$ = gc3($2);}
+          | '(' '+' ')'                 {$$ = gc3(varPlus);}
+          | '(' '-' ')'                 {$$ = gc3(varMinus);}
+          | '(' '!' ')'                 {$$ = gc3(varBang);}
+          | '(' '.' ')'                 {$$ = gc3(varDot);}
+          ;
+qvar      : QVARID                      {$$ = $1;}
+          | '(' QVAROP ')'              {$$ = gc3($2);}
+          | var                         {$$ = $1;}
+          ;
+con       : CONID                       {$$ = $1;}
+          | '(' CONOP ')'               {$$ = gc3($2);}
+          ;
+qcon      : QCONID                      {$$ = $1;}
+          | '(' QCONOP ')'              {$$ = gc3($2);}
+          | con                         {$$ = $1;}
+          ;
+varop     : '+'                         {$$ = gc1(varPlus);}
+          | '-'                         {$$ = gc1(varMinus);}
+          | varop_mipl                  {$$ = $1;}
+          ;
+varop_mi  : '+'                         {$$ = gc1(varPlus);}
+          | varop_mipl                  {$$ = $1;}
+          ;
+varop_pl  : '-'                         {$$ = gc1(varMinus);}
+          | varop_mipl                  {$$ = $1;}
+          ;
+varop_mipl: VAROP                       {$$ = $1;}
+          | '`' varid '`'               {$$ = gc3($2);}
+          | '!'                         {$$ = gc1(varBang);}
+          | '.'                         {$$ = gc1(varDot);}
+          ;
+qvarop    : '-'                         {$$ = gc1(varMinus);}
+          | qvarop_mi                   {$$ = $1;}
+          ;
+qvarop_mi : QVAROP                      {$$ = $1;}
+          | '`' QVARID '`'              {$$ = gc3($2);}
+          | varop_mi                    {$$ = $1;}
+          ;
+
+conop     : CONOP                       {$$ = $1;}
+          | '`' CONID  '`'              {$$ = gc3($2);}
+          ;
+qconop    : QCONOP                      {$$ = $1;}
+          | '`' QCONID '`'              {$$ = gc3($2);}
+          | conop                       {$$ = $1;}
+          ;
+op        : varop                       {$$ = $1;}
+          | conop                       {$$ = $1;}
+          ;
+qop       : qvarop                      {$$ = $1;}
+          | qconop                      {$$ = $1;}
+          ;
+
+/*- Stuff from STG hugs ---------------------------------------------------*/
+
+qvarid    : varid1                      {$$ = gc1($1);}
+          | QVARID                      {$$ = gc1($1);}
+
+varid1    : VARID                       {$$ = gc1($1);}
+          | HIDING                      {$$ = gc1(varHiding);}
+          | QUALIFIED                   {$$ = gc1(varQualified);}
+          | ASMOD                       {$$ = gc1(varAsMod);}
           ;
 
 /*- Tricks to force insertion of leading and closing braces ---------------*/
@@ -1003,7 +887,7 @@ qual      : exp FROM exp                {$$ = gc3(ap(FROMQUAL,pair($1,$3)));}
 begin     : error                       {yyerrok; goOffside(startColumn);}
           ;
                                         /* deal with trailing semicolon    */
-end       : '}'                         {$$ = gc1($1);}
+end       : '}'                         {$$ = $1;}
           | error                       {yyerrok; 
                                          if (canUnOffside()) {
                                              unOffside();
@@ -1045,7 +929,7 @@ Cell e; {
     return e;
 }
 
-static Void local syntaxError(s)       /* report on syntax error           */
+static Void local syntaxError(s)        /* report on syntax error          */
 String s; {
     ERRMSG(row) "Syntax error in %s (unexpected %s)", s, unexpected()
     EEND;
@@ -1062,7 +946,7 @@ static String local unexpected() {     /* find name for unexpected token   */
 #define keyword(kw) sprintf(buffer,fmt,kwd,kw); return buffer;
         case INFIXL    : keyword("infixl");
         case INFIXR    : keyword("infixr");
-        case INFIX     : keyword("infix");
+        case INFIXN    : keyword("infix");
         case FOREIGN   : keyword("foreign");
         case UNSAFE    : keyword("unsafe");
         case TINSTANCE : keyword("instance");
@@ -1081,10 +965,7 @@ static String local unexpected() {     /* find name for unexpected token   */
         case DERIVING  : keyword("deriving");
         case DEFAULT   : keyword("default");
         case IMPORT    : keyword("import");
-        case EXPORT    : keyword("export");
-        case MODULETOK : keyword("module");
-        case INTERFACE : keyword("interface");
-        case WILDCARD  : keyword("_");
+        case TMODULE   : keyword("module");
         case ALL       : keyword("forall");
 #undef keyword
 
@@ -1138,54 +1019,30 @@ static String local unexpected() {     /* find name for unexpected token   */
     }
 }
 
-static Cell local checkPrec(p)         /* Check for valid precedence value */
+static Cell local checkPrec(p)          /* Check for valid precedence value*/
 Cell p; {
-    if ((!isInt(p) || intOf(p)<MIN_PREC || intOf(p)>MAX_PREC)
-        && (!isBignum(p) || bignumOf(p)<MIN_PREC || bignumOf(p)>MAX_PREC)
-        ) {
+    if (!isInt(p) || intOf(p)<MIN_PREC || intOf(p)>MAX_PREC) {
         ERRMSG(row) "Precedence value must be an integer in the range [%d..%d]",
                     MIN_PREC, MAX_PREC
         EEND;
     }
-    if (isBignum(p)) {
-        return mkInt(bignumOf(p));
-    } else {
-        return p;
-    }
-}
-
-static Void local fixDefn(a,line,p,ops)/* Declare syntax of operators      */
-Syntax a;
-Cell   line;
-Cell   p;
-List   ops; {
-    Int l = intOf(line);
-    a     = mkSyntax(a,intOf(p));
-    map2Proc(setSyntax,l,a,ops);
+    return p;
 }
 
-static Void local setSyntax(line,sy,op)/* set syntax of individ. operator  */
-Int    line;
-Syntax sy;
-Cell   op; {
-    addSyntax(line,textOf(op),sy);
-    opDefns = cons(op,opDefns);
-}
-
-static Cell local buildTuple(tup)      /* build tuple (x1,...,xn) from list*/
-List tup; {                            /* [xn,...,x1]                      */
+static Cell local buildTuple(tup)       /* build tuple (x1,...,xn) from    */
+List tup; {                             /* list [xn,...,x1]                */
     Int  n = 0;
     Cell t = tup;
     Cell x;
 
-    do {                               /*     .                    .       */
-        x      = fst(t);               /*    / \                  / \      */
-        fst(t) = snd(t);               /*   xn  .                .   xn    */
-        snd(t) = x;                    /*        .    ===>      .          */
-        x      = t;                    /*         .            .           */
-        t      = fun(x);               /*          .          .            */
-        n++;                           /*         / \        / \           */
-    } while (nonNull(t));              /*        x1  NIL   (n)  x1         */
+    do {                                /*    .                    .       */
+        x      = fst(t);                /*   / \                  / \      */
+        fst(t) = snd(t);                /*  xn  .                .   xn    */
+        snd(t) = x;                     /*       .    ===>      .          */
+        x      = t;                     /*        .            .           */
+        t      = fun(x);                /*         .          .            */
+        n++;                            /*        / \        / \           */
+    } while (nonNull(t));               /*       x1  NIL   (n)  x1         */
     fst(x) = mkTuple(n);
     return tup;
 }
@@ -1231,228 +1088,16 @@ Cell c; {                               /* T a1 ... a                      */
             ERRMSG(row) "Illegal left hand side in datatype definition"
             EEND;
     }
+    assert(0); return 0; /* NOTREACHED */
 }
 
 #if !TREX
 static Void local noTREX(where)
 String where; {
-    ERRMSG(row) "Attempt to use Typed Records with Extensions\nwhile parsing %s. This feature is disabled in this build of Hugs.",
-                 where
+    ERRMSG(row) "Attempt to use TREX records while parsing %s.\n", where ETHEN
+    ERRTEXT     "(TREX is disabled in this build of Hugs)"
     EEND;
 }
 #endif
 
-/* Expressions involving infix operators or unary minus are parsed as elements
- * of the following type:
- *
- *     data OpExp = Only Exp | Neg OpExp | Infix OpExp Op Exp
- *
- * (The algorithms here do not assume that negation can be applied only once,
- * i.e., that - - x is a syntax error, as required by the Haskell report.
- * Instead, that restriction is captured by the grammar itself, given above.)
- *
- * There are rules of precedence and grouping, expressed by two functions:
- *
- *     prec :: Op -> Int;   assoc :: Op -> Assoc    (Assoc = {L, N, R})
- *
- * OpExp values are rearranged accordingly when a complete expression has
- * been read using a simple shift-reduce parser whose result may be taken
- * to be a value of the following type:
- *
- *     data Exp = Atom Int | Negate Exp | Apply Op Exp Exp | Error String
- *
- * The machine on which this parser is based can be defined as follows:
- *
- *     tidy                         :: OpExp -> [(Op,Exp)] -> Exp
- *     tidy (Only a)      []         = a
- *     tidy (Only a)      ((o,b):ss) = tidy (Only (Apply o a b)) ss
- *     tidy (Infix a o b) []         = tidy a [(o,b)]
- *     tidy (Infix a o b) ((p,c):ss)
- *                      | shift  o p = tidy a ((o,b):(p,c):ss)
- *                      | red    o p = tidy (Infix a o (Apply p b c)) ss
- *                      | ambig  o p = Error "ambiguous use of operators"
- *     tidy (Neg e)       []         = tidy (tidyNeg e) []
- *     tidy (Neg e)       ((o,b):ss)
- *                      | nshift o   = tidy (Neg (underNeg o b e)) ss
- *                      | nred   o   = tidy (tidyNeg e) ((o,b):ss)
- *                      | nambig o   = Error "illegal use of negation"
- *
- * At each stage, the parser can either shift, reduce, accept, or error.
- * The transitions when dealing with juxtaposed operators o and p are
- * determined by the following rules:
- *
- *     shift o p  = (prec o > prec p)
- *               || (prec o == prec p && assoc o == L && assoc p == L)
- *
- *     red o p    = (prec o < prec p)
- *               || (prec o == prec p && assoc o == R && assoc p == R)
- *
- *     ambig o p  = (prec o == prec p)
- *               && (assoc o == N || assoc p == N || assoc o /= assoc p)
- *
- * The transitions when dealing with juxtaposed unary minus and infix operators
- * are as follows.  The precedence of unary minus (infixl 6) is hardwired in
- * to these definitions, as it is to the definitions of the Haskell grammar
- * in the official report.
- *
- *     nshift o   = (prec o > 6)
- *     nred   o   = (prec o < 6) || (prec o == 6 && assoc o == L)
- *     nambig o   = prec o == 6 && (assoc o == R || assoc o == N)
- *
- * An OpExp of the form (Neg e) means negate the last thing in the OpExp e;
- * we can force this negation using:
- *
- *     tidyNeg              :: OpExp -> OpExp
- *     tidyNeg (Only e)      = Only (Negate e)
- *     tidyNeg (Infix a o b) = Infix a o (Negate b)
- *     tidyNeg (Neg e)       = tidyNeg (tidyNeg e)
- * 
- * On the other hand, if we want to sneak application of an infix operator
- * under a negation, then we use:
- *
- *     underNeg                  :: Op -> Exp -> OpExp -> OpExp
- *     underNeg o b (Only e)      = Only (Apply o e b)
- *     underNeg o b (Neg e)       = Neg (underNeg o b e)
- *     underNeg o b (Infix e p f) = Infix e p (Apply o f b)
- *
- * As a concession to efficiency, we lower the number of calls to syntaxOf
- * by keeping track of the values of sye, sys throughout the process.  The
- * value APPLIC is used to indicate that the syntax value is unknown.
- */
-
-#define UMINUS_PREC  6                  /* Change these settings at your   */
-#define UMINUS_ASSOC LEFT_ASS           /* own risk; they may not work!    */
-
-static Cell local tidyInfix(e)          /* convert OpExp to Expr           */
-Cell e; {                               /* :: OpExp                        */
-    Cell s     = NIL;                   /* :: [(Op,Exp)]                   */
-    Syntax sye = APPLIC;                /* Syntax of op in e (init unknown)*/
-    Syntax sys = APPLIC;                /* Syntax of op in s (init unknown)*/
-
-    for (;;)
-        switch (whatIs(e)) {
-            case ONLY : e = snd(e);
-                        while (nonNull(s)) {
-                            Cell next   = arg(fun(s));
-                            arg(fun(s)) = e;
-                            e           = s;
-                            s           = next;
-                        }
-                        return e;
-
-            case NEG  : if (nonNull(s)) {
-
-                            if (sys==APPLIC) {  /* calculate sys           */
-                                sys = identSyntax(fun(fun(s)));
-                                if (sys==APPLIC) sys=DEF_OPSYNTAX;
-                            }
-
-                            if (precOf(sys)==UMINUS_PREC &&     /* nambig  */
-                                assocOf(sys)!=UMINUS_ASSOC) {
-                                ERRMSG(row)
-                                 "Ambiguous use of unary minus with \"%s\"",
-                                   textToStr(textOf(fun(fun(s))))
-                                EEND;
-                            }
-
-                            if (precOf(sys)>UMINUS_PREC) {      /* nshift  */
-                                Cell e1    = snd(e);
-                                Cell t     = s;
-                                s          = arg(fun(s));
-                                while (whatIs(e1)==NEG)
-                                    e1 = snd(e1);
-                                arg(fun(t)) = arg(e1);
-                                arg(e1)     = t;
-                                sys         = APPLIC;
-                                continue;
-                            }
-                        
-                        }
-
-                        /* Intentional fall-thru for nreduce and isNull(s) */
-                        {   Cell prev = e;              /* e := tidyNeg e  */
-                            Cell temp = arg(prev);
-                            Int  nneg = 1;
-                            for (; whatIs(temp)==NEG; nneg++) {
-                                fun(prev) = varNegate;
-                                prev      = temp;
-                                temp      = arg(prev);
-                            }
-                            /* These special cases are required for
-                             * pattern matching.
-                             */
-                            if (isInt(arg(temp))) {     /* special cases   */
-                                if (nneg&1)             /* for literals    */
-                                    arg(temp) = intNegate(arg(temp));
-                            }
-                            else if (isBignum(arg(temp))) {
-                                if (nneg&1) 
-                                    arg(temp) = bignumNegate(arg(temp));
-                            }
-                            else if (isFloat(arg(temp))) {
-                                if (nneg&1) 
-                                    arg(temp) = floatNegate(arg(temp));
-                            }
-                            else {
-                                fun(prev) = varNegate;
-                                arg(prev) = arg(temp);
-                                arg(temp) = e;
-                            }
-                            e = temp;
-                        }
-                        continue;
-
-            default   : if (isNull(s)) {/* Move operation onto empty stack */
-                            Cell next   = arg(fun(e));
-                            s           = e;
-                            arg(fun(s)) = NIL;
-                            e           = next;
-                            sys         = sye;
-                            sye         = APPLIC;
-                        }
-                        else {          /* deal with pair of operators     */
-
-                            if (sye==APPLIC) {  /* calculate sys and sye   */
-                                sye = identSyntax(fun(fun(e)));
-                                if (sye==APPLIC) sye=DEF_OPSYNTAX;
-                            }
-                            if (sys==APPLIC) {
-                                sys = identSyntax(fun(fun(s)));
-                                if (sys==APPLIC) sys=DEF_OPSYNTAX;
-                            }
-
-                            if (precOf(sye)==precOf(sys) &&     /* ambig   */
-                                (assocOf(sye)!=assocOf(sys) ||
-                                 assocOf(sye)==NON_ASS)) {
-                                ERRMSG(row)
-                                "Ambiguous use of operator \"%s\" with \"%s\"",
-                                  textToStr(textOf(fun(fun(e)))),
-                                  textToStr(textOf(fun(fun(s))))
-                                EEND;
-                            }
-
-                            if (precOf(sye)>precOf(sys) ||      /* shift   */
-                                (precOf(sye)==precOf(sys) &&
-                                 assocOf(sye)==LEFT_ASS &&
-                                 assocOf(sys)==LEFT_ASS)) {
-                                Cell next   = arg(fun(e));
-                                arg(fun(e)) = s;
-                                s           = e;
-                                e           = next;
-                                sys         = sye;
-                                sye         = APPLIC;
-                            }
-                            else {                              /* reduce  */
-                                Cell next   = arg(fun(s));
-                                arg(fun(s)) = arg(e);
-                                arg(e)      = s;
-                                s           = next;
-                                sys         = APPLIC;
-                                /* sye unchanged */
-                            }
-                        }
-                        continue;
-        }
-}
-
 /*-------------------------------------------------------------------------*/
index 6a88cb8..fc5eaa1 100644 (file)
@@ -1,10 +1,15 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
- * preds.c:     Copyright (c) Mark P Jones 1991-1998.   All rights reserved.
- *              See NOTICE for details and conditions of use etc...
- *              Hugs version 1.3c, March 1998
+ * Part of the type checker dealing with predicates and entailment
+ *
+ * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
+ * Haskell Group 1994-99, and is distributed as Open Source software
+ * under the Artistic License; see the file "Artistic" that is included
+ * in the distribution for details.
  *
- * Part of type checker dealing with predicates and entailment.
+ * $RCSfile: preds.c,v $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:35 $
  * ------------------------------------------------------------------------*/
 
 /* --------------------------------------------------------------------------
@@ -19,10 +24,11 @@ static Void   local qualifyBinding    Args((List,Cell));
 static Cell   local qualifyExpr       Args((Int,List,Cell));
 static Void   local overEvid          Args((Cell,Cell));
 
-static Cell   local scFind            Args((Cell,Cell,Int,Cell,Int));
-static Cell   local scEntail          Args((List,Cell,Int));
-static Cell   local entail            Args((List,Cell,Int));
-static Cell   local inEntail          Args((List,Cell,Int));
+static Void   local cutoffExceeded    Args((Cell,Int,Cell,Int,List));
+static Cell   local scFind            Args((Cell,Cell,Int,Cell,Int,Int));
+static Cell   local scEntail          Args((List,Cell,Int,Int));
+static Cell   local entail            Args((List,Cell,Int,Int));
+static Cell   local inEntail          Args((List,Cell,Int,Int));
 #if TREX
 static Cell   local lacksNorm         Args((Type,Int,Cell));
 #endif
@@ -167,12 +173,37 @@ Cell ev; {
  *
  * ------------------------------------------------------------------------*/
 
-static Cell local scFind(e,pi1,o1,pi,o) /* Use superclass entailment to    */
+Int cutoff = 16;                        /* Used to limit depth of recursion*/
+
+static Void local cutoffExceeded(pi,o,pi1,o1,ps)
+Cell pi, pi1;                           /* Display error msg when cutoff   */
+Int  o,  o1;
+List ps; {
+    clearMarks();
+    ERRMSG(0)
+        "\n*** The type checker has reached the cutoff limit while trying to\n"
+    ETHEN ERRTEXT
+        "*** determine whether:\n***     "     ETHEN ERRPRED(copyPred(pi,o));
+    ps = (isNull(pi1)) ? copyPreds(ps) : singleton(copyPred(pi1,o1));
+    ERRTEXT
+        "\n*** can be deduced from:\n***     " ETHEN ERRCONTEXT(ps);
+    ERRTEXT
+        "\n*** This may indicate that the problem is undecidable.  However,\n"
+    ETHEN ERRTEXT
+        "*** you may still try to increase the cutoff limit using the -c\n"
+    ETHEN ERRTEXT
+        "*** option and then try again.  (The current setting is -c%d)\n",
+        cutoff
+    EEND;
+}
+
+static Cell local scFind(e,pi1,o1,pi,o,d)/* Use superclass entailment to   */
 Cell e;                                 /* find evidence for (pi,o) using  */
 Cell pi1;                               /* the evidence e for (pi1,o1).    */
 Int  o1;
 Cell pi;
-Int  o; {
+Int  o;
+Int  d; {
     Class h1 = getHead(pi1);
     Class h  = getHead(pi);
 
@@ -185,8 +216,12 @@ Int  o; {
         List dsels = cclass(h1).dsels;
         if (!matchPred(pi1,o1,cclass(h1).head,beta))
             internal("scFind");
+
+        if (d++ >= cutoff)
+            cutoffExceeded(pi,o,pi1,o1,NIL);
+
         for (; nonNull(scs); scs=tl(scs), dsels=tl(dsels)) {
-            Cell ev = scFind(ap(hd(dsels),e),hd(scs),beta,pi,o);
+            Cell ev = scFind(ap(hd(dsels),e),hd(scs),beta,pi,o,d);
             if (nonNull(ev))
                 return ev;
         }
@@ -195,13 +230,14 @@ Int  o; {
     return NIL;
 }
 
-static Cell local scEntail(ps,pi,o)     /* Calc evidence for (pi,o) from ps*/
+static Cell local scEntail(ps,pi,o,d)   /* Calc evidence for (pi,o) from ps*/
 List ps;                                /* Using superclasses and equality.*/
 Cell pi;
-Int  o; {
+Int  o;
+Int  d; {
     for (; nonNull(ps); ps=tl(ps)) {
         Cell pi1 = hd(ps);
-        Cell ev  = scFind(thd3(pi1),fst3(pi1),intOf(snd3(pi1)),pi,o);
+        Cell ev  = scFind(thd3(pi1),fst3(pi1),intOf(snd3(pi1)),pi,o,d);
         if (nonNull(ev))
             return ev;
     }
@@ -256,18 +292,20 @@ Int  o; {
  * to cause any further concern, except in pathological cases.)
  * ------------------------------------------------------------------------*/
 
-static Cell local entail(ps,pi,o)       /* Calc evidence for (pi,o) from ps*/
+static Cell local entail(ps,pi,o,d)     /* Calc evidence for (pi,o) from ps*/
 List ps;                                /* Uses superclasses, equality,    */
 Cell pi;                                /* tautology, and construction     */
-Int  o; {
-    Cell ev = scEntail(ps,pi,o);
-    return nonNull(ev) ? ev : inEntail(ps,pi,o);
+Int  o;
+Int  d; {
+    Cell ev = scEntail(ps,pi,o,d);
+    return nonNull(ev) ? ev : inEntail(ps,pi,o,d);
 }
 
-static Cell local inEntail(ps,pi,o)     /* Calc evidence for (pi,o) from ps*/
+static Cell local inEntail(ps,pi,o,d)   /* Calc evidence for (pi,o) from ps*/
 List ps;                                /* using a top-level instance      */
 Cell pi;                                /* entailment                      */
-Int  o; {
+Int  o;
+Int  d; {
 #if TREX
     if (isAp(pi) && isExt(fun(pi))) {   /* Lacks predicates                */
         Cell e  = fun(pi);
@@ -295,18 +333,21 @@ Int  o; {
     else {
 #endif
     Inst in = findInstFor(pi,o);        /* Class predicates                */
+
     if (nonNull(in)) {
         Int  beta = typeOff;
-        Cell d    = inst(in).builder;
-        Cell ds   = inst(in).specifics;
-        for (; nonNull(ds); ds=tl(ds)) {
-            Cell ev = entail(ps,hd(ds),beta);
+        Cell e    = inst(in).builder;
+        Cell es   = inst(in).specifics;
+        if (d++ >= cutoff)
+            cutoffExceeded(pi,o,NIL,0,ps);
+        for (; nonNull(es); es=tl(es)) {
+            Cell ev = entail(ps,hd(es),beta,d);
             if (nonNull(ev))
-                d = ap(d,ev);
+                e = ap(e,ev);
             else
                 return NIL;
         }
-        return d;
+        return e;
     }
     return NIL;
 #if TREX
@@ -323,7 +364,7 @@ Cell  pi; {                             /* is tautological, and we can use */
     emptySubstitution();
     beta = newKindedVars(ks);           /* (ks provides kinds for any      */
     ps   = makePredAss(ps,beta);        /*  vars that appear in pi.)       */
-    ev   = entail(ps,pi,beta);
+    ev   = entail(ps,pi,beta,0);
     emptySubstitution();
     return ev;
 }
@@ -371,7 +412,7 @@ List qs; {                              /* returning equiv minimal subset  */
 
     while (0<n--) {
         Cell pi = hd(qs);
-        Cell ev = scEntail(tl(qs),fst3(pi),intOf(snd3(pi)));
+        Cell ev = scEntail(tl(qs),fst3(pi),intOf(snd3(pi)),0);
         if (nonNull(ev)) {
             overEvid(thd3(pi),ev);      /* Overwrite dict var with evidence*/
             qs      = tl(qs);           /* ... and discard predicate       */
@@ -396,20 +437,24 @@ Int  o; {                               /* superclass hierarchy            */
  * ------------------------------------------------------------------------*/
 
 static Void local elimTauts() {         /* Remove tautological constraints */
-    List ps = preds;                    /* from preds                      */
-    preds   = NIL;
-    while (nonNull(ps)) {
-        Cell pi = hd(ps);
-        Cell ev = entail(NIL,fst3(pi),intOf(snd3(pi)));
-        if (nonNull(ev)) {
-            overEvid(thd3(pi),ev);
-            ps = tl(ps);
-        }
-        else {
-            List tmp = tl(ps);
-            tl(ps)   = preds;
-            preds    = ps;
-            ps       = tmp;
+    if (haskell98) {                    /* from preds                      */
+        reducePreds();                  /* (or context reduce for Hask98)  */
+    } else {
+        List ps = preds;
+        preds   = NIL;
+        while (nonNull(ps)) {
+            Cell pi = hd(ps);
+            Cell ev = entail(NIL,fst3(pi),intOf(snd3(pi)),0);
+            if (nonNull(ev)) {
+                overEvid(thd3(pi),ev);
+                ps = tl(ps);
+            }
+            else {
+                List tmp = tl(ps);
+                tl(ps)   = preds;
+                preds    = ps;
+                ps           = tmp;
+            }
         }
     }
 }
@@ -474,7 +519,7 @@ List sps; {                             /* context ps.  sps = savePreds.   */
         Cell p  = preds;
         Cell pi = fst3(hd(p));
         Int  o  = intOf(snd3(hd(p)));
-        Cell ev = entail(ps,pi,o);
+        Cell ev = entail(ps,pi,o,0);
         preds   = tl(preds);
 
         if (nonNull(ev))                /* Discharge if ps ||- (pi,o)      */
@@ -582,11 +627,11 @@ List vs; {                              /* for variables vs subject to  */
     Bool defaulted = FALSE;
 
 #ifdef DEBUG_DEFAULTS
-    printf("Attempt to resolve variables ");
+    Printf("Attempt to resolve variables ");
     printExp(stdout,vs);
-    printf(" with context ");
+    Printf(" with context ");
     printContext(stdout,copyPreds(preds));
-    printf("\n");
+    Printf("\n");
 #endif
 
     resetGenerics();                    /* find type variables in ps    */
@@ -601,16 +646,16 @@ List vs; {                              /* for variables vs subject to  */
         Int vn = intOf(hd(pvs));
 
 #ifdef DEBUG_DEFAULTS
-        printf("is var %d included in ",vn);
+        Printf("is var %d included in ",vn);
         printExp(stdout,vs);
-        printf("?\n");
+        Printf("?\n");
 #endif
 
         if (!intIsMember(vn,vs))
             defaulted |= resolveVar(vn);
 #ifdef DEBUG_DEFAULTS
         else
-            printf("Yes, so no ambiguity!\n");
+            Printf("Yes, so no ambiguity!\n");
 #endif
     }
 
@@ -635,7 +680,7 @@ Int  vn; {                              /* variable vn can be resolved  */
      */
 
 #ifdef DEBUG_DEFAULTS
-    printf("Trying to default variable %d\n",vn);
+    Printf("Trying to default variable %d\n",vn);
 #endif
 
     for (; nonNull(ps); ps=tl(ps)) {
@@ -649,7 +694,7 @@ Int  vn; {                              /* variable vn can be resolved  */
             else if (c!=classEq    && c!=classOrd  && c!=classShow &&
                      c!=classRead  && c!=classIx   && c!=classEnum &&
 #if EVAL_INSTANCES
-                     c!=classEval &&
+                     c!=classEval  &&
 #endif
                      c!=classBounded)
                 return FALSE;
@@ -676,18 +721,18 @@ Int  vn; {                              /* variable vn can be resolved  */
     if (aNumClass) {
         List ds = defaultDefns;         /* N.B. guaranteed to be monotypes */
 #ifdef DEBUG_DEFAULTS
-        printf("Default conditions met, looking for type\n");
+        Printf("Default conditions met, looking for type\n");
 #endif
         for (; nonNull(ds); ds=tl(ds)) {
             List cs1 = cs;
-            while (nonNull(cs1) && nonNull(entail(NIL,ap(hd(cs1),hd(ds)),0)))
+            while (nonNull(cs1) && nonNull(entail(NIL,ap(hd(cs1),hd(ds)),0,0)))
                 cs1 = tl(cs1);
             if (isNull(cs1)) {
                 bindTv(vn,hd(ds),0);
 #ifdef DEBUG_DEFAULTS
-                printf("Default type for variable %d is ",vn);
+                Printf("Default type for variable %d is ",vn);
                 printType(stdout,hd(ds));
-                printf("\n");
+                Printf("\n");
 #endif
                 return TRUE;
             }
@@ -695,7 +740,7 @@ Int  vn; {                              /* variable vn can be resolved  */
     }
 
 #ifdef DEBUG_DEFAULTS
-    printf("No default permitted/found\n");
+    Printf("No default permitted/found\n");
 #endif
     return FALSE;
 }
index 6abd9aa..8886a3a 100644 (file)
@@ -1,4 +1,4 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Basic data type definitions, prototypes and standard macros including
  * machine dependent variations...
@@ -8,8 +8,8 @@
  * Hugs version 1.4, December 1997
  *
  * $RCSfile: prelude.h,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:33 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:36 $
  * ------------------------------------------------------------------------*/
 
 #include "config.h"
@@ -228,14 +228,20 @@ extern  int     stricmp    Args((const char *, const char*));
 typedef unsigned Bool;
 #define TRUE     1
 #define FALSE    0
-typedef char    *String;
-typedef int      Int;
-typedef long     Long;
-typedef int      Char;
-typedef unsigned int Word; /* at least 32 bits */
-typedef void*    Ptr;
-typedef void*    Addr;
-typedef Word*    HpPtr;
+
+typedef char           *String;
+typedef int             Int;
+typedef long            Long;
+typedef int             Char;
+typedef unsigned int    Unsigned; /* at least 32 bits */
+typedef void*           Ptr;
+typedef void*           Addr;
+typedef void*           HpPtr;
+
+#define FloatImpType       double
+#define FloatPro           double
+#define FloatFMT           "%.9g"
+
 
 /* ToDo: this should probably go in dynamic.h - but then
  * storage.h has to include dynamic.h!
index c4a3491..809d54a 100644 (file)
@@ -1,27 +1,28 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Strongly connected components algorithm for static.c.
  *
- * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
- * All rights reserved. See NOTICE for details and conditions of use etc...
- * Hugs version 1.4, December 1997
+ * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
+ * Haskell Group 1994-99, and is distributed as Open Source software
+ * under the Artistic License; see the file "Artistic" that is included
+ * in the distribution for details.
  *
  * $RCSfile: scc.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:34 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:36 $
  * ------------------------------------------------------------------------*/
 
 #ifndef SCC_C
 #define SCC_C
-#define visited(d) (isInt(DEPENDS(d)))  /* binding already visited ?       */
+#define visited(d) (isInt(DEPENDS(d)))          /* binding already visited?*/
 
 static Cell daSccs = NIL;
 static Int  daCount;
 
 static Int local sccMin Args((Int,Int));
 
-static Int local sccMin(x,y)           /* calculate minimum of x,y (unless */
-Int x,y; {                             /* y is zero)                       */
+static Int local sccMin(x,y)            /* calculate minimum of x,y        */
+Int x, y; {                             /* (unless y is zero)              */
     return (x<=y || y==0) ? x : y;
 }
 #endif
index 601ef0a..2cf01cd 100644 (file)
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Static Analysis for Hugs
  *
- * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
- * All rights reserved. See NOTICE for details and conditions of use etc...
- * Hugs version 1.4, December 1997
+ * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
+ * Haskell Group 1994-99, and is distributed as Open Source software
+ * under the Artistic License; see the file "Artistic" that is included
+ * in the distribution for details.
  *
  * $RCSfile: static.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:35 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:37 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
 #include "storage.h"
+#include "backend.h"
 #include "connect.h"
-#include "input.h"
-#include "type.h"
-#include "static.h"
-#include "translate.h"
-#include "hugs.h"  /* for target */
 #include "errors.h"
 #include "subst.h"
-#include "link.h"
-#include "modules.h"
-#include "derive.h"
 
 /* --------------------------------------------------------------------------
  * local function prototypes:
  * ------------------------------------------------------------------------*/
 
-static Module thisModule = 0;           /* module currently being processed*/
-
-static Void  local kindError         Args((Int,Constr,Constr,String,Kind,Int));
+static Void   local kindError           Args((Int,Constr,Constr,String,Kind,Int));
+#if !IGNORE_MODULES
+static Void   local checkQualImport     Args((Pair));
+static Void   local checkUnqualImport   Args((Triple));
+
+static Name   local lookupName          Args((Text,List));
+static List   local checkSubentities    Args((List,List,List,String,Text));
+static List   local checkExportTycon    Args((List,Text,Cell,Tycon));
+static List   local checkExportClass    Args((List,Text,Cell,Class));
+static List   local checkExport         Args((List,Text,Cell));
+static List   local checkImportEntity   Args((List,Module,Cell));
+static List   local resolveImportList   Args((Module,Cell));
+static Void   local checkImportList     Args((Pair));
+
+static Void   local importEntity        Args((Module,Cell));
+static Void   local importName          Args((Module,Name));
+static Void   local importTycon         Args((Module,Tycon));
+static Void   local importClass         Args((Module,Class));
+static List   local checkExports        Args((List));
+#endif
 
-static Void  local checkTyconDefn    Args((Tycon));
-static Void  local depConstrs        Args((Tycon,List,Cell));
-static List  local addSels           Args((Int,Name,List,List));
-static List  local selectCtxt        Args((List,List));
-static Void  local checkSynonyms     Args((List));
-static List  local visitSyn          Args((List,Tycon,List));
+static Void   local checkTyconDefn      Args((Tycon));
+static Void   local depConstrs          Args((Tycon,List,Cell));
+static List   local addSels             Args((Int,Name,List,List));
+static List   local selectCtxt          Args((List,List));
+static Void   local checkSynonyms       Args((List));
+static List   local visitSyn            Args((List,Tycon,List));
 #if EVAL_INSTANCES
-static Void  local deriveEval        Args((List));
-static List  local calcEvalContexts  Args((Tycon,List,List));
+static Void   local deriveEval          Args((List));
+static List   local calcEvalContexts    Args((Tycon,List,List));
+static Void   local checkBanged         Args((Name,Kinds,List,Type));
 #endif
-static Void  local checkBanged       Args((Name,Kinds,List,Type));
-static Type  local instantiateSyn    Args((Type,Type));
-
-static Void  local checkClassDefn    Args((Class));
-static Void  local depPredExp        Args((Int,List,Cell));
-static Void  local checkMems         Args((Class,List,Cell));
-static Void  local addMembers        Args((Class));
-static Name  local newMember         Args((Int,Int,Cell,Type));
-static Name  local newDSel           Args((Class,Int));
-static Name  local newDBuild         Args((Class));
-static Text  local generateText      Args((String, Class));
-static Int   local visitClass        Args((Class));
-
-static List  local classBindings     Args((String,Class,List));
-static Name  local memberName        Args((Class,Text));
-static List  local numInsert         Args((Int,Cell,List));
-
-static List  local typeVarsIn        Args((Cell,List,List));
-static List  local maybeAppendVar    Args((Cell,List));
-
-static Type  local checkSigType      Args((Int,String,Cell,Type));
-static Type  local depTopType        Args((Int,List,Type));
-static Type  local depCompType       Args((Int,List,Type));
-static Type  local depTypeExp        Args((Int,List,Type));
-static Type  local depTypeVar        Args((Int,List,Text));
-static Void  local kindConstr        Args((Int,Int,Int,Constr));
-static Kind  local kindAtom          Args((Int,Constr));
-static Void  local kindPred          Args((Int,Int,Int,Cell));
-static Void  local kindType          Args((Int,String,Type));
-static Void  local fixKinds          Args((Void));
-
-static Void  local kindTCGroup       Args((List));
-static Void  local initTCKind        Args((Cell));
-static Void  local kindTC            Args((Cell));
-static Void  local genTC             Args((Cell));
-
-static Void  local checkInstDefn     Args((Inst));
-static Void  local insertInst        Args((Inst));
-static Bool  local instCompare       Args((Inst,Inst));
-static Name  local newInstImp        Args((Inst));
-static Void  local kindInst          Args((Inst,Int));
-static Void  local checkDerive       Args((Tycon,List,List,Cell));
-static Void  local addDerInst        Args((Int,Class,List,List,Type,Int));
-
-static Void  local deriveContexts    Args((List));
-static Void  local initDerInst       Args((Inst));
-static Void  local calcInstPreds     Args((Inst));
-static Void  local maybeAddPred      Args((Cell,Int,Int,List));
-static Cell  local copyAdj           Args((Cell,Int,Int));
-static Void  local tidyDerInst       Args((Inst));
-
-static Void  local addDerivImp       Args((Inst));
-
-static Void  local checkDefaultDefns Args((Void));
-
-static Void  local checkForeignImport Args((Name));
-static Void  local checkForeignExport Args((Name));
-
-static Cell  local checkPat          Args((Int,Cell));
-static Cell  local checkMaybeCnkPat  Args((Int,Cell));
-static Cell  local checkApPat        Args((Int,Int,Cell));
-static Void  local addPatVar         Args((Int,Cell));
-static Name  local conDefined        Args((Int,Cell));
-static Void  local checkIsCfun       Args((Int,Name));
-static Void  local checkCfunArgs     Args((Int,Cell,Int));
-static Cell  local applyBtyvs        Args((Cell));
-static Cell  local bindPat           Args((Int,Cell));
-static Void  local bindPats          Args((Int,List));
-
-static List  local extractSigdecls   Args((List));
-static List  local extractBindings   Args((List));
-static List  local eqnsToBindings    Args((List));
-static Void  local notDefined        Args((Int,List,Cell));
-static Cell  local findBinding       Args((Text,List));
-static Void  local addSigDecl        Args((List,Cell));
-static Void  local setType           Args((Int,Cell,Cell,List));
-
-static List  local dependencyAnal    Args((List));
-static List  local topDependAnal     Args((List));
-static Void  local addDepField       Args((Cell));
-static Void  local remDepField       Args((List));
-static Void  local remDepField1      Args((Cell));
-static Void  local clearScope        Args((Void));
-static Void  local withinScope       Args((List));
-static Void  local leaveScope        Args((Void));
-
-static Void  local depBinding        Args((Cell));
-static Void  local depDefaults       Args((Class));
-static Void  local depInsts          Args((Inst));
-static Void  local depClassBindings  Args((List));
-static Void  local depAlt            Args((Cell));
-static Void  local depRhs            Args((Cell));
-static Void  local depGuard          Args((Cell));
-static Cell  local depExpr           Args((Int,Cell));
-static Void  local depPair           Args((Int,Cell));
-static Void  local depTriple         Args((Int,Cell));
-static Void  local depComp           Args((Int,Cell,List));
-static Void  local depCaseAlt        Args((Int,Cell));
-static Cell  local depVar            Args((Int,Cell));
-static Cell  local depQVar           Args((Int,Cell));
-static Void  local depConFlds        Args((Int,Cell,Bool));
-static Void  local depUpdFlds        Args((Int,Cell));
-static List  local depFields         Args((Int,Cell,List,Bool));
+static Type   local instantiateSyn      Args((Type,Type));
+
+static Void   local checkClassDefn      Args((Class));
+static Void   local depPredExp          Args((Int,List,Cell));
+static Void   local checkMems           Args((Class,List,Cell));
+static Void   local addMembers          Args((Class));
+static Name   local newMember           Args((Int,Int,Cell,Type,Class));
+static Name   local newDSel             Args((Class,Int));
+static Name   local newDBuild           Args((Class));
+static Text   local generateText        Args((String,Class));
+static Int    local visitClass          Args((Class));
+
+static List   local classBindings       Args((String,Class,List));
+static Name   local memberName          Args((Class,Text));
+static List   local numInsert           Args((Int,Cell,List));
+
+static List   local typeVarsIn          Args((Cell,List,List));
+static List   local maybeAppendVar      Args((Cell,List));
+
+static Type   local checkSigType        Args((Int,String,Cell,Type));
+static Type   local depTopType          Args((Int,List,Type));
+static Type   local depCompType         Args((Int,List,Type));
+static Type   local depTypeExp          Args((Int,List,Type));
+static Type   local depTypeVar          Args((Int,List,Text));
+static List   local checkQuantVars      Args((Int,List,List,Cell));
+static List   local offsetTyvarsIn      Args((Type,List));
+static Void   local kindConstr          Args((Int,Int,Int,Constr));
+static Kind   local kindAtom            Args((Int,Constr));
+static Void   local kindPred            Args((Int,Int,Int,Cell));
+static Void   local kindType            Args((Int,String,Type));
+static Void   local fixKinds            Args((Void));
+
+static Void   local kindTCGroup         Args((List));
+static Void   local initTCKind          Args((Cell));
+static Void   local kindTC              Args((Cell));
+static Void   local genTC               Args((Cell));
+
+static Void   local checkInstDefn       Args((Inst));
+static Void   local insertInst          Args((Inst));
+static Bool   local instCompare         Args((Inst,Inst));
+static Name   local newInstImp          Args((Inst));
+static Void   local kindInst            Args((Inst,Int));
+static Void   local checkDerive         Args((Tycon,List,List,Cell));
+static Void   local addDerInst          Args((Int,Class,List,List,Type,Int));
+static Void   local deriveContexts      Args((List));
+static Void   local initDerInst         Args((Inst));
+static Void   local calcInstPreds       Args((Inst));
+static Void   local maybeAddPred        Args((Cell,Int,Int,List));
+static Cell   local copyAdj             Args((Cell,Int,Int));
+static Void   local tidyDerInst         Args((Inst));
+
+static Void   local addDerivImp         Args((Inst));
+static List   local getDiVars           Args((Int));
+static Cell   local mkBind              Args((String,List));
+static Cell   local mkVarAlts           Args((Int,Cell));
+
+static List   local makeDPats2          Args((Cell,Int));
+
+static Bool   local isEnumType          Args((Tycon));
+
+static Void   local checkDefaultDefns   Args((Void));
+
+static Void   local checkForeignImport Args((Name));
+static Void   local checkForeignExport Args((Name));
+
+static Name   local addNewPrim          Args((Int,Text,String,Cell));
+
+static Cell   local tidyInfix           Args((Int,Cell));
+static Pair   local attachFixity        Args((Int,Cell));
+static Syntax local lookupSyntax        Args((Text));
+
+static Cell   local checkPat            Args((Int,Cell));
+static Cell   local checkMaybeCnkPat    Args((Int,Cell));
+static Cell   local checkApPat          Args((Int,Int,Cell));
+static Void   local addToPatVars        Args((Int,Cell));
+static Name   local conDefined          Args((Int,Cell));
+static Void   local checkIsCfun         Args((Int,Name));
+static Void   local checkCfunArgs       Args((Int,Cell,Int));
+static Cell   local checkPatType        Args((Int,String,Cell,Type));
+static Cell   local applyBtyvs          Args((Cell));
+static Cell   local bindPat             Args((Int,Cell));
+static Void   local bindPats            Args((Int,List));
+
+static List   local extractSigdecls     Args((List));
+static List   local extractFixdecls     Args((List));
+static List   local extractBindings     Args((List));
+static List   local getPatVars          Args((Int,Cell,List));
+static List   local addPatVar           Args((Int,Cell,List));
+static List   local eqnsToBindings      Args((List,List,List,List));
+static Void   local notDefined          Args((Int,List,Cell));
+static Cell   local findBinding         Args((Text,List));
+static Cell   local getAttr             Args((List,Cell));
+static Void   local addSigdecl          Args((List,Cell));
+static Void   local addFixdecl          Args((List,List,List,List,Triple));
+static Void   local dupFixity           Args((Int,Text));
+static Void   local missFixity          Args((Int,Text));
+
+static List   local dependencyAnal      Args((List));
+static List   local topDependAnal       Args((List));
+static Void   local addDepField         Args((Cell));
+static Void   local remDepField         Args((List));
+static Void   local remDepField1        Args((Cell));
+static Void   local clearScope          Args((Void));
+static Void   local withinScope         Args((List));
+static Void   local leaveScope          Args((Void));
+static Void   local saveSyntax          Args((Cell,Cell));
+
+static Void   local depBinding          Args((Cell));
+static Void   local depDefaults         Args((Class));
+static Void   local depInsts            Args((Inst));
+static Void   local depClassBindings    Args((List));
+static Void   local depAlt              Args((Cell));
+static Void   local depRhs              Args((Cell));
+static Void   local depGuard            Args((Cell));
+static Cell   local depExpr             Args((Int,Cell));
+static Void   local depPair             Args((Int,Cell));
+static Void   local depTriple           Args((Int,Cell));
+static Void   local depComp             Args((Int,Cell,List));
+static Void   local depCaseAlt          Args((Int,Cell));
+static Cell   local depVar              Args((Int,Cell));
+static Cell   local depQVar             Args((Int,Cell));
+static Void   local depConFlds          Args((Int,Cell,Bool));
+static Void   local depUpdFlds          Args((Int,Cell));
+static List   local depFields           Args((Int,Cell,List,Bool));
 #if TREX
-static Cell  local depRecord         Args((Int,Cell));
+static Cell   local depRecord           Args((Int,Cell));
 #endif
 
-static List  local tcscc             Args((List,List));
-static List  local bscc              Args((List));
+static List   local tcscc               Args((List,List));
+static List   local bscc                Args((List));
 
-static Void  local addRSsigdecls     Args((Pair));
-static Void  local opDefined         Args((List,Cell));
-static Void  local allNoPrevDef      Args((Cell));
-static Void  local noPrevDef         Args((Int,Cell));
-static Void  local duplicateError       Args((Int,Module,Text,String));
-static Void  local checkTypeIn       Args((Pair));
+static Void   local addRSsigdecls       Args((Pair));
+static Void   local allNoPrevDef        Args((Cell));
+static Void   local noPrevDef           Args((Int,Cell));
+#if IGNORE_MODULES
+static Void   local duplicateErrorAux   Args((Int,Text,String));
+#define duplicateError(l,m,t,k) duplicateErrorAux(l,t,k)
+#else
+static Void   local duplicateErrorAux   Args((Int,Module,Text,String));
+#define duplicateError(l,m,t,k) duplicateErrorAux(l,m,t,k)
+#endif
+static Void   local checkTypeIn         Args((Pair));
 
 /* --------------------------------------------------------------------------
  * The code in this file is arranged in roughly the following order:
  *  - Kind inference preliminaries
+ *  - Module declarations
  *  - Type declarations (data, type, newtype, type in)
  *  - Class declarations
  *  - Type signatures
  *  - Instance declarations
  *  - Default declarations
+ *  - Primitive definitions
  *  - Patterns
+ *  - Infix expressions
  *  - Value definitions
  *  - Top-level static analysis and control
+ *  - Haskell 98 compatibility tests
  * ------------------------------------------------------------------------*/
 
 /* --------------------------------------------------------------------------
@@ -225,6 +267,443 @@ Kind   extKind;                         /* Kind of extension, *->row->row  */
 #endif
 
 /* --------------------------------------------------------------------------
+ * Static analysis of modules:
+ * ------------------------------------------------------------------------*/
+
+#if HSCRIPT
+String reloadModule;
+#endif
+
+#if !IGNORE_MODULES
+Void startModule(nm)                             /* switch to a new module */
+Cell nm; {
+    Module m;
+    if (!isCon(nm)) internal("startModule");
+    if (isNull(m = findModule(textOf(nm))))
+        m = newModule(textOf(nm));
+    else if (!isPreludeScript()) {
+        /* You're allowed to break the rules in the Prelude! */
+#if HSCRIPT
+        reloadModule = textToStr(textOf(nm));
+#endif
+        ERRMSG(0) "Module \"%s\" already loaded", textToStr(textOf(nm))
+        EEND;
+    }
+    setCurrModule(m);
+}
+
+Void setExportList(exps)              /* Add export list to current module */
+List exps; {
+    module(currentModule).exports = exps;
+}
+
+Void addQualImport(orig,new)         /* Add to qualified import list       */
+Cell orig;     /* Original name of module                                  */
+Cell new;  {   /* Name module is called within this module (or NIL)        */
+    module(currentModule).qualImports = 
+      cons(pair(isNull(new)?orig:new,orig),module(currentModule).qualImports);
+}
+
+Void addUnqualImport(mod,entities)     /* Add to unqualified import list   */
+Cell mod;         /* Name of module                                        */
+List entities;  { /* List of entity names                                  */
+    unqualImports = cons(pair(mod,entities),unqualImports);
+}
+
+static Void local checkQualImport(i)   /* Process qualified import         */
+Pair i; {
+    Module m = findModid(snd(i));
+    if (isNull(m)) {
+        ERRMSG(0) "Module \"%s\" not previously loaded", 
+                  textToStr(textOf(snd(i)))
+        EEND;
+    }
+    snd(i)=m;
+}
+
+static Void local checkUnqualImport(i) /* Process unqualified import       */
+Pair i; {
+    Module m = findModid(fst(i));
+    if (isNull(m)) {
+        ERRMSG(0) "Module \"%s\" not previously loaded", 
+                  textToStr(textOf(fst(i)))
+        EEND;
+    }
+    fst(i)=m;
+}
+
+static Name local lookupName(t,nms)    /* find text t in list of Names     */
+Text t;
+List nms; { /* :: [Name] */
+    for(; nonNull(nms); nms=tl(nms)) {
+        if (t == name(hd(nms)).text)
+            return hd(nms);
+    }
+    return NIL;
+}
+
+static List local checkSubentities(imports,named,wanted,description,textParent)
+List   imports;
+List   named;       /* :: [ Q?(Var|Con)(Id|Op) ]                  */
+List   wanted;      /* :: [Name]                                  */
+String description; /* "<constructor>|<member> of <type>|<class>" */
+Text   textParent; {
+    for(; nonNull(named); named=tl(named)) {
+        Pair x = hd(named);
+        /* ToDo: ignores qualifier; doesn't check that entity is in scope */
+        Text t = isPair(snd(x)) ? qtextOf(x) : textOf(x);
+        Name n = lookupName(t,wanted);
+        if (isNull(n)) {
+            ERRMSG(0) "Entity \"%s\" is not a %s \"%s\"",
+                      textToStr(t),
+                      description,
+                      textToStr(textParent)
+            EEND;
+        }
+        imports = cons(n,imports);
+    }
+    return imports;
+}
+
+static List local checkImportEntity(imports,exporter,entity)
+List   imports; /* Accumulated list of things to import */
+Module exporter;
+Cell   entity; { /* Entry from import list */
+    List oldImports = imports;
+    Text t  = isIdent(entity) ? textOf(entity) : textOf(fst(entity));
+    List es = module(exporter).exports; 
+    for(; nonNull(es); es=tl(es)) {
+        Cell e = hd(es); /* :: Entity | (Entity, NIL|DOTDOT) */
+        if (isPair(e)) {
+            Cell f = fst(e);
+            if (isTycon(f)) {
+                if (tycon(f).text == t) {
+                    imports = cons(f,imports);
+                    if (!isIdent(entity)) {
+                        switch (tycon(f).what) {
+                        case NEWTYPE:
+                        case DATATYPE:
+                            if (DOTDOT == snd(entity)) {
+                                imports=dupOnto(tycon(f).defn,imports);
+                            } else {
+                                imports=checkSubentities(imports,snd(entity),tycon(f).defn,"constructor of type",t);
+                            }
+                            break;
+                        default:;
+                          /* deliberate fall thru */
+                        }
+                    }
+                }
+            } else if (isClass(f)) {
+                if (cclass(f).text == t) {
+                    imports = cons(f,imports);
+                    if (!isIdent(entity)) {
+                        if (DOTDOT == snd(entity)) {
+                            return dupOnto(cclass(f).members,imports);
+                        } else {
+                            return checkSubentities(imports,snd(entity),cclass(f).members,"member of class",t);
+                        }
+                    }
+                }
+            } else {
+                internal("checkImportEntity2");
+            }
+        } else if (isName(e)) {
+            if (isIdent(entity) && name(e).text == t) {
+                imports = cons(e,imports);
+            }
+        } else {
+            internal("checkImportEntity3");
+        }
+    }
+    if (imports == oldImports) {
+        ERRMSG(0) "Unknown entity \"%s\" imported from module \"%s\"",
+                  textToStr(t),
+                  textToStr(module(exporter ).text)
+        EEND;
+    }
+    return imports;
+}
+
+static List local resolveImportList(m,impList)
+Module m;  /* exporting module */
+Cell   impList; {
+    List imports = NIL;
+    if (DOTDOT == impList) {
+        List es = module(m).exports;
+        for(; nonNull(es); es=tl(es)) {
+            Cell e = hd(es);
+            if (isName(e))
+                imports = cons(e,imports);
+            else {
+                Cell c = fst(e);
+                List subentities = NIL;
+                imports = cons(c,imports);
+                if (isTycon(c)
+                    && (tycon(c).what == DATATYPE 
+                        || tycon(c).what == NEWTYPE))
+                    subentities = tycon(c).defn;
+                else if (isClass(c))
+                    subentities = cclass(c).members;
+                if (DOTDOT == snd(e)) {
+                    imports = dupOnto(subentities,imports);
+                }
+            }
+        }
+    } else {
+        map1Accum(checkImportEntity,imports,m,impList);
+    }
+    return imports;
+}
+
+static Void local checkImportList(importSpec) /*Import a module unqualified*/
+Pair importSpec; {
+    Module m       = fst(importSpec);
+    Cell   impList = snd(importSpec);
+
+    List   imports = NIL; /* entities we want to import */
+    List   hidden  = NIL; /* entities we want to hide   */
+
+    if (moduleThisScript(m)) { 
+        ERRMSG(0) "Module \"%s\" recursively imports itself",
+                  textToStr(module(m).text)
+        EEND;
+    }
+    if (isPair(impList) && HIDDEN == fst(impList)) {
+        /* Somewhat inefficient - but obviously correct:
+         * imports = importsOf("module Foo") `setDifference` hidden;
+         */
+        hidden  = resolveImportList(m, snd(impList));
+        imports = resolveImportList(m, DOTDOT);
+    } else {
+        imports = resolveImportList(m, impList);
+    }
+    for(; nonNull(imports); imports=tl(imports)) {
+        Cell e = hd(imports);
+        if (!cellIsMember(e,hidden))
+            importEntity(m,e);
+    }
+    /* ToDo: hang onto the imports list for processing export list entries
+     * of the form "module Foo"
+     */
+}
+
+static Void local importEntity(source,e)
+Module source;
+Cell e; {
+    switch (whatIs(e)) {
+      case NAME  : importName(source,e); 
+                   break;
+      case TYCON : importTycon(source,e); 
+                   break;
+      case CLASS : importClass(source,e);
+                   break;
+      default: internal("importEntity");
+    }
+}
+
+static Void local importName(source,n)
+Module source;
+Name n; {
+    Name clash = addName(n);
+    if (nonNull(clash) && clash!=n) {
+        ERRMSG(0) "Entity \"%s\" imported from module \"%s\" already defined in module \"%s\"",
+                  textToStr(name(n).text), 
+                  textToStr(module(source).text),
+                  textToStr(module(name(clash).mod).text)
+        EEND;
+    }
+}
+
+static Void local importTycon(source,tc)
+Module source;
+Tycon tc; {
+    Tycon clash=addTycon(tc);
+    if (nonNull(clash) && clash!=tc) {
+        ERRMSG(0) "Tycon \"%s\" imported from \"%s\" already defined in module \"%s\"",
+                  textToStr(tycon(tc).text),
+                  textToStr(module(source).text),
+                  textToStr(module(tycon(clash).mod).text)      
+        EEND;
+    }
+    if (nonNull(findClass(tycon(tc).text))) {
+        ERRMSG(0) "Import of type constructor \"%s\" clashes with class in module \"%s\"",
+                  textToStr(tycon(tc).text),
+                  textToStr(module(tycon(tc).mod).text) 
+        EEND;
+    }
+}
+
+static Void local importClass(source,c)
+Module source;
+Class c; {
+    Class clash=addClass(c);
+    if (nonNull(clash) && clash!=c) {
+        ERRMSG(0) "Class \"%s\" imported from \"%s\" already defined in module \"%s\"",
+                  textToStr(cclass(c).text),
+                  textToStr(module(source).text),
+                  textToStr(module(cclass(clash).mod).text)     
+        EEND;
+    }
+    if (nonNull(findTycon(cclass(c).text))) {
+        ERRMSG(0) "Import of class \"%s\" clashes with type constructor in module \"%s\"",
+                  textToStr(cclass(c).text),
+                  textToStr(module(source).text)        
+        EEND;
+    }
+}
+
+static List local checkExportTycon(exports,mt,spec,tc)
+List  exports;
+Text  mt;
+Cell  spec; 
+Tycon tc; {
+    if (DOTDOT == spec || SYNONYM == tycon(tc).what) {
+        return cons(pair(tc,DOTDOT), exports);
+    } else {
+        return cons(pair(tc,NIL), exports);
+    }
+}
+
+static List local checkExportClass(exports,mt,spec,cl)
+List  exports;
+Text  mt;
+Class cl;
+Cell  spec; {
+    if (DOTDOT == spec) {
+        return cons(pair(cl,DOTDOT), exports);
+    } else {
+        return cons(pair(cl,NIL), exports);
+    }
+}
+
+static List local checkExport(exports,mt,e) /* Process entry in export list*/
+List exports;
+Text mt; 
+Cell e; {
+    if (isIdent(e)) {
+        Cell export = NIL;
+        List origExports = exports;
+        if (nonNull(export=findQualName(e))) {
+            exports=cons(export,exports);
+        } 
+        if (isQCon(e) && nonNull(export=findQualTycon(e))) {
+            exports = checkExportTycon(exports,mt,NIL,export);
+        } 
+        if (isQCon(e) && nonNull(export=findQualClass(e))) {
+            /* opaque class export */
+            exports = checkExportClass(exports,mt,NIL,export);
+        }
+        if (exports == origExports) {
+            ERRMSG(0) "Unknown entity \"%s\" exported from module \"%s\"",
+                      identToStr(e),
+                      textToStr(mt)
+            EEND;
+        }
+        return exports;
+    } else if (MODULEENT == fst(e)) {
+        Module m = findModid(snd(e));
+        /* ToDo: shouldn't allow export of module we didn't import */
+        if (isNull(m)) {
+            ERRMSG(0) "Unknown module \"%s\" exported from module \"%s\"",
+                      textToStr(textOf(snd(e))),
+                      textToStr(mt)
+            EEND;
+        }
+        if (m == currentModule) {
+            /* Exporting the current module exports local definitions */
+            List xs;
+            for(xs=module(m).classes; nonNull(xs); xs=tl(xs)) {
+                if (cclass(hd(xs)).mod==m) 
+                    exports = checkExportClass(exports,mt,DOTDOT,hd(xs));
+            }
+            for(xs=module(m).tycons; nonNull(xs); xs=tl(xs)) {
+                if (tycon(hd(xs)).mod==m) 
+                    exports = checkExportTycon(exports,mt,DOTDOT,hd(xs));
+            }
+            for(xs=module(m).names; nonNull(xs); xs=tl(xs)) {
+                if (name(hd(xs)).mod==m) 
+                    exports = cons(hd(xs),exports);
+            }
+        } else {
+            /* Exporting other modules imports all things imported 
+             * unqualified from it.  
+             * ToDo: we reexport everything exported by a module -
+             * whether we imported it or not.  This gives the wrong
+             * result for "module M(module N) where import N(x)"
+             */
+            exports = dupOnto(module(m).exports,exports);
+        }
+        return exports;
+    } else {
+        Cell ident = fst(e); /* class name or type name */
+        Cell parts = snd(e); /* members or constructors */
+        Cell nm;
+        if (isQCon(ident) && nonNull(nm=findQualTycon(ident))) {
+            switch (tycon(nm).what) {
+            case SYNONYM:
+                if (DOTDOT!=parts) {
+                    ERRMSG(0) "Explicit constructor list given for type synonym \"%s\" in export list of module \"%s\"",
+                              identToStr(ident),
+                              textToStr(mt)
+                    EEND;
+                }
+                return cons(pair(nm,DOTDOT),exports);
+            case RESTRICTSYN:   
+                ERRMSG(0) "Transparent export of restricted type synonym \"%s\" in export list of module \"%s\"",
+                          identToStr(ident),
+                          textToStr(mt)
+                EEND;
+                return exports; /* Not reached */
+            case NEWTYPE:
+            case DATATYPE:
+                if (DOTDOT==parts) {
+                    return cons(pair(nm,DOTDOT),exports);
+                } else {
+                    exports = checkSubentities(exports,parts,tycon(nm).defn,
+                                               "constructor of type",
+                                               tycon(nm).text);
+                    return cons(pair(nm,DOTDOT), exports);
+                }
+            default:
+                internal("checkExport1");
+            }
+        } else if (isQCon(ident) && nonNull(nm=findQualClass(ident))) {
+            if (DOTDOT == parts) {
+                return cons(pair(nm,DOTDOT),exports);
+            } else {
+                exports = checkSubentities(exports,parts,cclass(nm).members,
+                                           "member of class",cclass(nm).text);
+                return cons(pair(nm,DOTDOT), exports);
+            }
+        } else {
+            ERRMSG(0) "Explicit export list given for non-class/datatype \"%s\" in export list of module \"%s\"",
+                      identToStr(ident),
+                      textToStr(mt)
+            EEND;
+        }
+    }
+    assert(0); return 0; /* NOTREACHED */
+}
+
+static List local checkExports(exports)
+List exports; {
+    Module m  = lastModule();
+    Text   mt = module(m).text;
+    List   es = NIL;
+
+    map1Accum(checkExport,es,mt,exports);
+
+#if DEBUG_MODULES
+    for(xs=es; nonNull(xs); xs=tl(xs)) {
+        Printf(" %s", textToStr(textOfEntity(hd(xs))));
+    }
+#endif
+    return es;
+}
+#endif
+
+/* --------------------------------------------------------------------------
  * Static analysis of type declarations:
  *
  * Type declarations come in two forms:
@@ -265,6 +744,7 @@ Cell what; {                            /* SYNONYM/DATATYPE/etc...         */
         tycon(nw).arity = argCount;
         tycon(nw).what  = what;
         if (what==RESTRICTSYN) {
+            h98DoesntSupport(line,"restricted type synonyms");
             typeInDefns = cons(pair(nw,snd(rhs)),typeInDefns);
             rhs         = fst(rhs);
         }
@@ -370,7 +850,6 @@ Cell  cd; {                             /* definitions (w or w/o deriving) */
     List derivs    = snd(cd);
     List compTypes = NIL;
     List sels      = NIL;
-    Int  ntvs      = length(tyvars);
     Int  i;
 
     for (i=0; i<tycon(t).arity; ++i)    /* build representation for tycon  */
@@ -380,6 +859,7 @@ Cell  cd; {                             /* definitions (w or w/o deriving) */
         ctxt = fst(snd(cs));
         cs   = snd(snd(cs));
         map2Proc(depPredExp,line,tyvars,ctxt);
+        h98CheckCtxt(line,"context",TRUE,ctxt,NIL);
     }
 
     if (nonNull(cs) && isNull(tl(cs)))  /* Single constructor datatype?    */
@@ -387,8 +867,9 @@ Cell  cd; {                             /* definitions (w or w/o deriving) */
 
     for (; nonNull(cs); cs=tl(cs)) {    /* For each constructor function:  */
         Cell con   = hd(cs);
-        List sig   = typeVarsIn(con,NIL,dupList(tyvars));
-        Int  etvs  = length(sig);
+        List sig   = dupList(tyvars);
+        List evs   = NIL;               /* locally quantified vars         */
+        List lps   = NIL;               /* locally bound predicates        */
         List ctxt1 = ctxt;              /* constructor function context    */
         List scs   = NIL;               /* strict components               */
         List fs    = NONE;              /* selector names                  */
@@ -397,6 +878,27 @@ Cell  cd; {                             /* definitions (w or w/o deriving) */
         Int  nr2   = 0;                 /* Number of rank 2 args           */
         Name n;                         /* name for constructor function   */
 
+        if (whatIs(con)==POLYTYPE) {    /* Locally quantified vars         */
+            evs = fst(snd(con));
+            con = snd(snd(con));
+            sig = checkQuantVars(line,evs,sig,con);
+        }
+
+        if (whatIs(con)==QUAL) {        /* Local predicates                */
+            List us;
+            lps     = fst(snd(con));
+            for (us = typeVarsIn(lps,NIL,NIL); nonNull(us); us=tl(us))
+                if (!varIsMember(textOf(hd(us)),evs)) {
+                    ERRMSG(line)
+                        "Variable \"%s\" in constraint is not locally bound",
+                        textToStr(textOf(hd(us)))
+                    EEND;
+                }
+            map2Proc(depPredExp,line,sig,lps);
+            con     = snd(snd(con));
+            arity   = length(lps);
+        }
+
         if (whatIs(con)==LABC) {        /* Skeletize constr components     */
             Cell fls = snd(snd(con));   /* get field specifications        */
             con      = fst(snd(con));
@@ -440,7 +942,7 @@ Cell  cd; {                             /* definitions (w or w/o deriving) */
             ctxt1 = selectCtxt(ctxt1,offsetTyvarsIn(con,NIL));
 
         for (i=arity; isAp(con); i--) { /* Calculate type of constructor   */
-            Type t   = fun(con);
+            Type ty  = fun(con);
             Type cmp = arg(con);
             fun(con) = typeArrow;
             if (isPolyType(cmp)) {
@@ -455,13 +957,13 @@ Cell  cd; {                             /* definitions (w or w/o deriving) */
             if (nonNull(derivs))        /* and build list of components    */
                 compTypes = cons(cmp,compTypes);
             type     = ap(con,type);
-            con      = t;
+            con      = ty;
         }
 
         if (nr2>0)                      /* Add rank 2 annotation           */
             type = ap(RANK2,pair(mkInt(nr2),type));
 
-        if (etvs>ntvs) {                /* Add existential annotation      */
+        if (nonNull(evs)) {             /* Add existential annotation      */
             if (nonNull(derivs)) {
                 ERRMSG(line) "Cannot derive instances for types" ETHEN
                 ERRTEXT      " with existentially typed components"
@@ -472,11 +974,17 @@ Cell  cd; {                             /* definitions (w or w/o deriving) */
                    "Cannot use selectors with existentially typed components"
                 EEND;
             }
-            type = ap(EXIST,pair(mkInt(etvs-ntvs),type));
+            type = ap(EXIST,pair(mkInt(length(evs)),type));
         }
+
+        if (nonNull(lps)) {             /* Add local preds part to type    */
+            type = ap(CDICTS,pair(lps,type));
+        }
+
         if (nonNull(ctxt1)) {           /* Add context part to type        */
             type = ap(QUAL,pair(ctxt1,type));
         }
+
         if (nonNull(sig)) {             /* Add quantifiers to type         */
             List ts1 = sig;
             for (; nonNull(ts1); ts1=tl(ts1)) {
@@ -487,20 +995,37 @@ Cell  cd; {                             /* definitions (w or w/o deriving) */
 
         n = findName(textOf(con));      /* Allocate constructor fun name   */
         if (isNull(n)) {
-            n = newName(textOf(con));
+            n = newName(textOf(con),NIL);
         } else if (name(n).defn!=PREDEFINED) {
             duplicateError(line,name(n).mod,name(n).text,
                            "constructor function");
         }
         name(n).arity  = arity;         /* Save constructor fun details    */
         name(n).line   = line;
+        name(n).parent = t;
         name(n).number = cfunNo(conNo++);
         name(n).type   = type;
         if (tycon(t).what==NEWTYPE) {
+            if (nonNull(lps)) {
+                ERRMSG(line)
+                   "A newtype constructor cannot have class constraints"
+                EEND;
+            }
+            if (arity!=1) {
+                ERRMSG(line)
+                   "A newtype constructor must have exactly one argument"
+                EEND;
+            }
+            if (nonNull(scs)) {
+                ERRMSG(line)
+                   "Illegal strictess annotation for newtype constructor"
+                EEND;
+            }
             name(n).defn = nameId;
         } else {
             implementCfun(n,scs);
         }
+
         hd(cs) = n;
         if (fs!=NONE) {
             sels = addSels(line,n,fs,sels);
@@ -518,15 +1043,33 @@ Cell  cd; {                             /* definitions (w or w/o deriving) */
     }
 }
 
+Int userArity(c)                        /* Find arity for cfun, ignoring   */
+Name c; {                               /* CDICTS parameters               */
+    Int  a = name(c).arity;
+    Type t = name(c).type;
+    Int  w;
+    if (isPolyType(t)) {
+        t = monotypeOf(t);
+    }
+    if ((w=whatIs(t))==QUAL) {
+        w = whatIs(t=snd(snd(t)));
+    }
+    if (w==CDICTS) {
+        a -= length(fst(snd(t)));
+    }
+    return a;
+}
+
+static List cfunSfuns;                  /* List of (Cfun,[SelectorVar])    */
+                                        /*  - used for deriving Show       */
+
 static List local addSels(line,c,fs,ss) /* Add fields to selector list     */
 Int  line;                              /* line number of constructor      */
 Name c;                                 /* corresponding constr function   */
 List fs;                                /* list of fields (varids)         */
 List ss; {                              /* list of existing selectors      */
     Int sn    = 1;
-#if DERIVE_SHOW | DERIVE_READ
     cfunSfuns = cons(pair(c,fs),cfunSfuns);
-#endif
     for (; nonNull(fs); fs=tl(fs), ++sn) {
         List ns = ss;
         Text t  = textOf(hd(fs));
@@ -540,6 +1083,7 @@ List ss; {                              /* list of existing selectors      */
         while (nonNull(ns) && t!=name(hd(ns)).text) {
             ns = tl(ns);
         }
+
         if (nonNull(ns)) {
             name(hd(ns)).defn = cons(pair(c,mkInt(sn)),name(hd(ns)).defn);
         } else {
@@ -549,7 +1093,7 @@ List ss; {                              /* list of existing selectors      */
                              textToStr(t)
                 EEND;
             }
-            n              = newName(t);
+            n              = newName(t,c);
             name(n).line   = line;
             name(n).number = SELNAME;
             name(n).defn   = singleton(pair(c,mkInt(sn)));
@@ -608,8 +1152,9 @@ List  syns; {
         List path1 = NIL;
         for (; nonNull(ds); ds=tl(ds)) {
             if (cellIsMember(hd(ds),syns)) {
-                if (isNull(path1))
+                if (isNull(path1)) {
                     path1 = cons(t,path);
+                }
                 syns = visitSyn(path1,hd(ds),syns);
             }
         }
@@ -618,6 +1163,7 @@ List  syns; {
     return removeCell(t,syns);
 }
 
+#if EVAL_INSTANCES
 /* --------------------------------------------------------------------------
  * The following code is used in calculating contexts for the automatically
  * derived Eval instances for newtype and restricted type synonyms.  This is
@@ -626,7 +1172,6 @@ List  syns; {
  * future.
  * ------------------------------------------------------------------------*/
 
-#if EVAL_INSTANCES
 static Void local deriveEval(tcs)       /* Derive instances of Eval        */
 List tcs; {
     List ts1 = tcs;
@@ -670,7 +1215,7 @@ List tcs; {
                     for (; nonNull(scs); scs=tl(scs)) {
                         Int i = intOf(hd(scs));
                         for (; n<i; n++) {
-                            t = arg(t);
+                                t = arg(t);
                         }
                         checkBanged(c,ks,ctxt,arg(fun(t)));
                     }
@@ -719,9 +1264,9 @@ List  ps; {
             ctxt = singleton(ap(classEval,copyType(t,o)));
             break;
         } else if (isTuple(h)                   /* Check for tuples ...    */
-                || h==tc                        /* ... direct recursion    */
-                || cellIsMember(h,ps)           /* ... mutual recursion    */
-                || tycon(h).what==DATATYPE) {   /* ... or datatype.        */
+                   || h==tc                     /* ... direct recursion    */
+                   || cellIsMember(h,ps)        /* ... mutual recursion    */
+                   || tycon(h).what==DATATYPE) {/* ... or datatype.        */
             break;                              /* => empty context        */
         } else {
             Cell pi = ap(classEval,t);
@@ -730,6 +1275,10 @@ List  ps; {
             if (cellIsMember(h,ts)) {           /* Not yet visited?        */
                 ts = calcEvalContexts(h,removeCell(h,ts),cons(h,ts));
             }
+<<<<<<<<<<<<<< variant A
+>>>>>>>>>>>>>> variant B
+
+======= end of combination
             if (nonNull(in=findInstFor(pi,o))) {/* Look for Eval instance  */
                 List qs = inst(in).specifics;
                 Int  o1 = typeOff;
@@ -750,10 +1299,10 @@ List  ps; {
 }
 
 static Void local checkBanged(c,ks,ps,ty)
-Name  c;                                /* Check that banged component of c*/
-Kinds ks;                               /* with type ty is an instance of  */
-List  ps;                               /* Eval under the predicates in ps.*/
-Type  ty; {                             /* (All types using ks)            */
+Name  c;                                /* Check that banged component of c */
+Kinds ks;                               /* with type ty is an instance of   */
+List  ps;                               /* Eval under the predicates in ps. */
+Type  ty; {                             /* (All types using ks)             */
     Cell pi = ap(classEval,ty);
     if (isNull(provePred(ks,ps,pi))) {
         ERRMSG(name(c).line) "Illegal datatype strictness annotation:" ETHEN
@@ -825,12 +1374,12 @@ Type env; {                             /* values for OFFSET type vars     */
  *   stages of static analysis.
  * ------------------------------------------------------------------------*/
 
-Void classDefn(line,head,ms)            /* process new class definition    */
-Int  line;                              /* definition line number          */
-Cell head;                              /* class header :: ([Supers],Class)*/
-List ms; {                              /* class definition body           */
-    Text ct   = textOf(getHead(snd(head)));
-    Int arity = argCount;
+Void classDefn(line,head,ms)           /* process new class definition     */
+Int  line;                             /* definition line number           */
+Cell head;                             /* class header :: ([Supers],Class) */
+List ms; {                             /* class definition body            */
+    Text ct    = textOf(getHead(snd(head)));
+    Int  arity = argCount;
 
     if (nonNull(findClass(ct))) {
         ERRMSG(line) "Repeated definition of class \"%s\"",
@@ -849,6 +1398,8 @@ List ms; {                              /* class definition body           */
         cclass(nw).members = ms;
         cclass(nw).level   = 0;
         classDefns         = cons(nw,classDefns);
+        if (arity!=1)
+            h98DoesntSupport(line,"multiple parameter classes");
     }
 }
 
@@ -863,7 +1414,7 @@ List ms; {                              /* class definition body           */
  * class definition:
  * - check that variables in header are distinct
  * - replace head by skeleton
- * - check superclass declarations, replace by skeltons
+ * - check superclass declarations, replace by skeletons
  * - split body of class into members and declarations
  * - make new name entry for each member function
  * - record member function number (eventually an offset into dictionary!)
@@ -876,11 +1427,13 @@ List ms; {                              /* class definition body           */
  * - check that extended class hierarchy does not contain any cycles
  * ------------------------------------------------------------------------*/
 
-static Void local checkClassDefn(c)     /* validate class definition       */
+static Void local checkClassDefn(c)    /* validate class definition        */
 Class c; {
     List tyvars = NIL;
     Int  args   = cclass(c).arity - 1;
     Cell temp   = cclass(c).head;
+    List fs     = NIL;
+    List ss     = NIL;
 
     for (; isAp(temp); temp=fun(temp)) {
         if (!isVar(arg(temp))) {
@@ -904,10 +1457,14 @@ Class c; {
 
     tcDeps              = NIL;          /* find dependents                 */
     map2Proc(depPredExp,cclass(c).line,tyvars,cclass(c).supers);
+    h98CheckCtxt(cclass(c).line,"class definition",FALSE,cclass(c).supers,NIL);
     cclass(c).numSupers = length(cclass(c).supers);
     cclass(c).defaults  = extractBindings(cclass(c).members);   /* defaults*/
-    cclass(c).members   = extractSigdecls(cclass(c).members);
-    map2Proc(checkMems,c,tyvars,cclass(c).members);
+    ss                  = extractSigdecls(cclass(c).members);
+    fs                  = extractFixdecls(cclass(c).members);
+    cclass(c).members   = pair(ss,fs);
+    map2Proc(checkMems,c,tyvars,ss);
+
     cclass(c).kinds     = tcDeps;
     tcDeps              = NIL;
 }
@@ -924,6 +1481,8 @@ Cell pred; {
         h         = fun(pred);
     }
     arg(pred) = depTypeExp(line,tyvars,arg(pred));
+    if (args!=1)
+        h98DoesntSupport(line,"multiple parameter classes");
 
     if (isQCon(h)) {                    /* standard class constraint       */
         Class c = findQualClass(h);
@@ -937,8 +1496,9 @@ Cell pred; {
                         textToStr(cclass(c).text)
             EEND;
         }
-        if (cellIsMember(c,classDefns) && !cellIsMember(c,tcDeps))
+        if (cellIsMember(c,classDefns) && !cellIsMember(c,tcDeps)) {
             tcDeps = cons(c,tcDeps);
+        }
     }
 #if TREX
     else if (isExt(h)) {                /* Lacks predicate                 */
@@ -974,7 +1534,7 @@ Cell  m; {
     fst(snd(t)) = cons(cclass(c).head,fst(snd(t)));/* Add main predicate   */
     snd(snd(t)) = depTopType(line,tyvars,snd(snd(t)));
 
-    for (tvs=tyvars; nonNull(tvs); tvs=tl(tvs)) { /* Quantify              */
+    for (tvs=tyvars; nonNull(tvs); tvs=tl(tvs)){/* Quantify                */
         sig = ap(NIL,sig);
     }
     t       = mkPolyType(sig,t);
@@ -984,11 +1544,13 @@ Cell  m; {
     if (isAmbiguous(t)) {
         ambigError(line,"class declaration",hd(vs),t);
     }
+    h98CheckType(line,"member type",hd(vs),t);
 }
 
 static Void local addMembers(c)         /* Add definitions of member funs  */
 Class c; {                              /* and other parts of class struct.*/
-    List ms  = cclass(c).members;
+    List ms  = fst(cclass(c).members);
+    List fs  = snd(cclass(c).members);
     List ns  = NIL;                     /* List of names                   */
     Int  mno;                           /* Member function number          */
 
@@ -1002,12 +1564,27 @@ Class c; {                              /* and other parts of class struct.*/
         List vs   = rev(snd3(hd(ms)));
         Type t    = thd3(hd(ms));
         for (; nonNull(vs); vs=tl(vs)) {
-            ns = cons(newMember(line,mno++,hd(vs),t),ns);
+            ns = cons(newMember(line,mno++,hd(vs),t,c),ns);
         }
     }
     cclass(c).members    = rev(ns);     /* Save list of members            */
     cclass(c).numMembers = length(cclass(c).members);
 
+    for (; nonNull(fs); fs=tl(fs)) {    /* fixity declarations             */
+        Int    line = intOf(fst3(hd(fs)));
+        List   ops  = snd3(hd(fs));
+        Syntax s    = intOf(thd3(hd(fs)));
+        for (; nonNull(ops); ops=tl(ops)) {
+            Name n = nameIsMember(textOf(hd(ops)),cclass(c).members);
+            if (isNull(n)) {
+                missFixity(line,textOf(hd(ops)));
+            } else if (name(n).syntax!=NO_SYNTAX) {
+                dupFixity(line,textOf(hd(ops)));
+            }
+            name(n).syntax = s;
+        }
+    }
+
 /*  Not actually needed just yet; for the time being, dictionary code will
     not be passed through the type checker.
 
@@ -1019,27 +1596,25 @@ Class c; {                              /* and other parts of class struct.*/
 */
 
     mno                  = cclass(c).numSupers + cclass(c).numMembers;
-    cclass(c).dcon       = addPrimCfun(generateText("Make.%s",c),mno,0,0);
-    implementCfun(cclass(c).dcon,NIL); /* ADR addition */
-#if USE_NEWTYPE_FOR_DICTS
+    cclass(c).dcon       = addPrimCfun(generateText("Make.%s",c),mno,0,NIL);
     if (mno==1) {                       /* Single entry dicts use newtype  */
         name(cclass(c).dcon).defn = nameId;
         name(hd(cclass(c).members)).number = mfunNo(0);
     }
-#endif
     cclass(c).dbuild     = newDBuild(c);
     cclass(c).defaults   = classBindings("class",c,cclass(c).defaults);
 }
 
-static Name local newMember(l,no,v,t)   /* Make definition for member fn   */
-Int  l;
-Int  no;
-Cell v;
-Type t; {
+static Name local newMember(l,no,v,t,parent)
+Int   l;                                /* Make definition for member fn   */
+Int   no;
+Cell  v;
+Type  t; 
+Class parent; {
     Name m = findName(textOf(v));
 
     if (isNull(m)) {
-        m = newName(textOf(v));
+        m = newName(textOf(v),parent);
     } else if (name(m).defn!=PREDEFINED) {
         ERRMSG(l) "Repeated definition for member function \"%s\"",
                   textToStr(name(m).text)
@@ -1060,7 +1635,7 @@ Int   no; {
     char buf[16];
 
     sprintf(buf,"sc%d.%s",no,"%s");
-    s              = newName(generateText(buf,c));
+    s              = newName(generateText(buf,c),c);
     name(s).line   = cclass(c).line;
     name(s).arity  = 1;
     name(s).number = DFUNNAME;
@@ -1069,7 +1644,7 @@ Int   no; {
 
 static Name local newDBuild(c)          /* Make definition for builder     */
 Class c; {
-    Name b         = newName(generateText("class.%s",c));
+    Name b         = newName(generateText("class.%s",c),c);
     name(b).line   = cclass(c).line;
     name(b).arity  = cclass(c).numSupers+1;
     return b;
@@ -1102,7 +1677,7 @@ Class c; {                              /* class hierarchy is acyclic      */
         ERRMSG(cclass(c).line) "Class hierarchy for \"%s\" is not acyclic",
                                textToStr(cclass(c).text)
         EEND;
-    } else if (cclass(c).level == 0) {   /* visiting class for first time   */
+    } else if (cclass(c).level == 0) {  /* visiting class for first time   */
         List scs = cclass(c).supers;
         Int  lev = 0;
         cclass(c).level = (-1);
@@ -1120,30 +1695,30 @@ Class c; {                              /* class hierarchy is acyclic      */
  * ------------------------------------------------------------------------*/
 
 static List local classBindings(where,c,bs)
-String where;                           /*check validity of bindings bs for*/
-Class  c;                               /* class c (or an instance of c)   */
+String where;                           /* Check validity of bindings bs   */
+Class  c;                               /* for class c (or an inst of c)   */
 List   bs; {                            /* sort into approp. member order  */
     List nbs = NIL;
 
     for (; nonNull(bs); bs=tl(bs)) {
-        Cell b = hd(bs);
+        Cell b    = hd(bs);
+        Cell body = snd(snd(b));
         Name mnm;
 
-        if (!isVar(fst(b))) {           /* only allows function bindings   */
-            ERRMSG(rhsLine(snd(snd(snd(b)))))
-               "Pattern binding illegal in %s declaration", where
+        if (!isVar(fst(b))) {           /* Only allow function bindings    */
+            ERRMSG(rhsLine(snd(body)))
+                "Pattern binding illegal in %s declaration", where
             EEND;
         }
 
         if (isNull(mnm=memberName(c,textOf(fst(b))))) {
-            ERRMSG(rhsLine(snd(hd(snd(snd(b))))))
+            ERRMSG(rhsLine(snd(hd(body))))
                 "No member \"%s\" in class \"%s\"",
                 textToStr(textOf(fst(b))), textToStr(cclass(c).text)
             EEND;
         }
-
-        snd(b) = snd(snd(b));
-        nbs = numInsert(mfunOf(mnm)-1,b,nbs);
+        snd(b) = body;
+        nbs    = numInsert(mfunOf(mnm)-1,b,nbs);
     }
     return nbs;
 }
@@ -1160,8 +1735,8 @@ Text  t; {                              /* return NIL if not a member      */
     return NIL;
 }
 
-static List local numInsert(n,x,xs)     /* insert x at nth position in xs, */
-Int  n;                                 /* filling gaps with NIL           */
+static List local numInsert(n,x,xs)    /* insert x at nth position in xs,  */
+Int  n;                                /* filling gaps with NIL            */
 Cell x;
 List xs; {
     List start = isNull(xs) ? cons(NIL,NIL) : xs;
@@ -1194,9 +1769,10 @@ List vs; {                              /* listed in us.                   */
         case VAROPCELL : if (nonNull(findBtyvs(textOf(ty)))
                              || varIsMember(textOf(ty),us)) {
                              return vs;
-                          } else {
+                         } else {
                              return maybeAppendVar(ty,vs);
-                          }
+                         }
+
         case POLYTYPE  : return typeVarsIn(monotypeOf(ty),polySigOf(ty),vs);
 
         case QUAL      : {   List qs = fst(snd(ty));
@@ -1218,8 +1794,8 @@ List vs; {                              /* listed in us.                   */
     return vs;
 }
 
-static List local maybeAppendVar(v,vs)  /* append variable to list if not  */
-Cell v;                                 /* already included                */
+static List local maybeAppendVar(v,vs) /* append variable to list if not   */
+Cell v;                                /* already included                 */
 List vs; {
     Text t = textOf(v);
     List p = NIL;
@@ -1238,6 +1814,7 @@ List vs; {
     } else {
         vs    = cons(v,NIL);
     }
+
     return vs;
 }
 
@@ -1267,6 +1844,7 @@ Type   type; {
     } else {
         type = depTopType(line,tvs,type);
     }
+
     if (n>0) {
         if (n>=NUM_OFFSETS) {
             ERRMSG(line) "Too many type variables in %s\n", where
@@ -1284,6 +1862,8 @@ Type   type; {
     kindType(line,"type expression",type);
     fixKinds();
     unkindTypes = sunk;
+
+    h98CheckType(line,where,e,type);
     return type;
 }
 
@@ -1295,7 +1875,7 @@ Type t; {
     Type t1   = t;
     Int  nr2  = 0;
     Int  i    = 1;
-    for (; getHead(t1)==typeArrow; ++i) {
+    for (; getHead(t1)==typeArrow && argCount==2; ++i) {
         arg(fun(t1)) = depCompType(l,tvs,arg(fun(t1)));
         if (isPolyType(arg(fun(t1)))) {
             nr2 = i;
@@ -1323,35 +1903,16 @@ Type t; {
         List nfr  = NIL;
         if (isPolyType(t)) {
             List vs  = fst(snd(t));
-            List bvs = typeVarsIn(monotypeOf(t),NIL,NIL);
-            List us  = vs;
-            for (; nonNull(us); us=tl(us)) {
-                Text u = textOf(hd(us));
-                if (varIsMember(u,tl(us))) {
-                    ERRMSG(l) "Duplicated quantified variable %s",
-                              textToStr(u)
-                    EEND;
-                }
-                if (varIsMember(u,tvs)) {
-                    ERRMSG(l) "Local quantifier for %s hides an outer use",
-                              textToStr(u)
-                    EEND;
-                }
-                if (!varIsMember(u,bvs)) {
-                    ERRMSG(l) "Locally quantified variable %s is not used",
-                              textToStr(u)
-                    EEND;
-                }
-            }
-            nfr = replicate(length(vs),NIL);
-            tvs = appendOnto(tvs,vs);
-            t   = monotypeOf(t);
+            t        = monotypeOf(t);
+            tvs      = checkQuantVars(l,vs,tvs,t);
+            nfr      = replicate(length(vs),NIL);
         }
         if (whatIs(t)==QUAL) {
             map2Proc(depPredExp,l,tvs,fst(snd(t)));
             snd(snd(t)) = depTypeExp(l,tvs,snd(snd(t)));
-            if (isAmbiguous(t))
+            if (isAmbiguous(t)) {
                 ambigError(l,"type component",NIL,t);
+            }
         } else {
             t = depTypeExp(l,tvs,t);
         }
@@ -1396,7 +1957,7 @@ Type type; {
                           }
 
 #if TREX
-        case EXT        :
+        case EXT        : h98DoesntSupport(line,"extensible records");
 #endif
         case TYCON      :
         case TUPLE      : break;
@@ -1426,11 +1987,66 @@ Text tv; {
     return mkOffset(offset);
 }
 
+static List local checkQuantVars(line,vs,tvs,body)
+Int  line;
+List vs;                                /* variables to quantify over      */
+List tvs;                               /* variables already in scope      */
+Cell body; {                            /* type/constr for scope of vars   */
+    if (nonNull(vs)) {
+        List bvs = typeVarsIn(body,NIL,NIL);
+        List us  = vs;
+        for (; nonNull(us); us=tl(us)) {
+            Text u = textOf(hd(us));
+            if (varIsMember(u,tl(us))) {
+                ERRMSG(line) "Duplicated quantified variable %s",
+                             textToStr(u)
+                EEND;
+            }
+            if (varIsMember(u,tvs)) {
+                ERRMSG(line) "Local quantifier for %s hides an outer use",
+                             textToStr(u)
+                EEND;
+            }
+            if (!varIsMember(u,bvs)) {
+                ERRMSG(line) "Locally quantified variable %s is not used",
+                             textToStr(u)
+                EEND;
+            }
+        }
+        tvs = appendOnto(tvs,vs);
+    }
+    return tvs;
+}
+
 /* --------------------------------------------------------------------------
  * Check for ambiguous types:
  * A type  Preds => type  is ambiguous if not (TV(P) `subset` TV(type))
  * ------------------------------------------------------------------------*/
 
+static List local offsetTyvarsIn(t,vs)  /* add list of offset tyvars in t  */
+Type t;                                 /* to list vs                      */
+List vs; {
+    switch (whatIs(t)) {
+        case AP       : return offsetTyvarsIn(fun(t),
+                                offsetTyvarsIn(arg(t),vs));
+
+        case OFFSET   : if (cellIsMember(t,vs))
+                            return vs;
+                        else
+                            return cons(t,vs);
+
+        case QUAL     : return offsetTyvarsIn(snd(t),vs);
+
+        case POLYTYPE : return offsetTyvarsIn(monotypeOf(t),vs);
+                        /* slightly inaccurate, but won't matter here      */
+
+        case EXIST    :
+        case RANK2    : return offsetTyvarsIn(snd(snd(t)),vs);
+
+        default       : return vs;
+    }
+}
+
 Bool isAmbiguous(type)                  /* Determine whether type is       */
 Type type; {                            /* ambiguous                       */
     if (isPolyType(type)) {
@@ -1474,9 +2090,9 @@ Cell c; {
     Int  n = argCount;
 
 #ifdef DEBUG_KINDS
-    printf("kindConstr: alpha=%d, m=%d, c=",alpha,m);
+    Printf("kindConstr: alpha=%d, m=%d, c=",alpha,m);
     printType(stdout,c);
-    printf("\n");
+    Printf("\n");
 #endif
 
     switch (whatIs(h)) {
@@ -1488,14 +2104,16 @@ Cell c; {
                             Kinds ks = polySigOf(t);
                             Int   m1 = 0;
                             Int   beta;
-                            for (; isAp(ks); ks=tl(ks))
+                            for (; isAp(ks); ks=tl(ks)) {
                                 m1++;
+                            }
                             beta        = newKindvars(m1);
                             unkindTypes = cons(pair(mkInt(beta),t),unkindTypes);
                             checkKind(line,beta,m1,monotypeOf(t),NIL,pt,STAR,0);
                         }
                         return;
 
+        case CDICTS   :
         case QUAL     : if (n!=0) {
                             internal("kindConstr2");
                         }
@@ -1528,7 +2146,7 @@ Cell c; {
 
     if (n==0) {                         /* trivial case, no arguments      */
         typeIs = kindAtom(alpha,c);
-    } else {                              /* non-trivial application         */
+    } else {                            /* non-trivial application         */
         static String app = "constructor application";
         Cell   a = c;
         Int    i;
@@ -1569,9 +2187,9 @@ Cell c; {
 #endif
     }
 #if DEBUG_KINDS
-    printf("kindAtom(%d,whatIs(%d)) on ",alpha,whatIs(c));
+    Printf("kindAtom(%d,whatIs(%d)) on ",alpha,whatIs(c));
     printType(stdout,c);
-    printf("\n");
+    Printf("\n");
 #endif
     internal("kindAtom");
     return STAR;/* not reached */
@@ -1628,11 +2246,11 @@ static Void local fixKinds() {          /* add kind annotations to types   */
             }
         }
 #ifdef DEBUG_KINDS
-        printf("Type expression: ");
+        Printf("Type expression: ");
         printType(stdout,snd(pr));
-        printf(" :: ");
+        Printf(" :: ");
         printKind(stdout,polySigOf(snd(pr)));
-        printf("\n");
+        Printf("\n");
 #endif
     }
 }
@@ -1701,8 +2319,8 @@ Cell c; {                               /* is well-kinded                  */
         }
     }
     else {                              /* scan type exprs in class defn to*/
-        List ms   = cclass(c).members;  /* determine the class signature   */
-        Int  m    = cclass(c).arity;
+        List ms   = fst(cclass(c).members);
+        Int  m    = cclass(c).arity;    /* determine the class signature   */
         Int  beta = newKindvars(m);
         kindPred(cclass(c).line,beta,m,cclass(c).head);
         map3Proc(kindPred,cclass(c).line,beta,m,cclass(c).supers);
@@ -1719,9 +2337,9 @@ Cell c; {                               /* given tycon/class               */
     if (isTycon(c)) {
         tycon(c).kind = copyKindvar(intOf(tycon(c).kind));
 #ifdef DEBUG_KINDS
-        printf("%s :: ",textToStr(tycon(c).text));
+        Printf("%s :: ",textToStr(tycon(c).text));
         printKind(stdout,tycon(c).kind);
-        putchar('\n');
+        Putchar('\n');
 #endif
     } else {
         Kinds ks = cclass(c).kinds;
@@ -1729,9 +2347,9 @@ Cell c; {                               /* given tycon/class               */
             hd(ks) = copyKindvar(intOf(hd(ks)));
         }
 #ifdef DEBUG_KINDS
-        printf("%s :: ",textToStr(cclass(c).text));
+        Printf("%s :: ",textToStr(cclass(c).text));
         printKinds(stdout,cclass(c).kinds);
-        putchar('\n');
+        Putchar('\n');
 #endif
     }
 }
@@ -1747,10 +2365,10 @@ Cell c; {                               /* given tycon/class               */
  *   stages of static analysis.
  * ------------------------------------------------------------------------*/
 
-Void instDefn(line,head,ms)             /* process new instance definition */
-Int  line;                              /* definition line number          */
-Cell head;                              /* inst header :: (context,Class)  */
-List ms; {                              /* instance members                */
+Void instDefn(line,head,ms)            /* process new instance definition  */
+Int  line;                             /* definition line number           */
+Cell head;                             /* inst header :: (context,Class)   */
+List ms; {                             /* instance members                 */
     Inst nw             = newInst();
     inst(nw).line       = line;
     inst(nw).specifics  = fst(head);
@@ -1776,14 +2394,48 @@ List ms; {                              /* instance members                */
  * ------------------------------------------------------------------------*/
 
 Bool allowOverlap = FALSE;              /* TRUE => allow overlapping insts */
+Name nameListMonad = NIL;               /* builder function for List Monad */
 
 static Void local checkInstDefn(in)     /* Validate instance declaration   */
 Inst in; {
     Int  line   = inst(in).line;
     List tyvars = typeVarsIn(inst(in).head,NIL,NIL);
 
+    if (haskell98) {                    /* Check for `simple' type         */
+        List tvs = NIL;
+        Cell t   = arg(inst(in).head);
+        for (; isAp(t); t=fun(t)) {
+            if (!isVar(arg(t))) {
+                ERRMSG(line)
+                   "syntax error in instance head (variable expected)"
+                EEND;
+            }
+            if (varIsMember(textOf(arg(t)),tvs)) {
+                ERRMSG(line) "repeated type variable \"%s\" in instance head",
+                             textToStr(textOf(arg(t)))
+                EEND;
+            }
+            tvs = cons(arg(t),tvs);
+        }
+        if (isVar(t)) {
+            ERRMSG(line)
+                "syntax error in instance head (constructor expected)"
+            EEND;
+        }
+    }
+
     depPredExp(line,tyvars,inst(in).head);
+
+    if (haskell98) {
+        Type h = getHead(arg(inst(in).head));
+        if (isSynonym(h)) {
+            ERRMSG(line) "Cannot use type synonym in instance head"
+            EEND;
+        }
+    }
+
     map2Proc(depPredExp,line,tyvars,inst(in).specifics);
+    h98CheckCtxt(line,"instance definition",FALSE,inst(in).specifics,NIL);
     inst(in).numSpecifics = length(inst(in).specifics);
     inst(in).c            = getHead(inst(in).head);
     if (!isClass(inst(in).c)) {
@@ -1801,13 +2453,25 @@ Inst in; {
     insertInst(in);
 
     if (nonNull(extractSigdecls(inst(in).implements))) {
-        ERRMSG(line) "Type signature decls not permitted in instance decl"
+        ERRMSG(line)
+          "Type signature declarations not permitted in instance declaration"
+        EEND;
+    }
+    if (nonNull(extractFixdecls(inst(in).implements))) {
+        ERRMSG(line)
+          "Fixity declarations not permitted in instance declaration"
         EEND;
     }
     inst(in).implements = classBindings("instance",
                                         inst(in).c,
                                         extractBindings(inst(in).implements));
     inst(in).builder    = newInstImp(in);
+    /*ToDo*/
+fprintf(stderr, "\npreludeLoaded query\n" );
+    if (/*!preludeLoaded &&*/ isNull(nameListMonad) && isAp(inst(in).head)
+        && fun(inst(in).head)==classMonad && arg(inst(in).head)==typeList) {
+        nameListMonad = inst(in).builder;
+    }
 }
 
 static Void local insertInst(in)        /* Insert instance into class      */
@@ -1822,7 +2486,7 @@ Inst in; {
         Int beta  = newKindedVars(inst(hd(ins)).kinds);
         if (unifyPred(inst(in).head,alpha,inst(hd(ins)).head,beta)) {
             Cell pi  = copyPred(inst(in).head,alpha);
-            if (allowOverlap) {         /* So long as one is more specific */
+            if (allowOverlap && !haskell98) {
                 Bool bef = instCompare(in,hd(ins));
                 Bool aft = instCompare(hd(ins),in);
                 if (bef && !aft) {      /* in comes strictly before hd(ins)*/
@@ -1866,7 +2530,7 @@ Inst ia, ib;{
 
 static Name local newInstImp(in)        /* Make definition for inst builder*/
 Inst in; {
-    Name b         = newName(inventText());
+    Name b         = newName(inventText(),in);
     name(b).line   = inst(in).line;
     name(b).arity  = inst(in).numSpecifics;
     name(b).number = DFUNNAME;
@@ -1892,11 +2556,11 @@ Int  freedom; {
         inst(in).kinds = cons(copyKindvar(beta+freedom),inst(in).kinds);
     }
 #ifdef DEBUG_KINDS
-    printf("instance ");
+    Printf("instance ");
     printPred(stdout,inst(in).head);
-    printf(" :: ");
+    Printf(" :: ");
     printKinds(stdout,inst(in).kinds);
-    putchar('\n');
+    Putchar('\n');
 #endif
     emptySubstitution();
 }
@@ -1960,9 +2624,6 @@ Int   n; {
 }
 
 #if EVAL_INSTANCES
-/* ADR addition */
-static List evalInsts = NIL;
-
 Void addEvalInst(line,t,arity,ctxt)     /* Add dummy instance for Eval     */
 Int  line;
 Cell t;
@@ -1983,8 +2644,6 @@ List ctxt; {
     kindInst(in,arity);
     cclass(classEval).instances
              = appendOnto(cclass(classEval).instances,singleton(in));
-    /* ADR addition */
-    evalInsts             = cons(in,evalInsts);
 }
 #endif
 
@@ -1994,13 +2653,13 @@ Class c;                                /* c *must* be ShowRecRow          */
 Ext   e; {
     Inst in               = newInst();
     inst(in).c            = c;
-    inst(in).head         = ap(c,ap2(e,mkOffset(0),mkOffset(1)));
+    inst(in).head         = ap(c,ap2(e,aVar,bVar));
     inst(in).kinds        = extKind;
-    inst(in).specifics    = cons(ap(classShow,mkOffset(0)),
-                                 cons(ap(e,mkOffset(1)),
-                                      cons(ap(c,mkOffset(1)),NIL)));
+    inst(in).specifics    = cons(ap(classShow,aVar),
+                                 cons(ap(e,bVar),
+                                      cons(ap(c,bVar),NIL)));
     inst(in).numSpecifics = 3;
-    inst(in).builder      = implementRecShw(extText(e));
+    inst(in).builder      = implementRecShw(extText(e),in);
     cclass(c).instances   = appendOnto(cclass(c).instances,singleton(in));
     return in;
 }
@@ -2010,13 +2669,13 @@ Class c;                                /* c *must* be EqRecRow            */
 Ext   e; {
     Inst in               = newInst();
     inst(in).c            = c;
-    inst(in).head         = ap(c,ap2(e,mkOffset(0),mkOffset(1)));
+    inst(in).head         = ap(c,ap2(e,aVar,bVar));
     inst(in).kinds        = extKind;
-    inst(in).specifics    = cons(ap(classEq,mkOffset(0)),
-                                 cons(ap(e,mkOffset(1)),
-                                      cons(ap(c,mkOffset(1)),NIL)));
+    inst(in).specifics    = cons(ap(classEq,aVar),
+                                 cons(ap(e,bVar),
+                                      cons(ap(c,bVar),NIL)));
     inst(in).numSpecifics = 3;
-    inst(in).builder      = implementRecEq(extText(e));
+    inst(in).builder      = implementRecEq(extText(e),in);
     cclass(c).instances   = appendOnto(cclass(c).instances,singleton(in));
     return in;
 }
@@ -2074,9 +2733,6 @@ List is; {
     } while (instsChanged);
 
     mapProc(tidyDerInst,is);            /* Tidy up results                 */
-#if DERIVE_SHOW | DERIVE_READ
-    cfunSfuns = NIL;                    /* Only needed to derive Read/Show */
-#endif
 }
 
 static Void local initDerInst(in)       /* Prepare instance for calculation*/
@@ -2093,11 +2749,11 @@ Inst in; {                              /* of derived instance context     */
     inst(in).numSpecifics = beta;
 
 #ifdef DEBUG_DERIVING
-    printf("initDerInst: ");
+    Printf("initDerInst: ");
     printPred(stdout,inst(in).head);
-    printf("\n");
+    Printf("\n");
     printContext(stdout,snd(snd(inst(in).specifics)));
-    printf("\n");
+    Printf("\n");
 #endif
 }
 
@@ -2109,9 +2765,9 @@ Inst in; {                              /* of the context for a derived    */
     Int  beta   = inst(in).numSpecifics;
 
 #ifdef DEBUG_DERIVING
-    printf("calcInstPreds: ");
+    Printf("calcInstPreds: ");
     printPred(stdout,inst(in).head);
-    printf("\n");
+    Printf("\n");
 #endif
 
     while (nonNull(ps)) {
@@ -2159,8 +2815,9 @@ Inst in; {                              /* of the context for a derived    */
                 List qs  = inst(in1).specifics;
                 Int  off = mkInt(typeOff);
                 if (whatIs(qs)==DERIVE) {       /* Still being derived     */
-                    for (qs=fst(snd(qs)); nonNull(hd(qs)); qs=tl(qs))
+                    for (qs=fst(snd(qs)); nonNull(hd(qs)); qs=tl(qs)) {
                         ps = cons(pair(hd(qs),off),ps);
+                    }
                     retain = cons(pair(off,qs),retain);
                 } else {                        /* Previously def'd inst   */
                     for (; nonNull(qs); qs=tl(qs)) {
@@ -2238,14 +2895,15 @@ Inst in; {                              /* calculations                    */
     clearMarks();
     copyPred(inst(in).head,o);
     inst(in).specifics    = simpleContext(ps,o);
+    h98CheckCtxt(inst(in).line,"derived instance",FALSE,inst(in).specifics,in);
     inst(in).numSpecifics = length(inst(in).specifics);
 
 #ifdef DEBUG_DERIVING
-    printf("Derived instance: ");
+    Printf("Derived instance: ");
     printContext(stdout,inst(in).specifics);
-    printf(" ||- ");
+    Printf(" ||- ");
     printPred(stdout,inst(in).head);
-    printf("\n");
+    Printf("\n");
 #endif
 }
 
@@ -2258,42 +2916,21 @@ Inst in; {
     List  imp = NIL;
     Type  t   = getHead(arg(inst(in).head));
     Class c   = inst(in).c;
-#if DERIVE_EQ
-    if (c==classEq)
+    if (c==classEq) {
         imp = deriveEq(t);
-    else
-#endif
-#if DERIVE_ORD
-    if (c==classOrd)
+    } else if (c==classOrd) {
         imp = deriveOrd(t);
-    else 
-#endif
-#if DERIVE_ENUM
-    if (c==classEnum)
+    } else if (c==classEnum) {
         imp = deriveEnum(t);
-    else 
-#endif
-#if DERIVE_IX
-    if (c==classIx)
+    } else if (c==classIx) {
         imp = deriveIx(t);
-    else 
-#endif
-#if DERIVE_SHOW
-    if (c==classShow)
+    } else if (c==classShow) {
         imp = deriveShow(t);
-    else 
-#endif
-#if DERIVE_READ
-    if (c==classRead)
+    } else if (c==classRead) {
         imp = deriveRead(t);
-    else 
-#endif
-#if DERIVE_BOUNDED
-    if (c==classBounded)
+    } else if (c==classBounded) {
         imp = deriveBounded(t);
-    else 
-#endif
-    {
+    } else {
         ERRMSG(inst(in).line) "Cannot derive instances of class \"%s\"",
                               textToStr(cclass(inst(in).c).text)
         EEND;
@@ -2307,6 +2944,7 @@ Inst in; {
                                         imp);
 }
 
+
 /* --------------------------------------------------------------------------
  * Default definitions; only one default definition is permitted in a
  * given script file.  If no default is supplied, then a standard system
@@ -2339,6 +2977,11 @@ static Void local checkDefaultDefns() { /* check that default types are    */
     } else {
         defaultDefns = stdDefaults;
     }
+
+    if (isNull(classNum)) {
+        classNum = findClass(findText("Num"));
+    }
+
     for (ds=defaultDefns; nonNull(ds); ds=tl(ds)) {
         if (isNull(provePred(NIL,NIL,ap(classNum,hd(ds))))) {
             ERRMSG(defaultLine)
@@ -2348,6 +2991,8 @@ static Void local checkDefaultDefns() { /* check that default types are    */
     }
 }
 
+
+/*-- from STG --*/
 /* --------------------------------------------------------------------------
  * Foreign import declarations are Hugs' equivalent of GHC's ccall mechanism.
  * They are used to "import" C functions into a module.
@@ -2369,7 +3014,7 @@ Cell type; {
     Int  l = intOf(line);
 
     if (isNull(n)) {
-        n = newName(t);
+        n = newName(t,NIL);
     } else if (name(n).defn!=PREDEFINED) {
         ERRMSG(l) "Redeclaration of foreign \"%s\"", textToStr(t)
         EEND;
@@ -2404,7 +3049,7 @@ Cell type; {
     Int  l = intOf(line);
 
     if (isNull(n)) {
-        n = newName(t);
+        n = newName(t,NIL);
     } else if (name(n).defn!=PREDEFINED) {
         ERRMSG(l) "Redeclaration of foreign \"%s\"", textToStr(t)
         EEND;
@@ -2425,6 +3070,63 @@ Name p; {
     implementForeignExport(p);
 }
 
+
+
+
+#if 0
+/*-- from 98 --*/
+/* --------------------------------------------------------------------------
+ * Primitive definitions are usually only included in the first script
+ * file read - the prelude.  A primitive definition associates a variable
+ * name with a string (which identifies a built-in primitive) and a type.
+ * ------------------------------------------------------------------------*/
+
+Void primDefn(line,prims,type)          /* Handle primitive definitions    */
+Cell line;
+List prims;
+Cell type; {
+    primDefns = cons(triple(line,prims,type),primDefns);
+}
+
+static List local checkPrimDefn(pd)     /* Check primitive definition      */
+Triple pd; {
+    Int  line  = intOf(fst3(pd));
+    List prims = snd3(pd);
+    Type type  = thd3(pd);
+    emptySubstitution();
+    type = checkSigType(line,"primitive definition",fst(hd(prims)),type);
+    for (; nonNull(prims); prims=tl(prims)) {
+        Cell   p    = hd(prims);
+        Bool   same = isVar(p);
+        Text   pt   = textOf(same ? p : fst(p));
+        String pr   = textToStr(textOf(same ? p : snd(p)));
+        hd(prims)   = addNewPrim(line,pt,pr,type);
+    }
+    return snd3(pd);
+}
+
+static Name local addNewPrim(l,vn,s,t)  /* make binding of variable vn to  */
+Int    l;                               /* primitive function referred     */
+Text   vn;                              /* to by s, with given type t      */
+String s;
+Cell   t;{
+    Name n = findName(vn);
+
+    if (isNull(n)) {
+        n = newName(vn,NIL);
+    } else if (name(n).defn!=PREDEFINED) {
+        duplicateError(l,name(n).mod,vn,"primitive");
+    }
+
+    addPrim(l,n,s,t);
+    return n;
+}
+#endif
+
+
+
+
+
 /* --------------------------------------------------------------------------
  * Static analysis of patterns:
  *
@@ -2444,31 +3146,37 @@ Name p; {
  * complete pattern list (as is required on the lhs of a function defn).
  * ------------------------------------------------------------------------*/
 
-static List patVars;                    /* List of vars bound in pattern   */
+static List patVars;                   /* List of vars bound in pattern    */
 
-static Cell local checkPat(line,p)      /* Check valid pattern syntax      */
+static Cell local checkPat(line,p)     /* Check valid pattern syntax       */
 Int  line;
 Cell p; {
     switch (whatIs(p)) {
         case VARIDCELL :
-        case VAROPCELL : addPatVar(line,p);
+        case VAROPCELL : addToPatVars(line,p);
                          break;
 
+        case INFIX     : return checkPat(line,tidyInfix(line,snd(p)));
+
         case AP        : return checkMaybeCnkPat(line,p);
 
         case NAME      :
         case QUALIDENT : 
-        case CONIDCELL :
+        case CONIDCELL : 
         case CONOPCELL : return checkApPat(line,0,p);
 
+#if BIGNUMS
+        case ZERONUM   :
+        case POSNUM    :
+        case NEGNUM    :
+#endif
         case WILDCARD  :
         case STRCELL   :
         case CHARCELL  :
-        case INTCELL   : 
-        case BIGCELL   : 
         case FLOATCELL : break;
+        case INTCELL   : break;
 
-        case ASPAT     : addPatVar(line,fst(snd(p)));
+        case ASPAT     : addToPatVars(line,fst(snd(p)));
                          snd(snd(p)) = checkPat(line,snd(snd(p)));
                          break;
 
@@ -2481,27 +3189,11 @@ Cell p; {
         case CONFLDS   : depConFlds(line,p,TRUE);
                          break;
 
-        case ESIGN     : {   Type t   = snd(snd(p));
-                             List tvs = typeVarsIn(t,NIL,NIL);
-                             for (; nonNull(tvs); tvs=tl(tvs)) {
-                                 Int beta    = newKindvars(1);
-                                 hd(btyvars) = cons(pair(hd(tvs),mkInt(beta)),
-                                                    hd(btyvars));
-                             }
-                             t = checkSigType(line,
-                                              "pattern type",
-                                              fst(snd(p)),
-                                              t);
-                             if (isPolyType(t) 
-                                 || whatIs(t)==QUAL
-                                 || whatIs(t)==RANK2) {
-                                 ERRMSG(line)
-                                  "Illegal type in pattern annotation"
-                                 EEND;
-                             }
-                             snd(snd(p)) = t;
-                             fst(snd(p)) = checkPat(line,fst(snd(p)));
-                         }
+        case ESIGN     : snd(snd(p)) = checkPatType(line,
+                                                    "pattern",
+                                                    fst(snd(p)),
+                                                    snd(snd(p)));
+                         fst(snd(p)) = checkPat(line,fst(snd(p)));
                          break;
 
         default        : ERRMSG(line) "Illegal pattern syntax"
@@ -2510,25 +3202,24 @@ Cell p; {
     return p;
 }
 
-static Cell local checkMaybeCnkPat(l,p) /* Check applicative pattern with  */
-Int  l;                                 /* the possibility of n+k pattern  */
+static Cell local checkMaybeCnkPat(l,p)/* Check applicative pattern with   */
+Int  l;                                /* the possibility of n+k pattern   */
 Cell p; {
 #if NPLUSK
     Cell h = getHead(p);
 
     if (argCount==2 && isVar(h) && textOf(h)==textPlus) {       /* n+k     */
         Cell v = arg(fun(p));
-        if (!isInt(arg(p)) && !isBignum(arg(p))) {
-                ERRMSG(l) "Second argument in (n+k) pattern must be an integer"
-                EEND;
+        if (!isInt(arg(p))) {
+            ERRMSG(l) "Second argument in (n+k) pattern must be an integer"
+            EEND;
         }
-#if 0 /* can't call intOf - it might be a bignum */
         if (intOf(arg(p))<=0) {
-                ERRMSG(l) "Integer k in (n+k) pattern must be > 0"
-                EEND;
+            ERRMSG(l) "Integer k in (n+k) pattern must be > 0"
+            EEND;
         }
-#endif
-        overwrite2(fun(p),ADDPAT,arg(p));
+        fst(fun(p))      = ADDPAT;
+        intValOf(fun(p)) = intOf(arg(p));
         arg(p)           = checkPat(l,v);
         return p;
     }
@@ -2537,8 +3228,8 @@ Cell p; {
 }
 
 static Cell local checkApPat(line,args,p)
-Int  line;                              /* check validity of application   */
-Int  args;                              /* of constructor to arguments     */
+Int  line;                             /* check validity of application    */
+Int  args;                             /* of constructor to arguments      */
 Cell p; {
     switch (whatIs(p)) {
         case AP        : fun(p) = checkApPat(line,args+1,fun(p));
@@ -2552,19 +3243,20 @@ Cell p; {
                          break;
 
 #if TREX
-        case EXT       : if (args!=2) {
+        case EXT       : h98DoesntSupport(line,"extensible records");
+                         if (args!=2) {
                              ERRMSG(line) "Illegal record pattern"
                              EEND;
                          }
                          break;
 #endif
 
-        case QUALIDENT : 
-                if (!isQCon(p)) {
-                    ERRMSG(line) "Illegal use of qualified variable in pattern"
-                    EEND;
-                }
-                /* deliberate fall through */
+        case QUALIDENT : if (!isQCon(p)) {
+                            ERRMSG(line)
+                                "Illegal use of qualified variable in pattern"
+                            EEND;
+                         }
+                         /* deliberate fall through */
         case CONIDCELL :
         case CONOPCELL : p = conDefined(line,p);
                          checkCfunArgs(line,p,args);
@@ -2580,40 +3272,41 @@ Cell p; {
     return p;
 }
 
-static Void local addPatVar(line,v)     /* add variable v to list of vars  */
-Int  line;                              /* in current pattern, checking for*/
-Cell v; {                               /* repeated variables.             */
-     Text t = textOf(v);
-     List p = NIL;
-     List n = patVars;
-
-     for (; nonNull(n); p=n, n=tl(n)) {
-         if (textOf(hd(n))==t) {
-             ERRMSG(line) "Repeated variable \"%s\" in pattern",
-                          textToStr(t)
-             EEND;
-         }
-     }
-     if (isNull(p)) {
+static Void local addToPatVars(line,v)  /* Add variable v to list of vars  */
+Int  line;                              /* in current pattern, checking    */
+Cell v; {                               /* for repeated variables.         */
+    Text t = textOf(v);
+    List p = NIL;
+    List n = patVars;
+
+    for (; nonNull(n); p=n, n=tl(n)) {
+        if (textOf(hd(n))==t) {
+            ERRMSG(line) "Repeated variable \"%s\" in pattern",
+                         textToStr(t)
+            EEND;
+        }
+    }
+
+    if (isNull(p)) {
          patVars = cons(v,NIL);
-     } else {
+    } else {
          tl(p)   = cons(v,NIL);
-     }
+    }
 }
 
-static Name local conDefined(line,nm)   /* check that nm is the name of a  */
-Int  line;                              /* previously defined constructor  */
-Cell nm; {                              /* function.                       */
-    Cell c=findQualName(line,nm);
-    if (isNull(c)) {
+static Name local conDefined(line,nm)  /* check that nm is the name of a   */
+Int  line;                             /* previously defined constructor   */
+Cell nm; {                             /* function.                        */
+    Name n = findQualName(nm);
+    if (isNull(n)) {
         ERRMSG(line) "Undefined constructor function \"%s\"", identToStr(nm)
         EEND;
     }
-    checkIsCfun(line,c);
-    return c;
+    checkIsCfun(line,n);
+    return n;
 }
 
-static Void local checkIsCfun(line,c)   /* Check that c is a constructor fn*/
+static Void local checkIsCfun(line,c)  /* Check that c is a constructor fn */
 Int  line;
 Name c; {
     if (!isCfun(c)) {
@@ -2624,20 +3317,41 @@ Name c; {
 }
 
 static Void local checkCfunArgs(line,c,args)
-Int  line;                              /* Check constructor applied with  */
-Cell c;                                 /* correct number of arguments     */
+Int  line;                             /* Check constructor applied with   */
+Cell c;                                /* correct number of arguments      */
 Int  args; {
-    if (name(c).arity!=args) {
-        ERRMSG(line) "Constructor function \"%s\" needs %d args in pattern",
-                     textToStr(name(c).text), name(c).arity
+    Int a = userArity(c);
+    if (a!=args) {
+        ERRMSG(line)
+          "Constructor \"%s\" must have exactly %d argument%s in pattern",
+          textToStr(name(c).text), a, ((a==1)?"":"s")
+        EEND;
+    }
+}
+
+static Cell local checkPatType(l,wh,e,t)/* Check type appearing in pattern */
+Int    l;
+String wh;
+Cell   e;
+Type   t; {
+    List tvs = typeVarsIn(t,NIL,NIL);
+    h98DoesntSupport(l,"pattern type annotations");
+    for (; nonNull(tvs); tvs=tl(tvs)) {
+        Int beta    = newKindvars(1);
+        hd(btyvars) = cons(pair(hd(tvs),mkInt(beta)), hd(btyvars));
+    }
+    t = checkSigType(l,"pattern type",e,t);
+    if (isPolyType(t) || whatIs(t)==QUAL || whatIs(t)==RANK2) {
+        ERRMSG(l) "Illegal syntax in %s type annotation", wh
         EEND;
     }
+    return t;
 }
 
 static Cell local applyBtyvs(pat)       /* Record bound type vars in pat   */
 Cell pat; {
     List bts = hd(btyvars);
-    btyvars  = tl(btyvars);
+    leaveBtyvs();
     if (nonNull(bts)) {
         pat = ap(BIGLAM,pair(bts,pat));
         for (; nonNull(bts); bts=tl(bts)) {
@@ -2652,14 +3366,18 @@ Cell pat; {
  * dependency and scope analysis.
  * ------------------------------------------------------------------------*/
 
-static List bounds;                     /* list of lists of bound vars     */
-static List bindings;                   /* list of lists of binds in scope */
-static List depends;                    /* list of lists of dependents     */
+static List bounds;                    /* list of lists of bound vars      */
+static List bindings;                  /* list of lists of binds in scope  */
+static List depends;                   /* list of lists of dependents      */
+
+/* bounds   :: [[Var]]        -- var equality used on Vars     */
+/* bindings :: [[([Var],?)]]  -- var equality used on Vars     */
+/* depends  :: [[Var]]        -- pointer equality used on Vars */
 
-#define saveBvars()      hd(bounds)     /* list of bvars in current scope  */
-#define restoreBvars(bs) hd(bounds)=bs  /* restore list of bound variables */
+#define saveBvars()      hd(bounds)    /* list of bvars in current scope   */
+#define restoreBvars(bs) hd(bounds)=bs /* restore list of bound variables  */
 
-static Cell local bindPat(line,p)       /* add new bound vars for pattern  */
+static Cell local bindPat(line,p)      /* add new bound vars for pattern   */
 Int  line;
 Cell p; {
     patVars    = NIL;
@@ -2668,7 +3386,7 @@ Cell p; {
     return p;
 }
 
-static Void local bindPats(line,ps)     /* add new bound vars for patterns */
+static Void local bindPats(line,ps)    /* add new bound vars for patterns  */
 Int  line;
 List ps; {
     patVars    = NIL;
@@ -2684,7 +3402,9 @@ List ps; {
  *   known.
  *
  * The result of parsing a list of value declarations is a list of Eqns:
- *       Eqn ::= (SIGDECL,(Line,[Var],type))  |  (Expr,Rhs)
+ *       Eqn ::= (SIGDECL,(Line,[Var],type))
+ *            |  (FIXDECL,(Line,[Op],SyntaxInt))
+ *            |  (Expr,Rhs)
  * The ordering of the equations in this list is the reverse of the original
  * ordering in the script parsed.  This is a consequence of the structure of
  * the parser ... but also turns out to be most convenient for the static
@@ -2713,15 +3433,16 @@ List ps; {
  * - Every variable named in a type signature declaration is defined by
  *   one or more equations elsewhere in the script.
  * - No variable has more than one type declaration.
+ * - Similar properties for fixity declarations.
  *
  * ------------------------------------------------------------------------*/
 
-#define bindingType(b) fst(snd(b))      /* type (or types) for binding     */
-#define fbindAlts(b)   snd(snd(b))      /*alternatives for function binding*/
+#define bindingAttr(b) fst(snd(b))     /* type(s)/fixity(ies) for binding  */
+#define fbindAlts(b)   snd(snd(b))     /* alternatives for function binding*/
 
-static List local extractSigdecls(es)   /* extract the SIGDECLS from list  */
-List es; {                              /* of equations                    */
-    List sigDecls  = NIL;               /* :: [(Line,[Var],Type)]          */
+static List local extractSigdecls(es)  /* Extract the SIGDECLS from list   */
+List es; {                             /* of equations                     */
+    List sigdecls = NIL;               /* :: [(Line,[Var],Type)]           */
 
     for(; nonNull(es); es=tl(es)) {
         if (fst(hd(es))==SIGDECL) {                  /* type-declaration?  */
@@ -2735,103 +3456,167 @@ List es; {                              /* of equations                    */
                     EEND;
                 }
             }
-            sigDecls = cons(sig,sigDecls);          /* discard SIGDECL tag */
+            sigdecls = cons(sig,sigdecls);           /* discard SIGDECL tag*/
         }
     }
-    return sigDecls;
+    return sigdecls;
 }
 
-static List local extractBindings(es)   /* extract untyped bindings from   */
-List es; {                              /* given list of equations         */
+static List local extractFixdecls(es)   /* Extract the FIXDECLS from list  */
+List es; {                              /* of equations                    */
+    List fixdecls = NIL;                /* :: [(Line,SyntaxInt,[Op])]      */
+
+    for(; nonNull(es); es=tl(es)) {
+        if (fst(hd(es))==FIXDECL) {                  /* fixity declaration?*/
+            fixdecls = cons(snd(hd(es)),fixdecls);   /* discard FIXDECL tag*/
+        }
+    }
+    return fixdecls;
+}
+
+static List local extractBindings(ds)   /* extract untyped bindings from   */
+List ds; {                              /* given list of equations         */
     Cell lastVar   = NIL;               /* = var def'd in last eqn (if any)*/
     Int  lastArity = 0;                 /* = number of args in last defn   */
     List bs        = NIL;               /* :: [Binding]                    */
 
-    for(; nonNull(es); es=tl(es)) {
-        Cell e = hd(es);
-
-        if (fst(e)!=SIGDECL) {
-            Int  line    = rhsLine(snd(e));
-            Cell lhsHead = getHead(fst(e));
-
-            switch (whatIs(lhsHead)) {
-                case VARIDCELL :
-                case VAROPCELL : {                    /* function-binding? */
-                    Cell newAlt = pair(getArgs(fst(e)), snd(e));
-                    if (nonNull(lastVar) && textOf(lhsHead)==textOf(lastVar)) {
-                        if (argCount!=lastArity) {
-                            ERRMSG(line)
-                                "Equations give different arities for \"%s\"",
-                                textToStr(textOf(lhsHead))
-                            EEND;
-                        }
-                        fbindAlts(hd(bs)) = cons(newAlt,fbindAlts(hd(bs)));
-                    }
-                    else {
-                        lastVar   = lhsHead;
-                        lastArity = argCount;
-                        notDefined(line,bs,lhsHead);
-                        bs        = cons(pair(lhsHead,
-                                              pair(NIL,
-                                                   singleton(newAlt))),
-                                         bs);
-                    }
+    for(; nonNull(ds); ds=tl(ds)) {
+        Cell d = hd(ds);
+        if (fst(d)==FUNBIND) {          /* Function bindings               */
+            Cell rhs    = snd(snd(d));
+            Int  line   = rhsLine(rhs);
+            Cell lhs    = fst(snd(d));
+            Cell v      = getHead(lhs);
+            Cell newAlt = pair(getArgs(lhs),rhs);
+            if (!isVar(v)) {
+                internal("FUNBIND");
+            }
+            if (nonNull(lastVar) && textOf(v)==textOf(lastVar)) {
+                if (argCount!=lastArity) {
+                    ERRMSG(line) "Equations give different arities for \"%s\"",
+                                 textToStr(textOf(v))
+                    EEND;
                 }
-                break;
+                fbindAlts(hd(bs)) = cons(newAlt,fbindAlts(hd(bs)));
+            }
+            else {
+                lastVar   = v;
+                lastArity = argCount;
+                notDefined(line,bs,v);
+                bs        = cons(pair(v,pair(NIL,singleton(newAlt))),bs);
+            }
 
-            case QUALIDENT: if (isQVar(lhsHead)) {
-            ERRMSG(line) "Binding for qualified variable \"%s\" not allowed",
-                         identToStr(lhsHead)
-            EEND;
-        }
-        break;
-        /* deliberate fall through */
-#if TREX
-                case EXT       :
-#endif
-                case CONFLDS   :
-                case CONOPCELL :
-                case CONIDCELL :
-                case FINLIST   :
-                case TUPLE     :
-                case NAME      :
-                case LAZYPAT   : 
-                case ASPAT     : lastVar = NIL;       /* pattern-binding?  */
-                                 patVars = NIL;
-                                 enterBtyvs();
-                                 fst(e)  = checkPat(line,fst(e));
-                                 if (isNull(patVars)) {
-                                     ERRMSG(line)
-                                       "No variables defined in lhs pattern"
-                                     EEND;
-                                 }
-                                 map2Proc(notDefined,line,bs,patVars);
-                                 bs = cons(pair(patVars,pair(NIL,e)),bs);
-                                 if (nonNull(hd(btyvars))) {
-                                     ERRMSG(line)
-                                      "Sorry, no type variables are allowed in pattern binding type annotations"
-                                     EEND;
-                                 }
-                                 leaveBtyvs();
-                                 break;
-
-                default        : ERRMSG(line) "Improper left hand side"
-                                 EEND;
+        } else if (fst(d)==PATBIND) {   /* Pattern bindings                */
+            Cell rhs  = snd(snd(d));
+            Int  line = rhsLine(rhs);
+            Cell pat  = fst(snd(d));
+            while (whatIs(pat)==ESIGN) {/* Move type annotations to rhs   */
+                Cell p        = fst(snd(pat));
+                fst(snd(pat)) = rhs;
+                snd(snd(d))   = rhs = pat;
+                fst(snd(d))   = pat = p;
+                fst(rhs)      = RSIGN;
             }
+            if (isVar(pat)) {           /* Convert simple pattern bind to */
+                notDefined(line,bs,pat);/* a function binding             */
+                bs = cons(pair(pat,pair(NIL,singleton(pair(NIL,rhs)))),bs);
+            } else {
+                List vs = getPatVars(line,pat,NIL);
+                if (isNull(vs)) {
+                    ERRMSG(line) "No variables defined in lhs pattern"
+                    EEND;
+                }
+                map2Proc(notDefined,line,bs,vs);
+                bs          = cons(pair(vs,pair(NIL,snd(d))),bs);
+            }
+            lastVar = NIL;
         }
     }
     return bs;
 }
 
-static List local eqnsToBindings(es)    /*Convert list of equations to list*/
-List es; {                              /*of typed bindings                */
+static List local getPatVars(line,p,vs) /* Find list of variables bound in */
+Int  line;                              /* pattern p                       */
+Cell p;
+List vs; {
+    switch (whatIs(p)) {
+        case AP         : do {
+                              vs = getPatVars(line,arg(p),vs);
+                              p  = fun(p);
+                          } while (isAp(p));
+                          return vs;    /* Ignore head of application      */
+
+        case CONFLDS    : {   List pfs = snd(snd(p));
+                              for (; nonNull(pfs); pfs=tl(pfs)) {
+                                  if (isVar(hd(pfs))) {
+                                      vs = addPatVar(line,hd(pfs),vs);
+                                  } else {
+                                      vs = getPatVars(line,snd(hd(pfs)),vs);
+                                  }
+                              }
+                          }
+                          return vs;
+
+        case FINLIST    : {   List ps = snd(p);
+                              for (; nonNull(ps); ps=tl(ps)) {
+                                  vs = getPatVars(line,hd(ps),vs);
+                              }
+                          }
+                          return vs;
+
+        case ESIGN      : return getPatVars(line,fst(snd(p)),vs);
+
+        case LAZYPAT    :
+        case NEG        :
+        case ONLY       :
+        case INFIX      : return getPatVars(line,snd(p),vs);
+
+        case ASPAT      : return addPatVar(line,fst(snd(p)),
+                                             getPatVars(line,snd(snd(p)),vs));
+
+        case VARIDCELL  :
+        case VAROPCELL  : return addPatVar(line,p,vs);
+
+        case CONIDCELL  :
+        case CONOPCELL  :
+        case QUALIDENT  :
+        case INTCELL    :
+        case FLOATCELL  :
+        case CHARCELL   :
+        case STRCELL    :
+        case NAME       :
+        case WILDCARD   : return vs;
+
+        default         : internal("getPatVars");
+    }
+    return vs;
+}
+
+static List local addPatVar(line,v,vs)  /* Add var to list of previously   */
+Int  line;                              /* encountered variables           */
+Cell v;
+List vs; {
+    if (varIsMember(textOf(v),vs)) {
+        ERRMSG(line) "Repeated use of variable \"%s\" in pattern binding",
+                     textToStr(textOf(v))
+        EEND;
+    }
+    return cons(v,vs);
+}
+
+static List local eqnsToBindings(es,ts,cs,ps)
+List es;                                /* Convert list of equations to    */
+List ts;                                /* list of typed bindings          */
+List cs;
+List ps; {
     List bs = extractBindings(es);
-    map1Proc(addSigDecl,bs,extractSigdecls(es));
+    map1Proc(addSigdecl,bs,extractSigdecls(es));
+    map4Proc(addFixdecl,bs,ts,cs,ps,extractFixdecls(es));
     return bs;
 }
 
-static Void local notDefined(line,bs,v) /* check if name already defined in*/
-Int  line;                              /* list of bindings                */
+static Void local notDefined(line,bs,v)/* check if name already defined in */
+Int  line;                             /* list of bindings                 */
 List bs;
 Cell v; {
     if (nonNull(findBinding(textOf(v),bs))) {
@@ -2840,73 +3625,449 @@ Cell v; {
     }
 }
 
-static Cell local findBinding(t,bs)     /* look for binding for variable t */
-Text t;                                 /* in list of bindings bs          */
+static Cell local findBinding(t,bs)    /* look for binding for variable t  */
+Text t;                                /* in list of bindings bs           */
 List bs; {
     for (; nonNull(bs); bs=tl(bs)) {
         if (isVar(fst(hd(bs)))) {                     /* function-binding? */
             if (textOf(fst(hd(bs)))==t) {
                 return hd(bs);
             }
-        } else if (nonNull(varIsMember(t,fst(hd(bs))))) { /* pattern-binding?  */
+        } else if (nonNull(varIsMember(t,fst(hd(bs))))){/* pattern-binding?*/
             return hd(bs);
         }
     }
     return NIL;
 }
 
-static Void local addSigDecl(bs,sigDecl)/* add type information to bindings*/
-List bs;                                /* :: [Binding]                    */
-Cell sigDecl; {                         /* :: (Line,[Var],Type)            */
-    Int  line = intOf(fst3(sigDecl));
-    Cell vs   = snd3(sigDecl);
-    Cell type = checkSigType(line,"type declaration",hd(vs),thd3(sigDecl));
-
-    map3Proc(setType,line,type,bs,vs);
-}
-
-static Void local setType(line,type,bs,v)
-Int  line;                              /* Set type of variable            */
-Cell type;
-Cell v;
-List bs; {
+static Cell local getAttr(bs,v)         /* Locate type/fixity attribute    */
+List bs;                                /* for variable v in bindings bs   */
+Cell v; {
     Text t = textOf(v);
     Cell b = findBinding(t,bs);
 
-    if (isNull(b)) {
-        ERRMSG(line) "Type declaration for variable \"%s\" with no body",
-                     textToStr(t)
-        EEND;
-    }
-
-    if (isVar(fst(b))) {                              /* function-binding? */
-        if (isNull(bindingType(b))) {
-            bindingType(b) = type;
-            return;
+    if (isNull(b)) {                                    /* No binding      */
+        return NIL;
+    } else if (isVar(fst(b))) {                         /* func binding?   */
+        if (isNull(bindingAttr(b))) {
+            bindingAttr(b) = pair(NIL,NIL);
         }
-    } else {                                          /* pattern-binding?  */
+        return bindingAttr(b);
+    } else {                                            /* pat binding?    */
         List vs = fst(b);
-        List ts = bindingType(b);
+        List as = bindingAttr(b);
 
-        if (isNull(ts)) {
-            bindingType(b) = ts = replicate(length(vs),NIL);
+        if (isNull(as)) {
+            bindingAttr(b) = as = replicate(length(vs),NIL);
         }
+
         while (nonNull(vs) && t!=textOf(hd(vs))) {
             vs = tl(vs);
-            ts = tl(ts);
+            as = tl(as);
         }
 
-        if (nonNull(vs) && isNull(hd(ts))) {
-            hd(ts) = type;
-            return;
+        if (isNull(vs)) {
+            internal("getAttr");
+        } else if (isNull(hd(as))) {
+            hd(as) = pair(NIL,NIL);
         }
+        return hd(as);
     }
+}
 
-    ERRMSG(line) "Repeated type declaration for \"%s\"", textToStr(t)
+static Void local addSigdecl(bs,sigdecl)/* add type information to bindings*/
+List bs;                               /* :: [Binding]                     */
+Cell sigdecl; {                        /* :: (Line,[Var],Type)             */
+    Int  l    = intOf(fst3(sigdecl));
+    List vs   = snd3(sigdecl);
+    Type type = checkSigType(l,"type declaration",hd(vs),thd3(sigdecl));
+
+    for (; nonNull(vs); vs=tl(vs)) {
+        Cell v    = hd(vs);
+        Pair attr = getAttr(bs,v);
+        if (isNull(attr)) {
+            ERRMSG(l) "Missing binding for variable \"%s\" in type signature",
+                      textToStr(textOf(v))
+            EEND;
+        } else if (nonNull(fst(attr))) {
+            ERRMSG(l) "Repeated type signature for \"%s\"",
+                      textToStr(textOf(v))
+            EEND;
+        }
+        fst(attr) = type;
+    }
+}
+
+static Void local addFixdecl(bs,ts,cs,ps,fixdecl)
+List   bs;
+List   ts;
+List   cs;
+List   ps;
+Triple fixdecl; {
+    Int  line = intOf(fst3(fixdecl));
+    List ops  = snd3(fixdecl);
+    Cell sy   = thd3(fixdecl);
+
+    for (; nonNull(ops); ops=tl(ops)) {
+        Cell op   = hd(ops);
+        Text t    = textOf(op);
+        Cell attr = getAttr(bs,op);
+        if (nonNull(attr)) {            /* Found name in binding?          */
+            if (nonNull(snd(attr))) {
+                dupFixity(line,t);
+            }
+            snd(attr) = sy;
+        } else {                        /* Look in tycons, classes, prims  */
+            Name n   = NIL;
+            List ts1 = ts;
+            List cs1 = cs;
+            List ps1 = ps;
+            for (; isNull(n) && nonNull(ts1); ts1=tl(ts1)) {    /* tycons  */
+                Tycon tc = hd(ts1);
+                if (tycon(tc).what==DATATYPE || tycon(tc).what==NEWTYPE) {
+                    n = nameIsMember(t,tycon(tc).defn);
+                }
+            }
+            for (; isNull(n) && nonNull(cs1); cs1=tl(cs1)) {    /* classes */
+                n = nameIsMember(t,cclass(hd(cs1)).members);
+            }
+            for (; isNull(n) && nonNull(ps1); ps1=tl(ps1)) {    /* prims   */
+                n = nameIsMember(t,hd(ps1));
+            }
+
+            if (isNull(n)) {
+                missFixity(line,t);
+            } else if (name(n).syntax!=NO_SYNTAX) {
+                dupFixity(line,t);
+            }
+            name(n).syntax = intOf(sy);
+        }
+    }
+}
+
+static Void local dupFixity(line,t)     /* Report repeated fixity decl     */
+Int  line;
+Text t; {
+    ERRMSG(line)
+        "Repeated fixity declaration for operator \"%s\"", textToStr(t)
+    EEND;
+}
+
+static Void local missFixity(line,t)    /* Report missing op for fixity    */
+Int  line;
+Text t; {
+    ERRMSG(line)
+        "Cannot find binding for operator \"%s\" in fixity declaration",
+        textToStr(t)
     EEND;
 }
 
 /* --------------------------------------------------------------------------
+ * Dealing with infix operators:
+ *
+ * Expressions involving infix operators or unary minus are parsed as
+ * elements of the following type:
+ *
+ *     data InfixExp = Only Exp | Neg InfixExp | Infix InfixExp Op Exp
+ *
+ * (The algorithms here do not assume that negation can be applied only once,
+ * i.e., that - - x is a syntax error, as required by the Haskell report.
+ * Instead, that restriction is captured by the grammar itself, given above.)
+ *
+ * There are rules of precedence and grouping, expressed by two functions:
+ *
+ *     prec :: Op -> Int;   assoc :: Op -> Assoc    (Assoc = {L, N, R})
+ *
+ * InfixExp values are rearranged accordingly when a complete expression
+ * has been read using a simple shift-reduce parser whose result may be taken
+ * to be a value of the following type:
+ *
+ *     data Exp = Atom Int | Negate Exp | Apply Op Exp Exp | Error String
+ *
+ * The machine on which this parser is based can be defined as follows:
+ *
+ *     tidy                         :: InfixExp -> [(Op,Exp)] -> Exp
+ *     tidy (Only a)      []         = a
+ *     tidy (Only a)      ((o,b):ss) = tidy (Only (Apply o a b)) ss
+ *     tidy (Infix a o b) []         = tidy a [(o,b)]
+ *     tidy (Infix a o b) ((p,c):ss)
+ *                      | shift  o p = tidy a ((o,b):(p,c):ss)
+ *                      | red    o p = tidy (Infix a o (Apply p b c)) ss
+ *                      | ambig  o p = Error "ambiguous use of operators"
+ *     tidy (Neg e)       []         = tidy (tidyNeg e) []
+ *     tidy (Neg e)       ((o,b):ss)
+ *                      | nshift o   = tidy (Neg (underNeg o b e)) ss
+ *                      | nred   o   = tidy (tidyNeg e) ((o,b):ss)
+ *                      | nambig o   = Error "illegal use of negation"
+ *
+ * At each stage, the parser can either shift, reduce, accept, or error.
+ * The transitions when dealing with juxtaposed operators o and p are
+ * determined by the following rules:
+ *
+ *     shift o p  = (prec o > prec p)
+ *               || (prec o == prec p && assoc o == L && assoc p == L)
+ *
+ *     red o p    = (prec o < prec p)
+ *               || (prec o == prec p && assoc o == R && assoc p == R)
+ *
+ *     ambig o p  = (prec o == prec p)
+ *               && (assoc o == N || assoc p == N || assoc o /= assoc p)
+ *
+ * The transitions when dealing with juxtaposed unary minus and infix
+ * operators are as follows.  The precedence of unary minus (infixl 6) is
+ * hardwired in to these definitions, as it is to the definitions of the
+ * Haskell grammar in the official report.
+ *
+ *     nshift o   = (prec o > 6)
+ *     nred   o   = (prec o < 6) || (prec o == 6 && assoc o == L)
+ *     nambig o   = prec o == 6 && (assoc o == R || assoc o == N)
+ *
+ * An InfixExp of the form (Neg e) means negate the last thing in
+ * the InfixExp e; we can force this negation using:
+ *
+ *     tidyNeg              :: OpExp -> OpExp
+ *     tidyNeg (Only e)      = Only (Negate e)
+ *     tidyNeg (Infix a o b) = Infix a o (Negate b)
+ *     tidyNeg (Neg e)       = tidyNeg (tidyNeg e)
+ * 
+ * On the other hand, if we want to sneak application of an infix operator
+ * under a negation, then we use:
+ *
+ *     underNeg                  :: Op -> Exp -> OpExp -> OpExp
+ *     underNeg o b (Only e)      = Only (Apply o e b)
+ *     underNeg o b (Neg e)       = Neg (underNeg o b e)
+ *     underNeg o b (Infix e p f) = Infix e p (Apply o f b)
+ *
+ * As a concession to efficiency, we lower the number of calls to syntaxOf
+ * by keeping track of the values of sye, sys throughout the process.  The
+ * value APPLIC is used to indicate that the syntax value is unknown.
+ * ------------------------------------------------------------------------*/
+
+static Cell local tidyInfix(line,e)     /* Convert infixExp to Exp         */
+Int  line;
+Cell e; {                               /* :: OpExp                        */
+    Cell   s   = NIL;                   /* :: [(Op,Exp)]                   */
+    Syntax sye = APPLIC;                /* Syntax of op in e (init unknown)*/
+    Syntax sys = APPLIC;                /* Syntax of op in s (init unknown)*/
+    Cell   d   = e;
+
+    while (fst(d)!=ONLY) {              /* Attach fixities to operators    */
+        if (fst(d)==NEG) {
+            d = snd(d);
+        } else {
+            fun(fun(d)) = attachFixity(line,fun(fun(d)));
+            d           = arg(fun(d));
+        }
+    }
+
+    for (;;)
+        switch (whatIs(e)) {
+            case ONLY : e = snd(e);
+                        while (nonNull(s)) {
+                            Cell next   = arg(fun(s));
+                            arg(fun(s)) = e;
+                            fun(fun(s)) = snd(fun(fun(s)));
+                            e           = s;
+                            s           = next;
+                        }
+                        return e;
+
+            case NEG  : if (nonNull(s)) {
+                            if (sys==APPLIC) {  /* calculate sys           */
+                                sys = intOf(fst(fun(fun(s))));
+                            }
+
+                            if (precOf(sys)==UMINUS_PREC &&     /* nambig  */
+                                assocOf(sys)!=UMINUS_ASSOC) {
+                                ERRMSG(line)
+                                 "Ambiguous use of unary minus with \""
+                                ETHEN ERREXPR(snd(fun(fun(s))));
+                                ERRTEXT "\""
+                                EEND;
+                            }
+
+                            if (precOf(sys)>UMINUS_PREC) {      /* nshift  */
+                                Cell e1    = snd(e);
+                                Cell t     = s;
+                                s          = arg(fun(s));
+                                while (whatIs(e1)==NEG)
+                                    e1 = snd(e1);
+                                arg(fun(t)) = arg(e1);
+                                fun(fun(t)) = snd(fun(fun(t)));
+                                arg(e1)     = t;
+                                sys         = APPLIC;
+                                continue;
+                            }
+                        }
+
+                        /* Intentional fall-thru for nreduce and isNull(s) */
+
+                        {   Cell prev = e;              /* e := tidyNeg e  */
+                            Cell temp = arg(prev);
+                            Int  nneg = 1;
+                            for (; whatIs(temp)==NEG; nneg++) {
+                                fun(prev) = nameNegate;
+                                prev      = temp;
+                                temp      = arg(prev);
+                            }
+                            if (isInt(arg(temp))) {     /* special cases   */
+                                if (nneg&1)             /* for literals    */
+                                    arg(temp) = mkInt(-intOf(arg(temp)));
+                            }
+#if BIGNUMS
+                            else if (isBignum(arg(temp))) {
+                                if (nneg&1)
+                                    arg(temp) = bigNeg(arg(temp));
+                            }
+#endif
+                            else if (isFloat(arg(temp))) {
+                                if (nneg&1)
+                                    arg(temp) = mkFloat(-floatOf(arg(temp)));
+                            }
+                            else {
+                                fun(prev) = nameNegate;
+                                arg(prev) = arg(temp);
+                                arg(temp) = e;
+                            }
+                            e = temp;
+                        }
+                        continue;
+
+            default   : if (isNull(s)) {/* Move operation onto empty stack */
+                            Cell next   = arg(fun(e));
+                            s           = e;
+                            arg(fun(s)) = NIL;
+                            e           = next;
+                            sys         = sye;
+                            sye         = APPLIC;
+                        }
+                        else {          /* deal with pair of operators     */
+
+                            if (sye==APPLIC) {  /* calculate sys and sye   */
+                                sye = intOf(fst(fun(fun(e))));
+                            }
+                            if (sys==APPLIC) {
+                                sys = intOf(fst(fun(fun(s))));
+                            }
+
+                            if (precOf(sye)==precOf(sys) &&     /* ambig   */
+                                (assocOf(sye)!=assocOf(sys) ||
+                                 assocOf(sye)==NON_ASS)) {
+                                ERRMSG(line) "Ambiguous use of operator \""
+                                ETHEN ERREXPR(snd(fun(fun(e))));
+                                ERRTEXT "\" with \""
+                                ETHEN ERREXPR(snd(fun(fun(s))));
+                                ERRTEXT "\""
+                                EEND;
+                            }
+
+                            if (precOf(sye)>precOf(sys) ||      /* shift   */
+                                (precOf(sye)==precOf(sys) &&
+                                 assocOf(sye)==LEFT_ASS &&
+                                 assocOf(sys)==LEFT_ASS)) {
+                                Cell next   = arg(fun(e));
+                                arg(fun(e)) = s;
+                                s           = e;
+                                e           = next;
+                                sys         = sye;
+                                sye         = APPLIC;
+                            }
+                            else {                              /* reduce  */
+                                Cell next   = arg(fun(s));
+                                arg(fun(s)) = arg(e);
+                                fun(fun(s)) = snd(fun(fun(s)));
+                                arg(e)      = s;
+                                s           = next;
+                                sys         = APPLIC;
+                                /* sye unchanged */
+                            }
+                        }
+                        continue;
+        }
+}
+
+static Pair local attachFixity(line,op) /* Attach fixity to operator in an */
+Int  line;                              /* infix expression                */
+Cell op; {
+    Syntax sy = DEF_OPSYNTAX;
+
+    switch (whatIs(op)) {
+        case VAROPCELL :
+        case VARIDCELL : if ((sy=lookupSyntax(textOf(op)))==NO_SYNTAX) {
+                             Name n = findName(textOf(op));
+                             if (isNull(n)) {
+                                ERRMSG(line) "Undefined variable \"%s\"",
+                                             textToStr(textOf(op))
+                                EEND;
+                             }
+                             sy = syntaxOf(n);
+                             op = n;
+                         }
+                         break;
+
+        case CONOPCELL :
+        case CONIDCELL : sy = syntaxOf(op = conDefined(line,op));
+                         break;
+
+        case QUALIDENT : {   Name n = findQualName(op);
+                             if (nonNull(n)) {
+                                 op = n;
+                                 sy = syntaxOf(n);
+                             } else {
+                                 ERRMSG(line)
+                                   "Undefined qualified variable \"%s\"",
+                                   identToStr(op)
+                                 EEND;
+                             }
+                         }
+                         break;
+    }
+    if (sy==APPLIC) {
+        sy = DEF_OPSYNTAX;
+    }
+    return pair(mkInt(sy),op);          /* Pair fixity with (possibly)     */
+                                        /* translated operator             */
+}
+
+static Syntax local lookupSyntax(t)     /* Try to find fixity for var in   */
+Text t; {                               /* enclosing bindings              */
+    List bounds1   = bounds;
+    List bindings1 = bindings;
+
+    while (nonNull(bindings1)) {
+        if (nonNull(varIsMember(t,hd(bounds1)))) {
+            return DEF_OPSYNTAX;
+        } else {
+            Cell b = findBinding(t,hd(bindings1));
+            if (nonNull(b)) {
+                Cell a = fst(snd(b));
+                if (isVar(fst(b))) {    /* Function binding                */
+                    if (nonNull(a) && nonNull(snd(a))) {
+                        return intOf(snd(a));
+                    }
+                } else {                /* Pattern binding                 */
+                    List vs = fst(b);
+                    while (nonNull(vs) && nonNull(a)) {
+                        if (t==textOf(hd(vs))) {
+                            if (nonNull(hd(a)) && isInt(snd(hd(a)))) {
+                                return intOf(snd(hd(a)));
+                            }
+                            break;
+                        }
+                        vs = tl(vs);
+                        a  = tl(a);
+                    }
+                }
+                return DEF_OPSYNTAX;
+            }
+        }
+        bounds1   = tl(bounds1);
+        bindings1 = tl(bindings1);
+    }
+    return NO_SYNTAX;
+}
+
+/* --------------------------------------------------------------------------
  * To facilitate dependency analysis, lists of bindings are temporarily
  * augmented with an additional field, which is used in two ways:
  * - to build the `adjacency lists' for the dependency graph. Represented by
@@ -2919,76 +4080,113 @@ List bs; {
  * Using this extra field, the type of each list of declarations during
  * dependency analysis is [Binding'] where:
  *
- *    Binding' ::= (Var, (Dep, (Type, [Alt])))         -- function binding
- *              |  ([Var], (Dep, ([Type], (Pat,Rhs)))) -- pattern binding
+ *    Binding' ::= (Var, (Attr, (Dep, [Alt])))         -- function binding
+ *              |  ([Var], ([Attr], (Dep, (Pat,Rhs)))) -- pattern binding
  *
  * ------------------------------------------------------------------------*/
 
-#define depVal(d) (fst(snd(d)))         /* Access to dependency information*/
-                                                                           
+#define depVal(d) (fst(snd(snd(d))))    /* Access to dependency information*/
+
 static List local dependencyAnal(bs)    /* Separate lists of bindings into */
 List bs; {                              /* mutually recursive groups in    */
-                                        /* order of dependency             */
-                                                                           
     mapProc(addDepField,bs);            /* add extra field for dependents  */
     mapProc(depBinding,bs);             /* find dependents of each binding */
     bs = bscc(bs);                      /* sort to strongly connected comps*/
     mapProc(remDepField,bs);            /* remove dependency info field    */
-    return bs;                                                             
-}                                                                          
-                                                                           
+    return bs;
+}
+
 static List local topDependAnal(bs)     /* Like dependencyAnal(), but at   */
 List bs; {                              /* top level, reporting on progress*/
-    List xs;                                                               
-    Int  i = 0;                                                            
-                                                                           
-    setGoal("Dependency analysis",(Target)(length(bs)));                   
-    mapProc(addDepField,bs);            /* add extra field for dependents  */
-    for (xs=bs; nonNull(xs); xs=tl(xs)) {                                  
-        emptySubstitution();                                               
-        depBinding(hd(xs));                                                
-        soFar((Target)(i++));                                              
-    }                                                                      
-    bs = bscc(bs);                      /* sort to strongly connected comps*/
-    mapProc(remDepField,bs);            /* remove dependency info field    */
-    done();                                                                
-    return bs;                                                             
-}                                                                          
-                                                                           
-static Void local addDepField(b)        /* add extra field to binding to   */
-Cell b; {                               /* hold list of dependents         */
-    snd(b) = pair(NIL,snd(b));
-}
-
-static Void local remDepField(bs)       /* remove dependency field from    */
-List bs; {                              /* list of bindings                */
-    mapProc(remDepField1,bs);                                              
-}                                                                          
-                                                                           
-static Void local remDepField1(b)       /* remove dependency field from    */
-Cell b; {                               /* single binding                  */
-    snd(b) = snd(snd(b));                                                  
-}                                                                          
-                                                                           
-static Void local clearScope() {        /* initialise dependency scoping   */
-    bounds   = NIL;                                                        
-    bindings = NIL;                                                        
-    depends  = NIL;                                                        
-}                                                                          
-                                                                           
-static Void local withinScope(bs)       /* enter scope of bindings bs      */
-List bs; {                                                                 
-    bounds   = cons(NIL,bounds);                                           
-    bindings = cons(bs,bindings);                                          
-    depends  = cons(NIL,depends);                                          
-}                                                                          
-                                                                           
-static Void local leaveScope() {        /* leave scope of last withinScope */
+    List xs;
+    Int  i = 0;
+
+    setGoal("Dependency analysis",(Target)(length(bs)));
+    mapProc(addDepField,bs);           /* add extra field for dependents   */
+    for (xs=bs; nonNull(xs); xs=tl(xs)) {
+        emptySubstitution();
+        depBinding(hd(xs));
+        soFar((Target)(i++));
+    }
+    bs = bscc(bs);                     /* sort to strongly connected comps */
+    mapProc(remDepField,bs);           /* remove dependency info field     */
+    done();
+    return bs;
+}
+
+static Void local addDepField(b)       /* add extra field to binding to    */
+Cell b; {                              /* hold list of dependents          */
+    snd(snd(b)) = pair(NIL,snd(snd(b)));
+}
+
+static Void local remDepField(bs)      /* remove dependency field from     */
+List bs; {                             /* list of bindings                 */
+    mapProc(remDepField1,bs);
+}
+
+static Void local remDepField1(b)      /* remove dependency field from     */
+Cell b; {                              /* single binding                   */
+    snd(snd(b)) = snd(snd(snd(b)));
+}
+
+static Void local clearScope() {       /* initialise dependency scoping    */
+    bounds   = NIL;
+    bindings = NIL;
+    depends  = NIL;
+}
+
+static Void local withinScope(bs)       /* Enter scope of bindings bs      */
+List bs; {
+    bounds   = cons(NIL,bounds);
+    bindings = cons(bs,bindings);
+    depends  = cons(NIL,depends);
+}
+
+static Void local leaveScope() {        /* Leave scope of last withinScope */
+    List bs       = hd(bindings);       /* Remove fixity info from binds   */
+    Bool toplevel = isNull(tl(bindings));
+    for (; nonNull(bs); bs=tl(bs)) {
+        Cell b = hd(bs);
+        if (isVar(fst(b))) {            /* Variable binding                */
+            Cell a = fst(snd(b));
+            if (isPair(a)) {
+                if (toplevel) {
+                    saveSyntax(fst(b),snd(a));
+                }
+                fst(snd(b)) = fst(a);
+            }
+        } else {                        /* Pattern binding                 */
+            List vs = fst(b);
+            List as = fst(snd(b));
+            while (nonNull(vs) && nonNull(as)) {
+                if (isPair(hd(as))) {
+                    if (toplevel) {
+                        saveSyntax(hd(vs),snd(hd(as)));
+                    }
+                    hd(as) = fst(hd(as));
+                }
+                vs = tl(vs);
+                as = tl(as);
+            }
+        }
+    }
     bounds   = tl(bounds);
     bindings = tl(bindings);
     depends  = tl(depends);
 }
 
+static Void local saveSyntax(v,sy)      /* Save syntax of top-level var    */
+Cell v;                                 /* in corresponding Name           */
+Cell sy; {
+    Name n = findName(textOf(v));
+    if (isNull(n) || name(n).syntax!=NO_SYNTAX) {
+        internal("saveSyntax");
+    }
+    if (nonNull(sy)) {
+        name(n).syntax = intOf(sy);
+    }
+}
+
 /* --------------------------------------------------------------------------
  * As a side effect of the dependency analysis we also make the following
  * checks:
@@ -3003,38 +4201,52 @@ static Void local leaveScope() {        /* leave scope of last withinScope */
  * - No free (i.e. unbound) variables are used in the declaration list.
  * ------------------------------------------------------------------------*/
 
-static Void local depBinding(b)         /* find dependents of binding      */
+static Void local depBinding(b)        /* find dependents of binding       */
 Cell b; {
-    Cell defpart = snd(snd(snd(b)));    /* definition part of binding      */
+    Cell defpart = snd(snd(snd(b)));   /* definition part of binding       */
 
     hd(depends) = NIL;
 
-    if (isVar(fst(b))) {                /* function-binding?               */
+    if (isVar(fst(b))) {               /* function-binding?                */
         mapProc(depAlt,defpart);
-        if (isNull(fst(snd(snd(b))))) { /* Save dep info for implicitly    */
-            fst(snd(snd(b))) = ap(IMPDEPS,hd(depends)); /* typed var binds */
+        if (isNull(fst(snd(b)))) {      /* Save dep info if no type sig    */
+            fst(snd(b)) = pair(ap(IMPDEPS,hd(depends)),NIL);
+        } else if (isNull(fst(fst(snd(b))))) {
+            fst(fst(snd(b))) = ap(IMPDEPS,hd(depends));
         }
-    } else {                            /* pattern-binding?                */
+    } else {                           /* pattern-binding?                 */
+        Int line = rhsLine(snd(defpart));
+        enterBtyvs();
+        patVars = NIL;
+        fst(defpart) = checkPat(line,fst(defpart));
         depRhs(snd(defpart));
+#if 0
+        if (nonNull(hd(btyvars))) {
+            ERRMSG(line)
+              "Sorry, no type variables are allowed in pattern binding type annotations"
+            EEND;
+        }
+#endif
+        fst(defpart) = applyBtyvs(fst(defpart));
     }
     depVal(b) = hd(depends);
 }
 
-static Void local depDefaults(c)        /* dependency analysis on defaults */
-Class c; {                              /* from class definition           */
+static Void local depDefaults(c)       /* dependency analysis on defaults  */
+Class c; {                             /* from class definition            */
     depClassBindings(cclass(c).defaults);
 }
 
-static Void local depInsts(in)          /* dependency analysis on instance */
-Inst in; {                              /* bindings                        */
+static Void local depInsts(in)         /* dependency analysis on instance  */
+Inst in; {                             /* bindings                         */
     depClassBindings(inst(in).implements);
 }
 
-static Void local depClassBindings(bs)  /* dependency analysis on list of  */
-List bs; {                              /* bindings, possibly containing   */
-    for (; nonNull(bs); bs=tl(bs)) {    /* NIL bindings ...                */
-        if (nonNull(hd(bs))) {          /* No need to add extra field for  */
-           mapProc(depAlt,snd(hd(bs))); /* dependency information ...      */
+static Void local depClassBindings(bs) /* dependency analysis on list of   */
+List bs; {                             /* bindings, possibly containing    */
+    for (; nonNull(bs); bs=tl(bs)) {   /* NIL bindings ...                 */
+        if (nonNull(hd(bs))) {         /* No need to add extra field for   */
+           mapProc(depAlt,snd(hd(bs)));/* dependency information...        */
         }
     }
 }
@@ -3055,7 +4267,7 @@ Cell r; {
         case GUARDED : mapProc(depGuard,snd(r));
                        break;
 
-        case LETREC  : fst(snd(r)) = eqnsToBindings(fst(snd(r)));
+        case LETREC  : fst(snd(r)) = eqnsToBindings(fst(snd(r)),NIL,NIL,NIL);
                        withinScope(fst(snd(r)));
                        fst(snd(r)) = dependencyAnal(fst(snd(r)));
                        hd(depends) = fst(snd(r));
@@ -3063,17 +4275,24 @@ Cell r; {
                        leaveScope();
                        break;
 
+        case RSIGN   : snd(snd(r)) = checkPatType(rhsLine(fst(snd(r))),
+                                                  "result",
+                                                  rhsExpr(fst(snd(r))),
+                                                  snd(snd(r)));
+                       depRhs(fst(snd(r)));
+                       break;
+
         default      : snd(r) = depExpr(intOf(fst(r)),snd(r));
                        break;
     }
 }
 
-static Void local depGuard(g)           /*find dependents of single guarded*/
-Cell g; {                               /* expression                      */
+static Void local depGuard(g)          /* find dependents of single guarded*/
+Cell g; {                              /* expression                       */
     depPair(intOf(fst(g)),snd(g));
 }
 
-static Cell local depExpr(line,e)       /* find dependents of expression   */
+static Cell local depExpr(line,e)      /* find dependents of expression    */
 Int  line;
 Cell e; {
     switch (whatIs(e)) {
@@ -3090,6 +4309,8 @@ Cell e; {
                               return conDefined(line,e);
                           }
 
+        case INFIX     : return depExpr(line,tidyInfix(line,snd(e)));
+
 #if TREX
         case RECSEL     : break;
 
@@ -3111,13 +4332,17 @@ Cell e; {
                           break;
 #endif
 
+#if BIGNUMS
+        case ZERONUM    :
+        case POSNUM     :
+        case NEGNUM     :
+#endif
         case NAME       :
         case TUPLE      :
         case STRCELL    :
         case CHARCELL   :
-        case INTCELL    : 
-        case BIGCELL    : 
-        case FLOATCELL  : break;
+        case FLOATCELL  :
+        case INTCELL    : break;
 
         case COND       : depTriple(line,snd(e));
                           break;
@@ -3125,7 +4350,7 @@ Cell e; {
         case FINLIST    : map1Over(depExpr,line,snd(e));
                           break;
 
-        case LETREC     : fst(snd(e)) = eqnsToBindings(fst(snd(e)));
+        case LETREC     : fst(snd(e)) = eqnsToBindings(fst(snd(e)),NIL,NIL,NIL);
                           withinScope(fst(snd(e)));
                           fst(snd(e)) = dependencyAnal(fst(snd(e)));
                           hd(depends) = fst(snd(e));
@@ -3171,7 +4396,7 @@ Cell e; {
                           EEND;
 #endif
 
-        default         : internal("in depExpr");
+        default         : internal("depExpr");
    }
    return e;
 }
@@ -3195,9 +4420,9 @@ static Void local depComp(l,e,qs)       /* find dependents of comprehension*/
 Int  l;
 Cell e;
 List qs; {
-    if (isNull(qs))
+    if (isNull(qs)) {
         fst(e) = depExpr(l,fst(e));
-    else {
+    } else {
         Cell q   = hd(qs);
         List qs1 = tl(qs);
         switch (whatIs(q)) {
@@ -3211,7 +4436,7 @@ List qs; {
                             }
                             break;
 
-            case QWHERE   : snd(q)      = eqnsToBindings(snd(q));
+            case QWHERE   : snd(q)      = eqnsToBindings(snd(q),NIL,NIL,NIL);
                             withinScope(snd(q));
                             snd(q)      = dependencyAnal(snd(q));
                             hd(depends) = snd(q);
@@ -3254,8 +4479,9 @@ Cell e; {
         }
         n = findBinding(t,hd(bindings1)); /* look for t in var bindings    */
         if (nonNull(n)) {
-           if (!cellIsMember(n,hd(depends1)))
-               hd(depends1) = cons(n,hd(depends1));
+            if (!cellIsMember(n,hd(depends1))) {
+                hd(depends1) = cons(n,hd(depends1));
+            }
            return (isVar(fst(n)) ? fst(n) : e);
         }
 
@@ -3269,27 +4495,31 @@ Cell e; {
         EEND;
     }
 
-    if (name(n).mod != thisModule) {
+#if !IGNORE_MODULES
+    if (!moduleThisScript(name(n).mod)) {
         return n;
     }
+#endif
     /* Later phases of the system cannot cope if we resolve references
      * to unprocessed objects too early.  This is the main reason that
      * we cannot cope with recursive modules at the moment.
      */
-    return n;
+    return e;
 }
 
 static Cell local depQVar(line,e)/* register occurrence of qualified variable */
 Int line;
 Cell e; {
-    Cell n = findQualName(line,e);
+    Name n = findQualName(e);
     if (isNull(n)) {                            /* check global definitions */
         ERRMSG(line) "Undefined qualified variable \"%s\"", identToStr(e)
         EEND;
     }
+#if !IGNORE_MODULES
     if (name(n).mod != currentModule) {
         return n;
     }
+#endif
     if (fst(e) == VARIDCELL) {
         e = mkVar(qtextOf(e));
     } else {
@@ -3316,7 +4546,7 @@ Bool isP; {
     if (!isP && isPair(name(c).defn)) { /* Check that banged fields defined*/
         List scs = fst(name(c).defn);   /* List of strict components       */
         Type t   = name(c).type;
-        Int  a   = name(c).arity;
+        Int  a   = userArity(c);
         List fs  = snd(snd(e));
         List ss;
         if (isPolyType(t)) {            /* Find tycon that c belongs to    */
@@ -3325,6 +4555,9 @@ Bool isP; {
         if (whatIs(t)==QUAL) {
             t = snd(snd(t));
         }
+        if (whatIs(t)==CDICTS) {
+            t = snd(snd(t));
+        }
         while (0<a--) {
             t = arg(t);
         }
@@ -3396,9 +4629,11 @@ Bool isP; {
         Name s;
 
         if (isVar(fb)) {                /* expand  var  to  var = var      */
+            h98DoesntSupport(l,"missing field bindings");
             fb = hd(fs) = pair(fb,fb);
         }
-        s = findQualName(l,fst(fb));    /* check for selector              */
+
+        s = findQualName(fst(fb));      /* check for selector              */
         if (nonNull(s) && isSfun(s)) {
             fst(fb) = s;
         } else {
@@ -3409,8 +4644,9 @@ Bool isP; {
 
         if (isNull(ss)) {               /* for first named selector        */
             List scs = name(s).defn;    /* calculate list of constructors  */
-            for (; nonNull(scs); scs=tl(scs))
+            for (; nonNull(scs); scs=tl(scs)) {
                 cs = cons(fst(hd(scs)),cs);
+            }
             ss = singleton(s);          /* initialize selector list        */
         } else {                        /* for subsequent selectors        */
             List ds = cs;               /* intersect constructor lists     */
@@ -3456,6 +4692,7 @@ Cell e; {                               /* to make construction and update */
     List exts = NIL;                    /* more efficient.                 */
     Cell r    = e;
 
+    h98DoesntSupport(line,"extensible records");
     do {                                /* build up list of extensions     */
         Text   t    = extText(fun(fun(r)));
         String s    = textToStr(t);
@@ -3484,6 +4721,7 @@ Cell e; {                               /* to make construction and update */
 }
 #endif
 
+
 /* --------------------------------------------------------------------------
  * Several parts of this program require an algorithm for sorting a list
  * of values (with some added dependency information) into a list of strongly
@@ -3496,7 +4734,7 @@ Cell e; {                               /* to make construction and update */
 #define  SCC2            tcscc          /* make scc algorithm for Tycons   */
 #define  LOWLINK         tclowlink
 #define  DEPENDS(c)      (isTycon(c) ? tycon(c).kind : cclass(c).kinds)
-#define  SETDEPENDS(c,v) if(isTycon(c))tycon(c).kind=v;else cclass(c).kinds=v
+#define  SETDEPENDS(c,v) if(isTycon(c)) tycon(c).kind=v; else cclass(c).kinds=v
 #include "scc.c"
 #undef   SETDEPENDS
 #undef   DEPENDS
@@ -3527,79 +4765,79 @@ Void checkExp() {                       /* Top level static check on Expr  */
 }
 
 Void checkDefns() {                     /* Top level static analysis       */
+#if !IGNORE_MODULES
+    Module thisModule = lastModule();
+#endif
     staticAnalysis(RESET);
-    thisModule = lastModule();
+
+#if !IGNORE_MODULES
     setCurrModule(thisModule);
 
     /* Resolve module references */
     mapProc(checkQualImport,  module(thisModule).qualImports);
     mapProc(checkUnqualImport,unqualImports);
-
-    /* Add implicit import declarations - if Prelude has been loaded */
-    {
-        Module modulePrelude = findModule(findText("Prelude"));
-        if (nonNull(modulePrelude)) {
-            /* Add "import Prelude" if there`s no explicit import */
-            if (thisModule != modulePrelude
-                && isNull(cellAssoc(modulePrelude,unqualImports))
-                && isNull(cellRevAssoc(modulePrelude,module(thisModule).qualImports))) {
-                unqualImports = cons(pair(modulePrelude,DOTDOT),unqualImports);
-            }
-            /* Add "import qualified Prelude" */
-            module(thisModule).qualImports=cons(pair(conPrelude,modulePrelude),
-                                                module(thisModule).qualImports);
-        }
+    /* Add "import Prelude" if there`s no explicit import */
+    if (thisModule!=modulePrelude
+        && isNull(cellAssoc(modulePrelude,unqualImports))
+        && isNull(cellRevAssoc(modulePrelude,module(thisModule).qualImports))) {
+        unqualImports = cons(pair(modulePrelude,DOTDOT),unqualImports);
+    } else {
+        /* Every module (including the Prelude) implicitly contains 
+         * "import qualified Prelude" 
+         */
+        module(thisModule).qualImports=cons(pair(mkCon(textPrelude),modulePrelude),
+                                            module(thisModule).qualImports);
     }
-    map1Proc(checkImportList, thisModule, unqualImports);
+    mapProc(checkImportList, unqualImports);
+#endif
 
     linkPreludeTC();                    /* Get prelude tycons and classes  */
-    setCurrModule(thisModule);
-
     mapProc(checkTyconDefn,tyconDefns); /* validate tycon definitions      */
     checkSynonyms(tyconDefns);          /* check synonym definitions       */
     mapProc(checkClassDefn,classDefns); /* process class definitions       */
     mapProc(kindTCGroup,tcscc(tyconDefns,classDefns)); /* attach kinds     */
     mapProc(addMembers,classDefns);     /* add definitions for member funs */
     mapProc(visitClass,classDefns);     /* check class hierarchy           */
+    linkPreludeCM();                    /* Get prelude cfuns and mfuns     */
 
+    /* ToDo: reinstate?
+       mapOver(checkPrimDefn,primDefns); */  /* check primitive declarations    */
+    
     instDefns = rev(instDefns);         /* process instance definitions    */
     mapProc(checkInstDefn,instDefns);
 
-    linkPreludeCM();                    /* Get prelude cfuns and mfuns     */
     setCurrModule(thisModule);
-
     mapProc(addDerivImp,derivedInsts);  /* Add impls for derived instances */
     deriveContexts(derivedInsts);       /* Calculate derived inst contexts */
 #if EVAL_INSTANCES
     deriveEval(tyconDefns);             /* Derive instances of Eval        */
 #endif
-    tyconDefns = NIL;
     instDefns  = appendOnto(instDefns,derivedInsts);
-#if EVAL_INSTANCES
-    instDefns  = appendOnto(evalInsts,instDefns); /* ADR addition */
-#endif
     checkDefaultDefns();                /* validate default definitions    */
 
     mapProc(addRSsigdecls,typeInDefns); /* add sigdecls for RESTRICTSYN    */
+#if 0 /* from STG */
     valDefns = eqnsToBindings(valDefns);/* translate value equations       */
     map1Proc(opDefined,valDefns,opDefns);/*check all declared ops bound    */
+#else /* from 98 */
+    valDefns   = eqnsToBindings(valDefns,tyconDefns,classDefns, NIL/*primDefns*/ );
+    tyconDefns = NIL;
+    /* primDefns  = NIL; */
+#endif
     mapProc(allNoPrevDef,valDefns);     /* check against previous defns    */
 
-    linkPreludeNames();         /* Get prelude names           */
-    setCurrModule(thisModule);
-
-    mapProc(checkForeignImport,foreignImports);        /* check foreign imports   */
-    mapProc(checkForeignExport,foreignExports);        /* check foreign exports   */
+    mapProc(checkForeignImport,foreignImports); /* check foreign imports   */
+    mapProc(checkForeignExport,foreignExports); /* check foreign exports   */
     foreignImports = NIL;
     foreignExports = NIL;
 
+#if !IGNORE_MODULES
     /* Every top-level name has now been created - so we can build the     */
     /* export list.  Note that this has to happen before dependency        */
     /* analysis so that references to Prelude.foo will be resolved         */
     /* when compiling the prelude.                                         */
-    /* Note too that this is just a little too late to catch the use of    */
-    /* qualified tycons (for the current module) in data declarations      */
-    module(thisModule).exports = checkExports(thisModule,module(thisModule).exports);
+    module(thisModule).exports = checkExports(module(thisModule).exports);
+#endif
 
     mapProc(checkTypeIn,typeInDefns);   /* check restricted synonym defns  */
 
@@ -3627,21 +4865,8 @@ Pair pr; {
     }
 }
 
-static Void local opDefined(bs,op)      /* check that op bound in bs       */
-List bs;                                /* (or in current module for       */
-Cell op; {                              /* constructor functions etc...)   */
-    Name n;
-
-    if (isNull(findBinding(textOf(op),bs))
-           && (isNull(n=findName(textOf(op))) || name(n).mod != thisModule)) {
-        ERRMSG(0) "No top level definition for operator symbol \"%s\"",
-                  textToStr(textOf(op))
-        EEND;
-    }
-}
-
-static Void local allNoPrevDef(b)       /* ensure no previous bindings for */
-Cell b; {                               /* variables in new binding        */
+static Void local allNoPrevDef(b)        /* ensure no previous bindings for*/
+Cell b; {                                /* variables in new binding       */
     if (isVar(fst(b))) {
         noPrevDef(rhsLine(snd(hd(snd(snd(b))))),fst(b));
     } else {
@@ -3650,37 +4875,46 @@ Cell b; {                               /* variables in new binding        */
     }
 }
 
-static Void local noPrevDef(line,v)     /* ensure no previous binding for  */
-Int  line;                              /* new variable                    */
+static Void local noPrevDef(line,v)      /* ensure no previous binding for */
+Int  line;                               /* new variable                   */
 Cell v; {
     Name n = findName(textOf(v));
 
     if (isNull(n)) {
-        n            = newName(textOf(v));
+        n            = newName(textOf(v),NIL);
         name(n).defn = PREDEFINED;
     } else if (name(n).defn!=PREDEFINED) {
-        ERRMSG(line) "Attempt to redefine variable \"%s\"",
-                     textToStr(name(n).text)
-        EEND;
+        duplicateError(line,name(n).mod,name(n).text,"variable");
     }
     name(n).line = line;
 }
 
-static Void local duplicateError(line,mod,t,kind)/* report duplicate defn */
+#if IGNORE_MODULES
+static Void local duplicateErrorAux(line,t,kind) /* report duplicate defn */
+Int    line;
+Text   t;
+String kind; {
+    ERRMSG(line) "Definition of %s \"%s\" clashes with import", kind,
+                 textToStr(t)
+    EEND;
+}
+#else /* !IGNORE_MODULES */
+static Void local duplicateErrorAux(line,mod,t,kind)/* report duplicate defn */
 Int    line;
 Module mod;
 Text   t;
 String kind; {
     if (mod == currentModule) {
         ERRMSG(line) "Repeated definition for %s \"%s\"", kind, 
-            textToStr(t)
+                     textToStr(t)
         EEND;
     } else {
         ERRMSG(line) "Definition of %s \"%s\" clashes with import", kind,
-            textToStr(t)
+                     textToStr(t)
         EEND;
     }
 }
+#endif /* !IGNORE_MODULES */
 
 static Void local checkTypeIn(cvs)      /* Check that vars in restricted   */
 Pair cvs; {                             /* synonym are defined             */
@@ -3698,24 +4932,100 @@ Pair cvs; {                             /* synonym are defined             */
 }
 
 /* --------------------------------------------------------------------------
+ * Haskell 98 compatibility tests:
+ * ------------------------------------------------------------------------*/
+
+Bool h98Pred(allowArgs,pi)              /* Check syntax of Hask98 predicate*/
+Bool allowArgs;
+Cell pi; {
+    return isClass(getHead(pi)) && argCount==1 &&
+           isOffset(getHead(arg(pi))) && (argCount==0 || allowArgs);
+}
+
+Cell h98Context(allowArgs,ps)           /* Check syntax of Hask98 context  */
+Bool allowArgs;
+List ps; {
+    for (; nonNull(ps); ps=tl(ps)) {
+        if (!h98Pred(allowArgs,hd(ps))) {
+            return hd(ps);
+        }
+    }
+    return NIL;
+}
+
+Void h98CheckCtxt(line,wh,allowArgs,ps,in)
+Int    line;                            /* Report illegal context/predicate*/
+String wh;
+Bool   allowArgs;
+List   ps;
+Inst   in; {
+    if (haskell98) {
+        Cell pi = h98Context(allowArgs,ps);
+        if (nonNull(pi)) {
+            ERRMSG(line) "Illegal Haskell 98 class constraint in %s",wh ETHEN
+            if (nonNull(in)) {
+                ERRTEXT  "\n*** Instance   : " ETHEN ERRPRED(inst(in).head);
+            }
+            ERRTEXT      "\n*** Constraint : " ETHEN ERRPRED(pi);
+            if (nonNull(ps) && nonNull(tl(ps))) {
+                ERRTEXT  "\n*** Context    : " ETHEN ERRCONTEXT(ps);
+            }
+            ERRTEXT      "\n"
+            EEND;
+        }
+    }
+}
+
+Void h98CheckType(line,wh,e,t)          /* Check for Haskell 98 type       */
+Int    line;
+String wh;
+Cell   e;
+Type   t; {
+    if (haskell98) {
+        Type ty = t;
+        if (isPolyType(t))
+            t = monotypeOf(t);
+        if (whatIs(t)==QUAL) {
+            Cell pi = h98Context(TRUE,fst(snd(t)));
+            if (nonNull(pi)) {
+                ERRMSG(line) "Illegal Haskell 98 class constraint in %s",wh
+                ETHEN
+                ERRTEXT  "\n*** Expression : " ETHEN ERREXPR(e);
+                ERRTEXT  "\n*** Type       : " ETHEN ERRTYPE(ty);
+                ERRTEXT  "\n"
+                EEND;
+            }
+        }
+    }
+}
+
+Void h98DoesntSupport(line,wh)          /* Report feature missing in H98   */
+Int    line;
+String wh; {
+    if (haskell98) {
+        ERRMSG(line) "Haskell 98 does not support %s", wh
+        EEND;
+    }
+}
+
+/* --------------------------------------------------------------------------
  * Static Analysis control:
  * ------------------------------------------------------------------------*/
 
 Void staticAnalysis(what)
 Int what; {
     switch (what) {
-        case RESET   : daSccs       = NIL;
+        case RESET   : cfunSfuns    = NIL;
+                       daSccs       = NIL;
                        patVars      = NIL;
                        bounds       = NIL;
                        bindings     = NIL;
                        depends      = NIL;
                        tcDeps       = NIL;
                        derivedInsts = NIL;
-#if EVAL_INSTANCES
-                       evalInsts    = NIL;
-#endif
+                       diVars       = NIL;
+                       diNum        = 0;
                        unkindTypes  = NIL;
-                       thisModule   = 0;
                        break;
 
         case MARK    : mark(daSccs);
@@ -3725,9 +5035,8 @@ Int what; {
                        mark(depends);
                        mark(tcDeps);
                        mark(derivedInsts);
-#if EVAL_INSTANCES
-                       mark(evalInsts);
-#endif
+                       mark(diVars);
+                       mark(cfunSfuns);
                        mark(unkindTypes);
 #if TREX
                        mark(extKind);
index 6b0029f..032e014 100644 (file)
@@ -1,4 +1,4 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * STG syntax
  *
@@ -7,15 +7,15 @@
  * Hugs version 1.4, December 1997
  *
  * $RCSfile: stg.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:38 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:39 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
 #include "storage.h"
+#include "backend.h"
 #include "connect.h"
 #include "errors.h"
-#include "stg.h"
 #include "link.h"      /* for nameTrue/False     */
 #include "Assembler.h" /* for AsmRep and primops */
 
@@ -79,7 +79,7 @@ StgExpr makeStgLambda( List args, StgExpr body )
         return body;
     } else {
         if (whatIs(body) == LAMBDA) {
-            return mkStgLambda(dupListOnto(args,stgLambdaArgs(body)),
+            return mkStgLambda(dupOnto(args,stgLambdaArgs(body)),
                                stgLambdaBody(body));
         } else {
             return mkStgLambda(args,body);
@@ -150,3 +150,495 @@ StgVar mkStgVar( StgRhs rhs, Cell info )
 }
 
 /*-------------------------------------------------------------------------*/
+
+/* --------------------------------------------------------------------------
+ * STG pretty printer
+ *
+ * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
+ * All rights reserved. See NOTICE for details and conditions of use etc...
+ * Hugs version 1.4, December 1997
+ *
+ * $RCSfile: stg.c,v $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:39 $
+ * ------------------------------------------------------------------------*/
+
+/* --------------------------------------------------------------------------
+ * Local functions
+ * ------------------------------------------------------------------------*/
+
+static Void local pIndent        Args((Int));
+static Void local unlexVar       Args((Text));
+static Void local unlexCharConst Args((Cell));
+static Void local unlexStrConst  Args((Text));
+
+static Void local putStgVar       Args((StgVar));
+static Void local putStgVars      Args((List));
+static Void local putStgAtom      Args((StgAtom a));
+static Void local putStgAtoms     Args((List as));
+static Void local putStgBinds     Args((List));
+static Void local putStgExpr      Args((StgExpr));
+static Void local putStgRhs       Args((StgRhs));
+static Void local putStgPat       Args((StgPat));
+static Void local putStgPrimPat   Args((StgPrimPat));
+
+/* --------------------------------------------------------------------------
+ * Basic output routines:
+ * ------------------------------------------------------------------------*/
+
+static FILE *outputStream;             /* current output stream            */
+static Int  outColumn = 0;             /* current output column number     */
+                                           
+static Void local putChr( Int c );
+static Void local putStr( String s );
+static Void local putInt( Int n );
+static Void local putPtr( Ptr p );
+                                           
+static Void local putChr(c)            /* print single character           */
+Int c; {                                       
+    Putc(c,outputStream);                              
+    outColumn++;                                   
+}                                          
+                                           
+static Void local putStr(s)            /* print string                     */
+String s; {                                    
+    for (; *s; s++) {                                  
+        Putc(*s,outputStream);                             
+        outColumn++;                                   
+    }                                          
+}                                          
+                                           
+static Void local putInt(n)            /* print integer                    */
+Int n; {
+    static char intBuf[16];
+    sprintf(intBuf,"%d",n);
+    putStr(intBuf);
+}
+
+static Void local putPtr(p)            /* print pointer                    */
+Ptr p; {
+    static char intBuf[16];
+    sprintf(intBuf,"%p",p);
+    putStr(intBuf);
+}
+
+/* --------------------------------------------------------------------------
+ * Indentation and showing names/constants
+ * ------------------------------------------------------------------------*/
+
+static Void local pIndent(n)           /* indent to particular position    */
+Int n; {
+    outColumn = n;
+    while (0<n--) {
+        Putc(' ',outputStream);
+    }
+}
+
+static Void local unlexVar(t)          /* print text as a variable name    */
+Text t; {                              /* operator symbols must be enclosed*/
+    String s = textToStr(t);           /* in parentheses... except [] ...  */
+
+    if ((isascii(s[0]) && isalpha(s[0])) || s[0]=='_' || s[0]=='[' || s[0]=='(')
+        putStr(s);
+    else {
+        putChr('(');
+        putStr(s);
+        putChr(')');
+    }
+}
+
+static Void local unlexCharConst(c)
+Cell c; {
+    putChr('\'');
+    putStr(unlexChar(c,'\''));
+    putChr('\'');
+}
+
+static Void local unlexStrConst(t)
+Text t; {
+    String s            = textToStr(t);
+    static Char SO      = 14;          /* ASCII code for '\SO'             */
+    Bool   lastWasSO    = FALSE;
+    Bool   lastWasDigit = FALSE;
+    Bool   lastWasEsc   = FALSE;
+
+    putChr('\"');
+    for (; *s; s++) {
+        String ch = unlexChar(*s,'\"');
+        Char   c  = ' ';
+
+        if ((lastWasSO && *ch=='H') ||
+                (lastWasEsc && lastWasDigit && isascii(*ch) && isdigit(*ch)))
+            putStr("\\&");
+
+        lastWasEsc   = (*ch=='\\');
+        lastWasSO    = (*s==SO);
+        for (; *ch; c = *ch++)
+            putChr(*ch);
+        lastWasDigit = (isascii(c) && isdigit(c));
+    }
+    putChr('\"');
+}
+
+/* --------------------------------------------------------------------------
+ * Pretty printer for stg code:
+ * ------------------------------------------------------------------------*/
+
+static Void putStgAlts    ( Int left, List alts );
+static Void putStgPrimAlt ( Int left, List vs, StgExpr body );
+
+static Void local putStgVar(StgVar v) 
+{
+    if (isName(v)) {
+        unlexVar(name(v).text);
+    } else {
+        putStr("id");
+        putInt(-v);
+    }
+}
+
+static Void local putStgVars( List vs )
+{
+    for(; nonNull(vs); vs=tl(vs)) {
+        putStgVar(hd(vs));
+        putChr(' ');
+    }
+}
+
+static Void local putStgAtom( StgAtom a )
+{
+    switch (whatIs(a)) {
+    case STGVAR: 
+    case NAME: 
+            putStgVar(a);
+            break;
+    case CHARCELL: 
+            unlexCharConst(charOf(a));
+            putChr('#');
+            break;
+    case INTCELL: 
+            putInt(intOf(a));
+            putChr('#');
+            break;
+    case BIGCELL: 
+            putStr(bignumToString(a));
+            putChr('#');
+            break;
+    case FLOATCELL: 
+            putStr(floatToString(a));
+            putChr('#');
+            break;
+    case STRCELL: 
+            unlexStrConst(textOf(a));
+            break;
+    case PTRCELL: 
+            putPtr(ptrOf(a));
+            putChr('#');
+            break;
+    default: 
+            fprintf(stderr,"\nYoiks: "); printExp(stderr,a);
+            internal("putStgAtom");
+    }
+}
+
+Void putStgAtoms( List as )
+{
+    putChr('{');
+    while (nonNull(as)) {
+        putStgAtom(hd(as));
+        as=tl(as);
+        if (nonNull(as)) {
+            putChr(',');
+        }
+    }
+    putChr('}');
+}
+
+Void putStgPat( StgPat pat )
+{
+    putStgVar(pat);
+    if (nonNull(stgVarBody(pat))) {
+        StgDiscr d  = stgConCon(stgVarBody(pat));
+        List     vs = stgConArgs(stgVarBody(pat));
+        putChr('@');
+        switch (whatIs(d)) {
+        case NAME:
+            { 
+                unlexVar(name(d).text);
+                for (; nonNull(vs); vs=tl(vs)) {
+                    putChr(' ');
+                    putStgVar(hd(vs));
+                }
+                break;
+            }
+        case TUPLE: 
+            { 
+                putChr('(');
+                putStgVar(hd(vs));
+                vs=tl(vs);
+                while (nonNull(vs)) {
+                    putChr(',');
+                    putStgVar(hd(vs));
+                    vs=tl(vs);
+                }
+                putChr(')');
+                break;
+            }
+        default: 
+                fprintf(stderr,"\nYoiks: "); printExp(stderr,d);
+                internal("putStgPat");
+        }
+    }
+}
+
+Void putStgPrimPat( StgPrimPat pat )  
+{
+    putStgVar(pat);
+    if (nonNull(stgVarBody(pat))) {
+        StgExpr d  = stgVarBody(pat);
+        putChr('@');
+        switch (whatIs(d)) {
+        case INTCELL:
+            {
+                putInt(intOf(d));
+                putChr('#');
+                break;
+            }
+        default: 
+                fprintf(stderr,"\nYoiks: "); printExp(stderr,d);
+                internal("putStgPrimPat");
+        }
+    }
+    putChr(' ');
+}
+
+Void putStgBinds(binds)        /* pretty print locals           */
+List binds; {
+    Int left = outColumn;
+
+    putStr("let { ");
+    while (nonNull(binds)) {
+        Cell bind = hd(binds);
+        putStgVar(bind);
+        putStr(" = ");
+        putStgRhs(stgVarBody(bind));
+        putStr("\n");
+        binds = tl(binds);
+        if (nonNull(binds))
+            pIndent(left+6);
+    }
+    pIndent(left);
+    putStr("} in  ");
+}
+
+static Void putStgAlts( Int left, List alts )
+{
+    if (length(alts) == 1) {
+        StgCaseAlt alt = hd(alts);
+        putStr("{ ");
+        putStgPat(stgCaseAltPat(alt));
+        putStr(" ->\n");
+        pIndent(left);
+        putStgExpr(stgCaseAltBody(alt));
+        putStr("}");
+    } else {
+        putStr("{\n");
+        for (; nonNull(alts); alts=tl(alts)) {
+            StgCaseAlt alt = hd(alts);
+            pIndent(left+2);
+            putStgPat(stgCaseAltPat(alt));
+            putStr(" -> ");
+            putStgExpr(stgCaseAltBody(alt));
+            putStr("\n");
+        }
+        pIndent(left);
+        putStr("}\n");
+    }
+}
+
+static Void putStgPrimAlts( Int left, List alts )
+{
+    if (length(alts) == 1) {
+        StgPrimAlt alt = hd(alts);
+        putStr("{ ");
+        mapProc(putStgPrimPat,stgPrimAltPats(alt));
+        putStr(" ->\n");
+        pIndent(left);
+        putStgExpr(stgPrimAltBody(alt));
+        putStr("}");
+    } else {
+        putStr("{\n");
+        for (; nonNull(alts); alts=tl(alts)) {
+            StgPrimAlt alt = hd(alts);
+            pIndent(left+2);
+            mapProc(putStgPrimPat,stgPrimAltPats(alt));
+            putStr(" -> ");
+            putStgExpr(stgPrimAltBody(alt));
+            putStr("\n");
+        }
+        pIndent(left);
+        putStr("}\n");
+    }
+}
+
+Void putStgExpr( StgExpr e )                        /* pretty print expr */
+{
+    switch (whatIs(e)) {
+    case LETREC: 
+            putStgBinds(stgLetBinds(e));
+            putStgExpr(stgLetBody(e));
+            break;
+    case LAMBDA:
+        {   
+            Int left = outColumn;
+            putStr("\\ ");
+            putStgVars(stgLambdaArgs(e));
+            putStr("->\n");
+            pIndent(left+2);
+            putStgExpr(stgLambdaBody(e));
+            break;
+        }
+    case CASE: 
+        {
+            Int left = outColumn;
+            putStr("case ");
+            putStgExpr(stgCaseScrut(e));
+            putStr(" of ");
+            putStgAlts(left,stgCaseAlts(e));
+            break;
+        }
+    case PRIMCASE:
+        { 
+            Int  left = outColumn;
+            putStr("case# ");
+            putStgExpr(stgPrimCaseScrut(e));
+            putStr(" of ");
+            putStgPrimAlts(left,stgPrimCaseAlts(e));
+            break;
+        }
+    case STGPRIM: 
+        {
+            Cell op = stgPrimOp(e);
+            unlexVar(name(op).text);
+            putStgAtoms(stgPrimArgs(e));
+            break;
+        }
+    case STGAPP: 
+            putStgVar(stgAppFun(e));
+            putStgAtoms(stgAppArgs(e));
+            break;
+    case STGVAR: 
+    case NAME: 
+            putStgVar(e);
+            break;
+    default: 
+            fprintf(stderr,"\nYoiks: "); printExp(stderr,e);
+            internal("putStgExpr");
+    }
+}
+
+Void putStgRhs( StgRhs e )            /* print lifted definition         */
+{
+    switch (whatIs(e)) {
+    case STGCON:
+        {
+            Name   con  = stgConCon(e);
+            if (isTuple(con)) {
+                putStr("Tuple");
+                putInt(tupleOf(con));
+            } else {
+                unlexVar(name(con).text);
+            }
+            putStgAtoms(stgConArgs(e));
+            break;
+        }
+    default: 
+            putStgExpr(e);
+            break;
+    }
+}
+
+static void beginStgPP( FILE* fp );
+static void endStgPP( FILE* fp );
+
+static void beginStgPP( FILE* fp )
+{
+    outputStream = fp;
+    putChr('\n');
+    outColumn = 0;
+}
+
+static void endStgPP( FILE* fp )
+{
+    fflush(fp);
+}
+
+Void printStg(fp,b)              /* Pretty print sc defn on fp      */
+FILE  *fp;
+StgVar b; 
+{
+    beginStgPP(fp);
+    putStgVar(b);
+    putStr(" = ");
+    putStgRhs(stgVarBody(b));
+    putStr("\n");
+    endStgPP(fp);
+}
+
+#if DEBUG_PRINTER
+Void ppStg( StgVar v )
+{
+    if (debugCode) {
+        printStg(stdout,v);
+    }
+}
+
+Void ppStgExpr( StgExpr e )
+{
+    if (debugCode) {
+        beginStgPP(stdout);
+        putStgExpr(e);
+        endStgPP(stdout);
+    }
+}
+
+Void ppStgRhs( StgRhs rhs )
+{
+    if (debugCode) {
+        beginStgPP(stdout);
+        putStgRhs(rhs);
+        endStgPP(stdout);
+    }
+}
+
+Void ppStgAlts( List alts )
+{
+    if (debugCode) {
+        beginStgPP(stdout);
+        putStgAlts(0,alts);
+        endStgPP(stdout);
+    }
+}
+
+extern Void ppStgPrimAlts( List alts )
+{
+    if (debugCode) {
+        beginStgPP(stdout);
+        putStgPrimAlts(0,alts);
+        endStgPP(stdout);
+    }
+}
+
+extern Void ppStgVars( List vs )
+{
+    if (debugCode) {
+        beginStgPP(stdout);
+        printf("Vars: ");
+        putStgVars(vs);
+        printf("\n");
+        endStgPP(stdout);
+    }
+}
+#endif
+
+/*-------------------------------------------------------------------------*/
index ccf0512..7b3d978 100644 (file)
@@ -1,4 +1,4 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Substitute variables in an expression
  *
@@ -7,17 +7,15 @@
  * Hugs version 1.4, December 1997
  *
  * $RCSfile: stgSubst.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:40 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:40 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
 #include "storage.h"
+#include "backend.h"
 #include "connect.h"
 #include "errors.h"
-#include "stg.h"
-
-#include "stgSubst.h"
 
 /* --------------------------------------------------------------------------
  * Local function prototypes:
index e88c53e..4f84aa1 100644 (file)
@@ -1,26 +1,24 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Primitives for manipulating global data structures
  *
- * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
- * All rights reserved. See NOTICE for details and conditions of use etc...
- * Hugs version 1.4, December 1997
+ * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
+ * Haskell Group 1994-99, and is distributed as Open Source software
+ * under the Artistic License; see the file "Artistic" that is included
+ * in the distribution for details.
  *
  * $RCSfile: storage.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:41 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:40 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
 #include "storage.h"
+#include "backend.h"
 #include "connect.h"
-#include "charset.h"
 #include "errors.h"
-#include "link.h"    /* for nameCons         */
 #include <setjmp.h>
 
-#include "machdep.h" /* gc-related functions */
-
 /*#define DEBUG_SHOWUSE*/
 
 /* --------------------------------------------------------------------------
@@ -29,7 +27,9 @@
 
 static Int  local hash                  Args((String));
 static Int  local saveText              Args((Text));
+#if !IGNORE_MODULES
 static Module local findQualifier       Args((Text));
+#endif
 static Void local hashTycon             Args((Tycon));
 static List local insertTycon           Args((Tycon,List));
 static Void local hashName              Args((Name));
@@ -39,11 +39,21 @@ static Bool local stringMatch           Args((String,String));
 static Bool local typeInvolves          Args((Type,Type));
 static Cell local markCell              Args((Cell));
 static Void local markSnd               Args((Cell));
+static Cell local indirectChain         Args((Cell));
+static Bool local isMarked              Args((Cell));
 static Cell local lowLevelLastIn        Args((Cell));
 static Cell local lowLevelLastOut       Args((Cell));
-static Module local moduleOfScript      Args((Script));
-static Script local scriptThisFile      Args((Text));
-
+/* from STG */
+       Module local moduleOfScript      Args((Script));
+       Script local scriptThisFile      Args((Text));
+/* from 98 */
+#if IO_HANDLES
+static Void local freeHandle            Args((Int));
+#endif
+#if GC_STABLEPTRS
+static Void local resetStablePtrs       Args((Void));
+#endif
+/* end */
 
 /* --------------------------------------------------------------------------
  * Text storage:
@@ -95,34 +105,33 @@ Text t; {
 
 String identToStr(v) /*find string corresp to given ident or qualified name*/
 Cell v; {
-    static char newVar[33];
-
-    assert(isPair(v));
-    switch (fst(v)) {
-        case VARIDCELL  :
-        case VAROPCELL  : 
-        case CONIDCELL  :
-        case CONOPCELL  : return text+textOf(v);
-
-        case QUALIDENT  : sprintf(newVar,"%s.%s",
-                                  text+qmodOf(v),text+qtextOf(v));
-                          return newVar;
+    if (!isPair(v)) {
+        internal("identToStr");
     }
-    internal("identToStr 2");
-}
-
-Syntax identSyntax(v)           /* find syntax of ident or qualified ident */
-Cell v; {
-    assert(isPair(v));
     switch (fst(v)) {
         case VARIDCELL  :
         case VAROPCELL  : 
         case CONIDCELL  :
-        case CONOPCELL  : return syntaxOf(textOf(v));
+        case CONOPCELL  : return text+textOf(v);
 
-        case QUALIDENT  : return syntaxOf(qtextOf(v));
-    }
-    internal("identSyntax 2");
+        case QUALIDENT  : {   Text pos = textHw;
+                              Text t   = qmodOf(v);
+                              while (pos+1 < savedText && text[t]!=0) {
+                                  text[pos++] = text[t++];
+                              }
+                              if (pos+1 < savedText) {
+                                  text[pos++] = '.';
+                              }
+                              t = qtextOf(v);
+                              while (pos+1 < savedText && text[t]!=0) {
+                                  text[pos++] = text[t++];
+                              }
+                              text[pos] = '\0';
+                              return text+textHw;
+                          }
+    }
+    internal("identToStr2");
+    assert(0); return 0; /* NOTREACHED */
 }
 
 Text inventText()     {                 /* return new unused variable name */
@@ -210,61 +219,6 @@ Text t; {                               /* at top of text table            */
     return savedText;
 }
 
-/* --------------------------------------------------------------------------
- * Syntax storage:
- *
- * Operator declarations are stored in a table which associates Text values
- * with Syntax values.
- * ------------------------------------------------------------------------*/
-
-static Int syntaxHw;                   /* next unused syntax table entry   */
-static struct strSyntax {              /* table of Text <-> Syntax values  */
-    Text   text;
-    Syntax syntax;
-} DEFTABLE(tabSyntax,NUM_SYNTAX);
-
-Syntax defaultSyntax(t)                /* Find default syntax of var named */
-Text t; {                              /* by t ...                         */
-    String s = textToStr(t);
-    return isIn(s[0],SYMBOL) ? DEF_OPSYNTAX : APPLIC;
-}
-
-Syntax syntaxOf(t)                     /* look up syntax of operator symbol*/
-Text t; {
-    int i;
-
-    for (i=0; i<syntaxHw; ++i)
-        if (tabSyntax[i].text==t)
-            return tabSyntax[i].syntax;
-    return defaultSyntax(t);
-}
-
-Void addSyntax(line,t,sy)              /* add (t,sy) to syntax table       */
-Int    line;
-Text   t;
-Syntax sy; {
-    int i;
-
-    for (i=0; i<syntaxHw; ++i)
-        if (tabSyntax[i].text==t) {
-            /* There's no problem with multiple identical fixity declarations.
-             * - but note that it's not allowed by the Haskell report.  ADR
-             */
-            if (tabSyntax[i].syntax == sy) return;
-            ERRMSG(line) "Attempt to redefine syntax of operator \"%s\"",
-                         textToStr(t)
-            EEND;
-        }
-
-    if (syntaxHw>=NUM_SYNTAX) {
-        ERRMSG(line) "Too many fixity declarations"
-        EEND;
-    }
-
-    tabSyntax[syntaxHw].text   = t;
-    tabSyntax[syntaxHw].syntax = sy;
-    syntaxHw++;
-}
 
 /* --------------------------------------------------------------------------
  * Ext storage:
@@ -324,10 +278,10 @@ Text t; {
     tycon(tyconHw).kind          = NIL;
     tycon(tyconHw).defn          = NIL;
     tycon(tyconHw).what          = NIL;
-    tycon(tyconHw).conToTag      = NIL;
-    tycon(tyconHw).tagToCon      = NIL;
+#if !IGNORE_MODULES
     tycon(tyconHw).mod           = currentModule;
     module(currentModule).tycons = cons(tyconHw,module(currentModule).tycons);
+#endif
     tycon(tyconHw).nextTyconHash = tyconHash[h];
     tyconHash[h]                 = tyconHw;
 
@@ -348,7 +302,9 @@ Tycon tc; {
     Tycon oldtc = findTycon(tycon(tc).text);
     if (isNull(oldtc)) {
         hashTycon(tc);
+#if !IGNORE_MODULES
         module(currentModule).tycons=cons(tc,module(currentModule).tycons);
+#endif
         return tc;
     } else
         return oldtc;
@@ -364,41 +320,38 @@ Tycon tc; {
 
 Tycon findQualTycon(id) /*locate (possibly qualified) Tycon in tycon table */
 Cell id; {
-    assert(isPair(id));
+    if (!isPair(id)) internal("findQualTycon");
     switch (fst(id)) {
         case CONIDCELL :
         case CONOPCELL :
             return findTycon(textOf(id));
         case QUALIDENT : {
+#if IGNORE_MODULES
+            return findTycon(qtextOf(id));
+#else /* !IGNORE_MODULES */
             Text   t  = qtextOf(id);
             Module m  = findQualifier(qmodOf(id));
             List   es = NIL;
-            if (isNull(m)) 
-                return NIL;
-            if (m==currentModule) {
-                /* The Haskell report (rightly) forbids this.
-                 * We added it to let the Prelude refer to itself
-                 * without having to import itself.
-                 */
-                return findTycon(t);
-            }
+            if (isNull(m)) return NIL;
             for(es=module(m).exports; nonNull(es); es=tl(es)) {
                 Cell e = hd(es);
                 if (isPair(e) && isTycon(fst(e)) && tycon(fst(e)).text==t) 
                     return fst(e);
             }
             return NIL;
+#endif /* !IGNORE_MODULES */
         }
         default : internal("findQualTycon2");
     }
+    assert(0); return 0; /* NOTREACHED */
 }
 
 Tycon addPrimTycon(t,kind,ar,what,defn) /* add new primitive type constr   */
-Text   t;
-Kind   kind;
-Int    ar;
-Cell   what;
-Cell   defn; {
+Text t;
+Kind kind;
+Int  ar;
+Cell what;
+Cell defn; {
     Tycon tc        = newTycon(t);
     tycon(tc).line  = 0;
     tycon(tc).kind  = kind;
@@ -455,18 +408,23 @@ List   ts; {                            /* Null pattern matches every tycon*/
 
 #define NAMEHSZ  256                            /* Size of Name hash table */
 #define nHash(x) ((x)%NAMEHSZ)                  /* hash fn :: Text->Int    */
-/*static*/Name   nameHw;                      /* next unused name        */
+static  Name     nameHw;                        /* next unused name        */
 static  Name     DEFTABLE(nameHash,NAMEHSZ);    /* Hash table storage      */
 struct  strName  DEFTABLE(tabName,NUM_NAME);    /* Name table storage      */
 
-Name newName(t)                         /* add new name to name table      */
-Text t; {
+Name newName(t,parent)                  /* Add new name to name table      */
+Text t; 
+Cell parent; {
+    Int h = nHash(t);
+
     if (nameHw-NAMEMIN >= NUM_NAME) {
         ERRMSG(0) "Name storage space exhausted"
         EEND;
     }
     name(nameHw).text         = t;      /* clear new name record           */
     name(nameHw).line         = 0;
+    name(nameHw).syntax       = NO_SYNTAX;
+    name(nameHw).parent       = parent;
     name(nameHw).arity        = 0;
     name(nameHw).number       = EXECNAME;
     name(nameHw).defn         = NIL;
@@ -476,10 +434,12 @@ Text t; {
     name(nameHw).mod          = currentModule;
     hashName(nameHw);
     module(currentModule).names=cons(nameHw,module(currentModule).names);
+    name(nameHw).nextNameHash = nameHash[h];
+    nameHash[h]               = nameHw;
     return nameHw++;
 }
 
-Name findName(t)                        /* locate name in name table       */
+Name findName(t)                        /* Locate name in name table       */
 Text t; {
     Name n = nameHash[nHash(t)];
 
@@ -490,30 +450,31 @@ Text t; {
     return n;
 }
 
-Name addName(nm)      /* Insert Name in name table - if no clash is caused */
-Name nm; {
+Name addName(nm)                        /* Insert Name in name table - if  */
+Name nm; {                              /* no clash is caused              */
     Name oldnm = findName(name(nm).text);
     if (isNull(oldnm)) {
         hashName(nm);
+#if !IGNORE_MODULES
         module(currentModule).names=cons(nm,module(currentModule).names);
+#endif
         return nm;
-    } else {
+    } else
         return oldnm;
-    }
 }
 
-static Void local hashName(nm)          /* Insert Name into hash table       */
+static Void local hashName(nm)          /* Insert Name into hash table     */
 Name nm; {
-    Text t = name(nm).text;
-    Int  h = nHash(t);
+    Text t                = name(nm).text;
+    Int  h                = nHash(t);
     name(nm).nextNameHash = nameHash[h];
     nameHash[h]           = nm;
 }
 
-Name findQualName(line,id) /* locate (possibly qualified) name in name table */
-Int  line;
-Cell id; {
-    assert(isPair(id));
+Name findQualName(id)              /* Locate (possibly qualified) name*/
+Cell id; {                         /* in name table                   */
+    if (!isPair(id))
+        internal("findQualName");
     switch (fst(id)) {
         case VARIDCELL :
         case VAROPCELL :
@@ -521,6 +482,9 @@ Cell id; {
         case CONOPCELL :
             return findName(textOf(id));
         case QUALIDENT : {
+#if IGNORE_MODULES
+            return findName(qtextOf(id));
+#else /* !IGNORE_MODULES */
             Text   t  = qtextOf(id);
             Module m  = findQualifier(qmodOf(id));
             List   es = NIL;
@@ -540,8 +504,7 @@ Cell id; {
                     List subentities = NIL;
                     Cell c = fst(e);
                     if (isTycon(c)
-                        && (tycon(c).what == DATATYPE 
-                            || tycon(c).what == NEWTYPE))
+                        && (tycon(c).what==DATATYPE || tycon(c).what==NEWTYPE))
                         subentities = tycon(c).defn;
                     else if (isClass(c))
                         subentities = cclass(c).members;
@@ -553,9 +516,11 @@ Cell id; {
                 }
             }
             return NIL;
+#endif /* !IGNORE_MODULES */
         }
         default : internal("findQualName2");
     }
+    assert(0); return 0; /* NOTREACHED */
 }
 
 /* --------------------------------------------------------------------------
@@ -567,7 +532,7 @@ Text t;
 Int  arity;
 Int  no;
 Int  rep; { /* Really AsmRep */
-    Name n          = newName(t);
+    Name n          = newName(t,NIL);
     name(n).arity   = arity;
     name(n).number  = cfunNo(no);
     name(n).type    = NIL;
@@ -580,12 +545,11 @@ Name s;                                 /* selector s in constructor c.    */
 Name c; {
     List cns;
     cns = name(s).defn;
-    for (; nonNull(cns); cns=tl(cns)) {
+    for (; nonNull(cns); cns=tl(cns))
         if (fst(hd(cns))==c)
             return intOf(snd(hd(cns)));
-    }
     internal("sfunPos");
-    return 0;/*NOTREACHED*/
+    return 0;/* NOTREACHED */
 }
 
 static List local insertName(nm,ns)     /* insert name nm into sorted list */
@@ -613,6 +577,7 @@ List addNamesMatching(pat,ns)           /* Add names matching pattern pat  */
 String pat;                             /* to list of names ns             */
 List   ns; {                            /* Null pattern matches every name */
     Name nm;                            /* (Names with NIL type, or hidden */
+#if 1
     for (nm=NAMEMIN; nm<nameHw; ++nm)   /* or invented names are excluded) */
         if (!inventedText(name(nm).text) && nonNull(name(nm).type)) {
             String str = textToStr(name(nm).text);
@@ -620,6 +585,18 @@ List   ns; {                            /* Null pattern matches every name */
                 ns = insertName(nm,ns);
         }
     return ns;
+#else
+    List mns = module(currentModule).names;
+    for(; nonNull(mns); mns=tl(mns)) {
+        Name nm = hd(mns);
+        if (!inventedText(name(nm).text)) {
+            String str = textToStr(name(nm).text);
+            if (str[0]!='_' && (!pat || stringMatch(pat,str)))
+                ns = insertName(nm,ns);
+        }
+    }
+    return ns;
+#endif
 }
 
 /* --------------------------------------------------------------------------
@@ -691,9 +668,6 @@ String str; {
 static Class classHw;                  /* next unused class                */
 static List  classes;                  /* list of classes in current scope */
 static Inst  instHw;                   /* next unused instance record      */
-#if USE_DICTHW
-static Int   dictHw;                   /* next unused dictionary number    */
-#endif
 
 struct strClass DEFTABLE(tabClass,NUM_CLASSES); /* table of class records  */
 struct strInst far *tabInst;           /* (pointer to) table of instances  */
@@ -716,8 +690,10 @@ Text t; {
     cclass(classHw).defaults  = NIL;
     cclass(classHw).instances = NIL;
     classes=cons(classHw,classes);
+#if !IGNORE_MODULES
     cclass(classHw).mod       = currentModule;
     module(currentModule).classes=cons(classHw,module(currentModule).classes);
+#endif
     return classHw++;
 }
 
@@ -737,36 +713,44 @@ Text t; {
     return NIL;
 }
 
-Class addClass(c)        /* Insert Class in class list - if no clash caused */
-Class c; {
+Class addClass(c)                       /* Insert Class in class list      */
+Class c; {                              /*  - if no clash caused           */
     Class oldc = findClass(cclass(c).text);
     if (isNull(oldc)) {
         classes=cons(c,classes);
+#if !IGNORE_MODULES
         module(currentModule).classes=cons(c,module(currentModule).classes);
+#endif
         return c;
-    } else
+    }
+    else
         return oldc;
 }
 
-Class findQualClass(c) /* look for (possibly qualified) class in class list */
-Cell c; {
+Class findQualClass(c)                  /* Look for (possibly qualified)   */
+Cell c; {                               /* class in class list             */
     if (!isQualIdent(c)) {
         return findClass(textOf(c));
     } else {
-        Text   t = qtextOf(c);
-        Module m = findQualifier(qmodOf(c));
+#if IGNORE_MODULES
+        return findClass(qtextOf(c));
+#else /* !IGNORE_MODULES */
+        Text   t  = qtextOf(c);
+        Module m  = findQualifier(qmodOf(c));
         List   es = NIL;
-        if (isNull(m)) return NIL;
-        for(es=module(m).exports; nonNull(es); es=tl(es)) {
+        if (isNull(m))
+            return NIL;
+        for (es=module(m).exports; nonNull(es); es=tl(es)) {
             Cell e = hd(es);
             if (isPair(e) && isClass(fst(e)) && cclass(fst(e)).text==t) 
                 return fst(e);
         }
+#endif
     }
     return NIL;
 }
 
-Inst newInst() {                       /* add new instance to table        */
+Inst newInst() {                       /* Add new instance to table        */
     if (instHw-INSTMIN >= NUM_INSTS) {
         ERRMSG(0) "Instance storage space exhausted"
         EEND;
@@ -776,11 +760,22 @@ Inst newInst() {                       /* add new instance to table        */
     inst(instHw).specifics  = NIL;
     inst(instHw).implements = NIL;
     inst(instHw).builder    = NIL;
-    inst(instHw).mod        = currentModule;
+    /* from STG */ inst(instHw).mod        = currentModule;
 
     return instHw++;
 }
 
+#ifdef DEBUG_DICTS
+extern Void printInst Args((Inst));
+
+Void printInst(in)
+Inst in; {
+    Class cl = inst(in).c;
+    Printf("%s-", textToStr(cclass(cl).text));
+    printType(stdout,inst(in).t);
+}
+#endif /* DEBUG_DICTS */
+
 Inst findFirstInst(tc)                  /* look for 1st instance involving */
 Tycon tc; {                             /* the type constructor tc         */
     return findNextInst(tc,INSTMIN-1);
@@ -816,11 +811,49 @@ Type tc; {
 Cell DEFTABLE(cellStack,NUM_STACK); /* Storage for cells on stack          */
 StackPtr sp;                        /* stack pointer                       */
 
+#if GIMME_STACK_DUMPS
+
+#define UPPER_DISP  5               /* # display entries on top of stack   */
+#define LOWER_DISP  5               /* # display entries on bottom of stack*/
+
+Void hugsStackOverflow() {          /* Report stack overflow               */
+    extern Int  rootsp;
+    extern Cell evalRoots[];
+
+    ERRMSG(0) "Control stack overflow" ETHEN
+    if (rootsp>=0) {
+        Int i;
+        if (rootsp>=UPPER_DISP+LOWER_DISP) {
+            for (i=0; i<UPPER_DISP; i++) {
+                ERRTEXT "\nwhile evaluating: " ETHEN
+                ERREXPR(evalRoots[rootsp-i]);
+            }
+            ERRTEXT "\n..." ETHEN
+            for (i=LOWER_DISP-1; i>=0; i--) {
+                ERRTEXT "\nwhile evaluating: " ETHEN
+                ERREXPR(evalRoots[i]);
+            }
+        }
+        else {
+            for (i=rootsp; i>=0; i--) {
+                ERRTEXT "\nwhile evaluating: " ETHEN
+                ERREXPR(evalRoots[i]);
+            }
+        }
+    }
+    ERRTEXT "\n"
+    EEND;
+}
+
+#else /* !GIMME_STACK_DUMPS */
+
 Void hugsStackOverflow() {          /* Report stack overflow               */
     ERRMSG(0) "Control stack overflow"
     EEND;
 }
 
+#endif /* !GIMME_STACK_DUMPS */
+
 /* --------------------------------------------------------------------------
  * Module storage:
  *
@@ -838,6 +871,7 @@ Void hugsStackOverflow() {          /* Report stack overflow               */
  *
  * ------------------------------------------------------------------------*/
 
+#if !IGNORE_MODULES
 static  Module   moduleHw;              /* next unused Module              */
 struct  Module   DEFTABLE(tabModule,NUM_MODULE); /* Module storage         */
 Module  currentModule;                  /* Module currently being processed*/
@@ -867,9 +901,8 @@ Module findModule(t)                    /* locate Module in module table  */
 Text t; {
     Module m;
     for(m=MODMIN; m<moduleHw; ++m) {
-        if (module(m).text==t) {
+        if (module(m).text==t)
             return m;
-        }
     }
     return NIL;
 }
@@ -883,6 +916,7 @@ Cell c; {
         case CONIDCELL : return findModule(textOf(c));
         default        : internal("findModid");
     }
+    assert(0); return 0; /* NOTREACHED */
 }
 
 static local Module findQualifier(t)    /* locate Module in import list   */
@@ -896,10 +930,13 @@ Text t; {
         return modulePreludeHugs;
     }
     for (ms=module(currentModule).qualImports; nonNull(ms); ms=tl(ms)) {
-        if (textOf(fst(hd(ms)))==t) {
+        if (textOf(fst(hd(ms)))==t)
             return snd(hd(ms));
-        }
     }
+#if 1 /* mpj */
+    if (module(currentModule).text==t)
+        return currentModule;
+#endif
     return NIL;
 }
 
@@ -908,17 +945,16 @@ Module m; {
     Int i;
     if (m!=currentModule) {
         currentModule = m; /* This is the only assignment to currentModule */
-        for (i=0; i<TYCONHSZ; ++i) {
+        for (i=0; i<TYCONHSZ; ++i)
             tyconHash[i] = NIL;
-        }
         mapProc(hashTycon,module(m).tycons);
-        for (i=0; i<NAMEHSZ; ++i) {
+        for (i=0; i<NAMEHSZ; ++i)
             nameHash[i] = NIL;
-        }
         mapProc(hashName,module(m).names);
         classes = module(m).classes;
     }
 }
+#endif /* !IGNORE_MODULES */
 
 /* --------------------------------------------------------------------------
  * Script file storage:
@@ -935,15 +971,13 @@ typedef struct {                       /* record of storage state prior to */
     Text  textHw;
     Text  nextNewText;
     Text  nextNewDText;
-    Int   syntaxHw;
+#if !IGNORE_MODULES
     Module moduleHw;
+#endif
     Tycon tyconHw;
     Name  nameHw;
     Class classHw;
     Inst  instHw;
-#if USE_DICTHW
-    Int   dictHw;
-#endif
 #if TREX
     Ext   extHw;
 #endif
@@ -968,8 +1002,9 @@ String f; {                             /* of status for later restoration  */
     }
 #ifdef DEBUG_SHOWUSE
     showUse("Text",   textHw,           NUM_TEXT);
-    showUse("Syntax", syntaxHw,         NUM_SYNTAX);
+#if !IGNORE_MODULES
     showUse("Module", moduleHw-MODMIN,  NUM_MODULE);
+#endif
     showUse("Tycon",  tyconHw-TYCMIN,   NUM_TYCON);
     showUse("Name",   nameHw-NAMEMIN,   NUM_NAME);
     showUse("Class",  classHw-CLASSMIN, NUM_CLASSES);
@@ -983,21 +1018,34 @@ String f; {                             /* of status for later restoration  */
     scripts[scriptHw].textHw       = textHw;
     scripts[scriptHw].nextNewText  = nextNewText;
     scripts[scriptHw].nextNewDText = nextNewDText;
-    scripts[scriptHw].syntaxHw     = syntaxHw;
+#if !IGNORE_MODULES
     scripts[scriptHw].moduleHw     = moduleHw;
+#endif
     scripts[scriptHw].tyconHw      = tyconHw;
     scripts[scriptHw].nameHw       = nameHw;
     scripts[scriptHw].classHw      = classHw;
     scripts[scriptHw].instHw       = instHw;
-#if USE_DICTHW
-    scripts[scriptHw].dictHw       = dictHw;
-#endif
 #if TREX
     scripts[scriptHw].extHw        = extHw;
 #endif
     return scriptHw++;
 }
 
+Bool isPreludeScript() {                /* Test whether this is the Prelude*/
+    return (scriptHw==0);
+}
+
+#if !IGNORE_MODULES
+Bool moduleThisScript(m)                /* Test if given module is defined */
+Module m; {                             /* in current script file          */
+    return scriptHw<1 || m>=scripts[scriptHw-1].moduleHw;
+}
+
+Module lastModule() {              /* Return module in current script file */
+    return (moduleHw>MODMIN ? moduleHw-1 : modulePrelude);
+}
+#endif /* !IGNORE_MODULES */
+
 #define scriptThis(nm,t,tag)            Script nm(x)                       \
                                         t x; {                             \
                                             Script s=0;                    \
@@ -1012,18 +1060,18 @@ scriptThis(scriptThisInst,Inst,instHw)
 scriptThis(scriptThisClass,Class,classHw)
 #undef scriptThis
 
-Module lastModule() {              /* Return module in current script file */
-    return (moduleHw-1);
-}
-
-static Module local moduleOfScript(s)
+Module moduleOfScript(s)
 Script s; {
-    return scripts[s-1].moduleHw;
+    return (s==0) ? modulePrelude : scripts[s-1].moduleHw;
 }
 
+#if !IGNORE_MODULES
 String fileOfModule(m)
 Module m; {
     Script s;
+    if (m == modulePrelude) {
+        return STD_PRELUDE;
+    }
     for(s=0; s<scriptHw; ++s) {
         if (scripts[s].moduleHw == m) {
             return textToStr(scripts[s].file);
@@ -1031,8 +1079,9 @@ Module m; {
     }
     return 0;
 }
+#endif
 
-static Script local scriptThisFile(f)
+Script scriptThisFile(f)
 Text f; {
     Script s;
     for (s=0; s < scriptHw; ++s) {
@@ -1040,6 +1089,9 @@ Text f; {
             return s+1;
         }
     }
+    if (f == findText(STD_PRELUDE)) {
+        return 0;
+    }
     return (-1);
 }
 
@@ -1050,7 +1102,9 @@ Script sno; {                           /* to reading script sno           */
         textHw       = scripts[sno].textHw;
         nextNewText  = scripts[sno].nextNewText;
         nextNewDText = scripts[sno].nextNewDText;
-        syntaxHw     = scripts[sno].syntaxHw;
+#if !IGNORE_MODULES
+        moduleHw     = scripts[sno].moduleHw;
+#endif
         tyconHw      = scripts[sno].tyconHw;
         nameHw       = scripts[sno].nameHw;
         classHw      = scripts[sno].classHw;
@@ -1064,8 +1118,8 @@ Script sno; {                           /* to reading script sno           */
 
         for (i=moduleHw; i >= scripts[sno].moduleHw; --i) {
             if (module(i).objectFile) {
-                printf("closing objectFile for module %d\n",i);
-                dlclose(module(i).objectFile);
+                printf("[bogus] closing objectFile for module %d\n",i);
+                /*dlclose(module(i).objectFile);*/
             }
         }
         moduleHw = scripts[sno].moduleHw;
@@ -1079,6 +1133,21 @@ Script sno; {                           /* to reading script sno           */
                 textHash[i][j] = NOTEXT;
         }
 
+#if IGNORE_MODULES
+        for (i=0; i<TYCONHSZ; ++i) {
+            Tycon tc = tyconHash[i];
+            while (nonNull(tc) && tc>=tyconHw)
+                tc = tycon(tc).nextTyconHash;
+            tyconHash[i] = tc;
+        }
+
+        for (i=0; i<NAMEHSZ; ++i) {
+            Name n = nameHash[i];
+            while (nonNull(n) && n>=nameHw)
+                n = name(n).nextNameHash;
+            nameHash[i] = n;
+        }
+#else /* !IGNORE_MODULES */
         currentModule=NIL;
         for (i=0; i<TYCONHSZ; ++i) {
             tyconHash[i] = NIL;
@@ -1086,6 +1155,7 @@ Script sno; {                           /* to reading script sno           */
         for (i=0; i<NAMEHSZ; ++i) {
             nameHash[i] = NIL;
         }
+#endif /* !IGNORE_MODULES */
 
         for (i=CLASSMIN; i<classHw; i++) {
             List ins = cclass(i).instances;
@@ -1119,15 +1189,36 @@ Script sno; {                           /* to reading script sno           */
 Int     heapSize = DEFAULTHEAP;         /* number of cells in heap         */
 Heap    heapFst;                        /* array of fst component of pairs */
 Heap    heapSnd;                        /* array of snd component of pairs */
+#ifndef GLOBALfst
 Heap    heapTopFst;
+#endif
+#ifndef GLOBALsnd
 Heap    heapTopSnd;
+#endif
 Bool    consGC = TRUE;                  /* Set to FALSE to turn off gc from*/
                                         /* C stack; use with extreme care! */
+#if     PROFILING
+Heap    heapThd, heapTopThd;            /* to keep record of producers     */
+Int     sysCount;                       /* record unattached cells         */
+Name    producer;                       /* current producer, if any        */
+Bool    profiling = FALSE;              /* should profiling be performed   */
+Int     profInterval = MAXPOSINT;       /* interval between samples        */
+FILE    *profile = 0;                   /* pointer to profiler log, if any */
+#endif
+Long    numCells;
+Int     numGcs;                         /* number of garbage collections   */
 Int     cellsRecovered;                 /* number of cells recovered       */
 
 static  Cell freeList;                  /* free list of unused cells       */
 static  Cell lsave, rsave;              /* save components of pair         */
 
+#if GC_WEAKPTRS
+static List weakPtrs;                   /* list of weak ptrs               */
+                                        /* reconstructed during every GC   */
+List   finalizers = NIL;
+List   liveWeakPtrs = NIL;
+#endif
+
 #if GC_STATISTICS
 
 static Int markCount, stackRoots;
@@ -1137,19 +1228,19 @@ static Int markCount, stackRoots;
 
 #define startGC()       \
     if (gcMessages) {   \
-        printf("\n");   \
+        Printf("\n");   \
         fflush(stdout); \
     }
 #define endGC()         \
     if (gcMessages) {   \
-        printf("\n");   \
+        Printf("\n");   \
         fflush(stdout); \
     }
 
 #define start()      markCount = 0
 #define end(thing,rs) \
     if (gcMessages) { \
-        printf("GC: %-18s: %4d cells, %4d roots.\n", thing, markCount, rs); \
+        Printf("GC: %-18s: %4d cells, %4d roots.\n", thing, markCount, rs); \
         fflush(stdout); \
     }
 #define recordMark() markCount++
@@ -1185,22 +1276,21 @@ Cell l, r; {                            /* heap, garbage collecting first  */
     freeList = snd(freeList);
     fst(c)   = l;
     snd(c)   = r;
+#if PROFILING
+    thd(c)   = producer;
+#endif
+    numCells++;
     return c;
 }
 
 Void overwrite(dst,src)                 /* overwrite dst cell with src cell*/
-Pair dst, src; {                        /* both *MUST* be pairs            */
-    assert(isPair(dst) && isPair(src));
-    fst(dst) = fst(src);
-    snd(dst) = snd(src);
-}
-
-Void overwrite2(dst,src1,src2)          /* overwrite dst cell with src cell*/
-Pair dst;
-Cell src1, src2; {
-    assert(isPair(dst));
-    fst(dst) = src1;
-    snd(dst) = src2;
+Cell dst, src; {                        /* both *MUST* be pairs            */
+    if (isPair(dst) && isPair(src)) {
+        fst(dst) = fst(src);
+        snd(dst) = snd(src);
+    }
+    else
+        internal("overwrite");
 }
 
 static Int *marks;
@@ -1215,8 +1305,8 @@ static Cell local markCell(c)           /* Traverse part of graph marking  */
 Cell c; {                               /* cells reachable from given root */
                                         /* markCell(c) is only called if c */
                                         /* is a pair                       */
-    {   register place = placeInSet(c);
-        register mask  = maskInSet(c);
+    {   register int place = placeInSet(c);
+        register int mask  = maskInSet(c);
         if (marks[place]&mask)
             return c;
         else {
@@ -1229,8 +1319,9 @@ Cell c; {                               /* cells reachable from given root */
         fst(c) = markCell(fst(c));
         markSnd(c);
     }
-    else if (isNull(fst(c)) || fst(c)>=BCSTAG)
+    else if (isNull(fst(c)) || fst(c)>=BCSTAG) {
         markSnd(c);
+    }
 
     return c;
 }
@@ -1244,8 +1335,8 @@ ma: t = c;                              /* Keep pointer to original pair   */
 mb: if (!isPair(c))
         return;
 
-    {   register place = placeInSet(c);
-        register mask  = maskInSet(c);
+    {   register int place = placeInSet(c);
+        register int mask  = maskInSet(c);
         if (marks[place]&mask)
             return;
         else {
@@ -1285,14 +1376,128 @@ Void garbageCollect()     {             /* Run garbage collector ...       */
     gcStarted();
     for (i=0; i<marksSize; ++i)         /* initialise mark set to empty    */
         marks[i] = 0;
-
+#if GC_WEAKPTRS
+    weakPtrs = NIL;                     /* clear list of weak pointers     */
+#endif
     everybody(MARK);                    /* Mark all components of system   */
 
+#if IO_HANDLES
+    for (i=0; i<NUM_HANDLES; ++i)       /* release any unused handles      */
+        if (nonNull(handles[i].hcell)) {
+            register place = placeInSet(handles[i].hcell);
+            register mask  = maskInSet(handles[i].hcell);
+            if ((marks[place]&mask)==0)
+                freeHandle(i);
+        }
+#endif
+#if GC_MALLOCPTRS
+    for (i=0; i<NUM_MALLOCPTRS; ++i)    /* release any unused mallocptrs   */
+        if (isPair(mallocPtrs[i].mpcell)) {
+            register place = placeInSet(mallocPtrs[i].mpcell);
+            register mask  = maskInSet(mallocPtrs[i].mpcell);
+            if ((marks[place]&mask)==0)
+                incMallocPtrRefCnt(i,-1);
+        }
+#endif /* GC_MALLOCPTRS */
+#if GC_WEAKPTRS
+    /* After GC completes, we scan the list of weak pointers that are
+     * still live and zap their contents unless the contents are still
+     * live (by some other means).
+     * Note that this means the contents must itself be heap allocated.
+     * This means it can't be a nullary constructor or an Int or a Name
+     * or lots of other things - hope this doesn't bite too hard.
+     */
+    for (; nonNull(weakPtrs); weakPtrs=nextWeakPtr(weakPtrs)) {
+        Cell ptr = derefWeakPtr(weakPtrs);
+        if (isGenPair(ptr)) {
+            Int  place = placeInSet(ptr);
+            Int  mask  = maskInSet(ptr);
+            if ((marks[place]&mask)==0) {
+                /* printf("Zapping weak pointer %d\n", ptr); */
+                derefWeakPtr(weakPtrs) = NIL;
+            } else {
+                /* printf("Keeping weak pointer %d\n", ptr); */
+            }
+        } else if (nonNull(ptr)) {
+            printf("Weak ptr contains object which isn't heap allocated %d\n", ptr);
+        }
+    }
+
+    if (nonNull(liveWeakPtrs) || nonNull(finalizers)) {
+        Bool anyMarked;                 /* Weak pointers with finalizers   */
+        List wps;
+        List newFins = NIL;
+
+        /* Step 1: iterate until we've found out what is reachable         */
+        do {
+            anyMarked = FALSE;
+            for (wps=liveWeakPtrs; nonNull(wps); wps=tl(wps)) {
+                Cell wp = hd(wps);
+                Cell k  = fst(snd(wp));
+                if (isNull(k)) {
+                    internal("bad weak ptr");
+                }
+                if (isMarked(k)) {
+                    Cell vf = snd(snd(wp));
+                    if (!isMarked(fst(vf)) || !isMarked(snd(vf))) {
+                        mark(fst(vf));
+                        mark(snd(vf));
+                        anyMarked = TRUE;
+                    }
+                }
+            }
+        } while (anyMarked);
+
+        /* Step 2: Now we know which weak pointers will die, so we can     */
+        /* remove them from the live set and gather their finalizers.  But */
+        /* note that we mustn't mark *anything* at this stage or we will   */
+        /* corrupt our view of what's alive, and what's dead.              */
+        wps = NIL;
+        while (nonNull(liveWeakPtrs)) {
+            Cell wp = hd(liveWeakPtrs);
+            List nx = tl(liveWeakPtrs);
+            Cell k  = fst(snd(wp));
+            if (!isMarked(k)) {                 /* If the key is dead, then*/
+                Cell vf      = snd(snd(wp));    /* stomp on weak pointer   */
+                fst(vf)      = snd(vf);
+                snd(vf)      = newFins;
+                newFins      = vf;              /* reuse because we can't  */
+                fst(snd(wp)) = NIL;             /* reallocate here ...     */
+                snd(snd(wp)) = NIL;
+                snd(wp)      = NIL;
+                liveWeakPtrs = nx;
+            } else {
+                tl(liveWeakPtrs) = wps;         /* Otherwise, weak pointer */
+                wps              = liveWeakPtrs;/* survives to face another*/
+                liveWeakPtrs     = nx;          /* garbage collection      */
+            }
+        }
+
+        /* Step 3: Now we've identified the live cells and the newly       */
+        /* scheduled finalizers, but we had better make sure that they are */
+        /* all marked now, including any internal structure, to ensure that*/
+        /* they make it to the other side of gc.                           */
+        for (liveWeakPtrs=wps; nonNull(wps); wps=tl(wps)) {
+            mark(snd(hd(wps)));
+        }
+        mark(liveWeakPtrs);
+        mark(newFins);
+        finalizers = revOnto(newFins,finalizers);
+    }
+
+#endif /* GC_WEAKPTRS */
     gcScanning();                       /* scan mark set                   */
     mask      = 1;
     place     = 0;
     recovered = 0;
     j         = 0;
+#if PROFILING
+    if (profile) {
+        sysCount = 0;
+        for (i=NAMEMIN; i<nameHw; i++)
+            name(i).count = 0;
+    }
+#endif
     freeList = NIL;
     for (i=1; i<=heapSize; i++) {
         if ((marks[place] & mask) == 0) {
@@ -1301,6 +1506,12 @@ Void garbageCollect()     {             /* Run garbage collector ...       */
             freeList = -i;
             recovered++;
         }
+#if PROFILING
+        else if (nonNull(thd(-i)))
+            name(thd(-i)).count++;
+        else
+            sysCount++;
+#endif
         mask <<= 1;
         if (++j == bitsPerWord) {
             place++;
@@ -1312,6 +1523,49 @@ Void garbageCollect()     {             /* Run garbage collector ...       */
     gcRecovered(recovered);
     breakOn(breakStat);                 /* restore break trapping if nec.  */
 
+#if PROFILING
+    if (profile) {
+        fprintf(profile,"BEGIN_SAMPLE %ld.00\n",numReductions);
+/* For the time being, we won't include the system count in the output:
+        if (sysCount>0)
+            fprintf(profile,"  SYSTEM %d\n",sysCount);
+*/
+        /* Accumulate costs in top level objects */
+        for (i=NAMEMIN; i<nameHw; i++) {
+            Name cc = i;
+            /* Use of "while" instead of "if" is pure paranoia - ADR */
+            while (isName(name(cc).parent)) 
+                cc = name(cc).parent;
+            if (i != cc) {
+                name(cc).count += name(i).count;
+                name(i).count = 0;
+            }
+        }
+        for (i=NAMEMIN; i<nameHw; i++)
+            if (name(i).count>0) 
+                if (isPair(name(i).parent)) {
+                    Pair p = name(i).parent;
+                    Cell f = fst(p);
+                    fprintf(profile,"  ");
+                    if (isClass(f))
+                        fprintf(profile,"%s",textToStr(cclass(f).text));
+                    else {
+                        fprintf(profile,"%s_",textToStr(cclass(inst(f).c).text));
+                        /* Will hp2ps accept the spaces produced by this? */
+                        printPred(profile,inst(f).head);
+                    }
+                    fprintf(profile,"_%s %d\n",
+                            textToStr(name(snd(p)).text),
+                            name(i).count);
+                } else {
+                    fprintf(profile,"  %s %d\n",
+                            textToStr(name(i).text),
+                            name(i).count);
+                }
+        fprintf(profile,"END_SAMPLE %ld.00\n",numReductions);
+    }
+#endif
+
     /* can only return if freeList is nonempty on return. */
     if (recovered<minRecovery || isNull(freeList)) {
         ERRMSG(0) "Garbage collection fails to reclaim sufficient space"
@@ -1320,6 +1574,22 @@ Void garbageCollect()     {             /* Run garbage collector ...       */
     cellsRecovered = recovered;
 }
 
+#if PROFILING
+Void profilerLog(s)                     /* turn heap profiling on, saving log*/
+String s; {                             /* in specified file                 */
+    if ((profile=fopen(s,"w")) != NULL) {
+        fprintf(profile,"JOB \"Hugs Heap Profile\"\n");
+        fprintf(profile,"DATE \"%s\"\n",timeString());
+        fprintf(profile,"SAMPLE_UNIT \"reductions\"\n");
+        fprintf(profile,"VALUE_UNIT \"cells\"\n");
+    }
+    else {
+        ERRMSG(0) "Cannot open profile log file \"%s\"", s
+        EEND;
+    }
+}
+#endif
+
 /* --------------------------------------------------------------------------
  * Code for saving last expression entered:
  *
@@ -1392,7 +1662,7 @@ Cell c; {                               /* except that Cells refering to   */
  * Miscellaneous operations on heap cells:
  * ------------------------------------------------------------------------*/
 
-/* profiling suggests that the number of calls to whatIs() is typically    */
+/* Profiling suggests that the number of calls to whatIs() is typically    */
 /* rather high.  The recoded version below attempts to improve the average */
 /* performance for whatIs() using a binary search for part of the analysis */
 
@@ -1413,14 +1683,17 @@ register Cell c; {
                                         else            return MODULE;
                     else                if (c>=OFFMIN)  return OFFSET;
 #if TREX
-                                        else if (c>=EXTMIN) return EXT;
+                                        else            return (c>=EXTMIN) ?
+                                                                EXT : TUPLE;
+#else
+                                        else            return TUPLE;
 #endif
-                                        else                return TUPLE;
 
 /*  if (isPair(c)) {
         register Cell fstc = fst(c);
         return isTag(fstc) ? fstc : AP;
     }
+    if (c>=INTMIN)   return INTCELL;
     if (c>=CHARMIN)  return CHARCELL;
     if (c>=CLASSMIN) return CLASS;
     if (c>=INSTMIN)  return INSTANCE;
@@ -1447,6 +1720,11 @@ Cell c;
 Int  depth; {
     if (0 == depth) {
         Printf("...");
+#if 0 /* Not in this version of Hugs */
+    } else if (isPair(c) && !isGenPair(c)) {
+        extern Void printEvalCell Args((Cell, Int));
+        printEvalCell(c,depth);
+#endif
     } else {
         Int tag = whatIs(c);
         switch (tag) {
@@ -1699,10 +1977,18 @@ Cell c; {
 
 Cell mkInt(n)                          /* make cell representing integer   */
 Int n; {
-    return isSmall(INTZERO+n) ? INTZERO+n : pair(INTCELL,n);
+    return (MINSMALLINT <= n && n <= MAXSMALLINT)
+           ? INTZERO+n
+           : pair(INTCELL,n);
 }
 
-#if PTR_ON_HEAP
+#if BIGNUMS
+Bool isBignum(c)                       /* cell holds bignum value?         */
+Cell c; {
+    return c==ZERONUM || (isPair(c) && (fst(c)==POSNUM || fst(c)==NEGNUM));
+}
+#endif
+
 #if SIZEOF_INTP == SIZEOF_INT
 typedef union {Int i; Ptr p;} IntOrPtr;
 Cell mkPtr(p)
@@ -1717,28 +2003,45 @@ Ptr ptrOf(c)
 Cell c;
 {
     IntOrPtr x;
-    assert(isPtr(c));
+    assert(fst(c) == PTRCELL);
     x.i = snd(c);
     return x.p;
 }
+#elif SIZEOF_INTP == 2*SIZEOF_INT
+typedef union {struct {Int i1; Int i2;} i; Ptr p;} IntOrPtr;
+Cell mkPtr(p)
+Ptr p;
+{
+    IntOrPtr x;
+    x.p = p;
+    return pair(PTRCELL,pair(mkInt(x.i.i1),mkInt(x.i.i2)));
+}
+
+Ptr ptrOf(c)
+Cell c;
+{
+    IntOrPtr x;
+    assert(fst(c) == PTRCELL);
+    x.i.i1 = intOf(fst(snd(c)));
+    x.i.i2 = intOf(snd(snd(c)));
+    return x.p;
+}
 #else
-/* For 8 byte addresses (used on the Alpha), we'll have to work harder */
-#error "PTR_ON_HEAP not supported on this architecture"
-#endif
-#endif
+#warning "type Addr not supported on this architecture - don't use it"
+Cell mkPtr(p)
+Ptr p;
+{
+    ERRMSG(0) "mkPtr: type Addr not supported on this architecture"
+    EEND;
+}
 
-String stringNegate( s )
-String s;
+Ptr ptrOf(c)
+Cell c;
 {
-    if (s[0] == '-') {
-        return &s[1];
-    } else {
-        static char t[100];
-        t[0] = '-';
-        strcpy(&t[1],s);  /* ToDo: use strncpy instead */
-        return t;
-    }
+    ERRMSG(0) "ptrOf: type Addr not supported on this architecture"
+    EEND;
 }
+#endif
 
 /* --------------------------------------------------------------------------
  * List operations:
@@ -1747,7 +2050,7 @@ String s;
 Int length(xs)                         /* calculate length of list xs      */
 List xs; {
     Int n = 0;
-    for (n=0; nonNull(xs); ++n)
+    for (; nonNull(xs); ++n)
         xs = tl(xs);
     return n;
 }
@@ -1765,19 +2068,20 @@ List xs, ys; {                         /* ys by modifying xs ...           */
     }
 }
 
-List revDupOnto(xs,ys)   /* non-destructively prepend xs backwards onto ys */
+List dupOnto(xs,ys)      /* non-destructively prepend xs backwards onto ys */
 List xs; 
 List ys; {
-    for( ; nonNull(xs); xs=tl(xs)) {
+    for (; nonNull(xs); xs=tl(xs))
         ys = cons(hd(xs),ys);
-    }
     return ys;
 }
 
-List dupListOnto(xs,ys)              /* Duplicate spine of list xs onto ys */
-List xs;
-List ys; {
-    return revOnto(revDupOnto(xs,NIL),ys);
+List dupList(xs)                       /* Duplicate spine of list xs       */
+List xs; {
+    List ys = NIL;
+    for (; nonNull(xs); xs=tl(xs))
+        ys = cons(hd(xs),ys);
+    return rev(ys);
 }
 
 List revOnto(xs,ys)                    /* Destructively reverse elements of*/
@@ -1793,16 +2097,27 @@ List xs, ys; {                         /* list xs onto list ys...          */
     return ys;
 }
 
-Bool eqList(as,bs)
-List as;
-List bs; {
-    while (nonNull(as) && nonNull(bs) && hd(as)==hd(bs)) {
-        as=tl(as);
-        bs=tl(bs);
+#if 0
+List delete(xs,y)                      /* Delete first use of y from xs    */
+List xs;
+Cell y; {
+    if (isNull(xs)) {
+        return xs;
+    } else if (hs(xs) == y) {
+        return tl(xs);
+    } else {
+        tl(xs) = delete(tl(xs),y);
+        return xs;
     }
-    return (isNull(as) && isNull(bs));
 }
 
+List minus(xs,ys)                      /* Delete members of ys from xs     */
+List xs, ys; {
+    mapAccum(delete,xs,ys);
+    return xs;
+}
+#endif
+
 Cell varIsMember(t,xs)                 /* Test if variable is a member of  */
 Text t;                                /* given list of variables          */
 List xs; {
@@ -1812,6 +2127,15 @@ List xs; {
     return NIL;
 }
 
+Name nameIsMember(t,ns)                 /* Test if name with text t is a   */
+Text t;                                 /* member of list of names xs      */
+List ns; {
+    for (; nonNull(ns); ns=tl(ns))
+        if (t==name(hd(ns)).text)
+            return hd(ns);
+    return NIL;
+}
+
 Cell intIsMember(n,xs)                 /* Test if integer n is member of   */
 Int  n;                                /* given list of integers           */
 List xs; {
@@ -1848,27 +2172,26 @@ List xs; {
     return NIL;
 }
 
-List replicate(n,x)                    /* create list of n copies of x     */
+List replicate(n,x)                     /* create list of n copies of x    */
 Int n;
 Cell x; {
     List xs=NIL;
-    assert(n>=0);
-    while (0<n--) {
+    while (0<n--)
         xs = cons(x,xs);
-    }
     return xs;
 }
 
-List diffList(xs,ys)                   /* list difference: xs\ys           */
-List xs, ys; {                         /* result contains all elements of  */
-    List result = NIL;                 /* `xs' not appearing in `ys'       */
-    while (nonNull(xs)) {
-        List next = tl(xs);
-        if (!cellIsMember(hd(xs),ys)) {
-            tl(xs) = result;
-            result = xs;
+List diffList(from,take)               /* list difference: from\take       */
+List from, take; {                     /* result contains all elements of  */
+    List result = NIL;                 /* `from' not appearing in `take'   */
+
+    while (nonNull(from)) {
+        List next = tl(from);
+        if (!cellIsMember(hd(from),take)) {
+            tl(from) = result;
+            result   = from;
         }
-        xs = next;
+        from = next;
     }
     return rev(result);
 }
@@ -1891,7 +2214,6 @@ Int  n;                                 /* specified length                */
 List xs; {
     List ys = xs;
 
-    assert(n>=0);
     if (n==0)
         return NIL;
     while (1<n-- && nonNull(xs))
@@ -1901,10 +2223,9 @@ List xs; {
     return ys;
 }
 
-List splitAt(n,xs)                    /* drop n things from front of list */
+List splitAt(n,xs)                         /* drop n things from front of list*/
 Int  n;       
 List xs; {
-    assert(n>=0);
     for(; n>0; --n) {
         xs = tl(xs);
     }
@@ -1914,10 +2235,10 @@ List xs; {
 Cell nth(n,xs)                         /* extract n'th element of list    */
 Int  n;
 List xs; {
-    assert(n>=0);
     for(; n>0 && nonNull(xs); --n, xs=tl(xs)) {
     }
-    assert(nonNull(xs));
+    if (isNull(xs))
+        internal("nth");
     return hd(xs);
 }
 
@@ -1965,7 +2286,6 @@ Cell e; {                              /* application:                     */
 Cell nthArg(n,e)                       /* return nth arg in application    */
 Int  n;                                /* of function to m args (m>=n)     */
 Cell e; {                              /* nthArg n (f x0 x1 ... xm) = xn   */
-    assert(n>=0);
     for (n=numArgs(e)-n-1; n>0; n--)
         e = fun(e);
     return arg(e);
@@ -1993,6 +2313,254 @@ List args; {
 }
 
 /* --------------------------------------------------------------------------
+ * Handle operations:
+ * ------------------------------------------------------------------------*/
+
+#if IO_HANDLES
+struct strHandle DEFTABLE(handles,NUM_HANDLES);
+
+Cell openHandle(s,hmode,binary)         /* open handle to file named s in  */
+String s;                               /* the specified hmode             */
+Int    hmode; 
+Bool   binary; {
+    Int i;
+
+    for (i=0; i<NUM_HANDLES && nonNull(handles[i].hcell); ++i)
+        ;                                       /* Search for unused handle*/
+    if (i>=NUM_HANDLES) {                       /* If at first we don't    */
+        garbageCollect();                       /* succeed, garbage collect*/
+        for (i=0; i<NUM_HANDLES && nonNull(handles[i].hcell); ++i)
+            ;                                   /* and try again ...       */
+    }
+    if (i>=NUM_HANDLES) {                       /* ... before we give up   */
+        ERRMSG(0) "Too many handles open; cannot open \"%s\"", s
+        EEND;
+    }
+    else {                                      /* prepare to open file    */
+        String stmode;
+        if (binary) {
+            stmode = (hmode&HAPPEND) ? "ab+" :
+                     (hmode&HWRITE)  ? "wb+" :
+                     (hmode&HREAD)   ? "rb" : (String)0;
+        } else {
+            stmode = (hmode&HAPPEND) ? "a+"  :
+                     (hmode&HWRITE)  ? "w+"  :
+                     (hmode&HREAD)   ? "r"  : (String)0;
+        }
+        if (stmode && (handles[i].hfp=fopen(s,stmode))) {
+            handles[i].hmode = hmode;
+            return (handles[i].hcell = ap(HANDCELL,i));
+        }
+    }
+    return NIL;
+}
+
+static Void local freeHandle(n)         /* release handle storage when no  */
+Int n; {                                /* heap references to it remain    */
+    if (0<=n && n<NUM_HANDLES && nonNull(handles[n].hcell)) {
+        if (n>HSTDERR && handles[n].hmode!=HCLOSED && handles[n].hfp) {
+            fclose(handles[n].hfp);
+            handles[n].hfp = 0;
+        }
+        fst(handles[n].hcell) = snd(handles[n].hcell) = NIL;
+        handles[n].hcell      = NIL;
+    }
+}
+#endif
+
+#if GC_MALLOCPTRS
+/* --------------------------------------------------------------------------
+ * Malloc Ptrs:
+ * ------------------------------------------------------------------------*/
+
+struct strMallocPtr mallocPtrs[NUM_MALLOCPTRS];
+
+/* It might GC (because it uses a table not a list) which will trash any
+ * unstable pointers.  
+ * (It happens that we never use it with unstable pointers.)
+ */
+Cell mkMallocPtr(ptr,cleanup)            /* create a new malloc pointer    */
+Ptr ptr;
+Void (*cleanup) Args((Ptr)); {
+    Int i;
+    for (i=0; i<NUM_MALLOCPTRS && mallocPtrs[i].refCount!=0; ++i)
+        ;                                       /* Search for unused entry */
+    if (i>=NUM_MALLOCPTRS) {                    /* If at first we don't    */
+        garbageCollect();                       /* succeed, garbage collect*/
+        for (i=0; i<NUM_MALLOCPTRS && mallocPtrs[i].refCount!=0; ++i)
+            ;                                   /* and try again ...       */
+    }
+    if (i>=NUM_MALLOCPTRS) {                    /* ... before we give up   */
+        ERRMSG(0) "Too many ForeignObjs open"
+        EEND;
+    }
+    mallocPtrs[i].ptr      = ptr;
+    mallocPtrs[i].cleanup  = cleanup;
+    mallocPtrs[i].refCount = 1;
+    return (mallocPtrs[i].mpcell = ap(MPCELL,i));
+}
+
+Void incMallocPtrRefCnt(n,i)             /* change ref count of MallocPtr */
+Int n;
+Int i; {        
+    if (!(0<=n && n<NUM_MALLOCPTRS && mallocPtrs[n].refCount > 0))
+        internal("freeMallocPtr");
+    mallocPtrs[n].refCount += i;
+    if (mallocPtrs[n].refCount <= 0) {
+        mallocPtrs[n].cleanup(mallocPtrs[n].ptr);
+
+        mallocPtrs[n].ptr      = 0;
+        mallocPtrs[n].cleanup  = 0;
+        mallocPtrs[n].refCount = 0;
+        mallocPtrs[n].mpcell   = NIL;
+    }
+}
+#endif /* GC_MALLOCPTRS */
+
+/* --------------------------------------------------------------------------
+ * Stable pointers
+ * This is a mechanism that allows the C world to manipulate pointers into the
+ * Haskell heap without having to worry that the garbage collector is going
+ * to delete it or move it around.
+ * The implementation and interface is based on my implementation in
+ * GHC - but, at least for now, is simplified by using a fixed size
+ * table of stable pointers.
+ * ------------------------------------------------------------------------*/
+
+#if GC_STABLEPTRS
+
+/* Each entry in the stable pointer table is either a heap pointer
+ * or is not currently allocated.
+ * Unallocated entries are threaded together into a freelist.
+ * The last entry in the list contains the Cell 0; all other values
+ * contain a Cell whose value is the next free stable ptr in the list.
+ * It follows that stable pointers are strictly positive (>0).
+ */
+static Cell stablePtrTable[NUM_STABLEPTRS];
+static Int  sptFreeList;
+#define SPT(sp) stablePtrTable[(sp)-1]
+
+static Void local resetStablePtrs() {
+    Int i;
+    /* It would be easier to build the free list in the other direction
+     * but, when debugging, it's way easier to understand if the first
+     * pointer allocated is "1".
+     */
+    for(i=1; i < NUM_STABLEPTRS; ++i)
+        SPT(i) = i+1;
+    SPT(NUM_STABLEPTRS) = 0;
+    sptFreeList = 1;
+}
+
+Int mkStablePtr(c)                  /* Create a stable pointer            */
+Cell c; {
+    Int i = sptFreeList;
+    if (i == 0)
+        return 0;
+    sptFreeList = SPT(i);
+    SPT(i) = c;
+    return i;
+}
+
+Cell derefStablePtr(p)              /* Dereference a stable pointer       */
+Int p; {
+    if (!(1 <= p && p <= NUM_STABLEPTRS)) {
+        internal("derefStablePtr");
+    }
+    return SPT(p);
+}
+
+Void freeStablePtr(i)               /* Free a stable pointer             */
+Int i; {
+    SPT(i) = sptFreeList;
+    sptFreeList = i;
+}
+
+#undef SPT
+#endif /* GC_STABLEPTRS */
+
+/* --------------------------------------------------------------------------
+ * plugin support
+ * ------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+ * GreenCard entry points
+ *
+ * GreenCard generated code accesses Hugs data structures and functions 
+ * (only) via these functions (which are stored in the virtual function
+ * table hugsAPI1.
+ *-------------------------------------------------------------------------*/
+
+#if GREENCARD
+
+static Cell  makeTuple      Args((Int));
+static Cell  makeInt        Args((Int));
+static Cell  makeChar       Args((Char));
+static Char  CharOf         Args((Cell));
+static Cell  makeFloat      Args((FloatPro));
+static Void* derefMallocPtr Args((Cell));
+static Cell* Fst            Args((Cell));
+static Cell* Snd            Args((Cell));
+
+static Cell  makeTuple(n)      Int      n; { return mkTuple(n); }
+static Cell  makeInt(n)        Int      n; { return mkInt(n); }
+static Cell  makeChar(n)       Char     n; { return mkChar(n); }
+static Char  CharOf(n)         Cell     n; { return charOf(n); }
+static Cell  makeFloat(n)      FloatPro n; { return mkFloat(n); }
+static Void* derefMallocPtr(n) Cell     n; { return derefMP(n); }
+static Cell* Fst(n)            Cell     n; { return (Cell*)&fst(n); }
+static Cell* Snd(n)            Cell     n; { return (Cell*)&snd(n); }
+
+HugsAPI1* hugsAPI1() {
+    static HugsAPI1 api;
+    static Bool initialised = FALSE;
+    if (!initialised) {
+        api.nameTrue        = nameTrue;
+        api.nameFalse       = nameFalse;
+        api.nameNil         = nameNil;
+        api.nameCons        = nameCons;
+        api.nameJust        = nameJust;
+        api.nameNothing     = nameNothing;
+        api.nameLeft        = nameLeft;
+        api.nameRight       = nameRight;
+        api.nameUnit        = nameUnit;
+        api.nameIORun       = nameIORun;
+        api.makeInt         = makeInt;
+        api.makeChar        = makeChar;
+        api.CharOf          = CharOf;
+        api.makeFloat       = makeFloat;
+        api.makeTuple       = makeTuple;
+        api.pair            = pair;
+        api.mkMallocPtr     = mkMallocPtr;
+        api.derefMallocPtr  = derefMallocPtr;
+        api.mkStablePtr     = mkStablePtr;
+        api.derefStablePtr  = derefStablePtr;
+        api.freeStablePtr   = freeStablePtr;
+        api.eval            = eval;
+        api.evalWithNoError = evalWithNoError;
+        api.evalFails       = evalFails;
+        api.whnfArgs        = &whnfArgs;
+        api.whnfHead        = &whnfHead;
+        api.whnfInt         = &whnfInt;
+        api.whnfFloat       = &whnfFloat;
+        api.garbageCollect  = garbageCollect;
+        api.stackOverflow   = hugsStackOverflow;
+        api.internal        = internal;
+        api.registerPrims   = registerPrims;
+        api.addPrimCfun     = addPrimCfun;
+        api.inventText      = inventText;
+        api.Fst             = Fst;
+        api.Snd             = Snd;
+        api.cellStack       = cellStack;
+        api.sp              = &sp;
+    }
+    return &api;
+}
+
+#endif /* GREENCARD */
+
+
+/* --------------------------------------------------------------------------
  * storage control:
  * ------------------------------------------------------------------------*/
 
@@ -2019,6 +2587,38 @@ Int what; {
     switch (what) {
         case RESET   : clearStack();
 
+                       /* the next 2 statements are particularly important
+                        * if you are using GLOBALfst or GLOBALsnd since the
+                        * corresponding registers may be reset to their
+                        * uninitialised initial values by a longjump.
+                        */
+                       heapTopFst = heapFst + heapSize;
+                       heapTopSnd = heapSnd + heapSize;
+#if PROFILING
+                       heapTopThd = heapThd + heapSize;
+                       if (profile) {
+                           garbageCollect();
+                           fclose(profile);
+#if HAVE_HP2PS
+                           system("hp2ps profile.hp");
+#endif
+                           profile = 0;
+                       }
+#endif
+#if IO_HANDLES
+                       handles[HSTDIN].hmode  = HREAD;
+                       handles[HSTDOUT].hmode = HAPPEND;
+                       handles[HSTDERR].hmode = HAPPEND;
+#endif
+#if GC_MALLOCPTRS
+                       for (i=0; i<NUM_MALLOCPTRS; i++)
+                           mallocPtrs[i].mpcell = NIL;
+#endif
+#if !HSCRIPT
+#if GC_STABLEPTRS
+                       resetStablePtrs();
+#endif
+#endif
                        consGC = TRUE;
                        lsave  = NIL;
                        rsave  = NIL;
@@ -2029,12 +2629,14 @@ Int what; {
         case MARK    : 
                        start();
                        for (i=NAMEMIN; i<nameHw; ++i) {
+                           mark(name(i).parent);
                            mark(name(i).defn);
                            mark(name(i).stgVar);
                            mark(name(i).type);
                        }
                        end("Names", nameHw-NAMEMIN);
 
+#if !IGNORE_MODULES
                        start();
                        for (i=MODMIN; i<moduleHw; ++i) {
                            mark(module(i).tycons);
@@ -2044,6 +2646,7 @@ Int what; {
                            mark(module(i).qualImports);
                        }
                        end("Modules", moduleHw-MODMIN);
+#endif
 
                        start();
                        for (i=TYCMIN; i<tyconHw; ++i) {
@@ -2068,8 +2671,8 @@ Int what; {
 
                        start();
                        for (i=INSTMIN; i<instHw; ++i) {
-                           mark(inst(i).kinds);
                            mark(inst(i).head);
+                           mark(inst(i).kinds);
                            mark(inst(i).specifics);
                            mark(inst(i).implements);
                        }
@@ -2085,6 +2688,24 @@ Int what; {
                        mark(lsave);
                        mark(rsave);
                        end("Last expression", 3);
+#if IO_HANDLES
+                       start();
+                       mark(handles[HSTDIN].hcell);
+                       mark(handles[HSTDOUT].hcell);
+                       mark(handles[HSTDERR].hcell);
+                       end("Standard handles", 3);
+#endif
+
+#if GC_STABLEPTRS
+                       start();
+                       for (i=0; i<NUM_STABLEPTRS; ++i)
+                           mark(stablePtrTable[i]);
+                       end("Stable pointers", NUM_STABLEPTRS);
+#endif
+
+#if GC_WEAKPTRS
+                       mark(finalizers);
+#endif
 
                        if (consGC) {
                            start();
@@ -2105,12 +2726,24 @@ Int what; {
 
                        heapTopFst = heapFst + heapSize;
                        heapTopSnd = heapSnd + heapSize;
+#if PROFILING
+                       heapThd = heapAlloc(heapSize);
+                       if (heapThd==(Heap)0) {
+                           ERRMSG(0) "Cannot allocate profiler storage space"
+                           EEND;
+                       }
+                       heapTopThd   = heapThd + heapSize;
+                       profile      = 0;
+                       if (0 == profInterval)
+                           profInterval = heapSize / DEF_PROFINTDIV;
+#endif
                        for (i=1; i<heapSize; ++i) {
                            fst(-i) = FREECELL;
                            snd(-i) = -(i+1);
                        }
                        snd(-heapSize) = NIL;
                        freeList  = -1;
+                       numGcs    = 0;
                        consGC    = TRUE;
                        lsave     = NIL;
                        rsave     = NIL;
@@ -2122,7 +2755,6 @@ Int what; {
                        }
 
                        TABALLOC(text,      char,             NUM_TEXT)
-                       TABALLOC(tabSyntax, struct strSyntax, NUM_SYNTAX)
                        TABALLOC(tyconHash, Tycon,            TYCONHSZ)
                        TABALLOC(tabTycon,  struct strTycon,  NUM_TYCON)
                        TABALLOC(nameHash,  Name,             NAMEHSZ)
@@ -2135,6 +2767,18 @@ Int what; {
 #endif
                        clearStack();
 
+#if IO_HANDLES
+                       TABALLOC(handles,   struct strHandle, NUM_HANDLES)
+                       for (i=0; i<NUM_HANDLES; i++)
+                           handles[i].hcell = NIL;
+                       handles[HSTDIN].hcell  = ap(HANDCELL,HSTDIN);
+                       handles[HSTDIN].hfp    = stdin;
+                       handles[HSTDOUT].hcell = ap(HANDCELL,HSTDOUT);
+                       handles[HSTDOUT].hfp   = stdout;
+                       handles[HSTDERR].hcell = ap(HANDCELL,HSTDERR);
+                       handles[HSTDERR].hfp   = stderr;
+#endif
+
                        textHw        = 0;
                        nextNewText   = NUM_TEXT;
                        nextNewDText  = (-1);
@@ -2143,14 +2787,24 @@ Int what; {
                        for (i=0; i<TEXTHSZ; ++i)
                            textHash[i][0] = NOTEXT;
 
-                       syntaxHw = 0;
 
+#if !IGNORE_MODULES
                        moduleHw = MODMIN;
+#endif
 
                        tyconHw  = TYCMIN;
                        for (i=0; i<TYCONHSZ; ++i)
                            tyconHash[i] = NIL;
 
+#if GC_WEAKPTRS
+                       finalizers   = NIL;
+                       liveWeakPtrs = NIL;
+#endif
+
+#if GC_STABLEPTRS
+                       resetStablePtrs();
+#endif
+
 #if TREX
                        extHw    = EXTMIN;
 #endif
index 4ea1d53..6c0d89a 100644 (file)
@@ -1,15 +1,16 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Defines storage datatypes: Text, Name, Module, Tycon, Cell, List, Pair,
  * Triple, ...
  *
- * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
- * All rights reserved. See NOTICE for details and conditions of use etc...
- * Hugs version 1.4, December 1997
+ * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
+ * Haskell Group 1994-99, and is distributed as Open Source software
+ * under the Artistic License; see the file "Artistic" that is included
+ * in the distribution for details.
  *
  * $RCSfile: storage.h,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:43 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:41 $
  * ------------------------------------------------------------------------*/
 
 /* --------------------------------------------------------------------------
@@ -21,7 +22,7 @@
  * ------------------------------------------------------------------------*/
 
 typedef Int          Text;                       /* text string            */
-typedef Word         Syntax;                     /* syntax (assoc,preced)  */
+typedef Unsigned     Syntax;                     /* syntax (assoc,preced)  */
 typedef Int          Cell;                       /* general cell value     */
 typedef Cell far     *Heap;                      /* storage of heap        */
 typedef Cell         Pair;                       /* pair cell              */
@@ -39,7 +40,7 @@ typedef Cell         Class;                      /* type class             */
 typedef Cell         Inst;                       /* instance of type class */
 typedef Cell         Triple;                     /* triple of cell values  */
 typedef Cell         List;                       /* list of cells          */
-typedef Cell         Bignum;                     /* integer literal        */
+typedef Cell         Bignum;                     /* bignum integer         */
 typedef Cell         Float;                      /* floating pt literal    */
 #if TREX
 typedef Cell         Ext;                        /* extension label        */
@@ -72,16 +73,20 @@ extern  Syntax       defaultSyntax      Args((Text));
 #define MAX_PREC  9                    /* strongest binding operator       */
 #define FUN_PREC  (MAX_PREC+2)         /* binding of function symbols      */
 #define DEF_PREC  MAX_PREC
-#define APPLIC    00000                /* written applicatively            */
-#define LEFT_ASS  02000                /* left associative infix           */
-#define RIGHT_ASS 04000                /* right associative infix          */
-#define NON_ASS   06000                /* non associative infix            */
-#define DEF_ASS   NON_ASS
+#define APPLIC    0                    /* written applicatively            */
+#define LEFT_ASS  1                    /* left associative infix           */
+#define RIGHT_ASS 2                    /* right associative infix          */
+#define NON_ASS   3                    /* non associative infix            */
+#define DEF_ASS   LEFT_ASS
+
+#define UMINUS_PREC  6                  /* Change these settings at your   */
+#define UMINUS_ASSOC LEFT_ASS           /* own risk; they may not work!    */
 
 #define assocOf(x)      ((x)&NON_ASS)
-#define precOf(x)       ((x)&(~NON_ASS))
-#define mkSyntax(a,p)   ((a)|(p))
+#define precOf(x)       ((x)>>2)
+#define mkSyntax(a,p)   ((a)|((p)<<2))
 #define DEF_OPSYNTAX    mkSyntax(DEF_ASS,DEF_PREC)
+#define NO_SYNTAX       (-1)
 
 extern  Void   addSyntax  Args((Int,Text,Syntax));
 extern  Syntax syntaxOf   Args((Text));
@@ -103,6 +108,14 @@ extern Int   cellsRecovered;            /* cells recovered by last gc      */
 
 #define fst(c)       heapTopFst[c]
 #define snd(c)       heapTopSnd[c]
+#if PROFILING
+extern   Heap        heapThd, heapTopThd;
+#define thd(c)       heapTopThd[c]
+extern   Name        producer;
+extern   Bool        profiling;
+extern   Int         profInterval;
+extern   Void        profilerLog     Args((String));
+#endif
 
 extern  Pair         pair            Args((Cell,Cell));
 extern  Void         garbageCollect  Args((Void));
@@ -140,6 +153,7 @@ extern  Cell         whatIs    Args((Cell));
 #define CONOPCELL    8            /* Operator constructor:    snd :: Text  */
 #define STRCELL      9            /* String literal:          snd :: Text  */
 #define INTCELL      10           /* Int literal:             snd :: Int   */
+#define ADDPAT       11           /* (_+k) pattern discr:     snd :: Int   */
 #define FLOATCELL    15           /* Floating Pt literal:     snd :: Text  */
 #define BIGCELL      16           /* Integer literal:         snd :: Text  */
 #if PTR_ON_HEAP
@@ -172,10 +186,24 @@ extern  Bool            isQCon      Args((Cell));
 extern  Bool            isQualIdent Args((Cell));
 extern  Bool            isIdent     Args((Cell));
 
-extern  String           stringNegate Args((String));
+#if 0
+Originally ...
+#define isFloat(c)      (isPair(c) && fst(c)==FLOATCELL)
+extern  Cell            mkFloat         Args((FloatPro));
+extern  FloatPro        floatOf         Args((Cell));
+extern  String          floatToString   Args((FloatPro));
+extern  FloatPro        stringToFloat   Args((String));
+#else
+#define isFloat(c)       (isPair(c) && fst(c)==FLOATCELL)
+#define stringToFloat(s) pair(FLOATCELL,findText(s))
+#define floatToString(f) textToStr(snd(f))
+#define floatEq(f1,f2)   (snd(f1) == snd(f2))
+#define floatNegate(f)   stringToFloat(stringNegate(floatToString(f)))
+#define floatOf(f)       atof(floatToString(f))
+#endif
+
+
 
-#define intEq(x,y)       (intOf(x) == intOf(y))
-#define intNegate(x)     mkInt(-intOf(x))
 
 #define isFloat(c)       (isPair(c) && fst(c)==FLOATCELL)
 #define stringToFloat(s) pair(FLOATCELL,findText(s))
@@ -183,13 +211,10 @@ extern  String           stringNegate Args((String));
 #define floatEq(f1,f2)   (snd(f1) == snd(f2))
 #define floatNegate(f)   stringToFloat(stringNegate(floatToString(f)))
 #define floatOf(f)       atof(floatToString(f))
+#define mkFloat(f)       (f)  /* ToDo: is this right? */
 
-#define isBignum(c)       (isPair(c) && fst(c)==BIGCELL)
-#define stringToBignum(s) pair(BIGCELL,findText(s))
 #define bignumToString(b) textToStr(snd(b))
-#define bignumEq(b1,b2)   (snd(b1) == snd(b2))
-#define bignumNegate(b)   stringToBignum(stringNegate(bignumToString(b)))
-#define bignumOf(b)       atoi(bignumToString(b))   /* ToDo: overflow check */
+
 
 #if PTR_ON_HEAP
 #define isPtr(c)        (isPair(c) && fst(c)==PTRCELL)
@@ -215,58 +240,70 @@ extern  Ptr             ptrOf           Args((Cell));
 #define COMP         26           /* COMP       snd :: (Exp,[Qual])        */
 #define ASPAT        27           /* ASPAT      snd :: (Var,Exp)           */
 #define ESIGN        28           /* ESIGN      snd :: (Exp,Type)          */
-#define CASE         29           /* CASE       snd :: (Exp,[Alt])         */
-#define NUMCASE      30           /* NUMCASE    snd :: (Exp,Disc,Rhs)      */
-#define FATBAR       31           /* FATBAR     snd :: (Exp,Exp)           */
-#define LAZYPAT      32           /* LAZYPAT    snd :: Exp                 */
+#define RSIGN        29           /* RSIGN      snd :: (Rhs,Type)          */
+#define CASE         30           /* CASE       snd :: (Exp,[Alt])         */
+#define NUMCASE      31           /* NUMCASE    snd :: (Exp,Disc,Rhs)      */
+#define FATBAR       32           /* FATBAR     snd :: (Exp,Exp)           */
+#define LAZYPAT      33           /* LAZYPAT    snd :: Exp                 */
 #define DERIVE       35           /* DERIVE     snd :: Cell                */
-#if NPLUSK
-#define ADDPAT       36           /* (_+k) pattern discr: snd :: Cell      */
+#if BREAK_FLOATS
+#define FLOATCELL    36           /* FLOATCELL  snd :: (Int,Int)           */
+#endif
+
+#if BIGNUMS
+#define POSNUM       37           /* POSNUM     snd :: [Int]               */
+#define NEGNUM       38           /* NEGNUM     snd :: [Int]               */
 #endif
 
 #define BOOLQUAL     39           /* BOOLQUAL   snd :: Exp                 */
 #define QWHERE       40           /* QWHERE     snd :: [Decl]              */
 #define FROMQUAL     41           /* FROMQUAL   snd :: (Exp,Exp)           */
 #define DOQUAL       42           /* DOQUAL     snd :: Exp                 */
+#define MONADCOMP    43           /* MONADCOMP  snd :: ((m,m0),(Exp,[Qual])*/
 
 #define GUARDED      44           /* GUARDED    snd :: [guarded exprs]     */
 
-#define ARRAY        45           /* Array:     snd :: (Bounds,[Values])   */
-#define MUTVAR       46           /* Mutvar:    snd :: Cell                */
+#define ARRAY        45           /* Array      snd :: (Bounds,[Values])   */
+#define MUTVAR       46           /* Mutvar     snd :: Cell                */
+#if INTERNAL_PRIMS
+#define HUGSOBJECT   47           /* HUGSOBJECT snd :: Cell                */
+#endif
 
 #define POLYTYPE     50           /* POLYTYPE   snd :: (Kind,Type)         */
 #define QUAL         51           /* QUAL       snd :: ([Classes],Type)    */
 #define RANK2        52           /* RANK2      snd :: (Int,Type)          */
 #define EXIST        53           /* EXIST      snd :: (Int,Type)          */
-#define POLYREC      54           /* POLYREC:   snd :: (Int,Type)          */
-#define BIGLAM       55           /* BIGLAM:    snd :: (vars,patterns)     */
+#define POLYREC      54           /* POLYREC    snd :: (Int,Type)          */
+#define BIGLAM       55           /* BIGLAM     snd :: (vars,patterns)     */
+#define CDICTS       56           /* CDICTS     snd :: ([Pred],Type)       */
 
-#define LABC         60           /* LABC:      snd :: (con,[(Vars,Type)]) */
-#define CONFLDS      61           /* CONFLDS:   snd :: (con,[Field])       */
-#define UPDFLDS      62           /* UPDFLDS:   snd :: (Exp,[con],[Field]) */
+#define LABC         60           /* LABC       snd :: (con,[(Vars,Type)]) */
+#define CONFLDS      61           /* CONFLDS    snd :: (con,[Field])       */
+#define UPDFLDS      62           /* UPDFLDS    snd :: (Exp,[con],[Field]) */
 #if TREX
-#define RECORD       63           /* RECORD:    snd :: [Val]               */
-#define EXTCASE      64           /* EXTCASE:   snd :: (Exp,Disc,Rhs)      */
-#define RECSEL       65           /* RECSEL:    snd :: Ext                 */
+#define RECORD       63           /* RECORD     snd :: [Val]               */
+#define EXTCASE      64           /* EXTCASE    snd :: (Exp,Disc,Rhs)      */
+#define RECSEL       65           /* RECSEL     snd :: Ext                 */
 #endif
+#define IMPDEPS      68           /* IMPDEPS    snd :: [Binding]           */
 
 #define QUALIDENT    70           /* Qualified identifier  snd :: (Id,Id)  */
 #define HIDDEN       71           /* hiding import list    snd :: [Entity] */
 #define MODULEENT    72           /* module in export list snd :: con      */
 
-#define ONLY         75           /* ONLY:      snd :: Exp (used in parser)*/
-#define NEG          76           /* NEG:       snd :: Exp (used in parser)*/
+#define INFIX        80           /* INFIX      snd :: (see tidyInfix)     */
+#define ONLY         81           /* ONLY       snd :: Exp                 */
+#define NEG          82           /* NEG        snd :: Exp                 */
 
-#define IMPDEPS      78           /* IMPDEFS:   snd :: [Binding]           */
-
-#define STGVAR       80           /* STGVAR     snd :: (StgRhs,info)       */
-#define STGAPP       81           /* STGAPP     snd :: (StgVar,[Arg])      */
-#define STGPRIM      82           /* STGPRIM    snd :: (PrimOp,[Arg])      */
-#define STGCON       83           /* STGCON     snd :: (StgCon,[Arg])      */
-#define PRIMCASE     84           /* PRIMCASE   snd :: (Expr,[PrimAlt])    */
+#if SIZEOF_INTP != SIZEOF_INT
+#define PTRCELL      90           /* C Heap Pointer snd :: (Int,Int)       */
+#endif
 
-/* Used when parsing GHC interface files */
-#define DICTAP       85           /* DICTTYPE   snd :: (QClassId,[Type])   */
+#define STGVAR       92           /* STGVAR     snd :: (StgRhs,info)       */
+#define STGAPP       93           /* STGAPP     snd :: (StgVar,[Arg])      */
+#define STGPRIM      94           /* STGPRIM    snd :: (PrimOp,[Arg])      */
+#define STGCON       95           /* STGCON     snd :: (StgCon,[Arg])      */
+#define PRIMCASE     96           /* PRIMCASE   snd :: (Expr,[PrimAlt])    */
 
 /* Last constructor tag must be less than SPECMIN */
 
@@ -287,6 +324,10 @@ extern  Ptr             ptrOf           Args((Cell));
 
 #define DOTDOT       106          /* ".." in import/export list            */
 
+#if BIGNUMS
+#define ZERONUM      108          /* The zero bignum (see POSNUM, NEGNUM)  */
+#endif
+
 #define NAME         110          /* whatIs code for isName                */
 #define TYCON        111          /* whatIs code for isTycon               */
 #define CLASS        112          /* whatIs code for isClass               */
@@ -301,14 +342,17 @@ extern  Ptr             ptrOf           Args((Cell));
 #endif
 
 #define SIGDECL      120          /* Signature declaration                 */
-#define PREDEFINED   121          /* predefined name, not yet filled       */
+#define FIXDECL      121          /* Fixity declaration                    */
+#define FUNBIND      122          /* Function binding                      */
+#define PATBIND      123          /* Pattern binding                       */
 
-#define DATATYPE     130          /* datatype type constructor             */
-#define NEWTYPE      131          /* newtype type constructor              */
-#define SYNONYM      132          /* synonym type constructor              */
-#define RESTRICTSYN  133          /* synonym with restricted scope         */
+#define DATATYPE     130          /* Datatype type constructor             */
+#define NEWTYPE      131          /* Newtype type constructor              */
+#define SYNONYM      132          /* Synonym type constructor              */
+#define RESTRICTSYN  133          /* Synonym with restricted scope         */
 
-#define NODEPENDS    135          /* stop calculation of deps in type check*/
+#define NODEPENDS    135          /* Stop calculation of deps in type check*/
+#define PREDEFINED   136          /* Predefined name, not yet filled       */
 
 /* --------------------------------------------------------------------------
  * Tuple data/type constructors:
@@ -355,6 +399,9 @@ extern Ext           mkExt Args((Text));
 
 #define MODMIN        (OFFMIN+NUM_OFFSETS)
 
+#if IGNORE_MODULES
+#define setCurrModule(m) doNothing()
+#else /* !IGNORE_MODULES */
 #define isModule(c)   (MODMIN<=(c) && (c)<TYCMIN)
 #define mkModule(n)   (MODMIN+(n))
 #define module(n)     tabModule[(n)-MODMIN]
@@ -392,6 +439,9 @@ extern Module findModule    Args((Text));
 extern Module findModid     Args((Cell));
 extern Void   setCurrModule Args((Module));
 
+#define isPrelude(m) (m==modulePrelude)
+#endif /* !IGNORE_MODULES */
+
 /* --------------------------------------------------------------------------
  * Type constructor names:
  * ------------------------------------------------------------------------*/
@@ -404,13 +454,13 @@ extern Void   setCurrModule Args((Module));
 struct strTycon {
     Text  text;
     Int   line;
+#if !IGNORE_MODULES
     Module mod;                         /* module that defines it          */
+#endif
     Int   arity;
     Kind  kind;                         /* kind (includes arity) of Tycon  */
     Cell  what;                         /* DATATYPE/SYNONYM/RESTRICTSYN... */
     Cell  defn;
-    Name  conToTag;  /* used in derived code */
-    Name  tagToCon;
     Tycon nextTyconHash;
 };
 
@@ -420,7 +470,7 @@ extern Tycon newTycon     Args((Text));
 extern Tycon findTycon    Args((Text));
 extern Tycon addTycon     Args((Tycon));
 extern Tycon findQualTycon Args((Cell));
-extern Tycon addPrimTycon  Args((Text,Kind,Int,Cell,Cell));
+extern Tycon addPrimTycon Args((Text,Kind,Int,Cell,Cell));
 
 #define isSynonym(h)    (isTycon(h) && tycon(h).what==SYNONYM)
 #define mkPolyType(n,t) pair(POLYTYPE,pair(n,t))
@@ -441,6 +491,8 @@ struct strName {
     Text   text;
     Int    line;
     Module mod;                         /* module that defines it          */
+    Syntax syntax;
+    Cell   parent; 
     Int    arity;
     Int    number;
     Cell   type;
@@ -483,10 +535,10 @@ extern struct strName DECTABLE(tabName);
 #define mfunOf(n)       ((-1)-name(n).number)
 #define mfunNo(i)       ((-1)-(i))
 
-extern Name   newName      Args((Text));
+extern Name   newName      Args((Text,Cell));
 extern Name   findName     Args((Text));
 extern Name   addName      Args((Name));
-extern Name   findQualName Args((Int,Cell));
+extern Name   findQualName Args((Cell));
 extern Name   addPrimCfun  Args((Text,Int,Int,Int));
 extern Int    sfunPos      Args((Name,Name));
 
@@ -494,7 +546,7 @@ extern Int    sfunPos      Args((Name,Name));
  * Type class values:
  * ------------------------------------------------------------------------*/
 
-#define INSTMIN      (NAMEMIN+NUM_NAME)          /* instances              */
+#define INSTMIN      (NAMEMIN+NUM_NAME) /* instances                       */
 #define isInst(c)    (INSTMIN<=(c) && (c)<CLASSMIN)
 #define mkInst(n)    (INSTMIN+(n))
 #define instOf(c)    ((Int)((c)-INSTMIN))
@@ -522,22 +574,24 @@ struct strInst {
 #define cclass(n)    tabClass[(n)-CLASSMIN]
 
 struct strClass {
-    Text  text;                         /* Name of class                   */
-    Int   line;                         /* Line where declaration begins   */
-    Module mod;                         /* module that defines it          */
-    Int   level;                        /* Level in class hierarchy        */
-    Int   arity;                        /* Number of arguments             */
-    Kinds kinds;                        /* Kinds of constructors in class  */
-    Cell  head;                         /* Head of class                   */
-    Name  dcon;                         /* Dictionay constructor function  */
-    List  supers;                       /* :: [Pred]                       */
-    Int   numSupers;                    /* length(supers)                  */
-    List  dsels;                        /* Superclass dictionary selectors */
-    List  members;                      /* :: [Name]                       */
-    Int   numMembers;                   /* length(members)                 */
-    Name  dbuild;                       /* Default dictionary builder      */
-    List  defaults;                     /* :: [Name]                       */
-    List  instances;                    /* :: [Inst]                       */
+    Text   text;                        /* Name of class                   */
+    Int    line;                        /* Line where declaration begins   */
+#if !IGNORE_MODULES
+    Module mod;                         /* module that declares it         */
+#endif
+    Int    level;                       /* Level in class hierarchy        */
+    Int    arity;                       /* Number of arguments             */
+    Kinds  kinds;                       /* Kinds of constructors in class  */
+    Cell   head;                        /* Head of class                   */
+    Name   dcon;                        /* Dictionary constructor function */
+    List   supers;                      /* :: [Pred]                       */
+    Int    numSupers;                   /* length(supers)                  */
+    List   dsels;                       /* Superclass dictionary selectors */
+    List   members;                     /* :: [Name]                       */
+    Int    numMembers;                  /* length(members)                 */
+    Name   dbuild;                      /* Default dictionary builder      */
+    List   defaults;                    /* :: [Name]                       */
+    List   instances;                   /* :: [Inst]                       */
 };
 
 extern struct strClass    DECTABLE(tabClass);
@@ -567,15 +621,20 @@ extern Inst  findNextInst  Args((Tycon,Inst));
  * ------------------------------------------------------------------------*/
 
 #define INTMIN       (CHARMIN+NUM_CHARS)
-#define INTMAX       MAXPOSINT
+#define INTMAX       (MAXPOSINT)
 #define isSmall(c)   (INTMIN<=(c))
 #define INTZERO      (INTMIN/2 + INTMAX/2)
+#define MINSMALLINT  (INTMIN - INTZERO)
+#define MAXSMALLINT  (INTMAX - INTZERO)
 #define mkDigit(c)   ((Cell)((c)+INTMIN))
 #define digitOf(c)   ((Int)((c)-INTMIN))
 
 extern  Bool isInt    Args((Cell));
 extern  Int  intOf    Args((Cell));
 extern  Cell mkInt    Args((Int));
+#if BIGNUMS
+extern  Bool isBignum Args((Cell));
+#endif
 
 /* --------------------------------------------------------------------------
  * Implementation of triples:
@@ -601,26 +660,25 @@ extern  Cell mkInt    Args((Int));
 #define tl(c)        snd(c)
 
 extern  Int          length       Args((List));
-extern  List         appendOnto   Args((List,List)); /* destructive     */ 
-extern  List         revDupOnto   Args((List,List)); /* non-destructive */ 
-extern  List         dupListOnto  Args((List,List)); /* non-destructive */ 
-extern  List         revOnto      Args((List,List)); /* destructive     */ 
-#define reverse(xs)  revDupOnto((xs),NIL)            /* non-destructive */ 
-#define dupList(xs)  dupListOnto((xs),NIL)           /* non-destructive */ 
-#define rev(xs)      revOnto((xs),NIL)               /* destructive     */ 
+extern  List         appendOnto   Args((List,List));    /* destructive     */
+extern  List         dupOnto      Args((List,List));
+extern  List         dupList      Args((List));
+extern  List         revOnto      Args((List, List));   /* destructive     */
+#define rev(xs)      revOnto((xs),NIL)                  /* destructive     */
 extern  Cell         cellIsMember Args((Cell,List));
 extern  Cell         cellAssoc    Args((Cell,List));
 extern  Cell         cellRevAssoc Args((Cell,List));
 extern  Bool         eqList       Args((List,List));
 extern  Cell         varIsMember  Args((Text,List));
+extern  Name         nameIsMember Args((Text,List));
 extern  Cell         intIsMember  Args((Int,List));
-extern  List         replicate    Args((Int,Cell)); 
-extern  List         diffList     Args((List,List)); /* destructive     */
-extern  List         deleteCell   Args((List,Cell)); /* non-destructive */
-extern  List         take         Args((Int,List));  /* destructive     */
-extern  List         splitAt      Args((Int,List));  /* non-destructive */
+extern  List         replicate    Args((Int,Cell));
+extern  List         diffList     Args((List,List));    /* destructive     */
+extern  List         deleteCell   Args((List,Cell));    /* non-destructive */
+extern  List         take         Args((Int,List));     /* destructive     */
+extern  List         splitAt      Args((Int,List));     /* non-destructive */
 extern  Cell         nth          Args((Int,List));
-extern  List         removeCell   Args((Cell,List)); /* destructive     */
+extern  List         removeCell   Args((Cell,List));    /* destructive     */
 
 /* The following macros provide `inline expansion' of some common ways of
  * traversing, using and modifying lists:
@@ -629,20 +687,22 @@ extern  List         removeCell   Args((Cell,List)); /* destructive     */
  *      with identifiers used elsewhere.
  */
 
-#define mapBasic(_init,_step)     {List Zs=(_init);\
-                                   for(;nonNull(Zs);Zs=tl(Zs))  \
-                                   _step;}
-#define mapModify(_init,_step)    mapBasic(_init,hd(Zs)=_step)
+#define mapBasic(_init,_step)           {List Zs=(_init);\
+                                         for(;nonNull(Zs);Zs=tl(Zs))  \
+                                         _step;}
+#define mapModify(_init,_step)          mapBasic(_init,hd(Zs)=_step)
 
-#define mapProc(_f,_xs)           mapBasic(_xs,_f(hd(Zs)))
-#define map1Proc(_f,_a,_xs)       mapBasic(_xs,_f(_a,hd(Zs)))
-#define map2Proc(_f,_a,_b,_xs)    mapBasic(_xs,_f(_a,_b,hd(Zs)))
-#define map3Proc(_f,_a,_b,_c,_xs) mapBasic(_xs,_f(_a,_b,_c,hd(Zs)))
+#define mapProc(_f,_xs)                 mapBasic(_xs,_f(hd(Zs)))
+#define map1Proc(_f,_a,_xs)             mapBasic(_xs,_f(_a,hd(Zs)))
+#define map2Proc(_f,_a,_b,_xs)          mapBasic(_xs,_f(_a,_b,hd(Zs)))
+#define map3Proc(_f,_a,_b,_c,_xs)       mapBasic(_xs,_f(_a,_b,_c,hd(Zs)))
+#define map4Proc(_f,_a,_b,_c,_d,_xs)    mapBasic(_xs,_f(_a,_b,_c,_d,hd(Zs)))
 
-#define mapOver(_f,_xs)           mapModify(_xs,_f(hd(Zs)))
-#define map1Over(_f,_a,_xs)       mapModify(_xs,_f(_a,hd(Zs)))
-#define map2Over(_f,_a,_b,_xs)    mapModify(_xs,_f(_a,_b,hd(Zs)))
-#define map3Over(_f,_a,_b,_c,_xs) mapModify(_xs,_f(_a,_b,_c,hd(Zs)))
+#define mapOver(_f,_xs)                 mapModify(_xs,_f(hd(Zs)))
+#define map1Over(_f,_a,_xs)             mapModify(_xs,_f(_a,hd(Zs)))
+#define map2Over(_f,_a,_b,_xs)          mapModify(_xs,_f(_a,_b,hd(Zs)))
+#define map3Over(_f,_a,_b,_c,_xs)       mapModify(_xs,_f(_a,_b,_c,hd(Zs)))
+#define map4Over(_f,_a,_b,_c,_d,_xs)    mapModify(_xs,_f(_a,_b,_c,_d,hd(Zs)))
 
 /* This is just what you want for functions with accumulating parameters */
 #define mapAccum(_f,_acc,_xs)           mapBasic(_xs,_acc=_f(_acc,hd(Zs)))
@@ -655,8 +715,8 @@ extern  List         removeCell   Args((Cell,List)); /* destructive     */
  * ------------------------------------------------------------------------*/
 
 #define ap(f,x)      pair(f,x)
-#define ap1(f,x)     ap(f,x) 
-#define ap2(f,x,y)   ap(ap(f,x),y) 
+#define ap1(f,x)     ap(f,x)
+#define ap2(f,x,y)   ap(ap(f,x),y)
 #define ap3(f,x,y,z) ap(ap(ap(f,x),y),z)
 #define fun(c)       fst(c)
 #define arg(c)       snd(c)
@@ -692,6 +752,8 @@ extern  StackPtr sp;
 #define drop()       sp--
 #define top()        stack(sp)
 #define pushed(n)    stack(sp-(n))
+#define topfun(f)    top()=ap((f),top())
+#define toparg(x)    top()=ap(top(),(x))
 
 extern  Void hugsStackOverflow Args((Void));
 
@@ -701,7 +763,11 @@ extern  Void hugsStackOverflow Args((Void));
  * ------------------------------------------------------------------------*/
 
 extern Script      startNewScript   Args((String));
+extern Bool        moduleThisScript Args((Module));
+extern Module      moduleOfScript   Args((Script));
+extern Bool        isPreludeScript  Args((Void));
 extern Module      lastModule       Args((Void));
+extern Script      scriptThisFile   Args((Text));
 extern Script      scriptThisName   Args((Name));
 extern Script      scriptThisTycon  Args((Tycon));
 extern Script      scriptThisInst   Args((Inst));
@@ -710,12 +776,186 @@ extern String      fileOfModule     Args((Module));
 extern Void        dropScriptsFrom  Args((Script));
 
 /* --------------------------------------------------------------------------
+ * I/O Handles:
+ * ------------------------------------------------------------------------*/
+
+#if IO_HANDLES
+#define HSTDIN          0       /* Numbers for standard handles            */
+#define HSTDOUT         1
+#define HSTDERR         2
+
+struct strHandle {              /* Handle description and status flags     */
+    Cell hcell;                 /* Heap representation of handle (or NIL)  */
+    FILE *hfp;                  /* Corresponding file pointer              */
+    Int  hmode;                 /* Current mode: see below                 */
+};
+
+#define HCLOSED         0000    /* no I/O permitted                        */
+#define HSEMICLOSED     0001    /* semiclosed reads only                   */
+#define HREAD           0002    /* set to enable reads from handle         */
+#define HWRITE          0004    /* set to enable writes to handle          */
+#define HAPPEND         0010    /* opened in append mode                   */
+
+extern Cell   openHandle Args((String,Int,Bool));
+extern struct strHandle  DECTABLE(handles);
+#endif
+
+/* --------------------------------------------------------------------------
+ * Malloc Pointers
+ * ------------------------------------------------------------------------*/
+
+#if GC_MALLOCPTRS
+struct strMallocPtr {           /* Malloc Ptr description                  */
+    Cell mpcell;                /* Back pointer to MPCELL                  */
+    Void *ptr;                  /* Pointer into C world                    */
+    Int  refCount;              /* Reference count                         */
+    Void (*cleanup) Args((Void *)); /* Code to free the C pointer          */
+};
+
+extern struct strMallocPtr       mallocPtrs[];
+extern Cell   mkMallocPtr        Args((Void *, Void (*)(Void *)));
+extern Void   freeMallocPtr      Args((Cell));
+extern Void   incMallocPtrRefCnt Args((Int, Int));
+
+#define mpOf(c)    snd(c)
+#define derefMP(c) (mallocPtrs[(Int)mpOf(c)].ptr)
+#endif /* GC_MALLOCPTRS */
+
+/* --------------------------------------------------------------------------
+ * Weak Pointers
+ * ------------------------------------------------------------------------*/
+
+#if GC_WEAKPTRS
+#define mkWeakPtr(c)    pair(WEAKCELL,pair(c,NIL))
+#define derefWeakPtr(c) fst(snd(c))
+#define nextWeakPtr(c) snd(snd(c))
+
+extern List finalizers;
+extern List liveWeakPtrs;
+
+#endif /* GC_WEAKPTRS */
+
+/* --------------------------------------------------------------------------
+ * Stable pointers
+ * ------------------------------------------------------------------------*/
+
+#if GC_STABLEPTRS
+extern  Int  mkStablePtr     Args((Cell));
+extern  Cell derefStablePtr  Args((Int));
+extern  Void freeStablePtr   Args((Int));
+#endif /* GC_STABLEPTRS */
+
+/* --------------------------------------------------------------------------
+ * Plugins
+ * ------------------------------------------------------------------------*/
+
+#if PLUGINS
+/* This is an exact copy of the declaration found in GreenCard.h */
+
+typedef int     HugsStackPtr;
+typedef int     HugsStablePtr;
+typedef Pointer HugsForeign;
+
+typedef struct {
+
+  /* evaluate next argument */
+  int            (*getInt   )     Args(());  
+  unsigned int   (*getWord  )     Args(());
+  void*          (*getAddr  )     Args(());
+  float          (*getFloat )     Args(());
+  double         (*getDouble)     Args(());
+  char           (*getChar  )     Args(());
+  HugsForeign    (*getForeign)    Args(());
+  HugsStablePtr  (*getStablePtr)  Args(());
+
+  /* push part of result   */
+  void           (*putInt   )     Args((int));           
+  void           (*putWord  )     Args((unsigned int));
+  void           (*putAddr  )     Args((void*));
+  void           (*putFloat )     Args((double));
+  void           (*putDouble)     Args((double));
+  void           (*putChar  )     Args((char));
+  void           (*putForeign)    Args((HugsForeign, void (*)(HugsForeign)));
+  void           (*putStablePtr)  Args((HugsStablePtr));
+
+  /* return n values in IO monad or Id monad */
+  void           (*returnIO)      Args((HugsStackPtr, int));
+  void           (*returnId)      Args((HugsStackPtr, int));
+  int            (*runIO)         Args((int));
+
+  /* free a stable pointer */                            
+  void           (*freeStablePtr) Args((HugsStablePtr));
+
+  /* register the prim table */                          
+  void           (*registerPrims) Args((struct primInfo*));
+                           
+  /* garbage collect */
+  void           (*garbageCollect) Args(());
+
+} HugsAPI2;
+
+extern  HugsAPI2* hugsAPI2     Args((Void));
+typedef Void (*InitModuleFun2) Args((HugsAPI2*));
+
+typedef struct {
+  Name  nameTrue, nameFalse;
+  Name  nameNil,  nameCons;
+  Name  nameJust, nameNothing;
+  Name  nameLeft, nameRight;
+  Name  nameUnit;
+  Name  nameIORun;
+
+  Cell  (*makeInt)         Args((Int));
+                           
+  Cell  (*makeChar)        Args((Char));
+  Char  (*CharOf)          Args((Cell));
+                           
+  Cell  (*makeFloat)       Args((FloatPro));
+  Cell  (*makeTuple)       Args((Int));
+  Pair  (*pair)            Args((Cell,Cell));
+                           
+  Cell  (*mkMallocPtr)     Args((Void *, Void (*)(Void *)));
+  Void *(*derefMallocPtr)  Args((Cell));
+                           
+  Int   (*mkStablePtr)     Args((Cell));
+  Cell  (*derefStablePtr)  Args((Int));
+  Void  (*freeStablePtr)   Args((Int));
+                           
+  Void  (*eval)            Args((Cell));
+  Cell  (*evalWithNoError) Args((Cell));
+  Void  (*evalFails)       Args((StackPtr));
+  Int   *whnfArgs;         
+  Cell  *whnfHead;         
+  Int   *whnfInt;          
+  Float *whnfFloat;        
+                           
+  Void  (*garbageCollect)  Args(());
+  Void  (*stackOverflow)   Args(());
+  Void  (*internal)        Args((String)) HUGS_noreturn;
+
+  Void  (*registerPrims)   Args((struct primInfo*));
+  Name  (*addPrimCfun)     Args((Text,Int,Int,Cell));
+  Text  (*inventText)      Args(());
+
+  Cell *(*Fst)             Args((Cell));
+  Cell *(*Snd)             Args((Cell));
+
+  Cell  *cellStack;
+  StackPtr *sp;
+} HugsAPI1;
+
+extern  HugsAPI1* hugsAPI1     Args((Void));
+typedef Void (*InitModuleFun1) Args((HugsAPI1*));
+#endif /* PLUGINS */
+
+
+/* --------------------------------------------------------------------------
  * Misc:
  * ------------------------------------------------------------------------*/
 
-extern  Void   setLastExpr      Args((Cell));
-extern  Cell   getLastExpr      Args((Void));
+extern  Void   setLastExpr       Args((Cell));
+extern  Cell   getLastExpr       Args((Void));
 extern  List   addTyconsMatching Args((String,List));
-extern  List   addNamesMatching Args((String,List));
+extern  List   addNamesMatching  Args((String,List));
 
 /*-------------------------------------------------------------------------*/
index 955eabb..8643df4 100644 (file)
@@ -1,11 +1,16 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
- * subst.c:     Copyright (c) Mark P Jones 1991-1998.   All rights reserved.
- *              See NOTICE for details and conditions of use etc...
- *              Hugs version 1.3c, March 1998
- *
  * Provides an implementation for the `current substitution' used during
  * type and kind inference in both static analysis and type checking.
+ *
+ * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
+ * Haskell Group 1994-99, and is distributed as Open Source software
+ * under the Artistic License; see the file "Artistic" that is included
+ * in the distribution for details.
+ *
+ * $RCSfile: subst.c,v $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:42 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
@@ -51,6 +56,7 @@ static Bool local varToTypeBind         Args((Tyvar *,Type,Int));
 #if TREX
 static Bool local inserter              Args((Type,Int,Type,Int));
 static Int  local remover               Args((Text,Type,Int));
+static Int  local tailVar               Args((Type,Int));
 #endif
 static Bool local kvarToVarBind         Args((Tyvar *,Tyvar *));
 static Bool local kvarToTypeBind        Args((Tyvar *,Type,Int));
@@ -166,9 +172,9 @@ Int n; {                                /* all of kind STAR                */
         tyvars[numTyvars-n].bound = NIL;
         tyvars[numTyvars-n].kind  = STAR;
 #ifdef DEBUG_TYPES
-        printf("new type variable: _%d ::: ",numTyvars-n);
+        Printf("new type variable: _%d ::: ",numTyvars-n);
         printKind(stdout,tyvars[numTyvars-n].kind);
-        putchar('\n');
+        Putchar('\n');
 #endif
     }
     return beta;
@@ -183,9 +189,9 @@ Kind k; {                               /* specified kinds                 */
         tyvars[numTyvars].bound = NIL;
         tyvars[numTyvars].kind  = fst(k);
 #ifdef DEBUG_TYPES
-        printf("new type variable: _%d ::: ",numTyvars);
+        Printf("new type variable: _%d ::: ",numTyvars);
         printKind(stdout,tyvars[numTyvars].kind);
-        putchar('\n');
+        Putchar('\n');
 #endif
         numTyvars++;
     }
@@ -317,9 +323,9 @@ Int  o; {
     tyv->bound = t;
     tyv->offs  = o;
 #ifdef DEBUG_TYPES
-    printf("binding type variable: _%d to ",vn);
+    Printf("binding type variable: _%d to ",vn);
     printType(stdout,debugType(t,o));
-    putchar('\n');
+    Putchar('\n');
 #endif
 }
 
@@ -396,7 +402,7 @@ Int   *ao; {                            /* expansion returned in (*at,*ao) */
  * Marking fixed variables in type expressions:
  * ------------------------------------------------------------------------*/
 
-Void clearMarks() {                     /* set all unbound type vars to    */
+Void clearMarks() {                     /* Set all unbound type vars to    */
     Int i;                              /* unused generic variables        */
     for (i=0; i<numTyvars; ++i)
         if (!isBound(tyvar(i)))
@@ -405,6 +411,15 @@ Void clearMarks() {                     /* set all unbound type vars to    */
     nextGeneric = 0;
 }
 
+Void markAllVars() {                    /* Set all unbound type vars to    */
+    Int i;                              /* be fixed vars                   */
+    for (i=0; i<numTyvars; ++i)
+        if (!isBound(tyvar(i)))
+            tyvar(i)->offs = FIXED_TYVAR;
+    genericVars = NIL;
+    nextGeneric = 0;
+}
+
 Void resetGenerics() {                  /* Reset all generic vars to unused*/
     Int i;
     for (i=0; i<numTyvars; ++i)
@@ -428,8 +443,10 @@ Void markType(t,o)                      /* mark fixed vars in type (t,o)   */
 Type t;
 Int  o; {
     switch (whatIs(t)) {
+        case POLYTYPE  :
+        case QUAL      :
 #if TREX
-        case EXT       :st
+        case EXT       :
 #endif
         case TYCON     :
         case TUPLE     : return;
@@ -450,8 +467,6 @@ Int  o; {
 
         case RANK2     : markType(snd(snd(t)),o);
                          return;
-        case POLYTYPE  : /* No need to mark generic types */
-                         return;
 
         default        : internal("markType");
     }
@@ -474,8 +489,11 @@ Type copyTyvar(vn)                      /* calculate most general form of  */
 Int vn; {                               /* type bound to given type var    */
     Tyvar *tyv = tyvar(vn);
 
-    if (isBound(tyv))
+    if ((tyv->bound)==SKOLEM) {
+        return mkInt(vn);
+    } else if (tyv->bound) {
         return copyType(tyv->bound,tyv->offs);
+    }
 
     switch (tyv->offs) {
         case FIXED_TYVAR    : return mkInt(vn);
@@ -586,7 +604,7 @@ Int  n; {
             Type a = arg(fun(t));
             if (isPolyType(a))
                 a = dropRank1(a,alpha,n);
-            as = ap2(typeArrow,a,as);
+            as = fn(a,as);
             t  = arg(t);
         }
         t = ap(RANK2,pair(r,revOnto(as,t)));
@@ -659,7 +677,7 @@ Int  m; {
         for (i=intOf(r); i>0; i--) {
             Type a = arg(fun(t));
             a      = isPolyType(a) ? liftRank1Body(a,m) : copyType(a,alpha);
-            as     = ap2(typeArrow,a,as);
+            as     = fn(a,as);
             t      = arg(t);
         }
         t = ap(RANK2,pair(r,revOnto(as,copyType(t,alpha))));
@@ -738,7 +756,7 @@ Int  o; {
 #endif
     }
 #ifdef DEBUG_KINDS
-    printf("getKind c = %d, whatIs=%d\n",c,whatIs(c));
+    Printf("getKind c = %d, whatIs=%d\n",c,whatIs(c));
 #endif
     internal("getKind");
     return STAR;/* not reached */
@@ -842,7 +860,7 @@ Tyvar *tyv1, *tyv2; {
         tyv1->bound = aVar;
         tyv1->offs  = tyvNum(tyv2);
 #ifdef DEBUG_TYPES
-        printf("vv binding tyvar: _%d to _%d\n",tyvNum(tyv1),tyvNum(tyv2));
+        Printf("vv binding tyvar: _%d to _%d\n",tyvNum(tyv1),tyvNum(tyv2));
 #endif
     }
     return TRUE;
@@ -868,9 +886,9 @@ Int   o; {                              /* have synonym as outermost constr*/
         tyv->bound = t;
         tyv->offs  = o;
 #ifdef DEBUG_TYPES
-        printf("vt binding type variable: _%d to ",tyvNum(tyv));
+        Printf("vt binding type variable: _%d to ",tyvNum(tyv));
         printType(stdout,debugType(t,o));
-        putchar('\n');
+        Putchar('\n');
 #endif
         return TRUE;
     }
@@ -914,23 +932,27 @@ un: if (tyv1)
             Int  a2 = argCount;
 
 #ifdef DEBUG_TYPES
-            printf("tt unifying types: ");
+            Printf("tt unifying types: ");
             printType(stdout,debugType(t1,o1));
-            printf(" with ");
+            Printf(" with ");
             printType(stdout,debugType(t2,o2));
-            putchar('\n');
+            Putchar('\n');
 #endif
-
             if (isOffset(h1) || isInt(h1)) h1=NIL;  /* represent var by NIL*/
             if (isOffset(h2) || isInt(h2)) h2=NIL;
 
 #if TREX
             if (isExt(h1) || isExt(h2)) {
-                if (a1==2 && isExt(h1) && a2==2 && isExt(h2))
-                    return inserter(fun(t1),o1,t2,o2) &&
-                              unify(arg(t1),o1,aVar,
-                                 remover(extText(h1),t2,o2));
-                else {
+                if (a1==2 && isExt(h1) && a2==2 && isExt(h2)) {
+                    if (extText(h1)==extText(h2)) {
+                        return unify(arg(fun(t1)),o1,arg(fun(t2)),o2) &&
+                                unify(arg(t1),o1,arg(t2),o2);
+                    } else {
+                        return inserter(t1,o1,t2,o2) &&
+                                  unify(arg(t1),o1,aVar,
+                                     remover(extText(h1),t2,o2));
+                    }
+                } else {
                     unifyFails = "rows are not compatible";
                     return FALSE;
                 }
@@ -1001,23 +1023,35 @@ un: if (tyv1)
 }
 
 #if TREX
-static Bool local inserter(ins,o,r,or)  /* Insert field into row (r,or)    */
-Type ins;                               /* inserter (ins,o), where ins is  */
-Int  o;                                 /* an applic of an EXT to a type.  */
+static Bool local inserter(r1,o1,r,o)   /* Insert first field in (r1,o1)   */
+Type r1;                                /* into row (r,o), both of which   */
+Int  o1;                                /* are known to begin with an EXT  */
 Type r;
-Int  or; {
-    Text labt = extText(fun(ins));      /* Find the text of the label      */
+Int  o; {
+    Text labt = extText(fun(fun(r1)));  /* Find the text of the label      */
+#ifdef DEBUG_TYPES
+    Printf("inserting ");
+    printType(stdout,debugType(r1,o1));
+    Printf(" into ");
+    printType(stdout,debugType(r,o));
+    Putchar('\n');
+#endif
     for (;;) {
         Tyvar *tyv;
-        deRef(tyv,r,or);
+        deRef(tyv,r,o);
         if (tyv) {
-            Int beta = newTyvars(1);    /* Extend row with new field       */
+            Int beta;                   /* Test for common tail            */
+            if (tailVar(arg(r1),o1)==tyvNum(tyv)) {
+                unifyFails = "distinct rows have common tail";
+                return FALSE;
+            }
+            beta = newTyvars(1);        /* Extend row with new field       */
             tyvar(beta)->kind = ROW;
-            return varToTypeBind(tyv,ap(ins,mkInt(beta)),o);
+            return varToTypeBind(tyv,ap(fun(r1),mkInt(beta)),o1);
         }
         else if (isAp(r) && isAp(fun(r)) && isExt(fun(fun(r)))) {
             if (labt==extText(fun(fun(r))))/* Compare existing fields      */
-                return unify(arg(ins),o,extField(r),or);
+                return unify(arg(fun(r1)),o1,extField(r),o);
             r = extRow(r);              /* Or skip to next field           */
         }
         else {                          /* Nothing else will match         */
@@ -1034,6 +1068,11 @@ Int  o; {
     Tyvar *tyv;
     Int    beta       = newTyvars(1);
     tyvar(beta)->kind = ROW;
+#ifdef DEBUG_TYPES
+    Printf("removing %s from",textToStr(l));
+    printType(stdout,debugType(r,o));
+    Putchar('\n');
+#endif
     deRef(tyv,r,o);
     if (tyv || !isAp(r) || !isAp(fun(r)) || !isExt(fun(fun(r))))
         internal("remover");
@@ -1044,10 +1083,30 @@ Int  o; {
     bindTv(beta,r,o);
     return beta;
 }
+
+
+static Int local tailVar(r,o)           /* Find var at tail end of a row   */
+Type r;
+Int  o; {
+    for (;;) {
+        Tyvar *tyv;
+        deRef(tyv,r,o);
+        if (tyv) {
+            return tyvNum(tyv);
+        }
+        else if (isAp(r) && isAp(fun(r)) && isExt(fun(fun(r)))) {
+            r = extRow(r);
+        }
+        else {
+            return (-1);
+        }
+    }
+}
 #endif
 
+
 Bool typeMatches(type,mt)               /* test if type matches monotype mt*/
-Type type, mt; {
+    Type type, mt; {                    /* imported from STG Hugs          */
     Bool result;
     if (isPolyType(type) || whatIs(type)==QUAL)
         return FALSE;
@@ -1059,6 +1118,27 @@ Type type, mt; {
     return result;
 }
 
+
+#if IO_MONAD
+Bool isProgType(ks,type)                /* Test if type is of the form     */
+List ks;                                /* IO t for some t.                */
+Type type; {
+    Bool result;
+    Int  alpha;
+    Int  beta;
+    if (isPolyType(type) || whatIs(type)==QUAL)
+        return FALSE;
+    emptySubstitution();
+    alpha  = newKindedVars(ks);
+    beta   = newTyvars(1);
+    bindOnlyAbove(beta);
+    result = unify(type,alpha,typeProgIO,beta);
+    unrestrictBind();
+    emptySubstitution();
+    return result;
+}
+#endif
+
 /* --------------------------------------------------------------------------
  * Matching predicates:
  *
@@ -1140,6 +1220,11 @@ Int  o; {
     return pi1==pi;
 }
 
+#if TREX
+static Cell trexShow = NIL;             /* Used to test for show on records*/
+static Cell trexEq   = NIL;             /* Used to test for eq on records  */
+#endif
+
 Inst findInstFor(pi,o)                  /* Find matching instance for pred */
 Cell  pi;                               /* (pi,o), or otherwise NIL.  If a */
 Int   o; {                              /* match is found, then tyvars from*/
@@ -1162,10 +1247,10 @@ Int   o; {                              /* match is found, then tyvars from*/
     unrestrictBind();
 
 #if TREX
-    {   Int showRow = strcmp(textToStr(cclass(c).text),"ShowRecRow");
-        Int eqRow   = strcmp(textToStr(cclass(c).text),"EqRecRow");
+    {   Bool wantShow   = (c==findQualClass(trexShow));
+        Bool wantEither = wantShow || (c==findQualClass(trexEq));
 
-        if (showRow==0 || eqRow==0) {           /* Generate instances of   */
+        if (wantEither) {                       /* Generate instances of   */
             Type  t = arg(pi);                  /* ShowRecRow and EqRecRow */
             Tyvar *tyv;                         /* on the fly              */
             Cell  e;
@@ -1179,8 +1264,7 @@ Int   o; {                              /* match is found, then tyvars from*/
                         break;
                     }
                 if (isNull(in))
-                    in = (showRow==0) ? addRecShowInst(c,e)
-                                      : addRecEqInst(c,e);
+                    in = (wantShow ? addRecShowInst(c,e) : addRecEqInst(c,e));
                 typeOff = newKindedVars(extKind);
                 bindTv(typeOff,arg(fun(t)),o);
                 bindTv(typeOff+1,arg(t),o);
@@ -1298,7 +1382,7 @@ Tyvar *tyv1, *tyv2; {                     /* for kind variable bindings    */
         tyv1->bound = aVar;
         tyv1->offs  = tyvNum(tyv2);
 #ifdef DEBUG_KINDS
-        printf("vv binding kvar: _%d to _%d\n",tyvNum(tyv1),tyvNum(tyv2));
+        Printf("vv binding kvar: _%d to _%d\n",tyvNum(tyv1),tyvNum(tyv2));
 #endif
     }
     return TRUE;
@@ -1312,9 +1396,9 @@ Int   o; {                              /* have synonym as outermost constr*/
         tyv->bound = t;
         tyv->offs  = o;
 #ifdef DEBUG_KINDS
-        printf("vt binding kind variable: _%d to ",tyvNum(tyv));
+        Printf("vt binding kind variable: _%d to ",tyvNum(tyv));
         printType(stdout,debugType(t,o));
-        putchar('\n');
+        Putchar('\n');
 #endif
         return TRUE;
     }
@@ -1340,11 +1424,11 @@ Int  o1,o2; {
             return kvarToTypeBind(kyv2,k1,o1);      /* k2 variable, k1 not */
         else {
 #ifdef DEBUG_KINDS
-            printf("unifying kinds: ");
+            Printf("unifying kinds: ");
             printType(stdout,debugType(k1,o1));
-            printf(" with ");
+            Printf(" with ");
             printType(stdout,debugType(k2,o2));
-            putchar('\n');
+            Putchar('\n');
 #endif
             if (k1==STAR && k2==STAR)               /* k1, k2 not vars     */
                 return TRUE;
@@ -1472,6 +1556,10 @@ Int what; {
                        mark(typeIs);
                        mark(predsAre);
                        mark(genericVars);
+#if TREX
+                       mark(trexShow);
+                       mark(trexEq);
+#endif
                        break;
 
         case INSTALL : substitution(RESET);
@@ -1481,6 +1569,12 @@ Int what; {
                            simpleKindCache[i] = NIL;
                            varKindCache[i]    = NIL;
                        }
+#if TREX
+                       trexShow = mkQCon(findText("Trex"),
+                                         findText("ShowRecRow"));
+                       trexEq   = mkQCon(findText("Trex"),
+                                         findText("EqRecRow"));
+#endif
                        break;
     }
 }
index 40f38c4..195b926 100644 (file)
@@ -1,10 +1,15 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
- * subst.h:     Copyright (c) Mark P Jones 1991-1998.   All rights reserved.
- *              See NOTICE for details and conditions of use etc...
- *              Hugs version 1.3c, March 1998
- *
  * Definitions for substitution data structure and operations.
+ *
+ * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
+ * Haskell Group 1994-99, and is distributed as Open Source software
+ * under the Artistic License; see the file "Artistic" that is included
+ * in the distribution for details.
+ *
+ * $RCSfile: subst.h,v $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:43 $
  * ------------------------------------------------------------------------*/
 
 typedef struct {                        /* Each type variable contains:    */
@@ -28,8 +33,8 @@ extern  List            btyvars;        /* explicitly scoped type vars     */
 #define tyvar(n)        (tyvars+(n))    /* nth type variable               */
 #define tyvNum(t)       ((t)-tyvars)    /* and the corresp. inverse funct. */
 #define isBound(t)      (((t)->bound) && ((t)->bound!=SKOLEM))
-#define aVar            mkOffset(0)     /* Simple skeleton for type var    */
-#define bVar            mkOffset(1)     /* Simple skeleton for type var    */
+#define aVar            mkOffset(0)     /* Simple skeletons for type vars  */
+#define bVar            mkOffset(1)
 #define enterBtyvs()    btyvars = cons(NIL,btyvars)
 #define leaveBtyvs()    btyvars = tl(btyvars)
 
@@ -62,6 +67,7 @@ extern Cell  getDerefHead       Args((Type,Int));
 extern Void  expandSyn          Args((Tycon, Int, Type *, Int *));
 
 extern Void  clearMarks         Args((Void));
+extern Void  markAllVars        Args((Void));
 extern Void  resetGenerics      Args((Void));
 extern Void  markTyvar          Args((Int));
 extern Void  markType           Args((Type,Int));
@@ -103,6 +109,4 @@ extern Inst  findInstFor        Args((Cell,Int));
 
 extern Bool  sameSchemes        Args((Type,Type));
 
-extern Bool  typeMatches        Args((Type,Type));
-
 /*-------------------------------------------------------------------------*/
index 0b0e697..fc2d407 100644 (file)
@@ -1,4 +1,7 @@
-/* -*- mode: hugs-c; -*- */
+<<<<<<<<<<<<<< variant A
+
+>>>>>>>>>>>>>> variant B
+======= end of combination
 /* --------------------------------------------------------------------------
  * This file provides a simple mechanism for measuring elapsed time on Unix
  * machines (more precisely, on any machine with an rusage() function).
  * optimizations, means that there are much more significant overheads than
  * can be accounted for by small variations in Hugs code.
  *
- * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
- * All rights reserved. See NOTICE for details and conditions of use etc...
- * Hugs version 1.4, December 1997
+ * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
+ * Haskell Group 1994-99, and is distributed as Open Source software
+ * under the Artistic License; see the file "Artistic" that is included
+ * in the distribution for details.
  *
  * $RCSfile: timer.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:46 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:43 $
  * ------------------------------------------------------------------------*/
 
 
index 5bac3c1..d87fa3e 100644 (file)
@@ -8,24 +8,18 @@
  * Hugs version 1.4, December 1997
  *
  * $RCSfile: translate.c,v $
- * $Revision: 1.3 $
- * $Date: 1999/01/13 16:47:26 $
+ * $Revision: 1.4 $
+ * $Date: 1999/02/03 17:08:44 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
 #include "storage.h"
+#include "backend.h"
 #include "connect.h"
 #include "errors.h"
-#include "stg.h"
-#include "compiler.h"
-#include "pmc.h"  /* for discrArity                 */
-#include "hugs.h" /* for debugCode                  */
-#include "type.h" /* for conToTagType, tagToConType */
 #include "link.h"
-#include "pp.h"
 #include "dynamic.h"
 #include "Assembler.h"
-#include "translate.h"
 
 /* ---------------------------------------------------------------- */
 
@@ -155,7 +149,7 @@ StgExpr failExpr;
         }
     case GUARDED:
         {   
-            List guards = reverse(snd(e));
+            List guards = rev(snd(e));
             e = failExpr;
             for(; nonNull(guards); guards=tl(guards)) {
                 Cell g   = hd(guards);
@@ -492,6 +486,8 @@ static StgExpr forceArgs( List is, List args, StgExpr e )
     return e;
 }
 
+#if 0
+ToDo: reinstate eventually
 /* \ v -> case v of { ...; Ci _ _ -> i; ... } */
 Void implementConToTag(t)
 Tycon t; {                    
@@ -592,6 +588,7 @@ Tycon t; {
         if (etxt) free(etxt);
     }
 }
+#endif
 
 Void implementCfun(c,scs)               /* Build implementation for constr */
 Name c;                                 /* fun c.  scs lists integers (1..)*/
@@ -826,7 +823,10 @@ String r_reps; {
 
     /* box results */
     if (strcmp(r_reps,"B") == 0) {
-        StgPrimAlt altF = mkStgPrimAlt(singleton(mkStgPrimVar(mkInt(0),mkStgRep(INT_REP),NIL)),
+        StgPrimAlt altF = mkStgPrimAlt(singleton(
+                                         mkStgPrimVar(mkInt(0),
+                                                      mkStgRep(INT_REP),NIL)
+                                       ),
                                        nameFalse);
         StgPrimAlt altT = mkStgPrimAlt(singleton(mkStgPrimVar(NIL,mkStgRep(INT_REP),NIL)),
                                        nameTrue);
@@ -839,7 +839,7 @@ String r_reps; {
     b_args = mkBoxedVars(a_reps);
     u_args = mkUnboxedVars(a_reps);
     if (addState) {
-        List actual_args = appendOnto(extra_args,dupListOnto(u_args,singleton(s0)));
+        List actual_args = appendOnto(extra_args,dupOnto(u_args,singleton(s0)));
         StgRhs rhs = makeStgLambda(singleton(s0),
                                    unboxVars(a_reps,b_args,u_args,
                                              mkStgPrimCase(mkStgPrim(op,actual_args),
index a95b8d0..40b7c03 100644 (file)
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
- * type.c:      Copyright (c) Mark P Jones 1991-1998.   All rights reserved.
- *              See NOTICE for details and conditions of use etc...
- *              Hugs version 1.3c, March 1998
- *
  * This is the Hugs type checker
+ *
+ * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
+ * Haskell Group 1994-99, and is distributed as Open Source software
+ * under the Artistic License; see the file "Artistic" that is included
+ * in the distribution for details.
+ *
+ * $RCSfile: type.c,v $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:44 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
 #include "storage.h"
+#include "backend.h"
 #include "connect.h"
-#include "input.h"
-#include "static.h"
-#include "hugs.h" /* for target   */
-#include "pat.h"  /* for failFree */
 #include "errors.h"
 #include "subst.h"
-#include "type.h"
-#include "link.h"
 #include "Assembler.h" /* for AsmCTypes */
 
 /*#define DEBUG_TYPES*/
 /*#define DEBUG_KINDS*/
 /*#define DEBUG_DEFAULTS*/
 /*#define DEBUG_SELS*/
-/*#define DEBUG_CODE*/
 /*#define DEBUG_DEPENDS*/
 /*#define DEBUG_DERIVING*/
+/*#define DEBUG_CODE*/
 
 Bool catchAmbigs       = FALSE;         /* TRUE => functions with ambig.   */
                                         /*         types produce error     */
 
+#if 1
+//ToDo: perhaps this should be somewhere else (link.c?)
+//all this stuff came with 98, and not STG
+Type typeArrow,   typeList;             /* Important primitive types       */
+Type typeUnit;
+
+Module modulePrelude;
+
+static Type typeInt,     typeDouble;
+static Type typeInteger, typeAddr;
+static Type typeString,  typeChar;
+static Type typeBool,    typeMaybe;
+static Type typeOrdering;
+
+Class classEq,    classOrd;             /* `standard' classes              */
+Class classIx,    classEnum;
+Class classShow,  classRead;
+#if EVAL_INSTANCES
+Class classEval;
+#endif
+Class classBounded;
+
+Class classReal,       classIntegral;   /* `numeric' classes               */
+Class classRealFrac,   classRealFloat;
+Class classFractional, classFloating;
+Class classNum;
+
+List stdDefaults;                       /* standard default values         */
+
+Name nameFromInt, nameFromDouble;       /* coercion of numerics            */
+Name nameFromInteger;
+Name nameEq,      nameCompare;          /* derivable names                 */
+Name nameLe;
+Name nameShowsPrec;
+Name nameReadsPrec;
+Name nameMinBnd,  nameMaxBnd;
+Name nameIndex,   nameInRange;
+Name nameRange;
+Name nameMult,    namePlus;
+Name nameTrue,    nameFalse;            /* primitive boolean constructors  */
+Name nameNil,     nameCons;             /* primitive list constructors     */
+Name nameJust,    nameNothing;          /* primitive Maybe constructors    */
+Name nameLeft,    nameRight;            /* primitive Either constructors   */
+Name nameUnit;                          /* primitive Unit type constructor */
+Name nameLT,      nameEQ;               /* Ordering constructors           */
+Name nameGT;
+Class classMonad;                       /* Monads                          */
+Name nameReturn,  nameBind;             /* for translating monad comps     */
+Name nameMFail;
+Name nameGt;                            /* for readsPrec                   */
+#if EVAL_INSTANCES
+Name nameStrict,  nameSeq;              /* Members of class Eval           */
+#endif
+
+#if    IO_MONAD
+Type   typeProgIO;                      /* For the IO monad, IO ()         */
+Name   nameUserErr;                     /* loosely coupled IOError cfuns   */
+Name   nameNameErr,  nameSearchErr;
+#endif
+#if    IO_HANDLES
+Name   nameWriteErr, nameIllegal;
+Name   nameEOFErr;
+#endif
+
+#if TREX
+Type  typeNoRow;                        /* Empty row                       */
+Type  typeRec;                          /* Record formation                */
+Name  nameNoRec;                        /* Empty record                    */
+#endif
+
+//end ToDo
+#endif
+
 /* --------------------------------------------------------------------------
  * Local function prototypes:
  * ------------------------------------------------------------------------*/
@@ -53,6 +126,8 @@ static Void   local enterPendingBtyvs Args((Void));
 static Void   local leavePendingBtyvs Args((Void));
 static Cell   local patBtyvs          Args((Cell));
 static Void   local doneBtyvs         Args((Int));
+static Void   local enterSkolVars     Args((Void));
+static Void   local leaveSkolVars     Args((Int,Type,Int,Int));
 
 static Void   local typeError         Args((Int,Cell,Cell,String,Type,Int));
 static Void   local reportTypeError   Args((Int,Cell,Cell,String,Type,Type));
@@ -67,8 +142,8 @@ static Void   local typeAlt           Args((String,Cell,Cell,Type,Int,Int));
 static Int    local funcType          Args((Int));
 static Void   local typeCase          Args((Int,Int,Cell));
 static Void   local typeComp          Args((Int,Type,Cell,List));
+static Cell   local typeMonadComp     Args((Int,Cell));
 static Void   local typeDo            Args((Int,Cell));
-static Cell   local compZero          Args((List,Int));
 static Void   local typeConFlds       Args((Int,Cell));
 static Void   local typeUpdFlds       Args((Int,Cell));
 static Cell   local typeFreshPat      Args((Int,Cell));
@@ -102,21 +177,26 @@ static Bool   local equalTypes        Args((Type,Type));
 static Void   local typeDefnGroup     Args((List));
 static Pair   local typeSel           Args((Name));
 
+static List   offsetTyvarsIn          Args((Type,List));
+static Type   conToTagType            Args((Tycon));
+static Type   tagToConType            Args((Tycon));
+
+
 /* --------------------------------------------------------------------------
  * Frequently used type skeletons:
  * ------------------------------------------------------------------------*/
 
-static Type  arrow;                     /* mkOffset(0) -> mkOffset(1)      */
+/* ToDo: move these to link.c and call them 'typeXXXX' */
+       Type  arrow;                     /* mkOffset(0) -> mkOffset(1)      */
 static Type  boundPair;                 /* (mkOffset(0),mkOffset(0))       */
-static Type  listof;                    /* [ mkOffset(0) ]                 */
+       Type  listof;                    /* [ mkOffset(0) ]                 */
 static Type  typeVarToVar;              /* mkOffset(0) -> mkOffset(0)      */
 
-static Cell  predNum;                   /* Num (mkOffset(0))               */
-static Cell  predFractional;            /* Fractional (mkOffset(0))        */
-static Cell  predIntegral;              /* Integral (mkOffset(0))          */
+       Cell  predNum;                   /* Num (mkOffset(0))               */
+       Cell  predFractional;            /* Fractional (mkOffset(0))        */
+       Cell  predIntegral;              /* Integral (mkOffset(0))          */
 static Kind  starToStar;                /* Type -> Type                    */
-static Cell  predMonad;                 /* Monad (mkOffset(0))             */
-static Cell  predMonad0;                /* Monad0 (mkOffset(0))            */
+       Cell  predMonad;                 /* Monad (mkOffset(0))             */
 
 /* --------------------------------------------------------------------------
  * Assumptions:
@@ -153,6 +233,8 @@ static List defnBounds;                 /*::[[(Var,Type)]] possibly ovrlded*/
 static List varsBounds;                 /*::[[(Var,Type)]] not overloaded  */
 static List depends;                    /*::[?[Var]] dependents/NODEPENDS  */
 static List skolVars;                   /*::[[Var]] skolem vars            */
+static List localEvs;                   /*::[[(Pred,offset,ev)]]           */
+static List savedPs;                    /*::[[(Pred,offset,ev)]]           */
 static Cell dummyVar;                   /* Used to put extra tvars into ass*/
 
 #define saveVarsAss()     List saveAssump = hd(varsBounds)
@@ -165,6 +247,8 @@ static Void local emptyAssumption() {   /* set empty type assumption       */
     varsBounds = NIL;
     depends    = NIL;
     skolVars   = NIL;
+    localEvs   = NIL;
+    savedPs    = NIL;
 }
 
 static Void local enterBindings() {    /* Add new level to assumption sets */
@@ -279,9 +363,9 @@ Cell v; {
     Int beta = newTyvars(1);
     addVarAssump(v,mkInt(beta));
 #ifdef DEBUG_TYPES
-    printf("variable, assume ");
+    Printf("variable, assume ");
     printExp(stdout,v);
-    printf(" :: _%d\n",beta);
+    Printf(" :: _%d\n",beta);
 #endif
     return beta;
 }
@@ -296,14 +380,20 @@ Type type; {
         ta = pair(POLYREC,pair(ta,type));
     hd(defnBounds) = cons(pair(v,ta), hd(defnBounds));
 #ifdef DEBUG_TYPES
-    printf("definition, assume ");
+    Printf("definition, assume ");
     printExp(stdout,v);
-    printf(" :: _%d\n",beta);
+    Printf(" :: _%d\n",beta);
 #endif
     bindTv(beta,typeIs,typeOff);       /* Bind beta to new type skeleton   */
 }
 
 /* --------------------------------------------------------------------------
+ * Predicates:
+ * ------------------------------------------------------------------------*/
+
+#include "preds.c"
+
+/* --------------------------------------------------------------------------
  * Bound and skolemized type variables:
  * ------------------------------------------------------------------------*/
 
@@ -360,7 +450,6 @@ Cell p; {
             snd(hd(bts))      = mkInt(beta);
         }
     }
-    skolVars = cons(NIL,skolVars);
     return p;
 }
 
@@ -370,23 +459,54 @@ Int l; {
         hd(pendingBtyvs) = cons(pair(mkInt(l),hd(btyvars)),hd(pendingBtyvs));
         hd(btyvars)      = NIL;
     }
+}
+
+static Void local enterSkolVars() {
+    skolVars = cons(NIL,skolVars);
+    localEvs = cons(NIL,localEvs);
+    savedPs  = cons(preds,savedPs);
+    preds    = NIL;
+}
+
+static Void local leaveSkolVars(l,t,o,m)
+Int  l;
+Type t;
+Int  o;
+Int  m; {
+    if (nonNull(hd(localEvs))) {        /* Check for local predicates      */
+        List sks = hd(skolVars);
+        List sps = NIL;
+        if (isNull(sks)) {
+            internal("leaveSkolVars");
+        }
+        markAllVars();                  /* Mark all variables in current   */
+        do {                            /* substitution, then unmark sks.  */
+            tyvar(intOf(fst(hd(sks))))->offs = UNUSED_GENERIC;
+            sks = tl(sks);
+        } while (nonNull(sks));
+        sps   = elimPredsUsing(hd(localEvs),sps);
+        preds = revOnto(preds,sps);
+    }
 
     if (nonNull(hd(skolVars))) {        /* Check that Skolem vars do not   */
         List vs;                        /* escape their scope              */
+        Int  i = 0;
 
         clearMarks();                   /* Look for occurences in the      */
-        markType(typeIs,typeOff);       /* result type                     */
+        for (; i<m; i++)                /* inferred type                   */
+            markTyvar(o+i);
+        markType(t,o);
 
         for (vs=hd(skolVars); nonNull(vs); vs=tl(vs)) {
             Int vn = intOf(fst(hd(vs)));
             if (tyvar(vn)->offs == FIXED_TYVAR) {
                 Cell tv = copyTyvar(vn);
-                Type t  = copyType(typeIs,typeOff);
-                ERRMSG(l) "Existentially quantified variable in result type"
+                Type ty = liftRank2(t,o,m);
+                ERRMSG(l) "Existentially quantified variable in inferred type"
                 ETHEN
-                ERRTEXT   "\nvariable     : " ETHEN ERRTYPE(tv);
-                ERRTEXT   "\nfrom pattern : " ETHEN ERREXPR(snd(hd(vs)));
-                ERRTEXT   "\nresult type  : " ETHEN ERRTYPE(t);
+                ERRTEXT   "\n*** Variable     : " ETHEN ERRTYPE(tv);
+                ERRTEXT   "\n*** From pattern : " ETHEN ERREXPR(snd(hd(vs)));
+                ERRTEXT   "\n*** Result type  : " ETHEN ERRTYPE(ty);
                 ERRTEXT   "\n"
                 EEND;
             }
@@ -399,23 +519,21 @@ Int l; {
         for (vs=hd(skolVars); nonNull(vs); vs=tl(vs)) {
             Int vn = intOf(fst(hd(vs)));
             if (tyvar(vn)->offs == FIXED_TYVAR) {
-                ERRMSG(l) "Existentially quantified variable from pattern "
+                ERRMSG(l)
+                  "Existentially quantified variable escapes from pattern "
                 ETHEN ERREXPR(snd(hd(vs)));
-                ERRTEXT   " appears in enclosing assumptions"   /*so there!*/
+                ERRTEXT "\n"
                 EEND;
             }
         }
     }
+    localEvs = tl(localEvs);
     skolVars = tl(skolVars);
+    preds    = revOnto(preds,hd(savedPs));
+    savedPs  = tl(savedPs);
 }
 
 /* --------------------------------------------------------------------------
- * Predicates:
- * ------------------------------------------------------------------------*/
-
-#include "preds.c"
-
-/* --------------------------------------------------------------------------
  * Type errors:
  * ------------------------------------------------------------------------*/
 
@@ -433,9 +551,9 @@ Int    o; {                           /* type inferred is (typeIs,typeOff) */
 { List vs = genericVars;
   for (; nonNull(vs); vs=tl(vs)) {
      Int v = intOf(hd(vs));
-     printf("%c :: ", ('a'+tyvar(v)->offs));
+     Printf("%c :: ", ('a'+tyvar(v)->offs));
      printKind(stdout,tyvar(v)->kind);
-     putchar('\n');
+     Putchar('\n');
   }
 }
 #endif
@@ -511,13 +629,13 @@ Cell e; {
     static int number = 0;
     Cell retv;
     int  mynumber = number++;
-    printf("%d) to check: ",mynumber);
+    Printf("%d) to check: ",mynumber);
     printExp(stdout,e);
-    putchar('\n');
+    Putchar('\n');
     retv = mytypeExpr(l,e);
-    printf("%d) result: ",mynumber);
+    Printf("%d) result: ",mynumber);
     printType(stdout,debugType(typeIs,typeOff));
-    putchar('\n');
+    Putchar('\n');
     return retv;
 }
 static Cell local mytypeExpr(l,e)       /* Determine type of expr/pattern  */
@@ -545,35 +663,29 @@ Cell e; {
         case TUPLE      : typeTuple(e);
                           break;
 
-#if OVERLOADED_CONSTANTS
-        case BIGCELL    : {   Int alpha = newTyvars(1);
+#if BIGNUMS
+        case POSNUM     :
+        case ZERONUM    :
+        case NEGNUM     : {   Int alpha = newTyvars(1);
                               inferType(aVar,alpha);
-                              return ap2(nameFromInteger,
-                                         assumeEvid(predNum,alpha),
-                                         e);
+                              return ap(ap(nameFromInteger,
+                                           assumeEvid(predNum,alpha)),
+                                           e);
                           }
-
+#endif
         case INTCELL    : {   Int alpha = newTyvars(1);
                               inferType(aVar,alpha);
-                              return ap2(nameFromInt,
-                                         assumeEvid(predNum,alpha),
-                                         e);
+                              return ap(ap(nameFromInt,
+                                           assumeEvid(predNum,alpha)),
+                                           e);
                           }
 
         case FLOATCELL  : {   Int alpha = newTyvars(1);
                               inferType(aVar,alpha);
-                              return ap2(nameFromDouble,
-                                         assumeEvid(predFractional,alpha),
-                                         e);
+                              return ap(ap(nameFromDouble,
+                                           assumeEvid(predFractional,alpha)),
+                                           e);
                           }
-#else
-        case BIGCELL    : inferType(typeBignum,0);
-                          break;
-        case INTCELL    : inferType(typeInt,0);
-                          break;
-        case FLOATCELL  : inferType(typeFloat,0);
-                          break;
-#endif
 
         case STRCELL    : inferType(typeString,0);
                           break;
@@ -592,10 +704,9 @@ Cell e; {
 #if TREX
         case EXT        : {   Int beta = newTyvars(2);
                               Cell pi  = ap(e,aVar);
-                              Type t   = fn(mkOffset(0),
-                                         fn(ap(typeRec,mkOffset(1)),
-                                            ap(typeRec,ap2(e,mkOffset(0),
-                                                           mkOffset(1)))));
+                              Type t   = fn(aVar,
+                                         fn(ap(typeRec,bVar),
+                                            ap(typeRec,ap(ap(e,aVar),bVar))));
                               tyvar(beta+1)->kind = ROW;
                               inferType(t,beta);
                               return ap(e,assumeEvid(pi,beta+1));
@@ -616,9 +727,11 @@ Cell e; {
                           break;
 
         case LETREC     : enterBindings();
+                          enterSkolVars();
                           mapProc(typeBindings,fst(snd(e)));
                           snd(snd(e)) = typeExpr(l,snd(snd(e)));
                           leaveBindings();
+                          leaveSkolVars(l,typeIs,typeOff,0);
                           break;
 
         case FINLIST    : {   Int  beta = newTyvars(1);
@@ -633,12 +746,7 @@ Cell e; {
         case DOCOMP     : typeDo(l,e);
                           break;
 
-        case COMP       : {   Int beta = newTyvars(1);
-                              typeComp(l,listof,snd(e),snd(snd(e)));
-                              bindTv(beta,typeIs,typeOff);
-                              inferType(listof,beta);
-                          }
-                          break;
+        case COMP       : return typeMonadComp(l,e);
 
         case CASE       : {    Int beta = newTyvars(2);    /* discr result */
                                check(l,fst(snd(e)),NIL,discr,aVar,beta);
@@ -659,8 +767,8 @@ Cell e; {
         case RECSEL     : {   Int beta = newTyvars(2);
                               Cell pi  = ap(snd(e),aVar);
                               Type t   = fn(ap(typeRec,
-                                               ap2(snd(e),mkOffset(0),
-                                                   mkOffset(1))),aVar);
+                                               ap(ap(snd(e),aVar),
+                                                            bVar)),aVar);
                               tyvar(beta+1)->kind = ROW;
                               inferType(t,beta);
                               return ap(e,assumeEvid(pi,beta+1));
@@ -744,19 +852,35 @@ Cell e; {                               /* requires polymorphism, qualified*/
 
     instantiate(typeIs);                /* Deal with polymorphism ...      */
     if (nonNull(predsAre)) {            /* ... and with qualified types.   */
-        Cell evs = NIL;
-        for (; nonNull(predsAre); predsAre=tl(predsAre))
+        List evs = NIL;
+        for (; nonNull(predsAre); predsAre=tl(predsAre)) {
             evs = cons(assumeEvid(hd(predsAre),typeOff),evs);
-        if (!isName(h) || !isCfun(h))
+        }
+        if (!isName(h) || !isCfun(h)) {
             h = applyToArgs(h,rev(evs));
+        }
+    }
+
+    if (whatIs(typeIs)==CDICTS) {       /* Deal with local dictionaries    */
+        List evs = makePredAss(fst(snd(typeIs)),typeOff);
+        List ps  = evs;
+        typeIs   = snd(snd(typeIs));
+        for (; nonNull(ps); ps=tl(ps)) {
+            h = ap(h,thd3(hd(ps)));
+        }
+        if (tcMode==EXPRESSION) {
+            preds = revOnto(evs,preds);
+        } else {
+            hd(localEvs) = revOnto(evs,hd(localEvs));
+        }
     }
 
     if (whatIs(typeIs)==EXIST) {        /* Deal with existential arguments */
         Int n  = intOf(fst(snd(typeIs)));
         typeIs = snd(snd(typeIs));
-        if (!isCfun(h) || n>typeFree)
+        if (!isCfun(getHead(h)) || n>typeFree) {
             internal("typeAp2");
-        else if (tcMode!=EXPRESSION) {
+        } else if (tcMode!=EXPRESSION) {
             Int alpha = typeOff + typeFree;
             for (; n>0; n--) {
                 bindTv(alpha-n,SKOLEM,0);
@@ -927,6 +1051,7 @@ Int    m; {
     Bool added = FALSE;
 
     saveVarsAss();
+    enterSkolVars();
     if (whatIs(t)==RANK2) {
         if (n<(nr2=intOf(fst(snd(t))))) {
             ERRMSG(l) "Definition requires at least %d parameters on lhs",
@@ -990,6 +1115,7 @@ Int    m; {
 
     restoreVarsAss();
     doneBtyvs(l);
+    leaveSkolVars(l,origt,o,m);
 }
 
 static Int local funcType(n)            /*return skeleton for function type*/
@@ -1009,7 +1135,7 @@ Cell c; {                              /*        rhs :: (var,beta+1)       */
     static String caseExpr = "case expression";
 
     saveVarsAss();
-
+    enterSkolVars();
     fst(c) = typeFreshPat(l,patBtyvs(fst(c)));
     shouldBe(l,fst(c),NIL,casePat,aVar,beta);
     snd(c) = typeRhs(snd(c));
@@ -1017,6 +1143,7 @@ Cell c; {                              /*        rhs :: (var,beta+1)       */
 
     restoreVarsAss();
     doneBtyvs(l);
+    leaveSkolVars(l,typeIs,typeOff,0);
 }
 
 static Void local typeComp(l,m,e,qs)    /* type check comprehension        */
@@ -1038,20 +1165,24 @@ List qs; {
                             break;
 
             case QWHERE   : enterBindings();
+                            enterSkolVars();
                             mapProc(typeBindings,snd(q));
                             typeComp(l,m,e,qs1);
                             leaveBindings();
+                            leaveSkolVars(l,typeIs,typeOff,0);
                             break;
 
             case FROMQUAL : {   Int beta = newTyvars(1);
                                 saveVarsAss();
                                 check(l,snd(snd(q)),NIL,genQual,m,beta);
+                                enterSkolVars();
                                 fst(snd(q))
                                     = typeFreshPat(l,patBtyvs(fst(snd(q))));
                                 shouldBe(l,fst(snd(q)),NIL,genQual,aVar,beta);
                                 typeComp(l,m,e,qs1);
                                 restoreVarsAss();
                                 doneBtyvs(l);
+                                leaveSkolVars(l,typeIs,typeOff,0);
                             }
                             break;
 
@@ -1062,6 +1193,24 @@ List qs; {
     }
 }
 
+static Cell local typeMonadComp(l,e)    /* type check monad comprehension  */
+Int  l;
+Cell e; {
+    Int  alpha        = newTyvars(1);
+    Int  beta         = newTyvars(1);
+    Cell mon          = ap(mkInt(beta),aVar);
+    Cell m            = assumeEvid(predMonad,beta);
+    tyvar(beta)->kind = starToStar;
+#if !MONAD_COMPS
+    bindTv(beta,typeList,0);
+#endif
+
+    typeComp(l,mon,snd(e),snd(snd(e)));
+    bindTv(alpha,typeIs,typeOff);
+    inferType(mon,alpha);
+    return ap(MONADCOMP,pair(m,snd(e)));
+}
+
 static Void local typeDo(l,e)           /* type check do-notation          */
 Int  l;
 Cell e; {
@@ -1074,20 +1223,7 @@ Cell e; {
 
     typeComp(l,mon,snd(e),snd(snd(e)));
     shouldBe(l,fst(snd(e)),NIL,finGen,mon,alpha);
-    snd(e) = pair(pair(m,compZero(snd(snd(e)),beta)),snd(e));
-}
-
-static Cell local compZero(qs,beta)     /* return evidence for Monad0 beta */
-List qs;                                /* if needed for qualifiers qs     */
-Int  beta; {
-    for (; nonNull(qs); qs=tl(qs))
-        switch (whatIs(hd(qs))) {
-            case FROMQUAL : if (failFree(fst(snd(hd(qs)))))
-                                break;
-                            /* intentional fall-thru */
-            case BOOLQUAL : return assumeEvid(predMonad0,beta);
-        }
-    return NIL;
+    snd(e) = pair(m,snd(e));
 }
 
 static Void local typeConFlds(l,e)      /* Type check a construction       */
@@ -1330,23 +1466,24 @@ Cell b; {                               /* gp with restricted overloading  */
 
     if (isVar(fst(b))) {                /* function-binding?               */
         Cell t = fst(snd(b));
-        if (whatIs(t)==IMPDEPS)         /* Discard implicitly typed deps   */
+        if (whatIs(t)==IMPDEPS)  {      /* Discard implicitly typed deps   */
             fst(snd(b)) = t = NIL;      /* in a restricted binding group.  */
+        }
         fst(snd(b)) = localizeBtyvs(t);
         restrictedAss(rhsLine(snd(hd(snd(snd(b))))), fst(b), t);
-    }
-    else {                              /* pattern-binding?                */
+    } else {                            /* pattern-binding?                */
         List vs   = fst(b);
         List ts   = fst(snd(b));
         Int  line = rhsLine(snd(snd(snd(b))));
 
-        for (; nonNull(vs); vs=tl(vs))
+        for (; nonNull(vs); vs=tl(vs)) {
             if (nonNull(ts)) {
                 restrictedAss(line,hd(vs),hd(ts)=localizeBtyvs(hd(ts)));
                 ts = tl(ts);
-            }
-            else
+            } else {
                 restrictedAss(line,hd(vs),NIL);
+            }
+        }
     }
 }
 
@@ -1408,20 +1545,20 @@ List bs; {
             fst(snd(hd(bs1))) = NIL;    /* reset imps type fields          */
 
 #ifdef DEBUG_DEPENDS
-    printf("Binding group:");
+    Printf("Binding group:");
     for (bs1=imps; nonNull(bs1); bs1=tl(bs1)) {
-        printf(" [imp:");
+        Printf(" [imp:");
         for (bs=hd(bs1); nonNull(bs); bs=tl(bs))
-            printf(" %s",textToStr(textOf(fst(hd(bs)))));
-        printf("]");
+            Printf(" %s",textToStr(textOf(fst(hd(bs)))));
+        Printf("]");
     }
     if (nonNull(exps)) {
-        printf(" [exp:");
+        Printf(" [exp:");
         for (bs=exps; nonNull(bs); bs=tl(bs))
-            printf(" %s",textToStr(textOf(fst(hd(bs)))));
-        printf("]");
+            Printf(" %s",textToStr(textOf(fst(hd(bs)))));
+        Printf("]");
     }
-    printf("\n");
+    Printf("\n");
 #endif
 
     /* ----------------------------------------------------------------------
@@ -1458,8 +1595,9 @@ List bs; {
 
         normPreds(line);
         savePreds = elimOuterPreds(savePreds);
-        if (nonNull(preds) && resolveDefs(genvarAllAss(hd(defnBounds))))
+        if (nonNull(preds) && resolveDefs(genvarAllAss(hd(defnBounds)))) {
             savePreds = elimOuterPreds(savePreds);
+        }
 
         map1Proc(genBind,preds,hd(imps));
         if (nonNull(preds)) {
@@ -1467,6 +1605,8 @@ List bs; {
             map1Proc(qualifyBinding,preds,hd(imps));
         }
 
+        h98CheckType(line,"inferred type",
+                        fst(hd(hd(defnBounds))),snd(hd(hd(defnBounds))));
         hd(varsBounds) = revOnto(hd(defnBounds),hd(varsBounds));
     }
 
@@ -1528,8 +1668,10 @@ List bs; {
         resetGenerics();                /* Make sure we're general enough  */
         ps = copyPreds(ps);
         t  = generalize(ps,liftRank2(t,o,m));
+
         if (!sameSchemes(t,fst(snd(b))))
             tooGeneral(line,fst(b),fst(snd(b)),t);
+        h98CheckType(line,"inferred type",fst(b),t);
 
         if (nonNull(preds))             /* Check context was strong enough */
             cantEstablish(line,extbind,fst(b),t,ps);
@@ -1722,18 +1864,18 @@ Inst in; {                              /* member functions for instance in*/
 
     for (ps=supers; nonNull(ps); ps=tl(ps)) {   /* Superclass dictionaries */
         Cell pi = hd(ps);
-        Cell ev = scEntail(params,fst3(pi),intOf(snd3(pi)));
-        if (isNull(ev)) 
-            ev = inEntail(evids,fst3(pi),intOf(snd3(pi)));
+        Cell ev = scEntail(params,fst3(pi),intOf(snd3(pi)),0);
+        if (isNull(ev))
+            ev = inEntail(evids,fst3(pi),intOf(snd3(pi)),0);
         if (isNull(ev)) {
             clearMarks();
             ERRMSG(inst(in).line) "Cannot build superclass instance" ETHEN
             ERRTEXT "\n*** Instance            : " ETHEN
-                    ERRPRED(copyPred(inst(in).head,beta));
+                ERRPRED(copyPred(inst(in).head,beta));
             ERRTEXT "\n*** Context supplied    : " ETHEN
-                    ERRCONTEXT(copyPreds(params));
+                ERRCONTEXT(copyPreds(params));
             ERRTEXT "\n*** Required superclass : " ETHEN
-                    ERRPRED(copyPred(fst3(pi),intOf(snd3(pi))));
+                ERRPRED(copyPred(fst3(pi),intOf(snd3(pi))));
             ERRTEXT "\n"
             EEND;
         }
@@ -1814,13 +1956,13 @@ Int    beta; {
     Type rt;
 
 #ifdef DEBUG_TYPES
-    printf("Type check member: ");
+    Printf("Type check member: ");
     printExp(stdout,mem);
-    printf(" :: ");
+    Printf(" :: ");
     printType(stdout,name(mem).type);
-    printf("\nfor the instance: ");
+    Printf("\nfor the instance: ");
     printPred(stdout,head);
-    printf("\n");
+    Printf("\n");
 #endif
 
     instantiate(name(mem).type);        /* Find required type              */
@@ -1835,9 +1977,9 @@ Int    beta; {
     rt = generalize(qs,liftRank2(t,o,m));
 
 #ifdef DEBUG_TYPES
-    printf("Required type is: ");
+    Printf("Required type is: ");
     printType(stdout,rt);
-    printf("\n");
+    Printf("\n");
 #endif
 
     hd(defnBounds) = NIL;               /* Type check each alternative     */
@@ -1869,9 +2011,9 @@ Int    beta; {
     ps = copyPreds(ps);
     t  = generalize(ps,liftRank2(t,o,m));
 #ifdef DEBUG_TYPES
-    printf("Inferred type is: ");
+    Printf("Inferred type is: ");
     printType(stdout,t);
-    printf("\n");
+    Printf("\n");
 #endif
     if (!sameSchemes(t,rt))
         tooGeneral(line,mem,rt,t);
@@ -1905,10 +2047,14 @@ Cell b; {
         Int  l               = rhsLine(snd(pb));
 
         tcMode  = OLD_PATTERN;
+        enterPendingBtyvs();
+        fst(pb) = patBtyvs(fst(pb));
         check(l,fst(pb),NIL,lhsPat,aVar,beta);
         tcMode  = EXPRESSION;
         snd(pb) = typeRhs(snd(pb));
         shouldBe(l,rhsExpr(snd(pb)),NIL,rhs,aVar,beta);
+        doneBtyvs(l);
+        leavePendingBtyvs();
     }
 }
 
@@ -1930,11 +2076,20 @@ Cell e; {
                        break;
 
         case LETREC  : enterBindings();
+                       enterSkolVars();
                        mapProc(typeBindings,fst(snd(e)));
                        snd(snd(e)) = typeRhs(snd(snd(e)));
                        leaveBindings();
+                       leaveSkolVars(rhsLine(snd(snd(e))),typeIs,typeOff,0);
                        break;
 
+        case RSIGN   : fst(snd(e)) = typeRhs(fst(snd(e)));
+                       shouldBe(rhsLine(fst(snd(e))),
+                                rhsExpr(fst(snd(e))),NIL,
+                                "result type",
+                                snd(snd(e)),0);
+                       return fst(snd(e));
+
         default      : snd(e) = typeExpr(intOf(fst(e)),snd(e));
                        break;
     }
@@ -1958,6 +2113,7 @@ Cell rhs; {
     switch (whatIs(rhs)) {
         case GUARDED : return snd(snd(hd(snd(rhs))));
         case LETREC  : return rhsExpr(snd(snd(rhs)));
+        case RSIGN   : return rhsExpr(fst(snd(rhs)));
         default      : return snd(rhs);
     }
 }
@@ -1967,6 +2123,7 @@ Cell rhs; {                            /* a right hand side                */
     switch (whatIs(rhs)) {
         case GUARDED : return intOf(fst(hd(snd(rhs))));
         case LETREC  : return rhsLine(snd(snd(rhs)));
+        case RSIGN   : return rhsLine(fst(snd(rhs)));
         default      : return intOf(fst(rhs));
     }
 }
@@ -2010,9 +2167,9 @@ Type dt; {
 
 #ifdef DEBUG_TYPES
     printExp(stdout,v);
-    printf(" :: ");
+    Printf(" :: ");
     printType(stdout,snd(ass));
-    printf("\n");
+    Printf("\n");
 #endif
 }
 
@@ -2058,11 +2215,11 @@ Type t; {                               /* with qualifying preds qs        */
         }
         t = mkPolyType(k,t);
 #ifdef DEBUG_KINDS
-    printf("Generalized type: ");
+    Printf("Generalized type: ");
     printType(stdout,t);
-    printf(" ::: ");
+    Printf(" ::: ");
     printKind(stdout,k);
-    printf("\n");
+    Printf("\n");
 #endif
     }
     return t;
@@ -2127,6 +2284,7 @@ Bool useDefs; {                         /* using defaults if reqd          */
     ctxt      = copyPreds(preds);
     type      = generalize(ctxt,copyType(type,beta));
     inputExpr = qualifyExpr(0,preds,inputExpr);
+    h98CheckType(0,"inferred type",inputExpr,type);
     typeChecker(RESET);
     emptySubstitution();
     return type;
@@ -2140,6 +2298,7 @@ Void typeCheckDefns() {                /* Type check top level bindings    */
 
     typeChecker(RESET);
     emptySubstitution();
+    enterSkolVars();
     enterBindings();
     setGoal("Type checking",t);
 
@@ -2191,6 +2350,14 @@ List bs; {                              /* (one top level scc)             */
         EEND;
     }
 
+    if (nonNull(hd(skolVars))) {
+        Cell b = hd(bs);
+        Name n = findName(isVar(fst(b)) ? textOf(fst(b)) : textOf(hd(fst(b))));
+        Int  l = nonNull(n) ? name(n).line : 0;
+        leaveSkolVars(l,typeUnit,0,0);
+        enterSkolVars();
+    }
+
     for (as=hd(varsBounds); nonNull(as); as=tl(as)) {
         Cell a = hd(as);                /* add infered types to environment*/
         Name n = findName(textOf(fst(a)));
@@ -2213,9 +2380,9 @@ Name s; {                               /* particular selector, s.         */
     Int  m;
 
 #ifdef DEBUG_SELS
-    printf("Selector %s, cns=",textToStr(name(s).text));
+    Printf("Selector %s, cns=",textToStr(name(s).text));
     printExp(stdout,cns);
-    putchar('\n');
+    Putchar('\n');
 #endif
 
     emptySubstitution();
@@ -2302,14 +2469,15 @@ Name s; {                               /* particular selector, s.         */
     map1Proc(qualify,preds,alts);
 
 #ifdef DEBUG_SELS
-    printf("Inferred arity = %d, type = ",name(s).arity);
+    Printf("Inferred arity = %d, type = ",name(s).arity);
     printType(stdout,name(s).type);
-    putchar('\n');
+    Putchar('\n');
 #endif
 
     return pair(s,alts);
 }
 
+
 /* --------------------------------------------------------------------------
  * Local function prototypes:
  * ------------------------------------------------------------------------*/
@@ -2320,7 +2488,7 @@ static Type local basicType Args((Char));
  * 
  * ------------------------------------------------------------------------*/
 
-List offsetTyvarsIn(t,vs)               /* add list of offset tyvars in t  */
+static List offsetTyvarsIn(t,vs)        /* add list of offset tyvars in t  */
 Type t;                                 /* to list vs                      */
 List vs; {
     switch (whatIs(t)) {
@@ -2347,6 +2515,7 @@ List vs; {
 static Type stateVar = NIL;
 static Type alphaVar = NIL;
 static Type betaVar  = NIL;
+static Type gammaVar = NIL;
 static Int  nextVar  = 0;
 
 static Void clearTyVars( void )
@@ -2354,6 +2523,7 @@ static Void clearTyVars( void )
     stateVar = NIL;
     alphaVar = NIL;
     betaVar  = NIL;
+    gammaVar = NIL;
     nextVar  = 0;
 }
 
@@ -2381,6 +2551,14 @@ static Type mkBetaVar( void )
     return betaVar;
 }
 
+static Type mkGammaVar( void )
+{
+    if (isNull(gammaVar)) {
+        gammaVar = mkOffset(nextVar++);
+    }
+    return gammaVar;
+}
+
 static Type local basicType(k)
 Char k; {
     switch (k) {
@@ -2445,10 +2623,13 @@ Char k; {
             return mkAlphaVar();  /* polymorphic */
     case BETA_REP:
             return mkBetaVar();   /* polymorphic */
+    case GAMMA_REP:
+            return mkGammaVar();   /* polymorphic */
     default:
             printf("Kind: '%c'\n",k);
             internal("basicType");
     }
+    assert(0); return 0; /* NOTREACHED */
 }
 
 /* Generate type of primop based on list of arg types and result types:
@@ -2508,7 +2689,7 @@ Type primType( Int /*AsmMonad*/ monad, String a_kinds, String r_kinds )
 }    
 
 /* forall a1 .. am. TC a1 ... am -> Int */
-Type conToTagType(t)
+static Type conToTagType(t)
 Tycon t; {
     Type   ty  = t;
     List   tvars = NIL;
@@ -2526,7 +2707,7 @@ Tycon t; {
 }
 
 /* forall a1 .. am. Int -> TC a1 ... am */
-Type tagToConType(t)
+static Type tagToConType(t)
 Tycon t; {
     Type   ty  = t;
     List   tvars = NIL;
@@ -2547,17 +2728,6 @@ Tycon t; {
  * Type checker control:
  * ------------------------------------------------------------------------*/
 
-Void mkTypes()
-{
-    arrow          = fn(aVar,mkOffset(1));
-    listof         = ap(typeList,aVar);
-    predNum        = ap(classNum,aVar);
-    predFractional = ap(classFractional,aVar);
-    predIntegral   = ap(classIntegral,aVar);
-    predMonad      = ap(classMonad,aVar);
-    predMonad0     = ap(classMonad0,aVar);
-}
-
 Void typeChecker(what)
 Int what; {
     switch (what) {
@@ -2572,6 +2742,8 @@ Int what; {
                        mark(depends);
                        mark(pendingBtyvs);
                        mark(skolVars);
+                       mark(localEvs);
+                       mark(savedPs);
                        mark(dummyVar);
                        mark(preds);
                        mark(stdDefaults);
@@ -2584,13 +2756,77 @@ Int what; {
                        mark(predIntegral);
                        mark(starToStar);
                        mark(predMonad);
-                       mark(predMonad0);
+#if IO_MONAD
+                       mark(typeProgIO);
+#endif
                        break;
 
         case INSTALL : typeChecker(RESET);
                        dummyVar     = inventVar();
+
+#if !IGNORE_MODULES
+                       modulePrelude = newModule(textPrelude);
+                       setCurrModule(modulePrelude);
+#endif
+
                        starToStar   = simpleKind(1);
+
+                       typeUnit     = addPrimTycon(findText("()"),
+                                                   STAR,0,DATATYPE,NIL);
+                       typeArrow    = addPrimTycon(findText("(->)"),
+                                                   simpleKind(2),2,
+                                                   DATATYPE,NIL);
+                       typeList     = addPrimTycon(findText("[]"),
+                                                   starToStar,1,
+                                                   DATATYPE,NIL);
+
+                       arrow        = fn(aVar,bVar);
+                       listof       = ap(typeList,aVar);
+                       boundPair    = ap(ap(mkTuple(2),aVar),aVar);
+
+                       nameUnit     = addPrimCfun(findText("()"),0,0,typeUnit);
+                       tycon(typeUnit).defn
+                                    = singleton(nameUnit);
+
+                       nameNil      = addPrimCfun(findText("[]"),0,1,
+                                                   mkPolyType(starToStar,
+                                                              listof));
+                       nameCons     = addPrimCfun(findText(":"),2,2,
+                                                   mkPolyType(starToStar,
+                                                              fn(aVar,
+                                                              fn(listof,
+                                                                 listof))));
+                       name(nameCons).syntax
+                                    = mkSyntax(RIGHT_ASS,5);
+
+                       tycon(typeList).defn
+                                    = cons(nameNil,cons(nameCons,NIL));
+
                        typeVarToVar = fn(aVar,aVar);
+#if TREX
+                       typeNoRow    = addPrimTycon(findText("EmptyRow"),
+                                                   ROW,0,DATATYPE,NIL);
+                       typeRec      = addPrimTycon(findText("Rec"),
+                                                   pair(ROW,STAR),1,
+                                                   DATATYPE,NIL);
+                       nameNoRec    = addPrimCfun(findText("EmptyRec"),0,0,
+                                                        ap(typeRec,typeNoRow));
+#else
+                       /* bogus definitions to avoid changing the prelude */
+                       addPrimCfun(findText("Rec"),      0,0,typeUnit);
+                       addPrimCfun(findText("EmptyRow"), 0,0,typeUnit);
+                       addPrimCfun(findText("EmptyRec"), 0,0,typeUnit);
+#endif
+#if IO_MONAD
+                       nameUserErr  = addPrimCfun(inventText(),1,1,NIL);
+                       nameNameErr  = addPrimCfun(inventText(),1,2,NIL);
+                       nameSearchErr= addPrimCfun(inventText(),1,3,NIL);
+#if IO_HANDLES
+                       nameIllegal  = addPrimCfun(inventText(),0,4,NIL);
+                       nameWriteErr = addPrimCfun(inventText(),1,5,NIL);
+                       nameEOFErr   = addPrimCfun(inventText(),1,6,NIL);
+#endif
+#endif
                        break;
     }
 }