[project @ 2000-04-14 15:18:05 by sewardj]
[ghc-hetmet.git] / ghc / interpreter / output.c
index 471dd51..ad8b0ff 100644 (file)
@@ -1,23 +1,23 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * Unparse expressions and types - for use in error messages, type checker
  * and for debugging.
  *
- * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
- * All rights reserved. See NOTICE for details and conditions of use etc...
- * Hugs version 1.4, December 1997
+ * The Hugs 98 system is Copyright (c) Mark P Jones, Alastair Reid, the
+ * Yale Haskell Group, and the Oregon Graduate Institute of Science and
+ * Technology, 1994-1999, All rights reserved.  It is distributed as
+ * free software under the license in the file "License", which is
+ * included in the distribution.
  *
  * $RCSfile: output.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:24 $
+ * $Revision: 1.17 $
+ * $Date: 2000/03/23 14:54:21 $
  * ------------------------------------------------------------------------*/
 
-#include "prelude.h"
+#include "hugsbasictypes.h"
 #include "storage.h"
 #include "connect.h"
-#include "input.h"  /* for textPlus */
 #include "errors.h"
-#include "link.h"
 #include <ctype.h>
 
 #define DEPTH_LIMIT     15
  * Local function prototypes:
  * ------------------------------------------------------------------------*/
 
-static Void local putChr         Args((Int));
-static Void local putStr         Args((String));
-static Void local putInt         Args((Int));
-
-static Void local put            Args((Int,Cell));
-static Void local putFlds        Args((Cell,List));
-static Void local putComp        Args((Cell,List));
-static Void local putQual        Args((Cell));
-static Bool local isDictVal      Args((Cell));
-static Cell local maySkipDict    Args((Cell));
-static Void local putAp          Args((Int,Cell));
-static Void local putOverInfix   Args((Int,Text,Syntax,Cell));
-static Void local putInfix       Args((Int,Text,Syntax,Cell,Cell));
-static Void local putSimpleAp    Args((Cell,Int));
-static Void local putTuple       Args((Int,Cell));
-static Int  local unusedTups     Args((Int,Cell));
-static Void local unlexVar       Args((Text));
-static Void local unlexOp        Args((Text));
-static Void local unlexCharConst Args((Cell));
-static Void local unlexStrConst  Args((Text));
-
-static Void local putSigType     Args((Cell));
-static Void local putContext     Args((List,Int));
-static Void local putPred        Args((Cell,Int));
-static Void local putType        Args((Cell,Int,Int));
-static Void local putTyVar       Args((Int));
-static Bool local putTupleType   Args((Cell,Int));
-static Void local putApType      Args((Type,Int,Int));
-
-static Void local putKind        Args((Kind));
-static Void local putKinds       Args((Kinds));
+static Void local put            ( Int,Cell );
+static Void local putFlds        ( Cell,List );
+static Void local putComp        ( Cell,List );
+static Void local putQual        ( Cell );
+static Bool local isDictVal      ( Cell );
+static Cell local maySkipDict    ( Cell );
+static Void local putAp          ( Int,Cell );
+static Void local putOverInfix   ( Int,Text,Syntax,Cell );
+static Void local putInfix       ( Int,Text,Syntax,Cell,Cell );
+static Void local putSimpleAp    ( Cell,Int );
+static Void local putTuple       ( Int,Cell );
+static Int  local unusedTups     ( Int,Cell );
+static Void local unlexOp        ( Text );
+
+static Void local putSigType     ( Cell );
+static Void local putContext     ( List,List,Int );
+static Void local putPred        ( Cell,Int );
+static Void local putType        ( Cell,Int,Int );
+static Void local putTyVar       ( Int );
+static Bool local putTupleType   ( Cell,Int );
+static Void local putApType      ( Type,Int,Int );
+
+static Void local putKind        ( Kind );
+static Void local putKinds       ( Kinds );
+
 
 /* --------------------------------------------------------------------------
  * Basic output routines:
  * ------------------------------------------------------------------------*/
 
