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*25810Sdonn static char sccsid[] = "@(#)fortran.c 5.3 (Berkeley) 01/10/86"; 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 30*25810Sdonn #define isspecial(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)); 183*25810Sdonn eval(s->symvalue.constval); 18412549Scsvaf printval(s); 18512549Scsvaf break; 18612549Scsvaf 18712549Scsvaf case REF: 18812549Scsvaf printf(" (dummy argument) "); 18916610Ssam 19014652Slinton case VAR: 19116610Ssam if (s->type->class == ARRAY && 19216610Ssam (not istypename(s->type->type,"char")) ) { 19316610Ssam char bounds[130], *p1, **p; 19412549Scsvaf p1 = bounds; 19512549Scsvaf p = &p1; 19616610Ssam mksubs(p,s->type); 19712549Scsvaf *p -= 1; 19812549Scsvaf **p = '\0'; /* get rid of trailing ',' */ 19916610Ssam printf(" %s %s[%s] ",typename(s), symname(s), bounds); 20012549Scsvaf } else { 20112549Scsvaf printf("%s %s", typename(s), symname(s)); 20212549Scsvaf } 20312549Scsvaf break; 20412549Scsvaf 20512549Scsvaf case FUNC: 20612627Scsvaf if (not istypename(s->type, "void")) { 20712549Scsvaf printf(" %s function ", typename(s) ); 20812549Scsvaf } 20916610Ssam else printf(" subroutine"); 21012549Scsvaf printf(" %s ", symname(s)); 21112549Scsvaf fortran_listparams(s); 21212549Scsvaf break; 21312549Scsvaf 21412549Scsvaf case MODULE: 21516610Ssam printf("source file \"%s.c\"", symname(s)); 21612549Scsvaf break; 21712549Scsvaf 21812549Scsvaf case PROG: 21912549Scsvaf printf("executable file \"%s\"", symname(s)); 22012549Scsvaf break; 22112549Scsvaf 22212549Scsvaf default: 22312549Scsvaf error("class %s in fortran_printdecl", classname(s)); 22412549Scsvaf } 22512549Scsvaf putchar('\n'); 22612549Scsvaf } 22712549Scsvaf 22812549Scsvaf /* 22912549Scsvaf * List the parameters of a procedure or function. 23012549Scsvaf * No attempt is made to combine like types. 23112549Scsvaf */ 23212549Scsvaf 23312549Scsvaf public fortran_listparams(s) 23412549Scsvaf Symbol s; 23512549Scsvaf { 23612549Scsvaf register Symbol t; 23712549Scsvaf 23812549Scsvaf putchar('('); 23912549Scsvaf for (t = s->chain; t != nil; t = t->chain) { 24012549Scsvaf printf("%s", symname(t)); 24112549Scsvaf if (t->chain != nil) { 24212549Scsvaf printf(", "); 24312549Scsvaf } 24412549Scsvaf } 24512549Scsvaf putchar(')'); 24612549Scsvaf if (s->chain != nil) { 24712549Scsvaf printf("\n"); 24812549Scsvaf for (t = s->chain; t != nil; t = t->chain) { 24912549Scsvaf if (t->class != REF) { 25012549Scsvaf panic("unexpected class %d for parameter", t->class); 25112549Scsvaf } 25212549Scsvaf printdecl(t, 0); 25312549Scsvaf } 25412549Scsvaf } else { 25512549Scsvaf putchar('\n'); 25612549Scsvaf } 25712549Scsvaf } 25812549Scsvaf 25912549Scsvaf /* 26012549Scsvaf * Print out the value on the top of the expression stack 26112549Scsvaf * in the format for the type of the given symbol. 26212549Scsvaf */ 26312549Scsvaf 26412549Scsvaf public fortran_printval(s) 26512549Scsvaf Symbol s; 26612549Scsvaf { 26712549Scsvaf register Symbol t; 26812549Scsvaf register Address a; 26912549Scsvaf register int i, len; 27018219Slinton double d1, d2; 27112549Scsvaf 27212549Scsvaf switch (s->class) { 27312549Scsvaf case CONST: 27412549Scsvaf case TYPE: 27512549Scsvaf case VAR: 27612549Scsvaf case REF: 27712549Scsvaf case FVAR: 27812549Scsvaf case TAG: 27912549Scsvaf fortran_printval(s->type); 28012549Scsvaf break; 28112549Scsvaf 28212549Scsvaf case ARRAY: 28312549Scsvaf t = rtype(s->type); 28412549Scsvaf if (t->class == RANGE and istypename(t->type, "char")) { 28512549Scsvaf len = size(s); 28612549Scsvaf sp -= len; 28712549Scsvaf printf("\"%.*s\"", len, sp); 28812549Scsvaf } else { 28912549Scsvaf fortran_printarray(s); 29012549Scsvaf } 29112549Scsvaf break; 29212549Scsvaf 29312549Scsvaf case RANGE: 294*25810Sdonn if (isspecial(s)) { 29512549Scsvaf switch (s->symvalue.rangev.lower) { 296*25810Sdonn case sizeof(short): 297*25810Sdonn if (istypename(s->type, "logical*2")) { 298*25810Sdonn printlogical(pop(short)); 299*25810Sdonn } 300*25810Sdonn break; 301*25810Sdonn 30212549Scsvaf case sizeof(float): 303*25810Sdonn if (istypename(s->type, "logical")) { 304*25810Sdonn printlogical(pop(long)); 305*25810Sdonn } else { 306*25810Sdonn prtreal(pop(float)); 307*25810Sdonn } 30812549Scsvaf break; 30912549Scsvaf 31012549Scsvaf case sizeof(double): 311*25810Sdonn if (istypename(s->type, "complex")) { 31218219Slinton d2 = pop(float); 31318219Slinton d1 = pop(float); 31418219Slinton printf("("); 31518219Slinton prtreal(d1); 31618219Slinton printf(","); 31718219Slinton prtreal(d2); 31818219Slinton printf(")"); 31918219Slinton } else { 32018219Slinton prtreal(pop(double)); 32112549Scsvaf } 32212549Scsvaf break; 32312549Scsvaf 32424553Smckusick case 2*sizeof(double): 32524553Smckusick d2 = pop(double); 32624553Smckusick d1 = pop(double); 32724553Smckusick printf("("); 32824553Smckusick prtreal(d1); 32924553Smckusick printf(","); 33024553Smckusick prtreal(d2); 33124553Smckusick printf(")"); 33224553Smckusick break; 33324553Smckusick 33412549Scsvaf default: 335*25810Sdonn panic("bad size \"%d\" for special", 33624553Smckusick s->symvalue.rangev.lower); 33712549Scsvaf break; 33812549Scsvaf } 33912549Scsvaf } else { 34012549Scsvaf printint(popsmall(s), s); 34112549Scsvaf } 34212549Scsvaf break; 34312549Scsvaf 34412549Scsvaf default: 34512549Scsvaf if (ord(s->class) > ord(TYPEREF)) { 34612549Scsvaf panic("printval: bad class %d", ord(s->class)); 34712549Scsvaf } 34812549Scsvaf error("don't know how to print a %s", fortran_classname(s)); 34912549Scsvaf /* NOTREACHED */ 35012549Scsvaf } 35112549Scsvaf } 35212549Scsvaf 35312549Scsvaf /* 354*25810Sdonn * Print out a logical 355*25810Sdonn */ 356*25810Sdonn 357*25810Sdonn private printlogical(i) 358*25810Sdonn Integer i; 359*25810Sdonn { 360*25810Sdonn if (i == 0) { 361*25810Sdonn printf(".false."); 362*25810Sdonn } else { 363*25810Sdonn printf(".true."); 364*25810Sdonn } 365*25810Sdonn } 366*25810Sdonn 367*25810Sdonn /* 36812549Scsvaf * Print out an int 36912549Scsvaf */ 37012549Scsvaf 37112549Scsvaf private printint(i, t) 37212549Scsvaf Integer i; 37312549Scsvaf register Symbol t; 37412549Scsvaf { 375*25810Sdonn if ( (t->type == t_int) or istypename(t->type, "integer") or 37612549Scsvaf istypename(t->type,"integer*2") ) { 37712549Scsvaf printf("%ld", i); 378*25810Sdonn } else if (istypename(t->type, "addr")) { 379*25810Sdonn printf("0x%lx", i); 38012549Scsvaf } else { 381*25810Sdonn error("unknown type in fortran printint"); 38212549Scsvaf } 38312549Scsvaf } 38412549Scsvaf 38512549Scsvaf /* 38612549Scsvaf * Print out a null-terminated string (pointer to char) 38712549Scsvaf * starting at the given address. 38812549Scsvaf */ 38912549Scsvaf 39012549Scsvaf private printstring(addr) 39112549Scsvaf Address addr; 39212549Scsvaf { 39312549Scsvaf register Address a; 39412549Scsvaf register Integer i, len; 39512549Scsvaf register Boolean endofstring; 39612549Scsvaf union { 39712549Scsvaf char ch[sizeof(Word)]; 39812549Scsvaf int word; 39912549Scsvaf } u; 40012549Scsvaf 40112549Scsvaf putchar('"'); 40212549Scsvaf a = addr; 40312549Scsvaf endofstring = false; 40412549Scsvaf while (not endofstring) { 40512549Scsvaf dread(&u, a, sizeof(u)); 40612549Scsvaf i = 0; 40712549Scsvaf do { 40812549Scsvaf if (u.ch[i] == '\0') { 40912549Scsvaf endofstring = true; 41012549Scsvaf } else { 41112549Scsvaf printchar(u.ch[i]); 41212549Scsvaf } 41312549Scsvaf ++i; 41412549Scsvaf } while (i < sizeof(Word) and not endofstring); 41512549Scsvaf a += sizeof(Word); 41612549Scsvaf } 41712549Scsvaf putchar('"'); 41812549Scsvaf } 41912549Scsvaf /* 42012549Scsvaf * Return the FORTRAN name for the particular class of a symbol. 42112549Scsvaf */ 42212549Scsvaf 42312549Scsvaf public String fortran_classname(s) 42412549Scsvaf Symbol s; 42512549Scsvaf { 42612549Scsvaf String str; 42712549Scsvaf 42812549Scsvaf switch (s->class) { 42912549Scsvaf case REF: 43012549Scsvaf str = "dummy argument"; 43112549Scsvaf break; 43212549Scsvaf 43312549Scsvaf case CONST: 43412549Scsvaf str = "parameter"; 43512549Scsvaf break; 43612549Scsvaf 43712549Scsvaf default: 43812549Scsvaf str = classname(s); 43912549Scsvaf } 44012549Scsvaf return str; 44112549Scsvaf } 44212549Scsvaf 44312549Scsvaf /* reverses the indices from the expr_list; should be folded into buildaref 44412549Scsvaf * and done as one recursive routine 44512549Scsvaf */ 44612549Scsvaf Node private rev_index(here,n) 44712549Scsvaf register Node here,n; 44812549Scsvaf { 44912549Scsvaf 45012549Scsvaf register Node i; 45112549Scsvaf 45212549Scsvaf if( here == nil or here == n) i=nil; 45312549Scsvaf else if( here->value.arg[1] == n) i = here; 45412549Scsvaf else i=rev_index(here->value.arg[1],n); 45512549Scsvaf return i; 45612549Scsvaf } 45712549Scsvaf 45812549Scsvaf public Node fortran_buildaref(a, slist) 45912549Scsvaf Node a, slist; 46012549Scsvaf { 46112549Scsvaf register Symbol as; /* array of array of .. cursor */ 46212549Scsvaf register Node en; /* Expr list cursor */ 46312549Scsvaf Symbol etype; /* Type of subscript expr */ 46412549Scsvaf Node esub, tree; /* Subscript expression ptr and tree to be built*/ 46512549Scsvaf 46612549Scsvaf tree=a; 46712549Scsvaf 46812549Scsvaf as = rtype(tree->nodetype); /* node->sym.type->array*/ 46912549Scsvaf if ( not ( 47012549Scsvaf (tree->nodetype->class == VAR or tree->nodetype->class == REF) 47112549Scsvaf and as->class == ARRAY 47212549Scsvaf ) ) { 47312549Scsvaf beginerrmsg(); 47412549Scsvaf prtree(stderr, a); 47512549Scsvaf fprintf(stderr, " is not an array"); 47612549Scsvaf /*fprintf(stderr, " a-> %x as %x ", tree->nodetype, as ); OUT*/ 47712549Scsvaf enderrmsg(); 47812549Scsvaf } else { 47912549Scsvaf for (en = rev_index(slist,nil); en != nil and as->class == ARRAY; 48012549Scsvaf en = rev_index(slist,en), as = as->type) { 48112549Scsvaf esub = en->value.arg[0]; 48212549Scsvaf etype = rtype(esub->nodetype); 48312549Scsvaf assert(as->chain->class == RANGE); 48412549Scsvaf if ( not compatible( t_int, etype) ) { 48512549Scsvaf beginerrmsg(); 48612549Scsvaf fprintf(stderr, "subscript "); 48712549Scsvaf prtree(stderr, esub); 48812549Scsvaf fprintf(stderr, " is type %s ",symname(etype->type) ); 48912549Scsvaf enderrmsg(); 49012549Scsvaf } 49112549Scsvaf tree = build(O_INDEX, tree, esub); 49212549Scsvaf tree->nodetype = as->type; 49312549Scsvaf } 49412549Scsvaf if (en != nil or 49512549Scsvaf (as->class == ARRAY && (not istypename(as->type,"char"))) ) { 49612549Scsvaf beginerrmsg(); 49712549Scsvaf if (en != nil) { 49812549Scsvaf fprintf(stderr, "too many subscripts for "); 49912549Scsvaf } else { 50012549Scsvaf fprintf(stderr, "not enough subscripts for "); 50112549Scsvaf } 50212549Scsvaf prtree(stderr, tree); 50312549Scsvaf enderrmsg(); 50412549Scsvaf } 50512549Scsvaf } 50612549Scsvaf return tree; 50712549Scsvaf } 50812549Scsvaf 50912549Scsvaf /* 51012549Scsvaf * Evaluate a subscript index. 51112549Scsvaf */ 51212549Scsvaf 51318219Slinton public fortran_evalaref(s, base, i) 51412549Scsvaf Symbol s; 51518219Slinton Address base; 51612549Scsvaf long i; 51712549Scsvaf { 51818219Slinton Symbol r, t; 51912549Scsvaf long lb, ub; 52012549Scsvaf 52118219Slinton t = rtype(s); 52218219Slinton r = t->chain; 52318219Slinton if ( 52418219Slinton r->symvalue.rangev.lowertype == R_ARG or 52518219Slinton r->symvalue.rangev.lowertype == R_TEMP 52618219Slinton ) { 52718219Slinton if (not getbound( 52818219Slinton s, r->symvalue.rangev.lower, r->symvalue.rangev.lowertype, &lb 52918219Slinton )) { 53012549Scsvaf error("dynamic bounds not currently available"); 53118219Slinton } 53218219Slinton } else { 53318219Slinton lb = r->symvalue.rangev.lower; 53412549Scsvaf } 53518219Slinton if ( 53618219Slinton r->symvalue.rangev.uppertype == R_ARG or 53718219Slinton r->symvalue.rangev.uppertype == R_TEMP 53818219Slinton ) { 53918219Slinton if (not getbound( 54018219Slinton s, r->symvalue.rangev.upper, r->symvalue.rangev.uppertype, &ub 54118219Slinton )) { 54212549Scsvaf error("dynamic bounds not currently available"); 54318219Slinton } 54418219Slinton } else { 54518219Slinton ub = r->symvalue.rangev.upper; 54612549Scsvaf } 54712549Scsvaf 54812549Scsvaf if (i < lb or i > ub) { 54912549Scsvaf error("subscript out of range"); 55012549Scsvaf } 55118219Slinton push(long, base + (i - lb) * size(t->type)); 55212549Scsvaf } 55312549Scsvaf 55412549Scsvaf private fortran_printarray(a) 55512549Scsvaf Symbol a; 55612549Scsvaf { 55712549Scsvaf struct Bounds { int lb, val, ub} dim[MAXDIM]; 55812549Scsvaf 55912549Scsvaf Symbol sc,st,eltype; 56012549Scsvaf char buf[50]; 56112549Scsvaf char *subscr; 56212549Scsvaf int i,ndim,elsize; 56312549Scsvaf Stack *savesp; 56412549Scsvaf Boolean done; 56512549Scsvaf 56612549Scsvaf st = a; 56712549Scsvaf 56812549Scsvaf savesp = sp; 56912549Scsvaf sp -= size(a); 57012549Scsvaf ndim=0; 57112549Scsvaf 57212549Scsvaf for(;;){ 57312549Scsvaf sc = st->chain; 57412549Scsvaf if(sc->symvalue.rangev.lowertype == R_ARG or 57512549Scsvaf sc->symvalue.rangev.lowertype == R_TEMP) { 57612549Scsvaf if( ! getbound(a,sc->symvalue.rangev.lower, 57712627Scsvaf sc->symvalue.rangev.lowertype, &dim[ndim].lb) ) 57812549Scsvaf error(" dynamic bounds not currently available"); 57912549Scsvaf } 58012549Scsvaf else dim[ndim].lb = sc->symvalue.rangev.lower; 58112549Scsvaf 58212549Scsvaf if(sc->symvalue.rangev.uppertype == R_ARG or 58312549Scsvaf sc->symvalue.rangev.uppertype == R_TEMP) { 58412549Scsvaf if( ! getbound(a,sc->symvalue.rangev.upper, 58512549Scsvaf sc->symvalue.rangev.uppertype, &dim[ndim].ub) ) 58612549Scsvaf error(" dynamic bounds not currently available"); 58712549Scsvaf } 58812549Scsvaf else dim[ndim].ub = sc->symvalue.rangev.upper; 58912549Scsvaf 59012549Scsvaf ndim ++; 59112549Scsvaf if (st->type->class == ARRAY) st=st->type; 59212549Scsvaf else break; 59312549Scsvaf } 59412549Scsvaf 59512549Scsvaf if(istypename(st->type,"char")) { 59612549Scsvaf eltype = st; 59712549Scsvaf ndim--; 59812549Scsvaf } 59912549Scsvaf else eltype=st->type; 60012549Scsvaf elsize=size(eltype); 60112549Scsvaf sp += elsize; 60212549Scsvaf /*printf("ndim %d elsize %lx in fortran_printarray\n",ndim,elsize);OUT*/ 60312549Scsvaf 60412549Scsvaf ndim--; 60512549Scsvaf for (i=0;i<=ndim;i++){ 60612549Scsvaf dim[i].val=dim[i].lb; 60712549Scsvaf /*OUT printf(" %d %d %d \n",i,dim[i].lb,dim[i].ub); 60812549Scsvaf fflush(stdout); OUT*/ 60912549Scsvaf } 61012549Scsvaf 61112549Scsvaf 61212549Scsvaf for(;;) { 61312549Scsvaf buf[0]=','; 61412549Scsvaf subscr = buf+1; 61512549Scsvaf 61612549Scsvaf for (i=ndim-1;i>=0;i--) { 61712549Scsvaf 61812549Scsvaf sprintf(subscr,"%d,",dim[i].val); 61912549Scsvaf subscr += strlen(subscr); 62012549Scsvaf } 62112549Scsvaf *--subscr = '\0'; 62212549Scsvaf 62312549Scsvaf for(i=dim[ndim].lb;i<=dim[ndim].ub;i++) { 62412549Scsvaf printf("[%d%s]\t",i,buf); 62512549Scsvaf printval(eltype); 62612549Scsvaf printf("\n"); 62712549Scsvaf sp += 2*elsize; 62812549Scsvaf } 62912549Scsvaf dim[ndim].val=dim[ndim].ub; 63012549Scsvaf 63112549Scsvaf i=ndim-1; 63212549Scsvaf if (i<0) break; 63312549Scsvaf 63412549Scsvaf done=false; 63512549Scsvaf do { 63612549Scsvaf dim[i].val++; 63712549Scsvaf if(dim[i].val > dim[i].ub) { 63812549Scsvaf dim[i].val = dim[i].lb; 63912549Scsvaf if(--i<0) done=true; 64012549Scsvaf } 64112549Scsvaf else done=true; 64212549Scsvaf } 64312549Scsvaf while (not done); 64412549Scsvaf if (i<0) break; 64512549Scsvaf } 64612549Scsvaf } 64716610Ssam 64816610Ssam /* 64916610Ssam * Initialize typetable at beginning of a module. 65016610Ssam */ 65116610Ssam 65216610Ssam public fortran_modinit (typetable) 65316610Ssam Symbol typetable[]; 65416610Ssam { 65516610Ssam /* nothing for now */ 65616610Ssam } 65716610Ssam 65816610Ssam public boolean fortran_hasmodules () 65916610Ssam { 66016610Ssam return false; 66116610Ssam } 66216610Ssam 66316610Ssam public boolean fortran_passaddr (param, exprtype) 66416610Ssam Symbol param, exprtype; 66516610Ssam { 66616610Ssam return false; 66716610Ssam } 668