Annotation of 43BSD/ucb/dbx/fortran.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.