-static FILE *outputStream;             /* current output stream            */
+FILE *outputStream;                    /* current output stream            */
+Int  outColumn = 0;                    /* current output column number     */
                                                                        
 #define OPEN(b)    if (b) putChr('(');                                 
 #define CLOSE(b)   if (b) putChr(')');                                 
                                                                        
-static Void local putChr(c)            /* print single character           */
+Void putChr(c)                         /* print single character           */
 Int c; {                                                               
     Putc(c,outputStream);                                              
+    outColumn++;                                                       
 }                                                                      
                                                                        
-static Void local putStr(s)            /* print string                     */
+Void putStr(s)                        /* print string                     */
 String s; {                                                            
     for (; *s; s++) {                                                  
         Putc(*s,outputStream);                                         
+        outColumn++;                                                   
     }                                                                  
 }                                                                      
                                                                        
-static Void local putInt(n)            /* print integer                    */
+Void putInt(n)                        /* print integer                    */
 Int n; {
     static char intBuf[16];
     sprintf(intBuf,"%d",n);
     putStr(intBuf);
 }
 
+Void putPtr(p)                        /* print pointer                    */
+Ptr p; {
+    static char intBuf[16];
+    sprintf(intBuf,"%p",p);
+    putStr(intBuf);
+}
+
 /* --------------------------------------------------------------------------
  * Precedence values (See Haskell 1.3 report, p.12):
  * ------------------------------------------------------------------------*/
