[project @ 1999-06-07 17:22:31 by sewardj]
authorsewardj <unknown>
Mon, 7 Jun 1999 17:22:54 +0000 (17:22 +0000)
committersewardj <unknown>
Mon, 7 Jun 1999 17:22:54 +0000 (17:22 +0000)
Many changes needed to support loading of GHC compiled code.  The main
changes are to parser.y and interface.c to load .hi files and create
appropriate symbol table entries.  Also, interface.c has the
beginnings of and ELF loader/linker in it.

15 files changed:
ghc/interpreter/Makefile
ghc/interpreter/codegen.c
ghc/interpreter/compiler.c
ghc/interpreter/connect.h
ghc/interpreter/dynamic.c
ghc/interpreter/hugs.c
ghc/interpreter/input.c
ghc/interpreter/interface.c [new file with mode: 0644]
ghc/interpreter/link.h
ghc/interpreter/machdep.c
ghc/interpreter/parser.y
ghc/interpreter/static.c
ghc/interpreter/storage.c
ghc/interpreter/storage.h
ghc/interpreter/type.c

index 45b574b..0a410a9 100644 (file)
@@ -1,6 +1,6 @@
 
 # ----------------------------------------------------------------------------- #
-# $Id: Makefile,v 1.8 1999/04/27 10:59:29 sewardj Exp $                         #
+# $Id: Makefile,v 1.9 1999/06/07 17:22:54 sewardj Exp $                         #
 # ----------------------------------------------------------------------------- #
 
 TOP = ../..
@@ -17,6 +17,7 @@ YACC = bison -y
 %.c: %.y
        -$(YACC) $<
        mv y.tab.c $@
+       rm -f input.o
 
 
 HS_SRCS =
@@ -24,9 +25,9 @@ HS_SRCS =
 Y_SRCS = parser.y
 C_SRCS = link.c type.c static.c storage.c derive.c input.c compiler.c subst.c \
      translate.c codegen.c lift.c free.c stgSubst.c optimise.c output.c   \
-     hugs.c dynamic.c stg.c sainteger.c
+     hugs.c dynamic.c stg.c sainteger.c interface.c
 
-SRC_CC_OPTS = -O2 -g -I$(GHC_DIR)/interpreter -I$(GHC_DIR)/includes -I$(GHC_DIR)/rts -D__HUGS__ -DCOMPILING_RTS -Wall -Wstrict-prototypes -Wno-unused
+SRC_CC_OPTS = -g -I$(GHC_DIR)/interpreter -I$(GHC_DIR)/includes -I$(GHC_DIR)/rts -D__HUGS__ -DCOMPILING_RTS -Wall -Wstrict-prototypes -Wno-unused
 
 GHC_LIBS_NEEDED = $(TOP)/ghc/rts/libHSrts.a
 
@@ -49,7 +50,7 @@ cleanish:
 
 snapshot:
        /bin/rm -f snapshot.tar
-       tar cvf snapshot.tar Makefile *.[chy] *-ORIG-* \
+       tar cvf snapshot.tar Makefile *.[chy] \
              ../rts/Assembler.c ../rts/Evaluator.c ../rts/Disassembler.c \
              ../rts/ForeignCall.c ../rts/Printer.c ../rts/QueueTemplate.h \
              ../includes/options.h ../includes/Assembler.h nHandle.c \
index ca9b482..32d1ebf 100644 (file)
@@ -7,8 +7,8 @@
  * Hugs version 1.4, December 1997
  *
  * $RCSfile: codegen.c,v $
- * $Revision: 1.6 $
- * $Date: 1999/04/27 10:06:48 $
+ * $Revision: 1.7 $
+ * $Date: 1999/06/07 17:22:53 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
@@ -106,15 +106,21 @@ static void cgBind( AsmBCO bco, StgVar v )
 
 static Void pushVar( AsmBCO bco, StgVar v )
 {
-    Cell info = stgVarInfo(v);
+    Cell info;
     assert(isStgVar(v));
-    if (isPtr(info)) {
-        asmClosure(bco,ptrOf(info));
-    } else if (isInt(info)) {
-        asmVar(bco,intOf(info),repOf(v));
+
+    if (isCPtr(v)) {
+fprintf ( stderr, "push cptr %p\n", (void*)cptrOf(v) );
     } else {
-        internal("pushVar");
-    }        
+       info = stgVarInfo(v);
+       if (isPtr(info)) {
+           asmClosure(bco,ptrOf(info));
+       } else if (isInt(info)) {
+           asmVar(bco,intOf(info),repOf(v));
+       } else {
+           internal("pushVar");
+       }        
+    }
 }
 
 static Void pushAtom( AsmBCO bco, StgAtom e )
@@ -154,6 +160,9 @@ static Void pushAtom( AsmBCO bco, StgAtom e )
             asmClosure(bco,asmStringObj(textToStr(textOf(e))));
 #endif
             break;
+    case CPTRCELL:
+            asmConstWord(bco,cptrOf(e));
+            break;
     case PTRCELL: 
             asmConstAddr(bco,ptrOf(e));
             break;
@@ -483,9 +492,13 @@ static Void build( AsmBCO bco, StgVar v )
             if (isName(fun)) {
                 fun = name(fun).stgVar;
             }
-            if (nonNull(stgVarBody(fun))
-                && whatIs(stgVarBody(fun)) == LAMBDA 
-                && length(stgLambdaArgs(stgVarBody(fun))) > length(args)) {
+            if (isCPtr(fun) 
+                ||
+                (nonNull(stgVarBody(fun))
+                 && whatIs(stgVarBody(fun)) == LAMBDA 
+                 && length(stgLambdaArgs(stgVarBody(fun))) > length(args)
+                )
+               ) {
                 AsmSp  start = asmBeginMkPAP(bco);
                 map1Proc(pushAtom,bco,reverse(args));
                 pushAtom(bco,fun);
index 112ae6d..97e3eef 100644 (file)
@@ -10,8 +10,8 @@
  * in the distribution for details.
  *
  * $RCSfile: compiler.c,v $
- * $Revision: 1.6 $
- * $Date: 1999/04/27 10:06:48 $
+ * $Revision: 1.7 $
+ * $Date: 1999/06/07 17:22:46 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
@@ -181,7 +181,7 @@ Cell e; {
                                              nv));
                           }
 
-        default         : internal("translate");
+        default         : fprintf(stderr, "stuff=%d\n",whatIs(e));internal("translate");
     }
     return e;
 }
index 3c444bd..41dc004 100644 (file)
@@ -7,8 +7,8 @@
  * in the distribution for details.
  *
  * $RCSfile: connect.h,v $
- * $Revision: 1.6 $
- * $Date: 1999/04/27 10:06:50 $
+ * $Revision: 1.7 $
+ * $Date: 1999/06/07 17:22:45 $
  * ------------------------------------------------------------------------*/
 
 /* --------------------------------------------------------------------------
@@ -497,4 +497,35 @@ extern List offsetTyvarsIn          Args((Type,List));
 extern Void optimiseTopBinds  Args((List));
 extern List cfunSfuns;                  /* List of (Cfun,[SelectorVar])    */
 
+extern Void  interface        Args((Int));
+
+extern List typeVarsIn        Args((Cell,List,List));
+
+extern Void getFileSize       Args((String, Long *));
+
+extern Void loadInterface     Args((String,Long));
+
+extern Void openGHCIface      Args((Text));
+extern Void loadSharedLib     Args((String));
+extern Void addGHCImports     Args((Int,Text,List));
+extern Void addGHCExports     Args((Cell,List));
+extern Void addGHCVar         Args((Int,Text,Type));
+extern Void addGHCSynonym     Args((Int,Cell,List,Type));
+extern Void addGHCDataDecl    Args((Int,List,Cell,List,List));
+extern Void addGHCNewType     Args((Int,List,Cell,List,Cell));
+extern Void addGHCClass       Args((Int,List,Cell,List,List));
+extern Void addGHCInstance    Args((Int,List,Pair,Text));
+extern Void finishInterfaces  Args((Void));
+
+extern Void hi_o_namesFromSrcName Args((String,String*,String* oName));
+extern Void parseInterface        Args((String,Long));
+
+
 #define SMALL_INLINE_SIZE 9
+
+
+// nasty hack, but seems an easy to convey the object name
+// and size to openGHCIface
+char nameObj[FILENAME_MAX+1];
+int  sizeObj;
+
index 57653d5..3fb2a61 100644 (file)
@@ -7,8 +7,8 @@
  * Hugs version 1.4, December 1997
  *
  * $RCSfile: dynamic.c,v $
- * $Revision: 1.4 $
- * $Date: 1999/03/01 14:46:45 $
+ * $Revision: 1.5 $
+ * $Date: 1999/06/07 17:22:31 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
@@ -21,7 +21,6 @@
 #include <stdio.h>
 #include <dlfcn.h>
 
