xref: /csrg-svn/old/dbx/fortran.c (revision 14652)
112554Scsvaf /* Copyright (c) 1982 Regents of the University of California */
212554Scsvaf 
3*14652Slinton static char sccsid[] = "@(#)fortran.c	1.4	08/16/83";
412554Scsvaf 
512549Scsvaf /*
612549Scsvaf  * FORTRAN dependent symbol routines.
712549Scsvaf  */
812549Scsvaf 
912549Scsvaf #include "defs.h"
1012549Scsvaf #include "symbols.h"
1112549Scsvaf #include "printsym.h"
1212549Scsvaf #include "languages.h"
1312549Scsvaf #include "fortran.h"
1412549Scsvaf #include "tree.h"
1512549Scsvaf #include "eval.h"
1612549Scsvaf #include "operators.h"
1712549Scsvaf #include "mappings.h"
1812549Scsvaf #include "process.h"
1912549Scsvaf #include "runtime.h"
2012549Scsvaf #include "machine.h"
2112549Scsvaf 
2212549Scsvaf #define isfloat(range) ( \
2312549Scsvaf     range->symvalue.rangev.upper == 0 and range->symvalue.rangev.lower > 0 \
2412549Scsvaf )
2512549Scsvaf 
2612549Scsvaf #define isrange(t, name) (t->class == RANGE and istypename(t->type, name))
2712549Scsvaf 
2812549Scsvaf #define MAXDIM  20
2912549Scsvaf /*
3012549Scsvaf  * Initialize FORTRAN language information.
3112549Scsvaf  */
3212549Scsvaf 
3312549Scsvaf public fortran_init()
3412549Scsvaf {
3512549Scsvaf     Language lang;
3612549Scsvaf 
3712549Scsvaf     lang = language_define("fortran", ".f");
3812549Scsvaf     language_setop(lang, L_PRINTDECL, fortran_printdecl);
3912549Scsvaf     language_setop(lang, L_PRINTVAL, fortran_printval);
4012549Scsvaf     language_setop(lang, L_TYPEMATCH, fortran_typematch);
4112549Scsvaf     language_setop(lang, L_BUILDAREF, fortran_buildaref);
4212549Scsvaf     language_setop(lang, L_EVALAREF, fortran_evalaref);
4312549Scsvaf }
4412549Scsvaf 
4512549Scsvaf /*
4612549Scsvaf  * Test if two types are compatible.
4712549Scsvaf  *
4812549Scsvaf  * Integers and reals are not compatible since they cannot always be mixed.
4912549Scsvaf  */
5012549Scsvaf 
5112549Scsvaf public Boolean fortran_typematch(type1, type2)
5212549Scsvaf Symbol type1, type2;
5312549Scsvaf {
5412549Scsvaf 
5512549Scsvaf /* only does integer for now; may need to add others
5612549Scsvaf */
5712549Scsvaf 
5812549Scsvaf     Boolean b;
5912549Scsvaf     register Symbol t1, t2, tmp;
6012549Scsvaf 
6112549Scsvaf     t1 = rtype(type1);
6212549Scsvaf     t2 = rtype(type2);
6312549Scsvaf     if(t1 == nil or t1->type == nil or t2 == nil or t2->type == nil ) b = false;
6412549Scsvaf     else { b = (Boolean)   (
6512549Scsvaf             (t1 == t2)  or
6612549Scsvaf 	    (t1->type == t_int and (istypename(t2->type, "integer") or
6712549Scsvaf                                     istypename(t2->type, "integer*2"))  ) or
6812549Scsvaf 	    (t2->type == t_int and (istypename(t1->type, "integer") or
6912549Scsvaf                                     istypename(t1->type, "integer*2"))  )
7012549Scsvaf                     );
7112549Scsvaf          }
7212549Scsvaf     /*OUT fprintf(stderr," %d compat %s %s \n", b,
7312549Scsvaf       (t1 == nil or t1->type == nil ) ? "nil" : symname(t1->type),
7412549Scsvaf       (t2 == nil or t2->type == nil ) ? "nil" : symname(t2->type)  );*/
7512549Scsvaf     return b;
7612549Scsvaf }
7712549Scsvaf 
7812549Scsvaf private String typename(s)
7912549Scsvaf Symbol s;
8012549Scsvaf {
8112549Scsvaf int ub;
8212549Scsvaf static char buf[20];
8312549Scsvaf char *pbuf;
8412549Scsvaf Symbol st,sc;
8512549Scsvaf 
8612549Scsvaf      if(s->type->class == TYPE) return(symname(s->type));
8712549Scsvaf 
8812549Scsvaf      for(st = s->type; st->type->class != TYPE; st = st->type);
8912549Scsvaf 
9012549Scsvaf      pbuf=buf;
9112549Scsvaf 
9212549Scsvaf      if(istypename(st->type,"char"))  {
9312549Scsvaf 	  sprintf(pbuf,"character*");
9412549Scsvaf           pbuf += strlen(pbuf);
9512549Scsvaf 	  sc = st->chain;
9612549Scsvaf           if(sc->symvalue.rangev.uppertype == R_ARG or
9712549Scsvaf              sc->symvalue.rangev.uppertype == R_TEMP) {
9812549Scsvaf 	      if( ! getbound(s,sc->symvalue.rangev.upper,
9912549Scsvaf                     sc->symvalue.rangev.uppertype, &ub) )
10012549Scsvaf 		sprintf(pbuf,"(*)");
10112549Scsvaf 	      else
10212549Scsvaf 		sprintf(pbuf,"%d",ub);
10312549Scsvaf           }
10412549Scsvaf  	  else sprintf(pbuf,"%d",sc->symvalue.rangev.upper);
10512549Scsvaf      }
10612549Scsvaf      else {
10712549Scsvaf           sprintf(pbuf,"%s ",symname(st->type));
10812549Scsvaf      }
10912549Scsvaf      return(buf);
11012549Scsvaf }
11112549Scsvaf 
11212549Scsvaf private Symbol mksubs(pbuf,st)
11312549Scsvaf Symbol st;
11412549Scsvaf char  **pbuf;
11512549Scsvaf {
11612549Scsvaf    int lb, ub;
11712549Scsvaf    Symbol r, eltype;
11812549Scsvaf 
11912549Scsvaf    if(st->class != ARRAY or (istypename(st->type, "char")) ) return;
12012549Scsvaf    else {
12112549Scsvaf           mksubs(pbuf,st->type);
12212549Scsvaf           assert( (r = st->chain)->class == RANGE);
12312549Scsvaf 
12412549Scsvaf           if(r->symvalue.rangev.lowertype == R_ARG or
12512549Scsvaf              r->symvalue.rangev.lowertype == R_TEMP) {
12612549Scsvaf 	      if( ! getbound(st,r->symvalue.rangev.lower,
12712549Scsvaf                     r->symvalue.rangev.lowertype, &lb) )
12812549Scsvaf 		sprintf(*pbuf,"?:");
12912549Scsvaf 	      else
13012549Scsvaf 		sprintf(*pbuf,"%d:",lb);
13112549Scsvaf 	  }
13212549Scsvaf           else {
13312549Scsvaf 		lb = r->symvalue.rangev.lower;
13412549Scsvaf 		sprintf(*pbuf,"%d:",lb);
13512549Scsvaf 		}
13612549Scsvaf     	  *pbuf += strlen(*pbuf);
13712549Scsvaf 
13812549Scsvaf           if(r->symvalue.rangev.uppertype == R_ARG or
13912549Scsvaf              r->symvalue.rangev.uppertype == R_TEMP) {
14012549Scsvaf 	      if( ! getbound(st,r->symvalue.rangev.upper,
14112549Scsvaf                     r->symvalue.rangev.uppertype, &ub) )
14212549Scsvaf 		sprintf(*pbuf,"?,");
14312549Scsvaf 	      else
14412549Scsvaf 		sprintf(*pbuf,"%d,",ub);
14512549Scsvaf 	  }
14612549Scsvaf           else {
14712549Scsvaf 		ub = r->symvalue.rangev.upper;
14812549Scsvaf 		sprintf(*pbuf,"%d,",ub);
14912549Scsvaf 		}
15012549Scsvaf     	  *pbuf += strlen(*pbuf);
15112549Scsvaf 
15212549Scsvaf        }
15312549Scsvaf }
15412549Scsvaf 
15512549Scsvaf /*
15612549Scsvaf  * Print out the declaration of a FORTRAN variable.
15712549Scsvaf  */
15812549Scsvaf 
15912549Scsvaf public fortran_printdecl(s)
16012549Scsvaf Symbol s;
16112549Scsvaf {
16212549Scsvaf 
16312549Scsvaf 
16412549Scsvaf Symbol eltype;
16512549Scsvaf 
16612549Scsvaf     switch (s->class) {
16712549Scsvaf 	case CONST:
16812549Scsvaf 	    printf("parameter %s = ", symname(s));
16912549Scsvaf             printval(s);
17012549Scsvaf 	    break;
17112549Scsvaf 
17212549Scsvaf         case REF:
17312549Scsvaf             printf(" (dummy argument) ");
174*14652Slinton 	    /* fall through */
175*14652Slinton 	case VAR:
176*14652Slinton 	    if (s->type->class == ARRAY and
177*14652Slinton 	        (not istypename(s->type->type, "char"))
178*14652Slinton 	    ) {
179*14652Slinton 		char bounds[130], *p1, **p;
18012549Scsvaf 
18112549Scsvaf 		p1 = bounds;
18212549Scsvaf                 p = &p1;
183*14652Slinton                 mksubs(p, s->type);
18412549Scsvaf                 *p -= 1;
18512549Scsvaf                 **p = '\0';   /* get rid of trailing ',' */
186*14652Slinton 		printf(" %s %s[%s] ", typename(s), symname(s), bounds);
18712549Scsvaf 	    } else {
18812549Scsvaf 		printf("%s %s", typename(s), symname(s));
18912549Scsvaf 	    }
19012549Scsvaf 	    break;
19112549Scsvaf 
19212549Scsvaf 	case FUNC:
19312627Scsvaf 	    if (not istypename(s->type, "void")) {
19412549Scsvaf                 printf(" %s function ", typename(s) );
195*14652Slinton 	    } else {
196*14652Slinton 		printf(" subroutine");
19712549Scsvaf 	    }
19812549Scsvaf 	    printf(" %s ", symname(s));
19912549Scsvaf 	    fortran_listparams(s);
20012549Scsvaf 	    break;
20112549Scsvaf 
20212549Scsvaf 	case MODULE:
203*14652Slinton 	    printf("source file \"%s.f\"", symname(s));
20412549Scsvaf 	    break;
20512549Scsvaf 
20612549Scsvaf 	case PROG:
20712549Scsvaf 	    printf("executable file \"%s\"", symname(s));
20812549Scsvaf 	    break;
20912549Scsvaf 
21012549Scsvaf 	default:
21112549Scsvaf 	    error("class %s in fortran_printdecl", classname(s));
21212549Scsvaf     }
21312549Scsvaf     putchar('\n');
21412549Scsvaf }
21512549Scsvaf 
21612549Scsvaf /*
21712549Scsvaf  * List the parameters of a procedure or function.
21812549Scsvaf  * No attempt is made to combine like types.
21912549Scsvaf  */
22012549Scsvaf 
22112549Scsvaf public fortran_listparams(s)
22212549Scsvaf Symbol s;
22312549Scsvaf {
22412549Scsvaf     register Symbol t;
22512549Scsvaf 
22612549Scsvaf     putchar('(');
22712549Scsvaf     for (t = s->chain; t != nil; t = t->chain) {
22812549Scsvaf 	printf("%s", symname(t));
22912549Scsvaf 	if (t->chain != nil) {
23012549Scsvaf 	    printf(", ");
23112549Scsvaf 	}
23212549Scsvaf     }
23312549Scsvaf     putchar(')');
23412549Scsvaf     if (s->chain != nil) {
23512549Scsvaf 	printf("\n");
23612549Scsvaf 	for (t = s->chain; t != nil; t = t->chain) {
23712549Scsvaf 	    if (t->class != REF) {
23812549Scsvaf 		panic("unexpected class %d for parameter", t->class);
23912549Scsvaf 	    }
24012549Scsvaf 	    printdecl(t, 0);
24112549Scsvaf 	}
24212549Scsvaf     } else {
24312549Scsvaf 	putchar('\n');
24412549Scsvaf     }
24512549Scsvaf }
24612549Scsvaf 
24712549Scsvaf /*
24812549Scsvaf  * Print out the value on the top of the expression stack
24912549Scsvaf  * in the format for the type of the given symbol.
25012549Scsvaf  */
25112549Scsvaf 
25212549Scsvaf public fortran_printval(s)
25312549Scsvaf Symbol s;
25412549Scsvaf {
25512549Scsvaf     register Symbol t;
25612549Scsvaf     register Address a;
25712549Scsvaf     register int i, len;
25812549Scsvaf 
25912549Scsvaf     /* printf("fortran_printval with class %s \n",classname(s)); OUT*/
26012549Scsvaf     switch (s->class) {
26112549Scsvaf 	case CONST:
26212549Scsvaf 	case TYPE:
26312549Scsvaf 	case VAR:
26412549Scsvaf 	case REF:
26512549Scsvaf 	case FVAR:
26612549Scsvaf 	case TAG:
26712549Scsvaf 	    fortran_printval(s->type);
26812549Scsvaf 	    break;
26912549Scsvaf 
27012549Scsvaf 	case ARRAY:
27112549Scsvaf 	    t = rtype(s->type);
27212549Scsvaf 	    if (t->class == RANGE and istypename(t->type, "char")) {
27312549Scsvaf 		len = size(s);
27412549Scsvaf 		sp -= len;
27512549Scsvaf 		printf("\"%.*s\"", len, sp);
27612549Scsvaf 	    } else {
27712549Scsvaf 		fortran_printarray(s);
27812549Scsvaf 	    }
27912549Scsvaf 	    break;
28012549Scsvaf 
28112549Scsvaf 	case RANGE:
28212549Scsvaf 	     if (isfloat(s)) {
28312549Scsvaf 		switch (s->symvalue.rangev.lower) {
28412549Scsvaf 		    case sizeof(float):
28512549Scsvaf 			prtreal(pop(float));
28612549Scsvaf 			break;
28712549Scsvaf 
28812549Scsvaf 		    case sizeof(double):
28912549Scsvaf 			if(istypename(s->type,"complex")) {
29012549Scsvaf 			   printf("(");
29112549Scsvaf 			prtreal(pop(float));
29212549Scsvaf 			   printf(",");
29312549Scsvaf 			prtreal(pop(float));
29412549Scsvaf 			   printf(")");
29512549Scsvaf 			}
29612549Scsvaf 			else prtreal(pop(double));
29712549Scsvaf 			break;
29812549Scsvaf 
29912549Scsvaf 		    default:
30012549Scsvaf 			panic("bad size \"%d\" for real",
30112549Scsvaf                                   t->symvalue.rangev.lower);
30212549Scsvaf 			break;
30312549Scsvaf 		}
30412549Scsvaf 	    } else {
30512549Scsvaf 		printint(popsmall(s), s);
30612549Scsvaf 	    }
30712549Scsvaf 	    break;
30812549Scsvaf 
30912549Scsvaf 	default:
31012549Scsvaf 	    if (ord(s->class) > ord(TYPEREF)) {
31112549Scsvaf 		panic("printval: bad class %d", ord(s->class));
31212549Scsvaf 	    }
31312549Scsvaf 	    error("don't know how to print a %s", fortran_classname(s));
31412549Scsvaf 	    /* NOTREACHED */
31512549Scsvaf     }
31612549Scsvaf }
31712549Scsvaf 
31812549Scsvaf /*
31912549Scsvaf  * Print out an int
32012549Scsvaf  */
32112549Scsvaf 
32212549Scsvaf private printint(i, t)
32312549Scsvaf Integer i;
32412549Scsvaf register Symbol t;
32512549Scsvaf {
32612549Scsvaf     if (istypename(t->type, "logical")) {
32712549Scsvaf 	printf(((Boolean) i) == true ? "true" : "false");
32812549Scsvaf     }
32912549Scsvaf     else if ( (t->type == t_int) or istypename(t->type, "integer") or
33012549Scsvaf                   istypename(t->type,"integer*2") ) {
33112549Scsvaf 	printf("%ld", i);
33212549Scsvaf     } else {
33312549Scsvaf       error("unkown type in fortran printint");
33412549Scsvaf     }
33512549Scsvaf }
33612549Scsvaf 
33712549Scsvaf /*
33812549Scsvaf  * Print out a null-terminated string (pointer to char)
33912549Scsvaf  * starting at the given address.
34012549Scsvaf  */
34112549Scsvaf 
34212549Scsvaf private printstring(addr)
34312549Scsvaf Address addr;
34412549Scsvaf {
34512549Scsvaf     register Address a;
34612549Scsvaf     register Integer i, len;
34712549Scsvaf     register Boolean endofstring;
34812549Scsvaf     union {
34912549Scsvaf 	char ch[sizeof(Word)];
35012549Scsvaf 	int word;
35112549Scsvaf     } u;
35212549Scsvaf 
35312549Scsvaf     putchar('"');
35412549Scsvaf     a = addr;
35512549Scsvaf     endofstring = false;
35612549Scsvaf     while (not endofstring) {
35712549Scsvaf 	dread(&u, a, sizeof(u));
35812549Scsvaf 	i = 0;
35912549Scsvaf 	do {
36012549Scsvaf 	    if (u.ch[i] == '\0') {
36112549Scsvaf 		endofstring = true;
36212549Scsvaf 	    } else {
36312549Scsvaf 		printchar(u.ch[i]);
36412549Scsvaf 	    }
36512549Scsvaf 	    ++i;
36612549Scsvaf 	} while (i < sizeof(Word) and not endofstring);
36712549Scsvaf 	a += sizeof(Word);
36812549Scsvaf     }
36912549Scsvaf     putchar('"');
37012549Scsvaf }
37112549Scsvaf /*
37212549Scsvaf  * Return the FORTRAN name for the particular class of a symbol.
37312549Scsvaf  */
37412549Scsvaf 
37512549Scsvaf public String fortran_classname(s)
37612549Scsvaf Symbol s;
37712549Scsvaf {
37812549Scsvaf     String str;
37912549Scsvaf 
38012549Scsvaf     switch (s->class) {
38112549Scsvaf 	case REF:
38212549Scsvaf 	    str = "dummy argument";
38312549Scsvaf 	    break;
38412549Scsvaf 
38512549Scsvaf 	case CONST:
38612549Scsvaf 	    str = "parameter";
38712549Scsvaf 	    break;
38812549Scsvaf 
38912549Scsvaf 	default:
39012549Scsvaf 	    str = classname(s);
39112549Scsvaf     }
39212549Scsvaf     return str;
39312549Scsvaf }
39412549Scsvaf 
39512549Scsvaf /* reverses the indices from the expr_list; should be folded into buildaref
39612549Scsvaf  * and done as one recursive routine
39712549Scsvaf  */
39812549Scsvaf Node private rev_index(here,n)
39912549Scsvaf register Node here,n;
40012549Scsvaf {
40112549Scsvaf 
40212549Scsvaf   register Node i;
40312549Scsvaf 
40412549Scsvaf   if( here == nil  or  here == n) i=nil;
40512549Scsvaf   else if( here->value.arg[1] == n) i = here;
40612549Scsvaf   else i=rev_index(here->value.arg[1],n);
40712549Scsvaf   return i;
40812549Scsvaf }
40912549Scsvaf 
41012549Scsvaf public Node fortran_buildaref(a, slist)
41112549Scsvaf Node a, slist;
41212549Scsvaf {
41312549Scsvaf     register Symbol as;      /* array of array of .. cursor */
41412549Scsvaf     register Node en;        /* Expr list cursor */
41512549Scsvaf     Symbol etype;            /* Type of subscript expr */
41612549Scsvaf     Node esub, tree;         /* Subscript expression ptr and tree to be built*/
41712549Scsvaf 
41812549Scsvaf     tree=a;
41912549Scsvaf 
42012549Scsvaf     as = rtype(tree->nodetype);     /* node->sym.type->array*/
42112549Scsvaf     if ( not (
42212549Scsvaf                (tree->nodetype->class == VAR or tree->nodetype->class == REF)
42312549Scsvaf                 and as->class == ARRAY
42412549Scsvaf              ) ) {
42512549Scsvaf 	beginerrmsg();
42612549Scsvaf 	prtree(stderr, a);
42712549Scsvaf 	fprintf(stderr, " is not an array");
42812549Scsvaf 	/*fprintf(stderr, " a-> %x as %x ", tree->nodetype, as ); OUT*/
42912549Scsvaf 	enderrmsg();
43012549Scsvaf     } else {
43112549Scsvaf 	for (en = rev_index(slist,nil); en != nil and as->class == ARRAY;
43212549Scsvaf                      en = rev_index(slist,en), as = as->type) {
43312549Scsvaf 	    esub = en->value.arg[0];
43412549Scsvaf 	    etype = rtype(esub->nodetype);
43512549Scsvaf             assert(as->chain->class == RANGE);
43612549Scsvaf 	    if ( not compatible( t_int, etype) ) {
43712549Scsvaf 		beginerrmsg();
43812549Scsvaf 		fprintf(stderr, "subscript ");
43912549Scsvaf 		prtree(stderr, esub);
44012549Scsvaf 		fprintf(stderr, " is type %s ",symname(etype->type) );
44112549Scsvaf 		enderrmsg();
44212549Scsvaf 	    }
44312549Scsvaf 	    tree = build(O_INDEX, tree, esub);
44412549Scsvaf 	    tree->nodetype = as->type;
44512549Scsvaf 	}
44612549Scsvaf 	if (en != nil or
44712549Scsvaf              (as->class == ARRAY && (not istypename(as->type,"char"))) ) {
44812549Scsvaf 	    beginerrmsg();
44912549Scsvaf 	    if (en != nil) {
45012549Scsvaf 		fprintf(stderr, "too many subscripts for ");
45112549Scsvaf 	    } else {
45212549Scsvaf 		fprintf(stderr, "not enough subscripts for ");
45312549Scsvaf 	    }
45412549Scsvaf 	    prtree(stderr, tree);
45512549Scsvaf 	    enderrmsg();
45612549Scsvaf 	}
45712549Scsvaf     }
45812549Scsvaf     return tree;
45912549Scsvaf }
46012549Scsvaf 
46112549Scsvaf /*
46212549Scsvaf  * Evaluate a subscript index.
46312549Scsvaf  */
46412549Scsvaf 
46512549Scsvaf public int fortran_evalaref(s, i)
46612549Scsvaf Symbol s;
46712549Scsvaf long i;
46812549Scsvaf {
46912549Scsvaf     Symbol r;
47012549Scsvaf     long lb, ub;
47112549Scsvaf 
47212549Scsvaf     r = rtype(s)->chain;
47312549Scsvaf     if(r->symvalue.rangev.lowertype == R_ARG or
47412549Scsvaf        r->symvalue.rangev.lowertype == R_TEMP  ) {
47512549Scsvaf 	if(! getbound(s,r->symvalue.rangev.lower,
47612549Scsvaf 		        r->symvalue.rangev.lowertype,&lb))
47712549Scsvaf           error("dynamic bounds not currently available");
47812549Scsvaf     }
47912549Scsvaf     else lb = r->symvalue.rangev.lower;
48012549Scsvaf 
48112549Scsvaf     if(r->symvalue.rangev.uppertype == R_ARG or
48212549Scsvaf        r->symvalue.rangev.uppertype == R_TEMP  ) {
48312549Scsvaf 	if(! getbound(s,r->symvalue.rangev.upper,
48412549Scsvaf 		        r->symvalue.rangev.uppertype,&ub))
48512549Scsvaf           error("dynamic bounds not currently available");
48612549Scsvaf     }
48712549Scsvaf     else ub = r->symvalue.rangev.upper;
48812549Scsvaf 
48912549Scsvaf     if (i < lb or i > ub) {
49012549Scsvaf 	error("subscript out of range");
49112549Scsvaf     }
49212549Scsvaf     return (i - lb);
49312549Scsvaf }
49412549Scsvaf 
49512549Scsvaf private fortran_printarray(a)
49612549Scsvaf Symbol a;
49712549Scsvaf {
49812549Scsvaf struct Bounds { int lb, val, ub} dim[MAXDIM];
49912549Scsvaf 
50012549Scsvaf Symbol sc,st,eltype;
50112549Scsvaf char buf[50];
50212549Scsvaf char *subscr;
50312549Scsvaf int i,ndim,elsize;
50412549Scsvaf Stack *savesp;
50512549Scsvaf Boolean done;
50612549Scsvaf 
50712549Scsvaf st = a;
50812549Scsvaf 
50912549Scsvaf savesp = sp;
51012549Scsvaf sp -= size(a);
51112549Scsvaf ndim=0;
51212549Scsvaf 
51312549Scsvaf for(;;){
51412549Scsvaf           sc = st->chain;
51512549Scsvaf           if(sc->symvalue.rangev.lowertype == R_ARG or
51612549Scsvaf              sc->symvalue.rangev.lowertype == R_TEMP) {
51712549Scsvaf 	      if( ! getbound(a,sc->symvalue.rangev.lower,
51812627Scsvaf                     sc->symvalue.rangev.lowertype, &dim[ndim].lb) )
51912549Scsvaf 		error(" dynamic bounds not currently available");
52012549Scsvaf 	  }
52112549Scsvaf 	  else dim[ndim].lb = sc->symvalue.rangev.lower;
52212549Scsvaf 
52312549Scsvaf           if(sc->symvalue.rangev.uppertype == R_ARG or
52412549Scsvaf              sc->symvalue.rangev.uppertype == R_TEMP) {
52512549Scsvaf 	      if( ! getbound(a,sc->symvalue.rangev.upper,
52612549Scsvaf                     sc->symvalue.rangev.uppertype, &dim[ndim].ub) )
52712549Scsvaf 		error(" dynamic bounds not currently available");
52812549Scsvaf 	  }
52912549Scsvaf 	  else dim[ndim].ub = sc->symvalue.rangev.upper;
53012549Scsvaf 
53112549Scsvaf           ndim ++;
53212549Scsvaf           if (st->type->class == ARRAY) st=st->type;
53312549Scsvaf 	  else break;
53412549Scsvaf      }
53512549Scsvaf 
53612549Scsvaf if(istypename(st->type,"char")) {
53712549Scsvaf 		eltype = st;
53812549Scsvaf 		ndim--;
53912549Scsvaf 	}
54012549Scsvaf else eltype=st->type;
54112549Scsvaf elsize=size(eltype);
54212549Scsvaf sp += elsize;
54312549Scsvaf  /*printf("ndim %d elsize %lx in fortran_printarray\n",ndim,elsize);OUT*/
54412549Scsvaf 
54512549Scsvaf ndim--;
54612549Scsvaf for (i=0;i<=ndim;i++){
54712549Scsvaf 	  dim[i].val=dim[i].lb;
54812549Scsvaf 	  /*OUT printf(" %d %d %d \n",i,dim[i].lb,dim[i].ub);
54912549Scsvaf 	    fflush(stdout); OUT*/
55012549Scsvaf }
55112549Scsvaf 
55212549Scsvaf 
55312549Scsvaf for(;;) {
55412549Scsvaf 	buf[0]=',';
55512549Scsvaf 	subscr = buf+1;
55612549Scsvaf 
55712549Scsvaf 	for (i=ndim-1;i>=0;i--)  {
55812549Scsvaf 
55912549Scsvaf 		sprintf(subscr,"%d,",dim[i].val);
56012549Scsvaf         	subscr += strlen(subscr);
56112549Scsvaf 	}
56212549Scsvaf         *--subscr = '\0';
56312549Scsvaf 
56412549Scsvaf 	for(i=dim[ndim].lb;i<=dim[ndim].ub;i++) {
56512549Scsvaf 	      	printf("[%d%s]\t",i,buf);
56612549Scsvaf 		printval(eltype);
56712549Scsvaf 	      	printf("\n");
56812549Scsvaf 		sp += 2*elsize;
56912549Scsvaf 	}
57012549Scsvaf         dim[ndim].val=dim[ndim].ub;
57112549Scsvaf 
57212549Scsvaf         i=ndim-1;
57312549Scsvaf         if (i<0) break;
57412549Scsvaf 
57512549Scsvaf         done=false;
57612549Scsvaf         do {
57712549Scsvaf 		dim[i].val++;
57812549Scsvaf 		if(dim[i].val > dim[i].ub) {
57912549Scsvaf 			dim[i].val = dim[i].lb;
58012549Scsvaf 			if(--i<0) done=true;
58112549Scsvaf 		}
58212549Scsvaf 		else done=true;
58312549Scsvaf          }
58412549Scsvaf 	 while (not done);
58512549Scsvaf          if (i<0) break;
58612549Scsvaf      }
58712549Scsvaf }
588