[project @ 2001-01-17 15:23:39 by sewardj]
[ghc-hetmet.git] / ghc / interpreter / static.c
diff --git a/ghc/interpreter/static.c b/ghc/interpreter/static.c
deleted file mode 100644 (file)
index 7636dd7..0000000
+++ /dev/null
@@ -1,5294 +0,0 @@
-
-/* --------------------------------------------------------------------------
- * Static Analysis for Hugs
- *
- * The Hugs 98 system is Copyright (c) Mark P Jones, Alastair Reid, the
- * Yale Haskell Group, and the Oregon Graduate Institute of Science and
- * Technology, 1994-1999, All rights reserved.  It is distributed as
- * free software under the license in the file "License", which is
- * included in the distribution.
- *
- * $RCSfile: static.c,v $
- * $Revision: 1.42 $
- * $Date: 2000/06/02 16:19:47 $
- * ------------------------------------------------------------------------*/
-
-#include "hugsbasictypes.h"
-#include "storage.h"
-#include "connect.h"
-#include "errors.h"
-
-/* --------------------------------------------------------------------------
- * local function prototypes:
- * ------------------------------------------------------------------------*/
-
-static Void   local kindError           ( Int,Constr,Constr,String,Kind,Int );
-static Void   local checkQualImport     ( Pair );
-static Void   local checkUnqualImport   ( Triple );
-
-static Name   local lookupName          ( Text,List );
-static List   local checkSubentities    ( List,List,List,String,Text );
-static List   local checkExportTycon    ( List,Text,Cell,Tycon );
-static List   local checkExportClass    ( List,Text,Cell,Class );
-static List   local checkExport         ( List,Text,Cell );
-static List   local checkImportEntity   ( List,Module,Cell );
-static List   local resolveImportList   ( Module,Cell );
-static Void   local checkImportList     ( Pair );
-
-static Void   local importEntity        ( Module,Cell );
-static Void   local importName          ( Module,Name );
-static Void   local importTycon         ( Module,Tycon );
-static Void   local importClass         ( Module,Class );
-static List   local checkExports        ( List, Module );
-
-static Void   local checkTyconDefn      ( Tycon );
-static Void   local depConstrs          ( Tycon,List,Cell );
-static List   local addSels             ( Int,Name,List,List );
-static List   local selectCtxt          ( List,List );
-static Void   local checkSynonyms       ( List );
-static List   local visitSyn            ( List,Tycon,List );
-static Type   local instantiateSyn      ( Type,Type );
-
-static Void   local checkClassDefn      ( Class );
-static Cell   local depPredExp         ( Int,List,Cell );
-static Void   local checkMems           ( Class,List,Cell );
-static Void   local checkMems2          ( Class,Cell );
-static Void   local addMembers          ( Class );
-static Name   local newMember           ( Int,Int,Cell,Type,Class );
-static Text   local generateText        ( String,Class );
-
-static List   local classBindings       ( String,Class,List );
-static Name   local memberName          ( Class,Text );
-static List   local numInsert           ( Int,Cell,List );
-
-static List   local maybeAppendVar      ( Cell,List );
-
-static Type   local checkSigType        ( Int,String,Cell,Type );
-static Void   local checkOptQuantVars  ( Int,List,List );
-static Type   local depTopType          ( Int,List,Type );
-static Type   local depCompType         ( Int,List,Type );
-static Type   local depTypeExp          ( Int,List,Type );
-static Type   local depTypeVar          ( Int,List,Text );
-static List   local checkQuantVars      ( Int,List,List,Cell );
-static List   local otvars             ( Cell,List );
-static Bool   local osubset            ( List,List );
-static Void   local kindConstr          ( Int,Int,Int,Constr );
-static Kind   local kindAtom            ( Int,Constr );
-static Void   local kindPred            ( Int,Int,Int,Cell );
-static Void   local kindType            ( Int,String,Type );
-static Void   local fixKinds            ( Void );
-
-static Void   local kindTCGroup         ( List );
-static Void   local initTCKind          ( Cell );
-static Void   local kindTC              ( Cell );
-static Void   local genTC               ( Cell );
-
-static Void   local checkInstDefn       ( Inst );
-static Void   local insertInst          ( Inst );
-static Bool   local instCompare         ( Inst,Inst );
-static Name   local newInstImp          ( Inst );
-static Void   local kindInst            ( Inst,Int );
-static Void   local checkDerive         ( Tycon,List,List,Cell );
-static Void   local addDerInst          ( Int,Class,List,List,Type,Int );
-static Void   local deriveContexts      ( List );
-static Void   local initDerInst         ( Inst );
-static Void   local calcInstPreds       ( Inst );
-static Void   local maybeAddPred        ( Cell,Int,Int,List );
-static List   local calcFunDeps                ( List );
-static Cell   local copyAdj             ( Cell,Int,Int );
-static Void   local tidyDerInst         ( Inst );
-static List   local otvarsZonk         ( Cell,List,Int );
-
-static Void   local addDerivImp         ( Inst );
-
-static Void   local checkDefaultDefns   ( Void );
-
-static Void   local checkForeignImport  ( Name );
-static Void   local checkForeignExport  ( Name );
-
-static Cell   local tidyInfix           ( Int,Cell );
-static Pair   local attachFixity        ( Int,Cell );
-static Syntax local lookupSyntax        ( Text );
-
-static Cell   local checkPat            ( Int,Cell );
-static Cell   local checkMaybeCnkPat    ( Int,Cell );
-static Cell   local checkApPat          ( Int,Int,Cell );
-static Void   local addToPatVars        ( Int,Cell );
-static Name   local conDefined          ( Int,Cell );
-static Void   local checkIsCfun         ( Int,Name );
-static Void   local checkCfunArgs       ( Int,Cell,Int );
-static Cell   local checkPatType        ( Int,String,Cell,Type );
-static Cell   local applyBtyvs          ( Cell );
-static Cell   local bindPat             ( Int,Cell );
-static Void   local bindPats            ( Int,List );
-
-static List   local extractSigdecls     ( List );
-static List   local extractFixdecls     ( List );
-static List   local extractBindings     ( List );
-static List   local getPatVars          ( Int,Cell,List );
-static List   local addPatVar           ( Int,Cell,List );
-static List   local eqnsToBindings      ( List,List,List,List );
-static Void   local notDefined          ( Int,List,Cell );
-static Cell   local findBinding         ( Text,List );
-static Cell   local getAttr             ( List,Cell );
-static Void   local addSigdecl          ( List,Cell );
-static Void   local addFixdecl          ( List,List,List,List,Triple );
-static Void   local dupFixity           ( Int,Text );
-static Void   local missFixity          ( Int,Text );
-
-static List   local dependencyAnal      ( List );
-static List   local topDependAnal       ( List );
-static Void   local addDepField         ( Cell );
-static Void   local remDepField         ( List );
-static Void   local remDepField1        ( Cell );
-static Void   local clearScope          ( Void );
-static Void   local withinScope         ( List );
-static Void   local leaveScope          ( Void );
-static Void   local saveSyntax          ( Cell,Cell );
-
-static Void   local depBinding          ( Cell );
-static Void   local depDefaults         ( Class );
-static Void   local depInsts            ( Inst );
-static Void   local depClassBindings    ( List );
-static Void   local depAlt              ( Cell );
-static Void   local depRhs              ( Cell );
-static Void   local depGuard            ( Cell );
-static Cell   local depExpr             ( Int,Cell );
-static Void   local depPair             ( Int,Cell );
-static Void   local depTriple           ( Int,Cell );
-static Void   local depComp             ( Int,Cell,List );
-static Void   local depCaseAlt          ( Int,Cell );
-static Cell   local depVar              ( Int,Cell );
-static Cell   local depQVar             ( Int,Cell );
-static Void   local depConFlds          ( Int,Cell,Bool );
-static Void   local depUpdFlds          ( Int,Cell );
-static List   local depFields           ( Int,Cell,List,Bool );
-#if IPARAM
-static Void   local depWith            ( Int,Cell );
-static List   local depDwFlds          ( Int,Cell,List );
-#endif
-#if TREX
-static Cell   local depRecord           ( Int,Cell );
-#endif
-
-static List   local tcscc               ( List,List );
-static List   local bscc                ( List );
-
-static Void   local addRSsigdecls       ( Pair );
-static Void   local allNoPrevDef        ( Cell );
-static Void   local noPrevDef           ( Int,Cell );
-static Bool   local odiff              ( List,List );
-static Void   local duplicateErrorAux   ( Int,Module,Text,String );
-#define duplicateError(l,m,t,k) duplicateErrorAux(l,m,t,k)
-static Void   local checkTypeIn         ( 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
- * ------------------------------------------------------------------------*/
-
-/* --------------------------------------------------------------------------
- * Kind checking preliminaries:
- * ------------------------------------------------------------------------*/
-
-Bool kindExpert = FALSE;                /* TRUE => display kind errors in  */
-                                        /*         full detail             */
-
-static Void local kindError(l,c,in,wh,k,o)
-Int    l;                               /* line number near constuctor exp */
-Constr c;                               /* constructor                     */
-Constr in;                              /* context (if any)                */
-String wh;                              /* place in which error occurs     */
-Kind   k;                               /* expected kind (k,o)             */
-Int    o; {                             /* inferred kind (typeIs,typeOff)  */
-    clearMarks();
-
-    if (!kindExpert) {                  /* for those with a fear of kinds  */
-        ERRMSG(l) "Illegal type" ETHEN
-        if (nonNull(in)) {
-            ERRTEXT " \"" ETHEN ERRTYPE(in);
-            ERRTEXT "\""  ETHEN
-        }
-        ERRTEXT " in %s\n", wh
-        EEND;
-    }
-
-    ERRMSG(l) "Kind error in %s", wh ETHEN
-    if (nonNull(in)) {
-        ERRTEXT "\n*** expression     : " ETHEN ERRTYPE(in);
-    }
-    ERRTEXT "\n*** constructor    : " ETHEN ERRTYPE(c);
-    ERRTEXT "\n*** kind           : " ETHEN ERRKIND(copyType(typeIs,typeOff));
-    ERRTEXT "\n*** does not match : " ETHEN ERRKIND(copyType(k,o));
-    if (unifyFails) {
-        ERRTEXT "\n*** because        : %s", unifyFails ETHEN
-    }
-    ERRTEXT "\n"
-    EEND;
-}
-
-#define shouldKind(l,c,in,wh,k,o)       if (!kunify(typeIs,typeOff,k,o)) \
-                                            kindError(l,c,in,wh,k,o)
-#define checkKind(l,a,m,c,in,wh,k,o)    kindConstr(l,a,m,c); \
-                                        shouldKind(l,c,in,wh,k,o)
-#define inferKind(k,o)                  typeIs=k; typeOff=o
-
-static List unkindTypes;                /* types in need of kind annotation*/
-#if TREX
-Kind   extKind;                         /* Kind of extension, *->row->row  */
-#endif
-
-/* --------------------------------------------------------------------------
- * Static analysis of modules:
- * ------------------------------------------------------------------------*/
-
-Void startModule ( Module m )                    /* switch to a new module */
-{
-    if (isNull(m)) internal("startModule");
-    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 = NIL;
-    es = module(exporter).exports; 
-
-    for(; nonNull(es); es=tl(es)) {
-        Cell e = hd(es); /* :: Entity
-                            | (Entity, NIL|DOTDOT)
-                            | tycon 
-                            | class
-                         */
-        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 (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 TUPLE:
-      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;
-        }
-    }
-    return exports; /* NOTUSED */
-}
-
-static List local checkExports ( List exports, Module thisModule )
-{
-    Module m  = thisModule;
-    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;
-}
-
-
-/* --------------------------------------------------------------------------
- * Static analysis of type declarations:
- *
- * Type declarations come in two forms:
- * - data declarations - define new constructed data types
- * - type declarations - define new type synonyms
- *
- * A certain amount of work is carried out as the declarations are
- * read during parsing.  In particular, for each type constructor
- * definition encountered:
- * - check that there is no previous definition of constructor
- * - ensure type constructor not previously used as a class name
- * - make a new entry in the type constructor table
- * - record line number of declaration
- * - Build separate lists of newly defined constructors for later use.
- * ------------------------------------------------------------------------*/
-
-Void tyconDefn(line,lhs,rhs,what)       /* process new type definition     */
-Int  line;                              /* definition line number          */
-Cell lhs;                               /* left hand side of definition    */
-Cell rhs;                               /* right hand side of definition   */
-Cell what; {                            /* SYNONYM/DATATYPE/etc...         */
-    Text t = textOf(getHead(lhs));
-
-    if (nonNull(findTycon(t))) {
-        ERRMSG(line) "Repeated definition of type constructor \"%s\"",
-                     textToStr(t)
-        EEND;
-    }
-    else if (nonNull(findClass(t))) {
-        ERRMSG(line) "\"%s\" used as both class and type constructor",
-                     textToStr(t)
-        EEND;
-    }
-    else {
-        Tycon nw        = newTycon(t);
-        tyconDefns      = cons(nw,tyconDefns);
-        tycon(nw).line  = line;
-        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);
-        }
-        tycon(nw).defn  = pair(lhs,rhs);
-    }
-}
-
-Void setTypeIns(bs)                     /* set local synonyms for given    */
-List bs; {                              /* binding group                   */
-    List cvs = typeInDefns;
-    for (; nonNull(cvs); cvs=tl(cvs)) {
-        Tycon c  = fst(hd(cvs));
-        List  vs = snd(hd(cvs));
-        for (tycon(c).what = RESTRICTSYN; nonNull(vs); vs=tl(vs)) {
-            if (nonNull(findBinding(textOf(hd(vs)),bs))) {
-                tycon(c).what = SYNONYM;
-                break;
-            }
-        }
-    }
-}
-
-Void clearTypeIns() {                   /* clear list of local synonyms    */
-    for (; nonNull(typeInDefns); typeInDefns=tl(typeInDefns))
-        tycon(fst(hd(typeInDefns))).what = RESTRICTSYN;
-}
-
-/* --------------------------------------------------------------------------
- * Further analysis of Type declarations:
- *
- * In order to allow the definition of mutually recursive families of
- * data types, the static analysis of the right hand sides of type
- * declarations cannot be performed until all of the type declarations
- * have been read.
- *
- * Once parsing is complete, we carry out the following:
- *
- * - check format of lhs, extracting list of bound vars and ensuring that
- *   there are no repeated variables and no Skolem variables.
- * - run dependency analysis on rhs to check that only bound type vars
- *   appear in type and that all constructors are defined.
- *   Replace type variables by offsets, constructors by Tycons.
- * - use list of dependents to sort into strongly connected components.
- * - ensure that there is not more than one synonym in each group.
- * - kind-check each group of type definitions.
- *
- * - check that there are no previous definitions for constructor
- *   functions in data type definitions.
- * - install synonym expansions and constructor definitions.
- * ------------------------------------------------------------------------*/
-
-static List tcDeps = NIL;               /* list of dependent tycons/classes*/
-
-static Void local checkTyconDefn(d)     /* validate type constructor defn  */
-Tycon d; {
-    Cell lhs    = fst(tycon(d).defn);
-    Cell rhs    = snd(tycon(d).defn);
-    Int  line   = tycon(d).line;
-    List tyvars = getArgs(lhs);
-    List temp;
-                                        /* check for repeated tyvars on lhs*/
-    for (temp=tyvars; nonNull(temp); temp=tl(temp))
-        if (nonNull(varIsMember(textOf(hd(temp)),tl(temp)))) {
-            ERRMSG(line) "Repeated type variable \"%s\" on left hand side",
-                         textToStr(textOf(hd(temp)))
-            EEND;
-        }
-
-    tcDeps = NIL;                       /* find dependents                 */
-    switch (whatIs(tycon(d).what)) {
-        case RESTRICTSYN :
-        case SYNONYM     : rhs = depTypeExp(line,tyvars,rhs);
-                           if (cellIsMember(d,tcDeps)) {
-                               ERRMSG(line) "Recursive type synonym \"%s\"",
-                                            textToStr(tycon(d).text)
-                               EEND;
-                           }
-                           break;
-
-        case DATATYPE    :
-        case NEWTYPE     : depConstrs(d,tyvars,rhs);
-                           rhs = fst(rhs);
-                           break;
-
-        default          : internal("checkTyconDefn");
-                           break;
-    }
-
-    tycon(d).defn = rhs;
-    tycon(d).kind = tcDeps;
-    tcDeps        = NIL;
-}
-
-static Void local depConstrs(t,tyvars,cd)
-Tycon t;                                /* Define constructor functions and*/
-List  tyvars;                           /* do dependency analysis for data */
-Cell  cd; {                             /* definitions (w or w/o deriving) */
-    Int  line      = tycon(t).line;
-    List ctxt      = NIL;
-    Int  conNo     = 1;
-    Type lhs       = t;
-    List cs        = fst(cd);
-    List derivs    = snd(cd);
-    List compTypes = NIL;
-    List sels      = NIL;
-    Int  i;
-
-    for (i=0; i<tycon(t).arity; ++i)    /* build representation for tycon  */
-        lhs = ap(lhs,mkOffset(i));      /* applied to full comp. of args   */
-
-    if (isQualType(cs)) {              /* allow for possible context      */
-        ctxt = fst(snd(cs));
-        cs   = snd(snd(cs));
-       map2Over(depPredExp,line,tyvars,ctxt);
-        h98CheckCtxt(line,"context",TRUE,ctxt,NIL);
-    }
-
-    if (nonNull(cs) && isNull(tl(cs)))  /* Single constructor datatype?    */
-        conNo = 0;
-
-    for (; nonNull(cs); cs=tl(cs)) {    /* For each constructor function:  */
-        Cell con   = hd(cs);
-        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                  */
-        Type type  = lhs;               /* constructor function type       */
-        Int  arity = 0;                 /* arity of constructor function   */
-        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 (isQualType(con)) {          /* Local predicates                */
-            List us;
-            lps     = fst(snd(con));
-           for (us = typeVarsIn(lps,NIL,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;
-                }
-           map2Over(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));
-            fs       = NIL;
-            for (; nonNull(fls); fls=tl(fls)) { /* for each field spec:    */
-                List vs     = fst(hd(fls));
-                Type t      = snd(hd(fls));     /* - scrutinize type       */
-                Bool banged = whatIs(t)==BANG;
-                t           = depCompType(line,sig,(banged ? arg(t) : t));
-                while (nonNull(vs)) {           /* - add named components  */
-                    Cell us = tl(vs);
-                    tl(vs)  = fs;
-                    fs      = vs;
-                    vs      = us;
-                    con     = ap(con,t);
-                    arity++;
-                    if (banged)
-                        scs = cons(mkInt(arity),scs);
-                }
-            }
-            fs  = rev(fs);
-            scs = rev(scs);             /* put strict comps in ascend ord  */
-        }
-        else {                          /* Non-labelled constructor        */
-            Cell c = con;
-            Int  compNo;
-            for (; isAp(c); c=fun(c))
-                arity++;
-            for (compNo=arity, c=con; isAp(c); c=fun(c)) {
-                Type t = arg(c);
-                if (whatIs(t)==BANG) {
-                    scs = cons(mkInt(compNo),scs);
-                    t   = arg(t);
-                }
-                compNo--;
-                arg(c) = depCompType(line,sig,t);
-            }
-        }
-
-        if (nonNull(ctxt1))             /* Extract relevant part of context*/
-            ctxt1 = selectCtxt(ctxt1,offsetTyvarsIn(con,NIL));
-
-        for (i=arity; isAp(con); i--) { /* Calculate type of constructor   */
-            Type ty  = fun(con);
-            Type cmp = arg(con);
-            fun(con) = typeArrow;
-           if (isPolyOrQualType(cmp)) {
-                if (nonNull(derivs)) {
-                    ERRMSG(line) "Cannot derive instances for types" ETHEN
-                   ERRTEXT      " with polymorphic or qualified components"
-                    EEND;
-                }
-                if (nr2==0)
-                    nr2 = i;
-            }
-            if (nonNull(derivs))        /* and build list of components    */
-                compTypes = cons(cmp,compTypes);
-            type     = ap(con,type);
-            con      = ty;
-        }
-
-       if (nr2>0) {                    /* Add rank 2 annotation           */
-           type = ap(RANK2,pair(mkInt(nr2-length(lps)),type));
-       }
-
-        if (nonNull(evs)) {             /* Add existential annotation      */
-            if (nonNull(derivs)) {
-                ERRMSG(line) "Cannot derive instances for types" ETHEN
-                ERRTEXT      " with existentially typed components"
-                EEND;
-            }
-            if (fs!=NONE) {
-                ERRMSG(line)
-                   "Cannot use selectors with existentially typed components"
-                EEND;
-            }
-            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)) {
-                hd(ts1) = NIL;
-            }
-            type = mkPolyType(sig,type);
-        }
-
-        n = findName(textOf(con));      /* Allocate constructor fun name   */
-        if (isNull(n)) {
-            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);
-            name(n).hasStrict = nonNull(scs);
-        }
-
-        hd(cs) = n;
-        if (fs!=NONE) {
-            sels = addSels(line,n,fs,sels);
-        }
-    }
-
-    if (nonNull(sels)) {
-        sels     = rev(sels);
-        fst(cd)  = appendOnto(fst(cd),sels);
-        selDefns = cons(sels,selDefns);
-    }
-
-    if (nonNull(derivs)) {              /* Generate derived instances      */
-        map3Proc(checkDerive,t,ctxt,compTypes,derivs);
-    }
-}
-
-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 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;
-    cfunSfuns = cons(pair(c,fs),cfunSfuns);
-    for (; nonNull(fs); fs=tl(fs), ++sn) {
-        List ns = ss;
-        Text t  = textOf(hd(fs));
-
-        if (nonNull(varIsMember(t,tl(fs)))) {
-            ERRMSG(line) "Repeated field name \"%s\" for constructor \"%s\"",
-                         textToStr(t), textToStr(name(c).text)
-            EEND;
-        }
-
-        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 {
-            Name n = findName(t);
-            if (nonNull(n)) {
-                ERRMSG(line) "Repeated definition for selector \"%s\"",
-                             textToStr(t)
-                EEND;
-            }
-            n              = newName(t,c);
-            name(n).line   = line;
-            name(n).number = SELNAME;
-            name(n).defn   = singleton(pair(c,mkInt(sn)));
-            ss             = cons(n,ss);
-        }
-    }
-    return ss;
-}
-
-static List local selectCtxt(ctxt,vs)   /* calculate subset of context     */
-List ctxt;
-List vs; {
-    if (isNull(vs)) {
-        return NIL;
-    } else {
-        List ps = NIL;
-        for (; nonNull(ctxt); ctxt=tl(ctxt)) {
-            List us = offsetTyvarsIn(hd(ctxt),NIL);
-            for (; nonNull(us) && cellIsMember(hd(us),vs); us=tl(us)) {
-            }
-            if (isNull(us)) {
-                ps = cons(hd(ctxt),ps);
-            }
-        }
-        return rev(ps);
-    }
-}
-
-static Void local checkSynonyms(ts)     /* Check for mutually recursive    */
-List ts; {                              /* synonyms                        */
-    List syns = NIL;
-    for (; nonNull(ts); ts=tl(ts)) {    /* build list of all synonyms      */
-        Tycon t = hd(ts);
-        switch (whatIs(tycon(t).what)) {
-            case SYNONYM     :
-            case RESTRICTSYN : syns = cons(t,syns);
-                               break;
-        }
-    }
-    while (nonNull(syns)) {             /* then visit each synonym         */
-        syns = visitSyn(NIL,hd(syns),syns);
-    }
-}
-
-static List local visitSyn(path,t,syns) /* visit synonym definition to look*/
-List  path;                             /* for cycles                      */
-Tycon t;
-List  syns; {
-    if (cellIsMember(t,path)) {         /* every elt in path depends on t  */
-        ERRMSG(tycon(t).line)
-            "Type synonyms \"%s\" and \"%s\" are mutually recursive",
-            textToStr(tycon(t).text), textToStr(tycon(hd(path)).text)
-        EEND;
-    } else {
-        List ds    = tycon(t).kind;
-        List path1 = NIL;
-        for (; nonNull(ds); ds=tl(ds)) {
-            if (cellIsMember(hd(ds),syns)) {
-                if (isNull(path1)) {
-                    path1 = cons(t,path);
-                }
-                syns = visitSyn(path1,hd(ds),syns);
-            }
-        }
-    }
-    tycon(t).defn = fullExpand(tycon(t).defn);
-    return removeCell(t,syns);
-}
-
-/* --------------------------------------------------------------------------
- * Expanding out all type synonyms in a type expression:
- * ------------------------------------------------------------------------*/
-
-Type fullExpand(t)                      /* find full expansion of type exp */
-Type t; {                               /* assuming that all relevant      */
-    Cell h = t;                         /* synonym defns of lower rank have*/
-    Int  n = 0;                         /* already been fully expanded     */
-    List args;
-    for (args=NIL; isAp(h); h=fun(h), n++) {
-        args = cons(fullExpand(arg(h)),args);
-    }
-    t = applyToArgs(h,args);
-    if (isSynonym(h) && n>=tycon(h).arity) {
-        if (n==tycon(h).arity) {
-            t = instantiateSyn(tycon(h).defn,t);
-        } else {
-            Type p = t;
-            while (--n > tycon(h).arity) {
-                p = fun(p);
-            }
-            fun(p) = instantiateSyn(tycon(h).defn,fun(p));
-        }
-    }
-    return t;
-}
-
-static Type local instantiateSyn(t,env) /* instantiate type according using*/
-Type t;                                 /* env to determine appropriate    */
-Type env; {                             /* values for OFFSET type vars     */
-    switch (whatIs(t)) {
-        case AP      : return ap(instantiateSyn(fun(t),env),
-                                 instantiateSyn(arg(t),env));
-
-        case OFFSET  : return nthArg(offsetOf(t),env);
-
-        default      : return t;
-    }
-}
-
-/* --------------------------------------------------------------------------
- * Static analysis of class declarations:
- *
- * Performed in a similar manner to that used for type declarations.
- *
- * The first part of the static analysis is performed as the declarations
- * are read during parsing.  The parser ensures that:
- * - the class header and all superclass predicates are of the form
- *   ``Class var''
- *
- * The classDefn() function:
- * - ensures that there is no previous definition for class
- * - checks that class name has not previously been used as a type constr.
- * - make new entry in class table
- * - record line number of declaration
- * - build list of classes defined in current script for use in later
- *   stages of static analysis.
- * ------------------------------------------------------------------------*/
-
-Void classDefn(line,head,ms,fds)       /* process new class definition    */
-Int  line;                            /* definition line number           */
-Cell head;                            /* class header :: ([Supers],Class) */
-List ms;                              /* class definition body            */
-List fds; {                           /* functional dependencies          */
-    Text ct    = textOf(getHead(snd(head)));
-    Int  arity = argCount;
-
-    if (nonNull(findClass(ct))) {
-       ERRMSG(line) "Repeated definition of class \"%s\"",
-                    textToStr(ct)
-       EEND;
-    } else if (nonNull(findTycon(ct))) {
-       ERRMSG(line) "\"%s\" used as both class and type constructor",
-                    textToStr(ct)
-       EEND;
-    } else {
-       Class nw           = newClass(ct);
-       cclass(nw).line    = line;
-       cclass(nw).arity   = arity;
-       cclass(nw).head    = snd(head);
-       cclass(nw).supers  = fst(head);
-       cclass(nw).members = ms;
-       cclass(nw).level   = 0;
-       cclass(nw).fds     = fds;
-       cclass(nw).xfds    = NIL;
-       classDefns         = cons(nw,classDefns);
-       if (arity!=1)
-           h98DoesntSupport(line,"multiple parameter classes");
-    }
-}
-
-/* --------------------------------------------------------------------------
- * Further analysis of class declarations:
- *
- * Full static analysis of class definitions must be postponed until the
- * complete script has been read and all static analysis on type definitions
- * has been completed.
- *
- * Once this has been achieved, we carry out the following checks on each
- * class definition:
- * - check that variables in header are distinct
- * - replace head by skeleton
- * - 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!)
- * - no member function has a previous definition ...
- * - no member function is mentioned more than once in the list of members
- * - each member function type is valid, replace vars by offsets
- * - qualify each member function type by class header
- * - only bindings for members appear in defaults
- * - only function bindings appear in defaults
- * - check that extended class hierarchy does not contain any cycles
- * ------------------------------------------------------------------------*/
-
-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))) {
-            ERRMSG(cclass(c).line) "Type variable required in class head"
-            EEND;
-        }
-        if (nonNull(varIsMember(textOf(arg(temp)),tyvars))) {
-            ERRMSG(cclass(c).line)
-                "Repeated type variable \"%s\" in class head",
-                textToStr(textOf(arg(temp)))
-            EEND;
-        }
-        tyvars = cons(arg(temp),tyvars);
-    }
-
-    for (fs=cclass(c).fds; nonNull(fs); fs=tl(fs)) {
-       Pair fd = hd(fs);
-       List vs = snd(fd);
-
-       /* Check for trivial dependency
-        */
-       if (isNull(vs)) {
-           ERRMSG(cclass(c).line) "Functional dependency is trivial"
-           EEND;
-       }
-
-       /* Check for duplicated vars on right hand side, and for vars on
-        * right that also appear on the left:
-        */
-       for (vs=snd(fd); nonNull(vs); vs=tl(vs)) {
-           if (varIsMember(textOf(hd(vs)),fst(fd))) {
-               ERRMSG(cclass(c).line)
-                   "Trivial dependency for variable \"%s\"",
-                   textToStr(textOf(hd(vs)))
-               EEND;
-           }
-           if (varIsMember(textOf(hd(vs)),tl(vs))) {
-               ERRMSG(cclass(c).line)
-                   "Repeated variable \"%s\" in functional dependency",
-                   textToStr(textOf(hd(vs)))
-               EEND;
-           }
-           hd(vs) = depTypeVar(cclass(c).line,tyvars,textOf(hd(vs)));
-       }
-
-       /* Check for duplicated vars on left hand side:
-        */
-       for (vs=fst(fd); nonNull(vs); vs=tl(vs)) {
-           if (varIsMember(textOf(hd(vs)),tl(vs))) {
-               ERRMSG(cclass(c).line)
-                   "Repeated variable \"%s\" in functional dependency",
-                   textToStr(textOf(hd(vs)))
-               EEND;
-           }
-           hd(vs) = depTypeVar(cclass(c).line,tyvars,textOf(hd(vs)));
-       }
-    }
-
-    /* add in the tyvars from the `supers' so that we don't
-       prematurely complain about undefined tyvars */
-    tyvars = typeVarsIn(cclass(c).supers,NIL,NIL,tyvars);
-
-    if (cclass(c).arity==0) {
-       cclass(c).head = c;
-    } else {
-       Int args = cclass(c).arity - 1;
-       for (temp=cclass(c).head; args>0; temp=fun(temp), args--) {
-           arg(temp) = mkOffset(args);
-       }
-       arg(temp) = mkOffset(0);
-       fun(temp) = c;
-    }
-
-    tcDeps             = NIL;          /* find dependents                 */
-    map2Over(depPredExp,cclass(c).line,tyvars,cclass(c).supers);
-
-    {   /* depPredExp instantiates class names to class structs, so
-         * now we have enough info to check for ambiguity
-         */
-       List tvts = offsetTyvarsIn(cclass(c).head,NIL);
-       List tvps = offsetTyvarsIn(cclass(c).supers,NIL);
-       List fds  = calcFunDeps(cclass(c).supers);
-       tvts = oclose(fds,tvts);
-       tvts = odiff(tvps,tvts);
-
-       if (!isNull(tvts)) {
-           ERRMSG(cclass(c).line) "Undefined type variable \"%s\"",
-             textToStr(textOf(nth(offsetOf(hd(tvts)),tyvars)))
-           EEND;
-       }
-    }
-
-    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*/
-    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;
-}
-
-
-/* --------------------------------------------------------------------------
- * Functional dependencies are inherited from superclasses.
- * For example, if I've got the following classes:
- *
- * class C a b | a -> b
- * class C [b] a => D a b
- *
- * then C will have the dependency ([a], [b]) as expected, and D will inherit
- * the dependency ([b], [a]) from C.
- * When doing pairwise improvement, we have to consider not just improving
- * when we see a pair of Cs or a pair of Ds in the context, but when we've
- * got a C and a D as well.  In this case, we only improve when the
- * predicate in question matches the type skeleton in the relevant superclass
- * constraint.  E.g., we improve the pair (C [Int] a, D b Int) (unifying
- * a and b), but we don't improve the pair (C Int a, D b Int).
- * To implement functional dependency inheritance, we calculate
- * the closure of all functional dependencies, and store the result
- * in an additional field `xfds' (extended functional dependencies).
- * The `xfds' field is a list of functional dependency lists, annotated
- * with a list of predicate skeletons constraining when improvement can
- * happen against this dependency list.  For example, the xfds field
- * for C above would be:
- *     [([C a b], [([a], [b])])]
- * and the xfds field for D would be:
- *     [([C [b] a, D a b], [([b], [a])])]
- * Self-improvement (of a C with a C, or a D with a D) is treated as a
- * special case of an inherited dependency.
- * ------------------------------------------------------------------------*/
-static List local inheritFundeps ( Class c, Cell pi, Int o )
-{
-    Int alpha = newKindedVars(cclass(c).kinds);
-    List scs = cclass(c).supers;
-    List xfds = NIL;
-    Cell this = NIL;
-    /* better not fail ;-) */
-    if (!matchPred(pi,o,cclass(c).head,alpha))
-       internal("inheritFundeps - predicate failed to match it's own head!");
-    this = copyPred(pi,o);
-    for (; nonNull(scs); scs=tl(scs)) {
-       Class s = getHead(hd(scs));
-       if (isClass(s)) {
-           List sfds = inheritFundeps(s,hd(scs),alpha);
-           for (; nonNull(sfds); sfds=tl(sfds)) {
-               Cell h = hd(sfds);
-               xfds = cons(pair(cons(this,fst(h)),snd(h)),xfds);
-           }
-       }
-    }
-    if (nonNull(cclass(c).fds)) {
-       List fds = NIL, fs = cclass(c).fds;
-       for (; nonNull(fs); fs=tl(fs)) {
-           fds = cons(pair(otvars(this,fst(hd(fs))),
-                           otvars(this,snd(hd(fs)))),fds);
-       }
-       xfds = cons(pair(cons(this,NIL),fds),xfds);
-    }
-    return xfds;
-}
-
-static Void local extendFundeps ( Class c )
-{ 
-    Int alpha;
-    emptySubstitution();
-    alpha = newKindedVars(cclass(c).kinds);
-    cclass(c).xfds = inheritFundeps(c,cclass(c).head,alpha);
-
-    /* we can now check for ambiguity */
-    map1Proc(checkMems2,c,fst(cclass(c).members));
-}
-
-
-static Cell local depPredExp(line,tyvars,pred)
-Int  line;
-List tyvars;
-Cell pred; {
-    Int  args = 0;
-    Cell prev = NIL;
-    Cell h    = pred;
-    for (; isAp(h); args++) {
-       arg(h) = depTypeExp(line,tyvars,arg(h));
-       prev   = h;
-       h      = fun(h);
-    }
-
-    if (args==0) {
-       h98DoesntSupport(line,"tag classes");
-    } else if (args!=1) {
-       h98DoesntSupport(line,"multiple parameter classes");
-    }
-
-    if (isQCon(h)) {                    /* standard class constraint       */
-        Class c = findQualClass(h);
-        if (isNull(c)) {
-            ERRMSG(line) "Undefined class \"%s\"", identToStr(h)
-            EEND;
-        }
-       if (isNull(prev)) {
-           pred = c;
-       } else {
-           fun(prev) = c;
-       }
-        if (args!=cclass(c).arity) {
-            ERRMSG(line) "Wrong number of arguments for class \"%s\"",
-                        textToStr(cclass(c).text)
-            EEND;
-        }
-        if (cellIsMember(c,classDefns) && !cellIsMember(c,tcDeps)) {
-            tcDeps = cons(c,tcDeps);
-        }
-    }
-#if TREX
-    else if (isExt(h)) {                /* Lacks predicate                 */
-        if (args!=1) {                  /* parser shouldn't let this happen*/
-            ERRMSG(line) "Wrong number of arguments for lacks predicate"
-            EEND;
-        }
-    }
-#endif
-    else 
-#if IPARAM
-         if (whatIs(h) != IPCELL)
-#endif
-    {
-       internal("depPredExp");
-    }
-    return pred;
-}
-
-static Void local checkMems(c,tyvars,m) /* check member function details   */
-Class c;
-List  tyvars;
-Cell  m; {
-    Int  line = intOf(fst3(m));
-    List vs   = snd3(m);
-    Type t    = thd3(m);
-    List sig  = NIL;
-    List tvs  = NIL;
-    List xtvs = NIL;
-
-    if (isPolyType(t)) {
-       xtvs = fst(snd(t));
-       t    = monotypeOf(t);
-    }
-  
-
-    tyvars    = typeVarsIn(t,NIL,xtvs,tyvars);
-                                       /* Look for extra type vars.       */
-    checkOptQuantVars(line,xtvs,tyvars);
-
-    if (isQualType(t)) {               /* Overloaded member signatures?   */
-       map2Over(depPredExp,line,tyvars,fst(snd(t)));
-    } else {
-        t = ap(QUAL,pair(NIL,t));
-    }
-
-    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                */
-        sig = ap(NIL,sig);
-    }
-    if (nonNull(sig)) {
-       t = mkPolyType(sig,t);
-    }
-    thd3(m) = t;                                /* Save type               */
-    take(cclass(c).arity,tyvars);               /* Delete extra type vars  */
-
-    h98CheckType(line,"member type",hd(vs),t);
-}
-
-static Void local checkMems2(c,m) /* check member function details   */
-Class c;
-Cell  m; {
-    Int  line = intOf(fst3(m));
-    List vs   = snd3(m);
-    Type t    = thd3(m);
-
-    if (isAmbiguous(t)) {
-        ambigError(line,"class declaration",hd(vs),t);
-    }
-}
-
-static Void local addMembers(c)         /* Add definitions of member funs  */
-Class c; {                              /* and other parts of class struct.*/
-    List ms  = fst(cclass(c).members);
-    List fs  = snd(cclass(c).members);
-    List ns  = NIL;                     /* List of names                   */
-    Int  mno;                           /* Member function number          */
-
-    for (mno=0; mno<cclass(c).numSupers; mno++) {
-        ns = cons(newDSel(c,mno),ns);
-    }
-    cclass(c).dsels = rev(ns);          /* Save dictionary selectors       */
-
-    for (mno=1, ns=NIL; nonNull(ms); ms=tl(ms)) {
-        Int  line = intOf(fst3(hd(ms)));
-        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,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.
-
-    cclass(c).dtycon    = addPrimTycon(generateText("Dict.%s",c),
-                                       NIL,
-                                       cclass(c).arity,
-                                       DATATYPE,
-                                       NIL);
-*/
-
-    mno                  = cclass(c).numSupers + cclass(c).numMembers;
-    /* cclass(c).dcon       = addPrimCfun(generateText("Make.%s",c),mno,0,NIL); */
-    cclass(c).dcon       = addPrimCfun(generateText(":D%s",c),mno,0,NIL);
-    /* implementCfun(cclass(c).dcon,NIL);
-       Don't manufacture a wrapper fn for dictionary constructors.
-       Applications of dictionary constructors are always saturated,
-       and translate.c:stgExpr() special-cases saturated constructor apps.
-    */
-
-    if (mno==1) {                       /* Single entry dicts use newtype  */
-        name(cclass(c).dcon).defn = nameId;
-       if (nonNull(cclass(c).members)) {
-           name(hd(cclass(c).members)).number = mfunNo(0);
-       }
-    }
-    cclass(c).defaults   = classBindings("class",c,cclass(c).defaults);
-}
-
-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),parent);
-    } else if (name(m).defn!=PREDEFINED) {
-        ERRMSG(l) "Repeated definition for member function \"%s\"",
-                  textToStr(name(m).text)
-        EEND;
-    }
-
-    name(m).line     = l;
-    name(m).arity    = 1;
-    name(m).number   = mfunNo(no);
-    name(m).type     = t;
-    return m;
-}
-
-Name newDSel(c,no)                      /* Make definition for dict selectr*/
-Class c;
-Int   no; {
-    Name s;
-    char buf[16];
-
-    /* sprintf(buf,"sc%d.%s",no,"%s"); */
-    sprintf(buf,"$p%d%s",no+1,"%s");
-    s                = newName(generateText(buf,c),c);
-    name(s).line     = cclass(c).line;
-    name(s).arity    = 1;
-    name(s).number   = DFUNNAME;
-    return s;
-}
-
-#define MAX_GEN  128
-
-static Text local generateText(sk,c)    /* We need to generate names for   */
-String sk;                              /* certain objects corresponding   */
-Class  c; {                             /* to each class.                  */
-    String cname = textToStr(cclass(c).text);
-    char buffer[MAX_GEN+1];
-
-    if ((strlen(sk)+strlen(cname))>=MAX_GEN) {
-        ERRMSG(0) "Please use a shorter name for class \"%s\"", cname
-        EEND;
-    }
-    sprintf(buffer,sk,cname);
-    return findText(buffer);
-}
-
-       Int visitClass(c)                /* visit class defn to check that  */
-Class c; {                              /* class hierarchy is acyclic      */
-#if TREX
-    if (isExt(c)) {                     /* special case for lacks preds    */
-        return 0;
-    }
-#endif
-    if (cclass(c).level < 0) {          /* already visiting this class?    */
-        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   */
-        List scs = cclass(c).supers;
-        Int  lev = 0;
-        cclass(c).level = (-1);
-        for (; nonNull(scs); scs=tl(scs)) {
-            Int l = visitClass(getHead(hd(scs)));
-            if (l>lev) lev=l;
-        }
-        cclass(c).level = 1+lev;        /* level = 1 + max level of supers */
-    }
-    return cclass(c).level;
-}
-
-/* --------------------------------------------------------------------------
- * Process class and instance declaration binding groups:
- * ------------------------------------------------------------------------*/
-
-static List local classBindings(where,c,bs)
-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 body = snd(snd(b));
-        Name mnm;
-
-        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(body))))
-                "No member \"%s\" in class \"%s\"",
-                textToStr(textOf(fst(b))), textToStr(cclass(c).text)
-            EEND;
-        }
-        snd(b) = body;
-        nbs    = numInsert(mfunOf(mnm)-1,b,nbs);
-    }
-    return nbs;
-}
-
-static Name local memberName(c,t)       /* return name of member function  */
-Class c;                                /* with name t in class c          */
-Text  t; {                              /* return NIL if not a member      */
-    List ms = cclass(c).members;
-    for (; nonNull(ms); ms=tl(ms)) {
-        if (t==name(hd(ms)).text) {
-            return hd(ms);
-        }
-    }
-    return 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;
-
-    for (xs=start; 0<n--; xs=tl(xs)) {
-        if (isNull(tl(xs))) {
-            tl(xs) = cons(NIL,NIL);
-        }
-    }
-    hd(xs) = x;
-    return start;
-}
-
-/* --------------------------------------------------------------------------
- * Calculate set of variables appearing in a given type expression (possibly
- * qualified) as a list of distinct values.  The order in which variables
- * appear in the list is the same as the order in which those variables
- * occur in the type expression when read from left to right.
- * ------------------------------------------------------------------------*/
-
-List local typeVarsIn(ty,us,ws,vs)      /*Calculate list of type variables*/
-Cell ty;                               /* used in type expression, reading*/
-List us;                               /* from left to right ignoring any */
-List ws;                               /* listed in us.                   */
-List vs; {                             /* ws = explicitly quantified vars */
-    if (isNull(ty)) return vs;
-    switch (whatIs(ty)) {
-        case DICTAP    : return typeVarsIn(snd(snd(ty)),us,ws,vs);
-        case UNBOXEDTUP: return typeVarsIn(snd(ty),us,ws,vs);
-
-       case AP        : return typeVarsIn(snd(ty),us,ws,
-                                          typeVarsIn(fst(ty),us,ws,vs));
-
-       case VARIDCELL :
-       case VAROPCELL : if ((nonNull(findBtyvs(textOf(ty)))
-                             && !varIsMember(textOf(ty),ws))
-                            || varIsMember(textOf(ty),us)) {
-                            return vs;
-                        } else {
-                            return maybeAppendVar(ty,vs);
-                        }
-
-       case POLYTYPE  : return typeVarsIn(monotypeOf(ty),polySigOf(ty),ws,vs);
-
-       case QUAL      : {   vs = typeVarsIn(fst(snd(ty)),us,ws,vs);
-                            return typeVarsIn(snd(snd(ty)),us,ws,vs);
-                        }
-
-       case BANG      : return typeVarsIn(snd(ty),us,ws,vs);
-
-       case LABC      : {   List fs = snd(snd(ty));
-                            for (; nonNull(fs); fs=tl(fs)) {
-                               vs = typeVarsIn(snd(hd(fs)),us,ws,vs);
-                            }
-                            return vs;
-                        }
-        case TUPLE:
-        case TYCON:
-        case CONIDCELL:
-        case QUALIDENT: return vs;
-
-        default: fprintf(stderr, " bad tag = %d\n", whatIs(ty));internal("typeVarsIn");
-    }
-    assert(0);
-}
-
-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;
-    List c = vs;
-
-    while (nonNull(c)) {
-        if (textOf(hd(c))==t) {
-            return vs;
-        }
-        p = c;
-        c = tl(c);
-    }
-
-    if (nonNull(p)) {
-        tl(p) = cons(v,NIL);
-    } else {
-        vs    = cons(v,NIL);
-    }
-
-    return vs;
-}
-
-/* --------------------------------------------------------------------------
- * Static analysis for type expressions is required to:
- *   - ensure that each type constructor or class used has been defined.
- *   - replace type variables by offsets, constructor names by Tycons.
- *   - ensure that the type is well-kinded.
- * ------------------------------------------------------------------------*/
-
-static Type local checkSigType(line,where,e,type)
-Int    line;                            /* Check validity of type expr in  */
-String where;                           /* explicit type signature         */
-Cell   e;
-Type   type; {
-    List tvs  = NIL;
-    List sunk = NIL;
-    List xtvs = NIL;
-
-    if (isPolyType(type)) {
-       xtvs = fst(snd(type));
-       type = monotypeOf(type);
-    }
-    tvs  = typeVarsIn(type,NIL,xtvs,NIL);
-    sunk = unkindTypes;
-    checkOptQuantVars(line,xtvs,tvs);
-
-    if (isQualType(type)) {
-       map2Over(depPredExp,line,tvs,fst(snd(type)));
-       snd(snd(type)) = depTopType(line,tvs,snd(snd(type)));
-
-        if (isAmbiguous(type)) {
-            ambigError(line,where,e,type);
-        }
-    } else {
-        type = depTopType(line,tvs,type);
-    }
-
-    if (nonNull(tvs)) {
-       if (length(tvs) >= (OFF_MAX-OFF_MIN+1)) {
-            ERRMSG(line) "Too many type variables in %s\n", where
-            EEND;
-        } else {
-            List ts = tvs;
-            for (; nonNull(ts); ts=tl(ts)) {
-                hd(ts) = NIL;
-            }
-            type    = mkPolyType(tvs,type);
-        }
-    }
-
-    unkindTypes = NIL;
-    kindType(line,"type expression",type);
-    fixKinds();
-    unkindTypes = sunk;
-
-    h98CheckType(line,where,e,type);
-    return type;
-}
-
-static Void local checkOptQuantVars(line,xtvs,tvs)
-Int  line;
-List xtvs;                             /* Explicitly quantified vars      */
-List tvs; {                            /* Implicitly quantified vars      */
-    if (nonNull(xtvs)) {
-       List vs = tvs;
-       for (; nonNull(vs); vs=tl(vs)) {
-           if (!varIsMember(textOf(hd(vs)),xtvs)) {
-               ERRMSG(line) "Quantifier does not mention type variable \"%s\"",
-                            textToStr(textOf(hd(vs)))
-               EEND;
-           }
-       }
-       for (vs=xtvs; nonNull(vs); vs=tl(vs)) {
-           if (!varIsMember(textOf(hd(vs)),tvs)) {
-               ERRMSG(line) "Quantified type variable \"%s\" is not used",
-                            textToStr(textOf(hd(vs)))
-               EEND;
-           }
-           if (varIsMember(textOf(hd(vs)),tl(vs))) {
-               ERRMSG(line) "Quantified type variable \"%s\" is repeated",
-                            textToStr(textOf(hd(vs)))
-               EEND;
-           }
-       }
-    }
-}
-
-static Type local depTopType(l,tvs,t)   /* Check top-level of type sig     */
-Int  l;
-List tvs;
-Type t; {
-    Type prev = NIL;
-    Type t1   = t;
-    Int  nr2  = 0;
-    Int  i    = 1;
-    for (; getHead(t1)==typeArrow && argCount==2; ++i) {
-        arg(fun(t1)) = depCompType(l,tvs,arg(fun(t1)));
-       if (isPolyOrQualType(arg(fun(t1)))) {
-            nr2 = i;
-        }
-        prev = t1;
-        t1   = arg(t1);
-    }
-    if (nonNull(prev)) {
-        arg(prev) = depTypeExp(l,tvs,t1);
-    } else {
-        t = depTypeExp(l,tvs,t1);
-    }
-    if (nr2>0) {
-        t = ap(RANK2,pair(mkInt(nr2),t));
-    }
-    return t;
-}
-
-static Type local depCompType(l,tvs,t)  /* Check component type for constr */
-Int  l;
-List tvs;
-Type t; {
-  Int  ntvs = length(tvs);
-  List nfr  = NIL;
-  if (isPolyType(t)) {
-    List vs  = fst(snd(t));
-    t        = monotypeOf(t);
-    tvs      = checkQuantVars(l,vs,tvs,t);
-    nfr      = replicate(length(vs),NIL);
-  }
-  if (isQualType(t)) {
-    map2Over(depPredExp,l,tvs,fst(snd(t)));
-    snd(snd(t)) = depTypeExp(l,tvs,snd(snd(t)));
-    if (isAmbiguous(t)) {
-      ambigError(l,"type component",NIL,t);
-    }
-  } else {
-    t = depTypeExp(l,tvs,t);
-  }
-  if (isNull(nfr)) {
-    return t;
-  }
-  take(ntvs,tvs);
-  return mkPolyType(nfr,t);
-}
-
-static Type local depTypeExp(line,tyvars,type)
-Int  line;
-List tyvars;
-Type type; {
-    switch (whatIs(type)) {
-        case AP         : fst(type) = depTypeExp(line,tyvars,fst(type));
-                          snd(type) = depTypeExp(line,tyvars,snd(type));
-                          break;
-
-        case VARIDCELL  : return depTypeVar(line,tyvars,textOf(type));
-
-        case QUALIDENT  : if (isQVar(type)) {
-                              ERRMSG(line) "Qualified type variables not allowed"
-                              EEND;
-                          }
-                          /* deliberate fall through */
-        case CONIDCELL  : {   Tycon tc = findQualTycon(type);
-                              if (isNull(tc)) {
-                                  ERRMSG(line)
-                                      "Undefined type constructor \"%s\"",
-                                      identToStr(type)
-                                  EEND;
-                              }
-                              if (cellIsMember(tc,tyconDefns) &&
-                                  !cellIsMember(tc,tcDeps)) {
-                                  tcDeps = cons(tc,tcDeps);
-                              }
-                              return tc;
-                          }
-
-#if TREX
-        case EXT        : h98DoesntSupport(line,"extensible records");
-#endif
-        case TYCON      :
-        case TUPLE      : break;
-
-        default         : internal("depTypeExp");
-    }
-    return type;
-}
-
-static Type local depTypeVar(line,tyvars,tv)
-Int  line;
-List tyvars;
-Text tv; {
-    Int offset = 0;
-    Int found  = (-1);
-
-    for (; nonNull(tyvars); offset++) {
-       if (tv==textOf(hd(tyvars))) {
-           found = offset;
-       }
-       tyvars = tl(tyvars);
-    }
-    if (found<0) {
-       Cell vt = findBtyvs(tv);
-       if (nonNull(vt)) {
-           return fst(vt);
-       }
-       ERRMSG(line) "Undefined type variable \"%s\"", textToStr(tv)
-       EEND;
-    }
-    return mkOffset(found);
-}
-
-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,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 0
-            if (varIsMember(u,tvs)) {
-                ERRMSG(line) "Local quantifier for %s hides an outer use",
-                             textToStr(u)
-                EEND;
-            }
-#endif
-            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))
- * ------------------------------------------------------------------------*/
-
-List 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;
-    }
-}
-
-List zonkTyvarsIn(t,vs)
-Type t;
-List vs; {
-    switch (whatIs(t)) {
-       case AP       : return zonkTyvarsIn(fun(t),
-                                zonkTyvarsIn(arg(t),vs));
-
-       case INTCELL  : if (cellIsMember(t,vs))
-                           return vs;
-                       else
-                           return cons(t,vs);
-
-       /* this case will lead to a type error --
-          much better than reporting an internal error ;-) */
-       /* case OFFSET   : internal("zonkTyvarsIn"); */
-
-       default       : return vs;
-    }
-}
-
-static List local otvars(pi,os)                /* os is a list of offsets that    */
-Cell pi;                               /* refer to the arguments of pi;   */
-List os; {                             /* find list of offsets in those   */
-    List us = NIL;                     /* positions                       */
-    for (; nonNull(os); os=tl(os)) {
-       us = offsetTyvarsIn(nthArg(offsetOf(hd(os)),pi),us);
-    }
-    return us;
-}
-
-static List local otvarsZonk(pi,os,o)  /* same as above, but zonks        */
-Cell pi;
-List os; {
-    List us = NIL;
-    for (; nonNull(os); os=tl(os)) {
-        Type t = zonkType(nthArg(offsetOf(hd(os)),pi),o);
-       us = zonkTyvarsIn(t,us);
-    }
-    return us;
-}
-
-static Bool local odiff(us,vs)
-List us, vs; {
-    while (nonNull(us) && cellIsMember(hd(us),vs)) {
-       us = tl(us);
-    }
-    return us;
-}
-
-static Bool local osubset(us,vs)       /* Determine whether us is subset  */
-List us, vs; {                         /* of vs                           */
-    while (nonNull(us) && cellIsMember(hd(us),vs)) {
-       us = tl(us);
-    }
-    return isNull(us);
-}
-
-List oclose(fds,vs)    /* Compute closure of vs wrt to fds*/
-List fds;
-List vs; {
-    Bool changed = TRUE;
-    while (changed) {
-       List fds1 = NIL;
-       changed = FALSE;
-        while (nonNull(fds)) {
-           Cell fd   = hd(fds);
-           List next = tl(fds);
-           if (osubset(fst(fd),vs)) {  /* Test if fd applies              */
-               List os = snd(fd);
-               for (; nonNull(os); os=tl(os)) {
-                   if (!cellIsMember(hd(os),vs)) {
-                       vs      = cons(hd(os),vs);
-                       changed = TRUE;
-                   }
-               }
-           } else {                    /* Didn't apply this time, so keep */
-               tl(fds) = fds1;
-               fds1    = fds;
-           }
-           fds = next;
-       }
-       fds = fds1;
-    }
-    return vs;
-}
-
-Bool isAmbiguous(type)                 /* Determine whether type is       */
-Type type; {                           /* ambiguous                       */
-    if (isPolyType(type)) {
-       type = monotypeOf(type);
-    }
-    if (isQualType(type)) {            /* only qualified types can be     */
-       List ps   = fst(snd(type));     /* ambiguous                       */
-       List tvps = offsetTyvarsIn(ps,NIL);
-       List tvts = offsetTyvarsIn(snd(snd(type)),NIL);
-       List fds  = calcFunDeps(ps);
-
-       tvts = oclose(fds,tvts);        /* Close tvts under fds            */
-       return !osubset(tvps,tvts);
-    }
-    return FALSE;
-}
-
-List calcFunDeps(ps)
-List ps; {
-    List fds  = NIL;
-    for (; nonNull(ps); ps=tl(ps)) {/* Calc functional dependencies       */
-       Cell pi = hd(ps);
-       Cell c  = getHead(pi);
-       if (isClass(c)) {
-           List xfs = cclass(c).xfds;
-           for (; nonNull(xfs); xfs=tl(xfs)) {
-               List fs = snd(hd(xfs));
-               for (; nonNull(fs); fs=tl(fs)) {
-                   fds = cons(pair(otvars(pi,fst(hd(fs))),
-                                   otvars(pi,snd(hd(fs)))),fds);
-               }
-           }
-       }
-#if IPARAM
-       else if (isIP(c)) {
-           fds = cons(pair(NIL,offsetTyvarsIn(arg(pi),NIL)),fds);
-       }
-#endif
-    }
-    return fds;
-}
-
-List calcFunDepsPreds(ps)
-List ps; {
-    List fds  = NIL;
-    for (; nonNull(ps); ps=tl(ps)) {/* Calc functional dependencies       */
-       Cell pi3 = hd(ps);
-       Cell pi = fst3(pi3);
-       Cell c  = getHead(pi);
-       Int o = intOf(snd3(pi3));
-       if (isClass(c)) {
-           List xfs = cclass(c).xfds;
-           for (; nonNull(xfs); xfs=tl(xfs)) {
-               List fs = snd(hd(xfs));
-               for (; nonNull(fs); fs=tl(fs)) {
-                   fds = cons(pair(otvarsZonk(pi,fst(hd(fs)),o),
-                                   otvarsZonk(pi,snd(hd(fs)),o)),fds);
-               }
-           }
-       }
-#if IPARAM
-       else if (isIP(c)) {
-           fds = cons(pair(NIL,zonkTyvarsIn(arg(pi),NIL)),fds);
-       }
-#endif
-    }
-    return fds;
-}
-
-Void ambigError(line,where,e,type)      /* produce error message for       */
-Int    line;                            /* ambiguity                       */
-String where;
-Cell   e;
-Type   type; {
-    ERRMSG(line) "Ambiguous type signature in %s", where ETHEN
-    ERRTEXT      "\n*** ambiguous type : " ETHEN ERRTYPE(type);
-    if (nonNull(e)) {
-        ERRTEXT  "\n*** assigned to    : " ETHEN ERREXPR(e);
-    }
-    ERRTEXT      "\n"
-    EEND;
-}
-
-/* --------------------------------------------------------------------------
- * Kind inference for simple types:
- * ------------------------------------------------------------------------*/
-
-static Void local kindConstr(line,alpha,m,c)
-Int  line;                              /* Determine kind of constructor   */
-Int  alpha;
-Int  m;
-Cell c; {
-    Cell h = getHead(c);
-    Int  n = argCount;
-
-#ifdef DEBUG_KINDS
-    Printf("kindConstr: alpha=%d, m=%d, c=",alpha,m);
-    printType(stdout,c);
-    Printf("\n");
-#endif
-
-    switch (whatIs(h)) {
-        case POLYTYPE : if (n!=0) {
-                            internal("kindConstr1");
-                        } else {
-                            static String pt = "polymorphic type";
-                            Type  t  = dropRank1(c,alpha,m);
-                            Kinds ks = polySigOf(t);
-                            Int   m1 = 0;
-                            Int   beta;
-                            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");
-                        }
-                        map3Proc(kindPred,line,alpha,m,fst(snd(c)));
-                        kindConstr(line,alpha,m,snd(snd(c)));
-                        return;
-
-        case EXIST    :
-        case RANK2    : kindConstr(line,alpha,m,snd(snd(c)));
-                        return;
-
-#if TREX
-        case EXT      : if (n!=2) {
-                            ERRMSG(line)
-                                "Illegal use of row in " ETHEN ERRTYPE(c);
-                            ERRTEXT "\n"
-                            EEND;
-                        }
-                        break;
-#endif
-
-        case TYCON    : if (isSynonym(h) && n<tycon(h).arity) {
-                            ERRMSG(line)
-                              "Not enough arguments for type synonym \"%s\"",
-                              textToStr(tycon(h).text)
-                            EEND;
-                        }
-                        break;
-    }
-
-    if (n==0) {                         /* trivial case, no arguments      */
-        typeIs = kindAtom(alpha,c);
-    } else {                            /* non-trivial application         */
-        static String app = "constructor application";
-        Cell   a = c;
-        Int    i;
-        Kind   k;
-        Int    beta;
-
-        varKind(n);
-        beta   = typeOff;
-        k      = typeIs;
-
-        typeIs = kindAtom(alpha,h);     /* h  :: v1 -> ... -> vn -> w      */
-        shouldKind(line,h,c,app,k,beta);
-
-        for (i=n; i>0; --i) {           /* ci :: vi for each 1 <- 1..n     */
-            checkKind(line,alpha,m,arg(a),c,app,aVar,beta+i-1);
-            a = fun(a);
-        }
-        tyvarType(beta+n);              /* inferred kind is w              */
-    }
-}
-
-static Kind local kindAtom(alpha,c)     /* Find kind of atomic constructor */
-Int  alpha;
-Cell c; {
-    switch (whatIs(c)) {
-        case TUPLE     : return simpleKind(tupleOf(c)); /*(,)::* -> * -> * */
-        case OFFSET    : return mkInt(alpha+offsetOf(c));
-        case TYCON     : return tycon(c).kind;
-        case INTCELL   : return c;
-        case VARIDCELL :
-        case VAROPCELL : {   Cell vt = findBtyvs(textOf(c));
-                             if (nonNull(vt)) {
-                                 return snd(vt);
-                             }
-                         }
-#if TREX
-        case EXT       : return extKind;
-#endif
-    }
-#if DEBUG_KINDS
-    Printf("kindAtom(%d,whatIs(%d)) on ",alpha,whatIs(c));
-    printType(stdout,c);
-    Printf("\n");
-#endif
-    internal("kindAtom");
-    return STAR;/* not reached */
-}
-
-static Void local kindPred(l,alpha,m,pi)/* Check kinds of arguments in pred*/
-Int  l;
-Int  alpha;
-Int  m;
-Cell pi; {
-#if TREX
-    if (isAp(pi) && isExt(fun(pi))) {
-        static String lackspred = "lacks predicate";
-        checkKind(l,alpha,m,arg(pi),NIL,lackspred,ROW,0);
-        return;
-    }
-#endif
-#if IPARAM
-    if (isAp(pi) && whatIs(fun(pi)) == IPCELL) {
-       static String ippred = "iparam predicate";
-       checkKind(l,alpha,m,arg(pi),NIL,ippred,STAR,0);
-       return;
-    }
-#endif
-    {   static String predicate = "class constraint";
-        Class c  = getHead(pi);
-        List  as = getArgs(pi);
-        Kinds ks = cclass(c).kinds;
-
-        while (nonNull(ks)) {
-            checkKind(l,alpha,m,hd(as),NIL,predicate,hd(ks),0);
-            ks = tl(ks);
-            as = tl(as);
-        }
-    }
-}
-
-static Void local kindType(line,wh,type)/* check that (poss qualified) type*/
-Int    line;                            /* is well-kinded                  */
-String wh;
-Type   type; {
-    checkKind(line,0,0,type,NIL,wh,STAR,0);
-}
-
-static Void local fixKinds() {          /* add kind annotations to types   */
-    for (; nonNull(unkindTypes); unkindTypes=tl(unkindTypes)) {
-        Pair pr   = hd(unkindTypes);
-        Int  beta = intOf(fst(pr));
-        Cell qts  = polySigOf(snd(pr));
-        for (;;) {
-            if (isNull(hd(qts))) {
-                hd(qts) = copyKindvar(beta++);
-            } else {
-                internal("fixKinds");
-            }
-            if (nonNull(tl(qts))) {
-                qts = tl(qts);
-            } else {
-                tl(qts) = STAR;
-                break;
-            }
-        }
-#ifdef DEBUG_KINDS
-        Printf("Type expression: ");
-        printType(stdout,snd(pr));
-        Printf(" :: ");
-        printKind(stdout,polySigOf(snd(pr)));
-        Printf("\n");
-#endif
-    }
-}
-
-/* --------------------------------------------------------------------------
- * Kind checking of groups of type constructors and classes:
- * ------------------------------------------------------------------------*/
-
-static Void local kindTCGroup(tcs)      /* find kinds for mutually rec. gp */
-List tcs; {                             /* of tycons and classes           */
-    emptySubstitution();
-    unkindTypes = NIL;
-    mapProc(initTCKind,tcs);
-    mapProc(kindTC,tcs);
-    mapProc(genTC,tcs);
-    fixKinds();
-    emptySubstitution();
-}
-    
-static Void local initTCKind(c)         /* build initial kind/arity for c  */
-Cell c; {
-    if (isTycon(c)) {                   /* Initial kind of tycon is:       */
-        Int beta = newKindvars(1);      /*    v1 -> ... -> vn -> vn+1      */
-        varKind(tycon(c).arity);        /* where n is the arity of c.      */
-        bindTv(beta,typeIs,typeOff);    /* For data definitions, vn+1 == * */
-        switch (whatIs(tycon(c).what)) {
-            case NEWTYPE  :
-            case DATATYPE : bindTv(typeOff+tycon(c).arity,STAR,0);
-        }
-        tycon(c).kind = mkInt(beta);
-    } else {
-        Int n    = cclass(c).arity;
-        Int beta = newKindvars(n);
-        cclass(c).kinds = NIL;
-       while (n>0) {
-            n--;
-            cclass(c).kinds = pair(mkInt(beta+n),cclass(c).kinds);
-        }
-    }
-}
-
-static Void local kindTC(c)             /* check each part of a tycon/class*/
-Cell c; {                               /* is well-kinded                  */
-    if (isTycon(c)) {
-        static String cfun = "constructor function";
-        static String tsyn = "synonym definition";
-        Int line = tycon(c).line;
-        Int beta = tyvar(intOf(tycon(c).kind))->offs;
-        Int m    = tycon(c).arity;
-        switch (whatIs(tycon(c).what)) {
-            case NEWTYPE     :
-            case DATATYPE    : {   List cs = tycon(c).defn;
-                                  if (isQualType(cs)) {
-                                       map3Proc(kindPred,line,beta,m,
-                                                                fst(snd(cs)));
-                                       tycon(c).defn = cs = snd(snd(cs));
-                                   }
-                                   for (; hasCfun(cs); cs=tl(cs)) {
-                                       kindType(line,cfun,name(hd(cs)).type);
-                                   }
-                                   break;
-                               }
-
-            default          : checkKind(line,beta,m,tycon(c).defn,NIL,
-                                                        tsyn,aVar,beta+m);
-        }
-    }
-    else {                              /* scan type exprs in class defn to*/
-        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);
-        for (; nonNull(ms); ms=tl(ms)) {
-            Int  line = intOf(fst3(hd(ms)));
-            Type type = thd3(hd(ms));
-            kindType(line,"member function type signature",type);
-        }
-    }
-}
-
-static Void local genTC(c)              /* generalise kind inferred for    */
-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));
-        printKind(stdout,tycon(c).kind);
-        Putchar('\n');
-#endif
-    } else {
-        Kinds ks = cclass(c).kinds;
-        for (; nonNull(ks); ks=tl(ks)) {
-            hd(ks) = copyKindvar(intOf(hd(ks)));
-        }
-#ifdef DEBUG_KINDS
-        Printf("%s :: ",textToStr(cclass(c).text));
-        printKinds(stdout,cclass(c).kinds);
-        Putchar('\n');
-#endif
-    }
-}
-
-/* --------------------------------------------------------------------------
- * Static analysis of instance declarations:
- *
- * The first part of the static analysis is performed as the declarations
- * are read during parsing:
- * - make new entry in instance table
- * - record line number of declaration
- * - build list of instances defined in current script for use in later
- *   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                 */
-    Inst nw             = newInst();
-    inst(nw).line       = line;
-    inst(nw).specifics  = fst(head);
-    inst(nw).head       = snd(head);
-    inst(nw).implements = ms;
-    instDefns           = cons(nw,instDefns);
-}
-
-/* --------------------------------------------------------------------------
- * Further static analysis of instance declarations:
- *
- * Makes the following checks:
- * - Class part of header has form C (T a1 ... an) where C is a known
- *   class, and T is a known datatype constructor (or restricted synonym),
- *   and there is no previous C-T instance, and (T a1 ... an) has a kind
- *   appropriate for the class C.
- * - Each element of context is a valid class expression, with type vars
- *   drawn from a1, ..., an.
- * - All bindings are function bindings
- * - All bindings define member functions for class C
- * - Arrange bindings into appropriate order for member list
- * - No top level type signature declarations
- * ------------------------------------------------------------------------*/
-
-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,NIL);
-    List tvps = NIL, tvts = NIL;
-    List fds = 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;
-        }
-    }
-
-    /* add in the tyvars from the `specifics' so that we don't
-       prematurely complain about undefined tyvars */
-    tyvars = typeVarsIn(inst(in).specifics,NIL,NIL,tyvars);
-    inst(in).head = 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;
-        }
-    }
-
-    map2Over(depPredExp,line,tyvars,inst(in).specifics);
-
-    /* OK, now we start over, and test for ambiguity */
-    tvts = offsetTyvarsIn(inst(in).head,NIL);
-    tvps = offsetTyvarsIn(inst(in).specifics,NIL);
-    fds  = calcFunDeps(inst(in).specifics);
-    tvts = oclose(fds,tvts);
-    tvts = odiff(tvps,tvts);
-    if (!isNull(tvts)) {
-       ERRMSG(line) "Undefined type variable \"%s\"",
-         textToStr(textOf(nth(offsetOf(hd(tvts)),tyvars)))
-       EEND;
-    }
-
-    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)) {
-        ERRMSG(line) "Illegal predicate in instance declaration"
-        EEND;
-    }
-
-    if (nonNull(cclass(inst(in).c).fds)) {
-        List fds = cclass(inst(in).c).fds;
-        for (; nonNull(fds); fds=tl(fds)) {
-            List as = otvars(inst(in).head, fst(hd(fds)));
-            List bs = otvars(inst(in).head, snd(hd(fds)));
-           List fs = calcFunDeps(inst(in).specifics);
-           as = oclose(fs,as);
-            if (!osubset(bs,as)) {
-               ERRMSG(inst(in).line)
-                  "Instance is more general than a dependency allows"
-               ETHEN
-               ERRTEXT "\n*** Instance         : "
-               ETHEN ERRPRED(inst(in).head);
-               ERRTEXT "\n*** For class        : "
-               ETHEN ERRPRED(cclass(inst(in).c).head);
-               ERRTEXT "\n*** Under dependency : "
-               ETHEN ERRFD(hd(fds));
-               ERRTEXT "\n"
-               EEND;
-            }
-        }
-    }
-
-    kindInst(in,length(tyvars));
-    insertInst(in);
-
-    if (nonNull(extractSigdecls(inst(in).implements))) {
-        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);
-    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      */
-Inst in; {
-    Class c    = inst(in).c;
-    List  ins  = cclass(c).instances;
-    List  prev = NIL;
-
-    if (nonNull(cclass(c).fds)) {      /* Check for conflicts with fds    */
-       List ins1 = cclass(c).instances;
-       for (; nonNull(ins1); ins1=tl(ins1)) {
-           List fds = cclass(c).fds;
-           substitution(RESET);
-           for (; nonNull(fds); fds=tl(fds)) {
-               Int  alpha = newKindedVars(inst(in).kinds);
-               Int  beta  = newKindedVars(inst(hd(ins1)).kinds);
-               List as    = fst(hd(fds));
-               Bool same  = TRUE;
-               for (; same && nonNull(as); as=tl(as)) {
-                   Int n = offsetOf(hd(as));
-                   same &= unify(nthArg(n,inst(in).head),alpha,
-                                 nthArg(n,inst(hd(ins1)).head),beta);
-               }
-               if (isNull(as) && same) {
-                   for (as=snd(hd(fds)); same && nonNull(as); as=tl(as)) {
-                       Int n = offsetOf(hd(as));
-                       same &= sameType(nthArg(n,inst(in).head),alpha,
-                                        nthArg(n,inst(hd(ins1)).head),beta);
-                   }
-                   if (!same) {
-                       ERRMSG(inst(in).line)
-                          "Instances are not consistent with dependencies"
-                       ETHEN
-                       ERRTEXT "\n*** This instance    : "
-                       ETHEN ERRPRED(inst(in).head);
-                       ERRTEXT "\n*** Conflicts with   : "
-                       ETHEN ERRPRED(inst(hd(ins)).head);
-                       ERRTEXT "\n*** For class        : "
-                       ETHEN ERRPRED(cclass(c).head);
-                       ERRTEXT "\n*** Under dependency : "
-                       ETHEN ERRFD(hd(fds));
-                       ERRTEXT "\n"
-                       EEND;
-                   }
-               }
-           }
-       }
-    }
-
-
-    substitution(RESET);
-    while (nonNull(ins)) {              /* Look for overlap w/ other insts */
-        Int alpha = newKindedVars(inst(in).kinds);
-        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 && !haskell98) {
-                Bool bef = instCompare(in,hd(ins));
-                Bool aft = instCompare(hd(ins),in);
-                if (bef && !aft) {      /* in comes strictly before hd(ins)*/
-                    break;
-                }
-                if (aft && !bef) {      /* in comes strictly after hd(ins) */
-                    prev = ins;
-                    ins  = tl(ins);
-                    continue;
-                }
-            }
-#if MULTI_INST
-           if (multiInstRes && nonNull(inst(in).specifics)) {
-               break;
-           } else {
-#endif
-            ERRMSG(inst(in).line) "Overlapping instances for class \"%s\"",
-                                  textToStr(cclass(c).text)
-            ETHEN
-            ERRTEXT "\n*** This instance   : " ETHEN ERRPRED(inst(in).head);
-            ERRTEXT "\n*** Overlaps with   : " ETHEN
-                                               ERRPRED(inst(hd(ins)).head);
-            ERRTEXT "\n*** Common instance : " ETHEN
-                                               ERRPRED(pi);
-            ERRTEXT "\n"
-            EEND;
-        }
-#if MULTI_INST
-           }
-#endif
-        prev = ins;                     /* No overlap detected, so move on */
-        ins  = tl(ins);                 /* to next instance                */
-    }
-    substitution(RESET);
-
-    if (nonNull(prev)) {                /* Insert instance at this point   */
-        tl(prev) = cons(in,ins);
-    } else {
-        cclass(c).instances = cons(in,ins);
-    }
-}
-
-static Bool local instCompare(ia,ib)    /* See if ia is an instance of ib  */
-Inst ia, ib;{
-    Int alpha = newKindedVars(inst(ia).kinds);
-    Int beta  = newKindedVars(inst(ib).kinds);
-    return matchPred(inst(ia).head,alpha,inst(ib).head,beta);
-}
-
-static Name local newInstImp(in)        /* Make definition for inst builder*/
-Inst in; {
-    Name b         = newName(inventText(),in);
-    name(b).line   = inst(in).line;
-    name(b).arity  = inst(in).numSpecifics;
-    name(b).number = DFUNNAME;
-    return b;
-}
-
-/* --------------------------------------------------------------------------
- * Kind checking of instance declaration headers:
- * ------------------------------------------------------------------------*/
-
-static Void local kindInst(in,freedom)  /* check predicates in instance    */
-Inst in;
-Int  freedom; {
-    Int beta;
-
-    emptySubstitution();
-    beta = newKindvars(freedom);
-    kindPred(inst(in).line,beta,freedom,inst(in).head);
-    if (whatIs(inst(in).specifics)!=DERIVE) {
-        map3Proc(kindPred,inst(in).line,beta,freedom,inst(in).specifics);
-    }
-    for (inst(in).kinds = NIL; 0<freedom--; ) {
-        inst(in).kinds = cons(copyKindvar(beta+freedom),inst(in).kinds);
-    }
-#ifdef DEBUG_KINDS
-    Printf("instance ");
-    printPred(stdout,inst(in).head);
-    Printf(" :: ");
-    printKinds(stdout,inst(in).kinds);
-    Putchar('\n');
-#endif
-    emptySubstitution();
-}
-
-/* --------------------------------------------------------------------------
- * Process derived instance requests:
- * ------------------------------------------------------------------------*/
-
-static List derivedInsts;               /* list of derived instances       */
-
-static Void local checkDerive(t,p,ts,ct)/* verify derived instance request */
-Tycon t;                                /* for tycon t, with explicit      */
-List  p;                                /* context p, component types ts   */
-List  ts;                               /* and named class ct              */
-Cell  ct; {
-    Int   line = tycon(t).line;
-    Class c    = findQualClass(ct);
-    if (isNull(c)) {
-        ERRMSG(line) "Unknown class \"%s\" in derived instance",
-                    identToStr(ct)
-        EEND;
-    }
-    addDerInst(line,c,p,dupList(ts),t,tycon(t).arity);
-}
-
-static Void local addDerInst(line,c,p,cts,t,a)  /* Add a derived instance  */
-Int   line;
-Class c;
-List  p, cts;
-Type  t;
-Int   a; {
-    Inst in;
-    Cell head = t;                              /* Build instance head     */
-    Int  i    = 0;
-
-    for (; i<a; i++) {
-        head = ap(head,mkOffset(i));
-    }
-    head = ap(c,head);
-
-    in                  = newInst();
-    inst(in).c          = c;
-    inst(in).line       = line;
-    inst(in).head       = head;
-    inst(in).specifics  = ap(DERIVE,pair(dupList(p),cts));
-    inst(in).implements = NIL;
-    inst(in).kinds      = mkInt(a);
-    derivedInsts        = cons(in,derivedInsts);
-}
-
-Void addTupInst(c,n)                    /* Request derived instance of c   */
-Class c;                                /* for mkTuple(n) constructor      */
-Int   n; {
-    Int  m   = n;
-    List cts = NIL;
-    while (0<m--) {
-        cts = cons(mkOffset(m),cts);
-    }
-    cts = rev(cts);
-    addDerInst(0,c,NIL,cts,mkTuple(n),n);
-}
-
-#if TREX
-Inst addRecShowInst(c,e)                /* Generate instance for ShowRecRow*/
-Class c;                                /* c *must* be ShowRecRow          */
-Ext   e; {
-    Inst in               = newInst();
-    inst(in).c            = c;
-    inst(in).head         = ap(c,ap2(e,aVar,bVar));
-    inst(in).kinds        = extKind;
-    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),in);
-    cclass(c).instances   = appendOnto(cclass(c).instances,singleton(in));
-    return in;
-}
-
-Inst addRecEqInst(c,e)                  /* Generate instance for EqRecRow  */
-Class c;                                /* c *must* be EqRecRow            */
-Ext   e; {
-    Inst in               = newInst();
-    inst(in).c            = c;
-    inst(in).head         = ap(c,ap2(e,aVar,bVar));
-    inst(in).kinds        = extKind;
-    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),in);
-    cclass(c).instances   = appendOnto(cclass(c).instances,singleton(in));
-    return in;
-}
-#endif
-
-/* --------------------------------------------------------------------------
- * Calculation of contexts for derived instances:
- *
- * Allowing arbitrary types to appear in contexts makes it rather harder
- * to decide what the context for a derived instance should be.  For
- * example, given:
- *
- *    data T a = MkT [a] deriving Show,
- *
- * we could have either of the following:
- *
- *    instance (Show [a]) => Show (T a) where ...
- *    instance (Show a) => Show (T a) where ...
- *
- * (assuming, of course, that instance (Show a) => Show [a]).  For now, we
- * choose to reduce contexts in the hope of detecting errors at an earlier
- * stage---in contrast with value definitions, there is no way for a user
- * to provide something analogous to a `type signature' by which they might
- * be able to control this behaviour themselves.  We eliminate tautological
- * predicates, but only allow predicates to appear in the final result if
- * they have at least one argument with a variable at its head.
- *
- * In general, we have to deal with mutually recursive instance declarations.
- * We find a solution in the obvious way by iterating to find a fixed point.
- * Of course, without restrictions on the form of instance declarations, we
- * cannot be sure that this will always terminate!
- *
- * For each instance we maintain a pair of the form DERIVE (ctxt,ps).
- * Ctxt is a list giving the parts of the context that have been produced
- * so far in the form of predicate skeletons.  During the calculation of
- * derived instances, we attach a dummy NIL value to the end of the list
- * which acts as a kind of `variable': other parts of the system maintain
- * pointers to this variable, and use it to detect when the context has
- * been extended with new elements.  Meanwhile, ps is a list containing
- * predicates (pi,o) together with (delayed) substitutions of the form
- * (o,xs) where o is an offset and xs is one of the context variables
- * described above, which may have been partially instantiated.
- * ------------------------------------------------------------------------*/
-
-static Bool instsChanged;
-
-static Void local deriveContexts(is)    /* Calc contexts for derived insts */
-List is; {
-    emptySubstitution();
-    mapProc(initDerInst,is);            /* Prepare derived instances       */
-
-    do {                                /* Main calculation of contexts    */
-        instsChanged = FALSE;
-        mapProc(calcInstPreds,is);
-    } while (instsChanged);
-
-    mapProc(tidyDerInst,is);            /* Tidy up results                 */
-}
-
-static Void local initDerInst(in)       /* Prepare instance for calculation*/
-Inst in; {                              /* of derived instance context     */
-    Cell spcs = inst(in).specifics;
-    Int  beta = newKindedVars(inst(in).kinds);
-    if (whatIs(spcs)!=DERIVE) {
-        internal("initDerInst");
-    }
-    fst(snd(spcs)) = appendOnto(fst(snd(spcs)),singleton(NIL));
-    for (spcs=snd(snd(spcs)); nonNull(spcs); spcs=tl(spcs)) {
-        hd(spcs) = ap2(inst(in).c,hd(spcs),mkInt(beta));
-    }
-    inst(in).numSpecifics = beta;
-
-#ifdef DEBUG_DERIVING
-    Printf("initDerInst: ");
-    printPred(stdout,inst(in).head);
-    Printf("\n");
-    printContext(stdout,snd(snd(inst(in).specifics)));
-    Printf("\n");
-#endif
-}
-
-static Void local calcInstPreds(in)     /* Calculate next approximation    */
-Inst in; {                              /* of the context for a derived    */
-    List retain = NIL;                  /* instance                        */
-    List ps     = snd(snd(inst(in).specifics));
-    List spcs   = fst(snd(inst(in).specifics));
-    Int  beta   = inst(in).numSpecifics;
-    Int  its    = 1;
-    Int  factor = 1+length(ps);
-
-#ifdef DEBUG_DERIVING
-    Printf("calcInstPreds: ");
-    printPred(stdout,inst(in).head);
-    Printf("\n");
-#endif
-
-    while (nonNull(ps)) {
-        Cell p = hd(ps);
-        ps     = tl(ps);
-       if (its++ >= factor*cutoff) {
-           Cell bpi = inst(in).head;
-           ERRMSG(inst(in).line) "\n*** Cannot derive " ETHEN ERRPRED(bpi);
-           ERRTEXT " after %d iterations.", its-1   ETHEN
-           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;
-       }
-        if (isInt(fst(p))) {                    /* Delayed substitution?   */
-            List qs = snd(p);
-            for (; nonNull(hd(qs)); qs=tl(qs)) {
-                ps = cons(pair(hd(qs),fst(p)),ps);
-            }
-            retain = cons(pair(fst(p),qs),retain);
-        }
-#if TREX
-        else if (isExt(fun(fst(p)))) {          /* Lacks predicate         */
-            Text   l = extText(fun(fst(p)));
-            Type   t = arg(fst(p));
-            Int    o = intOf(snd(p));
-            Type   h;
-            Tyvar *tyv;
-
-            deRef(tyv,t,o);
-            h = getDerefHead(t,o);
-            while (isExt(h) && argCount==2 && l!=extText(h)) {
-                t = arg(t);
-                deRef(tyv,t,o);
-                h = getDerefHead(t,o);
-            }
-            if (argCount==0 && isOffset(h)) {
-                maybeAddPred(ap(fun(fun(p)),h),o,beta,spcs);
-            } else if (argCount!=0 || h!=typeNoRow) {
-                Cell bpi = inst(in).head;
-                Cell pi  = copyPred(fun(p),intOf(snd(p)));
-                ERRMSG(inst(in).line) "Cannot derive " ETHEN ERRPRED(bpi);
-                ERRTEXT " because predicate " ETHEN ERRPRED(pi);
-                ERRTEXT " does not hold\n"
-                EEND;
-            }
-        }
-#endif
-        else {                                  /* Class predicate         */
-            Cell pi  = fst(p);
-            Int  o   = intOf(snd(p));
-            Inst in1 = findInstFor(pi,o);
-            if (nonNull(in1)) {
-                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)) {
-                        ps = cons(pair(hd(qs),off),ps);
-                    }
-                    retain = cons(pair(off,qs),retain);
-                } else {                        /* Previously def'd inst   */
-                    for (; nonNull(qs); qs=tl(qs)) {
-                        ps = cons(pair(hd(qs),off),ps);
-                    }
-                }
-            } else {                            /* No matching instance    */
-                Cell qi = pi;
-                while (isAp(qi) && isOffset(getDerefHead(arg(qi),o))) {
-                    qi = fun(qi);
-                }
-                if (isAp(qi)) {
-                    Cell bpi = inst(in).head;
-                    pi       = copyPred(pi,o);
-                    ERRMSG(inst(in).line) "An instance of " ETHEN ERRPRED(pi);
-                    ERRTEXT " is required to derive "       ETHEN ERRPRED(bpi);
-                    ERRTEXT "\n"
-                    EEND;
-                } else {
-                    maybeAddPred(pi,o,beta,spcs);
-                }
-            }
-        }
-    }
-    snd(snd(inst(in).specifics)) = retain;
-}
-
-static Void local maybeAddPred(pi,o,beta,ps)
-Cell pi;                                /* Add predicate pi to the list ps,*/
-Int  o;                                 /* setting the instsChanged flag if*/
-Int  beta;                              /* pi is not already a member and  */
-List ps; {                              /* using beta to adjust vars       */
-    Cell c = getHead(pi);
-    for (; nonNull(ps); ps=tl(ps)) {
-        if (isNull(hd(ps))) {           /* reached the `dummy' end of list?*/
-            hd(ps)       = copyAdj(pi,o,beta);
-            tl(ps)       = pair(NIL,NIL);
-            instsChanged = TRUE;
-            return;
-        } else if (c==getHead(hd(ps)) && samePred(pi,o,hd(ps),beta)) {
-            return;
-        }
-    }
-}
-
-static Cell local copyAdj(c,o,beta)     /* Copy (c,o), replacing vars with */
-Cell c;                                 /* offsets relative to beta.       */
-Int  o;
-Int  beta; {
-    switch (whatIs(c)) {
-        case AP     : {   Cell l = copyAdj(fst(c),o,beta);
-                          Cell r = copyAdj(snd(c),o,beta);
-                          return ap(l,r);
-                      }
-
-        case OFFSET : {   Int   vn   = o+offsetOf(c);
-                          Tyvar *tyv = tyvar(vn);
-                          if (isBound(tyv)) {
-                              return copyAdj(tyv->bound,tyv->offs,beta);
-                          }
-                          vn -= beta;
-                          if (vn<0 || vn>=(OFF_MAX-OFF_MIN+1)) {
-                              internal("copyAdj");
-                          }
-                          return mkOffset(vn);
-                      }
-    }
-    return c;
-}
-
-static Void local tidyDerInst(in)       /* Tidy up results of derived inst */
-Inst in; {                              /* calculations                    */
-    Int  o  = inst(in).numSpecifics;
-    List ps = tl(rev(fst(snd(inst(in).specifics))));
-    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: ");
-    printContext(stdout,inst(in).specifics);
-    Printf(" ||- ");
-    printPred(stdout,inst(in).head);
-    Printf("\n");
-#endif
-}
-
-/* --------------------------------------------------------------------------
- * Generate code for derived instances:
- * ------------------------------------------------------------------------*/
-
-static Void local addDerivImp(in)
-Inst in; {
-    List  imp = NIL;
-    Type  t   = getHead(arg(inst(in).head));
-    Class c   = inst(in).c;
-    if (c==classEq) {
-        imp = deriveEq(t);
-    } else if (c==classOrd) {
-        imp = deriveOrd(t);
-    } else if (c==classEnum) {
-        imp = deriveEnum(t);
-    } else if (c==classIx) {
-        imp = deriveIx(t);
-    } else if (c==classShow) {
-        imp = deriveShow(t);
-    } else if (c==classRead) {
-        imp = deriveRead(t);
-    } else if (c==classBounded) {
-        imp = deriveBounded(t);
-    } else {
-        ERRMSG(inst(in).line) "Cannot derive instances of class \"%s\"",
-                              textToStr(cclass(inst(in).c).text)
-        EEND;
-    }
-
-    kindInst(in,intOf(inst(in).kinds));
-    insertInst(in);
-    inst(in).builder    = newInstImp(in);
-    inst(in).implements = classBindings("derived instance",
-                                        inst(in).c,
-                                        imp);
-}
-
-
-/* --------------------------------------------------------------------------
- * Default definitions; only one default definition is permitted in a
- * given script file.  If no default is supplied, then a standard system
- * default will be used where necessary.
- * ------------------------------------------------------------------------*/
-
-Void defaultDefn(line,defs)             /* Handle default types definition */
-Int  line;
-List defs; {
-    if (defaultLine!=0) {
-        ERRMSG(line) "Multiple default declarations are not permitted in" ETHEN
-        ERRTEXT     "a single script file.\n"
-        EEND;
-    }
-    defaultDefns = defs;
-    defaultLine  = line;
-}
-
-static Void local checkDefaultDefns() { /* check that default types are    */
-    List ds = NIL;                      /* well-kinded instances of Num    */
-
-    if (defaultLine!=0) {
-        map2Over(depTypeExp,defaultLine,NIL,defaultDefns);
-        emptySubstitution();
-        unkindTypes = NIL;
-        map2Proc(kindType,defaultLine,"default type",defaultDefns);
-        fixKinds();
-        emptySubstitution();
-        mapOver(fullExpand,defaultDefns);
-    } 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)
-                "Default types must be instances of the Num class"
-            EEND;
-        }
-    }
-}
-
-
-/* --------------------------------------------------------------------------
- * Foreign import declarations are Hugs' equivalent of GHC's ccall mechanism.
- * They are used to "import" C functions into a module.
- * They are usually not written by hand but, rather, generated automatically
- * by GreenCard, IDL compilers or whatever.  We support foreign import 
- * (static) and foreign import dynamic.  In the latter case, extName==NIL.
- *
- * Foreign export declarations generate C wrappers for Hugs functions.
- * Hugs only provides "foreign export dynamic" because it's not obvious
- * what "foreign export static" would mean in an interactive setting.
- * ------------------------------------------------------------------------*/
-
-Void foreignImport(line,callconv,extName,intName,type) 
-                                              /* Handle foreign imports    */
-Cell line;
-Text callconv;
-Pair extName;
-Cell intName;
-Cell type; {
-    Text t = textOf(intName);
-    Name n = findName(t);
-
-    if (isNull(n)) {
-        n = newName(t,NIL);
-    } else if (name(n).defn!=PREDEFINED) {
-        ERRMSG(line) "Redeclaration of foreign \"%s\"", textToStr(t)
-        EEND;
-    }
-    name(n).line     = line;
-    name(n).defn     = extName;
-    name(n).type     = type;
-    name(n).callconv = callconv;
-    foreignImports   = cons(n,foreignImports);
-}
-
-static Void local checkForeignImport(p)   /* Check foreign import          */
-Name p; {
-    emptySubstitution();
-    name(p).type = checkSigType(name(p).line,
-                                "foreign import declaration",
-                                p,
-                                name(p).type);
-    /* We don't expand synonyms here because we don't want the IO
-     * part to be expanded.
-     * name(p).type = fullExpand(name(p).type);
-     */
-    implementForeignImport(p);
-}
-
-Void foreignExport(line,callconv,extName,intName,type)
-                                              /* Handle foreign exports    */
-Cell line;
-Text callconv;
-Cell extName;
-Cell intName;
-Cell type; {
-    Text t = textOf(intName);
-    Name n = findName(t);
-
-    if (isNull(n)) {
-        n = newName(t,NIL);
-    } else if (name(n).defn!=PREDEFINED) {
-        ERRMSG(line) "Redeclaration of foreign \"%s\"", textToStr(t)
-        EEND;
-    }
-    name(n).line     = line;
-    name(n).defn     = NIL;  /* nothing to say */
-    name(n).type     = type;
-    name(n).callconv = callconv;
-    foreignExports   = cons(n,foreignExports);
-}
-
-static Void local checkForeignExport(p)       /* Check foreign export      */
-Name p; {
-    emptySubstitution();
-    name(p).type = checkSigType(name(p).line,
-                                "foreign export declaration",
-                                p,
-                                name(p).type);
-    implementForeignExport(p);
-}
-
-
-
-/* --------------------------------------------------------------------------
- * Static analysis of patterns:
- *
- * Patterns are parsed as ordinary (atomic) expressions.  Static analysis
- * makes the following checks:
- *  - Patterns are well formed (according to pattern syntax), including the
- *    special case of (n+k) patterns.
- *  - All constructor functions have been defined and are used with the
- *    correct number of arguments.
- *  - No variable name is used more than once in a pattern.
- *
- * The list of pattern variables occuring in each pattern is accumulated in
- * a global list `patVars', which must be initialised to NIL at appropriate
- * points before using these routines to check for valid patterns.  This
- * mechanism enables the pattern checking routine to be mapped over a list
- * of patterns, ensuring that no variable occurs more than once in the
- * complete pattern list (as is required on the lhs of a function defn).
- * ------------------------------------------------------------------------*/
-
-static List patVars;                   /* List of vars bound in pattern    */
-
-static Cell local checkPat(line,p)     /* Check valid pattern syntax       */
-Int  line;
-Cell p; {
-    switch (whatIs(p)) {
-        case VARIDCELL :
-        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 CONOPCELL : return checkApPat(line,0,p);
-
-        case WILDCARD  :
-        case STRCELL   :
-        case CHARCELL  :
-        case FLOATCELL : break;
-        case INTCELL   : break;
-
-        case ASPAT     : addToPatVars(line,fst(snd(p)));
-                         snd(snd(p)) = checkPat(line,snd(snd(p)));
-                         break;
-
-        case LAZYPAT   : snd(p) = checkPat(line,snd(p));
-                         break;
-
-        case FINLIST   : map1Over(checkPat,line,snd(p));
-                         break;
-
-        case CONFLDS   : depConFlds(line,p,TRUE);
-                         break;
-
-        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"
-                         EEND;
-    }
-    return p;
-}
-
-static Cell local checkMaybeCnkPat(l,p)/* Check applicative pattern with   */
-Int  l;                                /* the possibility of n+k pattern   */
-Cell p; {
-    Cell h = getHead(p);
-
-    if (argCount==2 && isVar(h) && textOf(h)==textPlus) {       /* n+k     */
-        Cell v = arg(fun(p));
-        if (!isInt(arg(p))) {
-            ERRMSG(l) "Second argument in (n+k) pattern must be an integer"
-            EEND;
-        }
-        if (intOf(arg(p))<=0) {
-            ERRMSG(l) "Integer k in (n+k) pattern must be > 0"
-            EEND;
-        }
-        fst(fun(p))      = ADDPAT;
-        intValOf(fun(p)) = intOf(arg(p));
-        arg(p)           = checkPat(l,v);
-        return p;
-    }
-    return checkApPat(l,0,p);
-}
-
-static Cell local checkApPat(line,args,p)
-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));
-                         arg(p) = checkPat(line,arg(p));
-                         break;
-
-        case TUPLE     : if (tupleOf(p)!=args) {
-                             ERRMSG(line) "Illegal tuple pattern"
-                             EEND;
-                         }
-                         break;
-
-#if TREX
-        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 CONIDCELL :
-        case CONOPCELL : p = conDefined(line,p);
-                         checkCfunArgs(line,p,args);
-                         break;
-
-        case NAME      : checkIsCfun(line,p);
-                         checkCfunArgs(line,p,args);
-                         break;
-
-        default        : ERRMSG(line) "Illegal pattern syntax"
-                         EEND;
-    }
-    return 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 {
-         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.                        */
-    Name n = findQualName(nm);
-    if (isNull(n)) {
-        ERRMSG(line) "Undefined constructor function \"%s\"", identToStr(nm)
-        EEND;
-    }
-    checkIsCfun(line,n);
-    return n;
-}
-
-static Void local checkIsCfun(line,c)  /* Check that c is a constructor fn */
-Int  line;
-Name c; {
-    if (!isCfun(c)) {
-        ERRMSG(line) "\"%s\" is not a constructor function",
-                     textToStr(name(c).text)
-        EEND;
-    }
-}
-
-static Void local checkCfunArgs(line,c,args)
-Int  line;                             /* Check constructor applied with   */
-Cell c;                                /* correct number of arguments      */
-Int  args; {
-    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,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 (isPolyOrQualType(t) || 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);
-    leaveBtyvs();
-    if (nonNull(bts)) {
-        pat = ap(BIGLAM,pair(bts,pat));
-        for (; nonNull(bts); bts=tl(bts)) {
-            snd(hd(bts)) = copyKindvar(intOf(snd(hd(bts))));
-        }
-    }
-    return pat;
-}
-
-/* --------------------------------------------------------------------------
- * Maintaining lists of bound variables and local definitions, for
- * 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      */
-
-/* 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  */
-
-static Cell local bindPat(line,p)      /* add new bound vars for pattern   */
-Int  line;
-Cell p; {
-    patVars    = NIL;
-    p          = checkPat(line,p);
-    hd(bounds) = revOnto(patVars,hd(bounds));
-    return p;
-}
-
-static Void local bindPats(line,ps)    /* add new bound vars for patterns  */
-Int  line;
-List ps; {
-    patVars    = NIL;
-    map1Over(checkPat,line,ps);
-    hd(bounds) = revOnto(patVars,hd(bounds));
-}
-
-/* --------------------------------------------------------------------------
- * Before processing value and type signature declarations, all data and
- * type definitions have been processed so that:
- * - all valid type constructors (with their arities) are known.
- * - all valid constructor functions (with their arities and types) are
- *   known.
- *
- * The result of parsing a list of value declarations is a list of Eqns:
- *       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
- * analysis.
- *
- * As the first stage of the static analysis of value declarations, each
- * list of Eqns is converted to a list of Bindings.  As part of this
- * process:
- * - The ordering of the list of Bindings produced is the same as in the
- *   original script.
- * - When a variable (function) is defined over a number of lines, all
- *   of the definitions should appear together and each should give the
- *   same arity to the variable being defined.
- * - No variable can have more than one definition.
- * - For pattern bindings:
- *   - Each lhs is a valid pattern/function lhs, all constructor functions
- *     have been defined and are used with the correct number of arguments.
- *   - Each lhs contains no repeated pattern variables.
- *   - Each equation defines at least one variable (e.g. True = False is
- *     not allowed).
- * - Types appearing in type signatures are well formed:
- *    - Type constructors used are defined and used with correct number
- *      of arguments.
- *    - type variables are replaced by offsets, type constructor names
- *      by Tycons.
- * - 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 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)]           */
-
-    for(; nonNull(es); es=tl(es)) {
-        if (fst(hd(es))==SIGDECL) {                  /* type-declaration?  */
-            Pair sig  = snd(hd(es));
-            Int  line = intOf(fst3(sig));
-            List vs   = snd3(sig);
-            for(; nonNull(vs); vs=tl(vs)) {
-                if (isQualIdent(hd(vs))) {
-                    ERRMSG(line) "Type signature for qualified variable \"%s\" is not allowed",
-                                 identToStr(hd(vs))
-                    EEND;
-                }
-            }
-            sigdecls = cons(sig,sigdecls);           /* discard SIGDECL tag*/
-        }
-    }
-    return sigdecls;
-}
-
-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(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;
-                }
-                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);
-            }
-
-        } 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 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));
-    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                 */
-List bs;
-Cell v; {
-    if (nonNull(findBinding(textOf(v),bs))) {
-        ERRMSG(line) "\"%s\" multiply defined", textToStr(textOf(v))
-        EEND;
-    }
-}
-
-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?*/
-            return hd(bs);
-        }
-    }
-    return NIL;
-}
-
-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)) {                                    /* No binding      */
-        return NIL;
-    } else if (isVar(fst(b))) {                         /* func binding?   */
-        if (isNull(bindingAttr(b))) {
-            bindingAttr(b) = pair(NIL,NIL);
-        }
-        return bindingAttr(b);
-    } else {                                            /* pat binding?    */
-        List vs = fst(b);
-        List as = bindingAttr(b);
-
-        if (isNull(as)) {
-            bindingAttr(b) = as = replicate(length(vs),NIL);
-        }
-
-        while (nonNull(vs) && t!=textOf(hd(vs))) {
-            vs = tl(vs);
-            as = tl(as);
-        }
-
-        if (isNull(vs)) {
-            internal("getAttr");
-        } else if (isNull(hd(as))) {
-            hd(as) = pair(NIL,NIL);
-        }
-        return hd(as);
-    }
-}
-
-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)));
-                            }
-                            else if (isFloat(arg(temp))) {
-                                if (nneg&1)
-                                    arg(temp) = floatNegate(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
- *   a list of pointers to other bindings in the same list of bindings.
- * - to hold strictly positive integer values (depth first search numbers) of
- *   elements `on the stack' during the strongly connected components search
- *   algorithm, or a special value mkInt(0), once the binding has been added
- *   to a particular strongly connected component.
- *
- * Using this extra field, the type of each list of declarations during
- * dependency analysis is [Binding'] where:
- *
- *    Binding' ::= (Var, (Attr, (Dep, [Alt])))         -- function binding
- *              |  ([Var], ([Attr], (Dep, (Pat,Rhs)))) -- pattern binding
- *
- * ------------------------------------------------------------------------*/
-
-#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;
-}
-
-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(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:
- * - Each lhs is a valid pattern/function lhs, all constructor functions
- *   have been defined and are used with the correct number of arguments.
- * - No lhs contains repeated pattern variables.
- * - Expressions used on the rhs of an eqn should be well formed.  This
- *   includes:
- *   - Checking for valid patterns (including repeated vars) in lambda,
- *     case, and list comprehension expressions.
- *   - Recursively checking local lists of equations.
- * - No free (i.e. unbound) variables are used in the declaration list.
- * ------------------------------------------------------------------------*/
-
-static Void local depBinding(b)        /* find dependents of binding       */
-Cell b; {
-    Cell defpart = snd(snd(snd(b)));   /* definition part of binding       */
-
-    hd(depends) = NIL;
-
-    if (isVar(fst(b))) {               /* function-binding?                */
-        mapProc(depAlt,defpart);
-        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?                 */
-        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            */
-    depClassBindings(cclass(c).defaults);
-}
-
-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 depAlt(a)             /* Find dependents of alternative  */
-Cell a; {
-    List obvs = saveBvars();            /* Save list of bound variables    */
-    enterBtyvs();
-    bindPats(rhsLine(snd(a)),fst(a));   /* add new bound vars for patterns */
-    depRhs(snd(a));                     /* find dependents of rhs          */
-    fst(a)    = applyBtyvs(fst(a));
-    restoreBvars(obvs);                 /* restore original list of bvars  */
-}
-
-static Void local depRhs(r)             /* Find dependents of rhs          */
-Cell r; {
-    switch (whatIs(r)) {
-        case GUARDED : mapProc(depGuard,snd(r));
-                       break;
-
-        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));
-                       depRhs(snd(snd(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                       */
-    depPair(intOf(fst(g)),snd(g));
-}
-
-static Cell local depExpr(line,e)      /* find dependents of expression    */
-Int  line;
-Cell e; {
-  //Printf( "\n\n"); print(e,100); Printf("\n");
-  //printExp(stdout,e);
-    switch (whatIs(e)) {
-
-        case VARIDCELL  :
-        case VAROPCELL  : return depVar(line,e);
-
-        case CONIDCELL  :
-        case CONOPCELL  : return conDefined(line,e);
-
-        case QUALIDENT  : if (isQVar(e)) {
-                              return depQVar(line,e);
-                          } else { /* QConOrConOp */
-                              return conDefined(line,e);
-                          }
-
-        case INFIX     : return depExpr(line,tidyInfix(line,snd(e)));
-
-#if TREX
-        case RECSEL     : break;
-
-        case AP         : if (isAp(e) && isAp(fun(e)) && isExt(fun(fun(e)))) {
-                              return depRecord(line,e);
-                          } else {
-                              Cell nx = e;
-                              Cell a;
-                              do {
-                                  a      = nx;
-                                  arg(a) = depExpr(line,arg(a));
-                                  nx     = fun(a);
-                              } while (isAp(nx));
-                              fun(a) = depExpr(line,fun(a));
-                          }
-                          break;
-#else
-        case AP         : depPair(line,e);
-                          break;
-#endif
-
-#if IPARAM
-       case IPVAR      :
-#endif
-
-        case NAME       :
-        case TUPLE      :
-        case STRCELL    :
-        case CHARCELL   :
-        case FLOATCELL  :
-        case BIGCELL    :
-        case INTCELL    : break;
-
-        case COND       : depTriple(line,snd(e));
-                          break;
-
-        case FINLIST    : map1Over(depExpr,line,snd(e));
-                          break;
-
-        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));
-                          snd(snd(e)) = depExpr(line,snd(snd(e)));
-                          leaveScope();
-                          break;
-
-        case LAMBDA     : depAlt(snd(e));
-                          break;
-
-        case DOCOMP     : /* fall-thru */
-        case COMP       : depComp(line,snd(e),snd(snd(e)));
-                          break;
-
-        case ESIGN      : fst(snd(e)) = depExpr(line,fst(snd(e)));
-                          snd(snd(e)) = checkSigType(line,
-                                                     "expression",
-                                                     fst(snd(e)),
-                                                     snd(snd(e)));
-                          break;
-
-        case CASE       : fst(snd(e)) = depExpr(line,fst(snd(e)));
-                          map1Proc(depCaseAlt,line,snd(snd(e)));
-                          break;
-
-        case CONFLDS    : depConFlds(line,e,FALSE);
-                          break;
-
-        case UPDFLDS    : depUpdFlds(line,e);
-                          break;
-
-#if IPARAM
-       case WITHEXP    : depWith(line,e);
-                         break;
-#endif
-
-        case ASPAT      : ERRMSG(line) "Illegal `@' in expression"
-                          EEND;
-
-        case LAZYPAT    : ERRMSG(line) "Illegal `~' in expression"
-                          EEND;
-
-        case WILDCARD   : ERRMSG(line) "Illegal `_' in expression"
-                          EEND;
-
-#if TREX
-        case EXT        : ERRMSG(line) "Illegal application of record"
-                          EEND;
-#endif
-
-        default         : internal("depExpr");
-   }
-   return e;
-}
-
-static Void local depPair(line,e)       /* find dependents of pair of exprs*/
-Int  line;
-Cell e; {
-    fst(e) = depExpr(line,fst(e));
-    snd(e) = depExpr(line,snd(e));
-}
-
-static Void local depTriple(line,e)     /* find dependents of triple exprs */
-Int  line;
-Cell e; {
-    fst3(e) = depExpr(line,fst3(e));
-    snd3(e) = depExpr(line,snd3(e));
-    thd3(e) = depExpr(line,thd3(e));
-}
-
-static Void local depComp(l,e,qs)       /* find dependents of comprehension*/
-Int  l;
-Cell e;
-List qs; {
-    if (isNull(qs)) {
-        fst(e) = depExpr(l,fst(e));
-    } else {
-        Cell q   = hd(qs);
-        List qs1 = tl(qs);
-        switch (whatIs(q)) {
-            case FROMQUAL : {   List obvs   = saveBvars();
-                                snd(snd(q)) = depExpr(l,snd(snd(q)));
-                                enterBtyvs();
-                                fst(snd(q)) = bindPat(l,fst(snd(q)));
-                                depComp(l,e,qs1);
-                                fst(snd(q)) = applyBtyvs(fst(snd(q)));
-                                restoreBvars(obvs);
-                            }
-                            break;
-
-            case QWHERE   : snd(q)      = eqnsToBindings(snd(q),NIL,NIL,NIL);
-                            withinScope(snd(q));
-                            snd(q)      = dependencyAnal(snd(q));
-                            hd(depends) = snd(q);
-                            depComp(l,e,qs1);
-                            leaveScope();
-                            break;
-
-            case DOQUAL   : /* fall-thru */
-            case BOOLQUAL : snd(q) = depExpr(l,snd(q));
-                            depComp(l,e,qs1);
-                            break;
-        }
-    }
-}
-
-static Void local depCaseAlt(line,a)    /* Find dependents of case altern. */
-Int  line;
-Cell a; {
-    List obvs = saveBvars();            /* Save list of bound variables    */
-    enterBtyvs();
-    fst(a)    = bindPat(line,fst(a));   /* Add new bound vars for pats     */
-    depRhs(snd(a));                     /* Find dependents of rhs          */
-    fst(a)    = applyBtyvs(fst(a));
-    restoreBvars(obvs);                 /* Restore original list of bvars  */
-}
-
-static Cell local depVar(line,e)        /* Register occurrence of variable */
-Int line;
-Cell e; {
-    List bounds1   = bounds;
-    List bindings1 = bindings;
-    List depends1  = depends;
-    Text t         = textOf(e);
-    Cell n;
-
-    while (nonNull(bindings1)) {
-        n = varIsMember(t,hd(bounds1));   /* look for t in bound variables */
-        if (nonNull(n)) {
-            return n;
-        }
-        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));
-            }
-           return (isVar(fst(n)) ? fst(n) : e);
-        }
-
-        bounds1   = tl(bounds1);
-        bindings1 = tl(bindings1);
-        depends1  = tl(depends1);
-    }
-
-    if (isNull(n=findName(t))) {               /* check global definitions */
-        ERRMSG(line) "Undefined variable \"%s\"", textToStr(t)
-        EEND;
-    }
-
-    /* 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 e;
-}
-
-static Cell local depQVar(line,e)/* register occurrence of qualified variable */
-Int line;
-Cell e; {
-    Name n = findQualName(e);
-    if (isNull(n)) {                            /* check global definitions */
-        ERRMSG(line) "Undefined qualified variable \"%s\"", identToStr(e)
-        EEND;
-    }
-    if (name(n).mod != currentModule) {
-        return n;
-    }
-    if (fst(e) == VARIDCELL) {
-        e = mkVar(qtextOf(e));
-    } else {
-        e = mkVarop(qtextOf(e));
-    }
-    return depVar(line,e);
-}
-
-static Void local depConFlds(line,e,isP)/* check construction using fields */
-Int  line;
-Cell e;
-Bool isP; {
-    Name c = conDefined(line,fst(snd(e)));
-    if (isNull(snd(snd(e))) ||
-        nonNull(cellIsMember(c,depFields(line,e,snd(snd(e)),isP)))) {
-        fst(snd(e)) = c;
-    } else {
-        ERRMSG(line) "Constructor \"%s\" does not have selected fields in ",
-                     textToStr(name(c).text)
-        ETHEN ERREXPR(e);
-        ERRTEXT "\n"
-        EEND;
-    }
-    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   = userArity(c);
-        List fs  = snd(snd(e));
-        List ss;
-        if (isPolyType(t)) {            /* Find tycon that c belongs to    */
-            t = monotypeOf(t);
-        }
-       if (isQualType(t)) {
-            t = snd(snd(t));
-        }
-        if (whatIs(t)==CDICTS) {
-            t = snd(snd(t));
-        }
-        while (0<a--) {
-            t = arg(t);
-        }
-        while (isAp(t)) {
-            t = fun(t);
-        }
-        for (ss=tycon(t).defn; hasCfun(ss); ss=tl(ss)) {
-        }
-        /* Now we know the tycon t that c belongs to, and the corresponding
-         * list of selectors for that type, ss.  Now we have to check that
-         * each of the fields identified by scs appears in fs, using ss to
-         * cross reference, and convert integers to selector names.
-         */
-        for (; nonNull(scs); scs=tl(scs)) {
-            Int  i   = intOf(hd(scs));
-            List ss1 = ss;
-            for (; nonNull(ss1); ss1=tl(ss1)) {
-                List cns = name(hd(ss1)).defn;
-                for (; nonNull(cns); cns=tl(cns)) {
-                    if (fst(hd(cns))==c) {
-                        break;
-                    }
-                }
-                if (nonNull(cns) && intOf(snd(hd(cns)))==i) {
-                    break;
-                }
-            }
-            if (isNull(ss1)) {
-                internal("depConFlds");
-            } else {
-                Name s   = hd(ss1);
-                List fs1 = fs;
-                for (; nonNull(fs1) && s!=fst(hd(fs1)); fs1=tl(fs1)) {
-                }
-                if (isNull(fs1)) {
-                    ERRMSG(line) "Construction does not define strict field"
-                    ETHEN
-                    ERRTEXT      "\nExpression : " ETHEN ERREXPR(e);
-                    ERRTEXT      "\nField      : " ETHEN ERREXPR(s);
-                    ERRTEXT      "\n"
-                    EEND;
-                }
-            }
-        }
-    }
-}
-
-static Void local depUpdFlds(line,e)    /* check update using fields       */
-Int  line;
-Cell e; {
-    if (isNull(thd3(snd(e)))) {
-        ERRMSG(line) "Empty field list in update"
-        EEND;
-    }
-    fst3(snd(e)) = depExpr(line,fst3(snd(e)));
-    snd3(snd(e)) = depFields(line,e,thd3(snd(e)),FALSE);
-}
-
-static List local depFields(l,e,fs,isP) /* check field binding list        */
-Int  l;
-Cell e;
-List fs;
-Bool isP; {
-    List cs = NIL;
-    List ss = NIL;
-
-    for (; nonNull(fs); fs=tl(fs)) {    /* for each field binding          */
-        Cell fb = hd(fs);
-        Name s;
-
-        if (isVar(fb)) {                /* expand  var  to  var = var      */
-            h98DoesntSupport(l,"missing field bindings");
-            fb = hd(fs) = pair(fb,fb);
-        }
-
-        s = findQualName(fst(fb));      /* check for selector              */
-        if (nonNull(s) && isSfun(s)) {
-            fst(fb) = s;
-        } else {
-            ERRMSG(l) "\"%s\" is not a selector function/field name",
-                      textToStr(textOf(fst(fb)))
-            EEND;
-        }
-
-        if (isNull(ss)) {               /* for first named selector        */
-            List scs = name(s).defn;    /* calculate list of constructors  */
-            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     */
-            for (cs=NIL; nonNull(ds); ) {
-                List scs = name(s).defn;
-                while (nonNull(scs) && fst(hd(scs))!=hd(ds)) {
-                    scs = tl(scs);
-                }
-                if (isNull(scs)) {
-                    ds = tl(ds);
-                } else {
-                    List next = tl(ds);
-                    tl(ds)    = cs;
-                    cs        = ds;
-                    ds        = next;
-                }
-            }
-
-            if (cellIsMember(s,ss)) {   /* check for repeated uses         */
-                ERRMSG(l) "Repeated field name \"%s\" in field list",
-                          textToStr(name(s).text)
-                EEND;
-            }
-            ss = cons(s,ss);
-        }
-
-        if (isNull(cs)) {               /* Are there any matching constrs? */
-            ERRMSG(l) "No constructor has all of the fields specified in "
-            ETHEN ERREXPR(e);
-            ERRTEXT "\n"
-            EEND;
-        }
-
-        snd(fb) = (isP ? checkPat(l,snd(fb)) : depExpr(l,snd(fb)));
-    }
-    return cs;
-}
-
-#if IPARAM
-static Void local depWith(line,e)      /* check with using fields         */
-Int  line;
-Cell e; {
-    fst(snd(e)) = depExpr(line,fst(snd(e)));
-    snd(snd(e)) = depDwFlds(line,e,snd(snd(e)));
-}
-
-static List local depDwFlds(l,e,fs)/* check field binding list    */
-Int  l;
-Cell e;
-List fs;
-{
-    Cell c = fs;
-    for (; nonNull(c); c=tl(c)) {      /* for each field binding          */
-       snd(hd(c)) = depExpr(l,snd(hd(c)));
-    }
-    return fs;
-}
-#endif
-
-#if TREX
-static Cell local depRecord(line,e)     /* find dependents of record and   */
-Int  line;                              /* sort fields into approp. order  */
-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);
-        List   prev = NIL;
-        List   nx   = exts;
-        while (nonNull(nx) && strcmp(textToStr(extText(fun(fun(nx)))),s)>0) {
-            prev = nx;
-            nx   = extRow(nx);
-        }
-        if (nonNull(nx) && t==extText(fun(fun(nx)))) {
-            ERRMSG(line) "Repeated label \"%s\" in record ", s
-            ETHEN ERREXPR(e);
-            ERRTEXT "\n"
-            EEND;
-        }
-        if (isNull(prev)) {
-            exts = cons(fun(r),exts);
-        } else {
-            tl(prev) = cons(fun(r),nx);
-        }
-        extField(r) = depExpr(line,extField(r));
-        r           = extRow(r);
-    } while (isAp(r) && isAp(fun(r)) && isExt(fun(fun(r))));
-    r = depExpr(line,r);
-    return revOnto(exts,r);
-}
-#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
- * connected components in which each value appears before its dependents.
- *
- * Each of these algorithms is obtained by parameterising a standard
- * algorithm in "scc.c" as shown below.
- * ------------------------------------------------------------------------*/
-
-#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
-#include "scc.c"
-#undef   SETDEPENDS
-#undef   DEPENDS
-#undef   LOWLINK
-#undef   SCC2
-
-#define  SCC             bscc           /* make scc algorithm for Bindings */
-#define  LOWLINK         blowlink
-#define  DEPENDS(t)      depVal(t)
-#define  SETDEPENDS(c,v) depVal(c)=v
-#include "scc.c"
-#undef   SETDEPENDS
-#undef   DEPENDS
-#undef   LOWLINK
-#undef   SCC
-
-/* --------------------------------------------------------------------------
- * Main static analysis:
- * ------------------------------------------------------------------------*/
-
-Void checkExp() {                       /* Top level static check on Expr  */
-    staticAnalysis(RESET);
-    clearScope();                       /* Analyse expression in the scope */
-    withinScope(NIL);                   /* of no local bindings            */
-    inputExpr = depExpr(0,inputExpr);
-    leaveScope();
-    staticAnalysis(RESET);
-}
-
-#if EXPLAIN_INSTANCE_RESOLUTION
-Void checkContext(void) {              /* Top level static check on Expr  */
-    List vs, qs;
-
-    staticAnalysis(RESET);
-    clearScope();                      /* Analyse expression in the scope */
-    withinScope(NIL);                  /* of no local bindings            */
-    qs = inputContext;
-    for (vs = NIL; nonNull(qs); qs=tl(qs)) {
-       vs = typeVarsIn(hd(qs),NIL,NIL,vs);
-    }
-    map2Proc(depPredExp,0,vs,inputContext);
-    leaveScope();
-    staticAnalysis(RESET);
-}
-#endif
-
-Void checkDefns ( Module thisModule ) { /* Top level static analysis       */
-    Text modName = module(thisModule).text;
-
-    staticAnalysis(RESET);
-
-    setCurrModule(thisModule);
-
-    /* Resolve module references */
-    mapProc(checkQualImport,  module(thisModule).qualImports);
-    mapProc(checkUnqualImport,unqualImports);
-    /* Add "import Prelude" if there`s no explicit import */
-    if (modName == textPrelPrim || modName == textPrelude) {
-      /* Nothing. */
-    } else if (isNull(cellAssoc(modulePrelude,unqualImports))
-              && isNull(cellRevAssoc(modulePrelude,module(thisModule).qualImports))) {
-      unqualImports = cons(pair(modulePrelude,DOTDOT),unqualImports);
-    } else {
-      /* Every module implicitly contains "import qualified Prelude" 
-       */
-      module(thisModule).qualImports
-       =cons(pair(mkCon(textPrelude),modulePrelude),
-             module(thisModule).qualImports);
-    }
-    mapProc(checkImportList, unqualImports);
-
-    /* Note: there's a lot of side-effecting going on here, so
-       don't monkey about with the order of operations here unless
-       you know what you are doing */
-    if (!combined) linkPreludeTC();     /* Get prelude tycons and classes  */
-
-    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(visitClass,classDefns);    /* check class hierarchy           */
-    mapProc(extendFundeps,classDefns);  /* finish class definitions       */
-                                       /* (convenient if we do this after */
-                                       /* calling `visitClass' so that we */
-                                       /* know the class hierarchy is     */
-                                       /* acyclic)                        */
-
-    mapProc(addMembers,classDefns);     /* add definitions for member funs */
-
-    if (!combined) linkPreludeCM();     /* Get prelude cfuns and mfuns     */
-    
-    instDefns = rev(instDefns);         /* process instance definitions    */
-    mapProc(checkInstDefn,instDefns);
-
-    setCurrModule(thisModule);
-    mapProc(addRSsigdecls,typeInDefns);        /* add sigdecls for RESTRICTSYN    */
-    valDefns   = eqnsToBindings(valDefns,tyconDefns,classDefns,/*primDefns*/NIL);
-    mapProc(allNoPrevDef,valDefns);    /* check against previous defns    */
-    mapProc(addDerivImp,derivedInsts);  /* Add impls for derived instances */
-    deriveContexts(derivedInsts);       /* Calculate derived inst contexts */
-    instDefns  = appendOnto(instDefns,derivedInsts);
-    checkDefaultDefns();                /* validate default definitions    */
-
-    mapProc(allNoPrevDef,valDefns);     /* check against previous defns    */
-
-    if (!combined) linkPrimNames();     /* link primitive names           */
-
-    mapProc(checkForeignImport,foreignImports); /* check foreign imports   */
-    mapProc(checkForeignExport,foreignExports); /* check foreign exports   */
-    foreignImports = NIL;
-    foreignExports = NIL;
-
-    /* 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.                                         */
-    module(thisModule).exports 
-       = checkExports ( module(thisModule).exports, thisModule );
-
-    mapProc(checkTypeIn,typeInDefns);   /* check restricted synonym defns  */
-
-    clearScope();
-    withinScope(valDefns);
-    valDefns = topDependAnal(valDefns); /* top level dependency ordering   */
-    mapProc(depDefaults,classDefns);    /* dep. analysis on class defaults */
-    mapProc(depInsts,instDefns);        /* dep. analysis on inst defns     */
-    leaveScope();
-
-    /* ToDo: evalDefaults should match current evaluation module */
-    evalDefaults = defaultDefns;        /* Set defaults for evaluator      */
-
-    staticAnalysis(RESET);
-}
-
-
-
-
-static Void local addRSsigdecls(pr)     /* add sigdecls from TYPE ... IN ..*/
-Pair pr; {
-    List vs = snd(pr);                  /* get list of variables           */
-    for (; nonNull(vs); vs=tl(vs)) {
-        if (fst(hd(vs))==SIGDECL) {     /* find a sigdecl                  */
-            valDefns = cons(hd(vs),valDefns);   /* add to valDefns         */
-            hd(vs)   = hd(snd3(snd(hd(vs))));   /* and replace with var    */
-        }
-    }
-}
-
-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 {
-        Int line = rhsLine(snd(snd(snd(b))));
-        map1Proc(noPrevDef,line,fst(b));
-    }
-}
-
-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),NIL);
-        name(n).defn = PREDEFINED;
-    } else if (name(n).defn!=PREDEFINED) {
-        duplicateError(line,name(n).mod,name(n).text,"variable");
-    }
-    name(n).line = line;
-}
-
-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)
-        EEND;
-    } else {
-        ERRMSG(line) "Definition of %s \"%s\" clashes with import", kind,
-                     textToStr(t)
-        EEND;
-    }
-}
-
-static Void local checkTypeIn(cvs)      /* Check that vars in restricted   */
-Pair cvs; {                             /* synonym are defined             */
-    Tycon c  = fst(cvs);
-    List  vs = snd(cvs);
-
-    for (; nonNull(vs); vs=tl(vs)) {
-        if (isNull(findName(textOf(hd(vs))))) {
-            ERRMSG(tycon(c).line)
-                "No top level binding of \"%s\" for restricted synonym \"%s\"",
-                textToStr(textOf(hd(vs))), textToStr(tycon(c).text)
-            EEND;
-        }
-    }
-}
-
-/* --------------------------------------------------------------------------
- * 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 (isQualType(t)) {
-            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   : cfunSfuns    = NIL;
-                       daSccs       = NIL;
-                       patVars      = NIL;
-                       bounds       = NIL;
-                       bindings     = NIL;
-                       depends      = NIL;
-                       tcDeps       = NIL;
-                       derivedInsts = NIL;
-                       diVars       = NIL;
-                       diNum        = 0;
-                       unkindTypes  = NIL;
-                       break;
-
-        case MARK    : mark(daSccs);
-                       mark(patVars);
-                       mark(bounds);
-                       mark(bindings);
-                       mark(depends);
-                       mark(tcDeps);
-                       mark(derivedInsts);
-                       mark(diVars);
-                       mark(cfunSfuns);
-                       mark(unkindTypes);
-#if TREX
-                       mark(extKind);
-#endif
-                       break;
-
-        case POSTPREL: break;
-
-        case PREPREL : staticAnalysis(RESET);
-#if TREX
-                       extKind = pair(STAR,pair(ROW,ROW));
-#endif
-    }
-}
-
-/*-------------------------------------------------------------------------*/