|
|
1.1 ! root 1: /* Copyright (c) 1982 Regents of the University of California */ ! 2: ! 3: static char sccsid[] = "@(#)fortran.c 1.4 8/16/83"; ! 4: ! 5: /* ! 6: * FORTRAN dependent symbol routines. ! 7: */ ! 8: ! 9: #include "defs.h" ! 10: #include "symbols.h" ! 11: #include "printsym.h" ! 12: #include "languages.h" ! 13: #include "fortran.h" ! 14: #include "tree.h" ! 15: #include "eval.h" ! 16: #include "operators.h" ! 17: #include "mappings.h" ! 18: #include "process.h" ! 19: #include "runtime.h" ! 20: #include "machine.h" ! 21: ! 22: #define isfloat(range) ( \ ! 23: range->symvalue.rangev.upper == 0 and range->symvalue.rangev.lower > 0 \ ! 24: ) ! 25: ! 26: #define isrange(t, name) (t->class == RANGE and istypename(t->type, name)) ! 27: ! 28: #define MAXDIM 20 ! 29: /* ! 30: * Initialize FORTRAN language information. ! 31: */ ! 32: ! 33: public fortran_init() ! 34: { ! 35: Language lang; ! 36: ! 37: lang = language_define("fortran", ".f"); ! 38: language_setop(lang, L_PRINTDECL, fortran_printdecl); ! 39: language_setop(lang, L_PRINTVAL, fortran_printval); ! 40: language_setop(lang, L_TYPEMATCH, fortran_typematch); ! 41: language_setop(lang, L_BUILDAREF, fortran_buildaref); ! 42: language_setop(lang, L_EVALAREF, fortran_evalaref); ! 43: } ! 44: ! 45: /* ! 46: * Test if two types are compatible. ! 47: * ! 48: * Integers and reals are not compatible since they cannot always be mixed. ! 49: */ ! 50: ! 51: public Boolean fortran_typematch(type1, type2) ! 52: Symbol type1, type2; ! 53: { ! 54: ! 55: /* only does integer for now; may need to add others ! 56: */ ! 57: ! 58: Boolean b; ! 59: register Symbol t1, t2, tmp; ! 60: ! 61: t1 = rtype(type1); ! 62: t2 = rtype(type2); ! 63: if(t1 == nil or t1->type == nil or t2 == nil or t2->type == nil ) b = false; ! 64: else { b = (Boolean) ( ! 65: (t1 == t2) or ! 66: (t1->type == t_int and (istypename(t2->type, "integer") or ! 67: istypename(t2->type, "integer*2")) ) or ! 68: (t2->type == t_int and (istypename(t1->type, "integer") or ! 69: istypename(t1->type, "integer*2")) ) ! 70: ); ! 71: } ! 72: /*OUT fprintf(stderr," %d compat %s %s \n", b, ! 73: (t1 == nil or t1->type == nil ) ? "nil" : symname(t1->type), ! 74: (t2 == nil or t2->type == nil ) ? "nil" : symname(t2->type) );*/ ! 75: return b; ! 76: } ! 77: ! 78: private String typename(s) ! 79: Symbol s; ! 80: { ! 81: int ub; ! 82: static char buf[20]; ! 83: char *pbuf; ! 84: Symbol st,sc; ! 85: ! 86: if(s->type->class == TYPE) return(symname(s->type)); ! 87: ! 88: for(st = s->type; st->type->class != TYPE; st = st->type); ! 89: ! 90: pbuf=buf; ! 91: ! 92: if(istypename(st->type,"char")) { ! 93: sprintf(pbuf,"character*"); ! 94: pbuf += strlen(pbuf); ! 95: sc = st->chain; ! 96: if(sc->symvalue.rangev.uppertype == R_ARG or ! 97: sc->symvalue.rangev.uppertype == R_TEMP) { ! 98: if( ! getbound(s,sc->symvalue.rangev.upper, ! 99: sc->symvalue.rangev.uppertype, &ub) ) ! 100: sprintf(pbuf,"(*)"); ! 101: else ! 102: sprintf(pbuf,"%d",ub); ! 103: } ! 104: else sprintf(pbuf,"%d",sc->symvalue.rangev.upper); ! 105: } ! 106: else { ! 107: sprintf(pbuf,"%s ",symname(st->type)); ! 108: } ! 109: return(buf); ! 110: } ! 111: ! 112: private Symbol mksubs(pbuf,st) ! 113: Symbol st; ! 114: char **pbuf; ! 115: { ! 116: int lb, ub; ! 117: Symbol r, eltype; ! 118: ! 119: if(st->class != ARRAY or (istypename(st->type, "char")) ) return; ! 120: else { ! 121: mksubs(pbuf,st->type); ! 122: assert( (r = st->chain)->class == RANGE); ! 123: ! 124: if(r->symvalue.rangev.lowertype == R_ARG or ! 125: r->symvalue.rangev.lowertype == R_TEMP) { ! 126: if( ! getbound(st,r->symvalue.rangev.lower, ! 127: r->symvalue.rangev.lowertype, &lb) ) ! 128: sprintf(*pbuf,"?:"); ! 129: else ! 130: sprintf(*pbuf,"%d:",lb); ! 131: } ! 132: else { ! 133: lb = r->symvalue.rangev.lower; ! 134: sprintf(*pbuf,"%d:",lb); ! 135: } ! 136: *pbuf += strlen(*pbuf); ! 137: ! 138: if(r->symvalue.rangev.uppertype == R_ARG or ! 139: r->symvalue.rangev.uppertype == R_TEMP) { ! 140: if( ! getbound(st,r->symvalue.rangev.upper, ! 141: r->symvalue.rangev.uppertype, &ub) ) ! 142: sprintf(*pbuf,"?,"); ! 143: else ! 144: sprintf(*pbuf,"%d,",ub); ! 145: } ! 146: else { ! 147: ub = r->symvalue.rangev.upper; ! 148: sprintf(*pbuf,"%d,",ub); ! 149: } ! 150: *pbuf += strlen(*pbuf); ! 151: ! 152: } ! 153: } ! 154: ! 155: /* ! 156: * Print out the declaration of a FORTRAN variable. ! 157: */ ! 158: ! 159: public fortran_printdecl(s) ! 160: Symbol s; ! 161: { ! 162: ! 163: ! 164: Symbol eltype; ! 165: ! 166: switch (s->class) { ! 167: case CONST: ! 168: printf("parameter %s = ", symname(s)); ! 169: printval(s); ! 170: break; ! 171: ! 172: case REF: ! 173: printf(" (dummy argument) "); ! 174: /* fall through */ ! 175: case VAR: ! 176: if (s->type->class == ARRAY and ! 177: (not istypename(s->type->type, "char")) ! 178: ) { ! 179: char bounds[130], *p1, **p; ! 180: ! 181: p1 = bounds; ! 182: p = &p1; ! 183: mksubs(p, s->type); ! 184: *p -= 1; ! 185: **p = '\0'; /* get rid of trailing ',' */ ! 186: printf(" %s %s[%s] ", typename(s), symname(s), bounds); ! 187: } else { ! 188: printf("%s %s", typename(s), symname(s)); ! 189: } ! 190: break; ! 191: ! 192: case FUNC: ! 193: if (not istypename(s->type, "void")) { ! 194: printf(" %s function ", typename(s) ); ! 195: } else { ! 196: printf(" subroutine"); ! 197: } ! 198: printf(" %s ", symname(s)); ! 199: fortran_listparams(s); ! 200: break; ! 201: ! 202: case MODULE: ! 203: printf("source file \"%s.f\"", symname(s)); ! 204: break; ! 205: ! 206: case PROG: ! 207: printf("executable file \"%s\"", symname(s)); ! 208: break; ! 209: ! 210: default: ! 211: error("class %s in fortran_printdecl", classname(s)); ! 212: } ! 213: putchar('\n'); ! 214: } ! 215: ! 216: /* ! 217: * List the parameters of a procedure or function. ! 218: * No attempt is made to combine like types. ! 219: */ ! 220: ! 221: public fortran_listparams(s) ! 222: Symbol s; ! 223: { ! 224: register Symbol t; ! 225: ! 226: putchar('('); ! 227: for (t = s->chain; t != nil; t = t->chain) { ! 228: printf("%s", symname(t)); ! 229: if (t->chain != nil) { ! 230: printf(", "); ! 231: } ! 232: } ! 233: putchar(')'); ! 234: if (s->chain != nil) { ! 235: printf("\n"); ! 236: for (t = s->chain; t != nil; t = t->chain) { ! 237: if (t->class != REF) { ! 238: panic("unexpected class %d for parameter", t->class); ! 239: } ! 240: printdecl(t, 0); ! 241: } ! 242: } else { ! 243: putchar('\n'); ! 244: } ! 245: } ! 246: ! 247: /* ! 248: * Print out the value on the top of the expression stack ! 249: * in the format for the type of the given symbol. ! 250: */ ! 251: ! 252: public fortran_printval(s) ! 253: Symbol s; ! 254: { ! 255: register Symbol t; ! 256: register Address a; ! 257: register int i, len; ! 258: ! 259: /* printf("fortran_printval with class %s \n",classname(s)); OUT*/ ! 260: switch (s->class) { ! 261: case CONST: ! 262: case TYPE: ! 263: case VAR: ! 264: case REF: ! 265: case FVAR: ! 266: case TAG: ! 267: fortran_printval(s->type); ! 268: break; ! 269: ! 270: case ARRAY: ! 271: t = rtype(s->type); ! 272: if (t->class == RANGE and istypename(t->type, "char")) { ! 273: len = size(s); ! 274: sp -= len; ! 275: printf("\"%.*s\"", len, sp); ! 276: } else { ! 277: fortran_printarray(s); ! 278: } ! 279: break; ! 280: ! 281: case RANGE: ! 282: if (isfloat(s)) { ! 283: switch (s->symvalue.rangev.lower) { ! 284: case sizeof(float): ! 285: prtreal(pop(float)); ! 286: break; ! 287: ! 288: case sizeof(double): ! 289: if(istypename(s->type,"complex")) { ! 290: printf("("); ! 291: prtreal(pop(float)); ! 292: printf(","); ! 293: prtreal(pop(float)); ! 294: printf(")"); ! 295: } ! 296: else prtreal(pop(double)); ! 297: break; ! 298: ! 299: default: ! 300: panic("bad size \"%d\" for real", ! 301: t->symvalue.rangev.lower); ! 302: break; ! 303: } ! 304: } else { ! 305: printint(popsmall(s), s); ! 306: } ! 307: break; ! 308: ! 309: default: ! 310: if (ord(s->class) > ord(TYPEREF)) { ! 311: panic("printval: bad class %d", ord(s->class)); ! 312: } ! 313: error("don't know how to print a %s", fortran_classname(s)); ! 314: /* NOTREACHED */ ! 315: } ! 316: } ! 317: ! 318: /* ! 319: * Print out an int ! 320: */ ! 321: ! 322: private printint(i, t) ! 323: Integer i; ! 324: register Symbol t; ! 325: { ! 326: if (istypename(t->type, "logical")) { ! 327: printf(((Boolean) i) == true ? "true" : "false"); ! 328: } ! 329: else if ( (t->type == t_int) or istypename(t->type, "integer") or ! 330: istypename(t->type,"integer*2") ) { ! 331: printf("%ld", i); ! 332: } else { ! 333: error("unkown type in fortran printint"); ! 334: } ! 335: } ! 336: ! 337: /* ! 338: * Print out a null-terminated string (pointer to char) ! 339: * starting at the given address. ! 340: */ ! 341: ! 342: private printstring(addr) ! 343: Address addr; ! 344: { ! 345: register Address a; ! 346: register Integer i, len; ! 347: register Boolean endofstring; ! 348: union { ! 349: char ch[sizeof(Word)]; ! 350: int word; ! 351: } u; ! 352: ! 353: putchar('"'); ! 354: a = addr; ! 355: endofstring = false; ! 356: while (not endofstring) { ! 357: dread(&u, a, sizeof(u)); ! 358: i = 0; ! 359: do { ! 360: if (u.ch[i] == '\0') { ! 361: endofstring = true; ! 362: } else { ! 363: printchar(u.ch[i]); ! 364: } ! 365: ++i; ! 366: } while (i < sizeof(Word) and not endofstring); ! 367: a += sizeof(Word); ! 368: } ! 369: putchar('"'); ! 370: } ! 371: /* ! 372: * Return the FORTRAN name for the particular class of a symbol. ! 373: */ ! 374: ! 375: public String fortran_classname(s) ! 376: Symbol s; ! 377: { ! 378: String str; ! 379: ! 380: switch (s->class) { ! 381: case REF: ! 382: str = "dummy argument"; ! 383: break; ! 384: ! 385: case CONST: ! 386: str = "parameter"; ! 387: break; ! 388: ! 389: default: ! 390: str = classname(s); ! 391: } ! 392: return str; ! 393: } ! 394: ! 395: /* reverses the indices from the expr_list; should be folded into buildaref ! 396: * and done as one recursive routine ! 397: */ ! 398: Node private rev_index(here,n) ! 399: register Node here,n; ! 400: { ! 401: ! 402: register Node i; ! 403: ! 404: if( here == nil or here == n) i=nil; ! 405: else if( here->value.arg[1] == n) i = here; ! 406: else i=rev_index(here->value.arg[1],n); ! 407: return i; ! 408: } ! 409: ! 410: public Node fortran_buildaref(a, slist) ! 411: Node a, slist; ! 412: { ! 413: register Symbol as; /* array of array of .. cursor */ ! 414: register Node en; /* Expr list cursor */ ! 415: Symbol etype; /* Type of subscript expr */ ! 416: Node esub, tree; /* Subscript expression ptr and tree to be built*/ ! 417: ! 418: tree=a; ! 419: ! 420: as = rtype(tree->nodetype); /* node->sym.type->array*/ ! 421: if ( not ( ! 422: (tree->nodetype->class == VAR or tree->nodetype->class == REF) ! 423: and as->class == ARRAY ! 424: ) ) { ! 425: beginerrmsg(); ! 426: prtree(stderr, a); ! 427: fprintf(stderr, " is not an array"); ! 428: /*fprintf(stderr, " a-> %x as %x ", tree->nodetype, as ); OUT*/ ! 429: enderrmsg(); ! 430: } else { ! 431: for (en = rev_index(slist,nil); en != nil and as->class == ARRAY; ! 432: en = rev_index(slist,en), as = as->type) { ! 433: esub = en->value.arg[0]; ! 434: etype = rtype(esub->nodetype); ! 435: assert(as->chain->class == RANGE); ! 436: if ( not compatible( t_int, etype) ) { ! 437: beginerrmsg(); ! 438: fprintf(stderr, "subscript "); ! 439: prtree(stderr, esub); ! 440: fprintf(stderr, " is type %s ",symname(etype->type) ); ! 441: enderrmsg(); ! 442: } ! 443: tree = build(O_INDEX, tree, esub); ! 444: tree->nodetype = as->type; ! 445: } ! 446: if (en != nil or ! 447: (as->class == ARRAY && (not istypename(as->type,"char"))) ) { ! 448: beginerrmsg(); ! 449: if (en != nil) { ! 450: fprintf(stderr, "too many subscripts for "); ! 451: } else { ! 452: fprintf(stderr, "not enough subscripts for "); ! 453: } ! 454: prtree(stderr, tree); ! 455: enderrmsg(); ! 456: } ! 457: } ! 458: return tree; ! 459: } ! 460: ! 461: /* ! 462: * Evaluate a subscript index. ! 463: */ ! 464: ! 465: public int fortran_evalaref(s, i) ! 466: Symbol s; ! 467: long i; ! 468: { ! 469: Symbol r; ! 470: long lb, ub; ! 471: ! 472: r = rtype(s)->chain; ! 473: if(r->symvalue.rangev.lowertype == R_ARG or ! 474: r->symvalue.rangev.lowertype == R_TEMP ) { ! 475: if(! getbound(s,r->symvalue.rangev.lower, ! 476: r->symvalue.rangev.lowertype,&lb)) ! 477: error("dynamic bounds not currently available"); ! 478: } ! 479: else lb = r->symvalue.rangev.lower; ! 480: ! 481: if(r->symvalue.rangev.uppertype == R_ARG or ! 482: r->symvalue.rangev.uppertype == R_TEMP ) { ! 483: if(! getbound(s,r->symvalue.rangev.upper, ! 484: r->symvalue.rangev.uppertype,&ub)) ! 485: error("dynamic bounds not currently available"); ! 486: } ! 487: else ub = r->symvalue.rangev.upper; ! 488: ! 489: if (i < lb or i > ub) { ! 490: error("subscript out of range"); ! 491: } ! 492: return (i - lb); ! 493: } ! 494: ! 495: private fortran_printarray(a) ! 496: Symbol a; ! 497: { ! 498: struct Bounds { int lb, val, ub} dim[MAXDIM]; ! 499: ! 500: Symbol sc,st,eltype; ! 501: char buf[50]; ! 502: char *subscr; ! 503: int i,ndim,elsize; ! 504: Stack *savesp; ! 505: Boolean done; ! 506: ! 507: st = a; ! 508: ! 509: savesp = sp; ! 510: sp -= size(a); ! 511: ndim=0; ! 512: ! 513: for(;;){ ! 514: sc = st->chain; ! 515: if(sc->symvalue.rangev.lowertype == R_ARG or ! 516: sc->symvalue.rangev.lowertype == R_TEMP) { ! 517: if( ! getbound(a,sc->symvalue.rangev.lower, ! 518: sc->symvalue.rangev.lowertype, &dim[ndim].lb) ) ! 519: error(" dynamic bounds not currently available"); ! 520: } ! 521: else dim[ndim].lb = sc->symvalue.rangev.lower; ! 522: ! 523: if(sc->symvalue.rangev.uppertype == R_ARG or ! 524: sc->symvalue.rangev.uppertype == R_TEMP) { ! 525: if( ! getbound(a,sc->symvalue.rangev.upper, ! 526: sc->symvalue.rangev.uppertype, &dim[ndim].ub) ) ! 527: error(" dynamic bounds not currently available"); ! 528: } ! 529: else dim[ndim].ub = sc->symvalue.rangev.upper; ! 530: ! 531: ndim ++; ! 532: if (st->type->class == ARRAY) st=st->type; ! 533: else break; ! 534: } ! 535: ! 536: if(istypename(st->type,"char")) { ! 537: eltype = st; ! 538: ndim--; ! 539: } ! 540: else eltype=st->type; ! 541: elsize=size(eltype); ! 542: sp += elsize; ! 543: /*printf("ndim %d elsize %lx in fortran_printarray\n",ndim,elsize);OUT*/ ! 544: ! 545: ndim--; ! 546: for (i=0;i<=ndim;i++){ ! 547: dim[i].val=dim[i].lb; ! 548: /*OUT printf(" %d %d %d \n",i,dim[i].lb,dim[i].ub); ! 549: fflush(stdout); OUT*/ ! 550: } ! 551: ! 552: ! 553: for(;;) { ! 554: buf[0]=','; ! 555: subscr = buf+1; ! 556: ! 557: for (i=ndim-1;i>=0;i--) { ! 558: ! 559: sprintf(subscr,"%d,",dim[i].val); ! 560: subscr += strlen(subscr); ! 561: } ! 562: *--subscr = '\0'; ! 563: ! 564: for(i=dim[ndim].lb;i<=dim[ndim].ub;i++) { ! 565: printf("[%d%s]\t",i,buf); ! 566: printval(eltype); ! 567: printf("\n"); ! 568: sp += 2*elsize; ! 569: } ! 570: dim[ndim].val=dim[ndim].ub; ! 571: ! 572: i=ndim-1; ! 573: if (i<0) break; ! 574: ! 575: done=false; ! 576: do { ! 577: dim[i].val++; ! 578: if(dim[i].val > dim[i].ub) { ! 579: dim[i].val = dim[i].lb; ! 580: if(--i<0) done=true; ! 581: } ! 582: else done=true; ! 583: } ! 584: while (not done); ! 585: if (i<0) break; ! 586: } ! 587: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.