[project @ 2000-01-05 18:05:33 by sewardj]
[ghc-hetmet.git] / ghc / interpreter / hugs.c
index 80c4921..111f1bc 100644 (file)
@@ -9,8 +9,8 @@
  * included in the distribution.
  *
  * $RCSfile: hugs.c,v $
- * $Revision: 1.22 $
- * $Date: 1999/11/23 09:59:38 $
+ * $Revision: 1.31 $
+ * $Date: 2000/01/05 18:05:33 $
  * ------------------------------------------------------------------------*/
 
 #include <setjmp.h>
@@ -29,7 +29,7 @@
 #include "Rts.h"
 #include "RtsAPI.h"
 #include "Schedule.h"
-
+#include "Assembler.h"                                /* DEBUG_LoadSymbols */
 
 Bool haskell98 = TRUE;                  /* TRUE => Haskell 98 compatibility*/
 
@@ -97,6 +97,8 @@ static Void   local browse          Args((Void));
  * Machine dependent code for Hugs interpreter:
  * ------------------------------------------------------------------------*/
 
+       Bool   combined      = TRUE;
+
 #include "machdep.c"
 #ifdef WANT_TIMER
 #include "timer.c"
@@ -106,14 +108,15 @@ static Void   local browse              Args((Void));
  * Local data areas:
  * ------------------------------------------------------------------------*/
 
-static Bool   printing     = FALSE;     /* TRUE => currently printing value*/
-static Bool   showStats    = FALSE;     /* TRUE => print stats after eval  */
-static Bool   listScripts  = TRUE;      /* TRUE => list scripts after loading*/
-static Bool   addType      = FALSE;     /* TRUE => print type with value   */
-static Bool   useDots      = RISCOS;    /* TRUE => use dots in progress    */
-static Bool   quiet        = FALSE;     /* TRUE => don't show progress     */
+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   useDots       = RISCOS;   /* TRUE => use dots in progress    */
+static Bool   quiet         = FALSE;    /* TRUE => don't show progress     */
 static Bool   lastWasObject = FALSE;
        Bool   preludeLoaded = FALSE;
