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/10/15 21:40:57 $
14 * ------------------------------------------------------------------------*/
21 #include "link.h" /* for nameTrue/False */
22 #include "Assembler.h" /* for AsmRep and primops */
24 /* --------------------------------------------------------------------------
26 * ------------------------------------------------------------------------*/
28 void* stgConInfo( StgDiscr d )
32 return asmMkInfo(cfunOf(d),name(d).arity);
34 return asmMkInfo(0,tupleOf(d));
36 internal("stgConInfo");
40 int stgDiscrTag( StgDiscr d )
48 internal("stgDiscrTag");
52 /* --------------------------------------------------------------------------
53 * Utility functions for manipulating STG syntax trees.
54 * ------------------------------------------------------------------------*/
56 List makeArgs( Int n )
60 args = cons(mkStgVar(NIL,NIL),args);
65 StgExpr makeStgLambda( List args, StgExpr body )
70 if (whatIs(body) == LAMBDA) {
71 return mkStgLambda(dupListOnto(args,stgLambdaArgs(body)),
74 return mkStgLambda(args,body);
79 StgExpr makeStgApp( StgVar fun, List args )
84 return mkStgApp(fun,args);
88 StgExpr makeStgLet( List binds, StgExpr body )
93 return mkStgLet(binds,body);
97 StgExpr makeStgIf( StgExpr cond, StgExpr e1, StgExpr e2 )
99 if (cond == nameTrue) {
101 } else if (cond == nameFalse) {
104 return mkStgCase(cond,doubleton(mkStgCaseAlt(nameTrue,NIL,e1),
105 mkStgCaseAlt(nameFalse,NIL,e2)));
136 StgVar mkStgVar( StgRhs rhs, Cell info )
138 return ap(STGVAR,triple(rhs,mkStgRep(PTR_REP),info));
142 /* --------------------------------------------------------------------------
144 * ------------------------------------------------------------------------*/
146 /* --------------------------------------------------------------------------
148 * ------------------------------------------------------------------------*/
150 static Void local pIndent Args((Int));
152 static Void local putStgVar Args((StgVar));
153 static Void local putStgVars Args((List));
154 static Void local putStgAtom Args((StgAtom a));
155 static Void local putStgAtoms Args((List as));
156 static Void local putStgBinds Args((List));
157 static Void local putStgExpr Args((StgExpr));
158 static Void local putStgRhs Args((StgRhs));
159 static Void local putStgPat Args((StgCaseAlt));
160 static Void local putStgPrimPat Args((StgPrimAlt));
164 /* --------------------------------------------------------------------------
165 * Indentation and showing names/constants
166 * ------------------------------------------------------------------------*/
168 static Void local pIndent(n) /* indent to particular position */
172 Putc(' ',outputStream);
177 /* --------------------------------------------------------------------------
178 * Pretty printer for stg code:
179 * ------------------------------------------------------------------------*/
181 static Void putStgAlts ( Int left, List alts );
183 static Void local putStgVar(StgVar v)
186 if (name(v).inlineMe) putStr("IL__");
187 unlexVar(name(v).text);
192 putChr(charOf(stgVarRep(v)));
194 if (isInt(stgVarInfo(v))) {
196 putInt(intOf(stgVarInfo(v)));
202 static Void local putStgVars( List vs )
204 for(; nonNull(vs); vs=tl(vs)) {
210 static Void local putStgAtom( StgAtom a )
218 unlexCharConst(charOf(a));
226 putStr(bignumToString(a));
230 putStr(floatToString(a));
234 unlexStrConst(textOf(a));
240 case LETREC: case LAMBDA: case CASE: case PRIMCASE:
241 case STGAPP: case STGPRIM: case STGCON:
245 fprintf(stderr,"\nYoiks: "); printExp(stderr,a);
246 internal("putStgAtom");
250 Void putStgAtoms( List as )
253 while (nonNull(as)) {
263 Void putStgPat( StgCaseAlt alt )
265 if (whatIs(alt)==DEEFALT) {
266 putStgVar(stgDefaultVar(alt));
269 if (whatIs(alt)==CASEALT) {
270 List vs = stgCaseAltVars(alt);
271 if (whatIs(stgCaseAltCon(alt))==TUPLE) {
275 while (nonNull(vs)) {
283 if (whatIs(stgCaseAltCon(alt))==NAME) {
284 unlexVar(name(stgCaseAltCon(alt)).text);
285 for (; nonNull(vs); vs=tl(vs)) {
291 internal("putStgPat(2)");
294 internal("putStgPat(1)");
297 Void putStgPrimPat( StgVar v )
299 if (nonNull(stgVarBody(v))) {
300 StgExpr d = stgVarBody(v);
309 fprintf(stderr,"\nYoiks: "); printExp(stderr,d);
310 internal("putStgPrimPat");
318 Void putStgBinds(binds) /* pretty print locals */
320 Int left = outColumn;
323 while (nonNull(binds)) {
324 Cell bind = hd(binds);
327 putStgRhs(stgVarBody(bind));
337 static Void putStgAlts( Int left, List alts )
339 if (length(alts) == 1) {
340 StgCaseAlt alt = hd(alts);
345 if (isDefaultAlt(alt))
346 putStgExpr(stgDefaultBody(alt)); else
347 putStgExpr(stgCaseAltBody(alt));
351 for (; nonNull(alts); alts=tl(alts)) {
352 StgCaseAlt alt = hd(alts);
359 if (isDefaultAlt(alt))
360 putStgExpr(stgDefaultBody(alt)); else
361 putStgExpr(stgCaseAltBody(alt));
370 static Void putStgPrimAlts( Int left, List alts )
372 if (length(alts) == 1) {
373 StgPrimAlt alt = hd(alts);
375 mapProc(putStgPrimPat,stgPrimAltVars(alt));
378 putStgExpr(stgPrimAltBody(alt));
382 for (; nonNull(alts); alts=tl(alts)) {
383 StgPrimAlt alt = hd(alts);
385 mapProc(putStgPrimPat,stgPrimAltVars(alt));
387 putStgExpr(stgPrimAltBody(alt));
395 Void putStgExpr( StgExpr e ) /* pretty print expr */
397 if (isNull(e)) putStr("(putStgExpr:NIL)");else
402 Int left = outColumn;
403 putStgBinds(stgLetBinds(e));
404 if (whatIs(stgLetBody(e))==LETREC) {
405 putStr("\n"); pIndent(left);
407 if (whatIs(stgLetBody(e))==CASE) {
408 putStr("\n"); pIndent(left+2);
410 putStgExpr(stgLetBody(e));
415 Int left = outColumn;
417 putStgVars(stgLambdaArgs(e));
420 putStgExpr(stgLambdaBody(e));
425 Int left = outColumn;
427 putStgExpr(stgCaseScrut(e));
429 putStgAlts(left,stgCaseAlts(e));
434 /* a hack; not for regular use */
435 putStgAlts(outColumn,singleton(e));
438 /* a hack; not for regular use */
439 putStgPrimAlts(outColumn,singleton(e));
443 Int left = outColumn;
445 putStgExpr(stgPrimCaseScrut(e));
447 putStgPrimAlts(left,stgPrimCaseAlts(e));
452 Cell op = stgPrimOp(e);
453 unlexVar(name(op).text);
454 putStgAtoms(stgPrimArgs(e));
458 putStgExpr(stgAppFun(e));
459 putStgAtoms(stgAppArgs(e));
477 /* hope that it's really a list of StgExprs, so map putStgExpr
479 for (;nonNull(e);e=tl(e)) {
485 internal("putStgExpr");
486 /* Pretend it's a list of algebraic case alternatives. Used for
487 printing the case-alt lists attached to BCOs which are return
488 continuations. Very useful for debugging. An appalling hack tho.
490 /* fprintf(stderr, " "); putStgAlts(3,e); */
494 Void putStgRhs( StgRhs e ) /* print lifted definition */
499 Name con = stgConCon(e);
502 putInt(tupleOf(con));
504 unlexVar(name(con).text);
506 putStgAtoms(stgConArgs(e));
515 static void beginStgPP( FILE* fp );
516 static void endStgPP( FILE* fp );
518 static void beginStgPP( FILE* fp )
522 fflush(stderr); fflush(stdout);
525 static void endStgPP( FILE* fp )
530 Void printStg(fp,b) /* Pretty print sc defn on fp */
536 n = nameFromStgVar(b);
538 if (name(n).inlineMe) { putStr("INLINE\n"); pIndent(0); };
539 putStr(textToStr(name(n).text));
544 putStgRhs(stgVarBody(b));
549 #if 1 /*DEBUG_PRINTER*/
550 Void ppStg( StgVar v )
555 Void ppStgExpr( StgExpr e )
562 Void ppStgRhs( StgRhs rhs )
569 Void ppStgAlts( List alts )
576 extern Void ppStgPrimAlts( List alts )
579 putStgPrimAlts(0,alts);
583 extern Void ppStgVars( List vs )
593 /*-------------------------------------------------------------------------*/