xref: /csrg-svn/old/dbx/fortran.c (revision 12549)
1*12549Scsvaf /*
2*12549Scsvaf  * FORTRAN dependent symbol routines.
3*12549Scsvaf  */
4*12549Scsvaf 
5*12549Scsvaf #include "defs.h"
6*12549Scsvaf #include "symbols.h"
7*12549Scsvaf #include "printsym.h"
8*12549Scsvaf #include "languages.h"
9*12549Scsvaf #include "fortran.h"
10*12549Scsvaf #include "tree.h"
11*12549Scsvaf #include "eval.h"
12*12549Scsvaf #include "operators.h"
13*12549Scsvaf #include "mappings.h"
14*12549Scsvaf #include "process.h"
15*12549Scsvaf #include "runtime.h"
16*12549Scsvaf #include "machine.h"
17*12549Scsvaf 
18*12549Scsvaf #define isfloat(range) ( \
19*12549Scsvaf     range->symvalue.rangev.upper == 0 and range->symvalue.rangev.lower > 0 \
20*12549Scsvaf )
21*12549Scsvaf 
22*12549Scsvaf #define isrange(t, name) (t->class == RANGE and istypename(t->type, name))
23*12549Scsvaf 
24*12549Scsvaf #define MAXDIM  20
25*12549Scsvaf /*
26*12549Scsvaf  * Initialize FORTRAN language information.
27*12549Scsvaf  */
28*12549Scsvaf 
29*12549Scsvaf public fortran_init()
30*12549Scsvaf {
31*12549Scsvaf     Language lang;
32*12549Scsvaf 
33*12549Scsvaf     lang = language_define("fortran", ".f");
34*12549Scsvaf     language_setop(lang, L_PRINTDECL, fortran_printdecl);
35*12549Scsvaf     language_setop(lang, L_PRINTVAL, fortran_printval);
36*12549Scsvaf     language_setop(lang, L_TYPEMATCH, fortran_typematch);
37*12549Scsvaf     language_setop(lang, L_BUILDAREF, fortran_buildaref);
38*12549Scsvaf     language_setop(lang, L_EVALAREF, fortran_evalaref);
39*12549Scsvaf }
40*12549Scsvaf 
41*12549Scsvaf /*
42*12549Scsvaf  * Test if two types are compatible.
43*12549Scsvaf  *
44*12549Scsvaf  * Integers and reals are not compatible since they cannot always be mixed.
45*12549Scsvaf  */
46*12549Scsvaf 
47*12549Scsvaf public Boolean fortran_typematch(type1, type2)
48*12549Scsvaf Symbol type1, type2;
49*12549Scsvaf {
50*12549Scsvaf 
51*12549Scsvaf /* only does integer for now; may need to add others
52*12549Scsvaf */
53*12549Scsvaf 
54*12549Scsvaf     Boolean b;
55*12549Scsvaf     register Symbol t1, t2, tmp;
56*12549Scsvaf 
57*12549Scsvaf     t1 = rtype(type1);
58*12549Scsvaf     t2 = rtype(type2);
59*12549Scsvaf     if(t1 == nil or t1->type == nil or t2 == nil or t2->type == nil ) b = false;
60*12549Scsvaf     else { b = (Boolean)   (
61*12549Scsvaf             (t1 == t2)  or
62*12549Scsvaf 	    (t1->type == t_int and (istypename(t2->type, "integer") or
63*12549Scsvaf                                     istypename(t2->type, "integer*2"))  ) or
64*12549Scsvaf 	    (t2->type == t_int and (istypename(t1->type, "integer") or
65*12549Scsvaf                                     istypename(t1->type, "integer*2"))  )
66*12549Scsvaf                     );
67*12549Scsvaf          }
68*12549Scsvaf     /*OUT fprintf(stderr," %d compat %s %s \n", b,
69*12549Scsvaf       (t1 == nil or t1->type == nil ) ? "nil" : symname(t1->type),
70*12549Scsvaf       (t2 == nil or t2->type == nil ) ? "nil" : symname(t2->type)  );*/
71*12549Scsvaf     return b;
72*12549Scsvaf }
73*12549Scsvaf 
74*12549Scsvaf private String typename(s)
75*12549Scsvaf Symbol s;
76*12549Scsvaf {
77*12549Scsvaf int ub;
78*12549Scsvaf static char buf[20];
79*12549Scsvaf char *pbuf;
80*12549Scsvaf Symbol st,sc;
81*12549Scsvaf 
82*12549Scsvaf      if(s->type->class == TYPE) return(symname(s->type));
83*12549Scsvaf 
84*12549Scsvaf      for(st = s->type; st->type->class != TYPE; st = st->type);
85*12549Scsvaf 
86*12549Scsvaf      pbuf=buf;
87*12549Scsvaf 
88*12549Scsvaf      if(istypename(st->type,"char"))  {
89*12549Scsvaf 	  sprintf(pbuf,"character*");
90*12549Scsvaf           pbuf += strlen(pbuf);
91*12549Scsvaf 	  sc = st->chain;
92*12549Scsvaf           if(sc->symvalue.rangev.uppertype == R_ARG or
93*12549Scsvaf              sc->symvalue.rangev.uppertype == R_TEMP) {
94*12549Scsvaf 	      if( ! getbound(s,sc->symvalue.rangev.upper,
95*12549Scsvaf                     sc->symvalue.rangev.uppertype, &ub) )
96*12549Scsvaf 		sprintf(pbuf,"(*)");
97*12549Scsvaf 	      else
98*12549Scsvaf 		sprintf(pbuf,"%d",ub);
99*12549Scsvaf           }
100*12549Scsvaf  	  else sprintf(pbuf,"%d",sc->symvalue.rangev.upper);
101*12549Scsvaf      }
102*12549Scsvaf      else {
103*12549Scsvaf           sprintf(pbuf,"%s ",symname(st->type));
104*12549Scsvaf      }
105*12549Scsvaf      return(buf);
106*12549Scsvaf }
107*12549Scsvaf 
108*12549Scsvaf private Symbol mksubs(pbuf,st)
109*12549Scsvaf Symbol st;
110*12549Scsvaf char  **pbuf;
111*12549Scsvaf {
112*12549Scsvaf    int lb, ub;
113*12549Scsvaf    Symbol r, eltype;
114*12549Scsvaf 
115*12549Scsvaf    if(st->class != ARRAY or (istypename(st->type, "char")) ) return;
116*12549Scsvaf    else {
117*12549Scsvaf           mksubs(pbuf,st->type);
118*12549Scsvaf           assert( (r = st->chain)->class == RANGE);
119*12549Scsvaf 
120*12549Scsvaf           if(r->symvalue.rangev.lowertype == R_ARG or
121*12549Scsvaf              r->symvalue.rangev.lowertype == R_TEMP) {
122*12549Scsvaf 	      if( ! getbound(st,r->symvalue.rangev.lower,
123*12549Scsvaf                     r->symvalue.rangev.lowertype, &lb) )
124*12549Scsvaf 		sprintf(*pbuf,"?:");
125*12549Scsvaf 	      else
126*12549Scsvaf 		sprintf(*pbuf,"%d:",lb);
127*12549Scsvaf 	  }
128*12549Scsvaf           else {
129*12549Scsvaf 		lb = r->symvalue.rangev.lower;
130*12549Scsvaf 		sprintf(*pbuf,"%d:",lb);
131*12549Scsvaf 		}
132*12549Scsvaf     	  *pbuf += strlen(*pbuf);
133*12549Scsvaf 
134*12549Scsvaf           if(r->symvalue.rangev.uppertype == R_ARG or
135*12549Scsvaf              r->symvalue.rangev.uppertype == R_TEMP) {
136*12549Scsvaf 	      if( ! getbound(st,r->symvalue.rangev.upper,
137*12549Scsvaf                     r->symvalue.rangev.uppertype, &ub) )
138*12549Scsvaf 		sprintf(*pbuf,"?,");
139*12549Scsvaf 	      else
140*12549Scsvaf 		sprintf(*pbuf,"%d,",ub);
141*12549Scsvaf 	  }
142*12549Scsvaf           else {
143*12549Scsvaf 		ub = r->symvalue.rangev.upper;
144*12549Scsvaf 		sprintf(*pbuf,"%d,",ub);
145*12549Scsvaf 		}
146*12549Scsvaf     	  *pbuf += strlen(*pbuf);
147*12549Scsvaf 
148*12549Scsvaf        }
149*12549Scsvaf }
150*12549Scsvaf 
151*12549Scsvaf /*
152*12549Scsvaf  * Print out the declaration of a FORTRAN variable.
153*12549Scsvaf  */
154*12549Scsvaf 
155*12549Scsvaf public fortran_printdecl(s)
156*12549Scsvaf Symbol s;
157*12549Scsvaf {
158*12549Scsvaf 
159*12549Scsvaf 
160*12549Scsvaf Symbol eltype;
161*12549Scsvaf 
162*12549Scsvaf     switch (s->class) {
163*12549Scsvaf 
164*12549Scsvaf 	case CONST:
165*12549Scsvaf 
166*12549Scsvaf 	    printf("parameter %s = ", symname(s));
167*12549Scsvaf             printval(s);
168*12549Scsvaf 	    break;
169*12549Scsvaf 
170*12549Scsvaf         case REF:
171*12549Scsvaf             printf(" (dummy argument) ");
172*12549Scsvaf 
173*12549Scsvaf 	case VAR:
174*12549Scsvaf 	    if (s->type->class == ARRAY &&
175*12549Scsvaf 		 (not istypename(s->type->type,"char")) ) {
176*12549Scsvaf                 char bounds[130], *p1, **p;
177*12549Scsvaf 		p1 = bounds;
178*12549Scsvaf                 p = &p1;
179*12549Scsvaf                 mksubs(p,s->type);
180*12549Scsvaf                 *p -= 1;
181*12549Scsvaf                 **p = '\0';   /* get rid of trailing ',' */
182*12549Scsvaf 		printf(" %s %s[%s] ",typename(s), symname(s), bounds);
183*12549Scsvaf 	    } else {
184*12549Scsvaf 		printf("%s %s", typename(s), symname(s));
185*12549Scsvaf 	    }
186*12549Scsvaf 	    break;
187*12549Scsvaf 
188*12549Scsvaf 	case FUNC:
189*12549Scsvaf 	    if (not istypename(s->type, "subroutine")) {
190*12549Scsvaf                 printf(" %s function ", typename(s) );
191*12549Scsvaf 	    }
192*12549Scsvaf 	    else printf(" subroutine");
193*12549Scsvaf 	    printf(" %s ", symname(s));
194*12549Scsvaf 	    fortran_listparams(s);
195*12549Scsvaf 	    break;
196*12549Scsvaf 
197*12549Scsvaf 	case MODULE:
198*12549Scsvaf 	    printf("source file \"%s.c\"", symname(s));
199*12549Scsvaf 	    break;
200*12549Scsvaf 
201*12549Scsvaf 	case PROG:
202*12549Scsvaf 	    printf("executable file \"%s\"", symname(s));
203*12549Scsvaf 	    break;
204*12549Scsvaf 
205*12549Scsvaf 	default:
206*12549Scsvaf 	    error("class %s in fortran_printdecl", classname(s));
207*12549Scsvaf     }
208*12549Scsvaf     putchar('\n');
209*12549Scsvaf }
210*12549Scsvaf 
211*12549Scsvaf /*
212*12549Scsvaf  * List the parameters of a procedure or function.
213*12549Scsvaf  * No attempt is made to combine like types.
214*12549Scsvaf  */
215*12549Scsvaf 
216*12549Scsvaf public fortran_listparams(s)
217*12549Scsvaf Symbol s;
218*12549Scsvaf {
219*12549Scsvaf     register Symbol t;
220*12549Scsvaf 
221*12549Scsvaf     putchar('(');
222*12549Scsvaf     for (t = s->chain; t != nil; t = t->chain) {
223*12549Scsvaf 	printf("%s", symname(t));
224*12549Scsvaf 	if (t->chain != nil) {
225*12549Scsvaf 	    printf(", ");
226*12549Scsvaf 	}
227*12549Scsvaf     }
228*12549Scsvaf     putchar(')');
229*12549Scsvaf     if (s->chain != nil) {
230*12549Scsvaf 	printf("\n");
231*12549Scsvaf 	for (t = s->chain; t != nil; t = t->chain) {
232*12549Scsvaf 	    if (t->class != REF) {
233*12549Scsvaf 		panic("unexpected class %d for parameter", t->class);
234*12549Scsvaf 	    }
235*12549Scsvaf 	    printdecl(t, 0);
236*12549Scsvaf 	}
237*12549Scsvaf     } else {
238*12549Scsvaf 	putchar('\n');
239*12549Scsvaf     }
240*12549Scsvaf }
241*12549Scsvaf 
242*12549Scsvaf /*
243*12549Scsvaf  * Print out the value on the top of the expression stack
244*12549Scsvaf  * in the format for the type of the given symbol.
245*12549Scsvaf  */
246*12549Scsvaf 
247*12549Scsvaf public fortran_printval(s)
248*12549Scsvaf Symbol s;
249*12549Scsvaf {
250*12549Scsvaf     register Symbol t;
251*12549Scsvaf     register Address a;
252*12549Scsvaf     register int i, len;
253*12549Scsvaf 
254*12549Scsvaf     /* printf("fortran_printval with class %s \n",classname(s)); OUT*/
255*12549Scsvaf     switch (s->class) {
256*12549Scsvaf 	case CONST:
257*12549Scsvaf 	case TYPE:
258*12549Scsvaf 	case VAR:
259*12549Scsvaf 	case REF:
260*12549Scsvaf 	case FVAR:
261*12549Scsvaf 	case TAG:
262*12549Scsvaf 	    fortran_printval(s->type);
263*12549Scsvaf 	    break;
264*12549Scsvaf 
265*12549Scsvaf 	case ARRAY:
266*12549Scsvaf 	    t = rtype(s->type);
267*12549Scsvaf 	    if (t->class == RANGE and istypename(t->type, "char")) {
268*12549Scsvaf 		len = size(s);
269*12549Scsvaf 		sp -= len;
270*12549Scsvaf 		printf("\"%.*s\"", len, sp);
271*12549Scsvaf 	    } else {
272*12549Scsvaf 		fortran_printarray(s);
273*12549Scsvaf 	    }
274*12549Scsvaf 	    break;
275*12549Scsvaf 
276*12549Scsvaf 	case RANGE:
277*12549Scsvaf 	     if (isfloat(s)) {
278*12549Scsvaf 		switch (s->symvalue.rangev.lower) {
279*12549Scsvaf 		    case sizeof(float):
280*12549Scsvaf 			prtreal(pop(float));
281*12549Scsvaf 			break;
282*12549Scsvaf 
283*12549Scsvaf 		    case sizeof(double):
284*12549Scsvaf 			if(istypename(s->type,"complex")) {
285*12549Scsvaf 			   printf("(");
286*12549Scsvaf 			prtreal(pop(float));
287*12549Scsvaf 			   printf(",");
288*12549Scsvaf 			prtreal(pop(float));
289*12549Scsvaf 			   printf(")");
290*12549Scsvaf 			}
291*12549Scsvaf 			else prtreal(pop(double));
292*12549Scsvaf 			break;
293*12549Scsvaf 
294*12549Scsvaf 		    default:
295*12549Scsvaf 			panic("bad size \"%d\" for real",
296*12549Scsvaf                                   t->symvalue.rangev.lower);
297*12549Scsvaf 			break;
298*12549Scsvaf 		}
299*12549Scsvaf 	    } else {
300*12549Scsvaf 		printint(popsmall(s), s);
301*12549Scsvaf 	    }
302*12549Scsvaf 	    break;
303*12549Scsvaf 
304*12549Scsvaf 	default:
305*12549Scsvaf 	    if (ord(s->class) > ord(TYPEREF)) {
306*12549Scsvaf 		panic("printval: bad class %d", ord(s->class));
307*12549Scsvaf 	    }
308*12549Scsvaf 	    error("don't know how to print a %s", fortran_classname(s));
309*12549Scsvaf 	    /* NOTREACHED */
310*12549Scsvaf     }
311*12549Scsvaf }
312*12549Scsvaf 
313*12549Scsvaf /*
314*12549Scsvaf  * Print out an int
315*12549Scsvaf  */
316*12549Scsvaf 
317*12549Scsvaf private printint(i, t)
318*12549Scsvaf Integer i;
319*12549Scsvaf register Symbol t;
320*12549Scsvaf {
321*12549Scsvaf     if (istypename(t->type, "logical")) {
322*12549Scsvaf 	printf(((Boolean) i) == true ? "true" : "false");
323*12549Scsvaf     }
324*12549Scsvaf     else if ( (t->type == t_int) or istypename(t->type, "integer") or
325*12549Scsvaf                   istypename(t->type,"integer*2") ) {
326*12549Scsvaf 	printf("%ld", i);
327*12549Scsvaf     } else {
328*12549Scsvaf       error("unkown type in fortran printint");
329*12549Scsvaf     }
330*12549Scsvaf }
331*12549Scsvaf 
332*12549Scsvaf /*
333*12549Scsvaf  * Print out a null-terminated string (pointer to char)
334*12549Scsvaf  * starting at the given address.
335*12549Scsvaf  */
336*12549Scsvaf 
337*12549Scsvaf private printstring(addr)
338*12549Scsvaf Address addr;
339*12549Scsvaf {
340*12549Scsvaf     register Address a;
341*12549Scsvaf     register Integer i, len;
342*12549Scsvaf     register Boolean endofstring;
343*12549Scsvaf     union {
344*12549Scsvaf 	char ch[sizeof(Word)];
345*12549Scsvaf 	int word;
346*12549Scsvaf     } u;
347*12549Scsvaf 
348*12549Scsvaf     putchar('"');
349*12549Scsvaf     a = addr;
350*12549Scsvaf     endofstring = false;
351*12549Scsvaf     while (not endofstring) {
352*12549Scsvaf 	dread(&u, a, sizeof(u));
353*12549Scsvaf 	i = 0;
354*12549Scsvaf 	do {
355*12549Scsvaf 	    if (u.ch[i] == '\0') {
356*12549Scsvaf 		endofstring = true;
357*12549Scsvaf 	    } else {
358*12549Scsvaf 		printchar(u.ch[i]);
359*12549Scsvaf 	    }
360*12549Scsvaf 	    ++i;
361*12549Scsvaf 	} while (i < sizeof(Word) and not endofstring);
362*12549Scsvaf 	a += sizeof(Word);
363*12549Scsvaf     }
364*12549Scsvaf     putchar('"');
365*12549Scsvaf }
366*12549Scsvaf /*
367*12549Scsvaf  * Return the FORTRAN name for the particular class of a symbol.
368*12549Scsvaf  */
369*12549Scsvaf 
370*12549Scsvaf public String fortran_classname(s)
371*12549Scsvaf Symbol s;
372*12549Scsvaf {
373*12549Scsvaf     String str;
374*12549Scsvaf 
375*12549Scsvaf     switch (s->class) {
376*12549Scsvaf 	case REF:
377*12549Scsvaf 	    str = "dummy argument";
378*12549Scsvaf 	    break;
379*12549Scsvaf 
380*12549Scsvaf 	case CONST:
381*12549Scsvaf 	    str = "parameter";
382*12549Scsvaf 	    break;
383*12549Scsvaf 
384*12549Scsvaf 	default:
385*12549Scsvaf 	    str = classname(s);
386*12549Scsvaf     }
387*12549Scsvaf     return str;
388*12549Scsvaf }
389*12549Scsvaf 
390*12549Scsvaf /* reverses the indices from the expr_list; should be folded into buildaref
391*12549Scsvaf  * and done as one recursive routine
392*12549Scsvaf  */
393*12549Scsvaf Node private rev_index(here,n)
394*12549Scsvaf register Node here,n;
395*12549Scsvaf {
396*12549Scsvaf 
397*12549Scsvaf   register Node i;
398*12549Scsvaf 
399*12549Scsvaf   if( here == nil  or  here == n) i=nil;
400*12549Scsvaf   else if( here->value.arg[1] == n) i = here;
401*12549Scsvaf   else i=rev_index(here->value.arg[1],n);
402*12549Scsvaf   return i;
403*12549Scsvaf }
404*12549Scsvaf 
405*12549Scsvaf public Node fortran_buildaref(a, slist)
406*12549Scsvaf Node a, slist;
407*12549Scsvaf {
408*12549Scsvaf     register Symbol as;      /* array of array of .. cursor */
409*12549Scsvaf     register Node en;        /* Expr list cursor */
410*12549Scsvaf     Symbol etype;            /* Type of subscript expr */
411*12549Scsvaf     Node esub, tree;         /* Subscript expression ptr and tree to be built*/
412*12549Scsvaf 
413*12549Scsvaf     tree=a;
414*12549Scsvaf 
415*12549Scsvaf     as = rtype(tree->nodetype);     /* node->sym.type->array*/
416*12549Scsvaf     if ( not (
417*12549Scsvaf                (tree->nodetype->class == VAR or tree->nodetype->class == REF)
418*12549Scsvaf                 and as->class == ARRAY
419*12549Scsvaf              ) ) {
420*12549Scsvaf 	beginerrmsg();
421*12549Scsvaf 	prtree(stderr, a);
422*12549Scsvaf 	fprintf(stderr, " is not an array");
423*12549Scsvaf 	/*fprintf(stderr, " a-> %x as %x ", tree->nodetype, as ); OUT*/
424*12549Scsvaf 	enderrmsg();
425*12549Scsvaf     } else {
426*12549Scsvaf 	for (en = rev_index(slist,nil); en != nil and as->class == ARRAY;
427*12549Scsvaf                      en = rev_index(slist,en), as = as->type) {
428*12549Scsvaf 	    esub = en->value.arg[0];
429*12549Scsvaf 	    etype = rtype(esub->nodetype);
430*12549Scsvaf             assert(as->chain->class == RANGE);
431*12549Scsvaf 	    if ( not compatible( t_int, etype) ) {
432*12549Scsvaf 		beginerrmsg();
433*12549Scsvaf 		fprintf(stderr, "subscript ");
434*12549Scsvaf 		prtree(stderr, esub);
435*12549Scsvaf 		fprintf(stderr, " is type %s ",symname(etype->type) );
436*12549Scsvaf 		enderrmsg();
437*12549Scsvaf 	    }
438*12549Scsvaf 	    tree = build(O_INDEX, tree, esub);
439*12549Scsvaf 	    tree->nodetype = as->type;
440*12549Scsvaf 	}
441*12549Scsvaf 	if (en != nil or
442*12549Scsvaf              (as->class == ARRAY && (not istypename(as->type,"char"))) ) {
443*12549Scsvaf 	    beginerrmsg();
444*12549Scsvaf 	    if (en != nil) {
445*12549Scsvaf 		fprintf(stderr, "too many subscripts for ");
446*12549Scsvaf 	    } else {
447*12549Scsvaf 		fprintf(stderr, "not enough subscripts for ");
448*12549Scsvaf 	    }
449*12549Scsvaf 	    prtree(stderr, tree);
450*12549Scsvaf 	    enderrmsg();
451*12549Scsvaf 	}
452*12549Scsvaf     }
453*12549Scsvaf     return tree;
454*12549Scsvaf }
455*12549Scsvaf 
456*12549Scsvaf /*
457*12549Scsvaf  * Evaluate a subscript index.
458*12549Scsvaf  */
459*12549Scsvaf 
460*12549Scsvaf public int fortran_evalaref(s, i)
461*12549Scsvaf Symbol s;
462*12549Scsvaf long i;
463*12549Scsvaf {
464*12549Scsvaf     Symbol r;
465*12549Scsvaf     long lb, ub;
466*12549Scsvaf 
467*12549Scsvaf     r = rtype(s)->chain;
468*12549Scsvaf     if(r->symvalue.rangev.lowertype == R_ARG or
469*12549Scsvaf        r->symvalue.rangev.lowertype == R_TEMP  ) {
470*12549Scsvaf 	if(! getbound(s,r->symvalue.rangev.lower,
471*12549Scsvaf 		        r->symvalue.rangev.lowertype,&lb))
472*12549Scsvaf           error("dynamic bounds not currently available");
473*12549Scsvaf     }
474*12549Scsvaf     else lb = r->symvalue.rangev.lower;
475*12549Scsvaf 
476*12549Scsvaf     if(r->symvalue.rangev.uppertype == R_ARG or
477*12549Scsvaf        r->symvalue.rangev.uppertype == R_TEMP  ) {
478*12549Scsvaf 	if(! getbound(s,r->symvalue.rangev.upper,
479*12549Scsvaf 		        r->symvalue.rangev.uppertype,&ub))
480*12549Scsvaf           error("dynamic bounds not currently available");
481*12549Scsvaf     }
482*12549Scsvaf     else ub = r->symvalue.rangev.upper;
483*12549Scsvaf 
484*12549Scsvaf     if (i < lb or i > ub) {
485*12549Scsvaf 	error("subscript out of range");
486*12549Scsvaf     }
487*12549Scsvaf     return (i - lb);
488*12549Scsvaf }
489*12549Scsvaf 
490*12549Scsvaf private fortran_printarray(a)
491*12549Scsvaf Symbol a;
492*12549Scsvaf {
493*12549Scsvaf struct Bounds { int lb, val, ub} dim[MAXDIM];
494*12549Scsvaf 
495*12549Scsvaf Symbol sc,st,eltype;
496*12549Scsvaf char buf[50];
497*12549Scsvaf char *subscr;
498*12549Scsvaf int i,ndim,elsize;
499*12549Scsvaf Stack *savesp;
500*12549Scsvaf Boolean done;
501*12549Scsvaf 
502*12549Scsvaf st = a;
503*12549Scsvaf 
504*12549Scsvaf savesp = sp;
505*12549Scsvaf sp -= size(a);
506*12549Scsvaf ndim=0;
507*12549Scsvaf 
508*12549Scsvaf for(;;){
509*12549Scsvaf           sc = st->chain;
510*12549Scsvaf           if(sc->symvalue.rangev.lowertype == R_ARG or
511*12549Scsvaf              sc->symvalue.rangev.lowertype == R_TEMP) {
512*12549Scsvaf 	      if( ! getbound(a,sc->symvalue.rangev.lower,
513*12549Scsvaf                     sc->symvalue.rangev.lowertype, &dim[i].lb) )
514*12549Scsvaf 		error(" dynamic bounds not currently available");
515*12549Scsvaf 	  }
516*12549Scsvaf 	  else dim[ndim].lb = sc->symvalue.rangev.lower;
517*12549Scsvaf 
518*12549Scsvaf           if(sc->symvalue.rangev.uppertype == R_ARG or
519*12549Scsvaf              sc->symvalue.rangev.uppertype == R_TEMP) {
520*12549Scsvaf 	      if( ! getbound(a,sc->symvalue.rangev.upper,
521*12549Scsvaf                     sc->symvalue.rangev.uppertype, &dim[ndim].ub) )
522*12549Scsvaf 		error(" dynamic bounds not currently available");
523*12549Scsvaf 	  }
524*12549Scsvaf 	  else dim[ndim].ub = sc->symvalue.rangev.upper;
525*12549Scsvaf 
526*12549Scsvaf           ndim ++;
527*12549Scsvaf           if (st->type->class == ARRAY) st=st->type;
528*12549Scsvaf 	  else break;
529*12549Scsvaf      }
530*12549Scsvaf 
531*12549Scsvaf if(istypename(st->type,"char")) {
532*12549Scsvaf 		eltype = st;
533*12549Scsvaf 		ndim--;
534*12549Scsvaf 	}
535*12549Scsvaf else eltype=st->type;
536*12549Scsvaf elsize=size(eltype);
537*12549Scsvaf sp += elsize;
538*12549Scsvaf  /*printf("ndim %d elsize %lx in fortran_printarray\n",ndim,elsize);OUT*/
539*12549Scsvaf 
540*12549Scsvaf ndim--;
541*12549Scsvaf for (i=0;i<=ndim;i++){
542*12549Scsvaf 	  dim[i].val=dim[i].lb;
543*12549Scsvaf 	  /*OUT printf(" %d %d %d \n",i,dim[i].lb,dim[i].ub);
544*12549Scsvaf 	    fflush(stdout); OUT*/
545*12549Scsvaf }
546*12549Scsvaf 
547*12549Scsvaf 
548*12549Scsvaf for(;;) {
549*12549Scsvaf 	buf[0]=',';
550*12549Scsvaf 	subscr = buf+1;
551*12549Scsvaf 
552*12549Scsvaf 	for (i=ndim-1;i>=0;i--)  {
553*12549Scsvaf 
554*12549Scsvaf 		sprintf(subscr,"%d,",dim[i].val);
555*12549Scsvaf         	subscr += strlen(subscr);
556*12549Scsvaf 	}
557*12549Scsvaf         *--subscr = '\0';
558*12549Scsvaf 
559*12549Scsvaf 	for(i=dim[ndim].lb;i<=dim[ndim].ub;i++) {
560*12549Scsvaf 	      	printf("[%d%s]\t",i,buf);
561*12549Scsvaf 		printval(eltype);
562*12549Scsvaf 	      	printf("\n");
563*12549Scsvaf 		sp += 2*elsize;
564*12549Scsvaf 	}
565*12549Scsvaf         dim[ndim].val=dim[ndim].ub;
566*12549Scsvaf 
567*12549Scsvaf         i=ndim-1;
568*12549Scsvaf         if (i<0) break;
569*12549Scsvaf 
570*12549Scsvaf         done=false;
571*12549Scsvaf         do {
572*12549Scsvaf 		dim[i].val++;
573*12549Scsvaf 		if(dim[i].val > dim[i].ub) {
574*12549Scsvaf 			dim[i].val = dim[i].lb;
575*12549Scsvaf 			if(--i<0) done=true;
576*12549Scsvaf 		}
577*12549Scsvaf 		else done=true;
578*12549Scsvaf          }
579*12549Scsvaf 	 while (not done);
580*12549Scsvaf          if (i<0) break;
581*12549Scsvaf      }
582*12549Scsvaf }
583