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 20:03:36 $
14 * ------------------------------------------------------------------------*/
21 #include "Assembler.h" /* for AsmRep and primops */
23 /* --------------------------------------------------------------------------
25 * ------------------------------------------------------------------------*/
27 /* Make an info table for a constructor or tuple. */
28 void* stgConInfo ( StgDiscr d )
36 name(d).itbl = asmMkInfo(tag,name(d).arity);
42 tycon(d).itbl = asmMkInfo(tag,tupleOf(d));
46 internal("stgConInfo");
50 /* Return the tag for a constructor or tuple, starting at zero. */
51 int stgDiscrTag ( StgDiscr d )
55 case NAME: tag = cfunOf(d); break;
57 default: internal("stgDiscrTag");
63 /* --------------------------------------------------------------------------
64 * Utility functions for manipulating STG syntax trees.
65 * ------------------------------------------------------------------------*/
67 List makeArgs( Int n )
71 args = cons(mkStgVar(NIL,NIL),args);
76 StgExpr makeStgLambda( List args, StgExpr body )
81 if (whatIs(body) == LAMBDA) {
82 return mkStgLambda(dupListOnto(args,stgLambdaArgs(body)),
85 return mkStgLambda(args,body);
90 StgExpr makeStgApp( StgVar fun, List args )
95 return mkStgApp(fun,args);
99 StgExpr makeStgLet( List binds, StgExpr body )
104 return mkStgLet(binds,body);
108 StgExpr makeStgIf( StgExpr cond, StgExpr e1, StgExpr e2 )
110 if (cond == nameTrue) {
112 } else if (cond == nameFalse) {
115 return mkStgCase(cond,doubleton(mkStgCaseAlt(nameTrue,NIL,e1),
116 mkStgCaseAlt(nameFalse,NIL,e2)));
147 StgVar mkStgVar( StgRhs rhs, Cell info )
149 return ap(STGVAR,triple(rhs,mkStgRep(PTR_REP),info));
153 /* --------------------------------------------------------------------------
155 * ------------------------------------------------------------------------*/
157 /* --------------------------------------------------------------------------
159 * ------------------------------------------------------------------------*/
161 static Void local pIndent Args((Int));
163 static Void local putStgVar Args((StgVar));
164 static Void local putStgVars Args((List));
165 static Void local putStgAtom Args((StgAtom a));
166 static Void local putStgAtoms Args((List as));
167 static Void local putStgBinds Args((List));
168 static Void local putStgExpr Args((StgExpr));
169 static Void local putStgRhs Args((StgRhs));
170 static Void local putStgPat Args((StgCaseAlt));
171 static Void local putStgPrimPat Args((StgPrimAlt));
175 /* --------------------------------------------------------------------------
176 * Indentation and showing names/constants
177 * ------------------------------------------------------------------------*/
179 static Void local pIndent(n) /* indent to particular position */
183 Putc(' ',outputStream);
188 /* --------------------------------------------------------------------------
189 * Pretty printer for stg code:
190 * ------------------------------------------------------------------------*/
192 static Void putStgAlts ( Int left, List alts );
194 static Void local putStgVar(StgVar v)
197 unlexVar(name(v).text);
202 putChr(charOf(stgVarRep(v)));
204 if (isInt(stgVarInfo(v))) {
206 putInt(intOf(stgVarInfo(v)));
212 static Void local putStgVars( List vs )
214 for(; nonNull(vs); vs=tl(vs)) {
220 static Void local putStgAtom( StgAtom a )
228 unlexCharConst(charOf(a));
236 putStr(bignumToString(a));
240 putStr(floatToString(a));
244 unlexStrConst(textOf(a));
250 case LETREC: case LAMBDA: case CASE: case PRIMCASE:
251 case STGAPP: case STGPRIM: case STGCON:
255 fprintf(stderr,"\nYoiks: "); printExp(stderr,a);
256 internal("putStgAtom");
260 Void putStgAtoms( List as )
263 while (nonNull(as)) {
273 Void putStgPat( StgCaseAlt alt )
275 if (whatIs(alt)==DEEFALT) {
276 putStgVar(stgDefaultVar(alt));
279 if (whatIs(alt)==CASEALT) {
280 List vs = stgCaseAltVars(alt);
281 if (whatIs(stgCaseAltCon(alt))==TUPLE) {
285 while (nonNull(vs)) {
293 if (whatIs(stgCaseAltCon(alt))==NAME) {
294 unlexVar(name(stgCaseAltCon(alt)).text);
295 for (; nonNull(vs); vs=tl(vs)) {
301 internal("putStgPat(2)");
304 internal("putStgPat(1)");
307 Void putStgPrimPat( StgVar v )
309 if (nonNull(stgVarBody(v))) {
310 StgExpr d = stgVarBody(v);
319 fprintf(stderr,"\nYoiks: "); printExp(stderr,d);
320 internal("putStgPrimPat");
328 Void putStgBinds(binds) /* pretty print locals */
330 Int left = outColumn;
333 while (nonNull(binds)) {
334 Cell bind = hd(binds);
337 putStgRhs(stgVarBody(bind));
347 static Void putStgAlts( Int left, List alts )
349 if (length(alts) == 1) {
350 StgCaseAlt alt = hd(alts);
355 if (isDefaultAlt(alt))
356 putStgExpr(stgDefaultBody(alt)); else
357 putStgExpr(stgCaseAltBody(alt));
361 for (; nonNull(alts); alts=tl(alts)) {
362 StgCaseAlt alt = hd(alts);
369 if (isDefaultAlt(alt))
370 putStgExpr(stgDefaultBody(alt)); else
371 putStgExpr(stgCaseAltBody(alt));
380 static Void putStgPrimAlts( Int left, List alts )
382 if (length(alts) == 1) {
383 StgPrimAlt alt = hd(alts);
385 mapProc(putStgPrimPat,stgPrimAltVars(alt));
388 putStgExpr(stgPrimAltBody(alt));
392 for (; nonNull(alts); alts=tl(alts)) {
393 StgPrimAlt alt = hd(alts);
395 mapProc(putStgPrimPat,stgPrimAltVars(alt));
397 putStgExpr(stgPrimAltBody(alt));
405 Void putStgExpr( StgExpr e ) /* pretty print expr */
407 if (isNull(e)) putStr("(putStgExpr:NIL)");else
412 Int left = outColumn;
413 putStgBinds(stgLetBinds(e));
414 if (whatIs(stgLetBody(e))==LETREC) {
415 putStr("\n"); pIndent(left);
417 if (whatIs(stgLetBody(e))==CASE) {
418 putStr("\n"); pIndent(left+2);
420 putStgExpr(stgLetBody(e));
425 Int left = outColumn;
427 putStgVars(stgLambdaArgs(e));
430 putStgExpr(stgLambdaBody(e));
435 Int left = outColumn;
437 putStgExpr(stgCaseScrut(e));
439 putStgAlts(left,stgCaseAlts(e));
444 /* a hack; not for regular use */
445 putStgAlts(outColumn,singleton(e));
448 /* a hack; not for regular use */
449 putStgPrimAlts(outColumn,singleton(e));
453 Int left = outColumn;
455 putStgExpr(stgPrimCaseScrut(e));
457 putStgPrimAlts(left,stgPrimCaseAlts(e));
462 Cell op = stgPrimOp(e);
463 unlexVarStr(asmGetPrimopName(name(op).primop));
464 putStgAtoms(stgPrimArgs(e));
468 putStgExpr(stgAppFun(e));
469 putStgAtoms(stgAppArgs(e));
487 /* hope that it's really a list of StgExprs, so map putStgExpr
489 for (;nonNull(e);e=tl(e)) {
495 internal("putStgExpr");
496 /* Pretend it's a list of algebraic case alternatives. Used for
497 printing the case-alt lists attached to BCOs which are return
498 continuations. Very useful for debugging. An appalling hack tho.
500 /* fprintf(stderr, " "); putStgAlts(3,e); */
504 Void putStgRhs( StgRhs e ) /* print lifted definition */
509 Name con = stgConCon(e);
512 putInt(tupleOf(con));
514 unlexVar(name(con).text);
516 putStgAtoms(stgConArgs(e));
525 static void beginStgPP( FILE* fp );
526 static void endStgPP( FILE* fp );
528 static void beginStgPP( FILE* fp )
532 fflush(stderr); fflush(stdout);
535 static void endStgPP( FILE* fp )
540 Void printStg(fp,b) /* Pretty print sc defn on fp */
546 n = nameFromStgVar(b);
548 putStr(textToStr(name(n).text));
553 putStgRhs(stgVarBody(b));
558 Void ppStg( StgVar v )
563 Void ppStgExpr( StgExpr e )
570 Void ppStgRhs( StgRhs rhs )
577 Void ppStgAlts( List alts )
584 extern Void ppStgPrimAlts( List alts )
587 putStgPrimAlts(0,alts);
591 extern Void ppStgVars( List vs )
600 /*-------------------------------------------------------------------------*/