BSD 4_3_Tahoe release
[unix-history] / usr / src / lib / old_compiler / dbx / fortran.c
CommitLineData
2a24676e
DF
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 */
cedf04df 6
2a24676e 7#ifndef lint
ca67e7b4 8static char sccsid[] = "@(#)fortran.c 5.4 (Berkeley) 1/12/88";
2a24676e 9#endif not lint
0022c355 10
34d5a416 11static char rcsid[] = "$Header: fortran.c,v 1.3 87/03/25 20:00:03 donn Exp $";
cedf04df 12
3e90ba7b
AF
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
adc5c95e 30#define isspecial(range) ( \
3e90ba7b
AF
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
2fd0f574
SL
37
38private Language fort;
39
3e90ba7b
AF
40/*
41 * Initialize FORTRAN language information.
42 */
43
44public fortran_init()
45{
2fd0f574
SL
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);
3e90ba7b
AF
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
63public Boolean fortran_typematch(type1, type2)
64Symbol 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
90private String typename(s)
91Symbol s;
92{
93int ub;
94static char buf[20];
95char *pbuf;
96Symbol 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
124private Symbol mksubs(pbuf,st)
125Symbol st;
126char **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
171public fortran_printdecl(s)
172Symbol s;
173{
34d5a416 174 Symbol eltype;
3e90ba7b
AF
175
176 switch (s->class) {
3e90ba7b 177 case CONST:
3e90ba7b 178 printf("parameter %s = ", symname(s));
adc5c95e 179 eval(s->symvalue.constval);
3e90ba7b
AF
180 printval(s);
181 break;
182
183 case REF:
184 printf(" (dummy argument) ");
795c7e77 185
2fd0f574
SL
186 case VAR:
187 if (s->type->class == ARRAY &&
188 (not istypename(s->type->type,"char")) ) {
189 char bounds[130], *p1, **p;
3e90ba7b
AF
190 p1 = bounds;
191 p = &p1;
2fd0f574 192 mksubs(p,s->type);
3e90ba7b
AF
193 *p -= 1;
194 **p = '\0'; /* get rid of trailing ',' */
2fd0f574 195 printf(" %s %s[%s] ",typename(s), symname(s), bounds);
3e90ba7b
AF
196 } else {
197 printf("%s %s", typename(s), symname(s));
198 }
199 break;
200
201 case FUNC:
d27b8698 202 if (not istypename(s->type, "void")) {
3e90ba7b
AF
203 printf(" %s function ", typename(s) );
204 }
2fd0f574 205 else printf(" subroutine");
3e90ba7b
AF
206 printf(" %s ", symname(s));
207 fortran_listparams(s);
208 break;
209
210 case MODULE:
2fd0f574 211 printf("source file \"%s.c\"", symname(s));
3e90ba7b
AF
212 break;
213
214 case PROG:
215 printf("executable file \"%s\"", symname(s));
216 break;
217
218 default:
219 error("class %s in fortran_printdecl", classname(s));
220 }
221 putchar('\n');
222}
223
224/*
225 * List the parameters of a procedure or function.
226 * No attempt is made to combine like types.
227 */
228
229public fortran_listparams(s)
230Symbol s;
231{
232 register Symbol t;
233
234 putchar('(');
235 for (t = s->chain; t != nil; t = t->chain) {
236 printf("%s", symname(t));
237 if (t->chain != nil) {
238 printf(", ");
239 }
240 }
241 putchar(')');
242 if (s->chain != nil) {
243 printf("\n");
244 for (t = s->chain; t != nil; t = t->chain) {
245 if (t->class != REF) {
246 panic("unexpected class %d for parameter", t->class);
247 }
248 printdecl(t, 0);
249 }
250 } else {
251 putchar('\n');
252 }
253}
254
255/*
256 * Print out the value on the top of the expression stack
257 * in the format for the type of the given symbol.
258 */
259
260public fortran_printval(s)
261Symbol s;
262{
263 register Symbol t;
264 register Address a;
265 register int i, len;
0022c355 266 double d1, d2;
3e90ba7b 267
3e90ba7b
AF
268 switch (s->class) {
269 case CONST:
270 case TYPE:
271 case VAR:
272 case REF:
273 case FVAR:
274 case TAG:
275 fortran_printval(s->type);
276 break;
277
278 case ARRAY:
279 t = rtype(s->type);
280 if (t->class == RANGE and istypename(t->type, "char")) {
281 len = size(s);
282 sp -= len;
283 printf("\"%.*s\"", len, sp);
284 } else {
285 fortran_printarray(s);
286 }
287 break;
288
289 case RANGE:
34d5a416 290 if (isspecial(s)) {
3e90ba7b 291 switch (s->symvalue.rangev.lower) {
adc5c95e
DS
292 case sizeof(short):
293 if (istypename(s->type, "logical*2")) {
294 printlogical(pop(short));
295 }
296 break;
297
3e90ba7b 298 case sizeof(float):
adc5c95e
DS
299 if (istypename(s->type, "logical")) {
300 printlogical(pop(long));
301 } else {
302 prtreal(pop(float));
303 }
3e90ba7b
AF
304 break;
305
306 case sizeof(double):
34d5a416 307 if (istypename(s->type,"complex")) {
0022c355
ML
308 d2 = pop(float);
309 d1 = pop(float);
310 printf("(");
311 prtreal(d1);
312 printf(",");
313 prtreal(d2);
314 printf(")");
315 } else {
316 prtreal(pop(double));
3e90ba7b 317 }
3e90ba7b
AF
318 break;
319
c3111255
KM
320 case 2*sizeof(double):
321 d2 = pop(double);
322 d1 = pop(double);
323 printf("(");
324 prtreal(d1);
325 printf(",");
326 prtreal(d2);
327 printf(")");
328 break;
34d5a416 329
3e90ba7b 330 default:
adc5c95e 331 panic("bad size \"%d\" for special",
c3111255 332 s->symvalue.rangev.lower);
3e90ba7b
AF
333 break;
334 }
335 } else {
336 printint(popsmall(s), s);
337 }
338 break;
339
340 default:
341 if (ord(s->class) > ord(TYPEREF)) {
342 panic("printval: bad class %d", ord(s->class));
343 }
344 error("don't know how to print a %s", fortran_classname(s));
345 /* NOTREACHED */
346 }
347}
348
adc5c95e
DS
349/*
350 * Print out a logical
351 */
352
34d5a416
DS
353private printlogical (i)
354integer i;
adc5c95e
DS
355{
356 if (i == 0) {
357 printf(".false.");
358 } else {
359 printf(".true.");
360 }
361}
362
3e90ba7b
AF
363/*
364 * Print out an int
365 */
366
367private printint(i, t)
368Integer i;
369register Symbol t;
370{
34d5a416
DS
371 if (t->type == t_int or istypename(t->type, "integer") or
372 istypename(t->type,"integer*2")
373 ) {
3e90ba7b 374 printf("%ld", i);
adc5c95e
DS
375 } else if (istypename(t->type, "addr")) {
376 printf("0x%lx", i);
3e90ba7b 377 } else {
adc5c95e 378 error("unknown type in fortran printint");
3e90ba7b
AF
379 }
380}
381
382/*
383 * Print out a null-terminated string (pointer to char)
384 * starting at the given address.
385 */
386
387private printstring(addr)
388Address addr;
389{
390 register Address a;
391 register Integer i, len;
392 register Boolean endofstring;
393 union {
394 char ch[sizeof(Word)];
395 int word;
396 } u;
397
398 putchar('"');
399 a = addr;
400 endofstring = false;
401 while (not endofstring) {
402 dread(&u, a, sizeof(u));
403 i = 0;
404 do {
405 if (u.ch[i] == '\0') {
406 endofstring = true;
407 } else {
408 printchar(u.ch[i]);
409 }
410 ++i;
411 } while (i < sizeof(Word) and not endofstring);
412 a += sizeof(Word);
413 }
414 putchar('"');
415}
416/*
417 * Return the FORTRAN name for the particular class of a symbol.
418 */
419
420public String fortran_classname(s)
421Symbol s;
422{
423 String str;
424
425 switch (s->class) {
426 case REF:
427 str = "dummy argument";
428 break;
429
430 case CONST:
431 str = "parameter";
432 break;
433
434 default:
435 str = classname(s);
436 }
437 return str;
438}
439
440/* reverses the indices from the expr_list; should be folded into buildaref
441 * and done as one recursive routine
442 */
443Node private rev_index(here,n)
444register Node here,n;
445{
446
447 register Node i;
448
449 if( here == nil or here == n) i=nil;
450 else if( here->value.arg[1] == n) i = here;
451 else i=rev_index(here->value.arg[1],n);
452 return i;
453}
454
455public Node fortran_buildaref(a, slist)
456Node a, slist;
457{
458 register Symbol as; /* array of array of .. cursor */
459 register Node en; /* Expr list cursor */
460 Symbol etype; /* Type of subscript expr */
461 Node esub, tree; /* Subscript expression ptr and tree to be built*/
462
463 tree=a;
464
465 as = rtype(tree->nodetype); /* node->sym.type->array*/
466 if ( not (
467 (tree->nodetype->class == VAR or tree->nodetype->class == REF)
468 and as->class == ARRAY
469 ) ) {
470 beginerrmsg();
471 prtree(stderr, a);
472 fprintf(stderr, " is not an array");
473 /*fprintf(stderr, " a-> %x as %x ", tree->nodetype, as ); OUT*/
474 enderrmsg();
475 } else {
476 for (en = rev_index(slist,nil); en != nil and as->class == ARRAY;
477 en = rev_index(slist,en), as = as->type) {
478 esub = en->value.arg[0];
479 etype = rtype(esub->nodetype);
480 assert(as->chain->class == RANGE);
481 if ( not compatible( t_int, etype) ) {
482 beginerrmsg();
483 fprintf(stderr, "subscript ");
484 prtree(stderr, esub);
485 fprintf(stderr, " is type %s ",symname(etype->type) );
486 enderrmsg();
487 }
488 tree = build(O_INDEX, tree, esub);
489 tree->nodetype = as->type;
490 }
491 if (en != nil or
492 (as->class == ARRAY && (not istypename(as->type,"char"))) ) {
493 beginerrmsg();
494 if (en != nil) {
495 fprintf(stderr, "too many subscripts for ");
496 } else {
497 fprintf(stderr, "not enough subscripts for ");
498 }
499 prtree(stderr, tree);
500 enderrmsg();
501 }
502 }
503 return tree;
504}
505
506/*
507 * Evaluate a subscript index.
508 */
509
0022c355 510public fortran_evalaref(s, base, i)
3e90ba7b 511Symbol s;
0022c355 512Address base;
3e90ba7b
AF
513long i;
514{
0022c355 515 Symbol r, t;
3e90ba7b
AF
516 long lb, ub;
517
0022c355
ML
518 t = rtype(s);
519 r = t->chain;
520 if (
521 r->symvalue.rangev.lowertype == R_ARG or
522 r->symvalue.rangev.lowertype == R_TEMP
523 ) {
524 if (not getbound(
525 s, r->symvalue.rangev.lower, r->symvalue.rangev.lowertype, &lb
526 )) {
3e90ba7b 527 error("dynamic bounds not currently available");
0022c355
ML
528 }
529 } else {
530 lb = r->symvalue.rangev.lower;
3e90ba7b 531 }
0022c355
ML
532 if (
533 r->symvalue.rangev.uppertype == R_ARG or
534 r->symvalue.rangev.uppertype == R_TEMP
535 ) {
536 if (not getbound(
537 s, r->symvalue.rangev.upper, r->symvalue.rangev.uppertype, &ub
538 )) {
3e90ba7b 539 error("dynamic bounds not currently available");
0022c355
ML
540 }
541 } else {
542 ub = r->symvalue.rangev.upper;
3e90ba7b 543 }
3e90ba7b
AF
544
545 if (i < lb or i > ub) {
546 error("subscript out of range");
547 }
0022c355 548 push(long, base + (i - lb) * size(t->type));
3e90ba7b
AF
549}
550
551private fortran_printarray(a)
552Symbol a;
553{
554struct Bounds { int lb, val, ub} dim[MAXDIM];
555
556Symbol sc,st,eltype;
557char buf[50];
558char *subscr;
559int i,ndim,elsize;
560Stack *savesp;
561Boolean done;
562
563st = a;
564
565savesp = sp;
566sp -= size(a);
567ndim=0;
568
569for(;;){
570 sc = st->chain;
571 if(sc->symvalue.rangev.lowertype == R_ARG or
572 sc->symvalue.rangev.lowertype == R_TEMP) {
573 if( ! getbound(a,sc->symvalue.rangev.lower,
d27b8698 574 sc->symvalue.rangev.lowertype, &dim[ndim].lb) )
3e90ba7b
AF
575 error(" dynamic bounds not currently available");
576 }
577 else dim[ndim].lb = sc->symvalue.rangev.lower;
578
579 if(sc->symvalue.rangev.uppertype == R_ARG or
580 sc->symvalue.rangev.uppertype == R_TEMP) {
581 if( ! getbound(a,sc->symvalue.rangev.upper,
582 sc->symvalue.rangev.uppertype, &dim[ndim].ub) )
583 error(" dynamic bounds not currently available");
584 }
585 else dim[ndim].ub = sc->symvalue.rangev.upper;
586
587 ndim ++;
588 if (st->type->class == ARRAY) st=st->type;
589 else break;
590 }
591
592if(istypename(st->type,"char")) {
593 eltype = st;
594 ndim--;
595 }
596else eltype=st->type;
597elsize=size(eltype);
598sp += elsize;
599 /*printf("ndim %d elsize %lx in fortran_printarray\n",ndim,elsize);OUT*/
600
601ndim--;
602for (i=0;i<=ndim;i++){
603 dim[i].val=dim[i].lb;
604 /*OUT printf(" %d %d %d \n",i,dim[i].lb,dim[i].ub);
605 fflush(stdout); OUT*/
606}
607
608
609for(;;) {
610 buf[0]=',';
611 subscr = buf+1;
612
613 for (i=ndim-1;i>=0;i--) {
614
615 sprintf(subscr,"%d,",dim[i].val);
616 subscr += strlen(subscr);
617 }
618 *--subscr = '\0';
619
620 for(i=dim[ndim].lb;i<=dim[ndim].ub;i++) {
621 printf("[%d%s]\t",i,buf);
622 printval(eltype);
623 printf("\n");
624 sp += 2*elsize;
625 }
626 dim[ndim].val=dim[ndim].ub;
627
628 i=ndim-1;
629 if (i<0) break;
630
631 done=false;
632 do {
633 dim[i].val++;
634 if(dim[i].val > dim[i].ub) {
635 dim[i].val = dim[i].lb;
636 if(--i<0) done=true;
637 }
638 else done=true;
639 }
640 while (not done);
641 if (i<0) break;
642 }
643}
2fd0f574
SL
644
645/*
646 * Initialize typetable at beginning of a module.
647 */
648
649public fortran_modinit (typetable)
650Symbol typetable[];
651{
652 /* nothing for now */
653}
654
655public boolean fortran_hasmodules ()
656{
657 return false;
658}
659
660public boolean fortran_passaddr (param, exprtype)
661Symbol param, exprtype;
662{
663 return false;
664}