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