+       Bool   debugSC       = FALSE;
 
 typedef 
    struct { 
@@ -155,6 +158,8 @@ static Int    hpSize     = DEFAULTHEAP; /* Desired heap size               */
        String hugsEdit   = 0;           /* String for editor command       */
        String hugsPath   = 0;           /* String for file search path     */
 
+       List  ifaces_outstanding = NIL;
+
 #if REDIRECT_OUTPUT
 static Bool disableOutput = FALSE;      /* redirect output to buffer?      */
 #endif
@@ -224,17 +229,13 @@ char *argv[]; {
 
     CStackBase = &argc;                 /* Save stack base for use in gc   */
 
-    /* Try and figure out an absolute path to the executable, so
-       we can make a reasonable guess about where the default
-       libraries (Prelude etc) are.
-    */
-    setDefaultLibDir ( argv[0] );
-
     /* If first arg is +Q or -Q, be entirely silent, and automatically run
        main after loading scripts.  Useful for running the nofib suite.    */
     if (argc > 1 && (strcmp(argv[1],"+Q") == 0 || strcmp(argv[1],"-Q")==0)) {
        autoMain = TRUE;
-       hugsEnableOutput(0);
+       if (strcmp(argv[1],"-Q") == 0) {
+        hugsEnableOutput(0);
+       }
     }
 
     Printf("__   __ __  __  ____   ___      _________________________________________\n");
@@ -244,6 +245,13 @@ char *argv[]; {
     Printf("||   ||                         Report bugs to: hugs-bugs@haskell.org\n");
     Printf("||   || Version: %s _________________________________________\n\n",HUGS_VERSION);
 
+    /* Get the absolute path to the directory containing the hugs 
+       executable, so that we know where the Prelude and nHandle.so/.dll are.
+       We do this by reading env var STGHUGSDIR.  This needs to succeed, so
+       setInstallDir won't return unless it succeeds.
+    */
+    setInstallDir ( argv[0] );
+
 #if SYMANTEC_C
     Printf("   Ported to Macintosh by Hans Aberg, compiled " __DATE__ ".\n\n");
 #endif
@@ -299,9 +307,21 @@ String argv[]; {
    argc = prog_argc; argv = prog_argv;
 
    namesUpto = numScripts = 0;
+
+   /* Pre-scan flags to see if -c or +c is present.  This needs to
+      precede adding the stack entry for Prelude.  On the other hand,
+      that stack entry needs to be made before the cmd line args are
+      properly examined.  Hence the following pre-scan of them.
+   */
+   for (i=1; i < argc; ++i) {
+      if (strcmp(argv[i], "--")==0) break;
+      if (strcmp(argv[i], "-c")==0) combined = FALSE;
+      if (strcmp(argv[i], "+c")==0) combined = TRUE;
+   }
+
    addStackEntry("Prelude");
 
-   for (i=1; i<argc; ++i) {            /* process command line arguments  */
+   for (i=1; i < argc; ++i) {            /* process command line arguments  */
         if (strcmp(argv[i], "--")==0) break;
         if (strcmp(argv[i],"+")==0 && i+1<argc) {
             if (proj) {
@@ -317,7 +337,12 @@ String argv[]; {
     }
 
 #if DEBUG
-    DEBUG_LoadSymbols(argv_0_orig);
+    { 
+       char exe_name[N_INSTALLDIR + 6];
+       strcpy(exe_name, installDir);
+       strcat(exe_name, "hugs");
+       DEBUG_LoadSymbols(exe_name);
+    }
 #endif
 
 
@@ -330,12 +355,19 @@ String argv[]; {
 #endif
 
     if (haskell98) {
-        Printf("Haskell 98 mode: Restart with command line option -98 to enable extensions\n\n");
+        Printf("Haskell 98 mode: Restart with command line option -98 to enable extensions\n");
     } else {
-        Printf("Hugs mode: Restart with command line option +98 for Haskell 98 mode\n\n");
+        Printf("Hugs mode: Restart with command line option +98 for Haskell 98 mode\n");
+    }
+
+    if (combined) {
+        Printf("Combined mode: Restart with command line -c for standalone mode\n\n" );
+    } else {
+        Printf("Standalone mode: Restart with command line +c for combined mode\n\n" );
     }
  
-    everybody(INSTALL);
+    everybody(PREPREL);
+
     evalModule = findText("");      /* evaluate wrt last module by default */
     if (proj) {
         if (namesUpto>1) {
@@ -563,6 +595,16 @@ String s; {                             /* return FALSE if none found.     */
             case 'h' : setHeapSize(s+1);
                        return TRUE;
 
+            case 'c' : if (heapBuilt()) {
+                          FPrintf(stderr, 
+                                  "You can't enable/disable combined"
+                                  " operation inside Hugs\n" );
+                       } else {
+                         /* don't do anything, since pre-scan of args
+                             will have got it already */
+                       }
+                       return TRUE;
+
             case 'D' : /* hack */
                 {
                     extern void setRtsFlags( int x );
@@ -601,7 +643,7 @@ String s; {
 #if USE_REGISTRY
             FPrintf(stderr,"Change to heap size will not take effect until you rerun Hugs\n");
 #else
-            FPrintf(stderr,"Cannot change heap size\n");
+            FPrintf(stderr,"You cannot change heap size from inside Hugs\n");
 #endif
         } else {
             heapSize = hpSize;
@@ -760,14 +802,7 @@ struct options toggle[] = {             /* List of command line toggles    */
 #if DEBUG_CODE
     {'D', 1, "Debug: show generated G code",          &debugCode},
 #endif
-#if DEBUG_SHOWSC
     {'S', 1, "Debug: show generated SC code",         &debugSC},
-#endif
-#if 0
-    {'f', 1, "Terminate evaluation on first error",   &failOnError},
-    {'u', 1, "Use \"show\" to display results",       &useShow},
-    {'i', 1, "Chase imports while loading modules",   &chaseImports}, 
-#endif
     {0,   0, 0,                                       0}
 };
 
@@ -852,8 +887,8 @@ static Void local makeStackEntry ( ScriptInfo* ent, String iname )
         );
    if (!ok) {
       ERRMSG(0) 
-       /* "Can't file source or object+interface for module \"%s\"", */
-         "Can't file source for module \"%s\"",
+         "Can't find source or object+interface for module \"%s\"",
+         /* "Can't find source for module \"%s\"", */
          iname
       EEND;
    }
@@ -863,11 +898,14 @@ static Void local makeStackEntry ( ScriptInfo* ent, String iname )
    /* Load objects in preference to sources if both are available */
    /* 11 Oct 99: disable object loading in the interim.
       Will probably only reinstate when HEP becomes available.
-   fromObj = sAvail
+   */
+   if (combined) {
+      fromObj = sAvail
                 ? (oAvail && iAvail && timeEarlier(sTime,oTime))
                 : TRUE;
-   */
-   fromObj = FALSE;
+   } else {
+      fromObj = FALSE;
+   }
 
    /* ToDo: namesUpto overflow */
    ent->modName     = strCopy(iname);
@@ -887,12 +925,12 @@ static Void local makeStackEntry ( ScriptInfo* ent, String iname )
 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;
+    if (l > 4 && strncmp(s+l-4,".u_o" ,4)==0) s[l-4] = 0; else
+    if (l > 5 && strncmp(s+l-5,".u_hi",5)==0) s[l-5] = 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    */
@@ -937,17 +975,16 @@ Int stacknum; {
 
     //   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");
+      strcat(name, ".u_hi");
 
    scriptFile = name;
 
    if (scriptInfo[stacknum].fromSource) {
-      if (lastWasObject) finishInterfaces();
+      if (lastWasObject) processInterfaces();
       lastWasObject = FALSE;
       Printf("Reading script \"%s\":\n",name);
       needsImports = FALSE;
@@ -957,6 +994,12 @@ Int stacknum; {
       typeCheckDefns();
       compileDefns();
    } else {
+      Cell    iface;
+      List    imports;
+      ZTriple iface_info;
+      char    nameObj[FILENAME_MAX+1];
+      Int     sizeObj;
+
       Printf("Reading  iface \"%s\":\n", name);
       scriptFile = name;
       needsImports = FALSE;
@@ -967,14 +1010,25 @@ Int stacknum; {
       strcat(nameObj, DLL_ENDING);
       sizeObj = scriptInfo[stacknum].oSize;
 
-      loadInterface(name,len);
+      iface = readInterface(name,len);
+      imports = zsnd(iface); iface = zfst(iface);
+
+      if (nonNull(imports)) chase(imports);
       scriptFile = 0;
       lastWasObject = TRUE;
+
+      iface_info = ztriple(iface, findText(nameObj), mkInt(sizeObj) );
+      ifaces_outstanding = cons(iface_info,ifaces_outstanding);
+
       if (needsImports) return FALSE;
    }
  
    scriptFile = 0;
-   preludeLoaded = TRUE;
+
+   if (strcmp(scriptInfo[stacknum].modName, "Prelude")==0) {
+      preludeLoaded = TRUE;
+      everybody(POSTPREL);
+   }
    return TRUE;
 }
 
@@ -1137,7 +1191,7 @@ Int n; {                                /* loading everything after and    */
         strcat(name, scriptInfo[n].modName);
         if (scriptInfo[n].fromSource)
            strcat(name, scriptInfo[n].srcExt); else
-           strcat(name, ".hi");  //ToDo: should be .o
+           strcat(name, ".u_hi");  //ToDo: should be .o
         getFileInfo(name,&timeStamp, &fileSize);
         if (timeChanged(timeStamp,scriptInfo[n].lastChange)) {
            dropScriptsFrom(n-1);
@@ -1151,7 +1205,7 @@ Int n; {                                /* loading everything after and    */
     //numScripts = 0;
 
     while (numScripts < namesUpto) {
-ppSmStack ( "readscripts-loop2" );
+       ppSmStack ( "readscripts-loop2" );
 
        if (scriptInfo[numScripts].fromSource) {
 
@@ -1160,7 +1214,7 @@ ppSmStack ( "readscripts-loop2" );
           nextNumScripts = NUM_SCRIPTS; //bogus initialisation
           if (addScript(numScripts)) {
              numScripts++;
-assert(nextNumScripts==NUM_SCRIPTS);
+             assert(nextNumScripts==NUM_SCRIPTS);
           }
           else
              dropScriptsFrom(numScripts-1);
@@ -1178,21 +1232,21 @@ assert(nextNumScripts==NUM_SCRIPTS);
              nextNumScripts = NUM_SCRIPTS;
              if (addScript(numScripts)) {
                 numScripts++;
-assert(nextNumScripts==NUM_SCRIPTS);
+                assert(nextNumScripts==NUM_SCRIPTS);
              } else {
                //while (!scriptInfo[numScripts].fromSource && numScripts > 0)
                //   numScripts--;
                //if (scriptInfo[numScripts].fromSource)
                //   numScripts++;
                 numScripts = nextNumScripts;
-assert(nextNumScripts<NUM_SCRIPTS);
+                assert(nextNumScripts<NUM_SCRIPTS);
              }
           }
        }
-if (numScripts==namesUpto) ppSmStack( "readscripts-final") ;
+       if (numScripts==namesUpto) ppSmStack( "readscripts-final") ;
     }
 
-    finishInterfaces();
+    processInterfaces();
 
     { Int  m     = namesUpto-1;
       Text mtext = findText(scriptInfo[m].modName);
@@ -1342,7 +1396,7 @@ static Void local evaluator() {        /* evaluate expr and print value    */
 #endif
 
 #if 1
-    if (typeMatches(type,ap(typeIO,typeUnit))) {
+    if (isProgType(ks,bd)) {
         inputExpr = ap(nameRunIO,inputExpr);
         evalExp();
         Putchar('\n');
@@ -1761,7 +1815,7 @@ Text t; {
         } else {
             Printf("<unknown type>");
         }
-
+printf("\n");print(name(nm).type,10);printf("\n");
         if (isCfun(nm)) {
             Printf("  -- data constructor");
         } else if (isMfun(nm)) {
@@ -2352,8 +2406,9 @@ FILE* fp; {
 
 Void everybody(what)            /* send command `what' to each component of*/
 Int what; {                     /* system to respond as appropriate ...    */
+fprintf ( stderr, "EVERYBODY %d\n", what );
     machdep(what);              /* The order of calling each component is  */
-    storage(what);              /* important for the INSTALL command       */
+    storage(what);              /* important for the PREPREL command       */
     substitution(what);
     input(what);
     translateControl(what);