[project @ 2000-01-12 14:47:27 by sewardj]
[ghc-hetmet.git] / ghc / interpreter / hugs.c
index f1272c6..57a8fd4 100644 (file)
@@ -9,8 +9,8 @@
  * included in the distribution.
  *
  * $RCSfile: hugs.c,v $
- * $Revision: 1.24 $
- * $Date: 1999/11/25 10:19:16 $
+ * $Revision: 1.36 $
+ * $Date: 2000/01/12 14:47:27 $
  * ------------------------------------------------------------------------*/
 
 #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
@@ -302,9 +307,22 @@ 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");
+   if (combined) addStackEntry("PrelHugs");
 
-   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) {
@@ -338,12 +356,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");
+    }
+
+    if (combined) {
+        Printf("Combined mode: Restart with command line -c for standalone mode\n\n" );
     } else {
-        Printf("Hugs mode: Restart with command line option +98 for Haskell 98 mode\n\n");
+        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) {
@@ -571,6 +596,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 );
@@ -609,7 +644,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;
@@ -768,14 +803,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}
 };
 
@@ -860,8 +888,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;
    }
@@ -871,11 +899,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);
@@ -895,12 +926,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    */
@@ -935,6 +966,7 @@ String s; {                            /* to be read in ...                */
 /* Return TRUE if no imports were needed; FALSE otherwise. */
 static Bool local addScript(stacknum)   /* read single file                */
 Int stacknum; {
+   Bool didPrelude;
    static char name[FILENAME_MAX+1];
    Int len = scriptInfo[stacknum].size;
 
@@ -945,17 +977,22 @@ 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) {
+         didPrelude = processInterfaces();
+         if (didPrelude) {
+            preludeLoaded = TRUE;
+            everybody(POSTPREL);
+         }
+      }
       lastWasObject = FALSE;
       Printf("Reading script \"%s\":\n",name);
       needsImports = FALSE;
@@ -965,6 +1002,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;
@@ -975,14 +1018,21 @@ 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;
+
    return TRUE;
 }
 
@@ -1103,6 +1153,7 @@ 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];
+    Bool didPrelude;
 
     lastWasObject = FALSE;
     ppSmStack("readscripts-begin");
@@ -1145,7 +1196,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);
@@ -1159,7 +1210,7 @@ Int n; {                                /* loading everything after and    */
     //numScripts = 0;
 
     while (numScripts < namesUpto) {
-ppSmStack ( "readscripts-loop2" );
+       ppSmStack ( "readscripts-loop2" );
 
        if (scriptInfo[numScripts].fromSource) {
 
@@ -1168,7 +1219,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);
@@ -1186,24 +1237,34 @@ 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") ;
+    }
+
+    didPrelude = processInterfaces();
+    if (didPrelude) {
+       preludeLoaded = TRUE;
+       everybody(POSTPREL);
     }
 
-    finishInterfaces();
 
     { Int  m     = namesUpto-1;
       Text mtext = findText(scriptInfo[m].modName);
+
+      /* Hack to avoid starting up in PrelHugs */
+      if (mtext == findText("PrelHugs")) mtext = findText("Prelude");
+
+
       /* Commented out till we understand what
        * this is trying to do.
        * Problem, you cant find a module till later.
@@ -1330,6 +1391,7 @@ static Void local evaluator() {        /* evaluate expr and print value    */
     checkExp();
     defaultDefns = evalDefaults;
     type         = typeCheckExp(TRUE);
+
     if (isPolyType(type)) {
         ks = polySigOf(type);
         bd = monotypeOf(type);
@@ -1351,7 +1413,7 @@ static Void local evaluator() {        /* evaluate expr and print value    */
 
 #if 1
     if (isProgType(ks,bd)) {
-        inputExpr = ap(nameRunIO,inputExpr);
+        inputExpr = ap(nameRunIO_toplevel,inputExpr);
         evalExp();
         Putchar('\n');
     } else {
@@ -1363,9 +1425,9 @@ static Void local evaluator() {        /* evaluate expr and print value    */
             ERRTEXT   "\n"
             EEND;
         }
-        inputExpr = ap2(findName(findText("show")),d,inputExpr);
-        inputExpr = ap(findName(findText("putStr")), inputExpr);
-        inputExpr = ap(nameRunIO, inputExpr);
+        inputExpr = ap2(nameShow,           d,inputExpr);
+        inputExpr = ap (namePutStr,         inputExpr);
+        inputExpr = ap (nameRunIO_toplevel, inputExpr);
 
         evalExp(); printf("\n");
         if (addType) {
@@ -1769,7 +1831,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)) {
@@ -2360,8 +2422,11 @@ FILE* fp; {
 
 Void everybody(what)            /* send command `what' to each component of*/
 Int what; {                     /* system to respond as appropriate ...    */
+#if 0
+  fprintf ( stderr, "EVERYBODY %d\n", what );
+#endif
     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);