[project @ 1999-10-15 11:02:06 by sewardj]
[ghc-hetmet.git] / ghc / interpreter / link.c
1
2 /* --------------------------------------------------------------------------
3  * Load symbols required from the Prelude
4  *
5  * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
6  * All rights reserved. See NOTICE for details and conditions of use etc...
7  * Hugs version 1.4, December 1997
8  *
9  * $RCSfile: link.c,v $
10  * $Revision: 1.8 $
11  * $Date: 1999/10/15 11:02:15 $
12  * ------------------------------------------------------------------------*/
13
14 #include "prelude.h"
15 #include "storage.h"
16 #include "backend.h"
17 #include "connect.h"
18 #include "errors.h"
19 #include "Assembler.h" /* for asmPrimOps and AsmReps */
20
21 #include "link.h"
22
23
24 Type typeArrow;                         /* Function spaces                 */
25
26 Type typeChar;
27 Type typeInt;
28 Type typeInteger;
29 Type typeWord;
30 Type typeAddr;
31 Type typePrimArray;            
32 Type typePrimByteArray;
33 Type typeRef;                  
34 Type typePrimMutableArray;     
35 Type typePrimMutableByteArray; 
36 Type typeFloat;
37 Type typeDouble;
38 Type typeStable;
39 #ifdef PROVIDE_WEAK
40 Type typeWeak;
41 #endif
42 #ifdef PROVIDE_FOREIGN
43 Type typeForeign;
44 #endif
45 #ifdef PROVIDE_CONCURRENT
46 Type typeThreadId;
47 Type typeMVar;
48 #endif
49
50 Type typeList;
51 Type typeUnit;
52 Type typeString;
53 Type typeBool;
54 Type typeST;
55 Type typeIO;
56 Type typeException;
57
58 Class classEq;                          /* `standard' classes              */
59 Class classOrd;
60 Class classShow;
61 Class classRead;
62 Class classIx;
63 Class classEnum;
64 Class classBounded;
65
66 Class classReal;                        /* `numeric' classes               */
67 Class classIntegral;
68 Class classRealFrac;
69 Class classRealFloat;
70 Class classFractional;
71 Class classFloating;
72 Class classNum;
73 Class classMonad;                       /* Monads and monads with a zero   */
74
75 List stdDefaults;                       /* standard default values         */
76
77 Name nameTrue;    
78 Name nameFalse;            /* primitive boolean constructors  */
79 Name nameNil;     
80 Name nameCons;             /* primitive list constructors     */
81 Name nameUnit;                          /* primitive Unit type constructor */
82
83 Name nameEq;    
84 Name nameFromInt;
85 Name nameFromDouble;       /* coercion of numerics            */
86 Name nameFromInteger;
87 Name nameReturn;  
88 Name nameBind;             /* for translating monad comps     */
89 Name nameZero;                          /* for monads with a zero          */
90
91 Name nameId;
92 Name nameRunIO;
93 Name namePrint;
94
95 Name nameOtherwise;
96 Name nameUndefined;                     /* generic undefined value         */
97 #if NPLUSK
98 Name namePmSub; 
99 #endif
100 Name namePMFail;
101 Name nameEqChar;
102 Name nameEqInt;
103 #if !OVERLOADED_CONSTANTS
104 Name nameEqInteger;
105 #endif
106 Name nameEqDouble;
107 Name namePmInt;
108 Name namePmInteger;
109 Name namePmDouble;
110 Name namePmLe;
111 Name namePmSubtract;
112 Name namePmFromInteger;
113 Name nameMkIO;
114 Name nameRunST;
115 Name nameUnpackString;
116 Name nameError;
117 Name nameInd;
118 Name nameCreateAdjThunk;
119
120 Name nameAnd;
121 Name nameConCmp;
122 Name nameCompAux;
123 Name nameEnFrTh;
124 Name nameEnFrTo;
125 Name nameEnFrom;
126 Name nameEnFrEn;
127 Name nameEnToEn;
128 Name nameEnInRng;
129 Name nameEnIndex;
130 Name nameEnRange;
131 Name nameRangeSize;
132 Name nameComp;
133 Name nameShowField;
134 Name nameApp;
135 Name nameShowParen;
136 Name nameReadParen;
137 Name nameLex;
138 Name nameReadField;
139 Name nameFlip;
140
141 Name namePrimSeq;
142 Name namePrimCatch;
143 Name namePrimRaise;
144
145 Name nameFromTo;
146 Name nameFromThen;
147 Name nameFrom;
148 Name nameFromThenTo;
149 Name nameNegate;
150
151 /* these names are required before we've had a chance to do the right thing */
152 Name nameSel;
153 Name nameUnsafeUnpackCString;
154
155 /* constructors used during translation and codegen */
156 Name nameMkC;                           /* Char#        -> Char           */
157 Name nameMkI;                           /* Int#         -> Int            */
158 Name nameMkInteger;                     /* Integer#     -> Integer        */
159 Name nameMkW;                           /* Word#        -> Word           */
160 Name nameMkA;                           /* Addr#        -> Addr            */
161 Name nameMkF;                           /* Float#       -> Float           */
162 Name nameMkD;                           /* Double#      -> Double          */
163 Name nameMkPrimArray;            
164 Name nameMkPrimByteArray;
165 Name nameMkRef;                  
166 Name nameMkPrimMutableArray;     
167 Name nameMkPrimMutableByteArray; 
168 Name nameMkStable;                      /* StablePtr# a -> StablePtr a     */
169 #ifdef PROVIDE_WEAK
170 Name nameMkWeak;                        /* Weak# a      -> Weak a          */
171 #endif
172 #ifdef PROVIDE_FOREIGN
173 Name nameMkForeign;                     /* ForeignObj#  -> ForeignObj      */
174 #endif
175 #ifdef PROVIDE_CONCURRENT
176 Name nameMkThreadId;                    /* ThreadId#    -> ThreadId        */
177 Name nameMkMVar;                        /* MVar#        -> MVar            */
178 #endif
179
180
181
182 Name nameMinBnd;
183 Name nameMaxBnd;
184 Name nameCompare;
185 Name nameShowsPrec;
186 Name nameIndex;
187 Name nameReadsPrec; 
188 Name nameRange;
189 Name nameEQ;
190 Name nameInRange;
191 Name nameGt;
192 Name nameLe;
193 Name namePlus;
194 Name nameMult;
195 Name nameMFail;
196 Type typeOrdering;
197 Module modulePrelude;
198 Name nameMap;
199 Name nameMinus;
200
201
202 /* --------------------------------------------------------------------------
203  * Frequently used type skeletons:
204  * ------------------------------------------------------------------------*/
205
206 Type  arrow;                     /* mkOffset(0) -> mkOffset(1)      */
207 Type  boundPair;                 /* (mkOffset(0),mkOffset(0))       */
208 Type  listof;                    /* [ mkOffset(0) ]                 */
209 Type  typeVarToVar;              /* mkOffset(0) -> mkOffset(0)      */
210
211 Cell  predNum;                   /* Num (mkOffset(0))               */
212 Cell  predFractional;            /* Fractional (mkOffset(0))        */
213 Cell  predIntegral;              /* Integral (mkOffset(0))          */
214 Kind  starToStar;                /* Type -> Type                    */
215 Cell  predMonad;                 /* Monad (mkOffset(0))             */
216
217 /* --------------------------------------------------------------------------
218  * 
219  * ------------------------------------------------------------------------*/
220
221 static Tycon linkTycon ( String s );
222 static Tycon linkClass ( String s );
223 static Name  linkName  ( String s );
224 static Void  mkTypes   ( void );
225 static Name  predefinePrim ( String s );
226
227
228 static Tycon linkTycon( String s )
229 {
230     Tycon tc = findTycon(findText(s));
231     if (nonNull(tc)) {
232         return tc;
233     }
234     ERRMSG(0) "Prelude does not define standard type \"%s\"", s
235     EEND;
236 }
237
238 static Class linkClass( String s )
239 {
240     Class cc = findClass(findText(s));
241     if (nonNull(cc)) {
242         return cc;
243     }
244     ERRMSG(0) "Prelude does not define standard class \"%s\"", s
245     EEND;
246 }
247
248 static Name linkName( String s )
249 {
250     Name n = findName(findText(s));
251     if (nonNull(n)) {
252         return n;
253     }
254     ERRMSG(0) "Prelude does not define standard name \"%s\"", s
255     EEND;
256 }
257
258 static Name predefinePrim ( String s )
259 {
260     Name nm;
261     Text t = findText(s);
262     nm = findName(t);
263     if (nonNull(nm)) {
264        //fprintf(stderr, "predefinePrim: %s already exists\n", s );
265     } else {
266        nm = newName(t,NIL);
267        name(nm).defn=PREDEFINED;
268     }
269     return nm;
270 }
271
272 Void linkPreludeTC(void) {              /* Hook to tycons and classes in   */
273     static Bool initialised = FALSE;    /* prelude when first loaded       */
274     if (!initialised) {
275         Int i;
276         initialised = TRUE;
277         setCurrModule(modulePrelude);
278
279         typeChar         = linkTycon("Char");
280         typeInt          = linkTycon("Int");
281         typeInteger      = linkTycon("Integer");
282         typeWord         = linkTycon("Word");
283         typeAddr         = linkTycon("Addr");
284         typePrimArray            = linkTycon("PrimArray");
285         typePrimByteArray        = linkTycon("PrimByteArray");
286         typeRef                  = linkTycon("Ref");
287         typePrimMutableArray     = linkTycon("PrimMutableArray");
288         typePrimMutableByteArray = linkTycon("PrimMutableByteArray");
289         typeFloat        = linkTycon("Float");
290         typeDouble       = linkTycon("Double");
291         typeStable       = linkTycon("StablePtr");
292 #ifdef PROVIDE_WEAK
293         typeWeak         = linkTycon("Weak");
294 #endif
295 #ifdef PROVIDE_FOREIGN
296         typeForeign      = linkTycon("ForeignObj");
297 #endif
298 #ifdef PROVIDE_CONCURRENT
299         typeThreadId     = linkTycon("ThreadId");
300         typeMVar         = linkTycon("MVar");
301 #endif
302
303         typeBool         = linkTycon("Bool");
304         typeST           = linkTycon("ST");
305         typeIO           = linkTycon("IO");
306         typeException    = linkTycon("Exception");
307         typeString       = linkTycon("String");
308         typeOrdering     = linkTycon("Ordering");
309
310         classEq          = linkClass("Eq");
311         classOrd         = linkClass("Ord");
312         classIx          = linkClass("Ix");
313         classEnum        = linkClass("Enum");
314         classShow        = linkClass("Show");
315         classRead        = linkClass("Read");
316         classBounded     = linkClass("Bounded");
317         classReal        = linkClass("Real");
318         classIntegral    = linkClass("Integral");
319         classRealFrac    = linkClass("RealFrac");
320         classRealFloat   = linkClass("RealFloat");
321         classFractional  = linkClass("Fractional");
322         classFloating    = linkClass("Floating");
323         classNum         = linkClass("Num");
324         classMonad       = linkClass("Monad");
325
326         stdDefaults     = NIL;
327         stdDefaults     = cons(typeDouble,stdDefaults);
328 #if DEFAULT_BIGNUM
329         stdDefaults     = cons(typeInteger,stdDefaults);
330 #else
331         stdDefaults     = cons(typeInt,stdDefaults);
332 #endif
333         mkTypes();
334
335         nameMkC          = addPrimCfunREP(findText("C#"),1,0,CHAR_REP);
336         nameMkI          = addPrimCfunREP(findText("I#"),1,0,INT_REP);
337         nameMkW          = addPrimCfunREP(findText("W#"),1,0,WORD_REP);
338         nameMkA          = addPrimCfunREP(findText("A#"),1,0,ADDR_REP);
339         nameMkF          = addPrimCfunREP(findText("F#"),1,0,FLOAT_REP);
340         nameMkD          = addPrimCfunREP(findText("D#"),1,0,DOUBLE_REP);
341         nameMkStable     = addPrimCfunREP(findText("Stable#"),1,0,STABLE_REP);
342         nameMkInteger    = addPrimCfunREP(findText("Integer#"),1,0,0);
343 #ifdef PROVIDE_FOREIGN
344         nameMkForeign    = addPrimCfunREP(findText("Foreign#"),1,0,0);
345 #endif
346 #ifdef PROVIDE_WEAK
347         nameMkWeak       = addPrimCfunREP(findText("Weak#"),1,0,0);
348 #endif
349         nameMkPrimArray            = addPrimCfunREP(findText("PrimArray#"),1,0,0);
350         nameMkPrimByteArray        = addPrimCfunREP(findText("PrimByteArray#"),1,0,0);
351         nameMkRef                  = addPrimCfunREP(findText("Ref#"),1,0,0);
352         nameMkPrimMutableArray     = addPrimCfunREP(findText("PrimMutableArray#"),1,0,0);
353         nameMkPrimMutableByteArray = addPrimCfunREP(findText("PrimMutableByteArray#"),1,0,0);
354 #ifdef PROVIDE_CONCURRENT
355         nameMkThreadId   = addPrimCfun(findTextREP("ThreadId#"),1,0,0);
356         nameMkMVar       = addPrimCfun(findTextREP("MVar#"),1,0,0);
357 #endif
358         /* The following primitives are referred to in derived instances and
359          * hence require types; the following types are a little more general
360          * than we might like, but they are the closest we can get without a
361          * special datatype class.
362          */
363         name(nameConCmp).type
364             = mkPolyType(starToStar,fn(aVar,fn(aVar,typeOrdering)));
365         name(nameEnRange).type
366             = mkPolyType(starToStar,fn(boundPair,listof));
367         name(nameEnIndex).type
368             = mkPolyType(starToStar,fn(boundPair,fn(aVar,typeInt)));
369         name(nameEnInRng).type
370             = mkPolyType(starToStar,fn(boundPair,fn(aVar,typeBool)));
371         name(nameEnToEn).type
372             = mkPolyType(starToStar,fn(aVar,fn(typeInt,aVar)));
373         name(nameEnFrEn).type
374             = mkPolyType(starToStar,fn(aVar,typeInt));
375         name(nameEnFrom).type
376             = mkPolyType(starToStar,fn(aVar,listof));
377         name(nameEnFrTo).type
378             = name(nameEnFrTh).type
379             = mkPolyType(starToStar,fn(aVar,fn(aVar,listof)));
380
381         name(namePrimSeq).type
382             = primType(MONAD_Id, "ab", "b");
383         name(namePrimCatch).type
384             = primType(MONAD_Id, "aH", "a");
385         name(namePrimRaise).type
386             = primType(MONAD_Id, "E", "a");
387
388         for (i=2; i<=NUM_DTUPLES; i++) {/* Add derived instances of tuples */
389             addTupInst(classEq,i);
390             addTupInst(classOrd,i);
391             addTupInst(classIx,i);
392             addTupInst(classShow,i);
393             addTupInst(classRead,i);
394             addTupInst(classBounded,i);
395         }
396     }
397 }
398
399 static Void mkTypes ( void )
400 {
401         predNum        = ap(classNum,aVar);
402         predFractional = ap(classFractional,aVar);
403         predIntegral   = ap(classIntegral,aVar);
404         predMonad      = ap(classMonad,aVar);
405 }
406
407 Void linkPreludeCM(void) {              /* Hook to cfuns and mfuns in      */
408     static Bool initialised = FALSE;    /* prelude when first loaded       */
409     if (!initialised) {
410         Int i;
411         initialised = TRUE;
412
413         setCurrModule(modulePrelude);
414
415         /* constructors */
416         nameFalse        = linkName("False");
417         nameTrue         = linkName("True");
418
419         /* members */
420         nameEq           = linkName("==");
421         nameFromInt      = linkName("fromInt");
422         nameFromInteger  = linkName("fromInteger");
423         nameFromDouble   = linkName("fromDouble");
424         nameReturn       = linkName("return");
425         nameBind         = linkName(">>=");
426         nameLe           = linkName("<=");
427         nameGt           = linkName(">");
428         nameShowsPrec    = linkName("showsPrec");
429         nameReadsPrec    = linkName("readsPrec");
430         nameEQ           = linkName("EQ");
431         nameCompare      = linkName("compare");
432         nameMinBnd       = linkName("minBound");
433         nameMaxBnd       = linkName("maxBound");
434         nameRange        = linkName("range");
435         nameIndex        = linkName("index");
436         namePlus         = linkName("+");
437         nameMult         = linkName("*");
438         nameRangeSize    = linkName("rangeSize");
439         nameInRange      = linkName("inRange");
440         nameMinus        = linkName("-");
441         /* These come before calls to implementPrim */
442         for(i=0; i<NUM_TUPLES; ++i) {
443             implementTuple(i);
444         }
445     }
446 }
447
448 Void linkPreludeNames(void) {           /* Hook to names defined in Prelude */
449     static Bool initialised = FALSE;
450     if (!initialised) {
451         Int i;
452         initialised = TRUE;
453
454         setCurrModule(modulePrelude);
455
456         /* primops */
457         nameMkIO           = linkName("primMkIO");
458         for (i=0; asmPrimOps[i].name; ++i) {
459             Text t = findText(asmPrimOps[i].name);
460             Name n = findName(t);
461             if (isNull(n)) {
462                 n = newName(t,NIL);
463             }
464             name(n).line   = 0;
465             name(n).defn   = NIL;
466             name(n).type   = primType(asmPrimOps[i].monad,
467                                       asmPrimOps[i].args,
468                                       asmPrimOps[i].results);
469             name(n).arity  = strlen(asmPrimOps[i].args);
470             name(n).primop = &(asmPrimOps[i]);
471             implementPrim(n);
472         }
473
474         nameRunST         = linkName("primRunST");
475
476         /* static(tidyInfix)                        */
477         nameNegate        = linkName("negate");
478         /* user interface                           */
479         nameRunIO         = linkName("primRunIO");
480         namePrint         = linkName("print");
481         /* desugar                                  */
482         nameOtherwise     = linkName("otherwise");
483         nameUndefined     = linkName("undefined");
484         /* pmc                                      */
485 #if NPLUSK                      
486         namePmSub         = linkName("primPmSub");
487 #endif                          
488         /* translator                               */
489         nameEqChar        = linkName("primEqChar");
490         nameEqInt         = linkName("primEqInt");
491 nameCreateAdjThunk = linkName("primCreateAdjThunk");
492 #if !OVERLOADED_CONSTANTS
493         nameEqInteger     = linkName("primEqInteger");
494 #endif /* !OVERLOADED_CONSTANTS */
495         nameEqDouble      = linkName("primEqDouble");
496         namePmInt         = linkName("primPmInt");
497         name(namePmInt).inlineMe = TRUE;
498     }
499 }
500
501
502 /* ToDo: fix pFun (or eliminate its use) */
503 #define pFun(n,s) n = predefinePrim(s)
504
505 Void linkControl(what)
506 Int what; {
507     switch (what) {
508         case RESET   :
509         case MARK    : 
510                        break;
511
512         case INSTALL : linkControl(RESET);
513
514                        modulePrelude = newModule(textPrelude);
515                        setCurrModule(modulePrelude);
516
517                        typeArrow = addPrimTycon(findText("(->)"),
518                                                 pair(STAR,pair(STAR,STAR)),
519                                                 2,DATATYPE,NIL);
520
521                        /* newtype and USE_NEWTYPE_FOR_DICTS     */
522                        pFun(nameId,             "id");
523
524                        /* desugaring                            */
525                        pFun(nameInd,            "_indirect");
526                        name(nameInd).number = DFUNNAME;
527
528                        /* pmc                                   */
529                        pFun(nameSel,            "_SEL");
530
531                        /* strict constructors                   */
532                        pFun(nameFlip,           "flip"     );
533
534                        /* parser                                */
535                        pFun(nameFromTo,         "enumFromTo");
536                        pFun(nameFromThenTo,     "enumFromThenTo");
537                        pFun(nameFrom,           "enumFrom");
538                        pFun(nameFromThen,       "enumFromThen");
539
540                        /* deriving                              */
541                        pFun(nameApp,            "++");
542                        pFun(nameReadParen,      "readParen");
543                        pFun(nameShowParen,      "showParen");
544                        pFun(nameLex,            "lex");
545                        pFun(nameEnToEn,         "toEnumPR"); //not sure
546                        pFun(nameEnFrEn,         "fromEnum"); //not sure
547                        pFun(nameEnFrom,         "enumFrom"); //not sure
548                        pFun(nameEnFrTh,         "enumFromThen"); //not sure
549                        pFun(nameEnFrTo,         "enumFromTo"); //not sure
550                        pFun(nameEnRange,        "range"); //not sure
551                        pFun(nameEnIndex,        "index"); //not sure
552                        pFun(nameEnInRng,        "inRange"); //not sure
553                        pFun(nameConCmp,         "_concmp"); //very not sure
554                        pFun(nameComp,           ".");
555                        pFun(nameAnd,            "&&");
556                        pFun(nameCompAux,        "primCompAux");
557                        name(nameCompAux).inlineMe = TRUE;
558                        pFun(nameMap,            "map");
559
560                        /* implementTagToCon                     */
561                        pFun(namePMFail,         "primPmFail");
562                        pFun(nameError,          "error");
563                        pFun(nameUnpackString,   "primUnpackString");
564
565                        //                       /* foreign export dynamic */
566                        //pFun(nameCreateAdjThunk, "primCreateAdjThunk");
567
568                        /* hooks for handwritten bytecode */
569                        pFun(namePrimSeq,        "primSeq");
570                        pFun(namePrimCatch,      "primCatch");
571                        pFun(namePrimRaise,      "primRaise");
572                        {
573                           StgVar vv = mkStgVar(NIL,NIL);
574                           Name n = namePrimSeq;
575                           name(n).line = 0;
576                           name(n).arity = 1;
577                           name(n).type = NIL;
578                           vv = mkStgVar(NIL,NIL);
579                           stgVarInfo(vv) = mkPtr ( asm_BCO_seq() );
580                           name(n).stgVar = vv;
581                           stgGlobals=cons(pair(n,vv),stgGlobals);
582                           namePrimSeq = n;
583                        }
584                        {
585                           StgVar vv = mkStgVar(NIL,NIL);
586                           Name n = namePrimCatch;
587                           name(n).line = 0;
588                           name(n).arity = 2;
589                           name(n).type = NIL;
590                           stgVarInfo(vv) = mkPtr ( asm_BCO_catch() );
591                           name(n).stgVar = vv;
592                           stgGlobals=cons(pair(n,vv),stgGlobals);
593                        }
594                        {
595                           StgVar vv = mkStgVar(NIL,NIL);
596                           Name n = namePrimRaise;
597                           name(n).line = 0;
598                           name(n).arity = 1;
599                           name(n).type = NIL;
600                           stgVarInfo(vv) = mkPtr ( asm_BCO_raise() );
601                           name(n).stgVar = vv;
602                           stgGlobals=cons(pair(n,vv),stgGlobals);
603                        }
604
605                        break;
606     }
607 }
608 #undef pFun
609
610
611 /*-------------------------------------------------------------------------*/