2 /* --------------------------------------------------------------------------
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.
13 * $Date: 1999/12/07 11:14:56 $
14 * ------------------------------------------------------------------------*/
21 #include "link.h" /* for nameTrue/False */
22 #include "Assembler.h" /* for AsmRep and primops */
24 /* --------------------------------------------------------------------------
26 * ------------------------------------------------------------------------*/
28 void* stgConInfo( StgDiscr d )
33 name(d).itbl = asmMkInfo(cfunOf(d),name(d).arity);
37 tycon(d).itbl = asmMkInfo(0,tupleOf(d));
40 internal("stgConInfo");
44 int stgDiscrTag( StgDiscr d )
52 internal("stgDiscrTag");
56 /* --------------------------------------------------------------------------
57 * Utility functions for manipulating STG syntax trees.
58 * ------------------------------------------------------------------------*/
60 List makeArgs( Int n )
64 args = cons(mkStgVar(NIL,NIL),args);
69 StgExpr makeStgLambda( List args, StgExpr body )
74 if (whatIs(body) == LAMBDA) {
75 return mkStgLambda(dupListOnto(args,stgLambdaArgs(body)),
78 return mkStgLambda(args,body);
83 StgExpr makeStgApp( StgVar fun, List args )
88 return mkStgApp(fun,args);
92 StgExpr makeStgLet( List binds, StgExpr body )
97 return mkStgLet(binds,body);
101 StgExpr makeStgIf( StgExpr cond, StgExpr e1, StgExpr e2 )
103 if (cond == nameTrue) {
105 } else if (cond == nameFalse) {
108 return mkStgCase(cond,doubleton(mkStgCaseAlt(nameTrue,NIL,e1),
109 mkStgCaseAlt(nameFalse,NIL,e2)));
140 StgVar mkStgVar( StgRhs rhs, Cell info )
142 return ap(STGVAR,triple(rhs,mkStgRep(PTR_REP),info));
146 /* --------------------------------------------------------------------------
148 * ------------------------------------------------------------------------*/
150 /* --------------------------------------------------------------------------
152 * ------------------------------------------------------------------------*/
154 static Void local pIndent Args((Int));
156 static Void local putStgVar Args((StgVar));
157 static Void local putStgVars Args((List));
158 static Void local putStgAtom Args((StgAtom a));
159 static Void local putStgAtoms Args((List as));
160 static Void local putStgBinds Args((List));
161 static Void local putStgExpr Args((StgExpr));
162 static Void local putStgRhs Args((StgRhs));
163 static Void local putStgPat Args((StgCaseAlt));
164 static Void local putStgPrimPat Args((StgPrimAlt));
168 /* --------------------------------------------------------------------------
169 * Indentation and showing names/constants
170 * ------------------------------------------------------------------------*/
172 static Void local pIndent(n) /* indent to particular position */
176 Putc(' ',outputStream);
181 /* --------------------------------------------------------------------------
182 * Pretty printer for stg code:
183 * ------------------------------------------------------------------------*/
185 static Void putStgAlts ( Int left, List alts );
187 static Void local putStgVar(StgVar v)
190 unlexVar(name(v).text);
195 putChr(charOf(stgVarRep(v)));
197 if (isInt(stgVarInfo(v))) {
199 putInt(intOf(stgVarInfo(v)));
205 static Void local putStgVars( List vs )
207 for(; nonNull(vs); vs=tl(vs)) {
213 static Void local putStgAtom( StgAtom a )
221 unlexCharConst(charOf(a));
229 putStr(bignumToString(a));
233 putStr(floatToString(a));
237 unlexStrConst(textOf(a));
243 case LETREC: case LAMBDA: case CASE: case PRIMCASE:
244 case STGAPP: case STGPRIM: case STGCON:
248 fprintf(stderr,"\nYoiks: "); printExp(stderr,a);
249 internal("putStgAtom");
253 Void putStgAtoms( List as )
256 while (nonNull(as)) {
266 Void putStgPat( StgCaseAlt alt )
268 if (whatIs(alt)==DEEFALT) {
269 putStgVar(stgDefaultVar(alt));
272 if (whatIs(alt)==CASEALT) {
273 List vs = stgCaseAltVars(alt);
274 if (whatIs(stgCaseAltCon(alt))==TUPLE) {
278 while (nonNull(vs)) {
286 if (whatIs(stgCaseAltCon(alt))==NAME) {
287 unlexVar(name(stgCaseAltCon(alt)).text);
288 for (; nonNull(vs); vs=tl(vs)) {
294 internal("putStgPat(2)");
297 internal("putStgPat(1)");
300 Void putStgPrimPat( StgVar v )
302 if (nonNull(stgVarBody(v))) {
303 StgExpr d = stgVarBody(v);
312 fprintf(stderr,"\nYoiks: "); printExp(stderr,d);
313 internal("putStgPrimPat");
321 Void putStgBinds(binds) /* pretty print locals */
323 Int left = outColumn;
326 while (nonNull(binds)) {
327 Cell bind = hd(binds);
330 putStgRhs(stgVarBody(bind));
340 static Void putStgAlts( Int left, List alts )
342 if (length(alts) == 1) {
343 StgCaseAlt alt = hd(alts);
348 if (isDefaultAlt(alt))
349 putStgExpr(stgDefaultBody(alt)); else
350 putStgExpr(stgCaseAltBody(alt));
354 for (; nonNull(alts); alts=tl(alts)) {
355 StgCaseAlt alt = hd(alts);
362 if (isDefaultAlt(alt))
363 putStgExpr(stgDefaultBody(alt)); else
364 putStgExpr(stgCaseAltBody(alt));
373 static Void putStgPrimAlts( Int left, List alts )
375 if (length(alts) == 1) {
376 StgPrimAlt alt = hd(alts);
378 mapProc(putStgPrimPat,stgPrimAltVars(alt));
381 putStgExpr(stgPrimAltBody(alt));
385 for (; nonNull(alts); alts=tl(alts)) {
386 StgPrimAlt alt = hd(alts);
388 mapProc(putStgPrimPat,stgPrimAltVars(alt));
390 putStgExpr(stgPrimAltBody(alt));
398 Void putStgExpr( StgExpr e ) /* pretty print expr */
400 if (isNull(e)) putStr("(putStgExpr:NIL)");else
405 Int left = outColumn;
406 putStgBinds(stgLetBinds(e));
407 if (whatIs(stgLetBody(e))==LETREC) {
408 putStr("\n"); pIndent(left);
410 if (whatIs(stgLetBody(e))==CASE) {
411 putStr("\n"); pIndent(left+2);
413 putStgExpr(stgLetBody(e));
418 Int left = outColumn;
420 putStgVars(stgLambdaArgs(e));
423 putStgExpr(stgLambdaBody(e));
428 Int left = outColumn;
430 putStgExpr(stgCaseScrut(e));
432 putStgAlts(left,stgCaseAlts(e));
437 /* a hack; not for regular use */
438 putStgAlts(outColumn,singleton(e));
441 /* a hack; not for regular use */
442 putStgPrimAlts(outColumn,singleton(e));
446 Int left = outColumn;
448 putStgExpr(stgPrimCaseScrut(e));
450 putStgPrimAlts(left,stgPrimCaseAlts(e));
455 Cell op = stgPrimOp(e);
456 unlexVarStr(asmGetPrimopName(name(op).primop));
457 putStgAtoms(stgPrimArgs(e));
461 putStgExpr(stgAppFun(e));
462 putStgAtoms(stgAppArgs(e));
480 /* hope that it's really a list of StgExprs, so map putStgExpr
482 for (;nonNull(e);e=tl(e)) {
488 internal("putStgExpr");
489 /* Pretend it's a list of algebraic case alternatives. Used for
490 printing the case-alt lists attached to BCOs which are return
491 continuations. Very useful for debugging. An appalling hack tho.
493 /* fprintf(stderr, " "); putStgAlts(3,e); */
497 Void putStgRhs( StgRhs e ) /* print lifted definition */
502 Name con = stgConCon(e);
505 putInt(tupleOf(con));
507 unlexVar(name(con).text);
509 putStgAtoms(stgConArgs(e));
518 static void beginStgPP( FILE* fp );
519 static void endStgPP( FILE* fp );
521 static void beginStgPP( FILE* fp )
525 fflush(stderr); fflush(stdout);
528 static void endStgPP( FILE* fp )
533 Void printStg(fp,b) /* Pretty print sc defn on fp */
539 n = nameFromStgVar(b);
541 putStr(textToStr(name(n).text));
546 putStgRhs(stgVarBody(b));
551 #if 1 /*DEBUG_PRINTER*/
552 Void ppStg( StgVar v )
557 Void ppStgExpr( StgExpr e )
564 Void ppStgRhs( StgRhs rhs )
571 Void ppStgAlts( List alts )
578 extern Void ppStgPrimAlts( List alts )
581 putStgPrimAlts(0,alts);
585 extern Void ppStgVars( List vs )
595 /*-------------------------------------------------------------------------*/