-#if 0 /* apparently unused */
 ObjectFile loadLibrary(fn)
 String fn; {
     return dlopen(fn,RTLD_NOW | RTLD_GLOBAL);
@@ -32,7 +31,6 @@ ObjectFile file;
 String symbol; {
     return dlsym(file,symbol);
 }
-#endif
 
 void* getDLLSymbol(dll,symbol)  /* load dll and lookup symbol */
 String dll;
index b9268d6..2f426c5 100644 (file)
@@ -8,8 +8,8 @@
  * in the distribution for details.
  *
  * $RCSfile: hugs.c,v $
- * $Revision: 1.6 $
- * $Date: 1999/04/27 10:06:52 $
+ * $Revision: 1.7 $
+ * $Date: 1999/06/07 17:22:43 $
  * ------------------------------------------------------------------------*/
 
 #include <setjmp.h>
@@ -77,13 +77,13 @@ static Int    local argToInt          Args((String));
 
 static Void   local loadProject       Args((String));
 static Void   local clearProject      Args((Void));
-static Void   local addScriptName     Args((String,Bool));
-static Bool   local addScript         Args((String,Long));
+static Bool   local addScript         Args((Int));
 static Void   local forgetScriptsFrom Args((Script));
 static Void   local setLastEdit       Args((String,Int));
 static Void   local failed            Args((Void));
 static String local strCopy           Args((String));
 
+
 /* --------------------------------------------------------------------------
  * Machine dependent code for Hugs interpreter:
  * ------------------------------------------------------------------------*/
@@ -101,20 +101,39 @@ static Bool   printing     = FALSE;     /* TRUE => currently printing value*/
 static Bool   showStats    = FALSE;     /* TRUE => print stats after eval  */
 static Bool   listScripts  = TRUE;      /* TRUE => list scripts after loading*/
 static Bool   addType      = FALSE;     /* TRUE => print type with value   */
-static Bool   chaseImports = TRUE;      /* TRUE => chase imports on load   */
 static Bool   useDots      = RISCOS;    /* TRUE => use dots in progress    */
 static Bool   quiet        = FALSE;     /* TRUE => don't show progress     */
        Bool   preludeLoaded = FALSE;
-       Bool   optimise      = TRUE;
+       Bool   optimise      = FALSE;
+
+typedef 
+   struct { 
+      String modName;                   /* Module name                     */
+      Bool   details;             /* FALSE => remaining fields are invalid */
+      String path;                      /* Path to module                  */
+      String srcExt;                    /* ".hs" or ".lhs" if fromSource   */
+      Time   lastChange;                /* Time of last change to script   */
+      Bool   fromSource;                /* FALSE => load object code       */
+      Bool   postponed;                 /* Indicates postponed load        */
+      Bool   objLoaded;
+      Long   size;
+      Long   oSize;
+   }
+   ScriptInfo;
+
+static Void   local makeStackEntry    Args((ScriptInfo*,String));
+static Void   local addStackEntry     Args((String));
+
+static ScriptInfo scriptInfo[NUM_SCRIPTS];
 
-static String scriptName[NUM_SCRIPTS];  /* Script file names               */
-static Time   lastChange[NUM_SCRIPTS];  /* Time of last change to script   */
-static Bool   postponed[NUM_SCRIPTS];   /* Indicates postponed load        */
 static Int    numScripts;               /* Number of scripts loaded        */
+static Int    nextNumScripts;
 static Int    namesUpto;                /* Number of script names set      */
 static Bool   needsImports;             /* set to TRUE if imports required */
        String scriptFile;               /* Name of current script (if any) */
 
+
+
 static Text   evalModule  = 0;          /* Name of module we eval exprs in */
 static String currProject = 0;          /* Name of current project file    */
 static Bool   projectLoaded = FALSE;    /* TRUE => project file loaded     */
@@ -131,6 +150,41 @@ static Int    hpSize     = DEFAULTHEAP; /* Desired heap size               */
 static Bool disableOutput = FALSE;      /* redirect output to buffer?      */
 #endif
 
+String bool2str ( Bool b )
+{
+   if (b) return "Yes"; else return "No ";
+}
+
+void ppSmStack ( String who )
+{
+   int i, j;
+   fflush(stdout);fflush(stderr);
+   printf ( "\n" );
+   printf ( "ppSmStack %s:  numScripts = %d   namesUpto = %d  needsImports = %s\n",
+            who, numScripts, namesUpto, bool2str(needsImports) );
+   assert (namesUpto >= numScripts);
+   printf ( "     Det FrS Pst ObL           Module Ext   Size ModTime  Path\n" );
+   for (i = namesUpto-1; i >= 0; i--) {
+      printf ( "%c%2d: %3s %3s %3s %3s %16s %-4s %5ld %8lx %s\n",
+               (i==numScripts ? '*' : ' '),
+               i, bool2str(scriptInfo[i].details), 
+                  bool2str(scriptInfo[i].fromSource),
+                  bool2str(scriptInfo[i].postponed), 
+                  bool2str(scriptInfo[i].objLoaded),
+                  scriptInfo[i].modName, 
+                  scriptInfo[i].fromSource ? scriptInfo[i].srcExt : "",
+                  scriptInfo[i].size, 
+                  scriptInfo[i].lastChange,
+                  scriptInfo[i].path
+             );
+   }
+   //   printf ( "\n" );
+   fflush(stdout);fflush(stderr);
+ppScripts();
+ppModules();
+   printf ( "\n" );
+}
+
 /* --------------------------------------------------------------------------
  * Hugs entry point:
  * ------------------------------------------------------------------------*/
@@ -228,6 +282,9 @@ String argv[]; {
    startupHaskell (argc,argv);
    argc = prog_argc; argv = prog_argv;
 
+    namesUpto = numScripts = 0;
+    addStackEntry("Prelude");
+
    for (i=1; i<argc; ++i) {            /* process command line arguments  */
         if (strcmp(argv[i], "--")==0) break;
         if (strcmp(argv[i],"+")==0 && i+1<argc) {
@@ -239,7 +296,7 @@ String argv[]; {
             }
         } else if (argv[i] && argv[i][0]/* workaround for /bin/sh silliness*/
                  && !processOption(argv[i])) {
-            addScriptName(argv[i],TRUE);
+            addStackEntry(argv[i]);
         }
     }
 
@@ -247,12 +304,15 @@ String argv[]; {
     DEBUG_LoadSymbols(argv_0_orig);
 #endif
 
-    scriptName[0] = strCopy(findMPathname(NULL,STD_PRELUDE,hugsPath));
+
+
+#if 0
     if (!scriptName[0]) {
         Printf("Prelude not found on current path: \"%s\"\n",
                hugsPath ? hugsPath : "");
         fatal("Unable to load prelude");
     }
+#endif
 
     if (haskell98) {
         Printf("Haskell 98 mode: Restart with command line option -98 to enable extensions\n\n");
@@ -655,7 +715,6 @@ struct options toggle[] = {             /* List of command line toggles    */
     {'w', "Always show which modules are loaded",  &listScripts},
     {'k', "Show kind errors in full",              &kindExpert},
     {'o', "Allow overlapping instances",           &allowOverlap},
-    {'i', "Chase imports while loading modules",   &chaseImports},
     {'O', "Optimise (improve?) generated code",    &optimise},
 #if DEBUG_CODE
     {'D', "Debug: show generated code",            &debugCode},
@@ -705,7 +764,7 @@ String s; {
     scriptFile = currProject;
     forgetScriptsFrom(1);
     while ((s=readFilename())!=0)
-        addScriptName(s,TRUE);
+        addStackEntry(s);
     if (namesUpto<=1) {
         ERRMSG(0) "Empty project file"
         EEND;
@@ -724,107 +783,216 @@ static Void local clearProject() {      /* clear name for current project  */
 #endif
 }
 
-static Void local addScriptName(s,sch)  /* Add script to list of scripts   */
-String s;                               /* to be read in ...               */
-Bool   sch; {                           /* TRUE => requires pathname search*/
+
+
+static Void local makeStackEntry ( ScriptInfo* ent, String iname )
+{
+   Bool   ok, fromObj;
+   Bool   sAvail, iAvail, oAvail;
+   Time   sTime,  iTime,  oTime;
+   Long   sSize,  iSize,  oSize;
+   String path,   sExt;
+
+   ok = findFilesForModule (
+           iname,
+           &path,
+           &sExt,
+           &sAvail, &sTime, &sSize,
+           &iAvail, &iTime, &iSize,
+           &oAvail, &oTime, &oSize
+        );
+   if (!ok) {
+      ERRMSG(0) 
+         "Can't file source or object+interface for module \"%s\"",
+         iname
+      EEND;
+   }
+   /* findFilesForModule should enforce this */
+   if (!(sAvail || (oAvail && iAvail))) 
+      internal("chase");
+   /* Load objects in preference to sources if both are available */
+   fromObj = sAvail
+                ? (oAvail && iAvail && timeEarlier(sTime,oTime))
+                : TRUE;
+   /* ToDo: namesUpto overflow */
+   ent->modName     = strCopy(iname);
+   ent->details     = TRUE;
+   ent->path        = path;
+   ent->fromSource  = !fromObj;
+   ent->srcExt      = sExt;
+   ent->postponed   = FALSE;
+   ent->lastChange  = sTime; /* ToDo: is this right? */
+   ent->size        = fromObj ? iSize : sSize;
+   ent->oSize       = fromObj ? oSize : 0;
+   ent->objLoaded   = FALSE;
+}
+
+
+
+static Void nukeEnding( String s )
+{
+    Int l = strlen(s);
+    if (l > 2 && strncmp(s+l-2,".o"  ,3)==0) s[l-2] = 0; else
+    if (l > 3 && strncmp(s+l-3,".hi" ,3)==0) s[l-3] = 0; else
+    if (l > 3 && strncmp(s+l-3,".hs" ,3)==0) s[l-3] = 0; else
+    if (l > 4 && strncmp(s+l-4,".lhs",4)==0) s[l-4] = 0; else
+    if (l > 4 && strncmp(s+l-4,".dll",4)==0) s[l-4] = 0; else
+    if (l > 4 && strncmp(s+l-4,".DLL",4)==0) s[l-4] = 0;
+}
+
+static Void local addStackEntry(s)     /* Add script to list of scripts    */
+String s; {                            /* to be read in ...                */
+    String s2;
+    Bool   found;
+    Int    i;
+
     if (namesUpto>=NUM_SCRIPTS) {
         ERRMSG(0) "Too many module files (maximum of %d allowed)",
                   NUM_SCRIPTS
         EEND;
     }
-    else
-        scriptName[namesUpto++] = strCopy(sch ? findPathname(NULL,s) : s);
+
+    s = strCopy(s);
+    nukeEnding(s);
+    for (s2 = s; *s2; s2++)
+       if (*s2 == SLASH && *(s2+1)) s = s2+1;
+
+    found = FALSE;
+    for (i = 0; i < namesUpto; i++)
+       if (strcmp(scriptInfo[i].modName,s)==0)
+          found = TRUE;
+
+    if (!found) {
+       makeStackEntry ( &scriptInfo[namesUpto], strCopy(s) );
+       namesUpto++;
+    }
+    free(s);
 }
 
-static Bool local addScript(fname,len)  /* read single script file         */
-String fname;                           /* name of script file             */
-Long   len; {                           /* length of script file           */
-    scriptFile = fname;
+/* Return TRUE if no imports were needed; FALSE otherwise. */
+static Bool local addScript(stacknum)   /* read single file                */
+Int stacknum; {
+   static char name[FILENAME_MAX+1];
+   Int len = scriptInfo[stacknum].size;
 
 #if HUGS_FOR_WINDOWS                    /* Set clock cursor while loading  */
     allowBreak();
     SetCursor(LoadCursor(NULL, IDC_WAIT));
 #endif
 
-    Printf("Reading file \"%s\":\n",fname);
-    setLastEdit(fname,0);
-
-#if 0
-ToDo: reinstate
-    if (isInterfaceFile(fname)) {
-        loadInterface(fname);
-    } else
-#else
-           {
-        needsImports = FALSE;
-        parseScript(fname,len);         /* process script file             */
-        if (needsImports)
-            return FALSE;
-        checkDefns();
-        typeCheckDefns();
-        compileDefns();
-    }
-#endif
-    scriptFile = 0;
-    preludeLoaded = TRUE;
-    return TRUE;
+    //   setLastEdit(name,0);
+
+   nameObj[0] = 0;
+   strcpy(name, scriptInfo[stacknum].path);
+   strcat(name, scriptInfo[stacknum].modName);
+   if (scriptInfo[stacknum].fromSource)
+      strcat(name, scriptInfo[stacknum].srcExt); else
+      strcat(name, ".hi");
+
+   scriptFile = name;
+
+   if (scriptInfo[stacknum].fromSource) {
+      Printf("Reading script \"%s\":\n",name);
+      needsImports = FALSE;
+      parseScript(name,len);
+      if (needsImports) return FALSE;
+      checkDefns();
+      typeCheckDefns();
+      compileDefns();
+   } else {
+      Printf("Reading  iface \"%s\":\n", name);
+      scriptFile = name;
+      needsImports = FALSE;
+
+      // set nameObj for the benefit of openGHCIface
+      strcpy(nameObj, scriptInfo[stacknum].path);
+      strcat(nameObj, scriptInfo[stacknum].modName);
+      strcat(nameObj, DLL_ENDING);
+      sizeObj = scriptInfo[stacknum].oSize;
+
+      loadInterface(name,len);
+      scriptFile = 0;
+      if (needsImports) return FALSE;
+   }
+   scriptFile = 0;
+   preludeLoaded = TRUE;
+   return TRUE;
 }
 
+
 Bool chase(imps)                        /* Process list of import requests */
 List imps; {
-    if (chaseImports) {
-        Int    origPos  = numScripts;   /* keep track of original position */
-        String origName = scriptName[origPos];
-        for (; nonNull(imps); imps=tl(imps)) {
-            String iname = findPathname(origName,textToStr(textOf(hd(imps))));
-            Int    i     = 0;
-            for (; i<namesUpto; i++)
-                if (pathCmp(scriptName[i],iname)==0)
-                    break;
-            if (i>=origPos) {           /* Neither loaded or queued        */
-                String theName;
-                Time   theTime;
-                Bool   thePost;
-
-                postponed[origPos] = TRUE;
-                needsImports       = TRUE;
-
-                if (i>=namesUpto)       /* Name not found (i==namesUpto)   */
-                    addScriptName(iname,FALSE);
-                else if (postponed[i]) {/* Check for recursive dependency  */
-                    ERRMSG(0)
-                      "Recursive import dependency between \"%s\" and \"%s\"",
-                      scriptName[origPos], iname
-                    EEND;
-                }
-                /* Right rotate section of tables between numScripts and i so
-                 * that i ends up with other imports in front of orig. script
-                 */
-                theName = scriptName[i];
-                thePost = postponed[i];
-                timeSet(theTime,lastChange[i]);
-                for (; i>numScripts; i--) {
-                    scriptName[i] = scriptName[i-1];
-                    postponed[i]  = postponed[i-1];
-                    timeSet(lastChange[i],lastChange[i-1]);
-                }
-                scriptName[numScripts] = theName;
-                postponed[numScripts]  = thePost;
-                timeSet(lastChange[numScripts],theTime);
-                origPos++;
+    Int    dstPosn;
+    ScriptInfo tmp;
+    Int    origPos  = numScripts;       /* keep track of original position */
+    String origName = scriptInfo[origPos].modName;
+    for (; nonNull(imps); imps=tl(imps)) {
+        String iname = textToStr(textOf(hd(imps)));
+        Int    i     = 0;
+        for (; i<namesUpto; i++)
+            if (strcmp(scriptInfo[i].modName,iname)==0)
+                break;
+       //fprintf(stderr, "import name = %s   num = %d\n", iname, i );
+
+        if (i<namesUpto) {
+           /* We should have filled in the details of each module
+              the first time we hear about it.
+          */
+           assert(scriptInfo[i].details);
+        }
+
+        if (i>=origPos) {               /* Neither loaded or queued        */
+            String theName;
+            Time   theTime;
+            Bool   thePost;
+            Bool   theFS;
+
+            needsImports = TRUE;
+            if (scriptInfo[origPos].fromSource)
+               scriptInfo[origPos].postponed  = TRUE;
+
+            if (i==namesUpto) {         /* Name not found (i==namesUpto)   */
+                 /* Find out where it lives, whether source or object, etc */
+               makeStackEntry ( &scriptInfo[i], iname );
+               namesUpto++;
+            }
+            else 
+            if (scriptInfo[i].postponed && scriptInfo[i].fromSource) {
+                                        /* Check for recursive dependency  */
+                ERRMSG(0)
+                  "Recursive import dependency between \"%s\" and \"%s\"",
+                  scriptInfo[origPos].modName, iname
+                EEND;
             }
+            /* Move stack entry i to somewhere below origPos.  If i denotes 
+             * an object, destination is immediately below origPos.  
+             * Otherwise, it's underneath the queue of objects below origPos.
+             */
+            dstPosn = origPos-1;
+            if (scriptInfo[i].fromSource)
+               while (!scriptInfo[dstPosn].fromSource && dstPosn > 0)
+                  dstPosn--;
+
+            dstPosn++;
+            tmp = scriptInfo[i];
+            for (; i > dstPosn; i--) scriptInfo[i] = scriptInfo[i-1];
+            scriptInfo[dstPosn] = tmp;
+            if (dstPosn < nextNumScripts) nextNumScripts = dstPosn;
+            origPos++;
         }
-        return needsImports;
     }
-    return FALSE;
+    return needsImports;
 }
 
 static Void local forgetScriptsFrom(scno)/* remove scripts from system     */
 Script scno; {
     Script i;
+#if 0
     for (i=scno; i<namesUpto; ++i)
         if (scriptName[i])
             free(scriptName[i]);
+#endif
     dropScriptsFrom(scno-1);
     namesUpto = scno;
     if (numScripts>namesUpto)
@@ -839,7 +1007,7 @@ static Void local load() {           /* read filenames from command line   */
     String s;                        /* and add to list of scripts waiting */
                                      /* to be read                         */
     while ((s=readFilename())!=0)
-        addScriptName(s,TRUE);
+        addStackEntry(s);
     readScripts(1);
 }
 
@@ -868,12 +1036,16 @@ static Void local readScripts(n)        /* Reread current list of scripts, */
 Int n; {                                /* loading everything after and    */
     Time timeStamp;                     /* including the first script which*/
     Long fileSize;                      /* has been either changed or added*/
+    static char name[FILENAME_MAX+1];
 
+    ppSmStack("readscripts-begin");
 #if HUGS_FOR_WINDOWS
     SetCursor(LoadCursor(NULL, IDC_WAIT));
 #endif
 
+#if 0
     for (; n<numScripts; n++) {         /* Scan previously loaded scripts  */
+        ppSmStack("readscripts-loop1");
         getFileInfo(scriptName[n], &timeStamp, &fileSize);
         if (timeChanged(timeStamp,lastChange[n])) {
             dropScriptsFrom(n-1);
@@ -883,8 +1055,10 @@ Int n; {                                /* loading everything after and    */
     }
     for (; n<NUM_SCRIPTS; n++)          /* No scripts have been postponed  */
         postponed[n] = FALSE;           /* at this stage                   */
+    numScripts = 0;
 
     while (numScripts<namesUpto) {      /* Process any remaining scripts   */
+        ppSmStack("readscripts-loop2");
         getFileInfo(scriptName[numScripts], &timeStamp, &fileSize);
         timeSet(lastChange[numScripts],timeStamp);
         if (numScripts>0)               /* no new script for prelude       */
@@ -894,11 +1068,85 @@ Int n; {                                /* loading everything after and    */
         else
             dropScriptsFrom(numScripts-1);
     }
+#endif
+
+    interface(RESET);
+
+    for (; n<numScripts; n++) {
+        ppSmStack("readscripts-loop2");
+        strcpy(name, scriptInfo[n].path);
+        strcat(name, scriptInfo[n].modName);
+        if (scriptInfo[n].fromSource)
+           strcat(name, scriptInfo[n].srcExt); else
+           strcat(name, ".hi");  //ToDo: should be .o
+        getFileInfo(name,&timeStamp, &fileSize);
+        if (timeChanged(timeStamp,scriptInfo[n].lastChange)) {
+           dropScriptsFrom(n-1);
+           numScripts = n;
+           break;
+        }
+    }
+    for (; n<NUM_SCRIPTS; n++)
+        scriptInfo[n].postponed = FALSE;
+
+    //numScripts = 0;
+
+    while (numScripts < namesUpto) {
+ppSmStack ( "readscripts-loop2" );
+
+       if (scriptInfo[numScripts].fromSource) {
+
+          if (numScripts>0)
+              startNewScript(scriptInfo[numScripts].modName);
+          nextNumScripts = NUM_SCRIPTS; //bogus initialisation
+          if (addScript(numScripts)) {
+             numScripts++;
+assert(nextNumScripts==NUM_SCRIPTS);
+          }
+          else
+             dropScriptsFrom(numScripts-1);
+       } else {
+      
+          if (scriptInfo[numScripts].objLoaded) {
+             numScripts++;
+          } else {
+             scriptInfo[numScripts].objLoaded = TRUE;
+             /* new */
+             if (numScripts>0)
+                 startNewScript(scriptInfo[numScripts].modName);
+            /* end */
+             nextNumScripts = NUM_SCRIPTS;
+             if (addScript(numScripts)) {
+                numScripts++;
+assert(nextNumScripts==NUM_SCRIPTS);
+             } else {
+               //while (!scriptInfo[numScripts].fromSource && numScripts > 0)
+               //   numScripts--;
+               //if (scriptInfo[numScripts].fromSource)
+               //   numScripts++;
+                numScripts = nextNumScripts;
+assert(nextNumScripts<NUM_SCRIPTS);
+             }
+          }
+       }
+if (numScripts==namesUpto) ppSmStack( "readscripts-final") ;
+    }
+
+    finishInterfaces();
+
+    { Int  m     = namesUpto-1;
+      Text mtext = findText(scriptInfo[m].modName);
+      setCurrModule(mtext);
+      evalModule = mtext;
+    }
+
+    
 
     if (listScripts)
         whatScripts();
     if (numScripts<=1)
         setLastEdit((String)0, 0);
+    ppSmStack("readscripts-end  ");
 }
 
 static Void local whatScripts() {       /* list scripts in current session */
@@ -907,7 +1155,7 @@ static Void local whatScripts() {       /* list scripts in current session */
     if (projectLoaded)
         Printf(" (project: %s)",currProject);
     for (i=0; i<numScripts; ++i)
-        Printf("\n%s",scriptName[i]);
+        Printf("\n%s",scriptInfo[i].modName);
     Putchar('\n');
 }
 
@@ -928,6 +1176,9 @@ static Void local editor() {            /* interpreter-editor interface    */
 }
 
 static Void local find() {              /* edit file containing definition */
+#if 0
+This just plain wont work no more.
+ToDo: Fix!
     String nm = readFilename();         /* of specified name               */
     if (!nm) {
         ERRMSG(0) "No name specified"
@@ -955,6 +1206,7 @@ static Void local find() {              /* edit file containing definition */
             EEND;
         }
     }
+#endif
 }
 
 static Void local runEditor() {         /* run editor on script lastEdit   */
@@ -1158,7 +1410,7 @@ Cell   c; {
 
 extern Name nameHw;
 
-static Void local dumpStg() {           /* print STG stuff                 */
+static Void local dumpStg( void ) {       /* print STG stuff                 */
     String s;
     Text   t;
     Name   n;
@@ -1201,8 +1453,9 @@ static Void local dumpStg() {           /* print STG stuff                 */
         if (isNull(name(n).stgVar)) {
            Printf ( "Doesn't have a STG tree: %s\n", s );
         } else {
-           printf ( "\n{- stgVar of `%s' is id%d -}\n", s, -name(n).stgVar);
-           Printf ( "{- stgSize of body is %d -}\n\n", stgSize(stgVarBody(name(n).stgVar)));
+           Printf ( "\n{- stgVar of `%s' is id%d -}\n", s, -name(n).stgVar);
+           Printf ( "{- stgSize of body is %d -}\n\n", 
+                    stgSize(stgVarBody(name(n).stgVar)));
            printStg(stderr, name(n).stgVar);
         }
     }
@@ -1222,12 +1475,13 @@ static Void local info() {              /* describe objects                */
     }
 }
 
+
 static Void local describe(t)           /* describe an object              */
 Text t; {
     Tycon  tc  = findTycon(t);
     Class  cl  = findClass(t);
     Name   nm  = findName(t);
-    //Module mod = findEvalModule();
+    Module mod = findModule(t);
 
     if (nonNull(tc)) {                  /* as a type constructor           */
         Type t = tc;
@@ -1361,16 +1615,35 @@ Text t; {
         } else if (isSfun(nm)) {
             Printf("  -- selector function");
         }
-#if 0
-    ToDo: reinstate
-        if (name(nm).primDef) {
-            Printf("   -- primitive");
+        Printf("\n\n");
+    }
+
+    if (nonNull(mod)) {                 /* as a module                     */
+        List t;
+        Printf("-- module\n");
+
+        Printf("\n-- values\n");
+        for (t=module(mod).names; nonNull(t); t=tl(t)) {
+           Name nm = hd(t);
+           Printf ( "%s ", textToStr(name(nm).text));
         }
-#endif
+
+        Printf("\n\n-- type constructors\n");
+        for (t=module(mod).tycons; nonNull(t); t=tl(t)) {
+           Tycon tc = hd(t);
+           Printf ( "%s ", textToStr(tycon(tc).text));
+        }
+
+        Printf("\n\n-- classes\n");
+        for (t=module(mod).classes; nonNull(t); t=tl(t)) {
+           Class cl = hd(t);
+           Printf ( "%s ", textToStr(cclass(cl).text));
+        }
+
         Printf("\n\n");
     }
 
-    if (isNull(tc) && isNull(cl) && isNull(nm)) {
+    if (isNull(tc) && isNull(cl) && isNull(nm) && isNull(mod)) {
         Printf("Unknown reference `%s'\n",textToStr(t));
     }
 }
index cc11551..afae01f 100644 (file)
@@ -8,8 +8,8 @@
  * in the distribution for details.
  *
  * $RCSfile: input.c,v $
- * $Revision: 1.5 $
- * $Date: 1999/04/27 10:06:53 $
+ * $Revision: 1.6 $
+ * $Date: 1999/06/07 17:22:32 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
@@ -18,6 +18,7 @@
 #include "connect.h"
 #include "command.h"
 #include "errors.h"
+#include "link.h"
 #include <ctype.h>
 #if HAVE_GETDELIM_H
 #include "getdelim.h"
@@ -48,6 +49,7 @@ List evalDefaults    = NIL;             /* defaults for evaluator          */
 Cell inputExpr       = NIL;             /* input expression                */
 Bool literateScripts = FALSE;           /* TRUE => default to lit scripts  */
 Bool literateErrors  = TRUE;            /* TRUE => report errs in lit scrs */
+Bool offsideON       = TRUE;            /* TRUE => implement offside rule  */
 
 String repeatStr     = 0;               /* Repeat last expr                */
 
@@ -120,9 +122,9 @@ static Text textBar,     textMinus,    textFrom,   textArrow,  textLazy;
 static Text textBang,    textDot,      textAll,    textImplies;
 static Text textWildcard;
 
-static Text textModule,  textImport;
+static Text textModule,  textImport,    textInterface,  textInstImport;
 static Text textHiding,  textQualified, textAsMod;
-static Text textExport,  textUnsafe;
+static Text textExport,  textUnsafe,    text__All;
 
 Text   textNum;                         /* Num                             */
 Text   textPrelude;                     /* Prelude                         */
@@ -249,7 +251,8 @@ static String nextStringChar;          /* next char in string buffer       */
 #if     USE_READLINE                   /* for command line editors         */
 static  String currentLine;            /* editline or GNU readline         */
 static  String nextChar;
-#define nextConsoleChar() (unsigned char)(*nextChar=='\0' ? '\n' : *nextChar++)
+#define nextConsoleChar() \
+           (unsigned char)(*nextChar=='\0' ? '\n' : *nextChar++)
 extern  Void add_history  Args((String));
 extern  String readline   Args((String));
 #else
@@ -398,6 +401,35 @@ String nm; {
 }
 
 
+Void hi_o_namesFromSrcName ( String srcName, String* hiName, String* oName )
+{
+   Int len;
+   String dot;
+   len = 1 + strlen ( srcName );
+   *hiName = malloc(len);
+   *oName  = malloc(len);
+   if (!(*hiName && *oName)) internal("hi_o_namesFromSource");
+   (*hiName)[0] = (*oName)[0] = 0;
+   dot = strrchr(srcName, '.');
+   if (!dot) return;
+   if (filenamecmp(dot+1, "hs")==0 &&
+       filenamecmp(dot+1, "lhs")==0 &&
+       filenamecmp(dot+1, "verb")==0) return;
+
+   strcpy(*hiName, srcName);
+   dot = strrchr(*hiName, '.');
+   dot[1] = 'h';
+   dot[2] = 'i';
+   dot[3] = 0;
+
+   strcpy(*oName, srcName);
+   dot = strrchr(*oName, '.');
+   dot[1] = 'o';
+   dot[2] = 0;
+}
+
+
+
 /* This code originally came from Sigbjorn Finne (sof@dcs.gla.ac.uk).
  * I've removed the loop (since newLineSkip contains a loop too) and
  * replaced the warnings with errors. ADR
@@ -449,7 +481,8 @@ static Int local nextLine()
     if (lineLength <= 0) { /* EOF / IO error, who knows.. */
         return lineLength;
     }
-    else if (lineLength >= 2 && lineBuffer[0] == '#' && lineBuffer[1] == '!') {
+    else if (lineLength >= 2 && lineBuffer[0] == '#' && 
+             lineBuffer[1] == '!') {
         lineBuffer[0]='\n'; /* pretend it's a blank line */
         lineBuffer[1]='\0';
         lineLength=1;
@@ -1215,6 +1248,7 @@ static  Int        indentDepth = (-1); /* current indentation nesting      */
 
 static Void local goOffside(col)       /* insert offside marker            */
 Int col; {                             /* for specified column             */
+assert(offsideON);
     if (indentDepth>=MAXINDENT) {
         ERRMSG(row) "Too many levels of program nesting"
         EEND;
@@ -1223,10 +1257,12 @@ Int col; {                             /* for specified column             */
 }
 
 static Void local unOffside() {        /* leave layout rule area           */
+assert(offsideON);
     indentDepth--;
 }
 
 static Bool local canUnOffside() {     /* Decide if unoffside permitted    */
+assert(offsideON);
     return indentDepth>=0 && layout[indentDepth]!=HARD;
 }
 
@@ -1298,7 +1334,7 @@ static Int local yylex() {             /* Read next input token ...        */
         return firstTokenIs;
     }
 
-    if (insertOpen) {                  /* insert `soft' opening brace      */
+    if (offsideON && insertOpen) {     /* insert `soft' opening brace      */
         insertOpen    = FALSE;
         insertedToken = TRUE;
         goOffside(column);
@@ -1319,7 +1355,7 @@ static Int local yylex() {             /* Read next input token ...        */
         if (insertedToken)             /* avoid inserting multiple `;'s    */
             insertedToken = FALSE;     /* or putting `;' after `{'         */
         else
-        if (layout[indentDepth]!=HARD) {
+        if (offsideON && layout[indentDepth]!=HARD) {
             if (column<layout[indentDepth]) {
                 unOffside();
                 return '}';
@@ -1346,16 +1382,17 @@ static Int local yylex() {             /* Read next input token ...        */
         case '['  : skip(); return '['; 
         case ']'  : skip(); return ']';
         case '`'  : skip(); return '`';
-        case '{'  : goOffside(HARD);
+        case '{'  : if (offsideON) goOffside(HARD);
                     skip();
                     return '{';
-        case '}'  : if (indentDepth<0) {
+        case '}'  : if (offsideON && indentDepth<0) {
                         ERRMSG(row) "Misplaced `}'"
                         EEND;
                     }
-                    if (layout[indentDepth]==HARD)      /* skip over hard }*/
-                        skip();
-                    unOffside();        /* otherwise, we have to insert a }*/
+                    if (!(offsideON && layout[indentDepth]!=HARD))
+                        skip();                         /* skip over hard }*/
+                    if (offsideON) 
+                        unOffside();    /* otherwise, we have to insert a }*/
                     return '}';         /* to (try to) avoid an error...   */
 
         /* Character and string literals                                   */
@@ -1429,6 +1466,8 @@ static Int local yylex() {             /* Read next input token ...        */
         if (it==textClass)             return TCLASS;
         if (it==textInstance)          return TINSTANCE;
         if (it==textModule)            return TMODULE;
+        if (it==textInterface)         return INTERFACE;
+        if (it==textInstImport)        return INSTIMPORT;
         if (it==textImport)            return IMPORT;
         if (it==textExport)            return EXPORT;
         if (it==textHiding)            return HIDING;
@@ -1436,6 +1475,7 @@ static Int local yylex() {             /* Read next input token ...        */
         if (it==textAsMod)             return ASMOD;
         if (it==textWildcard)          return '_';
         if (it==textAll && !haskell98) return ALL;
+        if (it==text__All)             return ALL;
         if (it==textRepeat && reading==KEYBOARD)
             return repeatLast();
 
@@ -1472,7 +1512,8 @@ static Int local yylex() {             /* Read next input token ...        */
         return NUMLIT;
     }
 
-    ERRMSG(row) "Unrecognised character `\\%d' in column %d", ((int)c0), column
+    ERRMSG(row) "Unrecognised character `\\%d' in column %d", 
+                ((int)c0), column
     EEND;
     return 0; /*NOTREACHED*/
 }
@@ -1506,6 +1547,9 @@ static Void local parseInput(startWith)/* Parse input with given first tok,*/
 Int startWith; {                       /* determining whether to read a    */
     firstToken   = TRUE;               /* script or an expression          */
     firstTokenIs = startWith;
+    if (startWith==INTERFACE) 
+       offsideON = FALSE; else 
+       offsideON = TRUE;
 
     clearStack();
     if (yyparse()) {                   /* This can only be parser overflow */
@@ -1570,6 +1614,15 @@ Void parseExp() {                      /* Read an expression to evaluate   */
     setLastExpr(inputExpr);
 }
 
+Void parseInterface(nm,len)            /* Read a GHC interface file        */
+String nm;
+Long   len; {                          /* Used to set a target for reading */
+    input(RESET);
+    fileInput(nm,len);
+    parseInput(INTERFACE);
+}
+
+
 /* --------------------------------------------------------------------------
  * Input control:
  * ------------------------------------------------------------------------*/
@@ -1616,12 +1669,16 @@ Int what; {
                        textPrelude    = findText("Prelude");
                        textNum        = findText("Num");
                        textModule     = findText("module");
+                       textInterface  = findText("__interface");
+                       textInstImport = findText("__instimport");
+                       textExport     = findText("__export");
                        textImport     = findText("import");
                        textHiding     = findText("hiding");
                        textQualified  = findText("qualified");
                        textAsMod      = findText("as");
                        textWildcard   = findText("_");
                        textAll        = findText("forall");
+                       text__All      = findText("__forall");
                        varMinus       = mkVar(textMinus);
                        varPlus        = mkVar(textPlus);
                        varBang        = mkVar(textBang);
diff --git a/ghc/interpreter/interface.c b/ghc/interpreter/interface.c
new file mode 100644 (file)
index 0000000..b754bc5
--- /dev/null
@@ -0,0 +1,1652 @@
+
+/* --------------------------------------------------------------------------
+ * GHC interface file processing for Hugs
+ *
+ * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
+ * All rights reserved. See NOTICE for details and conditions of use etc...
+ * Hugs version 1.4, December 1997
+ *
+ * $RCSfile: interface.c,v $
+ * $Revision: 1.4 $
+ * $Date: 1999/06/07 17:22:51 $
+ * ------------------------------------------------------------------------*/
+
+/* ToDo:
+ * o use Z encoding
+ * o use vectored CONSTR_entry when appropriate
+ * o generate export list
+ *
+ * Needs GHC changes to generate member selectors,
+ * superclass selectors, etc
+ * o instance decls
+ * o dictionary constructors ?
+ *
+ * o Get Hugs/GHC to agree on what interface files look like.
+ * o figure out how to replace the Hugs Prelude with the GHC Prelude
+ */
+
+#include "prelude.h"
+#include "storage.h"
+#include "backend.h"
+#include "connect.h"
+#include "errors.h"
+#include "link.h"
+#include "Assembler.h" /* for wrapping GHC objects */
+#include "dynamic.h"
+
+#define DEBUG_IFACE
+
+/* --------------------------------------------------------------------------
+ * The "addGHC*" functions act as "impedence matchers" between GHC
+ * interface files and Hugs.  Their main job is to convert abstract
+ * syntax trees into Hugs' internal representations.
+ *
+ * The main trick here is how we deal with mutually recursive interface 
+ * files:
+ *
+ * o As we read an import decl, we add it to a list of required imports
+ *   (unless it's already loaded, of course).
+ *
+ * o Processing of declarations is split into two phases:
+ *
+ *   1) While reading the interface files, we construct all the Names,
+ *      Tycons, etc declared in the interface file but we don't try to
+ *      resolve references to any entities the declaration mentions.
+ *
+ *      This is done by the "addGHC*" functions.
+ *
+ *   2) After reading all the interface files, we finish processing the
+ *      declarations by resolving any references in the declarations
+ *      and doing any other processing that may be required.
+ *
+ *      This is done by the "finishGHC*" functions which use the 
+ *      "fixup*" functions to assist them.
+ *
+ *   The interface between these two phases are the "ghc*Decls" which
+ *   contain lists of decls that haven't been completed yet.
+ *
+ * ------------------------------------------------------------------------*/
+
+/* --------------------------------------------------------------------------
+ * local variables:
+ * ------------------------------------------------------------------------*/
+
+static List ghcVarDecls;     
+static List ghcConstrDecls;     
+static List ghcSynonymDecls; 
+static List ghcClassDecls; 
+static List ghcInstanceDecls;
+
+/* --------------------------------------------------------------------------
+ * local function prototypes:
+ * ------------------------------------------------------------------------*/
+
+static List local addGHCConstrs Args((Int,List,List));
+static Name local addGHCSel     Args((Int,Pair));
+static Name local addGHCConstr  Args((Int,Int,Triple));
+
+
+static Void  local finishGHCVar      Args((Name));     
+static Void  local finishGHCConstr   Args((Name));     
+static Void  local finishGHCSynonym  Args((Tycon)); 
+static Void  local finishGHCClass    Args((Class)); 
+static Void  local finishGHCInstance Args((Inst));
+static Void  local finishGHCImports  Args((Triple));
+static Void  local finishGHCExports  Args((Pair));
+static Void  local finishGHCModule   Args((Module));
+
+static Void  local bindGHCNameTo         Args((Name,Text));
+static Kinds local tvsToKind             Args((List));
+static Int   local arityFromType         Args((Type));
+                                         
+static List       local ifTyvarsIn       Args((Type));
+
+static Type       local tvsToOffsets       Args((Int,Type,List));
+static Type       local conidcellsToTycons Args((Int,Type));
+
+static Void       local resolveReferencesInObjectModule Args((Module));
+static Bool       local validateOImage Args((void*, Int));
+
+static Text text_info;
+static Text text_entry;
+static Text text_closure;
+static Text text_static_closure;
+static Text text_static_info;
+static Text text_con_info;
+static Text text_con_entry;
+
+
+/* --------------------------------------------------------------------------
+ * code:
+ * ------------------------------------------------------------------------*/
+
+List ifImports;   /* [ConId] -- modules imported by current interface */
+
+List ghcImports;  /* [(Module, Text, [ConId|VarId])]
+                     each (m1, m2, names) in this list
+                     represents 'module m1 where ... import m2 ( names ) ...'
+                     The list acts as a list of names to fix up in
+                        finishInterfaces().
+                 */
+
+List ghcExports;  /* [(ConId, [ConId|VarId])] */
+
+List ghcModules;  /* [Module] -- modules of the .his loaded in this group */
+
+Void addGHCExports(mod,stuff)
+Cell mod;
+List stuff; {
+   ghcExports = cons( pair(mod,stuff), ghcExports );
+}
+
+static Void local finishGHCExports(paire)
+Pair paire; {
+   Text modTxt = textOf(fst(paire));
+   List ids    = snd(paire);
+   Module mod  = findModule(modTxt);
+   if (isNull(mod)) {
+      ERRMSG(0) "Can't find module \"%s\" mentioned in export list",
+                textToStr(modTxt)
+      EEND;
+   }
+   
+   for (; nonNull(ids); ids=tl(ids)) {
+      Cell xs;
+      Cell id = hd(ids);  /* ConId|VarId */
+      Bool found = FALSE;
+      for (xs = module(mod).exports; nonNull(xs); xs=tl(xs)) {
+         Cell x = hd(xs);
+         if (isQCon(x)) continue;  /* ToDo: fix this right */
+         if (textOf(x)==textOf(id)) { found = TRUE; break; }
+      }
+      if (!found) {
+printf ( "adding %s to exports of %s\n",
+          identToStr(id), textToStr(modTxt) );
+       module(mod).exports = cons ( id, module(mod).exports );
+      }
+   }
+}
+
+
+static Void local finishGHCImports(triple)
+Triple triple;
+{
+   Module dstMod = fst3(triple);  // the importing module
+   Text   srcTxt = snd3(triple);
+   List   names  = thd3(triple);
+   Module srcMod = findModule ( srcTxt );
+   Module tmpCurrentModule = currentModule;
+   List   exps;
+   Bool   found;
+   Text   tnm;
+   Cell   nm;
+   Cell   x;
+   //fprintf(stderr, "finishGHCImports: dst=%s   src=%s\n", 
+   //                textToStr(module(dstMod).text),
+   //                textToStr(srcTxt) );
+   //print(names, 100);
+   //printf("\n");
+   /* for each nm in names
+      nm should be in module(src).exports -- if not, error
+      if nm notElem module(dst).names cons it on
+   */
+
+   if (isNull(srcMod)) {
+      /* I don't think this can actually ever happen, but still ... */
+      ERRMSG(0) "Interface for module \"%s\" imports unknown module \"%s\"",
+                textToStr(module(dstMod).text),
+                textToStr(srcTxt)
+      EEND;
+   }
+   //printf ( "exports of %s are\n", textToStr(module(srcMod).text) );
+   //print( module(srcMod).exports, 100 );
+   //printf( "\n" );
+
+   setCurrModule ( srcMod ); // so that later lookups succeed
+
+   for (; nonNull(names); names=tl(names)) {
+      nm = hd(names);
+      /* Check the exporting module really exports it. */
+      found = FALSE;
+      for (exps=module(srcMod).exports; nonNull(exps); exps=tl(exps)) {
+         Cell c = hd(exps);
+         //if (isPair(c)) c=fst(c);
+         assert(whatIs(c)==CONIDCELL || whatIs(c)==VARIDCELL);
+         assert(whatIs(nm)==CONIDCELL || whatIs(nm)==VARIDCELL);
+        //printf( "   compare `%s' `%s'\n", textToStr(textOf(c)), textToStr(textOf(nm)));
+         if (textOf(c)==textOf(nm)) { found=TRUE; break; }
+      }
+      if (!found) {
+         ERRMSG(0) "Interface for module \"%s\" imports \"%s\" from\n"
+                   "module \"%s\", but the latter doesn't export it",
+                   textToStr(module(dstMod).text), textToStr(textOf(nm)),
+                   textToStr(module(srcMod).text)
+         EEND;
+      }
+      /* Ok, it's exported.  Now figure out what it is we're really
+         importing. 
+      */
+      tnm = textOf(nm);
+
+      x = findName(tnm);
+      if (nonNull(x)) {
+         if (!cellIsMember(x,module(dstMod).names))
+            module(dstMod).names = cons(x, module(dstMod).names);
+         continue;
+      }
+
+      x = findTycon(tnm);
+      if (nonNull(x)) {
+         if (!cellIsMember(x,module(dstMod).tycons))
+            module(dstMod).tycons = cons(x, module(dstMod).tycons);
+         continue;
+      }
+
+      x = findClass(tnm);
+      if (nonNull(x)) {
+         if (!cellIsMember(x,module(dstMod).classes))
+            module(dstMod).classes = cons(x, module(dstMod).classes);
+         continue;
+      }
+
+      fprintf(stderr, "\npanic: Can't figure out what this is in finishGHCImports\n"
+                      "\t%s\n", textToStr(tnm) );
+      internal("finishGHCImports");
+   }
+
+   setCurrModule(tmpCurrentModule);
+}
+
+
+Void loadInterface(String fname, Long fileSize)
+{
+    ifImports = NIL;
+    parseInterface(fname,fileSize);
+    if (nonNull(ifImports))
+       chase(ifImports);
+}
+
+
+Void finishInterfaces ( void )
+{
+    /* the order of these doesn't matter
+     * (ToDo: unless synonyms have to be eliminated??)
+     */
+    mapProc(finishGHCVar,      ghcVarDecls);     
+    mapProc(finishGHCConstr,   ghcConstrDecls);     
+    mapProc(finishGHCSynonym,  ghcSynonymDecls); 
+    mapProc(finishGHCClass,    ghcClassDecls); 
+    mapProc(finishGHCInstance, ghcInstanceDecls);
+    mapProc(finishGHCExports,  ghcExports);
+    mapProc(finishGHCImports,  ghcImports);
+    mapProc(finishGHCModule,   ghcModules);
+    ghcVarDecls      = NIL;
+    ghcConstrDecls   = NIL;
+    ghcSynonymDecls  = NIL;
+    ghcClassDecls    = NIL;
+    ghcInstanceDecls = NIL;
+    ghcImports       = NIL;
+    ghcExports       = NIL;
+    ghcModules       = NIL;
+}
+
+
+static Void local finishGHCModule(mod)
+Module mod; {
+   // do the implicit 'import Prelude' thing
+   List pxs = module(modulePrelude).exports;
+   for (; nonNull(pxs); pxs=tl(pxs)) {
+      Cell px = hd(pxs);
+      again:
+      switch (whatIs(px)) {
+         case AP: 
+            px = fst(px); 
+            goto again;
+         case NAME: 
+            module(mod).names = cons ( px, module(mod).names );
+            break;
+         case TYCON: 
+            module(mod).tycons = cons ( px, module(mod).tycons );
+            break;
+         case CLASS: 
+            module(mod).classes = cons ( px, module(mod).classes );
+            break;
+         default:
+            fprintf(stderr, "finishGHCModule: unknown tag %d\n", whatIs(px));
+            break;
+      }
+   }
+
+   // Last, but by no means least ...
+   resolveReferencesInObjectModule ( mod );
+}
+
+Void openGHCIface(t)
+Text t; {
+    FILE* f;
+    void* img;
+    Module m = findModule(t);
+    if (isNull(m)) {
+        m = newModule(t);
+printf ( "new module %s\n", textToStr(t) );
+    } else if (m != modulePrelude) {
+        ERRMSG(0) "Module \"%s\" already loaded", textToStr(t)
+        EEND;
+    }
+
+    // sizeObj and nameObj will magically be set to the right
+    // thing when we arrive here.
+    // All this crud should be replaced with mmap when we do this
+    // for real(tm)
+    img = malloc ( sizeObj );
+    if (!img) {
+       ERRMSG(0) "Can't allocate memory to load object file for module \"%s\"",
+                 textToStr(t)
+       EEND;
+    }
+    f = fopen( nameObj, "rb" );
+    if (!f) {
+       // Really, this shouldn't happen, since makeStackEntry ensures the
+       // object is available.  Nevertheless ...
+       ERRMSG(0) "Object file \"%s\" can't be opened to read -- oops!",
+                &(nameObj[0])
+       EEND;
+    }
+    if (sizeObj != fread ( img, 1, sizeObj, f)) {
+       ERRMSG(0) "Read of object file \"%s\" failed", nameObj
+       EEND;
+    }
+    if (!validateOImage(img,sizeObj)) {
+       ERRMSG(0) "Validation of object file \"%s\" failed", nameObj 
+       EEND;
+    }
+    
+    assert(!module(m).oImage);
+    module(m).oImage = img;
+
+    if (!cellIsMember(m, ghcModules))
+       ghcModules = cons(m, ghcModules);
+
+    setCurrModule(m);
+}
+
+
+Void addGHCImports(line,mn,syms)
+Int    line;
+Text   mn;       /* the module to import from */
+List   syms; {   /* [ConId | VarId] -- the names to import */
+    List t;
+    Bool found;
+#   ifdef DEBUG_IFACE
+    printf("\naddGHCImport %s\n", textToStr(mn) );
+#   endif
+  
+    // Hack to avoid chasing Prel* junk right now
+    if (strncmp(textToStr(mn), "Prel",4)==0) return;
+
+    found = FALSE;
+    for (t=ifImports; nonNull(t); t=tl(t)) {
+       if (textOf(hd(t)) == mn) {
+          found = TRUE;
+          break;
+       }
+    }
+    if (!found) {
+       ifImports = cons(mkCon(mn),ifImports);
+       ghcImports = cons( triple(currentModule,mn,syms), ghcImports );
+    }
+}
+
+void addGHCVar(line,v,ty)
+Int  line;
+Text v;
+Type ty;
+{
+    Name   n;
+    String s;
+    List   tmp, tvs;
+    /* if this var is the name of a ghc-compiled dictionary,
+       ie, starts zdfC   where C is a capital,
+       ignore it.
+    */
+    s = textToStr(v);
+#   ifdef DEBUG_IFACE
+    printf("\nbegin addGHCVar %s\n", s);
+#   endif
+    if (s[0]=='z' && s[1]=='d' && s[2]=='f' && isupper((int)s[3])) {
+#      ifdef DEBUG_IFACE
+       printf("       ignoring %s\n", s);
+#      endif
+       return;
+    }
+    n = findName(v);
+    if (nonNull(n)) {
+        ERRMSG(0) "Attempt to redefine variable \"%s\"", textToStr(v)
+        EEND;
+    }
+    n = newName(v,NIL);
+    bindGHCNameTo(n, text_info);
+    bindGHCNameTo(n, text_closure);
+
+    tvs = nubList(ifTyvarsIn(ty));
+    for (tmp=tvs; nonNull(tmp); tmp=tl(tmp))
+       hd(tmp) = pair(hd(tmp),STAR);
+    if (nonNull(tvs))
+       ty = mkPolyType(tvsToKind(tvs),ty);
+
+    ty = tvsToOffsets(line,ty,tvs);
+    
+    /* prepare for finishGHCVar */
+    name(n).type = ty;
+    name(n).line = line;
+    ghcVarDecls = cons(n,ghcVarDecls);
+#   ifdef DEBUG_IFACE
+    printf("end   addGHCVar %s\n", s);
+#   endif
+}
+
+static Void local finishGHCVar(Name n)
+{
+    Int  line = name(n).line;
+    Type ty   = name(n).type;
+#   ifdef DEBUG_IFACE
+    fprintf(stderr, "\nbegin finishGHCVar %s\n", textToStr(name(n).text) );
+#   endif
+    setCurrModule(name(n).mod);
+    name(n).type = conidcellsToTycons(line,ty);
+#   ifdef DEBUG_IFACE
+    fprintf(stderr, "end   finishGHCVar %s\n", textToStr(name(n).text) );
+#   endif
+}
+
+Void addGHCSynonym(line,tycon,tvs,ty)
+Int  line;
+Cell tycon;  /* ConId          */
+List tvs;    /* [(VarId,Kind)] */
+Type ty; {
+    /* ToDo: worry about being given a decl for (->) ?
+     * and worry about qualidents for ()
+     */
+    Text t = textOf(tycon);
+    if (nonNull(findTycon(t))) {
+        ERRMSG(line) "Repeated definition of type constructor \"%s\"",
+                     textToStr(t)
+        EEND;
+    } else {
+        Tycon tc        = newTycon(t);
+        tycon(tc).line  = line;
+        tycon(tc).arity = length(tvs);
+        tycon(tc).what  = SYNONYM;
+        tycon(tc).kind  = tvsToKind(tvs);
+
+        /* prepare for finishGHCSynonym */
+        tycon(tc).defn  = tvsToOffsets(line,ty,tvs);
+        ghcSynonymDecls = cons(tc,ghcSynonymDecls);
+    }
+}
+
+static Void  local finishGHCSynonym(Tycon tc)
+{
+    Int  line = tycon(tc).line;
+
+    setCurrModule(tycon(tc).mod);
+    tycon(tc).defn = conidcellsToTycons(line,tycon(tc).defn);
+
+    /* ToDo: can't really do this until I've done all synonyms
+     * and then I have to do them in order
+     * tycon(tc).defn = fullExpand(ty);
+     */
+}
+
+Void addGHCDataDecl(line,ctx0,tycon,ktyvars,constrs0)
+Int  line;
+List ctx0;      /* [(QConId,VarId)]              */
+Cell tycon;     /* ConId                         */
+List ktyvars;   /* [(VarId,Kind)] */
+List constrs0;  /* [(ConId,[(Type,Text)],NIL)]  
+                   The NIL will become the constr's type
+                   The Text is an optional field name */
+    /* ToDo: worry about being given a decl for (->) ?
+     * and worry about qualidents for ()
+     */
+{
+    Type    ty, resTy, selTy, conArgTy;
+    List    tmp, conArgs, sels, constrs, fields, tyvarsMentioned;
+    List    ctx, ctx2;
+    Triple  constr;
+    Cell    conid;
+    Pair    conArg, ctxElem;
+    Text    conArgNm;
+
+    Text t = textOf(tycon);
+#   ifdef DEBUG_IFACE
+    fprintf(stderr, "\nbegin addGHCDataDecl %s\n",textToStr(t));
+#   endif
+    if (nonNull(findTycon(t))) {
+        ERRMSG(line) "Repeated definition of type constructor \"%s\"",
+                     textToStr(t)
+        EEND;
+    } else {
+        Tycon tc        = newTycon(t);
+        tycon(tc).text  = t;
+        tycon(tc).line  = line;
+        tycon(tc).arity = length(ktyvars);
+        tycon(tc).kind  = tvsToKind(ktyvars);
+        tycon(tc).what  = DATATYPE;
+
+        /* a list to accumulate selectors in :: [(VarId,Type)] */
+        sels = NIL;
+
+        /* make resTy the result type of the constr, T v1 ... vn */
+        resTy = tycon;
+        for (tmp=ktyvars; nonNull(tmp); tmp=tl(tmp))
+           resTy = ap(resTy,fst(hd(tmp)));
+
+        /* for each constructor ... */
+        for (constrs=constrs0; nonNull(constrs); constrs=tl(constrs)) {
+           constr = hd(constrs);
+           conid  = fst3(constr);
+           fields = snd3(constr);
+           assert(isNull(thd3(constr)));
+
+           /* Build type of constr and handle any selectors found.
+              Also collect up tyvars occurring in the constr's arg
+              types, so we can throw away irrelevant parts of the
+              context later.
+           */
+           ty = resTy;
+           tyvarsMentioned = NIL;  /* [VarId] */
+           conArgs = reverse(fields);
+           for (; nonNull(conArgs); conArgs=tl(conArgs)) {
+              conArg   = hd(conArgs); /* (Type,Text) */
+              conArgTy = fst(conArg);
+              conArgNm = snd(conArg);
+              tyvarsMentioned = dupListOnto(ifTyvarsIn(conArgTy),
+                                            tyvarsMentioned);
+              ty = fn(conArgTy,ty);
+              if (nonNull(conArgNm)) {
+                /* a field name is mentioned too */
+                 selTy = fn(resTy,conArgTy);
+                 if (whatIs(tycon(tc).kind) != STAR)
+                    selTy = pair(POLYTYPE,pair(tycon(tc).kind, selTy));
+                 selTy = tvsToOffsets(line,selTy, ktyvars);
+
+                 sels = cons( pair(conArgNm,selTy), sels);
+              }
+           }
+
+           /* Now ty is the constructor's type, not including context.
+              Throw away any parts of the context not mentioned in 
+              tyvarsMentioned, and use it to qualify ty.
+          */
+           ctx2 = NIL;
+           for (ctx=ctx0; nonNull(ctx); ctx=tl(ctx)) {
+              ctxElem = hd(ctx);     /* (QConId,VarId) */
+              if (nonNull(cellIsMember(textOf(snd(ctxElem)),tyvarsMentioned)))
+                 ctx2 = cons(ctxElem, ctx2);
+           }
+           if (nonNull(ctx2))
+              ty = ap(QUAL,pair(ctx2,ty));
+
+           /* stick the tycon's kind on, if not simply STAR */
+           if (whatIs(tycon(tc).kind) != STAR)
+              ty = pair(POLYTYPE,pair(tycon(tc).kind, ty));
+
+           ty = tvsToOffsets(line,ty, ktyvars);
+
+           /* Finally, stick the constructor's type onto it. */
+           thd3(hd(constrs)) = ty;
+        }
+
+        /* Final result is that 
+           constrs :: [(ConId,[(Type,Text)],Type)]   
+                      lists the constructors and their types
+           sels :: [(VarId,Type)]
+                   lists the selectors and their types
+       */
+        tycon(tc).defn  = addGHCConstrs(line,constrs0,sels);
+    }
+#   ifdef DEBUG_IFACE
+    fprintf(stderr, "end   addGHCDataDecl %s\n",textToStr(t));
+#   endif
+}
+
+
+static List local addGHCConstrs(line,cons,sels)
+Int  line;
+List cons;   /* [(ConId,[(Type,Text)],Type)] */
+List sels; { /* [(VarId,Type)]         */
+    List cs, ss;
+    Int  conNo = 0; /*  or maybe 1? */
+    for(cs=cons; nonNull(cs); cs=tl(cs), conNo++) {
+        Name c  = addGHCConstr(line,conNo,hd(cs));
+        hd(cs)  = c;
+    }
+    for(ss=sels; nonNull(ss); ss=tl(ss)) {
+        hd(ss) = addGHCSel(line,hd(ss));
+    }
+    return appendOnto(cons,sels);
+}
+
+static Name local addGHCSel(line,sel)
+Int  line;
+Pair sel;    /* (VarId,Type)        */
+{
+    Text t      = textOf(fst(sel));
+    Type type   = snd(sel);
+    
+    Name n = findName(t);
+    if (nonNull(n)) {
+        ERRMSG(line) "Repeated definition for selector \"%s\"",
+            textToStr(t)
+        EEND;
+    }
+
+    n              = newName(t,NIL);
+    name(n).line   = line;
+    name(n).number = SELNAME;
+    name(n).arity  = 1;
+    name(n).defn   = NIL;
+
+    /* prepare for finishGHCVar */
+    name(n).type = type;
+    ghcVarDecls = cons(n,ghcVarDecls);
+
+    return n;
+}
+
+static Name local addGHCConstr(line,conNo,constr)
+Int    line;
+Int    conNo;
+Triple constr; { /* (ConId,[(Type,Text)],Type) */
+    /* ToDo: add rank2 annotation and existential annotation
+     * these affect how constr can be used.
+     */
+    Text con   = textOf(fst3(constr));
+    Type type  = thd3(constr);
+    Int  arity = arityFromType(type);
+    Name n = findName(con);     /* Allocate constructor fun name   */
+    if (isNull(n)) {
+        n = newName(con,NIL);
+    } else if (name(n).defn!=PREDEFINED) {
+        ERRMSG(line) "Repeated definition for constructor \"%s\"",
+            textToStr(con)
+        EEND;
+    }
+    name(n).arity  = arity;     /* Save constructor fun details    */
+    name(n).line   = line;
+    name(n).number = cfunNo(conNo);
+
+    if (arity == 0) {
+       // expect to find the names
+       // Mod_Con_closure
+       // Mod_Con_static_closure
+       // Mod_Con_static_info
+       bindGHCNameTo(n, text_closure);
+       bindGHCNameTo(n, text_static_closure);
+       bindGHCNameTo(n, text_static_info);
+    } else {
+       // expect to find the names
+       // Mod_Con_closure
+       // Mod_Con_entry
+       // Mod_Con_info
+       // Mod_Con_con_info
+       // Mod_Con_static_info
+       bindGHCNameTo(n, text_closure);
+       bindGHCNameTo(n, text_entry);
+       bindGHCNameTo(n, text_info);
+       bindGHCNameTo(n, text_con_info);
+       bindGHCNameTo(n, text_static_info);
+    }
+
+    /* prepare for finishGHCCon */
+    name(n).type   = type;
+    ghcConstrDecls = cons(n,ghcConstrDecls);
+
+    return n;
+}
+
+static Void local finishGHCConstr(Name n)
+{
+    Int  line = name(n).line;
+    Type ty   = name(n).type;
+    setCurrModule(name(n).mod);
+#   ifdef DEBUG_IFACE
+    printf ( "\nbegin finishGHCConstr %s\n", textToStr(name(n).text));
+#   endif
+    name(n).type = conidcellsToTycons(line,ty);
+#   ifdef DEBUG_IFACE
+    printf ( "end   finishGHCConstr %s\n", textToStr(name(n).text));
+#   endif
+}
+
+
+Void addGHCNewType(line,ctx0,tycon,tvs,constr)
+Int  line;
+List ctx0;      /* [(QConId,VarId)]      */
+Cell tycon;     /* ConId | QualConId     */
+List tvs;       /* [(VarId,Kind)]        */
+Cell constr; {  /* (ConId,Type)          */
+    /* ToDo: worry about being given a decl for (->) ?
+     * and worry about qualidents for ()
+     */
+    List tmp;
+    Type resTy;
+    Text t = textOf(tycon);
+    if (nonNull(findTycon(t))) {
+        ERRMSG(line) "Repeated definition of type constructor \"%s\"",
+                     textToStr(t)
+        EEND;
+    } else {
+        Tycon tc        = newTycon(t);
+        tycon(tc).line  = line;
+        tycon(tc).arity = length(tvs);
+        tycon(tc).what  = NEWTYPE;
+        tycon(tc).kind  = tvsToKind(tvs);
+        /* can't really do this until I've read in all synonyms */
+
+        assert(nonNull(constr));
+        if (isNull(constr)) {
+            tycon(tc).defn = NIL;
+        } else {
+            /* constr :: (ConId,Type) */
+            Text con   = textOf(fst(constr));
+            Type type  = snd(constr);
+            Name n = findName(con);     /* Allocate constructor fun name   */
+            if (isNull(n)) {
+                n = newName(con,NIL);
+            } else if (name(n).defn!=PREDEFINED) {
+                ERRMSG(line) "Repeated definition for constructor \"%s\"",
+                    textToStr(con)
+                EEND;
+            }
+            name(n).arity  = 1;         /* Save constructor fun details    */
+            name(n).line   = line;
+            name(n).number = cfunNo(0);
+            name(n).defn   = nameId;
+            tycon(tc).defn = singleton(n);
+
+            /* prepare for finishGHCCon */
+            /* ToDo: we use finishGHCCon instead of finishGHCVar in case
+             * there's any existential quantification in the newtype -
+             * but I don't think that's allowed in newtype constrs.
+             * Still, no harm done by doing it this way...
+             */
+
+             /* make resTy the result type of the constr, T v1 ... vn */
+            resTy = tycon;
+            for (tmp=tvs; nonNull(tmp); tmp=tl(tmp))
+               resTy = ap(resTy,fst(hd(tmp)));
+            type = fn(type,resTy);
+            if (nonNull(ctx0))
+               type = ap(QUAL,pair(ctx0,type));
+
+            type = tvsToOffsets(line,type,tvs);
+
+            name(n).type   = type;
+            ghcConstrDecls = cons(n,ghcConstrDecls);
+        }
+    }
+}
+
+Void addGHCClass(line,ctxt,tc_name,tv,mems0)
+Int  line;
+List ctxt;       /* [(QConId, VarId)]     */ 
+Cell tc_name;    /* ConId                 */
+Text tv;         /* VarId                 */
+List mems0; {    /* [(VarId, Type)]       */
+    List mems;   /* [(VarId, Type)]       */
+    List tvsInT; /* [VarId] and then [(VarId,Kind)] */
+    List tvs;    /* [(VarId,Kind)]        */
+    Text ct     = textOf(tc_name);
+    Pair newCtx = pair(tc_name, tv);
+#   ifdef DEBUG_IFACE
+    printf ( "\nbegin addGHCclass %s\n", textToStr(ct) );
+#   endif
+    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).text       = ct;
+        cclass(nw).line       = line;
+        cclass(nw).arity      = 1;
+        cclass(nw).head       = ap(nw,mkOffset(0));
+        cclass(nw).kinds      = singleton(STAR); /* absolutely no idea at all */
+        cclass(nw).instances  = NIL;             /* what the kind should be   */
+        cclass(nw).numSupers  = length(ctxt);
+
+        /* Kludge to map the single tyvar in the context to Offset 0.
+           Need to do something better for multiparam type classes.
+        */
+        cclass(nw).supers     = tvsToOffsets(line,ctxt,
+                                             singleton(pair(tv,STAR)));
+
+        for (mems=mems0; nonNull(mems); mems=tl(mems)) {
+           Pair mem  = hd(mems);
+           Type memT = snd(mem);
+
+           /* Stick the new context on the member type */
+           if (whatIs(memT)==POLYTYPE) internal("addGHCClass");
+           if (whatIs(memT)==QUAL) {
+              memT = pair(QUAL,
+                          pair(cons(newCtx,fst(snd(memT))),snd(snd(memT))));
+           } else {
+              memT = pair(QUAL,
+                          pair(singleton(newCtx),memT));
+           }
+
+           /* Cook up a kind for the type. */
+           tvsInT = nubList(ifTyvarsIn(memT));
+
+           /* ToDo: maximally bogus */
+           for (tvs=tvsInT; nonNull(tvs); tvs=tl(tvs))
+              hd(tvs) = pair(hd(tvs),STAR);
+
+           memT = mkPolyType(tvsToKind(tvsInT),memT);
+           memT = tvsToOffsets(line,memT,tvsInT);
+
+           /* Park the type back on the member */
+           snd(mem) = memT;
+        }
+
+        cclass(nw).members    = mems0;
+        cclass(nw).numMembers = length(mems0);
+        ghcClassDecls = cons(nw,ghcClassDecls);
+
+        /* ToDo: 
+         * cclass(nw).dsels    = ?;
+         * cclass(nw).dbuild   = ?;
+         * cclass(nm).dcon     = ?;
+         * cclass(nm).defaults = ?;
+         */
+    }
+#   ifdef DEBUG_IFACE
+    printf ( "end   addGHCclass %s\n", textToStr(ct) );
+#   endif
+}
+
+static Void  local finishGHCClass(Class nw)
+{
+    List mems;
+    Int line = cclass(nw).line;
+    Int ctr  = - length(cclass(nw).members);
+
+#   ifdef DEBUG_IFACE
+    printf ( "\nbegin finishGHCclass %s\n", textToStr(cclass(nw).text) );
+#   endif
+
+    setCurrModule(cclass(nw).mod);
+
+    cclass(nw).level      = 0;  /* ToDo: 1 + max (map level supers) */
+    cclass(nw).head       = conidcellsToTycons(line,cclass(nw).head);
+    cclass(nw).supers     = conidcellsToTycons(line,cclass(nw).supers);
+    cclass(nw).members    = conidcellsToTycons(line,cclass(nw).members);
+
+    for (mems=cclass(nw).members; nonNull(mems); mems=tl(mems)) {
+       Pair mem = hd(mems); /* (VarId, Type) */
+       Text txt = textOf(fst(mem));
+       Type ty  = snd(mem);
+       Name n   = findName(txt);
+       if (nonNull(n)) {
+          ERRMSG(cclass(nw).line) 
+             "Repeated definition for class method \"%s\"",
+             textToStr(txt)
+          EEND;
+       }
+       n = newName(txt,NIL);
+       name(n).line   = cclass(nw).line;
+       name(n).type   = ty;
+       name(n).number = ctr++;
+       hd(mems) = n;
+    }
+#   ifdef DEBUG_IFACE
+    printf ( "end   finishGHCclass %s\n", textToStr(cclass(nw).text) );
+#   endif
+}
+
+Void addGHCInstance (line,ctxt0,cls,var)
+Int  line;
+List ctxt0;  /* [(QConId, Type)] */
+Pair cls;    /* (ConId, [Type])  */
+Text var; {  /* Text */
+    List tmp, tvs, ks;
+    Inst in = newInst();
+#   ifdef DEBUG_IFACE
+    printf ( "\nbegin addGHCInstance\n" );
+#   endif
+
+    /* Make tvs into a list of tyvars with bogus kinds. */
+    tvs = nubList(ifTyvarsIn(snd(cls)));
+    ks = NIL;
+    for (tmp = tvs; nonNull(tmp); tmp=tl(tmp)) {
+       hd(tmp) = pair(hd(tmp),STAR);
+       ks = cons(STAR,ks);
+    }
+
+    inst(in).line         = line;
+    inst(in).implements   = NIL;
+    inst(in).kinds        = ks;
+    inst(in).specifics    = tvsToOffsets(line,ctxt0,tvs);
+    inst(in).numSpecifics = length(ctxt0);
+    inst(in).head         = tvsToOffsets(line,cls,tvs);
+#if 0
+Is this still needed?
+    {
+        Name b         = newName(inventText(),NIL);
+        name(b).line   = line;
+        name(b).arity  = length(ctxt); /* unused? */
+        name(b).number = DFUNNAME;
+        inst(in).builder = b;
+        bindNameToClosure(b, lookupGHCClosure(inst(in).mod,var));
+    }
+#endif
+    ghcInstanceDecls = cons(in, ghcInstanceDecls);
+#   ifdef DEBUG_IFACE
+    printf ( "end   addGHCInstance\n" );
+#   endif
+}
+
+static Void  local finishGHCInstance(Inst in)
+{
+    Int  line   = inst(in).line;
+    Cell cl     = fst(inst(in).head);
+    Class c;
+#   ifdef DEBUG_IFACE
+    printf ( "\nbegin finishGHCInstance\n" );
+#   endif
+
+    setCurrModule(inst(in).mod);
+    c = findClass(textOf(cl));
+    if (isNull(c)) {
+        ERRMSG(line) "Unknown class \"%s\" in instance",
+                     textToStr(textOf(cl))
+        EEND;
+    }
+    inst(in).head         = conidcellsToTycons(line,inst(in).head);
+    inst(in).specifics    = conidcellsToTycons(line,inst(in).specifics);
+    cclass(c).instances   = cons(in,cclass(c).instances);
+#   ifdef DEBUG_IFACE
+    printf ( "end   finishGHCInstance\n" );
+#   endif
+}
+
+/* --------------------------------------------------------------------------
+ * Helper fns
+ * ------------------------------------------------------------------------*/
+
+/* This is called from the addGHC* functions.  It traverses a structure
+   and converts varidcells, ie, type variables parsed by the interface
+   parser, into Offsets, which is how Hugs wants to see them internally.
+   The Offset for a type variable is determined by its place in the list
+   passed as the second arg; the associated kinds are irrelevant.
+*/
+static Type local tvsToOffsets(line,type,ktyvars)
+Int  line;
+Type type;
+List ktyvars; { /* [(VarId|Text,Kind)] */
+   switch (whatIs(type)) {
+      case NIL:
+      case TUPLE:
+      case QUALIDENT:
+      case CONIDCELL:
+      case TYCON:
+         return type;
+      case AP: 
+         return ap( tvsToOffsets(line,fun(type),ktyvars),
+                    tvsToOffsets(line,arg(type),ktyvars) );
+      case POLYTYPE: 
+         return mkPolyType ( 
+                   polySigOf(type),
+                   tvsToOffsets(line,monotypeOf(type),ktyvars)
+                );
+         break;
+      case QUAL:
+         return pair(QUAL,pair(tvsToOffsets(line,fst(snd(type)),ktyvars),
+                               tvsToOffsets(line,snd(snd(type)),ktyvars)));
+      case VARIDCELL: /* Ha! some real work to do! */
+       { Int i = 0;
+         Text tv = textOf(type);
+         for (; nonNull(ktyvars); i++,ktyvars=tl(ktyvars)) {
+            Cell varid = fst(hd(ktyvars));
+            Text tt = isVar(varid) ? textOf(varid) : varid;
+            if (tv == tt) return mkOffset(i);            
+         }
+         ERRMSG(line) "Undefined type variable \"%s\"", textToStr(tv)
+         EEND;
+         break;
+       }
+      default: 
+         fprintf(stderr, "tvsToOffsets: unknown stuff %d\n", whatIs(type));
+         print(type,20);
+         fprintf(stderr,"\n");
+         assert(0);
+   }
+   assert(0); /* NOTREACHED */
+}
+
+
+/* This is called from the finishGHC* functions.  It traverses a structure
+   and converts conidcells, ie, type constructors parsed by the interface
+   parser, into Tycons (or Classes), which is how Hugs wants to see them
+   internally.  Calls to this fn have to be deferred to the second phase
+   of interface loading (finishGHC* rather than addGHC*) so that all relevant
+   Tycons or Classes have been loaded into the symbol tables and can be
+   looked up.
+*/
+static Type local conidcellsToTycons(line,type)
+Int  line;
+Type type; {
+   switch (whatIs(type)) {
+      case NIL:
+      case OFFSET:
+      case TYCON:
+      case CLASS:
+      case VARIDCELL:
+         return type;
+      case QUALIDENT:
+       { List t;
+         Text m     = qmodOf(type);
+         Text v     = qtextOf(type);
+         Module mod = findModule(m);
+printf ( "lookup qualident " ); print(type,100); printf("\n");
+         if (isNull(mod)) {
+            ERRMSG(line)
+               "Undefined module in qualified name \"%s\"",
+               identToStr(type)
+            EEND;
+            return NIL;
+         }
+         for (t=module(mod).tycons; nonNull(t); t=tl(t))
+            if (v == tycon(hd(t)).text) return hd(t);
+         for (t=module(mod).classes; nonNull(t); t=tl(t))
+            if (v == cclass(hd(t)).text) return hd(t);
+         ERRMSG(line)
+              "Undefined qualified class or type \"%s\"",
+              identToStr(type)
+         EEND;
+         return NIL;
+       }
+      case CONIDCELL:
+       { Tycon tc;
+         Class cl;
+         tc = findQualTycon(type);
+         if (nonNull(tc)) return tc;
+         cl = findQualClass(type);
+         if (nonNull(cl)) return cl;
+         ERRMSG(line)
+             "Undefined class or type constructor \"%s\"",
+             identToStr(type)
+         EEND;
+         return NIL;
+       }
+      case AP: 
+         return ap( conidcellsToTycons(line,fun(type)),
+                    conidcellsToTycons(line,arg(type)) );
+      case POLYTYPE: 
+         return mkPolyType ( 
+                   polySigOf(type),
+                   conidcellsToTycons(line,monotypeOf(type))
+                );
+         break;
+      case QUAL:
+         return pair(QUAL,pair(conidcellsToTycons(line,fst(snd(type))),
+                               conidcellsToTycons(line,snd(snd(type)))));
+      default: 
+         fprintf(stderr, "conidcellsToTycons: unknown stuff %d\n", 
+                 whatIs(type));
+         print(type,20);
+         fprintf(stderr,"\n");
+         assert(0);
+   }
+   assert(0); /* NOTREACHED */
+}
+
+
+/* --------------------------------------------------------------------------
+ * Utilities
+ *
+ * None of these do lookups or require that lookups have been resolved
+ * so they can be performed while reading interfaces.
+ * ------------------------------------------------------------------------*/
+
+static Kinds local tvsToKind(tvs)
+List tvs; { /* [(VarId,Kind)] */
+    List  rs;
+    Kinds r  = STAR;
+    for (rs=reverse(tvs); nonNull(rs); rs=tl(rs)) {
+        r = ap(snd(hd(rs)),r);
+    }
+    return r;
+}
+
+/* arity of a constructor with this type */
+static Int local arityFromType(type) 
+Type type; {
+    Int arity = 0;
+    if (isPolyType(type)) {
+        type = monotypeOf(type);
+    }
+    if (whatIs(type) == QUAL) {
+        type = snd(snd(type));
+    }
+    if (whatIs(type) == EXIST) {
+        type = snd(snd(type));
+    }
+    if (whatIs(type)==RANK2) {
+        type = snd(snd(type));
+    }
+    while (isAp(type) && getHead(type)==typeArrow) {
+        arity++;
+        type = arg(type);
+    }
+    return arity;
+}
+
+
+static List local ifTyvarsIn(type)
+Type type; {
+    List vs = typeVarsIn(type,NIL,NIL);
+    List vs2 = vs;
+    for (; nonNull(vs2); vs2=tl(vs2)) {
+       Cell v = hd(vs2);
+       if (whatIs(v)==VARIDCELL || whatIs(v)==VAROPCELL) {
+          hd(vs2) = textOf(hd(vs2)); 
+       } else {
+          internal("ifTyvarsIn");
+       }
+    }
+    return vs;
+}
+
+
+/* --------------------------------------------------------------------------
+ * Dynamic loading code (probably shouldn't be here)
+ *
+ * o .hi file explicitly says which .so file to load.
+ *   This avoids the need for a 1-to-1 relationship between .hi and .so files.
+ *
+ *   ToDo: when doing a :reload, we ought to check the modification date 
+ *         on the .so file.
+ *
+ * o module handles are unloaded (dlclosed) when we call dropScriptsFrom.
+ *
+ *   ToDo: do the same for foreign functions - but with complication that 
+ *         there may be multiple .so files
+ * ------------------------------------------------------------------------*/
+
+typedef struct { char* name; void* addr; } RtsTabEnt;
+
+/* not really true */
+extern int stg_gc_enter_1;
+extern int stg_chk_1;
+extern int stg_update_PAP;
+extern int __ap_2_upd_info;
+
+RtsTabEnt rtsTab[] 
+   = { 
+       { "stg_gc_enter_1",    &stg_gc_enter_1  },
+       { "stg_chk_1",         &stg_chk_1       },
+       { "stg_update_PAP",    &stg_update_PAP  },
+       { "__ap_2_upd_info",   &__ap_2_upd_info },
+       {0,0} 
+     };
+
+char* strsuffix ( char* s, char* suffix )
+{
+   int sl = strlen(s);
+   int xl = strlen(suffix);
+   if (xl > sl) return NULL;
+   if (0 == strcmp(s+sl-xl,suffix)) return s+sl-xl;
+   return NULL;
+}
+
+char* lookupObjName ( char* nameT )
+{
+   Text tm;
+   Text tn;
+   Text ts;
+   Name naam;
+   char* nm;
+   char* ty;
+   char* a;
+   Int   k;
+   Pair  pr;
+
+   if (isupper(((int)(nameT[0])))) {
+      // name defined in a module, eg Mod_xyz_static_closure
+      // Place a zero after the module name, and after
+      // the symbol name proper
+      // --> Mod\0xyz\0static_closure
+      nm = strchr(nameT, '_'); 
+      if (!nm) internal ( "lookupObjName");
+      *nm = 0;
+      nm++;
+      if ((ty=strsuffix(nm, "_static_closure"))) 
+         { *ty = 0; ty++; ts = text_static_closure; } 
+      else
+      if ((ty=strsuffix(nm, "_static_info"   ))) 
+         { *ty = 0; ty++; ts = text_static_info; } 
+      else
+      if ((ty=strsuffix(nm, "_con_info"      ))) 
+         { *ty = 0; ty++; ts = text_con_info; } 
+      else
+      if ((ty=strsuffix(nm, "_con_entry"     ))) 
+         { *ty = 0; ty++; ts = text_con_entry; } 
+      else
+      if ((ty=strsuffix(nm, "_info"          )))  
+         { *ty = 0; ty++; ts = text_info; } 
+      else
+      if ((ty=strsuffix(nm, "_entry"         ))) 
+         { *ty = 0; ty++; ts = text_entry; } 
+      else
+      if ((ty=strsuffix(nm, "_closure"       ))) 
+         { *ty = 0; ty++; ts = text_closure; } 
+      else {
+         fprintf(stderr, "lookupObjName: unknown suffix on %s\n", nameT );
+         return NULL;
+      }
+      tm = findText(nameT);
+      tn = findText(nm);
+      //printf ( "\nlooking at mod `%s' var `%s' ext `%s' \n",textToStr(tm),textToStr(tn),textToStr(ts));
+      naam = jrsFindQualName(tm,tn);
+      if (isNull(naam)) goto not_found;
+      pr = cellAssoc ( ts, name(naam).ghc_names );
+      if (isNull(pr)) goto no_info;
+      return ptrOf(snd(pr));
+   }
+   else {
+      // name presumably originating from the RTS
+      a = NULL;
+      for (k = 0; rtsTab[k].name; k++) {
+         if (0==strcmp(nameT,rtsTab[k].name)) {
+            a = rtsTab[k].addr;
+            break;
+         }
+      }
+      if (!a) goto not_found_rts;
+      return a;
+   }
+
+not_found:
+   fprintf ( stderr, 
+             "lookupObjName: can't resolve name `%s'\n", 
+             nameT );
+   return NULL;
+no_info:
+   fprintf ( stderr, 
+             "lookupObjName: no info for name `%s'\n", 
+             nameT );
+   return NULL;
+not_found_rts: 
+   fprintf ( stderr, 
+             "lookupObjName: can't resolve RTS name `%s'\n",
+             nameT );
+   return NULL;
+}
+
+
+/* --------------------------------------------------------------------------
+ * ELF specifics
+ * ------------------------------------------------------------------------*/
+
+#include <elf.h>
+
+static char* local findElfSection ( void* objImage, Elf32_Word sh_type )
+{
+   Int i;
+   char* ehdrC = (char*)objImage;
+   Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
+   Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
+   char* ptr = NULL;
+   for (i = 0; i < ehdr->e_shnum; i++) {
+      if (shdr[i].sh_type == sh_type &&
+          i !=  ehdr->e_shstrndx) {
+         ptr = ehdrC + shdr[i].sh_offset;
+         break;
+      }
+   }
+   return ptr;
+}
+
+static AsmClosure local findObjectSymbol_elfo ( void* objImage, char* name )
+{
+   Int i, nent, j;
+   Elf32_Shdr* shdr;
+   Elf32_Sym*  stab;
+   char* strtab;
+   char* ehdrC = (char*)objImage;
+   Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
+   shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
+
+   strtab = findElfSection ( objImage, SHT_STRTAB );
+   if (!strtab) internal("findObjectSymbol_elfo");
+
+   for (i = 0; i < ehdr->e_shnum; i++) {
+      if (shdr[i].sh_type != SHT_SYMTAB) continue;
+      stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
+      nent = shdr[i].sh_size / sizeof(Elf32_Sym);
+      for (j = 0; j < nent; j++) {
+         if ( strcmp(strtab + stab[j].st_name, name) == 0
+              && ELF32_ST_BIND(stab[j].st_info)==STB_GLOBAL ) {
+            return ehdrC + stab[j].st_value;
+         }
+      }
+   }
+   return NULL;
+}
+
+static Void local resolveReferencesInObjectModule_elfo( objImage )
+void* objImage; {
+   char symbol[1000]; // ToDo
+   int i, j, k;
+   Elf32_Sym*  stab;
+   char* strtab;
+   char* ehdrC = (char*)objImage;
+   Elf32_Ehdr* ehdr = (Elf32_Ehdr*) ehdrC;
+   Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
+   Elf32_Word* targ;
+   // first find "the" symbol table
+   //stab = findElfSection ( objImage, SHT_SYMTAB );
+
+   // also go find the string table
+   strtab = findElfSection ( objImage, SHT_STRTAB );
+
+   if (!stab || !strtab) 
+      internal("resolveReferencesInObjectModule_elfo");
+
+   for (i = 0; i < ehdr->e_shnum; i++) {
+      if (shdr[i].sh_type == SHT_REL ) {
+         Elf32_Rel*  rtab = (Elf32_Rel*) (ehdrC + shdr[i].sh_offset);
+         Int         nent = shdr[i].sh_size / sizeof(Elf32_Rel);
+         Int target_shndx = shdr[i].sh_info;
+         Int symtab_shndx = shdr[i].sh_link;
+         stab  = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
+         targ  = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
+         printf ( "relocations for section %d using symtab %d\n", target_shndx, symtab_shndx );
+         for (j = 0; j < nent; j++) {
+            Elf32_Addr offset = rtab[j].r_offset;
+            Elf32_Word info   = rtab[j].r_info;
+
+            Elf32_Addr  P = ((Elf32_Addr)targ) + offset;
+            Elf32_Word* pP = (Elf32_Word*)P;
+            Elf32_Addr  A = *pP;
+            Elf32_Addr  S;
+
+            printf ("Rel entry %3d is raw(%6p %6p)   ", j, (void*)offset, (void*)info );
+            if (!info) {
+               printf ( " ZERO\n" );
+               S = 0;
+            } else {
+               strcpy ( symbol, strtab+stab[ ELF32_R_SYM(info)].st_name );
+               printf ( "`%s'  ", symbol );
+               if (symbol[0] == 0) {
+                  printf ( "-- ignore?\n" );
+                    S = 0;
+               }
+               else {
+                  S = (Elf32_Addr)lookupObjName ( symbol );
+                  printf ( "resolves to %p\n", (void*)S );
+              }
+            }
+            switch (ELF32_R_TYPE(info)) {
+               case R_386_32:   *pP = S + A;     break;
+               case R_386_PC32: *pP = S + A - P; break;
+               default: fprintf(stderr, 
+                                "unhandled ELF relocation type %d\n",
+                                ELF32_R_TYPE(info));
+                        assert(0);
+           }
+
+         }
+      }
+      else
+      if (shdr[i].sh_type == SHT_RELA) {
+         printf ( "RelA " );
+      }
+   }
+}
+
+static Bool local validateOImage_elfo ( void* imgV, Int size )
+{
+   Elf32_Shdr* shdr;
+   Elf32_Sym*  stab;
+   int i, j, nent, nstrtab, nsymtabs;
+   char* sh_strtab;
+   char* strtab;
+
+   char* ehdrC = (char*)imgV;
+   Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
+
+   if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
+       ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
+       ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
+       ehdr->e_ident[EI_MAG3] != ELFMAG3) {
+      printf ( "Not an ELF header\n" ); 
+      return FALSE;
+   }
+   printf ( "Is an ELF header\n" );
+
+   if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
+      printf ( "Not 32 bit ELF\n" );
+      return FALSE;
+   }
+   printf ( "Is 32 bit ELF\n" );
+
+   if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
+      printf ( "Is little-endian\n" );
+   } else
+   if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
+      printf ( "Is big-endian\n" );
+   } else {
+      printf ( "Unknown endiannness\n" );
+      return FALSE;
+   }
+
+   if (ehdr->e_type != ET_REL) {
+      printf ( "Not a relocatable object (.o) file\n" );
+      return FALSE;
+   }
+   printf ( "Is a relocatable object (.o) file\n" );
+
+   printf ( "Architecture is " );
+   switch (ehdr->e_machine) {
+      case EM_386:   printf ( "x86\n" ); break;
+      case EM_SPARC: printf ( "sparc\n" ); break;
+      default:       printf ( "unknown\n" ); return FALSE;
+   }
+
+   printf ( "\nSection header table: start %d, n_entries %d, ent_size %d\n", 
+              ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize  );
+
+   assert (ehdr->e_shentsize == sizeof(Elf32_Shdr));
+
+   shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
+
+   if (ehdr->e_shstrndx == SHN_UNDEF) {
+      printf ( "No section header string table\n" );
+      sh_strtab = NULL;
+   } else {
+      printf ( "Section header string table is section %d\n", 
+               ehdr->e_shstrndx);
+      sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
+   }
+
+   for (i = 0; i < ehdr->e_shnum; i++) {
+      printf ( "%2d:  ", i );
+      printf ( "type=%2d  ", shdr[i].sh_type );
+      printf ( "size=%4d  ", shdr[i].sh_size );
+      if (shdr[i].sh_type == SHT_REL ) printf ( "Rel  " ); else
+      if (shdr[i].sh_type == SHT_RELA) printf ( "RelA " ); else
+                                       printf ( "     " );
+      if (sh_strtab) printf ( "sname=%s", sh_strtab + shdr[i].sh_name );
+      printf ( "\n" );
+   }
+
+   printf ( "\n\nString tables\n" );
+   strtab = NULL;
+   nstrtab = 0;
+   for (i = 0; i < ehdr->e_shnum; i++) {
+      if (shdr[i].sh_type == SHT_STRTAB &&
+          i !=  ehdr->e_shstrndx) {
+         printf ( "   section %d is a normal string table\n", i );
+         strtab = ehdrC + shdr[i].sh_offset;
+         nstrtab++;
+      }
+   }  
+   if (nstrtab != 1) 
+      printf ( "WARNING: no string tables, or too many\n" );
+
+   nsymtabs = 0;
+   printf ( "\n\nSymbol tables\n" ); 
+   for (i = 0; i < ehdr->e_shnum; i++) {
+      if (shdr[i].sh_type != SHT_SYMTAB) continue;
+      printf ( "section %d is a symbol table\n", i );
+      nsymtabs++;
+      stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
+      nent = shdr[i].sh_size / sizeof(Elf32_Sym);
+      printf ( "   number of entries is apparently %d (%d rem)\n",
+               nent,
+               shdr[i].sh_size % sizeof(Elf32_Sym)
+             );
+      if (0 != shdr[i].sh_size % sizeof(Elf32_Sym)) {
+         printf ( "non-integral number of symbol table entries\n");
+         return FALSE;
+      }
+      for (j = 0; j < nent; j++) {
+         printf ( "   %2d  ", j );
+         printf ( "  sec=%-5d  size=%-3d  val=%-5p  ", 
+                     (int)stab[j].st_shndx,
+                     (int)stab[j].st_size,
+                     (char*)stab[j].st_value );
+
+         printf ( "type=" );
+         switch (ELF32_ST_TYPE(stab[j].st_info)) {
+            case STT_NOTYPE:  printf ( "notype " ); break;
+            case STT_OBJECT:  printf ( "object " ); break;
+            case STT_FUNC  :  printf ( "func   " ); break;
+            case STT_SECTION: printf ( "section" ); break;
+            case STT_FILE:    printf ( "file   " ); break;
+            default:          printf ( "?      " ); break;
+         }
+         printf ( "  " );
+
+         printf ( "bind=" );
+         switch (ELF32_ST_BIND(stab[j].st_info)) {
+            case STB_LOCAL :  printf ( "local " ); break;
+            case STB_GLOBAL:  printf ( "global" ); break;
+            case STB_WEAK  :  printf ( "weak  " ); break;
+            default:          printf ( "?     " ); break;
+         }
+         printf ( "  " );
+
+         printf ( "name=%s\n", strtab + stab[j].st_name );
+      }
+   }
+
+   if (nsymtabs == 0) {
+      printf ( "Didn't find any symbol tables\n" );
+      return FALSE;
+   }
+
+   return TRUE;
+}
+
+
+/* --------------------------------------------------------------------------
+ * Generic lookups
+ * ------------------------------------------------------------------------*/
+
+static Void local bindGHCNameTo ( Name n, Text suffix )
+{
+    char symbol[1000]; /* ToDo: arbitrary constants must die */
+    AsmClosure res;
+    sprintf(symbol,"%s_%s_%s",
+            textToStr(module(currentModule).text),
+            textToStr(name(n).text),textToStr(suffix));
+    //    fprintf(stderr, "\nbindGHCNameTo %s ", symbol);
+    res = findObjectSymbol_elfo ( module(currentModule).oImage, symbol );
+    if (!res) {
+       ERRMSG(0) "Can't find symbol \"%s\" in object for module \"%s\"",
+                 symbol,
+                 textToStr(module(currentModule).text)
+       EEND;
+    }
+    //fprintf(stderr, " = %p\n", res );
+    name(n).ghc_names = cons(pair(suffix,mkPtr(res)), name(n).ghc_names);
+
+    // set the stgVar to be a CPTRCELL to the closure label.
+    // prefer dynamic over static closures if given a choice
+    if (suffix == text_closure || suffix == text_static_closure) {
+       if (isNull(name(n).stgVar)) {
+          // accept any old thing
+          name(n).stgVar = mkCPtr(res);
+       } else {
+          // only accept something more dynamic that what we have now
+          if (suffix != text_static_closure 
+              && isCPtr(name(n).stgVar)
+              && cptrOf(name(n).stgVar) != res)
+             name(n).stgVar = mkCPtr(res);
+       }
+    }
+}
+
+static Void local resolveReferencesInObjectModule ( Module m )
+{
+fprintf(stderr, "resolveReferencesInObjectModule %s\n",textToStr(module(m).text));
+   resolveReferencesInObjectModule_elfo ( module(m).oImage );
+}
+
+static Bool local validateOImage(img,size)
+void* img;
+Int   size; {
+   return validateOImage_elfo ( img, size );
+}
+
+
+/* --------------------------------------------------------------------------
+ * Control:
+ * ------------------------------------------------------------------------*/
+
+Void interface(what)
+Int what; {
+    switch (what) {
+    case INSTALL:
+    case RESET: 
+            ifImports           = NIL;
+            ghcVarDecls         = NIL;     
+            ghcConstrDecls      = NIL;     
+            ghcSynonymDecls     = NIL;
+            ghcClassDecls       = NIL;
+            ghcInstanceDecls    = NIL;
+            ghcExports          = NIL;
+            ghcImports          = NIL;
+            ghcModules          = NIL;
+            text_info           = findText("info");
+            text_entry          = findText("entry");
+            text_closure        = findText("closure");
+            text_static_closure = findText("static_closure");
+            text_static_info    = findText("static_info");
+            text_con_info       = findText("con_info");
+            text_con_entry      = findText("con_entry");
+            break;
+    case MARK: 
+            mark(ifImports);
+            mark(ghcVarDecls);     
+            mark(ghcConstrDecls);     
+            mark(ghcSynonymDecls); 
+            mark(ghcClassDecls); 
+            mark(ghcInstanceDecls);
+            mark(ghcImports);
+            mark(ghcExports);
+            mark(ghcModules);
+            break;
+    }
+}
+
+/*-------------------------------------------------------------------------*/
index 6caf0e4..b87a0e7 100644 (file)
@@ -130,3 +130,5 @@ extern       Cell  predFractional;;            /* Fractional (mkOffset(0))
 extern       Cell  predIntegral;;              /* Integral (mkOffset(0))          */
 extern       Kind  starToStar;;                /* Type -> Type                    */
 extern       Cell  predMonad;;                 /* Monad (mkOffset(0))             */
+
+
index ebdf4bb..2847b41 100644 (file)
@@ -12,8 +12,8 @@
  * in the distribution for details.
  *
  * $RCSfile: machdep.c,v $
- * $Revision: 1.5 $
- * $Date: 1999/04/27 10:06:55 $
+ * $Revision: 1.6 $
+ * $Date: 1999/06/07 17:22:37 $
  * ------------------------------------------------------------------------*/
 
 #ifdef HAVE_SIGNAL_H
@@ -133,14 +133,16 @@ static String local readRegChildStrings Args((HKEY, String, String, Char, String
 typedef struct { unsigned hi, lo; } Time;
 #define timeChanged(now,thn)    (now.hi!=thn.hi || now.lo!=thn.lo)
 #define timeSet(var,tm)         var.hi = tm.hi; var.lo = tm.lo
+error  timeEarlier not defined
 #else
 typedef time_t Time;
-#define timeChanged(now,thn)    (now!=thn)
-#define timeSet(var,tm)         var = tm
+#define timeChanged(now,thn)      (now!=thn)
+#define timeSet(var,tm)           var = tm
+#define timeEarlier(earlier,now)  (earlier < now)
 #endif
 
-static Void local getFileInfo   Args((String, Time *, Long *));
 static Bool local readable      Args((String));
+static Void local getFileInfo   Args((String, Time *, Long *));
 
 static Void local getFileInfo(f,tm,sz)  /* find time stamp and size of file*/
 String f;
@@ -149,10 +151,10 @@ Long   *sz; {
 #if defined HAVE_SYS_STAT_H || defined HAVE_STAT_H || defined HAVE_UNIX_H
     struct stat scbuf;
     if (!stat(f,&scbuf)) {
-        *tm = scbuf.st_mtime;
+        if (tm) *tm = scbuf.st_mtime;
         *sz = (Long)(scbuf.st_size);
     } else {
-        *tm = 0;
+        if (tm) *tm = 0;
         *sz = 0;
     }
 #else                                   /* normally just use stat()        */
@@ -161,15 +163,20 @@ Long   *sz; {
     r.r[1] = (int)s;
     os_swi(OS_File, &r);
     if(r.r[0] == 1 && (r.r[2] & 0xFFF00000) == 0xFFF00000) {
-        tm->hi = r.r[2] & 0xFF;         /* Load address (high byte)        */
-        tm->lo = r.r[3];                /* Execution address (low 4 bytes) */
+        if (tm) tm->hi = r.r[2] & 0xFF; /* Load address (high byte)        */
+        if (tm) tm->lo = r.r[3];        /* Execution address (low 4 bytes) */
     } else {                            /* Not found, or not time-stamped  */
-        tm->hi = tm->lo = 0;
+        if (tm) tm->hi = tm->lo = 0;
     }
     *sz = (Long)(r.r[0] == 1 ? r.r[4] : 0);
 #endif
 }
 
+Void getFileSize ( String f, Long* sz )
+{
+   getFileInfo ( f, NULL, sz );
+}
+
 #if defined HAVE_GETFINFO               /* Mac971031 */
 /* --------------------------------------------------------------------------
  * Define a MacOS version of access():
@@ -210,6 +217,7 @@ String f; {
     return (0 == access(f,4));
 #elif defined HAVE_SYS_STAT_H || defined HAVE_STAT_H
     struct stat scbuf;
+    //fprintf(stderr, "readable: %s\n", f );
     return (  !stat(f,&scbuf) 
            && (scbuf.st_mode & S_IREAD) /* readable     */
            && (scbuf.st_mode & S_IFREG) /* regular file */
@@ -255,7 +263,7 @@ static Bool   local tryEndings    Args((String));
 # define SLASH                   '/'
 # define isSLASH(c)              ((c)==SLASH)
 # define PATHSEP                 ':'
-# define DLL_ENDING              ".so"
+# define DLL_ENDING              ".o"
 #endif
 
 static String local hugsdir() {     /* directory containing lib/Prelude.hs */
@@ -367,9 +375,9 @@ String s; {                     /* a pathname in some appropriate manner.  */
 }
 
 #if HSCRIPT
-static String endings[] = { "", ".hs", ".lhs", ".hsx", ".hash", 0 };
+static String endings[] = { "", ".hi", ".hs", ".lhs", ".hsx", ".hash", 0 };
 #else
-static String endings[] = { "", ".hs", ".lhs", 0 };
+static String endings[] = { "", ".hi", ".hs", ".lhs", 0 };
 #endif
 static char   searchBuf[FILENAME_MAX+1];
 static Int    searchPos;
@@ -413,9 +421,9 @@ String s; {
    searches the base directory and its direct subdirectories for a file
 
    input: searchbuf contains SLASH terminated base directory
-              argument s contains the (base) filename
+          argument s contains the (base) filename
    output: TRUE: searchBuf contains the full filename
-                   FALSE: searchBuf is garbage, file not found
+           FALSE: searchBuf is garbage, file not found
 */
           
 
@@ -588,6 +596,124 @@ String path; {
 }
 
 /* --------------------------------------------------------------------------
+ * New path handling stuff for the Combined System (tm)
+ * ------------------------------------------------------------------------*/
+
+Bool findFilesForModule ( 
+        String  modName,
+        String* path,
+        String* sExt,
+        Bool* sAvail, Time* sTime, Long* sSize,
+        Bool* iAvail, Time* iTime, Long* iSize,
+        Bool* oAvail, Time* oTime, Long* oSize
+     )
+{
+   /* Let the module name given be M.
+      For each path entry P,
+        a  s(rc)       file will be P/M.hs or P/M.lhs
+        an i(nterface) file will be P/M.hi
+        an o(bject)    file will be P/M.o
+      If there is a s file or (both i and o files)
+        use P to fill in the path names.
+      Otherwise, move on to the next path entry.
+      If all path entries are exhausted, return False.
+   */
+   Int    nPath;
+   Bool   literate;
+   String peStart, peEnd;
+   String augdPath;       /* . and then hugsPath */
+
+   *path = *sExt = NULL;
+   *sAvail = *iAvail = *oAvail = FALSE;
+   *sSize  = *iSize  = *oSize  = 0;
+
+   augdPath = malloc(3+strlen(hugsPath));
+   if (!augdPath)
+      internal("moduleNameToFileNames: malloc failed(2)");
+   augdPath[0] = '.';
+   augdPath[1] = PATHSEP;
+   augdPath[2] = 0;
+   strcat(augdPath,hugsPath);
+
+   peEnd = augdPath-1;
+   while (1) {
+      /* Advance peStart and peEnd very paranoically, giving up at
+         the first sign of mutancy in the path string.
+      */
+      if (peEnd >= augdPath && !(*peEnd)) { free(augdPath); return FALSE; }
+      peStart = peEnd+1;
+      peEnd = peStart;
+      while (*peEnd && *peEnd != PATHSEP) peEnd++;
+      
+      /* Now peStart .. peEnd-1 bracket the next path element. */
+      nPath = peEnd-peStart;
+      if (nPath + strlen(modName) + 10 /*slush*/ > FILENAME_MAX) {
+         ERRMSG(0) "Hugs path \"%s\" contains excessively long component", 
+                   hugsPath
+         EEND;
+         free(augdPath); 
+         return FALSE;
+      }
+
+      strncpy(searchBuf, peStart, nPath); 
+      searchBuf[nPath] = 0;
+      if (nPath > 0 && !isSLASH(searchBuf[nPath-1])) 
+         searchBuf[nPath++] = SLASH;
+
+      strcpy(searchBuf+nPath, modName);
+      nPath += strlen(modName);
+
+      /* searchBuf now holds 'P/M'.  Try out the various endings. */
+      *path = *sExt = NULL;
+      *sAvail = *iAvail = *oAvail = FALSE;
+      *sSize  = *iSize  = *oSize  = 0;
+
+      strcpy(searchBuf+nPath, DLL_ENDING);
+      if (readable(searchBuf)) {
+         *oAvail = TRUE;
+         getFileInfo(searchBuf, oTime, oSize);
+      }
+
+      strcpy(searchBuf+nPath, ".hi");
+      if (readable(searchBuf)) {
+         *iAvail = TRUE;
+         getFileInfo(searchBuf, iTime, iSize);
+      }
+
+      strcpy(searchBuf+nPath, ".hs");
+      if (readable(searchBuf)) {
+         *sAvail = TRUE;
+         literate = FALSE;
+         getFileInfo(searchBuf, sTime, sSize);
+         *sExt = ".hs";
+      } else {
+         strcpy(searchBuf+nPath, ".lhs");
+         if (readable(searchBuf)) {
+            *sAvail = TRUE;
+            literate = TRUE;
+            getFileInfo(searchBuf, sTime, sSize);
+            *sExt = ".lhs";
+         }
+      }
+
+      /* Success? */
+      if (*sAvail || (*oAvail && *iAvail)) {
+         nPath -= strlen(modName);
+         *path = malloc(nPath+1);
+         if (!(*path))
+            internal("moduleNameToFileNames: malloc failed(1)");
+         strncpy(*path, searchBuf, nPath);
+         (*path)[nPath] = 0;
+         free(augdPath); 
+         return TRUE;
+      }
+
+   }
+   
+}
+
+
+/* --------------------------------------------------------------------------
  * Substitute old value of path into empty entries in new path
  * eg substPath("a:b:c::d:e","x:y:z") = "a:b:c:x:y:z:d:e"
  * ------------------------------------------------------------------------*/
index 60e565c..c746368 100644 (file)
@@ -11,8 +11,8 @@
  * in the distribution for details.
  *
  * $RCSfile: parser.y,v $
- * $Revision: 1.5 $
- * $Date: 1999/04/27 10:06:58 $
+ * $Revision: 1.6 $
+ * $Date: 1999/06/07 17:22:41 $
  * ------------------------------------------------------------------------*/
 
 %{
@@ -28,7 +28,8 @@
 #define only(t)                  ap(ONLY,t)
 #define letrec(bs,e)             (nonNull(bs) ? ap(LETREC,pair(bs,e)) : e)
 #define qualify(ps,t)            (nonNull(ps) ? ap(QUAL,pair(ps,t)) : t)
-#define exportSelf()             singleton(ap(MODULEENT,mkCon(module(currentModule).text)))
+#define exportSelf()             singleton(ap(MODULEENT, \
+                                    mkCon(module(currentModule).text)))
 #define yyerror(s)               /* errors handled elsewhere */
 #define YYSTYPE                  Cell
 
@@ -36,6 +37,7 @@ static Cell   local gcShadow     Args((Int,Cell));
 static Void   local syntaxError  Args((String));
 static String local unexpected   Args((Void));
 static Cell   local checkPrec    Args((Cell));
+static Void   local fixDefn      Args((Syntax,Cell,Cell,List));
 static Cell   local buildTuple   Args((List));
 static List   local checkContext Args((List));
 static Cell   local checkPred    Args((Cell));
@@ -87,17 +89,295 @@ static Void   local noTREX       Args((String));
 %token '!'        IMPLIES    '('        ','        ')'
 %token '['        ';'        ']'        '`'        '.'
 %token TMODULE    IMPORT     HIDING     QUALIFIED  ASMOD
-%token EXPORT     UNSAFE
+%token EXPORT     INTERFACE  REQUIRES   UNSAFE     INSTIMPORT
 
 %%
 /*- Top level script/module structure -------------------------------------*/
 
 start     : EXPR exp wherePart          {inputExpr = letrec($3,$2); sp-=2;}
           | SCRIPT topModule            {valDefns  = $2;            sp-=1;}
+          | INTERFACE iface             {sp-=1;}
           | error                       {syntaxError("input");}
           ;
 
+
+/*- GHC interface file parsing: -------------------------------------------*/
+
+/* Reading in an interface file is surprisingly like reading
+ * a normal Haskell module: we read in a bunch of declarations,
+ * construct symbol table entries, etc.  The "only" differences
+ * are that there's no syntactic sugar to deal with and we don't
+ * have to read in expressions.
+ */
+
+/*- Top-level interface files -----------------------------*/
+iface     : INTERFACE ifName NUMLIT checkVersion WHERE ifDecls 
+                                        {$$ = gc6(NIL); }
+          | INTERFACE error             {syntaxError("interface file");}
+          ;
+ifDecls:                                {$$=gc0(NIL);}
+          | ifDecl ';' ifDecls          {$$=gc3(cons($1,$3));}
+          ;
+varid_or_conid
+          : VARID                       { $$=gc1($1); }
+          | CONID                       { $$=gc1($1); }
+          ;
+opt_bang  : '!'                         {$$=gc1(NIL);}
+          |                             {$$=gc0(NIL);}
+          ;
+ifName    : CONID                       {openGHCIface(textOf($1)); 
+                                         $$ = gc1(NIL);}
+checkVersion
+          : NUMLIT                      {$$ = gc1(NIL); }
+          ;
+ifDecl    
+          : IMPORT CONID opt_bang NUMLIT COCO version_list_junk
+                                        { addGHCImports(intOf($4),textOf($2),
+                                                       $6);
+                                          $$ = gc6(NIL); 
+                                        }
+
+          | INSTIMPORT CONID            {$$=gc2(NIL);}
+
+          | EXPORT CONID ifEntities     { addGHCExports($2,$3);
+                                          $$=gc3(NIL);}
+
+          | NUMLIT INFIXL optDigit varid_or_conid   
+                                        {$$ = gc4(fixdecl($2,singleton($4),
+                                                          LEFT_ASS,$3)); }
+          | NUMLIT INFIXR optDigit varid_or_conid   
+                                        {$$ = gc4(fixdecl($2,singleton($4),
+                                                          RIGHT_ASS,$3)); }
+          | NUMLIT INFIXN optDigit varid_or_conid   
+                                        {$$ = gc4(fixdecl($2,singleton($4),
+                                                          NON_ASS,$3)); }
+
+          | TINSTANCE ifCtxInst ifInstHd '=' ifVar
+                                        { addGHCInstance(intOf($1),$2,$3,
+                                          textOf($5)); 
+                                          $$ = gc5(NIL); }
+          | NUMLIT TYPE ifCon ifKindedTyvarL '=' ifType
+                                        { addGHCSynonym(intOf($2),$3,$4,$6);
+                                          $$ = gc6(NIL); }
+
+          | NUMLIT DATA ifCtxDecl ifConData ifKindedTyvarL ifConstrs
+                                        { addGHCDataDecl(intOf($2),
+                                                         $3,$4,$5,$6);
+                                          $$ = gc6(NIL); }
+
+          | NUMLIT TNEWTYPE ifCtxDecl ifConData ifKindedTyvarL ifNewTypeConstr
+                                        { addGHCNewType(intOf($2),
+                                                        $3,$4,$5,$6);
+                                          $$ = gc6(NIL); }
+          | NUMLIT TCLASS ifCtxDecl ifCon ifTyvar ifCmeths
+                                        { addGHCClass(intOf($2),$3,$4,$5,$6);
+                                          $$ = gc6(NIL); }
+          | NUMLIT ifVar COCO ifType
+                                        { addGHCVar(intOf($3),textOf($2),$4);
+                                          $$ = gc4(NIL); }
+          | error                       { syntaxError(
+                                             "interface declaration"); }
+          ;
+
+
+/*- Interface variable and constructor ids ----------------*/
+ifTyvar   : VARID                       {$$ = $1;}
+          ;
+ifVar     : VARID                       {$$ = gc1($1);}
+          ;
+ifCon     : CONID                       {$$ = gc1($1);}
+          ;
+ifQCon    : CONID                       {$$ = gc1($1);}
+          | QCONID                      {$$ = gc1($1);}
+          ;
+ifConData : ifCon                       {$$ = gc1($1);}
+          | '(' ')'                     {$$ = gc2(typeUnit);}
+          | '[' ']'                     {$$ = gc2(typeList);}
+          | '(' ARROW ')'               {$$ = gc3(typeArrow);}
+          ;
+ifTCName  : CONID                       { $$ = gc1($1); }
+          | CONOP                       { $$ = gc1($1); }
+          | '(' ARROW ')'               { $$ = gc3(typeArrow); }
+          | '[' ']'                     { $$ = gc1(typeList);  }
+          ; 
+ifQTCName : ifTCName                    { $$ = gc1($1); }
+          | QCONID                      { $$ = gc1($1); }
+          | QCONOP                      { $$ = gc1($1); }
+          ; 
+
+
+/*- Interface contexts ------------------------------------*/
+ifCtxInst /* __forall [a b] {M.C1 a, M.C2 b} =>  */
+          /* :: [(QConId, VarId)]                */
+          : ALL ifForall ifCtxDecl      {$$=gc3($3);}
+          | ALL ifForall IMPLIES        {$$=gc3(NIL);}
+          |                             {$$=gc0(NIL);}
+          ;
+ifInstHd  /* { Class aType }    :: (ConId, Type) */
+          : '{' ifCon ifAType '}'       {$$=gc4(pair($2,$3));}
+          ;
+
+ifCtxDecl /* {M.C1 a, C2 b} :: [(QConId, VarId)] */ 
+          :                             { $$ = gc0(NIL); }
+          | '{' ifCtxDeclL '}' IMPLIES  { $$ = gc4($2);  }
+          ;                                    
+ifCtxDeclT /* {M.C1 a, C2 b} :: [(QConId, VarId)] */ 
+          :                             { $$ = gc0(NIL); }
+          | '{' ifCtxDeclL '}'          { $$ = gc3($2);  }
+          ;                                    
+ifCtxDeclL /* M.C1 a, C2 b :: [(QConId, VarId)] */
+          : ifCtxDeclLE ',' ifCtxDeclL  {$$=gc3(cons($1,$3));}
+          | ifCtxDeclLE                 {$$=gc1(cons($1,NIL));}
+          |                             {$$=gc0(NIL);}
+          ;
+ifCtxDeclLE /* M.C1 a   :: (QConId,VarId) */
+          : ifQCon ifTyvar              {$$=gc2(pair($1,$2));}
+          ;
+
+
+/*- Interface data declarations - constructor lists -------*/
+ifConstrs /* = Con1 | ... | ConN  :: [(ConId,[(Type,Text)],NIL)] */
+          :                             {$$ = gc0(NIL);}
+          | '=' ifConstrL               {$$ = gc2($2);}
+          ;
+ifConstrL /* [(ConId,[(Type,Text)],NIL)] */
+          : ifConstr                    {$$ = gc1(singleton($1));}
+          | ifConstr '|' ifConstrL      {$$ = gc3(cons($1,$3));}
+          ;
+ifConstr /* (ConId,[(Type,Text)],NIL) */
+          : ifConData ifDataAnonFieldL  {$$ = gc2(triple($1,$2,NIL));}
+          | ifConData '{' ifDataNamedFieldL '}' 
+                                        {$$ = gc4(triple($1,$3,NIL));}
+          ;
+ifDataAnonFieldL /* [(Type,Text)] */
+          :                             {$$=gc0(NIL);}
+          | ifDataAnonField ifDataAnonFieldL
+                                        {$$=gc2(cons($1,$2));}
+          ;
+ifDataNamedFieldL /* [(Type,Text)] */
+          :                             {$$=gc0(NIL);}
+          | ifDataNamedField            {$$=gc1(cons($1,NIL));}
+          | ifDataNamedField ',' ifDataNamedFieldL 
+                                        {$$=gc3(cons($1,$3));}
+          ;
+ifDataAnonField /* (Type,Text) */
+          : ifAType                     {$$=gc1(pair($1,NIL));}
+          ;
+ifDataNamedField  /* (Type,Text) */
+          : VARID COCO ifAType          {$$=gc3(pair($3,$1));}
+          ;
+
+
+/*- Interface class declarations - methods ----------------*/
+ifCmeths /* [(VarId,Type)] */
+          :                             { $$ = gc0(NIL); }
+          | WHERE '{' ifCmethL '}'      { $$ = gc4($3); }
+          ;
+ifCmethL /* [(VarId,Type)] */
+          : ifCmeth                     { $$ = gc1(singleton($1)); }
+          | ifCmeth ';' ifCmethL        { $$ = gc3(cons($1,$3));    }
+          ;
+ifCmeth /* (VarId,Type) */
+          : ifVar     COCO ifType       { $$ = gc3(pair($1,$3)); }
+          | ifVar '=' COCO ifType       { $$ = gc4(pair($1,$4)); } 
+                                              /* has default method */
+          ;
+
+
+/*- Interface newtype declararions ------------------------*/
+ifNewTypeConstr /* (ConId,Type) */
+          : '=' ifCon ifAType           { $$ = gc3(pair($2,$3)); }
+          ;
+
+
+/*- Interface type expressions ----------------------------*/
+ifType    : ALL ifForall ifCtxDeclT IMPLIES ifType 
+                                        { if ($3 == NIL)
+                                           $$=gc5($5); else
+                                           $$=gc5(pair(QUAL,pair($3,$5)));
+                                        }
+          | ifBType ARROW ifType        { $$ = gc3(fn($1,$3)); }
+          | ifBType                     { $$ = gc1($1); }
+          ;                                    
+ifForall /* [(VarId,Kind)] */
+          : '[' ifKindedTyvarL ']'      { $$ = gc3($2); }
+          ;                                    
+ifTypes2  : ifType ',' ifType           { $$ = gc3(doubleton($1,$3)); }
+          | ifType ',' ifTypes2         { $$ = gc3(cons($1,$3));      }
+          ;
+ifBType   : ifAType                     { $$ = gc1($1);        } 
+          | ifBType ifAType             { $$ = gc2(ap($1,$2)); }
+          ;
+ifAType   : ifQTCName                   { $$ = gc1($1); }
+          | ifTyvar                     { $$ = gc1($1); }
+          | '(' ')'                     { $$ = gc2(typeUnit); }
+          | '(' ifTypes2 ')'            { $$ = gc3(buildTuple($2)); }
+          | '[' ifType ']'              { $$ = gc3(ap(typeList,$2));}
+          | '{' ifQTCName ifATypes '}'  { $$ = gc4(ap(DICTAP,
+                                                      pair($2,$3))); }
+          | '(' ifType ')'              { $$ = gc3($2); }
+          ;
+ifATypes  :                             { $$ = gc0(NIL);         }
+          | ifAType ifATypes            { $$ = gc2(cons($1,$2)); }
+          ;
+
+
+/*- Interface kinds ---------------------------------------*/
+ifKindedTyvarL /* [(VarId,Kind)] */
+          :                              { $$ = gc0(NIL);         }
+          | ifKindedTyvar ifKindedTyvarL { $$ = gc2(cons($1,$2)); }
+          ;
+ifKindedTyvar /* (VarId,Kind) */
+          : ifTyvar                     { $$ = gc1(pair($1,STAR)); }
+          | ifTyvar COCO ifAKind        { $$ = gc3(pair($1,$3));   }
+          ; 
+ifKind    : ifAKind                     { $$ = gc1($1);        }
+          | ifAKind ARROW ifKind        { $$ = gc3(fn($1,$3)); }
+          ;
+ifAKind   : VAROP                       { $$ = gc1(STAR); } 
+                                            /* should be '*' */
+          | '(' ifKind ')'              { $$ = gc3($2);   }
+          ;
+
+
+/*- Interface version/export/import stuff -----------------*/
+ifEntities                                     
+          :                             { $$ = gc0(NIL);         }
+          | ifEntity ifEntities         { $$ = gc2(cons($1,$2)); }
+          ;
+ifEntity
+          : ifEntityOcc                 {$$=gc1($1);}
+          | ifEntityOcc ifStuffInside   {$$=gc2($1);}
+          | ifEntityOcc '|' ifStuffInside {$$=gc3($1);} 
+                                       /* exporting datacons but not tycon */
+          ;
+ifEntityOcc
+          : ifVar                       { $$ = gc1($1); }
+          | ifCon                       { $$ = gc1($1); }
+          | ARROW                       { $$ = gc1(typeArrow); }
+          | '(' ARROW ')'               { $$ = gc3(typeArrow); }  
+                                        /* why allow both? */
+          ;
+ifStuffInside
+          : '{' ifValOccs '}'           { $$ = gc3($2); }
+          ;
+ifValOccs
+          : ifValOcc                    { $$ = gc1(singleton($1)); }
+          | ifValOcc ifValOccs          { $$ = gc2(cons($1,$2));   }
+          ;
+ifValOcc
+          : ifVar                       {$$ = gc1($1); }
+          | ifCon                       {$$ = gc1($1); }
+          ;
+version_list_junk
+          :                                {$$=gc0(NIL);}
+          | VARID NUMLIT version_list_junk {$$=gc3(cons($1,$3));} 
+          | CONID NUMLIT version_list_junk {$$=gc3(cons($1,$3));}
+          ;
+
+
 /*- Haskell module header/import parsing: -----------------------------------
+
  * Syntax for Haskell modules (module headers and imports) is parsed but
  * most of it is ignored.  However, module names in import declarations
  * are used, of course, if import chasing is turned on.
@@ -108,7 +388,10 @@ start     : EXPR exp wherePart          {inputExpr = letrec($3,$2); sp-=2;}
  * We use the 1.2 header because it breaks much less pre-module code.
  */
 topModule : startMain begin modBody end {
-                                         setExportList(singleton(ap(MODULEENT,mkCon(module(currentModule).text))));
+                                         setExportList(singleton(
+                                            ap(MODULEENT,
+                                            mkCon(module(currentModule).text)
+                                            )));
                                          $$ = gc3($3);
                                         }
           | TMODULE modname expspec WHERE '{' modBody end
@@ -126,8 +409,11 @@ modname   : CONID                       {startModule($1); $$ = gc1(NIL);}
           ;
 modid     : CONID                       {$$ = $1;}
           | STRINGLIT                   { extern String scriptFile;
-                                          String modName = findPathname(scriptFile,textToStr(textOf($1)));
-                                          if (modName) { /* fillin pathname if known */
+                                          String modName 
+                                             = findPathname(scriptFile,
+                                                 textToStr(textOf($1)));
+                                          if (modName) { 
+                                              /* fillin pathname if known */
                                               $$ = mkStr(findText(modName));
                                           } else {
                                               $$ = $1;
@@ -252,7 +538,7 @@ topDecl   : TYPE tyLhs '=' type         {defTycon(4,$3,$2,$4,SYNONYM);}
           | TYPE error                  {syntaxError("type definition");}
           | DATA btype2 '=' constrs deriving
                                         {defTycon(5,$3,checkTyLhs($2),
-                                                    ap(rev($4),$5),DATATYPE);}
+                                                   ap(rev($4),$5),DATATYPE);}
           | DATA context IMPLIES tyLhs '=' constrs deriving
                                         {defTycon(7,$5,$4,
                                                   ap(qualify($2,rev($6)),
@@ -280,7 +566,7 @@ invars    : invars ',' invar            {$$ = gc3(cons($3,$1));}
           | invar                       {$$ = gc1(cons($1,NIL));}
           ;
 invar     : var COCO topType            {$$ = gc3(sigdecl($2,singleton($1),
-                                                                        $3));}
+                                                                       $3));}
           | var                         {$$ = $1;}
           ;
 constrs   : constrs '|' pconstr         {$$ = gc3(cons($3,$1));}
@@ -880,12 +1166,13 @@ varid1    : VARID                       {$$ = gc1($1);}
 
 /*- Tricks to force insertion of leading and closing braces ---------------*/
 
-begin     : error                       {yyerrok; goOffside(startColumn);}
+begin     : error                       {yyerrok; 
+                                         if (offsideON) goOffside(startColumn);}
           ;
                                         /* deal with trailing semicolon    */
 end       : '}'                         {$$ = $1;}
           | error                       {yyerrok; 
-                                         if (canUnOffside()) {
+                                         if (offsideON && canUnOffside()) {
                                              unOffside();
                                              /* insert extra token on stack*/
                                              push(NIL);
@@ -910,7 +1197,7 @@ Cell e; {
      *           x1  |  ...  |  xn  |  la   ===>  e  |  la
      *                                top()            top()
      *
-     * Othwerwise, the transformation is:
+     * Otherwise, the transformation is:
      *   pushed: n-1             0        0
      *           x1  |  ...  |  xn  ===>  e
      *                         top()     top()
@@ -962,7 +1249,7 @@ static String local unexpected() {     /* find name for unexpected token   */
         case DEFAULT   : keyword("default");
         case IMPORT    : keyword("import");
         case TMODULE   : keyword("module");
-        case ALL       : keyword("forall");
+        case ALL       : keyword("__forall");
 #undef keyword
 
         case ARROW     : return "`->'";
index 7b0e601..0959382 100644 (file)
@@ -8,8 +8,8 @@
  * in the distribution for details.
  *
  * $RCSfile: static.c,v $
- * $Revision: 1.6 $
- * $Date: 1999/04/27 10:07:01 $
+ * $Revision: 1.7 $
+ * $Date: 1999/06/07 17:22:35 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
@@ -65,7 +65,6 @@ static List   local classBindings       Args((String,Class,List));
 static Name   local memberName          Args((Class,Text));
 static List   local numInsert           Args((Int,Cell,List));
 
-static List   local typeVarsIn          Args((Cell,List,List));
 static List   local maybeAppendVar      Args((Cell,List));
 
 static Type   local checkSigType        Args((Int,String,Cell,Type));
@@ -1588,7 +1587,7 @@ List xs; {
  * occur in the type expression when read from left to right.
  * ------------------------------------------------------------------------*/
 
-static List local typeVarsIn(ty,us,vs)  /* Calculate list of type variables*/
+List typeVarsIn(ty,us,vs)               /* Calculate list of type variables*/
 Cell ty;                                /* used in type expression, reading*/
 List us;                                /* from left to right ignoring any */
 List vs; {                              /* listed in us.                   */
index 7495377..3d62bc5 100644 (file)
@@ -8,8 +8,8 @@
  * in the distribution for details.
  *
  * $RCSfile: storage.c,v $
- * $Revision: 1.6 $
- * $Date: 1999/04/27 10:07:05 $
+ * $Revision: 1.7 $
+ * $Date: 1999/06/07 17:22:49 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
@@ -415,6 +415,7 @@ Cell parent; {
     name(nameHw).type         = NIL;
     name(nameHw).primop       = 0;
     name(nameHw).mod          = currentModule;
+    name(nameHw).ghc_names    = NIL;
     module(currentModule).names=cons(nameHw,module(currentModule).names);
     name(nameHw).nextNameHash = nameHash[h];
     nameHash[h]               = nameHw;
@@ -443,8 +444,11 @@ Name nm; {                              /* no clash is caused              */
 
 static Void local hashName(nm)          /* Insert Name into hash table    */
 Name nm; {
-    Text t               = name(nm).text;
-    Int  h               = nHash(t);
+    Text t;
+    Int  h;
+    assert(isName(nm));
+    t = name(nm).text;
+    h = nHash(t);
     name(nm).nextNameHash = nameHash[h];
     nameHash[h]           = nm;
 }
@@ -500,6 +504,7 @@ Name nameFromStgVar ( StgVar v )
    return NIL;
 }
 
+
 /* --------------------------------------------------------------------------
  * Primitive functions:
  * ------------------------------------------------------------------------*/
@@ -743,6 +748,7 @@ Inst newInst() {                       /* Add new instance to table        */
     inst(instHw).specifics  = NIL;
     inst(instHw).implements = NIL;
     inst(instHw).builder    = NIL;
+    inst(instHw).mod        = currentModule;
 
     return instHw++;
 }
@@ -874,10 +880,24 @@ Text t; {
     module(moduleHw).tycons        = NIL;
     module(moduleHw).names         = NIL;
     module(moduleHw).classes       = NIL;
-    module(moduleHw).objectFile    = 0;
+    module(moduleHw).oImage        = NULL;
     return moduleHw++;
 }
 
+void ppModules ( void )
+{
+   Int i;
+   fflush(stderr); fflush(stdout);
+   printf ( "begin MODULES\n" );
+   for (i = moduleHw-1; i >= MODMIN; i--)
+      printf ( " %2d: %16s\n",
+               i-MODMIN, textToStr(module(i).text)
+             );
+   printf ( "end   MODULES\n" );
+   fflush(stderr); fflush(stdout);
+}
+
+
 Module findModule(t)                    /* locate Module in module table  */
 Text t; {
     Module m;
@@ -903,6 +923,7 @@ Cell c; {
 static local Module findQualifier(t)    /* locate Module in import list   */
 Text t; {
     Module ms;
+printf ( "findQualifier %s\n", textToStr(t));
     for (ms=module(currentModule).qualImports; nonNull(ms); ms=tl(ms)) {
         if (textOf(fst(hd(ms)))==t)
             return snd(hd(ms));
@@ -929,6 +950,21 @@ Module m; {
     }
 }
 
+Name jrsFindQualName ( Text mn, Text sn )
+{
+   Module m;
+   List   ns;
+
+   for (m=MODMIN; m<moduleHw; m++)
+      if (module(m).text == mn) break;
+   if (m == moduleHw) return NIL;
+   
+   for (ns = module(m).names; nonNull(ns); ns=tl(ns)) 
+      if (name(hd(ns)).text == sn) return hd(ns);
+
+   return NIL;
+}
+
 /* --------------------------------------------------------------------------
  * Script file storage:
  *
@@ -965,6 +1001,25 @@ Int val, mx; {
 static Script scriptHw;                 /* next unused script number       */
 static script scripts[NUM_SCRIPTS];     /* storage for script records      */
 
+
+void ppScripts ( void )
+{
+   Int i;
+   fflush(stderr); fflush(stdout);
+   printf ( "begin SCRIPTS\n" );
+   for (i = scriptHw-1; i >= 0; i--)
+      printf ( " %2d: %16s  tH=%d  mH=%d  yH=%d  "
+               "nH=%d  cH=%d  iH=%d  nnS=%d,%d\n",
+               i, textToStr(scripts[i].file),
+               scripts[i].textHw, scripts[i].moduleHw,
+               scripts[i].tyconHw, scripts[i].nameHw, 
+               scripts[i].classHw, scripts[i].instHw,
+               scripts[i].nextNewText, scripts[i].nextNewDText 
+             );
+   printf ( "end   SCRIPTS\n" );
+   fflush(stderr); fflush(stdout);
+}
+
 Script startNewScript(f)                /* start new script, keeping record */
 String f; {                             /* of status for later restoration  */
     if (scriptHw >= NUM_SCRIPTS) {
@@ -1537,6 +1592,10 @@ Int  depth; {
                 Printf("Polytype");
                 print(snd(c),depth-1);
                 break;
+        case QUAL:
+                Printf("Qualtype");
+                print(snd(c),depth-1);
+                break;
         case RANK2:
                 Printf("Rank2(");
                 if (isPair(snd(c)) && isInt(fst(snd(c)))) {
@@ -1755,6 +1814,22 @@ Cell c;
     x.i = snd(c);
     return x.p;
 }
+Cell mkCPtr(p)
+Ptr p;
+{
+    IntOrPtr x;
+    x.p = p;
+    return pair(CPTRCELL,x.i);
+}
+
+Ptr cptrOf(c)
+Cell c;
+{
+    IntOrPtr x;
+    assert(fst(c) == CPTRCELL);
+    x.i = snd(c);
+    return x.p;
+}
 #elif SIZEOF_INTP == 2*SIZEOF_INT
 typedef union {struct {Int i1; Int i2;} i; Ptr p;} IntOrPtr;
 Cell mkPtr(p)
@@ -1969,7 +2044,7 @@ List xs; {
     return ys;
 }
 
-List splitAt(n,xs)                         /* drop n things from front of list*/
+List splitAt(n,xs)                      /* drop n things from front of list*/
 Int  n;       
 List xs; {
     for(; n>0; --n) {
@@ -1978,7 +2053,7 @@ List xs; {
     return xs;
 }
 
-Cell nth(n,xs)                         /* extract n'th element of list    */
+Cell nth(n,xs)                          /* extract n'th element of list    */
 Int  n;
 List xs; {
     for(; n>0 && nonNull(xs); --n, xs=tl(xs)) {
@@ -2007,6 +2082,16 @@ List xs; {
     return xs;                          /* here if element not found       */
 }
 
+List nubList(xs)                        /* nuke dups in list               */
+List xs; {                              /* non destructive                 */
+   List outs = NIL;
+   for (; nonNull(xs); xs=tl(xs))
+      if (isNull(cellIsMember(hd(xs),outs)))
+         outs = cons(hd(xs),outs);
+   outs = rev(outs);
+   return outs;
+}
+
 /* --------------------------------------------------------------------------
  * Operations on applications:
  * ------------------------------------------------------------------------*/
@@ -2188,6 +2273,7 @@ Int what; {
                            mark(name(i).defn);
                            mark(name(i).stgVar);
                            mark(name(i).type);
+                           mark(name(i).ghc_names);
                        }
                        end("Names", nameHw-NAMEMIN);
 
index 7cb8c41..861bb82 100644 (file)
@@ -9,8 +9,8 @@
  * in the distribution for details.
  *
  * $RCSfile: storage.h,v $
- * $Revision: 1.6 $
- * $Date: 1999/04/27 10:07:06 $
+ * $Revision: 1.7 $
+ * $Date: 1999/06/07 17:22:47 $
  * ------------------------------------------------------------------------*/
 
 /* --------------------------------------------------------------------------
@@ -150,12 +150,33 @@ extern  Cell         whatIs    Args((Cell));
 #define BIGCELL      16           /* Integer literal:         snd :: Text  */
 #if PTR_ON_HEAP
 #define PTRCELL      17           /* C Heap Pointer           snd :: Ptr   */
+#define CPTRCELL     18           /* Native code pointer      snd :: Ptr   */
 #endif
 #if TREX
-#define EXTCOPY      18           /* Copy of an Ext:          snd :: Text  */
+#define EXTCOPY      19           /* Copy of an Ext:          snd :: Text  */
+#endif
+
+//#define textOf(c)       ((Text)(snd(c)))         /* c ::  (VAR|CON)(ID|OP) */
+
+#if 1
+static Text textOf( Cell c )
+{
+   Bool ok = 
+          (whatIs(c)==VARIDCELL
+           || whatIs(c)==CONIDCELL
+           || whatIs(c)==VAROPCELL
+           || whatIs(c)==CONOPCELL
+           || whatIs(c)==STRCELL
+           || whatIs(c)==DICTVAR
+          );
+   if (!ok) {
+fprintf(stderr, "\ntextOf -- tag %d\n",whatIs(c) );
+      assert(ok);
+   }
+   return snd(c);
+}
 #endif
 
-#define textOf(c)       ((Text)(snd(c)))         /* c ::  (VAR|CON)(ID|OP) */
 #define qmodOf(c)       (textOf(fst(snd(c))))    /* c ::  QUALIDENT        */
 #define qtextOf(c)      (textOf(snd(snd(c))))    /* c ::  QUALIDENT        */
 #define mkVar(t)        ap(VARIDCELL,t)
@@ -195,6 +216,9 @@ extern  String           stringNegate Args((String));
 #define isPtr(c)        (isPair(c) && fst(c)==PTRCELL)
 extern  Cell            mkPtr           Args((Ptr));
 extern  Ptr             ptrOf           Args((Cell));
+#define isCPtr(c)       (isPair(c) && fst(c)==CPTRCELL)
+extern  Cell            mkCPtr          Args((Ptr));
+extern  Ptr             cptrOf          Args((Cell));
 #endif
 
 /* --------------------------------------------------------------------------
@@ -265,6 +289,9 @@ extern  Ptr             ptrOf           Args((Cell));
 #define ONLY         81           /* ONLY       snd :: Exp                 */
 #define NEG          82           /* NEG        snd :: Exp                 */
 
+/* Used when parsing GHC interface files */
+#define DICTAP       85           /* DICTTYPE   snd :: (QClassId,[Type])   */
+
 #if SIZEOF_INTP != SIZEOF_INT
 #define PTRCELL      90           /* C Heap Pointer snd :: (Int,Int)       */
 #endif
@@ -392,7 +419,10 @@ struct Module {
      * evaluating an expression in the context of the current module.
      */
     List  qualImports;
-    ObjectFile objectFile; /* usually unused */
+    /* ptr to malloc'd lump of memory holding the obj file */
+    void* oImage;
+
+
 };
 
 extern Module currentModule;           /* Module currently being processed */
@@ -416,16 +446,16 @@ extern Void   setCurrModule Args((Module));
 #define tycon(n)     tabTycon[(n)-TYCMIN]
 
 struct strTycon {
-    Text  text;
-    Int   line;
+    Text   text;
+    Int    line;
     Module mod;                         /* module that defines it          */
-    Int   arity;
-    Kind  kind;                         /* kind (includes arity) of Tycon  */
-    Cell  what;                         /* DATATYPE/SYNONYM/RESTRICTSYN... */
-    Cell  defn;
-    Name  conToTag;                     /* used in derived code            */
-    Name  tagToCon;
-    Tycon nextTyconHash;
+    Int    arity;
+    Kind   kind;                        /* kind (includes arity) of Tycon  */
+    Cell   what;                        /* DATATYPE/SYNONYM/RESTRICTSYN... */
+    Cell   defn;
+    Name   conToTag;                    /* used in derived code            */
+    Name   tagToCon;
+    Tycon  nextTyconHash;
 };
 
 extern struct strTycon DECTABLE(tabTycon);
@@ -467,6 +497,7 @@ struct strName {
     Bool   simplified;    /* TRUE => already simplified */
     Bool   isDBuilder;    /* TRUE => is a dictionary builder */
     const void*  primop;  /* really StgPrim* */
+    List   ghc_names;     /* [(Text,Ptr)] */
     Name   nextNameHash;
 };
 
@@ -511,6 +542,7 @@ extern Name   addPrimCfun     Args((Text,Int,Int,Cell));
 extern Name   addPrimCfunREP  Args((Text,Int,Int,Int));
 extern Int    sfunPos         Args((Name,Name));
 extern Name   nameFromStgVar  Args((Cell));
+extern Name   jrsFindQualName Args((Text,Text));
 
 /* --------------------------------------------------------------------------
  * Type class values:
@@ -523,15 +555,15 @@ extern Name   nameFromStgVar  Args((Cell));
 #define inst(in)     tabInst[(in)-INSTMIN]
 
 struct strInst {
-    Class c;                            /* class C                         */
-    Int   line;
-  //Module mod;                         /* module that defines it          */
-    Kinds kinds;                        /* Kinds of variables in head      */
-    Cell  head;                         /* :: Pred                         */
-    List  specifics;                    /* :: [Pred]                       */
-    Int   numSpecifics;                 /* length(specifics)               */
-    List  implements;
-    Name  builder;                      /* Dictionary constructor function */
+    Class  c;                           /* class C                         */
+    Int    line;
+    Module mod;                         /* module that defines it          */
+    Kinds  kinds;                       /* Kinds of variables in head      */
+    Cell   head;                        /* :: Pred                         */
+    List   specifics;                   /* :: [Pred]                       */
+    Int    numSpecifics;                /* length(specifics)               */
+    List   implements;
+    Name   builder;                     /* Dictionary constructor function */
 };
 
 /* a predicate (an element :: Pred) is an application of a Class to one or
@@ -646,6 +678,7 @@ extern  List         splitAt      Args((Int,List));     /* non-destructive */
 extern  Cell         nth          Args((Int,List));
 extern  List         removeCell   Args((Cell,List));    /* destructive     */
 extern  List         dupListOnto  Args((List,List));    /* non-destructive */ 
+extern  List         nubList      Args((List));         /* non-destructive */
 
 /* The following macros provide `inline expansion' of some common ways of
  * traversing, using and modifying lists:
@@ -714,7 +747,7 @@ extern  StackPtr sp;
     chkStack(1);     \
     onto(c);         \
   } while (0)
-#define onto(c)      stack(++sp)=(c)
+#define onto(c)      stack(++sp)=(c);
 #define pop()        stack(sp--)
 #define drop()       sp--
 #define top()        stack(sp)
index d9913e9..ff794f7 100644 (file)
@@ -8,8 +8,8 @@
  * in the distribution for details.
  *
  * $RCSfile: type.c,v $
- * $Revision: 1.6 $
- * $Date: 1999/04/27 10:07:09 $
+ * $Revision: 1.7 $
+ * $Date: 1999/06/07 17:22:31 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
@@ -724,8 +724,6 @@ Cell e; {                               /* requires polymorphism, qualified*/
     Cell p = NIL;
     Cell a = e;
     Int  i;
-    //print(h,1000);
-    //printf("\n");
 
     switch (whatIs(h)) {
         case NAME      : typeIs = name(h).type;
@@ -757,9 +755,6 @@ Cell e; {                               /* requires polymorphism, qualified*/
     }
 
     if (isNull(typeIs)) {
-        //printf("\n NAME " );
-        //print(h,1000);
-        //printf(" TYPE " ); print(typeIs,1000);
         internal("typeAp1");
     }
 
@@ -1709,7 +1704,7 @@ Class c; {                              /* defaults for class c            */
         body = ap(LETREC,pair(singleton(locs),body));
     name(cclass(c).dbuild).defn
              = singleton(pair(args,body));
-    //--------- Default
+
     name(cclass(c).dbuild).inlineMe = TRUE;
     genDefns = cons(cclass(c).dbuild,genDefns);
     cclass(c).defaults = NIL;
@@ -1854,7 +1849,7 @@ Inst in; {                              /* member functions for instance in*/
 
     name(inst(in).builder).defn                 /* Register builder imp    */
              = singleton(pair(args,ap(LETREC,pair(singleton(locs),d))));
-    //--------- Actual
+
     name(inst(in).builder).inlineMe   = TRUE;
     name(inst(in).builder).isDBuilder = TRUE;
     genDefns = cons(inst(in).builder,genDefns);
@@ -2250,11 +2245,6 @@ Void typeCheckDefns() {                /* Type check top level bindings    */
 static Void local typeDefnGroup(bs)     /* type check group of value defns */
 List bs; {                              /* (one top level scc)             */
     List as;
-    // printf("\n\n+++ DefnGroup ++++++++++++++++++++++++++++\n");
-    //{ List qq; for (qq=bs;nonNull(qq);qq=tl(qq)){
-    //   print(hd(qq),4);
-    //   printf("\n");
-    //}}
 
     emptySubstitution();
     hd(defnBounds) = NIL;