[project @ 2000-03-23 14:54:20 by sewardj]
[ghc-hetmet.git] / ghc / interpreter / translate.c
index 1ff953b..aa0af80 100644 (file)
  * included in the distribution.
  *
  * $RCSfile: translate.c,v $
- * $Revision: 1.18 $
- * $Date: 1999/11/23 09:48:46 $
+ * $Revision: 1.30 $
+ * $Date: 2000/03/23 14:54:21 $
  * ------------------------------------------------------------------------*/
 
-#include "prelude.h"
+#include "hugsbasictypes.h"
 #include "storage.h"
-#include "backend.h"
 #include "connect.h"
 #include "errors.h"
-#include "link.h"
-#include "dynamic.h"
+
 #include "Assembler.h"
 
 
 /* ---------------------------------------------------------------- */
 
-static StgVar  local stgOffset       Args((Offset,List));
-static StgVar  local stgText         Args((Text,List));
-static StgRhs  local stgRhs          Args((Cell,Int,List,StgExpr));
-static StgCaseAlt local stgCaseAlt   Args((Cell,Int,List,StgExpr));
-static StgExpr local stgExpr         Args((Cell,Int,List,StgExpr));
+static StgVar     local stgOffset    ( Offset,List );
+static StgVar     local stgText      ( Text,List );
+static StgRhs     local stgRhs       ( Cell,Int,List,StgExpr );
+static StgCaseAlt local stgCaseAlt   ( Cell,Int,List,StgExpr );
+static StgExpr    local stgExpr      ( Cell,Int,List,StgExpr );
 
 /* ---------------------------------------------------------------- */
 
@@ -38,9 +36,7 @@ static StgExpr local stgExpr         Args((Cell,Int,List,StgExpr));
 /* dictionaries, tuples, etc                                        */
 List stgGlobals = NIL;
 
-static StgVar local getSTGTupleVar  Args((Cell));
-
-static StgVar local getSTGTupleVar( Cell d )
+static StgVar local getSTGTupleVar ( Cell d )
 {
     Pair p = cellAssoc(d,stgGlobals);
     /* Yoiks - only the Prelude sees Tuple decls! */
@@ -211,8 +207,8 @@ StgExpr failExpr;
             Cell   scrut = stgOffset(o,sc);
             Cell   h     = getHead(discr);
             Int    da    = discrArity(discr);
+            char   str[30];
 
-#if NPLUSK
             if (whatIs(h) == ADDPAT && argCount == 1) {
                 /*   ADDPAT num dictIntegral
                  * ==>
@@ -233,8 +229,10 @@ StgExpr failExpr;
                     dIntegral = mkStgVar(dIntegral,NIL);
                     binds = cons(dIntegral,binds);
                 }
+
                 /* box number */
-                n = mkStgVar(mkStgCon(nameMkInteger,singleton(n)),NIL);
+                sprintf(str, "%d", n);
+                n = mkStgVar(mkStgCon(nameMkInteger,singleton(stringToBignum(str))),NIL);
                 binds = cons(n,binds);
 
                 /* coerce number to right type (using Integral dict) */
@@ -257,7 +255,6 @@ StgExpr failExpr;
                                           failExpr)),
                          failExpr));
             }
-#endif /* NPLUSK */
 
             assert(isName(h) && argCount == 2);
             {
@@ -367,6 +364,7 @@ StgExpr failExpr;
             List args  = NIL;
             List binds = NIL;
             List as    = NIL;
+            Int  length_args;
 
             /* Unwind args */
             while (isAp(e)) {
@@ -407,6 +405,24 @@ StgExpr failExpr;
                 hd(as) = a;
             }
 
+            /* Special case: saturated constructor application */
+            length_args = length(args);
+            if ( (isName(e) && isCfun(e)
+                  && name(e).arity > 0 
+                  && name(e).arity == length_args)
+                 ||
+                 (isTuple(e) && tycon(e).tuple == length_args)
+               ) {
+               StgVar v; 
+               /* fprintf ( stderr, "saturated application of %s\n",
+                           textToStr(isTuple(e) ? tycon(e).text : name(e).text)); */
+               v = mkStgVar(mkStgCon(e,args),NIL);
+               binds = cons(v,binds);
+               return mkStgLet(binds,v);
+
+               
+            }
+
             /* Function must be StgVar or Name */
             e = stgRhs(e,co,sc,namePMFail);
             if (!isStgVar(e) && !isName(e)) {
@@ -419,22 +435,6 @@ StgExpr failExpr;
     }
 }
 
