[project @ 2000-03-22 18:14:22 by sewardj]
[ghc-hetmet.git] / ghc / interpreter / link.c
index bb42e1c..5ef79e4 100644 (file)
@@ -9,18 +9,17 @@
  * included in the distribution.
  *
  * $RCSfile: link.c,v $
- * $Revision: 1.40 $
- * $Date: 2000/02/08 15:32:30 $
+ * $Revision: 1.53 $
+ * $Date: 2000/03/22 18:14:22 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
 #include "storage.h"
-#include "backend.h"
 #include "connect.h"
 #include "errors.h"
-#include "Assembler.h" /* for asmPrimOps and AsmReps */
-
-#include "link.h"
+#include "Assembler.h"                  /* for asmPrimOps and AsmReps      */
+#include "Rts.h"                        /* to make Prelude.h palatable     */
+#include "Prelude.h"                    /* for fixupRTStoPreludeRefs       */
 
 
 Type typeArrow;                         /* Function spaces                 */
@@ -96,9 +95,7 @@ Name namePrint;
 
 Name nameOtherwise;
 Name nameUndefined;                     /* generic undefined value         */
-#if NPLUSK
 Name namePmSub; 
-#endif
 Name namePMFail;
 Name nameEqChar;
 Name namePmInt;
@@ -136,6 +133,17 @@ Name nameFrom;
 Name nameFromThenTo;
 Name nameNegate;
 
+Name nameAssert;
+Name nameAssertError;
+Name nameTangleMessage;
+Name nameIrrefutPatError;
+Name nameNoMethodBindingError;
+Name nameNonExhaustiveGuardsError;
+Name namePatError;
+Name nameRecSelError;
+Name nameRecConError;
+Name nameRecUpdError;
+
 /* these names are required before we've had a chance to do the right thing */
 Name nameSel;
 Name nameUnsafeUnpackCString;
@@ -273,7 +281,7 @@ static Name predefinePrim ( String s )
  * 
  * ------------------------------------------------------------------------*/
 
-/* In standalone mode, linkPreludeTC, linkPreludeCM and linkPreludeNames
+/* In standalone mode, linkPreludeTC, linkPreludeCM and linkPrimNames
    are called, in that order, during static analysis of Prelude.hs.
    In combined mode such an analysis does not happen.  Instead these
    calls will be made as a result of a call link(POSTPREL).
@@ -336,11 +344,7 @@ Void linkPreludeTC(void) {              /* Hook to tycons and classes in   */
 
         stdDefaults              = NIL;
         stdDefaults              = cons(typeDouble,stdDefaults);
-#       if DEFAULT_BIGNUM
         stdDefaults              = cons(typeInteger,stdDefaults);
-#       else
-        stdDefaults              = cons(typeInt,stdDefaults);
-#       endif
 
         predNum                  = ap(classNum,aVar);
         predFractional           = ap(classFractional,aVar);
