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