xref: /csrg-svn/old/dbx/fortran.c (revision 24553)
121603Sdist /*
221603Sdist  * Copyright (c) 1983 Regents of the University of California.
321603Sdist  * All rights reserved.  The Berkeley software License Agreement
421603Sdist  * specifies the terms and conditions for redistribution.
521603Sdist  */
612554Scsvaf 
721603Sdist #ifndef lint
8*24553Smckusick static char sccsid[] = "@(#)fortran.c	5.2 (Berkeley) 09/05/85";
921603Sdist #endif not lint
1012554Scsvaf 
1118219Slinton static char rcsid[] = "$Header: fortran.c,v 1.5 84/12/26 10:39:37 linton Exp $";
1218219Slinton 
1312549Scsvaf /*
1412549Scsvaf  * FORTRAN dependent symbol routines.
1512549Scsvaf  */
1612549Scsvaf 
1712549Scsvaf #include "defs.h"
1812549Scsvaf #include "symbols.h"
1912549Scsvaf #include "printsym.h"
2012549Scsvaf #include "languages.h"
2112549Scsvaf #include "fortran.h"
2212549Scsvaf #include "tree.h"
2312549Scsvaf #include "eval.h"
2412549Scsvaf #include "operators.h"
2512549Scsvaf #include "mappings.h"
2612549Scsvaf #include "process.h"
2712549Scsvaf #include "runtime.h"
2812549Scsvaf #include "machine.h"
2912549Scsvaf 
3012549Scsvaf #define isfloat(range) ( \
3112549Scsvaf     range->symvalue.rangev.upper == 0 and range->symvalue.rangev.lower > 0 \
3212549Scsvaf )
3312549Scsvaf 
3412549Scsvaf #define isrange(t, name) (t->class == RANGE and istypename(t->type, name))
3512549Scsvaf 
3612549Scsvaf #define MAXDIM  20
3716610Ssam 
3816610Ssam private Language fort;
3916610Ssam 
4012549Scsvaf /*
4112549Scsvaf  * Initialize FORTRAN language information.
4212549Scsvaf  */
4312549Scsvaf 
4412549Scsvaf public fortran_init()
4512549Scsvaf {
4616610Ssam     fort = language_define("fortran", ".f");
4716610Ssam     language_setop(fort, L_PRINTDECL, fortran_printdecl);
4816610Ssam     language_setop(fort, L_PRINTVAL, fortran_printval);
4916610Ssam     language_setop(fort, L_TYPEMATCH, fortran_typematch);
5016610Ssam     language_setop(fort, L_BUILDAREF, fortran_buildaref);
5116610Ssam     language_setop(fort, L_EVALAREF, fortran_evalaref);
5216610Ssam     language_setop(fort, L_MODINIT, fortran_modinit);
5316610Ssam     language_setop(fort, L_HASMODULES, fortran_hasmodules);
5416610Ssam     language_setop(fort, L_PASSADDR, fortran_passaddr);
5512549Scsvaf }
5612549Scsvaf 
5712549Scsvaf /*
5812549Scsvaf  * Test if two types are compatible.
5912549Scsvaf  *
6012549Scsvaf  * Integers and reals are not compatible since they cannot always be mixed.
6112549Scsvaf  */
6212549Scsvaf 
6312549Scsvaf public Boolean fortran_typematch(type1, type2)
6412549Scsvaf Symbol type1, type2;
6512549Scsvaf {
6612549Scsvaf 
6712549Scsvaf /* only does integer for now; may need to add others
6812549Scsvaf */
6912549Scsvaf 
7012549Scsvaf     Boolean b;
7112549Scsvaf     register Symbol t1, t2, tmp;
7212549Scsvaf 
7312549Scsvaf     t1 = rtype(type1);
7412549Scsvaf     t2 = rtype(type2);
7512549Scsvaf     if(t1 == nil or t1->type == nil or t2 == nil or t2->type == nil ) b = false;
7612549Scsvaf     else { b = (Boolean)   (
7712549Scsvaf             (t1 == t2)  or
7812549Scsvaf 	    (t1->type == t_int and (istypename(t2->type, "integer") or
7912549Scsvaf                                     istypename(t2->type, "integer*2"))  ) or
8012549Scsvaf 	    (t2->type == t_int and (istypename(t1->type, "integer") or
8112549Scsvaf                                     istypename(t1->type, "integer*2"))  )
8212549Scsvaf                     );
8312549Scsvaf          }
8412549Scsvaf     /*OUT fprintf(stderr," %d compat %s %s \n", b,
8512549Scsvaf       (t1 == nil or t1->type == nil ) ? "nil" : symname(t1->type),
8612549Scsvaf       (t2 == nil or t2->type == nil ) ? "nil" : symname(t2->type)  );*/
8712549Scsvaf     return b;
8812549Scsvaf }
8912549Scsvaf 
9012549Scsvaf private String typename(s)
9112549Scsvaf Symbol s;
9212549Scsvaf {
9312549Scsvaf int ub;
9412549Scsvaf static char buf[20];
9512549Scsvaf char *pbuf;
9612549Scsvaf Symbol st,sc;
9712549Scsvaf 
9812549Scsvaf      if(s->type->class == TYPE) return(symname(s->type));
9912549Scsvaf 
10012549Scsvaf      for(st = s->type; st->type->class != TYPE; st = st->type);
10112549Scsvaf 
10212549Scsvaf      pbuf=buf;
10312549Scsvaf 
10412549Scsvaf      if(istypename(st->type,"char"))  {
10512549Scsvaf 	  sprintf(pbuf,"character*");
10612549Scsvaf           pbuf += strlen(pbuf);
10712549Scsvaf 	  sc = st->chain;
10812549Scsvaf           if(sc->symvalue.rangev.uppertype == R_ARG or
10912549Scsvaf              sc->symvalue.rangev.uppertype == R_TEMP) {
11012549Scsvaf 	      if( ! getbound(s,sc->symvalue.rangev.upper,
11112549Scsvaf                     sc->symvalue.rangev.uppertype, &ub) )
11212549Scsvaf 		sprintf(pbuf,"(*)");
11312549Scsvaf 	      else
11412549Scsvaf 		sprintf(pbuf,"%d",ub);
11512549Scsvaf           }
11612549Scsvaf  	  else sprintf(pbuf,"%d",sc->symvalue.rangev.upper);
11712549Scsvaf      }
11812549Scsvaf      else {
11912549Scsvaf           sprintf(pbuf,"%s ",symname(st->type));
12012549Scsvaf      }
12112549Scsvaf      return(buf);
12212549Scsvaf }
12312549Scsvaf 
12412549Scsvaf private Symbol mksubs(pbuf,st)
12512549Scsvaf Symbol st;
12612549Scsvaf char  **pbuf;
12712549Scsvaf {
12812549Scsvaf    int lb, ub;
12912549Scsvaf    Symbol r, eltype;
13012549Scsvaf 
13112549Scsvaf    if(st->class != ARRAY or (istypename(st->type, "char")) ) return;
13212549Scsvaf    else {
13312549Scsvaf           mksubs(pbuf,st->type);
13412549Scsvaf           assert( (r = st->chain)->class == RANGE);
13512549Scsvaf 
13612549Scsvaf           if(r->symvalue.rangev.lowertype == R_ARG or
13712549Scsvaf              r->symvalue.rangev.lowertype == R_TEMP) {
13812549Scsvaf 	      if( ! getbound(st,r->symvalue.rangev.lower,
13912549Scsvaf                     r->symvalue.rangev.lowertype, &lb) )
14012549Scsvaf 		sprintf(*pbuf,"?:");
14112549Scsvaf 	      else
14212549Scsvaf 		sprintf(*pbuf,"%d:",lb);
14312549Scsvaf 	  }
14412549Scsvaf           else {
14512549Scsvaf 		lb = r->symvalue.rangev.lower;
14612549Scsvaf 		sprintf(*pbuf,"%d:",lb);
14712549Scsvaf 		}
14812549Scsvaf     	  *pbuf += strlen(*pbuf);
14912549Scsvaf 
15012549Scsvaf           if(r->symvalue.rangev.uppertype == R_ARG or
15112549Scsvaf              r->symvalue.rangev.uppertype == R_TEMP) {
15212549Scsvaf 	      if( ! getbound(st,r->symvalue.rangev.upper,
15312549Scsvaf                     r->symvalue.rangev.uppertype, &ub) )
15412549Scsvaf 		sprintf(*pbuf,"?,");
15512549Scsvaf 	      else
15612549Scsvaf 		sprintf(*pbuf,"%d,",ub);
15712549Scsvaf 	  }
15812549Scsvaf           else {
15912549Scsvaf 		ub = r->symvalue.rangev.upper;
16012549Scsvaf 		sprintf(*pbuf,"%d,",ub);
16112549Scsvaf 		}
16212549Scsvaf     	  *pbuf += strlen(*pbuf);
16312549Scsvaf 
16412549Scsvaf        }
16512549Scsvaf }
16612549Scsvaf 
16712549Scsvaf /*
16812549Scsvaf  * Print out the declaration of a FORTRAN variable.
16912549Scsvaf  */
17012549Scsvaf 
17112549Scsvaf public fortran_printdecl(s)
17212549Scsvaf Symbol s;
17312549Scsvaf {
17412549Scsvaf 
17512549Scsvaf 
17612549Scsvaf Symbol eltype;
17712549Scsvaf 
17812549Scsvaf     switch (s->class) {
17916610Ssam 
18012549Scsvaf 	case CONST:
18116610Ssam 
18212549Scsvaf 	    printf("parameter %s = ", symname(s));
18312549Scsvaf             printval(s);
18412549Scsvaf 	    break;
18512549Scsvaf 
18612549Scsvaf         case REF:
18712549Scsvaf             printf(" (dummy argument) ");
18816610Ssam 
18914652Slinton 	case VAR:
19016610Ssam 	    if (s->type->class == ARRAY &&
19116610Ssam 		 (not istypename(s->type->type,"char")) ) {
19216610Ssam                 char bounds[130], *p1, **p;
19312549Scsvaf 		p1 = bounds;
19412549Scsvaf                 p = &p1;
19516610Ssam                 mksubs(p,s->type);
19612549Scsvaf                 *p -= 1;
19712549Scsvaf                 **p = '\0';   /* get rid of trailing ',' */
19816610Ssam 		printf(" %s %s[%s] ",typename(s), symname(s), bounds);
19912549Scsvaf 	    } else {
20012549Scsvaf 		printf("%s %s", typename(s), symname(s));
20112549Scsvaf 	    }
20212549Scsvaf 	    break;
20312549Scsvaf 
20412549Scsvaf 	case FUNC:
20512627Scsvaf 	    if (not istypename(s->type, "void")) {
20612549Scsvaf                 printf(" %s function ", typename(s) );
20712549Scsvaf 	    }
20816610Ssam 	    else printf(" subroutine");
20912549Scsvaf 	    printf(" %s ", symname(s));
21012549Scsvaf 	    fortran_listparams(s);
21112549Scsvaf 	    break;
21212549Scsvaf 
21312549Scsvaf 	case MODULE:
21416610Ssam 	    printf("source file \"%s.c\"", symname(s));
21512549Scsvaf 	    break;
21612549Scsvaf 
21712549Scsvaf 	case PROG:
21812549Scsvaf 	    printf("executable file \"%s\"", symname(s));
21912549Scsvaf 	    break;
22012549Scsvaf 
22112549Scsvaf 	default:
22212549Scsvaf 	    error("class %s in fortran_printdecl", classname(s));
22312549Scsvaf     }
22412549Scsvaf     putchar('\n');
22512549Scsvaf }
22612549Scsvaf 
22712549Scsvaf /*
22812549Scsvaf  * List the parameters of a procedure or function.
22912549Scsvaf  * No attempt is made to combine like types.
23012549Scsvaf  */
23112549Scsvaf 
23212549Scsvaf public fortran_listparams(s)
23312549Scsvaf Symbol s;
23412549Scsvaf {
23512549Scsvaf     register Symbol t;
23612549Scsvaf 
23712549Scsvaf     putchar('(');
23812549Scsvaf     for (t = s->chain; t != nil; t = t->chain) {
23912549Scsvaf 	printf("%s", symname(t));
24012549Scsvaf 	if (t->chain != nil) {
24112549Scsvaf 	    printf(", ");
24212549Scsvaf 	}
24312549Scsvaf     }
24412549Scsvaf     putchar(')');
24512549Scsvaf     if (s->chain != nil) {
24612549Scsvaf 	printf("\n");
24712549Scsvaf 	for (t = s->chain; t != nil; t = t->chain) {
24812549Scsvaf 	    if (t->class != REF) {
24912549Scsvaf 		panic("unexpected class %d for parameter", t->class);
25012549Scsvaf 	    }
25112549Scsvaf 	    printdecl(t, 0);
25212549Scsvaf 	}
25312549Scsvaf     } else {
25412549Scsvaf 	putchar('\n');
25512549Scsvaf     }
25612549Scsvaf }
25712549Scsvaf 
25812549Scsvaf /*
25912549Scsvaf  * Print out the value on the top of the expression stack
26012549Scsvaf  * in the format for the type of the given symbol.
26112549Scsvaf  */
26212549Scsvaf 
26312549Scsvaf public fortran_printval(s)
26412549Scsvaf Symbol s;
26512549Scsvaf {
26612549Scsvaf     register Symbol t;
26712549Scsvaf     register Address a;
26812549Scsvaf     register int i, len;
26918219Slinton     double d1, d2;
27012549Scsvaf 
27112549Scsvaf     switch (s->class) {
27212549Scsvaf 	case CONST:
27312549Scsvaf 	case TYPE:
27412549Scsvaf 	case VAR:
27512549Scsvaf 	case REF:
27612549Scsvaf 	case FVAR:
27712549Scsvaf 	case TAG:
27812549Scsvaf 	    fortran_printval(s->type);
27912549Scsvaf 	    break;
28012549Scsvaf 
28112549Scsvaf 	case ARRAY:
28212549Scsvaf 	    t = rtype(s->type);
28312549Scsvaf 	    if (t->class == RANGE and istypename(t->type, "char")) {
28412549Scsvaf 		len = size(s);
28512549Scsvaf 		sp -= len;
28612549Scsvaf 		printf("\"%.*s\"", len, sp);
28712549Scsvaf 	    } else {
28812549Scsvaf 		fortran_printarray(s);
28912549Scsvaf 	    }
29012549Scsvaf 	    break;
29112549Scsvaf 
29212549Scsvaf 	case RANGE:
29312549Scsvaf 	     if (isfloat(s)) {
29412549Scsvaf 		switch (s->symvalue.rangev.lower) {
29512549Scsvaf 		    case sizeof(float):
29612549Scsvaf 			prtreal(pop(float));
29712549Scsvaf 			break;
29812549Scsvaf 
29912549Scsvaf 		    case sizeof(double):
30018219Slinton 			if (istypename(s->type,"complex")) {
30118219Slinton 			    d2 = pop(float);
30218219Slinton 			    d1 = pop(float);
30318219Slinton 			    printf("(");
30418219Slinton 			    prtreal(d1);
30518219Slinton 			    printf(",");
30618219Slinton 			    prtreal(d2);
30718219Slinton 			    printf(")");
30818219Slinton 			} else {
30918219Slinton 			    prtreal(pop(double));
31012549Scsvaf 			}
31112549Scsvaf 			break;
31212549Scsvaf 
313*24553Smckusick 		    case 2*sizeof(double):
314*24553Smckusick 			d2 = pop(double);
315*24553Smckusick 			d1 = pop(double);
316*24553Smckusick 			printf("(");
317*24553Smckusick 			prtreal(d1);
318*24553Smckusick 			printf(",");
319*24553Smckusick 			prtreal(d2);
320*24553Smckusick 			printf(")");
321*24553Smckusick 			break;
322*24553Smckusick 
32312549Scsvaf 		    default:
32412549Scsvaf 			panic("bad size \"%d\" for real",
325*24553Smckusick                                   s->symvalue.rangev.lower);
32612549Scsvaf 			break;
32712549Scsvaf 		}
32812549Scsvaf 	    } else {
32912549Scsvaf 		printint(popsmall(s), s);
33012549Scsvaf 	    }
33112549Scsvaf 	    break;
33212549Scsvaf 
33312549Scsvaf 	default:
33412549Scsvaf 	    if (ord(s->class) > ord(TYPEREF)) {
33512549Scsvaf 		panic("printval: bad class %d", ord(s->class));
33612549Scsvaf 	    }
33712549Scsvaf 	    error("don't know how to print a %s", fortran_classname(s));
33812549Scsvaf 	    /* NOTREACHED */
33912549Scsvaf     }
34012549Scsvaf }
34112549Scsvaf 
34212549Scsvaf /*
34312549Scsvaf  * Print out an int
34412549Scsvaf  */
34512549Scsvaf 
34612549Scsvaf private printint(i, t)
34712549Scsvaf Integer i;
34812549Scsvaf register Symbol t;
34912549Scsvaf {
35012549Scsvaf     if (istypename(t->type, "logical")) {
35112549Scsvaf 	printf(((Boolean) i) == true ? "true" : "false");
35212549Scsvaf     }
35312549Scsvaf     else if ( (t->type == t_int) or istypename(t->type, "integer") or
35412549Scsvaf                   istypename(t->type,"integer*2") ) {
35512549Scsvaf 	printf("%ld", i);
35612549Scsvaf     } else {
35712549Scsvaf       error("unkown type in fortran printint");
35812549Scsvaf     }
35912549Scsvaf }
36012549Scsvaf 
36112549Scsvaf /*
36212549Scsvaf  * Print out a null-terminated string (pointer to char)
36312549Scsvaf  * starting at the given address.
36412549Scsvaf  */
36512549Scsvaf 
36612549Scsvaf private printstring(addr)
36712549Scsvaf Address addr;
36812549Scsvaf {
36912549Scsvaf     register Address a;
37012549Scsvaf     register Integer i, len;
37112549Scsvaf     register Boolean endofstring;
37212549Scsvaf     union {
37312549Scsvaf 	char ch[sizeof(Word)];
37412549Scsvaf 	int word;
37512549Scsvaf     } u;
37612549Scsvaf 
37712549Scsvaf     putchar('"');
37812549Scsvaf     a = addr;
37912549Scsvaf     endofstring = false;
38012549Scsvaf     while (not endofstring) {
38112549Scsvaf 	dread(&u, a, sizeof(u));
38212549Scsvaf 	i = 0;
38312549Scsvaf 	do {
38412549Scsvaf 	    if (u.ch[i] == '\0') {
38512549Scsvaf 		endofstring = true;
38612549Scsvaf 	    } else {
38712549Scsvaf 		printchar(u.ch[i]);
38812549Scsvaf 	    }
38912549Scsvaf 	    ++i;
39012549Scsvaf 	} while (i < sizeof(Word) and not endofstring);
39112549Scsvaf 	a += sizeof(Word);
39212549Scsvaf     }
39312549Scsvaf     putchar('"');
39412549Scsvaf }
39512549Scsvaf /*
39612549Scsvaf  * Return the FORTRAN name for the particular class of a symbol.
39712549Scsvaf  */
39812549Scsvaf 
39912549Scsvaf public String fortran_classname(s)
40012549Scsvaf Symbol s;
40112549Scsvaf {
40212549Scsvaf     String str;
40312549Scsvaf 
40412549Scsvaf     switch (s->class) {
40512549Scsvaf 	case REF:
40612549Scsvaf 	    str = "dummy argument";
40712549Scsvaf 	    break;
40812549Scsvaf 
40912549Scsvaf 	case CONST:
41012549Scsvaf 	    str = "parameter";
41112549Scsvaf 	    break;
41212549Scsvaf 
41312549Scsvaf 	default:
41412549Scsvaf 	    str = classname(s);
41512549Scsvaf     }
41612549Scsvaf     return str;
41712549Scsvaf }
41812549Scsvaf 
41912549Scsvaf /* reverses the indices from the expr_list; should be folded into buildaref
42012549Scsvaf  * and done as one recursive routine
42112549Scsvaf  */
42212549Scsvaf Node private rev_index(here,n)
42312549Scsvaf register Node here,n;
42412549Scsvaf {
42512549Scsvaf 
42612549Scsvaf   register Node i;
42712549Scsvaf 
42812549Scsvaf   if( here == nil  or  here == n) i=nil;
42912549Scsvaf   else if( here->value.arg[1] == n) i = here;
43012549Scsvaf   else i=rev_index(here->value.arg[1],n);
43112549Scsvaf   return i;
43212549Scsvaf }
43312549Scsvaf 
43412549Scsvaf public Node fortran_buildaref(a, slist)
43512549Scsvaf Node a, slist;
43612549Scsvaf {
43712549Scsvaf     register Symbol as;      /* array of array of .. cursor */
43812549Scsvaf     register Node en;        /* Expr list cursor */
43912549Scsvaf     Symbol etype;            /* Type of subscript expr */
44012549Scsvaf     Node esub, tree;         /* Subscript expression ptr and tree to be built*/
44112549Scsvaf 
44212549Scsvaf     tree=a;
44312549Scsvaf 
44412549Scsvaf     as = rtype(tree->nodetype);     /* node->sym.type->array*/
44512549Scsvaf     if ( not (
44612549Scsvaf                (tree->nodetype->class == VAR or tree->nodetype->class == REF)
44712549Scsvaf                 and as->class == ARRAY
44812549Scsvaf              ) ) {
44912549Scsvaf 	beginerrmsg();
45012549Scsvaf 	prtree(stderr, a);
45112549Scsvaf 	fprintf(stderr, " is not an array");
45212549Scsvaf 	/*fprintf(stderr, " a-> %x as %x ", tree->nodetype, as ); OUT*/
45312549Scsvaf 	enderrmsg();
45412549Scsvaf     } else {
45512549Scsvaf 	for (en = rev_index(slist,nil); en != nil and as->class == ARRAY;
45612549Scsvaf                      en = rev_index(slist,en), as = as->type) {
45712549Scsvaf 	    esub = en->value.arg[0];
45812549Scsvaf 	    etype = rtype(esub->nodetype);
45912549Scsvaf             assert(as->chain->class == RANGE);
46012549Scsvaf 	    if ( not compatible( t_int, etype) ) {
46112549Scsvaf 		beginerrmsg();
46212549Scsvaf 		fprintf(stderr, "subscript ");
46312549Scsvaf 		prtree(stderr, esub);
46412549Scsvaf 		fprintf(stderr, " is type %s ",symname(etype->type) );
46512549Scsvaf 		enderrmsg();
46612549Scsvaf 	    }
46712549Scsvaf 	    tree = build(O_INDEX, tree, esub);
46812549Scsvaf 	    tree->nodetype = as->type;
46912549Scsvaf 	}
47012549Scsvaf 	if (en != nil or
47112549Scsvaf              (as->class == ARRAY && (not istypename(as->type,"char"))) ) {
47212549Scsvaf 	    beginerrmsg();
47312549Scsvaf 	    if (en != nil) {
47412549Scsvaf 		fprintf(stderr, "too many subscripts for ");
47512549Scsvaf 	    } else {
47612549Scsvaf 		fprintf(stderr, "not enough subscripts for ");
47712549Scsvaf 	    }
47812549Scsvaf 	    prtree(stderr, tree);
47912549Scsvaf 	    enderrmsg();
48012549Scsvaf 	}
48112549Scsvaf     }
48212549Scsvaf     return tree;
48312549Scsvaf }
48412549Scsvaf 
48512549Scsvaf /*
48612549Scsvaf  * Evaluate a subscript index.
48712549Scsvaf  */
48812549Scsvaf 
48918219Slinton public fortran_evalaref(s, base, i)
49012549Scsvaf Symbol s;
49118219Slinton Address base;
49212549Scsvaf long i;
49312549Scsvaf {
49418219Slinton     Symbol r, t;
49512549Scsvaf     long lb, ub;
49612549Scsvaf 
49718219Slinton     t = rtype(s);
49818219Slinton     r = t->chain;
49918219Slinton     if (
50018219Slinton 	r->symvalue.rangev.lowertype == R_ARG or
50118219Slinton         r->symvalue.rangev.lowertype == R_TEMP
50218219Slinton     ) {
50318219Slinton 	if (not getbound(
50418219Slinton 	    s, r->symvalue.rangev.lower, r->symvalue.rangev.lowertype, &lb
50518219Slinton 	)) {
50612549Scsvaf           error("dynamic bounds not currently available");
50718219Slinton 	}
50818219Slinton     } else {
50918219Slinton 	lb = r->symvalue.rangev.lower;
51012549Scsvaf     }
51118219Slinton     if (
51218219Slinton 	r->symvalue.rangev.uppertype == R_ARG or
51318219Slinton         r->symvalue.rangev.uppertype == R_TEMP
51418219Slinton     ) {
51518219Slinton 	if (not getbound(
51618219Slinton 	    s, r->symvalue.rangev.upper, r->symvalue.rangev.uppertype, &ub
51718219Slinton 	)) {
51812549Scsvaf           error("dynamic bounds not currently available");
51918219Slinton 	}
52018219Slinton     } else {
52118219Slinton 	ub = r->symvalue.rangev.upper;
52212549Scsvaf     }
52312549Scsvaf 
52412549Scsvaf     if (i < lb or i > ub) {
52512549Scsvaf 	error("subscript out of range");
52612549Scsvaf     }
52718219Slinton     push(long, base + (i - lb) * size(t->type));
52812549Scsvaf }
52912549Scsvaf 
53012549Scsvaf private fortran_printarray(a)
53112549Scsvaf Symbol a;
53212549Scsvaf {
53312549Scsvaf struct Bounds { int lb, val, ub} dim[MAXDIM];
53412549Scsvaf 
53512549Scsvaf Symbol sc,st,eltype;
53612549Scsvaf char buf[50];
53712549Scsvaf char *subscr;
53812549Scsvaf int i,ndim,elsize;
53912549Scsvaf Stack *savesp;
54012549Scsvaf Boolean done;
54112549Scsvaf 
54212549Scsvaf st = a;
54312549Scsvaf 
54412549Scsvaf savesp = sp;
54512549Scsvaf sp -= size(a);
54612549Scsvaf ndim=0;
54712549Scsvaf 
54812549Scsvaf for(;;){
54912549Scsvaf           sc = st->chain;
55012549Scsvaf           if(sc->symvalue.rangev.lowertype == R_ARG or
55112549Scsvaf              sc->symvalue.rangev.lowertype == R_TEMP) {
55212549Scsvaf 	      if( ! getbound(a,sc->symvalue.rangev.lower,
55312627Scsvaf                     sc->symvalue.rangev.lowertype, &dim[ndim].lb) )
55412549Scsvaf 		error(" dynamic bounds not currently available");
55512549Scsvaf 	  }
55612549Scsvaf 	  else dim[ndim].lb = sc->symvalue.rangev.lower;
55712549Scsvaf 
55812549Scsvaf           if(sc->symvalue.rangev.uppertype == R_ARG or
55912549Scsvaf              sc->symvalue.rangev.uppertype == R_TEMP) {
56012549Scsvaf 	      if( ! getbound(a,sc->symvalue.rangev.upper,
56112549Scsvaf                     sc->symvalue.rangev.uppertype, &dim[ndim].ub) )
56212549Scsvaf 		error(" dynamic bounds not currently available");
56312549Scsvaf 	  }
56412549Scsvaf 	  else dim[ndim].ub = sc->symvalue.rangev.upper;
56512549Scsvaf 
56612549Scsvaf           ndim ++;
56712549Scsvaf           if (st->type->class == ARRAY) st=st->type;
56812549Scsvaf 	  else break;
56912549Scsvaf      }
57012549Scsvaf 
57112549Scsvaf if(istypename(st->type,"char")) {
57212549Scsvaf 		eltype = st;
57312549Scsvaf 		ndim--;
57412549Scsvaf 	}
57512549Scsvaf else eltype=st->type;
57612549Scsvaf elsize=size(eltype);
57712549Scsvaf sp += elsize;
57812549Scsvaf  /*printf("ndim %d elsize %lx in fortran_printarray\n",ndim,elsize);OUT*/
57912549Scsvaf 
58012549Scsvaf ndim--;
58112549Scsvaf for (i=0;i<=ndim;i++){
58212549Scsvaf 	  dim[i].val=dim[i].lb;
58312549Scsvaf 	  /*OUT printf(" %d %d %d \n",i,dim[i].lb,dim[i].ub);
58412549Scsvaf 	    fflush(stdout); OUT*/
58512549Scsvaf }
58612549Scsvaf 
58712549Scsvaf 
58812549Scsvaf for(;;) {
58912549Scsvaf 	buf[0]=',';
59012549Scsvaf 	subscr = buf+1;
59112549Scsvaf 
59212549Scsvaf 	for (i=ndim-1;i>=0;i--)  {
59312549Scsvaf 
59412549Scsvaf 		sprintf(subscr,"%d,",dim[i].val);
59512549Scsvaf         	subscr += strlen(subscr);
59612549Scsvaf 	}
59712549Scsvaf         *--subscr = '\0';
59812549Scsvaf 
59912549Scsvaf 	for(i=dim[ndim].lb;i<=dim[ndim].ub;i++) {
60012549Scsvaf 	      	printf("[%d%s]\t",i,buf);
60112549Scsvaf 		printval(eltype);
60212549Scsvaf 	      	printf("\n");
60312549Scsvaf 		sp += 2*elsize;
60412549Scsvaf 	}
60512549Scsvaf         dim[ndim].val=dim[ndim].ub;
60612549Scsvaf 
60712549Scsvaf         i=ndim-1;
60812549Scsvaf         if (i<0) break;
60912549Scsvaf 
61012549Scsvaf         done=false;
61112549Scsvaf         do {
61212549Scsvaf 		dim[i].val++;
61312549Scsvaf 		if(dim[i].val > dim[i].ub) {
61412549Scsvaf 			dim[i].val = dim[i].lb;
61512549Scsvaf 			if(--i<0) done=true;
61612549Scsvaf 		}
61712549Scsvaf 		else done=true;
61812549Scsvaf          }
61912549Scsvaf 	 while (not done);
62012549Scsvaf          if (i<0) break;
62112549Scsvaf      }
62212549Scsvaf }
62316610Ssam 
62416610Ssam /*
62516610Ssam  * Initialize typetable at beginning of a module.
62616610Ssam  */
62716610Ssam 
62816610Ssam public fortran_modinit (typetable)
62916610Ssam Symbol typetable[];
63016610Ssam {
63116610Ssam     /* nothing for now */
63216610Ssam }
63316610Ssam 
63416610Ssam public boolean fortran_hasmodules ()
63516610Ssam {
63616610Ssam     return false;
63716610Ssam }
63816610Ssam 
63916610Ssam public boolean fortran_passaddr (param, exprtype)
64016610Ssam Symbol param, exprtype;
64116610Ssam {
64216610Ssam     return false;
64316610Ssam }
644