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