Annotation of 43BSDReno/pgrm/dbx/fortran.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

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