@@ -371,14 +375,16 @@ Void linkPreludeTC(void) {              /* Hook to tycons and classes in   */
         nameMkPrimMVar           = addPrimCfunREP(findText("MVar#"),1,0,0);
         nameMkInteger            = addPrimCfunREP(findText("Integer#"),1,0,0);
 
-        name(namePrimSeq).type   = primType(MONAD_Id, "ab", "b");
-        name(namePrimCatch).type = primType(MONAD_Id, "aH", "a");
-        name(namePrimRaise).type = primType(MONAD_Id, "E", "a");
-
-        /* This is a lie.  For a more accurate type of primTakeMVar
-           see ghc/interpreter/lib/Prelude.hs.
-       */
-        name(namePrimTakeMVar).type = primType(MONAD_Id, "rbc", "d");
+        if (!combined) {
+           name(namePrimSeq).type   = primType(MONAD_Id, "ab", "b");
+           name(namePrimCatch).type = primType(MONAD_Id, "aH", "a");
+           name(namePrimRaise).type = primType(MONAD_Id, "E", "a");
+
+           /* This is a lie.  For a more accurate type of primTakeMVar
+              see ghc/interpreter/lib/Prelude.hs.
+          */
+           name(namePrimTakeMVar).type = primType(MONAD_Id, "rbc", "d");
+        }
 
         if (!combined) {
            for (i=2; i<=NUM_DTUPLES; i++) {/* Add derived instances of tuples */
@@ -409,9 +415,9 @@ Void linkPreludeCM(void) {              /* Hook to cfuns and mfuns in      */
         nameEq           = linkName("==");
         nameFromInt      = linkName("fromInt");
         nameFromInteger  = linkName("fromInteger");
-        nameFromDouble   = linkName("fromDouble");
         nameReturn       = linkName("return");
         nameBind         = linkName(">>=");
+       nameMFail        = linkName("fail");
         nameLe           = linkName("<=");
         nameGt           = linkName(">");
         nameShowsPrec    = linkName("showsPrec");
@@ -436,10 +442,10 @@ Void linkPreludeCM(void) {              /* Hook to cfuns and mfuns in      */
     }
 }
 
-Void linkPreludeNames(void) {           /* Hook to names defined in Prelude */
+Void linkPrimNames ( void ) {        /* Hook to names defined in Prelude */
     static Bool initialised = FALSE;
+
     if (!initialised) {
-        Int i;
         initialised = TRUE;
 
         setCurrModule(modulePrelude);
@@ -448,22 +454,29 @@ Void linkPreludeNames(void) {           /* Hook to names defined in Prelude */
         nameMkIO           = linkName("hugsprimMkIO");
 
         if (!combined) {
-           for (i=0; asmPrimOps[i].name; ++i) {
-               Text t = findText(asmPrimOps[i].name);
-               Name n = findName(t);
-               if (isNull(n)) {
-                   n = newName(t,NIL);
-               }
-               name(n).line   = 0;
-               name(n).defn   = NIL;
-               name(n).type   = primType(asmPrimOps[i].monad,
-                                         asmPrimOps[i].args,
-                                         asmPrimOps[i].results);
-               name(n).arity  = strlen(asmPrimOps[i].args);
-               name(n).primop = &(asmPrimOps[i]);
-               implementPrim(n);
-           }
+         Int i;
+         for (i=0; asmPrimOps[i].name; ++i) {
+           Text t = findText(asmPrimOps[i].name);
+           Name n = findName(t);
+           if (isNull(n)) {
+             n = newName(t,NIL);
+             name(n).line   = 0;
+             name(n).defn   = NIL;
+             name(n).type   = primType(asmPrimOps[i].monad,
+                                       asmPrimOps[i].args,
+                                       asmPrimOps[i].results);
+             name(n).arity  = strlen(asmPrimOps[i].args);
+             name(n).primop = &(asmPrimOps[i]);
+             implementPrim(n);
+           } else {
+             ERRMSG(0) "Link Error in Prelude, surplus definition of \"%s\"", 
+                               asmPrimOps[i].name
+              EEND;          
+             // Name already defined!
+           }
+         }
         }
+
         /* static(tidyInfix)                        */
         nameNegate         = linkName("negate");
         /* user interface                           */
@@ -475,17 +488,17 @@ Void linkPreludeNames(void) {           /* Hook to names defined in Prelude */
         nameOtherwise      = linkName("otherwise");
         nameUndefined      = linkName("undefined");
         /* pmc                                      */
-#       if NPLUSK                      
         namePmSub          = linkName("hugsprimPmSub");
-#       endif                          
         /* translator                               */
         nameEqChar         = linkName("hugsprimEqChar");
         nameCreateAdjThunk = linkName("hugsprimCreateAdjThunk");
         namePmInt          = linkName("hugsprimPmInt");
         namePmInteger      = linkName("hugsprimPmInteger");
         namePmDouble       = linkName("hugsprimPmDouble");
+
+        nameFromDouble     = linkName("fromDouble");
         namePmFromInteger = linkName("hugsprimPmFromInteger");
+
         namePmSubtract    = linkName("hugsprimPmSubtract");
         namePmLe          = linkName("hugsprimPmLe");
 
@@ -515,13 +528,15 @@ Int what; {
                        break;
 
         case POSTPREL: {
+           Name nm;
            Module modulePrelBase = findModule(findText("PrelBase"));
            assert(nonNull(modulePrelBase));
-          fprintf(stderr, "linkControl(POSTPREL)\n");
+          /* fprintf(stderr, "linkControl(POSTPREL)\n"); */
            setCurrModule(modulePrelude);
            linkPreludeTC();
            linkPreludeCM();
-           linkPreludeNames();
+           linkPrimNames();
+           fixupRTStoPreludeRefs ( lookupObjName );
 
            nameUnpackString = linkName("hugsprimUnpackString");
            namePMFail       = linkName("hugsprimPmFail");
@@ -530,7 +545,7 @@ assert(nonNull(namePMFail));
 
 
                /* pmc                                   */
-               xyzzy(nameSel,            "_SEL");
+               pFun(nameSel,            "_SEL");
 
                /* strict constructors                   */
                xyzzy(nameFlip,           "flip"     );
@@ -543,9 +558,9 @@ assert(nonNull(namePMFail));
 
                /* deriving                              */
                xyzzy(nameApp,            "++");
-               xyzzy(nameReadField,      "readField");
+               xyzzy(nameReadField,      "hugsprimReadField");
                xyzzy(nameReadParen,      "readParen");
-               xyzzy(nameShowField,      "showField");
+               xyzzy(nameShowField,      "hugsprimShowField");
                xyzzy(nameShowParen,      "showParen");
                xyzzy(nameLex,            "lex");
                xyzzy(nameComp,           ".");
@@ -556,6 +571,7 @@ assert(nonNull(namePMFail));
                /* implementTagToCon                     */
                xyzzy(nameError,          "hugsprimError");
 
+
            typeStable = linkTycon("Stable");
            typeRef    = linkTycon("IORef");
            // {Prim,PrimByte,PrimMutable,PrimMutableByte}Array ?
@@ -564,6 +580,52 @@ assert(nonNull(namePMFail));
            ifLinkConstrItbl ( nameTrue );
            ifLinkConstrItbl ( nameNil );
            ifLinkConstrItbl ( nameCons );
+
+           /* PrelErr.hi doesn't give a type for error, alas.  
+              So error never appears in any symbol table.
+              So we fake it by copying the table entry for
+              hugsprimError -- which is just a call to error.
+              Although we put it on the Prelude export list, we
+              have to claim internally that it lives in PrelErr, 
+              so that the correct symbol (PrelErr_error_closure)
+              is referred to.
+              Big Big Sigh.
+           */
+           nm            = newName ( findText("error"), NIL );
+           name(nm)      = name(nameError);
+           name(nm).mod  = findModule(findText("PrelErr"));
+           name(nm).text = findText("error");
+           setCurrModule(modulePrelude);
+           module(modulePrelude).exports
+              = cons ( nm, module(modulePrelude).exports );
+
+           /* The GHC prelude doesn't seem to export Addr.  Add it to the
+              export list for the sake of compatibility with standalone mode.
+          */
+           module(modulePrelude).exports
+              = cons ( pair(typeAddr,DOTDOT), 
+                       module(modulePrelude).exports );
+           addTycon(typeAddr);
+
+           /* Make nameListMonad be the builder fn for instance Monad [].
+              Standalone hugs does this with a disgusting hack in 
+              checkInstDefn() in static.c.  We have a slightly different
+              disgusting hack for the combined case.
+           */
+           {
+           Class cm;   /* :: Class   */
+           List  is;   /* :: [Inst]  */
+           cm = findClassInAnyModule(findText("Monad"));
+           assert(nonNull(cm));
+           is = cclass(cm).instances;
+           assert(nonNull(is));
+           while (nonNull(is) && snd(inst(hd(is)).head) != typeList)
+              is = tl(is);
+           assert(nonNull(is));
+           nameListMonad = inst(hd(is)).builder;
+           assert(nonNull(nameListMonad));
+           }
+
            break;
         }
         case PREPREL : 
@@ -572,29 +634,36 @@ assert(nonNull(namePMFail));
                Module modulePrelBase;
 
                modulePrelude = findFakeModule(textPrelude);
-               module(modulePrelude).objectExtraNames 
-                  = singleton(findText("libHS_cbits"));
 
-               nameMkC = addWiredInBoxingTycon("PrelBase", "Char",  "C#",CHAR_REP,   STAR );
-               nameMkI = addWiredInBoxingTycon("PrelBase", "Int",   "I#",INT_REP,    STAR );
-               nameMkW = addWiredInBoxingTycon("PrelAddr", "Word",  "W#",WORD_REP,   STAR );
-               nameMkA = addWiredInBoxingTycon("PrelAddr", "Addr",  "A#",ADDR_REP,   STAR );
-               nameMkF = addWiredInBoxingTycon("PrelFloat","Float", "F#",FLOAT_REP,  STAR );
-               nameMkD = addWiredInBoxingTycon("PrelFloat","Double","D#",DOUBLE_REP, STAR );
+               nameMkC = addWiredInBoxingTycon("PrelBase", "Char",  "C#",
+                                               CHAR_REP,   STAR );
+               nameMkI = addWiredInBoxingTycon("PrelBase", "Int",   "I#",
+                                               INT_REP,    STAR );
+               nameMkW = addWiredInBoxingTycon("PrelAddr", "Word",  "W#",
+                                               WORD_REP,   STAR );
+               nameMkA = addWiredInBoxingTycon("PrelAddr", "Addr",  "A#",
+                                               ADDR_REP,   STAR );
+               nameMkF = addWiredInBoxingTycon("PrelFloat","Float", "F#",
+                                               FLOAT_REP,  STAR );
+               nameMkD = addWiredInBoxingTycon("PrelFloat","Double","D#",
+                                               DOUBLE_REP, STAR );
                nameMkInteger            
-                       = addWiredInBoxingTycon("PrelNum","Integer","Integer#",0 ,STAR );
+                       = addWiredInBoxingTycon("PrelNum","Integer","Integer#",
+                                               0 ,STAR );
                nameMkPrimByteArray      
-                       = addWiredInBoxingTycon("PrelGHC","ByteArray","PrimByteArray#",0 ,STAR );
+                       = addWiredInBoxingTycon("PrelGHC","ByteArray",
+                                               "PrimByteArray#",0 ,STAR );
 
                for (i=0; i<NUM_TUPLES; ++i) {
                    if (i != 1) addTupleTycon(i);
                }
               addWiredInEnumTycon("PrelBase","Bool",
-                                   doubleton(findText("False"),findText("True")));
+                                   doubleton(findText("False"),
+                                             findText("True")));
 
                //nameMkThreadId
-               //        = addWiredInBoxingTycon("PrelConc","ThreadId","ThreadId#"
-               //                                ,1,0,THREADID_REP);
+               //   = addWiredInBoxingTycon("PrelConc","ThreadId","ThreadId#"
+               //                           ,1,0,THREADID_REP);
 
                setCurrModule(modulePrelude);
 
@@ -612,13 +681,18 @@ assert(nonNull(namePMFail));
                   nameId. 
                */
                modulePrelBase = findModule(findText("PrelBase"));
+               module(modulePrelBase).objectExtraNames 
+                  = singleton(findText("libHS_cbits"));
+
                setCurrModule(modulePrelBase);
                pFun(nameId,             "id");
                setCurrModule(modulePrelude);
 
            } else {
+               fixupRTStoPreludeRefs(NULL);
 
-               modulePrelude = newModule(textPrelude);
+               modulePrelude = //newModule(textPrelude);
+                               findFakeModule(textPrelude);
                setCurrModule(modulePrelude);
         
                for (i=0; i<NUM_TUPLES; ++i) {
@@ -651,9 +725,9 @@ assert(nonNull(namePMFail));
 
                /* deriving                              */
                pFun(nameApp,            "++");
-               pFun(nameReadField,      "readField");
+               pFun(nameReadField,      "hugsprimReadField");
                pFun(nameReadParen,      "readParen");
-               pFun(nameShowField,      "showField");
+               pFun(nameShowField,      "hugsprimShowField");
                pFun(nameShowParen,      "showParen");
                pFun(nameLex,            "lex");
                pFun(nameComp,           ".");
@@ -666,6 +740,21 @@ assert(nonNull(namePMFail));
                pFun(nameError,          "error");
                pFun(nameUnpackString,   "hugsprimUnpackString");
 
+              /* assertion and exception issues */
+              pFun(nameAssert,         "assert");
+              pFun(nameAssertError,    "assertError");
+              pFun(nameTangleMessage,  "tangleMessager");
+              pFun(nameIrrefutPatError,        
+                                       "irrefutPatError");
+              pFun(nameNoMethodBindingError,
+                                       "noMethodBindingError");
+              pFun(nameNonExhaustiveGuardsError,
+                                       "nonExhaustiveGuardsError");
+              pFun(namePatError,       "patError");
+              pFun(nameRecSelError,    "recSelError");
+              pFun(nameRecConError,    "recConError");
+              pFun(nameRecUpdError,    "recUpdError");
+
                /* hooks for handwritten bytecode */
                pFun(namePrimSeq,        "primSeq");
                pFun(namePrimCatch,      "primCatch");
@@ -719,5 +808,5 @@ assert(nonNull(namePMFail));
 }
 #undef pFun
 
-#include "fooble.c"
+//#include "fooble.c"
 /*-------------------------------------------------------------------------*/