-#if 0 /* apparently not used */
-static Void ppExp( Name n, Int arity, Cell e )
-{
-    if (1 || debugCode) {
-        Int i;
-        printf("%s", textToStr(name(n).text));
-        for (i = arity; i > 0; i--) {
-            printf(" o%d", i);
-        }
-        printf(" = ");
-        printExp(stdout,e); 
-        printf("\n");
-    }
-}
-#endif
-
 
 Void stgDefn( Name n, Int arity, Cell e )
 {
@@ -452,7 +452,7 @@ Void stgDefn( Name n, Int arity, Cell e )
 
 Void implementCfun(c,scs)               /* Build implementation for constr */
 Name c;                                 /* fun c.  scs lists integers (1..)*/
-List scs; {                             /* in incr order of strict comps.  */
+List scs; {                             /* in incr order of strict fields. */
     Int a = name(c).arity;
 
     if (a > 0) {
@@ -770,7 +770,8 @@ Void implementForeignImport ( Name n )
     List argTys    = NIL;
     List resultTys = NIL;
     CFunDescriptor* descriptor = 0;
-    Bool addState = TRUE;
+    Bool addState  = TRUE;
+    Bool dynamic   = isNull(name(n).defn);
     while (getHead(t)==typeArrow && argCount==2) {
         Type ta = fullExpand(arg(fun(t)));
         Type tr = arg(t);
@@ -778,6 +779,17 @@ Void implementForeignImport ( Name n )
         t = tr;
     }
     argTys = rev(argTys);
+
+    /* argTys now holds the argument tys.  If this is a dynamic call,
+       the first one had better be an Addr.
+    */
+    if (dynamic) {
+       if (isNull(argTys) || hd(argTys) != typeAddr) {
+          ERRMSG(name(n).line) "First argument in f-i-dynamic must be an Addr"
+          EEND;
+       }
+    }
+
     if (getHead(t) == typeIO) {
         resultTys = getArgs(t);
         assert(length(resultTys) == 1);
@@ -797,8 +809,9 @@ Void implementForeignImport ( Name n )
     }
     mapOver(foreignOutboundTy,argTys);  /* allows foreignObj, byteArrays, etc */
     mapOver(foreignInboundTy,resultTys); /* doesn't */
-    descriptor = mkDescriptor(charListToString(argTys),
-                              charListToString(resultTys));
+    descriptor 
+       = mkDescriptor(charListToString(argTys),
+                      charListToString(resultTys));
     if (!descriptor) {
        ERRMSG(name(n).line) "Can't allocate memory for call descriptor"
        EEND;
@@ -820,33 +833,59 @@ Void implementForeignImport ( Name n )
        internal ( "implementForeignImport: unknown calling convention");
 
     {
-        Pair    extName = name(n).defn;
-        void*   funPtr  = getDLLSymbol(name(n).line,
-                                       textToStr(textOf(fst(extName))),
-                                       textToStr(textOf(snd(extName))));
-        List extra_args = doubleton(mkPtr(descriptor),mkPtr(funPtr));
-        StgRhs rhs = makeStgPrim(n,addState,extra_args,descriptor->arg_tys,
-                                 descriptor->result_tys);
-        StgVar v   = mkStgVar(rhs,NIL);
-        if (funPtr == 0) {
-            ERRMSG(name(n).line) "Could not find foreign function \"%s\" in \"%s\"", 
-                textToStr(textOf(snd(extName))),
-                textToStr(textOf(fst(extName)))
-            EEND;
+        Pair   extName;
+        void*  funPtr;
+        List   extra_args;
+        StgRhs rhs;
+        StgVar v;
+
+        if (dynamic) {
+           funPtr     = NULL;
+           extra_args = singleton(mkPtr(descriptor));
+           /* and we know that the first arg will be the function pointer */
+        } else {
+           extName = name(n).defn;
+           funPtr  = getDLLSymbol(name(n).line,
+                                  textToStr(textOf(fst(extName))),
+                                  textToStr(textOf(snd(extName))));
+           if (funPtr == 0) {
+               ERRMSG(name(n).line) 
+                   "Could not find foreign function \"%s\" in \"%s\"", 
+                   textToStr(textOf(snd(extName))),
+                   textToStr(textOf(fst(extName)))
+               EEND;
+           }
+           extra_args = doubleton(mkPtr(descriptor),mkPtr(funPtr));
         }
+
+        rhs              = makeStgPrim(n,addState,extra_args,
+                                       descriptor->arg_tys,
+                                       descriptor->result_tys);
+        v                = mkStgVar(rhs,NIL);
         name(n).defn     = NIL;
         name(n).stgVar   = v;
-        stgGlobals=cons(pair(n,v),stgGlobals);/*so it will get codegen'd */
+        stgGlobals       = cons(pair(n,v),stgGlobals);
+    }
+
+    /* At this point the descriptor contains a tags for all args,
+       because that makes makeStgPrim generate the correct unwrap
+       code.  From now on, the descriptor is only used at the time
+       the actual ccall is made.  So we need to zap the leading
+       addr arg IF this is a f-i-dynamic call.
+    */
+    if (dynamic) {
+       descriptor->arg_tys++;
+       descriptor->num_args--;
     }
 }
 
 
 /* Generate code:
  *
- * \ fun s0 ->
+ * \ fun ->
      let e1 = A# "...."
          e3 = C# 'c' -- (ccall), or 's' (stdcall)
-     in  primMkAdjThunk fun e1 e3 s0
+     in  primMkAdjThunk fun e1 e3
 
    we require, and check that,
      fun :: prim_arg* -> IO prim_result
@@ -879,7 +918,7 @@ Void implementForeignExport ( Name n )
         assert(length(resultTys) == 1);
         resultTys = hd(resultTys);
     } else {
-        ERRMSG(name(n).line) "foreign export doesn't return an IO type" ETHEN
+        ERRMSG(name(n).line) "function to be exported doesn't return an IO type: " ETHEN
         ERRTEXT " \"" ETHEN ERRTYPE(t);
         ERRTEXT "\""
         EEND;        
@@ -903,7 +942,6 @@ Void implementForeignExport ( Name n )
     else
        internal ( "implementForeignExport: unknown calling convention");
 
-
     {
     List     tdList;
     Text     tdText;
@@ -916,7 +954,7 @@ Void implementForeignExport ( Name n )
        tdList = cons(foreignOutboundTy(resultTys),tdList);
 
     tdText = findText(charListToString ( tdList ));
-    args   = makeArgs(2);
+    args   = makeArgs(1);
     e1     = mkStgVar(
                 mkStgCon(nameMkA,singleton(ap(STRCELL,tdText))),
                 NIL
@@ -935,7 +973,7 @@ Void implementForeignExport ( Name n )
                    tripleton(e1,e2,e3),
                    mkStgApp(
                       nameCreateAdjThunk,
-                      cons(hd(args),cons(e2,cons(e3,cons(hd(tl(args)),NIL))))
+                      cons(hd(args),cons(e2,cons(e3,NIL)))
                    )
                 )
              );
@@ -948,7 +986,6 @@ Void implementForeignExport ( Name n )
     }
 }
 
-// ToDo: figure out how to set inlineMe for these (non-Name) things
 Void implementTuple(size)
 Int size; {
     if (size > 0) {
@@ -971,16 +1008,14 @@ Int size; {
 Void translateControl(what)
 Int what; {
     switch (what) {
-    case INSTALL:
-        {
-            /* deliberate fall through */
-        }
-    case RESET: 
-            stgGlobals=NIL;
-            break;
-    case MARK: 
-            mark(stgGlobals);
-            break;
+       case POSTPREL: break;
+       case PREPREL:
+       case RESET: 
+          stgGlobals=NIL;
+          break;
+       case MARK: 
+          mark(stgGlobals);
+          break;
     }
 }