@@ -145,6 +149,18 @@ Cell e; {
         case CONOPCELL  : unlexVar(textOf(e));
                           break;
 
+#if IPARAM
+       case IPVAR      : putChr('?');
+                         unlexVar(textOf(e));
+                         break;
+
+       case WITHEXP    : OPEN(d>WHERE_PREC);
+                         putStr("dlet {...} in ");
+                         put(WHERE_PREC+1,fst(snd(e)));
+                         CLOSE(d>WHERE_PREC);
+                         break;
+#endif
+
 #if TREX
         case RECSEL     : putChr('#');
                           unlexVar(extText(snd(e)));
@@ -175,23 +191,31 @@ Cell e; {
         case COMP       : putComp(fst(snd(e)),snd(snd(e)));
                           break;
 
-        case CHARCELL   : unlexCharConst(charOf(e));
+        case MONADCOMP  : putComp(fst(snd(snd(e))),snd(snd(snd(e))));
                           break;
 
-        case INTCELL    : putInt(intOf(e));
+        case CHARCELL   : unlexCharConst(charOf(e));
                           break;
 
-        case BIGCELL    : putStr(bignumToString(e));
+        case INTCELL    : {   Int i = intOf(e);
+                              if (i<0 && d>=UMINUS_PREC) putChr('(');
+                              putInt(i);
+                              if (i<0 && d>=UMINUS_PREC) putChr(')');
+                          }
                           break;
 
-        case FLOATCELL  : putStr(floatToString(e));
+        case FLOATCELL  : {   Float f = floatOf(e);
+                              if (f<0 && d>=UMINUS_PREC) putChr('(');
+                              putStr(floatToString(e));
+                              if (f<0 && d>=UMINUS_PREC) putChr(')');
+                          }
                           break;
 
         case STRCELL    : unlexStrConst(textOf(e));
                           break;
 
         case LETREC     : OPEN(d>WHERE_PREC);
-#if DEBUG_CODE
+#if 0
                           putStr("let {");
                           put(NEVER,fst(snd(e)));
                           putStr("} in ");
@@ -214,7 +238,7 @@ Cell e; {
 
         case LAMBDA     : xs = fst(snd(e));
                           if (whatIs(xs)==BIGLAM)
-                              xs = snd(snd(e));
+                              xs = snd(snd(xs));
                           while (nonNull(xs) && isDictVal(hd(xs)))
                               xs = tl(xs);
                           if (isNull(xs)) {
@@ -247,7 +271,7 @@ Cell e; {
 
         case CASE       : putStr("case ");
                           put(NEVER,fst(snd(e)));
-#if DEBUG_CODE
+#if 0
                           putStr(" of {");
                           put(NEVER,snd(snd(e)));
                           putChr('}');
@@ -270,7 +294,7 @@ Cell e; {
     putDepth--;
 }
 
-static Void local putFlds(exp,fs)         /* Output exp using labelled fields*/
+static Void local putFlds(exp,fs)       /* Output exp using labelled fields*/
 Cell exp;
 List fs; {
     put(ALWAYS,exp);
@@ -288,7 +312,7 @@ List fs; {
                      isVar(e)  ? textOf(e)    : inventText();
 
             put(NEVER,f);
-            if (s!=t) {
+            if (haskell98 || s!=t) {
                 putStr(" = ");
                 put(NEVER,e);
             }
@@ -333,11 +357,11 @@ Cell q; {
 
 static Bool local isDictVal(e)          /* Look for dictionary value       */
 Cell e; {
-#if !DEBUG_CODE
+#if 0   /* was !DEBUG_CODE -- is it necessary? */
     Cell h = getHead(e);
     switch (whatIs(h)) {
-        case DICTVAR  : return TRUE;
-        case NAME     : return isDfun(h);
+        case DICTVAR : return TRUE;
+        case NAME    : return isDfun(h);
     }
 #endif
     return FALSE;
@@ -354,7 +378,7 @@ static Void local putAp(d,e)            /* print application (args>=1)     */
 Int  d;
 Cell e; {
     Cell   h;
-    Text   t;
+    Text   t = 0;                       /* bogus init to keep gcc -O happy */
     Syntax sy;
     Int    args = 0;
 
@@ -368,14 +392,12 @@ Cell e; {
     }
 
     switch (whatIs(h)) {
-#if NPLUSK
         case ADDPAT     : if (args==1)
-                              putInfix(d,textPlus,syntaxOf(textPlus),
-                                         arg(e),snd(h));
+                              putInfix(d,textPlus,syntaxOf(namePlus),
+                                         arg(e),mkInt(intValOf(fun(e))));
                           else
                               putStr("ADDPAT");
                           return;
-#endif
 
         case TUPLE      : OPEN(args>tupleOf(h) && d>=FUN_PREC);
                           putTuple(tupleOf(h),e);
@@ -384,19 +406,19 @@ Cell e; {
 
         case NAME       : if (args==1 &&
                               ((h==nameFromInt     && isInt(arg(e)))    ||
-                               (h==nameFromInteger && isBignum(arg(e))) ||
                                (h==nameFromDouble  && isFloat(arg(e))))) {
                               put(d,arg(e));
                               return;
                           }
-                          sy = syntaxOf(t = name(h).text);
+                          t  = name(h).text;
+                          sy = syntaxOf(h);
                           break;
 
         case VARIDCELL  :
         case VAROPCELL  :
         case DICTVAR    :
         case CONIDCELL  :
-        case CONOPCELL  : sy = syntaxOf(t = textOf(h));
+        case CONOPCELL  : sy = defaultSyntax(t = textOf(h));
                           break;
 
 #if TREX
@@ -527,11 +549,13 @@ Cell e; {                               /* args not yet printed ...        */
     return ts;
 }
 
-static Void local unlexVar(t)          /* print text as a variable name    */
-Text t; {                              /* operator symbols must be enclosed*/
-    String s = textToStr(t);           /* in parentheses... except [] ...  */
-
-    if ((isascii(s[0]) && isalpha(s[0])) || s[0]=='_' || s[0]=='[' || s[0]=='(')
+Void unlexVarStr(s)
+String s; {
+    if ((isascii((int)(s[0])) && isalpha((int)(s[0]))) 
+        || s[0]=='_' || s[0]=='[' || s[0]=='('
+        || s[0]=='$'
+        || (s[0]==':' && s[1]=='D')
+       )
         putStr(s);
     else {
         putChr('(');
@@ -540,11 +564,16 @@ Text t; {                              /* operator symbols must be enclosed*/
     }
 }
 
+Void unlexVar(t)                       /* print text as a variable name    */
+Text t; {                              /* operator symbols must be enclosed*/
+    unlexVarStr(textToStr(t));         /* in parentheses... except [] ...  */
+}
+
 static Void local unlexOp(t)           /* print text as operator name      */
 Text t; {                              /* alpha numeric symbols must be    */
     String s = textToStr(t);           /* enclosed by backquotes           */
 
-    if (isascii(s[0]) && isalpha(s[0])) {
+    if (isascii((int)(s[0])) && isalpha((int)(s[0]))) {
         putChr('`');
         putStr(s);
         putChr('`');
@@ -553,14 +582,14 @@ Text t; {                              /* alpha numeric symbols must be    */
         putStr(s);
 }
 
-static Void local unlexCharConst(c)
+Void unlexCharConst(c)
 Cell c; {
     putChr('\'');
     putStr(unlexChar(c,'\''));
     putChr('\'');
 }
 
-static Void local unlexStrConst(t)
+Void unlexStrConst(t)
 Text t; {
     String s            = textToStr(t);
     static Char SO      = 14;          /* ASCII code for '\SO'             */
@@ -574,7 +603,8 @@ Text t; {
         Char   c  = ' ';
 
         if ((lastWasSO && *ch=='H') ||
-                (lastWasEsc && lastWasDigit && isascii(*ch) && isdigit(*ch)))
+                (lastWasEsc && lastWasDigit 
+                 && isascii((int)(*ch)) && isdigit((int)(*ch))))
             putStr("\\&");
 
         lastWasEsc   = (*ch=='\\');
@@ -603,21 +633,33 @@ Cell t; {
     putType(t,NEVER,fr);                /* Finally, print rest of type ... */
 }
 
-static Void local putContext(qs,fr)     /* print context list              */
+static Void local putContext(ps,qs,fr)  /* print context list              */
+List ps;
 List qs;
 Int  fr; {
-    if (isNull(qs))
-        putStr("()");
-    else {
-        Int nq = length(qs);
-        if (nq!=1) putChr('(');
+    Int len = length(ps) + length(qs);
+    Int c   = len;
+#if IPARAM
+    Bool useParens = len!=1 || isIP(fun(hd(ps)));
+#else
+    Bool useParens = len!=1;
+#endif
+    if (useParens)
+        putChr('(');
+    for (; nonNull(ps); ps=tl(ps)) {
+        putPred(hd(ps),fr);
+        if (--c > 0) {
+            putStr(", ");
+        }
+    }
+    for (; nonNull(qs); qs=tl(qs)) {
         putPred(hd(qs),fr);
-        while (nonNull(qs=tl(qs))) {
+        if (--c > 0) {
             putStr(", ");
-            putPred(hd(qs),fr);
         }
-        if (nq!=1) putChr(')');
     }
+    if (useParens)
+        putChr(')');
 }
 
 static Void local putPred(pi,fr)        /* Output predicate                */
@@ -632,6 +674,15 @@ Int  fr; {
             return;
         }
 #endif
+#if IPARAM
+       if (whatIs(fun(pi)) == IPCELL) {
+           putChr('?');
+           putPred(fun(pi),fr);
+           putStr(" :: ");
+           putType(arg(pi),NEVER,fr);
+           return;
+       }
+#endif
         putPred(fun(pi),fr);
         putChr(' ');
         putType(arg(pi),ALWAYS,fr);
@@ -640,6 +691,10 @@ Int  fr; {
         putStr(textToStr(cclass(pi).text));
     else if (isCon(pi))
         putStr(textToStr(textOf(pi)));
+#if IPARAM
+    else if (whatIs(pi) == IPCELL)
+        unlexVar(textOf(pi));
+#endif
     else
         putStr("<unknownPredicate>");
 }
@@ -649,16 +704,16 @@ Cell t;
 Int  prec;
 Int  fr; {
     switch(whatIs(t)) {
-        case TYCON   : putStr(textToStr(tycon(t).text));
-                       break;
+        case TYCON     : putStr(textToStr(tycon(t).text));
+                         break;
 
-        case TUPLE   : {   Int n = tupleOf(t);
-                           putChr('(');
-                           while (--n > 0)
-                               putChr(',');
-                           putChr(')');
-                       }
-                       break;
+        case TUPLE     : {   Int n = tupleOf(t);
+                             putChr('(');
+                             while (--n > 0)
+                                 putChr(',');
+                             putChr(')');
+                         }
+                         break;
 
         case POLYTYPE  : {   Kinds ks = polySigOf(t);
                              OPEN(prec>=ARROW_PREC);
@@ -666,7 +721,7 @@ Int  fr; {
                              for (; isAp(ks); ks=tl(ks)) {
                                  putTyVar(fr++);
                                  if (isAp(tl(ks)))
-                                     putChr(',');
+                                     putChr(' ');
                              }
                              putStr(". ");
                              putType(monotypeOf(t),NEVER,fr);
@@ -674,10 +729,17 @@ Int  fr; {
                          }
                          break;
 
+        case CDICTS    :
         case QUAL      : OPEN(prec>=ARROW_PREC);
-                         putContext(fst(snd(t)),fr);
-                         putStr(" => ");
-                         putType(snd(snd(t)),NEVER,fr);
+                         if (whatIs(snd(snd(t)))==CDICTS) {
+                             putContext(fst(snd(t)),fst(snd(snd(snd(t)))),fr);
+                             putStr(" => ");
+                             putType(snd(snd(snd(snd(t)))),NEVER,fr);
+                         } else {
+                             putContext(fst(snd(t)),NIL,fr);
+                             putStr(" => ");
+                             putType(snd(snd(t)),NEVER,fr);
+                         }
                          CLOSE(prec>=ARROW_PREC);
                          break;
 
@@ -685,68 +747,65 @@ Int  fr; {
         case RANK2     : putType(snd(snd(t)),prec,fr);
                          break;
 
-        case OFFSET  : putTyVar(offsetOf(t));
-                       break;
+        case OFFSET    : putTyVar(offsetOf(t));
+                         break;
 
         case VARIDCELL :
         case VAROPCELL : putChr('_');
                          unlexVar(textOf(t));
                          break;
 
-        case INTCELL : putChr('_');
-                       putInt(intOf(t));
-                       break;
+        case INTCELL   : putChr('_');
+                         putInt(intOf(t));
+                         break;
 
-/* #ifdef DEBUG_TYPES */
-        case STAR    : putChr('*');
-                       break;
-/* #endif */
-
-        case AP      : {   Cell typeHead = getHead(t);
-                           Bool brackets = (argCount!=0 && prec>=ALWAYS);
-                           Int  args     = argCount;
-
-                           if (typeHead==typeList) {
-                               if (argCount==1) {
-                                   putChr('[');
-                                   putType(arg(t),NEVER,fr);
-                                   putChr(']');
-                                   return;
-                               }
-                           }
-                           else if (typeHead==typeArrow) {
-                               if (argCount==2) {
-                                   OPEN(prec>=ARROW_PREC);
-                                   putType(arg(fun(t)),ARROW_PREC,fr);
-                                   putStr(" -> ");
-                                   putType(arg(t),NEVER,fr);
-                                   CLOSE(prec>=ARROW_PREC);
-                                   return;
-                               }
-                               else if (argCount==1) {
-                                   putChr('(');
-                                   putType(arg(t),ARROW_PREC,fr);
-                                   putStr("->)");
-                                   return;
-                               }
-                           }
-                           else if (isTuple(typeHead)) {
-                               if (argCount==tupleOf(typeHead)) {
-                                   putChr('(');
-                                   putTupleType(t,fr);
-                                   putChr(')');
-                                   return;
-                               }
-                           }
+        case AP       : {   Cell typeHead = getHead(t);
+                            Bool brackets = (argCount!=0 && prec>=ALWAYS);
+                            Int  args    = argCount;
+
+                            if (typeHead==typeList) {
+                                if (argCount==1) {
+                                    putChr('[');
+                                    putType(arg(t),NEVER,fr);
+                                    putChr(']');
+                                    return;
+                                }
+                            }
+                            else if (typeHead==typeArrow) {
+                                if (argCount==2) {
+                                    OPEN(prec>=ARROW_PREC);
+                                    putType(arg(fun(t)),ARROW_PREC,fr);
+                                    putStr(" -> ");
+                                    putType(arg(t),NEVER,fr);
+                                    CLOSE(prec>=ARROW_PREC);
+                                    return;
+                                }
+#if 0
+                                else if (argCount==1) {
+                                    putChr('(');
+                                    putType(arg(t),ARROW_PREC,fr);
+                                    putStr("->)");
+                                    return;
+                                }
+#endif
+                            }
+                            else if (isTuple(typeHead)) {
+                                if (argCount==tupleOf(typeHead)) {
+                                    putChr('(');
+                                    putTupleType(t,fr);
+                                    putChr(')');
+                                    return;
+                                }
+                            }
 #if TREX
-                           else if (isExt(typeHead)) {
+                            else if (isExt(typeHead)) {
                                 if (args==2) {
                                     String punc = "(";
                                     do {
                                         putStr(punc);
                                         punc = ", ";
                                         putStr(textToStr(extText(typeHead)));
-                                        putStr("::");
+                                        putStr(" :: ");
                                         putType(extField(t),NEVER,fr);
                                         t        = extRow(t);
                                         typeHead = getHead(t);
@@ -764,13 +823,13 @@ Int  fr; {
                                     args-=2;
                             }
 #endif
-                           OPEN(brackets);
-                           putApType(t,args,fr);
-                           CLOSE(brackets);
-                       }
-                       break;
+                            OPEN(brackets);
+                            putApType(t,args,fr);
+                            CLOSE(brackets);
+                        }
+                        break;
 
-        default      : putStr("(bad type)");
+        default       : putStr("(bad type)");
     }
 }
 
@@ -866,6 +925,11 @@ Kinds ks; {
  * Main drivers:
  * ------------------------------------------------------------------------*/
 
+FILE *mystdout ( Void ) {
+  /* We use this from the gdb command line when debugging */
+  return stdout;
+}
+
 Void printExp(fp,e)                     /* print expr on specified stream  */
 FILE *fp;
 Cell e; {
@@ -885,7 +949,7 @@ Void printContext(fp,qs)                /* print context on spec. stream   */
 FILE *fp;
 List qs; {
     outputStream = fp;
-    putContext(qs,0);
+    putContext(qs,NIL,0);
 }
 
 Void printPred(fp,pi)                   /* print predicate pi on stream    */
@@ -903,10 +967,30 @@ Kind k; {
 }
 
 Void printKinds(fp,ks)                  /* print list of kinds on stream   */
-FILE *fp;
+FILE  *fp;
 Kinds ks; {
     outputStream = fp;
     putKinds(ks);
 }
 
+Void printFD(fp,fd)                    /* print functional dependency     */
+FILE* fp;
+Pair  fd; {
+    List us;
+    outputStream = fp;
+    for (us=fst(fd); nonNull(us); us=tl(us)) {
+        putTyVar(offsetOf(hd(us)));
+       if (nonNull(tl(us))) {
+           putChr(' ');
+       }
+    }
+    putStr(" -> ");
+    for (us=snd(fd); nonNull(us); us=tl(us)) {
+       putTyVar(offsetOf(hd(us)));
+       if (nonNull(tl(us))) {
+           putChr(' ');
+       }
+    }
+}
+  
 /*-------------------------------------------------------------------------*/