[project @ 2000-12-19 16:48:35 by sewardj]
[ghc-hetmet.git] / ghc / rts / Disassembler.c
1
2 /* -----------------------------------------------------------------------------
3  * Bytecode disassembler
4  *
5  * Copyright (c) 1994-1998.
6  *
7  * $RCSfile: Disassembler.c,v $
8  * $Revision: 1.15 $
9  * $Date: 2000/12/19 16:48:35 $
10  * ---------------------------------------------------------------------------*/
11
12 #if 0
13
14 #include "Rts.h"
15
16 #ifdef INTERPRETER
17
18 #include "RtsUtils.h"
19 #include "Bytecodes.h"
20 #include "Assembler.h"
21 #include "Printer.h"
22 #include "Disassembler.h"
23 #include "Interpreter.h"
24
25 /* --------------------------------------------------------------------------
26  * Disassembler
27  * ------------------------------------------------------------------------*/
28
29 static int disInstr ( StgBCO *bco, int pc )
30 {
31    StgArrWords* instr_arr = bco->instrs;
32    UShort*      instrs    = (UShort*)(&instr_arr->payload[0]);
33
34    switch (instrs[pc++]) {
35       case i_ARGCHECK: 
36          fprintf(stderr, "ARGCHECK %d\n", instrs[pc] );
37          pc += 1; break;
38       case i_PUSH_L: 
39          fprintf(stderr, "PUSH_L   %d\n", instrs[pc] );
40          pc += 1; break;
41       case i_PUSH_LL:
42          fprintf(stderr, "PUSH_LL  %d %d\n", instrs[pc], instrs[pc+1] ); 
43          pc += 2; break;
44       case i_PUSH_LLL:
45          fprintf(stderr, "PUSH_LLL %d %d %d\n", instrs[pc], instrs[pc+1], 
46                                                             instrs[pc+2] ); 
47          pc += 3; break;
48       case i_PUSH_G:
49          fprintf(stderr, "PUSH_G   " ); printPtr( ptrs[instrs[pc]] ); 
50          pc += 1; break;
51       case i_PUSH_AS:
52          fprintf(stderr, "PUSH_AS  " ); printPtr( ptrs[instrs[pc]] );
53          fprintf(stderr, " 0x%x", literals[instrs[pc+1]] );
54          pc += 2; break;
55       case i_PUSH_UBX:
56          fprintf(stderr, "PUSH_UBX ");
57          for (i = 0; i < instrs[pc+1]; i++) 
58             fprintf(stderr, "0x%x ", literals[i + instrs[pc]] );
59          fprintf(stderr, "\n");
60          pc += 2; break;
61       case i_PUSH_TAG:
62          fprintf(stderr, "PUSH_TAG %d\n", instrs[pc] );
63          pc += 1; break;
64       case i_SLIDE: 
65          fprintf(stderr, "SLIDE    %d down by %d\n", instrs[pc], instrs[pc+1] );
66          pc += 2; break;
67       case i_ALLOC:
68          fprintf(stderr, "ALLOC    %d words\n", instrs[pc] );
69          pc += 1; break;
70       case i_MKAP:
71          fprintf(stderr, "MKAP     %d words, %d stkoff\n", instrs[pc+1], 
72                                                            instrs[pc] );
73          pc += 2; break;
74       case i_UNPACK:
75          fprintf(stderr, "UNPACK   %d\n", instrs[pc] );
76          pc += 1; break;
77       case i_UPK_TAG:
78          fprintf(stderr, "UPK_TAG  %d words, %d conoff, %d stkoff\n",
79                          instrs[pc], instrs[pc+1], instrs[pc+2] );
80          pc += 3; break;
81       case i_PACK:
82          fprintf(stderr, "PACK     %d words with itbl ", instrs[pc+1] );
83          printPtr( itbls[instrs[pc]] );
84          pc += 2; break;
85       
86       case i_TESTLT_I:
87          
88 pc = disLitN ( bco, pc ); break;
89    case i_TESTEQ_I: pc = disLitNInt ( bco, pc );
90    }
91 }
92
93
94 static InstrPtr disNone         ( StgBCO *bco, InstrPtr pc, char* i );
95 static InstrPtr disInt          ( StgBCO *bco, InstrPtr pc, char* i );
96 static InstrPtr disIntInt       ( StgBCO *bco, InstrPtr pc, char* i );
97 static InstrPtr disInfo         ( StgBCO *bco, InstrPtr pc, char* i );
98 static InstrPtr disConstPtr     ( StgBCO *bco, InstrPtr pc, char* i );
99 static InstrPtr disConstInt     ( StgBCO *bco, InstrPtr pc, char* i );
100 static InstrPtr disConstChar    ( StgBCO *bco, InstrPtr pc, char* i );
101 static InstrPtr disConstFloat   ( StgBCO *bco, InstrPtr pc, char* i );
102
103 static InstrPtr disNone      ( StgBCO *bco, InstrPtr pc, char* i )
104 {
105     fprintf(stderr,"%s",i);
106     return pc;
107 }
108
109 static InstrPtr disInt       ( StgBCO *bco, InstrPtr pc, char* i )
110 {
111     StgInt x = bcoInstr(bco,pc++);
112     ASSERT(pc <= bco->n_instrs);
113     fprintf(stderr,"%s %d",i,x);
114     return pc;
115 }
116
117 static InstrPtr disInt16      ( StgBCO *bco, InstrPtr pc, char* i )
118 {
119     StgInt x = bcoInstr16(bco,pc); pc+=2;
120     ASSERT(pc <= bco->n_instrs);
121     fprintf(stderr,"%s %d",i,x);
122     return pc;
123 }
124
125 static InstrPtr disIntInt    ( StgBCO *bco, InstrPtr pc, char* i )
126 {
127     StgInt x = bcoInstr(bco,pc++);
128     StgInt y = bcoInstr(bco,pc++);
129     fprintf(stderr,"%s %d %d",i,x,y);
130     return pc;
131 }
132
133 static InstrPtr disIntInt16  ( StgBCO *bco, InstrPtr pc, char* i )
134 {
135     StgInt x, y;
136     x = bcoInstr16(bco,pc); pc += 2;
137     y = bcoInstr16(bco,pc); pc += 2;
138     fprintf(stderr,"%s %d %d",i,x,y);
139     return pc;
140 }
141
142 static InstrPtr disIntPC     ( StgBCO *bco, InstrPtr pc, char* i )
143 {
144     StgInt  x;
145     StgWord y;
146     x = bcoInstr(bco,pc++);
147     y = bcoInstr16(bco,pc); pc += 2;
148     fprintf(stderr,"%s %d %d",i,x,pc+y);
149     return pc;
150 }
151
152 #ifdef XMLAMBDA
153 static InstrPtr disInt16PC     ( StgBCO *bco, InstrPtr pc, char* i )
154 {
155     StgInt  x;
156     StgWord y;
157     x = bcoInstr(bco,pc); pc += 2;
158     y = bcoInstr16(bco,pc); pc += 2;
159     fprintf(stderr,"%s %d %d",i,x,pc+y);
160     return pc;
161 }
162 static InstrPtr disIntIntPC     ( StgBCO *bco, InstrPtr pc, char* i )
163 {
164     StgInt  x,y;
165     StgWord z;
166     x = bcoInstr(bco,pc++);
167     y = bcoInstr(bco,pc++);
168     z = bcoInstr16(bco,pc); pc += 2;
169     fprintf(stderr,"%s %d %d %d",i,x,y,pc+z);
170     return pc;
171 }
172 #endif
173
174 static InstrPtr disPC        ( StgBCO *bco, InstrPtr pc, char* i )
175 {
176     StgWord y = bcoInstr16(bco,pc); pc += 2;
177     fprintf(stderr,"%s %d",i,pc+y);
178     return pc;
179 }
180
181 static InstrPtr disInfo   ( StgBCO *bco, InstrPtr pc, char* i )
182 {
183     StgInfoTable* info = bcoConstInfoPtr(bco,bcoInstr(bco,pc++));
184     /* ToDo: print contents of infotable */
185     fprintf(stderr,"%s ",i);
186     printPtr(stgCast(StgPtr,info));
187     return pc;
188 }
189
190 static InstrPtr disInfo16 ( StgBCO *bco, InstrPtr pc, char* i )
191 {
192     StgWord x = bcoInstr16(bco,pc); 
193     StgInfoTable* info = bcoConstInfoPtr(bco,x);
194     pc+=2;
195     /* ToDo: print contents of infotable */
196     fprintf(stderr,"%s ",i);
197     printPtr(stgCast(StgPtr,info));
198     return pc;
199 }
200
201 static InstrPtr disConstPtr  ( StgBCO *bco, InstrPtr pc, char* i )
202 {
203     StgInt o = bcoInstr(bco,pc++);
204     StgPtr x = bcoConstPtr(bco,o);
205     fprintf(stderr,"%s [%d]=",i,o); 
206     printPtr(x); /* bad way to print it... */
207     return pc;
208 }
209
210 static InstrPtr disConstPtr16 ( StgBCO *bco, InstrPtr pc, char* i )
211 {
212     StgInt o; 
213     StgPtr x;
214     o = bcoInstr16(bco,pc); pc += 2;
215     x = bcoConstPtr(bco,o);
216     fprintf(stderr,"%s [%d]=",i,o); 
217     printPtr(x); /* bad way to print it... */
218     return pc;
219 }
220
221 static InstrPtr disConstInt  ( StgBCO *bco, InstrPtr pc, char* i )
222 {
223     StgInt x = bcoConstInt(bco,bcoInstr(bco,pc++));
224     fprintf(stderr,"%s %d (0x%x)",i,x,x);
225     return pc;
226 }
227
228 static InstrPtr disConstInt16 ( StgBCO *bco, InstrPtr pc, char* i )
229 {
230     StgInt x = bcoConstInt(bco,bcoInstr16(bco,pc)); pc += 2;
231     fprintf(stderr,"%s %d (0x%x)",i,x,x);
232     return pc;
233 }
234
235 static InstrPtr disConstAddr ( StgBCO *bco, InstrPtr pc, char* i )
236 {
237     StgAddr x = bcoConstAddr(bco,bcoInstr(bco,pc++));
238     fprintf(stderr,"%s ",i);
239     printPtr(x);
240     return pc;
241 }
242
243 static InstrPtr disConstAddr16 ( StgBCO *bco, InstrPtr pc, char* i )
244 {
245     StgAddr x = bcoConstAddr(bco,bcoInstr16(bco,pc)); pc += 2;
246     fprintf(stderr,"%s ",i);
247     printPtr(x);
248     return pc;
249 }
250
251 static InstrPtr disConstChar ( StgBCO *bco, InstrPtr pc, char* i )
252 {
253     StgChar x = bcoConstChar(bco,bcoInstr(bco,pc++));
254     if (isprint((int)x))
255        fprintf(stderr,"%s '%c'",i,x); else
256        fprintf(stderr,"%s 0x%x",i,(int)x);
257     return pc;
258 }
259
260 static InstrPtr disConstChar16 ( StgBCO *bco, InstrPtr pc, char* i )
261 {
262     StgChar x = bcoConstChar(bco,bcoInstr16(bco,pc)); pc += 2;
263     if (isprint((int)x))
264        fprintf(stderr,"%s '%c'",i,x); else
265        fprintf(stderr,"%s 0x%x",i,(int)x);
266     return pc;
267 }
268
269 static InstrPtr disConstFloat ( StgBCO *bco, InstrPtr pc, char* i )
270 {
271     StgFloat x = bcoConstFloat(bco,bcoInstr(bco,pc++));
272     fprintf(stderr,"%s %f",i,x);
273     return pc;
274 }
275
276 static InstrPtr disConstFloat16 ( StgBCO *bco, InstrPtr pc, char* i )
277 {
278     StgFloat x = bcoConstFloat(bco,bcoInstr16(bco,pc)); pc += 2;
279     fprintf(stderr,"%s %f",i,x);
280     return pc;
281 }
282
283 static InstrPtr disConstDouble ( StgBCO *bco, InstrPtr pc, char* i )
284 {
285     StgDouble x = bcoConstDouble(bco,bcoInstr(bco,pc++));
286     fprintf(stderr,"%s %f",i,x);
287     return pc;
288 }
289
290 static InstrPtr disConstDouble16 ( StgBCO *bco, InstrPtr pc, char* i )
291 {
292     StgDouble x = bcoConstDouble(bco,bcoInstr16(bco,pc)); pc += 2;
293     fprintf(stderr,"%s %f",i,x);
294     return pc;
295 }
296
297 InstrPtr disInstr( StgBCO *bco, InstrPtr pc )
298 {
299     Instr in;
300     ASSERT(pc < bco->n_instrs);
301     in = bcoInstr(bco,pc++);
302     switch (in) {
303     case i_INTERNAL_ERROR:
304             return disNone(bco,pc,"INTERNAL_ERROR");
305     case i_PANIC:
306             return disNone(bco,pc,"PANIC");
307     case i_STK_CHECK:
308             return disInt(bco,pc,"STK_CHECK");
309     case i_STK_CHECK_big:
310             return disInt16(bco,pc,"STK_CHECK_big");
311     case i_ARG_CHECK:
312             return disInt(bco,pc,"ARG_CHECK");
313     case i_ALLOC_AP:
314             return disInt(bco,pc,"ALLOC_AP");
315     case i_ALLOC_PAP:
316             return disInt(bco,pc,"ALLOC_PAP");
317     case i_ALLOC_CONSTR:
318             return disInfo(bco,pc,"ALLOC_CONSTR");
319     case i_ALLOC_CONSTR_big:
320             return disInfo16(bco,pc,"ALLOC_CONSTR_big");
321     case i_MKAP:
322             return disIntInt(bco,pc,"MKAP");
323     case i_MKAP_big:
324             return disIntInt16(bco,pc,"MKAP_big");
325     case i_MKPAP:
326             return disIntInt(bco,pc,"MKPAP");
327     case i_PACK:
328             return disInt(bco,pc,"PACK");
329     case i_SLIDE:
330             return disIntInt(bco,pc,"SLIDE");
331     case i_RV:
332             return disIntInt(bco,pc,"R_V");
333     case i_RVE:
334             return disIntInt(bco,pc,"R_V_E");
335     case i_VV:
336             return disIntInt(bco,pc,"V_V");
337     case i_SE:
338             return disIntInt(bco,pc,"S_E");
339     case i_SLIDE_big:
340             return disIntInt16(bco,pc,"SLIDE_big");
341     case i_ENTER:
342             return disNone(bco,pc,"ENTER");
343     case i_RETADDR:
344             return disConstPtr(bco,pc,"RETADDR");
345     case i_RETADDR_big:
346             return disConstPtr16(bco,pc,"RETADDR_big");
347     case i_TEST:
348             return disIntPC(bco,pc,"TEST");
349     case i_UNPACK:
350             return disNone(bco,pc,"UNPACK");
351     case i_VAR:
352             return disInt(bco,pc,"VAR");
353     case i_VAR_big:
354             return disInt16(bco,pc,"VAR_big");
355     case i_CONST:
356             return disConstPtr(bco,pc,"CONST");
357     case i_CONST_big:
358             return disConstPtr16(bco,pc,"CONST_big");
359
360 #ifdef XMLAMBDA
361     case i_ALLOC_ROW:
362             return disInt(bco,pc,"ALLOC_ROW");    
363     case i_ALLOC_ROW_big:
364             return disInt16(bco,pc,"ALLOC_ROW_big");    
365     case i_PACK_ROW:
366             return disInt(bco,pc,"PACK_ROW");    
367     case i_PACK_ROW_big:
368             return disInt16(bco,pc,"PACK_ROW_big");    
369     case i_UNPACK_ROW:
370             return disNone(bco,pc,"UNPACK_ROW");    
371     case i_CONST_ROW_TRIV:
372             return disNone(bco,pc,"CONST_ROW_TRIV");
373
374     case i_PACK_INJ_VAR:
375             return disInt(bco,pc,"PACK_INJ_VAR");
376     case i_PACK_INJ_VAR_big:
377             return disInt16(bco,pc,"PACK_INJ_VAR_big");
378     case i_PACK_INJ_CONST_8:
379             return disInt(bco,pc,"PACK_INJ_CONST_8");
380     case i_PACK_INJ_REL_8:
381             return disIntInt(bco,pc,"PACK_INJ_REL_8");
382     case i_PACK_INJ:
383             return disNone(bco,pc,"PACK_INJ");
384
385     case i_UNPACK_INJ:
386             return disNone(bco,pc,"UNPACK_INJ");
387
388     case i_TEST_INJ_VAR:
389             return disIntPC(bco,pc,"TEST_INJ_VAR");
390     case i_TEST_INJ_VAR_big:
391             return disInt16PC(bco,pc,"TEST_INJ_VAR_big");
392     case i_TEST_INJ_CONST_8:
393             return disIntPC(bco,pc,"TEST_INJ_CONST_8");
394     case i_TEST_INJ_REL_8:  
395             return disIntIntPC(bco,pc,"TEST_INJ_REL_8");
396     case i_TEST_INJ:
397             return disPC(bco,pc,"TEST_INJ");
398     
399     case i_CONST_WORD_8:
400             return disInt(bco,pc,"CONST_WORD_8");
401     case i_ADD_WORD_VAR:
402             return disInt(bco,pc,"ADD_WORD_VAR");
403     case i_ADD_WORD_VAR_big:
404             return disInt16(bco,pc,"ADD_WORD_VAR_big");
405     case i_ADD_WORD_VAR_8:
406             return disIntInt(bco,pc,"ADD_WORD_VAR_8");
407 #endif    
408
409     case i_VOID:
410             return disNone(bco,pc,"VOID");
411
412     case i_VAR_INT:
413             return disInt(bco,pc,"VAR_INT");
414     case i_VAR_INT_big:
415             return disInt16(bco,pc,"VAR_INT_big");
416     case i_CONST_INT:
417             return disConstInt(bco,pc,"CONST_INT");
418     case i_CONST_INT_big:
419             return disConstInt16(bco,pc,"CONST_INT_big");
420     case i_PACK_INT:
421             return disNone(bco,pc,"PACK_INT");
422     case i_UNPACK_INT:
423             return disNone(bco,pc,"UNPACK_INT");
424     case i_TEST_INT:
425             return disPC(bco,pc,"TEST_INT");
426
427     case i_CONST_INTEGER:
428             return disConstAddr(bco,pc,"CONST_INTEGER");
429     case i_CONST_INTEGER_big:
430             return disConstAddr16(bco,pc,"CONST_INTEGER_big");
431
432     case i_VAR_WORD:
433             return disInt(bco,pc,"VAR_WORD");
434     case i_CONST_WORD:
435             return disConstInt(bco,pc,"CONST_WORD");
436     case i_CONST_WORD_big:
437             return disConstInt16(bco,pc,"CONST_WORD_big");
438     case i_PACK_WORD:
439             return disNone(bco,pc,"PACK_WORD");
440     case i_UNPACK_WORD:
441             return disNone(bco,pc,"UNPACK_WORD");
442
443     case i_VAR_ADDR:
444             return disInt(bco,pc,"VAR_ADDR");
445     case i_VAR_ADDR_big:
446             return disInt16(bco,pc,"VAR_ADDR_big");
447     case i_CONST_ADDR:
448             return disConstAddr(bco,pc,"CONST_ADDR");
449     case i_CONST_ADDR_big:
450             return disConstAddr16(bco,pc,"CONST_ADDR_big");
451     case i_PACK_ADDR:
452             return disNone(bco,pc,"PACK_ADDR");
453     case i_UNPACK_ADDR:
454             return disNone(bco,pc,"UNPACK_ADDR");
455
456     case i_VAR_CHAR:
457             return disInt(bco,pc,"VAR_CHAR");
458     case i_VAR_CHAR_big:
459             return disInt16(bco,pc,"VAR_CHAR_big");
460     case i_CONST_CHAR:
461             return disConstChar(bco,pc,"CONST_CHAR");
462     case i_CONST_CHAR_big:
463             return disConstChar16(bco,pc,"CONST_CHAR_big");
464     case i_PACK_CHAR:
465             return disNone(bco,pc,"PACK_CHAR");
466     case i_UNPACK_CHAR:
467             return disNone(bco,pc,"UNPACK_CHAR");
468
469     case i_VAR_FLOAT:
470             return disInt(bco,pc,"VAR_FLOAT");
471     case i_VAR_FLOAT_big:
472             return disInt16(bco,pc,"VAR_FLOAT_big");
473     case i_CONST_FLOAT:
474             return disConstFloat(bco,pc,"CONST_FLOAT");
475     case i_CONST_FLOAT_big:
476             return disConstFloat16(bco,pc,"CONST_FLOAT_big");
477     case i_PACK_FLOAT:
478             return disNone(bco,pc,"PACK_FLOAT");
479     case i_UNPACK_FLOAT:
480             return disNone(bco,pc,"UNPACK_FLOAT");
481
482     case i_VAR_DOUBLE:
483             return disInt(bco,pc,"VAR_DOUBLE");
484     case i_VAR_DOUBLE_big:
485             return disInt16(bco,pc,"VAR_DOUBLE_big");
486     case i_CONST_DOUBLE:
487             return disConstDouble(bco,pc,"CONST_DOUBLE");
488     case i_CONST_DOUBLE_big:
489             return disConstDouble16(bco,pc,"CONST_DOUBLE_big");
490     case i_PACK_DOUBLE:
491             return disNone(bco,pc,"PACK_DOUBLE");
492     case i_UNPACK_DOUBLE:
493             return disNone(bco,pc,"UNPACK_DOUBLE");
494
495     case i_VAR_STABLE:
496             return disInt(bco,pc,"VAR_STABLE");
497     case i_PACK_STABLE:
498             return disNone(bco,pc,"PACK_STABLE");
499     case i_UNPACK_STABLE:
500             return disNone(bco,pc,"UNPACK_STABLE");
501
502     case i_PRIMOP1:
503         {
504             Primop1 op = bcoInstr(bco,pc++);
505             switch (op) {
506             case i_INTERNAL_ERROR1:
507                     return disNone(bco,pc,"INTERNAL_ERROR1");
508             case i_pushseqframe:
509                     return disNone(bco,pc,"i_pushseqframe");
510             case i_pushcatchframe:
511                     return disNone(bco,pc,"i_pushcatchframe");
512             default:
513                 {
514                     const AsmPrim* p = asmFindPrimop(i_PRIMOP1,op);
515                     if (p) {
516                         return disNone(bco,pc,p->name);
517                     }
518                     barf("Unrecognised primop1 %d\n",op);
519                 }
520             }
521         }
522     case i_PRIMOP2:
523         {
524             Primop2 op = bcoInstr(bco,pc++);
525             switch (op) {
526             case i_INTERNAL_ERROR2:
527                     return disNone(bco,pc,"INTERNAL_ERROR2");
528 #ifdef XMLAMBDA
529             case i_rowInsertAt:
530                     return disNone(bco,pc,"ROW_INSERT_1");
531             case i_rowChainInsert:
532                     return disNone(bco,pc,"ROW_INSERT");
533             case i_rowChainBuild:
534                     return disNone(bco,pc,"ROW_BUILD");
535             case i_rowRemoveAt:
536                     return disNone(bco,pc,"ROW_REMOVE_1");
537             case i_rowChainRemove:
538                     return disNone(bco,pc,"ROW_REMOVE");
539             case i_rowChainSelect:
540                     return disNone(bco,pc,"ROW_SELECT");
541             case i_ccall:
542                     return disNone(bco,pc,"ccall");
543 #endif
544             case i_ccall_ccall_Id:
545                     return disNone(bco,pc,"ccall_ccall_Id");
546             case i_ccall_ccall_IO:
547                     return disNone(bco,pc,"ccall_ccall_IO");
548             case i_ccall_stdcall_Id:
549                     return disNone(bco,pc,"ccall_stdcall_Id");
550             case i_ccall_stdcall_IO:
551                     return disNone(bco,pc,"ccall_stdcall_IO");
552             case i_raise:
553                     return disNone(bco,pc,"primRaise");
554             case i_takeMVar:
555                     return disNone(bco,pc,"primTakeMVar");
556             default:
557                 {
558                     const AsmPrim* p = asmFindPrimop(i_PRIMOP2,op);
559                     if (p) {
560                         return disNone(bco,pc,p->name);
561                     }
562                     barf("Unrecognised primop2 %d\n",op);
563                 }
564             }
565         }
566     default:
567             barf("Unrecognised instruction %d\n",in);
568     }
569 }
570
571 void  disassemble( StgBCO *bco, char* prefix )
572 {
573     int pc = 0;
574     int pcLim = bco->n_instrs;
575     ASSERT( get_itbl(bco)->type == BCO);
576     while (pc < pcLim) {
577         fprintf(stderr,"%s%d:\t",prefix,pc);
578         pc = disInstr(bco,pc);
579         fprintf(stderr,"\n");
580     }
581     if (bco->stgexpr) { 
582        ppStgExpr(bco->stgexpr);
583        fprintf(stderr, "\n");
584     }
585     else
586        fprintf(stderr, "\t(no associated tree)\n" );
587 }
588
589 #endif /* INTERPRETER */
590 #endif 0