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: 2000/03/10 14:53:00 $
14 * ------------------------------------------------------------------------*/
21 #include "link.h" /* for nameTrue/False */
22 #include "Assembler.h" /* for AsmRep and primops */
24 /* --------------------------------------------------------------------------
26 * ------------------------------------------------------------------------*/
28 /* Make an info table for a constructor or tuple. */
29 void* stgConInfo ( StgDiscr d )
37 name(d).itbl = asmMkInfo(tag,name(d).arity);
43 tycon(d).itbl = asmMkInfo(tag,tupleOf(d));
47 internal("stgConInfo");
51 /* Return the tag for a constructor or tuple, starting at zero. */
52 int stgDiscrTag ( StgDiscr d )
56 case NAME: tag = cfunOf(d); break;
58 default: internal("stgDiscrTag");
64 /* --------------------------------------------------------------------------
65 * Utility functions for manipulating STG syntax trees.
66 * ------------------------------------------------------------------------*/
68 List makeArgs( Int n )
72 args = cons(mkStgVar(NIL,NIL),args);
77 StgExpr makeStgLambda( List args, StgExpr body )
82 if (whatIs(body) == LAMBDA) {
83 return mkStgLambda(dupListOnto(args,stgLambdaArgs(body)),
86 return mkStgLambda(args,body);
91 StgExpr makeStgApp( StgVar fun, List args )
96 return mkStgApp(fun,args);
100 StgExpr makeStgLet( List binds, StgExpr body )
105 return mkStgLet(binds,body);
109 StgExpr makeStgIf( StgExpr cond, StgExpr e1, StgExpr e2 )
111 if (cond == nameTrue) {
113 } else if (cond == nameFalse) {
116 return mkStgCase(cond,doubleton(mkStgCaseAlt(nameTrue,NIL,e1),
117 mkStgCaseAlt(nameFalse,NIL,e2)));
148 StgVar mkStgVar( StgRhs rhs, Cell info )
150 return ap(STGVAR,triple(rhs,mkStgRep(PTR_REP),info));
154 /* --------------------------------------------------------------------------
156 * ------------------------------------------------------------------------*/
158 /* --------------------------------------------------------------------------
160 * ------------------------------------------------------------------------*/
162 static Void local pIndent Args((Int));
164 static Void local putStgVar Args((StgVar));
165 static Void local putStgVars Args((List));
166 static Void local putStgAtom Args((StgAtom a));
167 static Void local putStgAtoms Args((List as));
168 static Void local putStgBinds Args((List));
169 static Void local putStgExpr Args((StgExpr));
170 static Void local putStgRhs Args((StgRhs));
171 static Void local putStgPat Args((StgCaseAlt));
172 static Void local putStgPrimPat Args((StgPrimAlt));
176 /* --------------------------------------------------------------------------
177 * Indentation and showing names/constants
178 * ------------------------------------------------------------------------*/
180 static Void local pIndent(n) /* indent to particular position */
184 Putc(' ',outputStream);
189 /* --------------------------------------------------------------------------
190 * Pretty printer for stg code:
191 * ------------------------------------------------------------------------*/
193 static Void putStgAlts ( Int left, List alts );
195 static Void local putStgVar(StgVar v)
198 unlexVar(name(v).text);
203 putChr(charOf(stgVarRep(v)));
205 if (isInt(stgVarInfo(v))) {
207 putInt(intOf(stgVarInfo(v)));
213 static Void local putStgVars( List vs )
215 for(; nonNull(vs); vs=tl(vs)) {
221 static Void local putStgAtom( StgAtom a )
229 unlexCharConst(charOf(a));
237 putStr(bignumToString(a));
241 putStr(floatToString(a));
245 unlexStrConst(textOf(a));
251 case LETREC: case LAMBDA: case CASE: case PRIMCASE:
252 case STGAPP: case STGPRIM: case STGCON:
256 fprintf(stderr,"\nYoiks: "); printExp(stderr,a);
257 internal("putStgAtom");
261 Void putStgAtoms( List as )
264 while (nonNull(as)) {
274 Void putStgPat( StgCaseAlt alt )
276 if (whatIs(alt)==DEEFALT) {
277 putStgVar(stgDefaultVar(alt));
280 if (whatIs(alt)==CASEALT) {
281 List vs = stgCaseAltVars(alt);
282 if (whatIs(stgCaseAltCon(alt))==TUPLE) {
286 while (nonNull(vs)) {
294 if (whatIs(stgCaseAltCon(alt))==NAME) {
295 unlexVar(name(stgCaseAltCon(alt)).text);
296 for (; nonNull(vs); vs=tl(vs)) {
302 internal("putStgPat(2)");
305 internal("putStgPat(1)");
308 Void putStgPrimPat( StgVar v )
310 if (nonNull(stgVarBody(v))) {
311 StgExpr d = stgVarBody(v);
320 fprintf(stderr,"\nYoiks: "); printExp(stderr,d);
321 internal("putStgPrimPat");
329 Void putStgBinds(binds) /* pretty print locals */
331 Int left = outColumn;
334 while (nonNull(binds)) {
335 Cell bind = hd(binds);
338 putStgRhs(stgVarBody(bind));
348 static Void putStgAlts( Int left, List alts )
350 if (length(alts) == 1) {
351 StgCaseAlt alt = hd(alts);
356 if (isDefaultAlt(alt))
357 putStgExpr(stgDefaultBody(alt)); else
358 putStgExpr(stgCaseAltBody(alt));
362 for (; nonNull(alts); alts=tl(alts)) {
363 StgCaseAlt alt = hd(alts);
370 if (isDefaultAlt(alt))
371 putStgExpr(stgDefaultBody(alt)); else
372 putStgExpr(stgCaseAltBody(alt));
381 static Void putStgPrimAlts( Int left, List alts )
383 if (length(alts) == 1) {
384 StgPrimAlt alt = hd(alts);
386 mapProc(putStgPrimPat,stgPrimAltVars(alt));
389 putStgExpr(stgPrimAltBody(alt));
393 for (; nonNull(alts); alts=tl(alts)) {
394 StgPrimAlt alt = hd(alts);
396 mapProc(putStgPrimPat,stgPrimAltVars(alt));
398 putStgExpr(stgPrimAltBody(alt));
406 Void putStgExpr( StgExpr e ) /* pretty print expr */
408 if (isNull(e)) putStr("(putStgExpr:NIL)");else
413 Int left = outColumn;
414 putStgBinds(stgLetBinds(e));
415 if (whatIs(stgLetBody(e))==LETREC) {
416 putStr("\n"); pIndent(left);
418 if (whatIs(stgLetBody(e))==CASE) {
419 putStr("\n"); pIndent(left+2);
421 putStgExpr(stgLetBody(e));
426 Int left = outColumn;
428 putStgVars(stgLambdaArgs(e));
431 putStgExpr(stgLambdaBody(e));
436 Int left = outColumn;
438 putStgExpr(stgCaseScrut(e));
440 putStgAlts(left,stgCaseAlts(e));
445 /* a hack; not for regular use */
446 putStgAlts(outColumn,singleton(e));
449 /* a hack; not for regular use */
450 putStgPrimAlts(outColumn,singleton(e));
454 Int left = outColumn;
456 putStgExpr(stgPrimCaseScrut(e));
458 putStgPrimAlts(left,stgPrimCaseAlts(e));
463 Cell op = stgPrimOp(e);
464 unlexVarStr(asmGetPrimopName(name(op).primop));
465 putStgAtoms(stgPrimArgs(e));
469 putStgExpr(stgAppFun(e));
470 putStgAtoms(stgAppArgs(e));
488 /* hope that it's really a list of StgExprs, so map putStgExpr
490 for (;nonNull(e);e=tl(e)) {
496 internal("putStgExpr");
497 /* Pretend it's a list of algebraic case alternatives. Used for
498 printing the case-alt lists attached to BCOs which are return
499 continuations. Very useful for debugging. An appalling hack tho.
501 /* fprintf(stderr, " "); putStgAlts(3,e); */
505 Void putStgRhs( StgRhs e ) /* print lifted definition */
510 Name con = stgConCon(e);
513 putInt(tupleOf(con));
515 unlexVar(name(con).text);
517 putStgAtoms(stgConArgs(e));
526 static void beginStgPP( FILE* fp );
527 static void endStgPP( FILE* fp );
529 static void beginStgPP( FILE* fp )
533 fflush(stderr); fflush(stdout);
536 static void endStgPP( FILE* fp )
541 Void printStg(fp,b) /* Pretty print sc defn on fp */
547 n = nameFromStgVar(b);
549 putStr(textToStr(name(n).text));
554 putStgRhs(stgVarBody(b));
559 Void ppStg( StgVar v )
564 Void ppStgExpr( StgExpr e )
571 Void ppStgRhs( StgRhs rhs )
578 Void ppStgAlts( List alts )
585 extern Void ppStgPrimAlts( List alts )
588 putStgPrimAlts(0,alts);
592 extern Void ppStgVars( List vs )
601 /*-------------------------------------------------------------------------*/