[project @ 1999-02-03 17:08:25 by sewardj]
[ghc-hetmet.git] / ghc / interpreter / stg.c
index 6b0029f..032e014 100644 (file)
@@ -1,4 +1,4 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * STG syntax
  *
@@ -7,15 +7,15 @@
  * Hugs version 1.4, December 1997
  *
  * $RCSfile: stg.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:38 $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:39 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
 #include "storage.h"
+#include "backend.h"
 #include "connect.h"
 #include "errors.h"
-#include "stg.h"
 #include "link.h"      /* for nameTrue/False     */
 #include "Assembler.h" /* for AsmRep and primops */
 
@@ -79,7 +79,7 @@ StgExpr makeStgLambda( List args, StgExpr body )
         return body;
     } else {
         if (whatIs(body) == LAMBDA) {
-            return mkStgLambda(dupListOnto(args,stgLambdaArgs(body)),
+            return mkStgLambda(dupOnto(args,stgLambdaArgs(body)),
                                stgLambdaBody(body));
         } else {
             return mkStgLambda(args,body);
@@ -150,3 +150,495 @@ StgVar mkStgVar( StgRhs rhs, Cell info )
 }
 
 /*-------------------------------------------------------------------------*/
+
+/* --------------------------------------------------------------------------
+ * STG pretty printer
+ *
+ * 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
+ *
+ * $RCSfile: stg.c,v $
+ * $Revision: 1.3 $
+ * $Date: 1999/02/03 17:08:39 $
+ * ------------------------------------------------------------------------*/
+
+/* --------------------------------------------------------------------------
+ * Local functions
+ * ------------------------------------------------------------------------*/
+
+static Void local pIndent        Args((Int));
+static Void local unlexVar       Args((Text));
+static Void local unlexCharConst Args((Cell));
+static Void local unlexStrConst  Args((Text));
+
+static Void local putStgVar       Args((StgVar));
+static Void local putStgVars      Args((List));
+static Void local putStgAtom      Args((StgAtom a));
+static Void local putStgAtoms     Args((List as));
+static Void local putStgBinds     Args((List));
+static Void local putStgExpr      Args((StgExpr));
+static Void local putStgRhs       Args((StgRhs));
+static Void local putStgPat       Args((StgPat));
+static Void local putStgPrimPat   Args((StgPrimPat));
+
+/* --------------------------------------------------------------------------
+ * Basic output routines:
+ * ------------------------------------------------------------------------*/
+
+static FILE *outputStream;             /* current output stream            */
+static Int  outColumn = 0;             /* current output column number     */
+                                           
+static Void local putChr( Int c );
+static Void local putStr( String s );
+static Void local putInt( Int n );
+static Void local putPtr( Ptr p );
+                                           
+static Void local putChr(c)            /* print single character           */
+Int c; {                                       
+    Putc(c,outputStream);                              
+    outColumn++;                                   
+}                                          
+                                           
+static Void local putStr(s)            /* print string                     */
+String s; {                                    
+    for (; *s; s++) {                                  
+        Putc(*s,outputStream);                             
+        outColumn++;                                   
+    }                                          
+}                                          
+                                           
+static Void local putInt(n)            /* print integer                    */
+Int n; {
+    static char intBuf[16];
+    sprintf(intBuf,"%d",n);
+    putStr(intBuf);
+}
+
+static Void local putPtr(p)            /* print pointer                    */
+Ptr p; {
+    static char intBuf[16];
+    sprintf(intBuf,"%p",p);
+    putStr(intBuf);
+}
+
+/* --------------------------------------------------------------------------
+ * Indentation and showing names/constants
+ * ------------------------------------------------------------------------*/
+
+static Void local pIndent(n)           /* indent to particular position    */
+Int n; {
+    outColumn = n;
+    while (0<n--) {
+        Putc(' ',outputStream);
+    }
+}
+
+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]=='(')
+        putStr(s);
+    else {
+        putChr('(');
+        putStr(s);
+        putChr(')');
+    }
+}
+
+static Void local unlexCharConst(c)
+Cell c; {
+    putChr('\'');
+    putStr(unlexChar(c,'\''));
+    putChr('\'');
+}
+
+static Void local unlexStrConst(t)
+Text t; {
+    String s            = textToStr(t);
+    static Char SO      = 14;          /* ASCII code for '\SO'             */
+    Bool   lastWasSO    = FALSE;
+    Bool   lastWasDigit = FALSE;
+    Bool   lastWasEsc   = FALSE;
+
+    putChr('\"');
+    for (; *s; s++) {
+        String ch = unlexChar(*s,'\"');
+        Char   c  = ' ';
+
+        if ((lastWasSO && *ch=='H') ||
+                (lastWasEsc && lastWasDigit && isascii(*ch) && isdigit(*ch)))
+            putStr("\\&");
+
+        lastWasEsc   = (*ch=='\\');
+        lastWasSO    = (*s==SO);
+        for (; *ch; c = *ch++)
+            putChr(*ch);
+        lastWasDigit = (isascii(c) && isdigit(c));
+    }
+    putChr('\"');
+}
+
+/* --------------------------------------------------------------------------
+ * Pretty printer for stg code:
+ * ------------------------------------------------------------------------*/
+
+static Void putStgAlts    ( Int left, List alts );
+static Void putStgPrimAlt ( Int left, List vs, StgExpr body );
+
+static Void local putStgVar(StgVar v) 
+{
+    if (isName(v)) {
+        unlexVar(name(v).text);
+    } else {
+        putStr("id");
+        putInt(-v);
+    }
+}
+
+static Void local putStgVars( List vs )
+{
+    for(; nonNull(vs); vs=tl(vs)) {
+        putStgVar(hd(vs));
+        putChr(' ');
+    }
+}
+
+static Void local putStgAtom( StgAtom a )
+{
+    switch (whatIs(a)) {
+    case STGVAR: 
+    case NAME: 
+            putStgVar(a);
+            break;
+    case CHARCELL: 
+            unlexCharConst(charOf(a));
+            putChr('#');
+            break;
+    case INTCELL: 
+            putInt(intOf(a));
+            putChr('#');
+            break;
+    case BIGCELL: 
+            putStr(bignumToString(a));
+            putChr('#');
+            break;
+    case FLOATCELL: 
+            putStr(floatToString(a));
+            putChr('#');
+            break;
+    case STRCELL: 
+            unlexStrConst(textOf(a));
+            break;
+    case PTRCELL: 
+            putPtr(ptrOf(a));
+            putChr('#');
+            break;
+    default: 
+            fprintf(stderr,"\nYoiks: "); printExp(stderr,a);
+            internal("putStgAtom");
+    }
+}
+
+Void putStgAtoms( List as )
+{
+    putChr('{');
+    while (nonNull(as)) {
+        putStgAtom(hd(as));
+        as=tl(as);
+        if (nonNull(as)) {
+            putChr(',');
+        }
+    }
+    putChr('}');
+}
+
+Void putStgPat( StgPat pat )
+{
+    putStgVar(pat);
+    if (nonNull(stgVarBody(pat))) {
+        StgDiscr d  = stgConCon(stgVarBody(pat));
+        List     vs = stgConArgs(stgVarBody(pat));
+        putChr('@');
+        switch (whatIs(d)) {
+        case NAME:
+            { 
+                unlexVar(name(d).text);
+                for (; nonNull(vs); vs=tl(vs)) {
+                    putChr(' ');
+                    putStgVar(hd(vs));
+                }
+                break;
+            }
+        case TUPLE: 
+            { 
+                putChr('(');
+                putStgVar(hd(vs));
+                vs=tl(vs);
+                while (nonNull(vs)) {
+                    putChr(',');
+                    putStgVar(hd(vs));
+                    vs=tl(vs);
+                }
+                putChr(')');
+                break;
+            }
+        default: 
+                fprintf(stderr,"\nYoiks: "); printExp(stderr,d);
+                internal("putStgPat");
+        }
+    }
+}
+
+Void putStgPrimPat( StgPrimPat pat )  
+{
+    putStgVar(pat);
+    if (nonNull(stgVarBody(pat))) {
+        StgExpr d  = stgVarBody(pat);
+        putChr('@');
+        switch (whatIs(d)) {
+        case INTCELL:
+            {
+                putInt(intOf(d));
+                putChr('#');
+                break;
+            }
+        default: 
+                fprintf(stderr,"\nYoiks: "); printExp(stderr,d);
+                internal("putStgPrimPat");
+        }
+    }
+    putChr(' ');
+}
+
+Void putStgBinds(binds)        /* pretty print locals           */
+List binds; {
+    Int left = outColumn;
+
+    putStr("let { ");
+    while (nonNull(binds)) {
+        Cell bind = hd(binds);
+        putStgVar(bind);
+        putStr(" = ");
+        putStgRhs(stgVarBody(bind));
+        putStr("\n");
+        binds = tl(binds);
+        if (nonNull(binds))
+            pIndent(left+6);
+    }
+    pIndent(left);
+    putStr("} in  ");
+}
+
+static Void putStgAlts( Int left, List alts )
+{
+    if (length(alts) == 1) {
+        StgCaseAlt alt = hd(alts);
+        putStr("{ ");
+        putStgPat(stgCaseAltPat(alt));
+        putStr(" ->\n");
+        pIndent(left);
+        putStgExpr(stgCaseAltBody(alt));
+        putStr("}");
+    } else {
+        putStr("{\n");
+        for (; nonNull(alts); alts=tl(alts)) {
+            StgCaseAlt alt = hd(alts);
+            pIndent(left+2);
+            putStgPat(stgCaseAltPat(alt));
+            putStr(" -> ");
+            putStgExpr(stgCaseAltBody(alt));
+            putStr("\n");
+        }
+        pIndent(left);
+        putStr("}\n");
+    }
+}
+
+static Void putStgPrimAlts( Int left, List alts )
+{
+    if (length(alts) == 1) {
+        StgPrimAlt alt = hd(alts);
+        putStr("{ ");
+        mapProc(putStgPrimPat,stgPrimAltPats(alt));
+        putStr(" ->\n");
+        pIndent(left);
+        putStgExpr(stgPrimAltBody(alt));
+        putStr("}");
+    } else {
+        putStr("{\n");
+        for (; nonNull(alts); alts=tl(alts)) {
+            StgPrimAlt alt = hd(alts);
+            pIndent(left+2);
+            mapProc(putStgPrimPat,stgPrimAltPats(alt));
+            putStr(" -> ");
+            putStgExpr(stgPrimAltBody(alt));
+            putStr("\n");
+        }
+        pIndent(left);
+        putStr("}\n");
+    }
+}
+
+Void putStgExpr( StgExpr e )                        /* pretty print expr */
+{
+    switch (whatIs(e)) {
+    case LETREC: 
+            putStgBinds(stgLetBinds(e));
+            putStgExpr(stgLetBody(e));
+            break;
+    case LAMBDA:
+        {   
+            Int left = outColumn;
+            putStr("\\ ");
+            putStgVars(stgLambdaArgs(e));
+            putStr("->\n");
+            pIndent(left+2);
+            putStgExpr(stgLambdaBody(e));
+            break;
+        }
+    case CASE: 
+        {
+            Int left = outColumn;
+            putStr("case ");
+            putStgExpr(stgCaseScrut(e));
+            putStr(" of ");
+            putStgAlts(left,stgCaseAlts(e));
+            break;
+        }
+    case PRIMCASE:
+        { 
+            Int  left = outColumn;
+            putStr("case# ");
+            putStgExpr(stgPrimCaseScrut(e));
+            putStr(" of ");
+            putStgPrimAlts(left,stgPrimCaseAlts(e));
+            break;
+        }
+    case STGPRIM: 
+        {
+            Cell op = stgPrimOp(e);
+            unlexVar(name(op).text);
+            putStgAtoms(stgPrimArgs(e));
+            break;
+        }
+    case STGAPP: 
+            putStgVar(stgAppFun(e));
+            putStgAtoms(stgAppArgs(e));
+            break;
+    case STGVAR: 
+    case NAME: 
+            putStgVar(e);
+            break;
+    default: 
+            fprintf(stderr,"\nYoiks: "); printExp(stderr,e);
+            internal("putStgExpr");
+    }
+}
+
+Void putStgRhs( StgRhs e )            /* print lifted definition         */
+{
+    switch (whatIs(e)) {
+    case STGCON:
+        {
+            Name   con  = stgConCon(e);
+            if (isTuple(con)) {
+                putStr("Tuple");
+                putInt(tupleOf(con));
+            } else {
+                unlexVar(name(con).text);
+            }
+            putStgAtoms(stgConArgs(e));
+            break;
+        }
+    default: 
+            putStgExpr(e);
+            break;
+    }
+}
+
+static void beginStgPP( FILE* fp );
+static void endStgPP( FILE* fp );
+
+static void beginStgPP( FILE* fp )
+{
+    outputStream = fp;
+    putChr('\n');
+    outColumn = 0;
+}
+
+static void endStgPP( FILE* fp )
+{
+    fflush(fp);
+}
+
+Void printStg(fp,b)              /* Pretty print sc defn on fp      */
+FILE  *fp;
+StgVar b; 
+{
+    beginStgPP(fp);
+    putStgVar(b);
+    putStr(" = ");
+    putStgRhs(stgVarBody(b));
+    putStr("\n");
+    endStgPP(fp);
+}
+
+#if DEBUG_PRINTER
+Void ppStg( StgVar v )
+{
+    if (debugCode) {
+        printStg(stdout,v);
+    }
+}
+
+Void ppStgExpr( StgExpr e )
+{
+    if (debugCode) {
+        beginStgPP(stdout);
+        putStgExpr(e);
+        endStgPP(stdout);
+    }
+}
+
+Void ppStgRhs( StgRhs rhs )
+{
+    if (debugCode) {
+        beginStgPP(stdout);
+        putStgRhs(rhs);
+        endStgPP(stdout);
+    }
+}
+
+Void ppStgAlts( List alts )
+{
+    if (debugCode) {
+        beginStgPP(stdout);
+        putStgAlts(0,alts);
+        endStgPP(stdout);
+    }
+}
+
+extern Void ppStgPrimAlts( List alts )
+{
+    if (debugCode) {
+        beginStgPP(stdout);
+        putStgPrimAlts(0,alts);
+        endStgPP(stdout);
+    }
+}
+
+extern Void ppStgVars( List vs )
+{
+    if (debugCode) {
+        beginStgPP(stdout);
+        printf("Vars: ");
+        putStgVars(vs);
+        printf("\n");
+        endStgPP(stdout);
+    }
+}
+#endif
+
+/*-------------------------------------------------------------------------*/