121603Sdist /*
238105Sbostic * Copyright (c) 1983 The Regents of the University of California.
338105Sbostic * All rights reserved.
438105Sbostic *
5*42683Sbostic * %sccs.include.redist.c%
621603Sdist */
712554Scsvaf
821603Sdist #ifndef lint
9*42683Sbostic static char sccsid[] = "@(#)fortran.c 5.7 (Berkeley) 06/01/90";
1038105Sbostic #endif /* not lint */
1112554Scsvaf
1212549Scsvaf /*
1312549Scsvaf * FORTRAN dependent symbol routines.
1412549Scsvaf */
1512549Scsvaf
1612549Scsvaf #include "defs.h"
1712549Scsvaf #include "symbols.h"
1812549Scsvaf #include "printsym.h"
1912549Scsvaf #include "languages.h"
2012549Scsvaf #include "fortran.h"
2112549Scsvaf #include "tree.h"
2212549Scsvaf #include "eval.h"
2312549Scsvaf #include "operators.h"
2412549Scsvaf #include "mappings.h"
2512549Scsvaf #include "process.h"
2612549Scsvaf #include "runtime.h"
2712549Scsvaf #include "machine.h"
2812549Scsvaf
2925810Sdonn #define isspecial(range) ( \
3012549Scsvaf range->symvalue.rangev.upper == 0 and range->symvalue.rangev.lower > 0 \
3112549Scsvaf )
3212549Scsvaf
3312549Scsvaf #define isrange(t, name) (t->class == RANGE and istypename(t->type, name))
3412549Scsvaf
3512549Scsvaf #define MAXDIM 20
3616610Ssam
3716610Ssam private Language fort;
3816610Ssam
3912549Scsvaf /*
4012549Scsvaf * Initialize FORTRAN language information.
4112549Scsvaf */
4212549Scsvaf
fortran_init()4312549Scsvaf public fortran_init()
4412549Scsvaf {
4516610Ssam fort = language_define("fortran", ".f");
4616610Ssam language_setop(fort, L_PRINTDECL, fortran_printdecl);
4716610Ssam language_setop(fort, L_PRINTVAL, fortran_printval);
4816610Ssam language_setop(fort, L_TYPEMATCH, fortran_typematch);
4916610Ssam language_setop(fort, L_BUILDAREF, fortran_buildaref);
5016610Ssam language_setop(fort, L_EVALAREF, fortran_evalaref);
5116610Ssam language_setop(fort, L_MODINIT, fortran_modinit);
5216610Ssam language_setop(fort, L_HASMODULES, fortran_hasmodules);
5316610Ssam language_setop(fort, L_PASSADDR, fortran_passaddr);
5412549Scsvaf }
5512549Scsvaf
5612549Scsvaf /*
5712549Scsvaf * Test if two types are compatible.
5812549Scsvaf *
5912549Scsvaf * Integers and reals are not compatible since they cannot always be mixed.
6012549Scsvaf */
6112549Scsvaf
fortran_typematch(type1,type2)6212549Scsvaf public Boolean fortran_typematch(type1, type2)
6312549Scsvaf Symbol type1, type2;
6412549Scsvaf {
6512549Scsvaf
6612549Scsvaf /* only does integer for now; may need to add others
6712549Scsvaf */
6812549Scsvaf
6912549Scsvaf Boolean b;
7012549Scsvaf register Symbol t1, t2, tmp;
7112549Scsvaf
7212549Scsvaf t1 = rtype(type1);
7312549Scsvaf t2 = rtype(type2);
7412549Scsvaf if(t1 == nil or t1->type == nil or t2 == nil or t2->type == nil ) b = false;
7512549Scsvaf else { b = (Boolean) (
7612549Scsvaf (t1 == t2) or
7712549Scsvaf (t1->type == t_int and (istypename(t2->type, "integer") or
7812549Scsvaf istypename(t2->type, "integer*2")) ) or
7912549Scsvaf (t2->type == t_int and (istypename(t1->type, "integer") or
8012549Scsvaf istypename(t1->type, "integer*2")) )
8112549Scsvaf );
8212549Scsvaf }
8312549Scsvaf /*OUT fprintf(stderr," %d compat %s %s \n", b,
8412549Scsvaf (t1 == nil or t1->type == nil ) ? "nil" : symname(t1->type),
8512549Scsvaf (t2 == nil or t2->type == nil ) ? "nil" : symname(t2->type) );*/
8612549Scsvaf return b;
8712549Scsvaf }
8812549Scsvaf
typename(s)8912549Scsvaf private String typename(s)
9012549Scsvaf Symbol s;
9112549Scsvaf {
9212549Scsvaf int ub;
9312549Scsvaf static char buf[20];
9412549Scsvaf char *pbuf;
9512549Scsvaf Symbol st,sc;
9612549Scsvaf
9712549Scsvaf if(s->type->class == TYPE) return(symname(s->type));
9812549Scsvaf
9912549Scsvaf for(st = s->type; st->type->class != TYPE; st = st->type);
10012549Scsvaf
10112549Scsvaf pbuf=buf;
10212549Scsvaf
10312549Scsvaf if(istypename(st->type,"char")) {
10412549Scsvaf sprintf(pbuf,"character*");
10512549Scsvaf pbuf += strlen(pbuf);
10612549Scsvaf sc = st->chain;
10712549Scsvaf if(sc->symvalue.rangev.uppertype == R_ARG or
10812549Scsvaf sc->symvalue.rangev.uppertype == R_TEMP) {
10912549Scsvaf if( ! getbound(s,sc->symvalue.rangev.upper,
11012549Scsvaf sc->symvalue.rangev.uppertype, &ub) )
11112549Scsvaf sprintf(pbuf,"(*)");
11212549Scsvaf else
11312549Scsvaf sprintf(pbuf,"%d",ub);
11412549Scsvaf }
11512549Scsvaf else sprintf(pbuf,"%d",sc->symvalue.rangev.upper);
11612549Scsvaf }
11712549Scsvaf else {
11812549Scsvaf sprintf(pbuf,"%s ",symname(st->type));
11912549Scsvaf }
12012549Scsvaf return(buf);
12112549Scsvaf }
12212549Scsvaf
mksubs(pbuf,st)12312549Scsvaf private Symbol mksubs(pbuf,st)
12412549Scsvaf Symbol st;
12512549Scsvaf char **pbuf;
12612549Scsvaf {
12712549Scsvaf int lb, ub;
12812549Scsvaf Symbol r, eltype;
12912549Scsvaf
13012549Scsvaf if(st->class != ARRAY or (istypename(st->type, "char")) ) return;
13112549Scsvaf else {
13212549Scsvaf mksubs(pbuf,st->type);
13312549Scsvaf assert( (r = st->chain)->class == RANGE);
13412549Scsvaf
13512549Scsvaf if(r->symvalue.rangev.lowertype == R_ARG or
13612549Scsvaf r->symvalue.rangev.lowertype == R_TEMP) {
13712549Scsvaf if( ! getbound(st,r->symvalue.rangev.lower,
13812549Scsvaf r->symvalue.rangev.lowertype, &lb) )
13912549Scsvaf sprintf(*pbuf,"?:");
14012549Scsvaf else
14112549Scsvaf sprintf(*pbuf,"%d:",lb);
14212549Scsvaf }
14312549Scsvaf else {
14412549Scsvaf lb = r->symvalue.rangev.lower;
14512549Scsvaf sprintf(*pbuf,"%d:",lb);
14612549Scsvaf }
14712549Scsvaf *pbuf += strlen(*pbuf);
14812549Scsvaf
14912549Scsvaf if(r->symvalue.rangev.uppertype == R_ARG or
15012549Scsvaf r->symvalue.rangev.uppertype == R_TEMP) {
15112549Scsvaf if( ! getbound(st,r->symvalue.rangev.upper,
15212549Scsvaf r->symvalue.rangev.uppertype, &ub) )
15312549Scsvaf sprintf(*pbuf,"?,");
15412549Scsvaf else
15512549Scsvaf sprintf(*pbuf,"%d,",ub);
15612549Scsvaf }
15712549Scsvaf else {
15812549Scsvaf ub = r->symvalue.rangev.upper;
15912549Scsvaf sprintf(*pbuf,"%d,",ub);
16012549Scsvaf }
16112549Scsvaf *pbuf += strlen(*pbuf);
16212549Scsvaf
16312549Scsvaf }
16412549Scsvaf }
16512549Scsvaf
16612549Scsvaf /*
16712549Scsvaf * Print out the declaration of a FORTRAN variable.
16812549Scsvaf */
16912549Scsvaf
fortran_printdecl(s)17012549Scsvaf public fortran_printdecl(s)
17112549Scsvaf Symbol s;
17212549Scsvaf {
17333317Sdonn Symbol eltype;
17412549Scsvaf
17512549Scsvaf switch (s->class) {
17612549Scsvaf case CONST:
17712549Scsvaf printf("parameter %s = ", symname(s));
17825810Sdonn eval(s->symvalue.constval);
17912549Scsvaf printval(s);
18012549Scsvaf break;
18112549Scsvaf
18212549Scsvaf case REF:
18312549Scsvaf printf(" (dummy argument) ");
18416610Ssam
18514652Slinton case VAR:
18616610Ssam if (s->type->class == ARRAY &&
18716610Ssam (not istypename(s->type->type,"char")) ) {
18816610Ssam char bounds[130], *p1, **p;
18912549Scsvaf p1 = bounds;
19012549Scsvaf p = &p1;
19116610Ssam mksubs(p,s->type);
19212549Scsvaf *p -= 1;
19312549Scsvaf **p = '\0'; /* get rid of trailing ',' */
19416610Ssam printf(" %s %s[%s] ",typename(s), symname(s), bounds);
19512549Scsvaf } else {
19612549Scsvaf printf("%s %s", typename(s), symname(s));
19712549Scsvaf }
19812549Scsvaf break;
19912549Scsvaf
20012549Scsvaf case FUNC:
20112627Scsvaf if (not istypename(s->type, "void")) {
20212549Scsvaf printf(" %s function ", typename(s) );
20312549Scsvaf }
20416610Ssam else printf(" subroutine");
20512549Scsvaf printf(" %s ", symname(s));
20612549Scsvaf fortran_listparams(s);
20712549Scsvaf break;
20812549Scsvaf
20912549Scsvaf case MODULE:
21016610Ssam printf("source file \"%s.c\"", symname(s));
21112549Scsvaf break;
21212549Scsvaf
21312549Scsvaf case PROG:
21412549Scsvaf printf("executable file \"%s\"", symname(s));
21512549Scsvaf break;
21612549Scsvaf
21712549Scsvaf default:
21812549Scsvaf error("class %s in fortran_printdecl", classname(s));
21912549Scsvaf }
22012549Scsvaf putchar('\n');
22112549Scsvaf }
22212549Scsvaf
22312549Scsvaf /*
22412549Scsvaf * List the parameters of a procedure or function.
22512549Scsvaf * No attempt is made to combine like types.
22612549Scsvaf */
22712549Scsvaf
fortran_listparams(s)22812549Scsvaf public fortran_listparams(s)
22912549Scsvaf Symbol s;
23012549Scsvaf {
23112549Scsvaf register Symbol t;
23212549Scsvaf
23312549Scsvaf putchar('(');
23412549Scsvaf for (t = s->chain; t != nil; t = t->chain) {
23512549Scsvaf printf("%s", symname(t));
23612549Scsvaf if (t->chain != nil) {
23712549Scsvaf printf(", ");
23812549Scsvaf }
23912549Scsvaf }
24012549Scsvaf putchar(')');
24112549Scsvaf if (s->chain != nil) {
24212549Scsvaf printf("\n");
24312549Scsvaf for (t = s->chain; t != nil; t = t->chain) {
24412549Scsvaf if (t->class != REF) {
24512549Scsvaf panic("unexpected class %d for parameter", t->class);
24612549Scsvaf }
24712549Scsvaf printdecl(t, 0);
24812549Scsvaf }
24912549Scsvaf } else {
25012549Scsvaf putchar('\n');
25112549Scsvaf }
25212549Scsvaf }
25312549Scsvaf
25412549Scsvaf /*
25512549Scsvaf * Print out the value on the top of the expression stack
25612549Scsvaf * in the format for the type of the given symbol.
25712549Scsvaf */
25812549Scsvaf
fortran_printval(s)25912549Scsvaf public fortran_printval(s)
26012549Scsvaf Symbol s;
26112549Scsvaf {
26212549Scsvaf register Symbol t;
26312549Scsvaf register Address a;
26412549Scsvaf register int i, len;
26518219Slinton double d1, d2;
26612549Scsvaf
26712549Scsvaf switch (s->class) {
26812549Scsvaf case CONST:
26912549Scsvaf case TYPE:
27012549Scsvaf case VAR:
27112549Scsvaf case REF:
27212549Scsvaf case FVAR:
27312549Scsvaf case TAG:
27412549Scsvaf fortran_printval(s->type);
27512549Scsvaf break;
27612549Scsvaf
27712549Scsvaf case ARRAY:
27812549Scsvaf t = rtype(s->type);
27912549Scsvaf if (t->class == RANGE and istypename(t->type, "char")) {
28012549Scsvaf len = size(s);
28112549Scsvaf sp -= len;
28212549Scsvaf printf("\"%.*s\"", len, sp);
28312549Scsvaf } else {
28412549Scsvaf fortran_printarray(s);
28512549Scsvaf }
28612549Scsvaf break;
28712549Scsvaf
28812549Scsvaf case RANGE:
28933317Sdonn if (isspecial(s)) {
29012549Scsvaf switch (s->symvalue.rangev.lower) {
29125810Sdonn case sizeof(short):
29225810Sdonn if (istypename(s->type, "logical*2")) {
29325810Sdonn printlogical(pop(short));
29425810Sdonn }
29525810Sdonn break;
29625810Sdonn
29712549Scsvaf case sizeof(float):
29825810Sdonn if (istypename(s->type, "logical")) {
29925810Sdonn printlogical(pop(long));
30025810Sdonn } else {
30125810Sdonn prtreal(pop(float));
30225810Sdonn }
30312549Scsvaf break;
30412549Scsvaf
30512549Scsvaf case sizeof(double):
30633317Sdonn if (istypename(s->type,"complex")) {
30718219Slinton d2 = pop(float);
30818219Slinton d1 = pop(float);
30918219Slinton printf("(");
31018219Slinton prtreal(d1);
31118219Slinton printf(",");
31218219Slinton prtreal(d2);
31318219Slinton printf(")");
31418219Slinton } else {
31518219Slinton prtreal(pop(double));
31612549Scsvaf }
31712549Scsvaf break;
31812549Scsvaf
31924553Smckusick case 2*sizeof(double):
32024553Smckusick d2 = pop(double);
32124553Smckusick d1 = pop(double);
32224553Smckusick printf("(");
32324553Smckusick prtreal(d1);
32424553Smckusick printf(",");
32524553Smckusick prtreal(d2);
32624553Smckusick printf(")");
32724553Smckusick break;
32833317Sdonn
32912549Scsvaf default:
33025810Sdonn panic("bad size \"%d\" for special",
33124553Smckusick s->symvalue.rangev.lower);
33212549Scsvaf break;
33312549Scsvaf }
33412549Scsvaf } else {
33512549Scsvaf printint(popsmall(s), s);
33612549Scsvaf }
33712549Scsvaf break;
33812549Scsvaf
33912549Scsvaf default:
34012549Scsvaf if (ord(s->class) > ord(TYPEREF)) {
34112549Scsvaf panic("printval: bad class %d", ord(s->class));
34212549Scsvaf }
34312549Scsvaf error("don't know how to print a %s", fortran_classname(s));
34412549Scsvaf /* NOTREACHED */
34512549Scsvaf }
34612549Scsvaf }
34712549Scsvaf
34812549Scsvaf /*
34925810Sdonn * Print out a logical
35025810Sdonn */
35125810Sdonn
printlogical(i)35233317Sdonn private printlogical (i)
35333317Sdonn integer i;
35425810Sdonn {
35525810Sdonn if (i == 0) {
35625810Sdonn printf(".false.");
35725810Sdonn } else {
35825810Sdonn printf(".true.");
35925810Sdonn }
36025810Sdonn }
36125810Sdonn
36225810Sdonn /*
36312549Scsvaf * Print out an int
36412549Scsvaf */
36512549Scsvaf
printint(i,t)36612549Scsvaf private printint(i, t)
36712549Scsvaf Integer i;
36812549Scsvaf register Symbol t;
36912549Scsvaf {
37033317Sdonn if (t->type == t_int or istypename(t->type, "integer") or
37133317Sdonn istypename(t->type,"integer*2")
37233317Sdonn ) {
37312549Scsvaf printf("%ld", i);
37425810Sdonn } else if (istypename(t->type, "addr")) {
37525810Sdonn printf("0x%lx", i);
37612549Scsvaf } else {
37725810Sdonn error("unknown type in fortran printint");
37812549Scsvaf }
37912549Scsvaf }
38012549Scsvaf
38112549Scsvaf /*
38212549Scsvaf * Print out a null-terminated string (pointer to char)
38312549Scsvaf * starting at the given address.
38412549Scsvaf */
38512549Scsvaf
printstring(addr)38612549Scsvaf private printstring(addr)
38712549Scsvaf Address addr;
38812549Scsvaf {
38912549Scsvaf register Address a;
39012549Scsvaf register Integer i, len;
39112549Scsvaf register Boolean endofstring;
39212549Scsvaf union {
39312549Scsvaf char ch[sizeof(Word)];
39412549Scsvaf int word;
39512549Scsvaf } u;
39612549Scsvaf
39712549Scsvaf putchar('"');
39812549Scsvaf a = addr;
39912549Scsvaf endofstring = false;
40012549Scsvaf while (not endofstring) {
40112549Scsvaf dread(&u, a, sizeof(u));
40212549Scsvaf i = 0;
40312549Scsvaf do {
40412549Scsvaf if (u.ch[i] == '\0') {
40512549Scsvaf endofstring = true;
40612549Scsvaf } else {
40712549Scsvaf printchar(u.ch[i]);
40812549Scsvaf }
40912549Scsvaf ++i;
41012549Scsvaf } while (i < sizeof(Word) and not endofstring);
41112549Scsvaf a += sizeof(Word);
41212549Scsvaf }
41312549Scsvaf putchar('"');
41412549Scsvaf }
41512549Scsvaf /*
41612549Scsvaf * Return the FORTRAN name for the particular class of a symbol.
41712549Scsvaf */
41812549Scsvaf
fortran_classname(s)41912549Scsvaf public String fortran_classname(s)
42012549Scsvaf Symbol s;
42112549Scsvaf {
42212549Scsvaf String str;
42312549Scsvaf
42412549Scsvaf switch (s->class) {
42512549Scsvaf case REF:
42612549Scsvaf str = "dummy argument";
42712549Scsvaf break;
42812549Scsvaf
42912549Scsvaf case CONST:
43012549Scsvaf str = "parameter";
43112549Scsvaf break;
43212549Scsvaf
43312549Scsvaf default:
43412549Scsvaf str = classname(s);
43512549Scsvaf }
43612549Scsvaf return str;
43712549Scsvaf }
43812549Scsvaf
43912549Scsvaf /* reverses the indices from the expr_list; should be folded into buildaref
44012549Scsvaf * and done as one recursive routine
44112549Scsvaf */
rev_index(here,n)44212549Scsvaf Node private rev_index(here,n)
44312549Scsvaf register Node here,n;
44412549Scsvaf {
44512549Scsvaf
44612549Scsvaf register Node i;
44712549Scsvaf
44812549Scsvaf if( here == nil or here == n) i=nil;
44912549Scsvaf else if( here->value.arg[1] == n) i = here;
45012549Scsvaf else i=rev_index(here->value.arg[1],n);
45112549Scsvaf return i;
45212549Scsvaf }
45312549Scsvaf
fortran_buildaref(a,slist)45412549Scsvaf public Node fortran_buildaref(a, slist)
45512549Scsvaf Node a, slist;
45612549Scsvaf {
45712549Scsvaf register Symbol as; /* array of array of .. cursor */
45812549Scsvaf register Node en; /* Expr list cursor */
45912549Scsvaf Symbol etype; /* Type of subscript expr */
46012549Scsvaf Node esub, tree; /* Subscript expression ptr and tree to be built*/
46112549Scsvaf
46212549Scsvaf tree=a;
46312549Scsvaf
46412549Scsvaf as = rtype(tree->nodetype); /* node->sym.type->array*/
46512549Scsvaf if ( not (
46612549Scsvaf (tree->nodetype->class == VAR or tree->nodetype->class == REF)
46712549Scsvaf and as->class == ARRAY
46812549Scsvaf ) ) {
46912549Scsvaf beginerrmsg();
47012549Scsvaf prtree(stderr, a);
47112549Scsvaf fprintf(stderr, " is not an array");
47212549Scsvaf /*fprintf(stderr, " a-> %x as %x ", tree->nodetype, as ); OUT*/
47312549Scsvaf enderrmsg();
47412549Scsvaf } else {
47512549Scsvaf for (en = rev_index(slist,nil); en != nil and as->class == ARRAY;
47612549Scsvaf en = rev_index(slist,en), as = as->type) {
47712549Scsvaf esub = en->value.arg[0];
47812549Scsvaf etype = rtype(esub->nodetype);
47912549Scsvaf assert(as->chain->class == RANGE);
48012549Scsvaf if ( not compatible( t_int, etype) ) {
48112549Scsvaf beginerrmsg();
48212549Scsvaf fprintf(stderr, "subscript ");
48312549Scsvaf prtree(stderr, esub);
48412549Scsvaf fprintf(stderr, " is type %s ",symname(etype->type) );
48512549Scsvaf enderrmsg();
48612549Scsvaf }
48712549Scsvaf tree = build(O_INDEX, tree, esub);
48812549Scsvaf tree->nodetype = as->type;
48912549Scsvaf }
49012549Scsvaf if (en != nil or
49112549Scsvaf (as->class == ARRAY && (not istypename(as->type,"char"))) ) {
49212549Scsvaf beginerrmsg();
49312549Scsvaf if (en != nil) {
49412549Scsvaf fprintf(stderr, "too many subscripts for ");
49512549Scsvaf } else {
49612549Scsvaf fprintf(stderr, "not enough subscripts for ");
49712549Scsvaf }
49812549Scsvaf prtree(stderr, tree);
49912549Scsvaf enderrmsg();
50012549Scsvaf }
50112549Scsvaf }
50212549Scsvaf return tree;
50312549Scsvaf }
50412549Scsvaf
50512549Scsvaf /*
50612549Scsvaf * Evaluate a subscript index.
50712549Scsvaf */
50812549Scsvaf
fortran_evalaref(s,base,i)50918219Slinton public fortran_evalaref(s, base, i)
51012549Scsvaf Symbol s;
51118219Slinton Address base;
51212549Scsvaf long i;
51312549Scsvaf {
51418219Slinton Symbol r, t;
51512549Scsvaf long lb, ub;
51612549Scsvaf
51718219Slinton t = rtype(s);
51818219Slinton r = t->chain;
51918219Slinton if (
52018219Slinton r->symvalue.rangev.lowertype == R_ARG or
52118219Slinton r->symvalue.rangev.lowertype == R_TEMP
52218219Slinton ) {
52318219Slinton if (not getbound(
52418219Slinton s, r->symvalue.rangev.lower, r->symvalue.rangev.lowertype, &lb
52518219Slinton )) {
52612549Scsvaf error("dynamic bounds not currently available");
52718219Slinton }
52818219Slinton } else {
52918219Slinton lb = r->symvalue.rangev.lower;
53012549Scsvaf }
53118219Slinton if (
53218219Slinton r->symvalue.rangev.uppertype == R_ARG or
53318219Slinton r->symvalue.rangev.uppertype == R_TEMP
53418219Slinton ) {
53518219Slinton if (not getbound(
53618219Slinton s, r->symvalue.rangev.upper, r->symvalue.rangev.uppertype, &ub
53718219Slinton )) {
53812549Scsvaf error("dynamic bounds not currently available");
53918219Slinton }
54018219Slinton } else {
54118219Slinton ub = r->symvalue.rangev.upper;
54212549Scsvaf }
54312549Scsvaf
54412549Scsvaf if (i < lb or i > ub) {
54512549Scsvaf error("subscript out of range");
54612549Scsvaf }
54718219Slinton push(long, base + (i - lb) * size(t->type));
54812549Scsvaf }
54912549Scsvaf
fortran_printarray(a)55012549Scsvaf private fortran_printarray(a)
55112549Scsvaf Symbol a;
55212549Scsvaf {
55340261Sdonn struct Bounds { int lb, val, ub; } dim[MAXDIM];
55412549Scsvaf
55512549Scsvaf Symbol sc,st,eltype;
55612549Scsvaf char buf[50];
55712549Scsvaf char *subscr;
55812549Scsvaf int i,ndim,elsize;
55912549Scsvaf Stack *savesp;
56012549Scsvaf Boolean done;
56112549Scsvaf
56212549Scsvaf st = a;
56312549Scsvaf
56412549Scsvaf savesp = sp;
56512549Scsvaf sp -= size(a);
56612549Scsvaf ndim=0;
56712549Scsvaf
56812549Scsvaf for(;;){
56912549Scsvaf sc = st->chain;
57012549Scsvaf if(sc->symvalue.rangev.lowertype == R_ARG or
57112549Scsvaf sc->symvalue.rangev.lowertype == R_TEMP) {
57212549Scsvaf if( ! getbound(a,sc->symvalue.rangev.lower,
57312627Scsvaf sc->symvalue.rangev.lowertype, &dim[ndim].lb) )
57412549Scsvaf error(" dynamic bounds not currently available");
57512549Scsvaf }
57612549Scsvaf else dim[ndim].lb = sc->symvalue.rangev.lower;
57712549Scsvaf
57812549Scsvaf if(sc->symvalue.rangev.uppertype == R_ARG or
57912549Scsvaf sc->symvalue.rangev.uppertype == R_TEMP) {
58012549Scsvaf if( ! getbound(a,sc->symvalue.rangev.upper,
58112549Scsvaf sc->symvalue.rangev.uppertype, &dim[ndim].ub) )
58212549Scsvaf error(" dynamic bounds not currently available");
58312549Scsvaf }
58412549Scsvaf else dim[ndim].ub = sc->symvalue.rangev.upper;
58512549Scsvaf
58612549Scsvaf ndim ++;
58712549Scsvaf if (st->type->class == ARRAY) st=st->type;
58812549Scsvaf else break;
58912549Scsvaf }
59012549Scsvaf
59112549Scsvaf if(istypename(st->type,"char")) {
59212549Scsvaf eltype = st;
59312549Scsvaf ndim--;
59412549Scsvaf }
59512549Scsvaf else eltype=st->type;
59612549Scsvaf elsize=size(eltype);
59712549Scsvaf sp += elsize;
59812549Scsvaf /*printf("ndim %d elsize %lx in fortran_printarray\n",ndim,elsize);OUT*/
59912549Scsvaf
60012549Scsvaf ndim--;
60112549Scsvaf for (i=0;i<=ndim;i++){
60212549Scsvaf dim[i].val=dim[i].lb;
60312549Scsvaf /*OUT printf(" %d %d %d \n",i,dim[i].lb,dim[i].ub);
60412549Scsvaf fflush(stdout); OUT*/
60512549Scsvaf }
60612549Scsvaf
60712549Scsvaf
60812549Scsvaf for(;;) {
60912549Scsvaf buf[0]=',';
61012549Scsvaf subscr = buf+1;
61112549Scsvaf
61212549Scsvaf for (i=ndim-1;i>=0;i--) {
61312549Scsvaf
61412549Scsvaf sprintf(subscr,"%d,",dim[i].val);
61512549Scsvaf subscr += strlen(subscr);
61612549Scsvaf }
61712549Scsvaf *--subscr = '\0';
61812549Scsvaf
61912549Scsvaf for(i=dim[ndim].lb;i<=dim[ndim].ub;i++) {
62012549Scsvaf printf("[%d%s]\t",i,buf);
62112549Scsvaf printval(eltype);
62212549Scsvaf printf("\n");
62312549Scsvaf sp += 2*elsize;
62412549Scsvaf }
62512549Scsvaf dim[ndim].val=dim[ndim].ub;
62612549Scsvaf
62712549Scsvaf i=ndim-1;
62812549Scsvaf if (i<0) break;
62912549Scsvaf
63012549Scsvaf done=false;
63112549Scsvaf do {
63212549Scsvaf dim[i].val++;
63312549Scsvaf if(dim[i].val > dim[i].ub) {
63412549Scsvaf dim[i].val = dim[i].lb;
63512549Scsvaf if(--i<0) done=true;
63612549Scsvaf }
63712549Scsvaf else done=true;
63812549Scsvaf }
63912549Scsvaf while (not done);
64012549Scsvaf if (i<0) break;
64112549Scsvaf }
64212549Scsvaf }
64316610Ssam
64416610Ssam /*
64516610Ssam * Initialize typetable at beginning of a module.
64616610Ssam */
64716610Ssam
fortran_modinit(typetable)64816610Ssam public fortran_modinit (typetable)
64916610Ssam Symbol typetable[];
65016610Ssam {
65116610Ssam /* nothing for now */
65216610Ssam }
65316610Ssam
fortran_hasmodules()65416610Ssam public boolean fortran_hasmodules ()
65516610Ssam {
65616610Ssam return false;
65716610Ssam }
65816610Ssam
fortran_passaddr(param,exprtype)65916610Ssam public boolean fortran_passaddr (param, exprtype)
66016610Ssam Symbol param, exprtype;
66116610Ssam {
66216610Ssam return false;
66316610Ssam }
664