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