Bell 32V development
[unix-history] / usr / src / cmd / f77 / misc.c
CommitLineData
0d57d6f5
TL
1#include "defs"
2
3
4
5cpn(n, a, b)
6register int n;
7register char *a, *b;
8{
9while(--n >= 0)
10 *b++ = *a++;
11}
12
13
14
15eqn(n, a, b)
16register int n;
17register char *a, *b;
18{
19while(--n >= 0)
20 if(*a++ != *b++)
21 return(NO);
22return(YES);
23}
24
25
26
27
28
29
30
31cmpstr(a, b, la, lb) /* compare two strings */
32register char *a, *b;
33ftnint la, lb;
34{
35register char *aend, *bend;
36aend = a + la;
37bend = b + lb;
38
39
40if(la <= lb)
41 {
42 while(a < aend)
43 if(*a != *b)
44 return( *a - *b );
45 else
46 { ++a; ++b; }
47
48 while(b < bend)
49 if(*b != ' ')
50 return(' ' - *b);
51 else
52 ++b;
53 }
54
55else
56 {
57 while(b < bend)
58 if(*a != *b)
59 return( *a - *b );
60 else
61 { ++a; ++b; }
62 while(a < aend)
63 if(*a != ' ')
64 return(*a - ' ');
65 else
66 ++a;
67 }
68return(0);
69}
70
71
72
73
74
75chainp hookup(x,y)
76register chainp x, y;
77{
78register chainp p;
79
80if(x == NULL)
81 return(y);
82
83for(p = x ; p->nextp ; p = p->nextp)
84 ;
85p->nextp = y;
86return(x);
87}
88
89
90
91struct listblock *mklist(p)
92chainp p;
93{
94register struct listblock *q;
95
96q = ALLOC(listblock);
97q->tag = TLIST;
98q->listp = p;
99return(q);
100}
101
102
103chainp mkchain(p,q)
104register int p, q;
105{
106register chainp r;
107
108if(chains)
109 {
110 r = chains;
111 chains = chains->nextp;
112 }
113else
114 r = ALLOC(chain);
115
116r->datap = p;
117r->nextp = q;
118return(r);
119}
120
121
122
123char * varstr(n, s)
124register int n;
125register char *s;
126{
127register int i;
128static char name[XL+1];
129
130for(i=0; i<n && *s!=' ' && *s!='\0' ; ++i)
131 name[i] = *s++;
132
133name[i] = '\0';
134
135return( name );
136}
137
138
139
140
141char * varunder(n, s)
142register int n;
143register char *s;
144{
145register int i;
146static char name[XL+1];
147
148for(i=0; i<n && *s!=' ' && *s!='\0' ; ++i)
149 name[i] = *s++;
150
151#if TARGET != GCOS
152name[i++] = '_';
153#endif
154
155name[i] = '\0';
156
157return( name );
158}
159
160
161
162
163
164char * nounder(n, s)
165register int n;
166register char *s;
167{
168register int i;
169static char name[XL+1];
170
171for(i=0; i<n && *s!=' ' && *s!='\0' ; ++s)
172 if(*s != '_')
173 name[i++] = *s;
174
175name[i] = '\0';
176
177return( name );
178}
179
180
181
182char *copyn(n, s)
183register int n;
184register char *s;
185{
186register char *p, *q;
187
188p = q = ckalloc(n);
189while(--n >= 0)
190 *q++ = *s++;
191return(p);
192}
193
194
195
196char *copys(s)
197char *s;
198{
199return( copyn( strlen(s)+1 , s) );
200}
201
202
203
204ftnint convci(n, s)
205register int n;
206register char *s;
207{
208ftnint sum;
209sum = 0;
210while(n-- > 0)
211 sum = 10*sum + (*s++ - '0');
212return(sum);
213}
214
215char *convic(n)
216ftnint n;
217{
218static char s[20];
219register char *t;
220
221s[19] = '\0';
222t = s+19;
223
224do {
225 *--t = '0' + n%10;
226 n /= 10;
227 } while(n > 0);
228
229return(t);
230}
231
232
233
234double convcd(n, s)
235int n;
236register char *s;
237{
238double atof();
239char v[100];
240register char *t;
241if(n > 90)
242 {
243 err("too many digits in floating constant");
244 n = 90;
245 }
246for(t = v ; n-- > 0 ; s++)
247 *t++ = (*s=='d' ? 'e' : *s);
248*t = '\0';
249return( atof(v) );
250}
251
252
253
254struct nameblock *mkname(l, s)
255int l;
256register char *s;
257{
258struct hashentry *hp;
259int hash;
260register struct nameblock *q;
261register int i;
262char n[VL];
263
264hash = 0;
265for(i = 0 ; i<l && *s!='\0' ; ++i)
266 {
267 hash += *s;
268 n[i] = *s++;
269 }
270hash %= MAXHASH;
271while( i < VL )
272 n[i++] = ' ';
273
274hp = hashtab + hash;
275while(q = hp->varp)
276 if( hash==hp->hashval && eqn(VL,n,q->varname) )
277 return(q);
278 else if(++hp >= lasthash)
279 hp = hashtab;
280
281if(++nintnames >= MAXHASH-1)
282 fatal("hash table full");
283hp->varp = q = ALLOC(nameblock);
284hp->hashval = hash;
285q->tag = TNAME;
286cpn(VL, n, q->varname);
287return(q);
288}
289
290
291
292struct labelblock *mklabel(l)
293ftnint l;
294{
295register struct labelblock *lp;
296
297if(l == 0)
298 return(0);
299
300for(lp = labeltab ; lp < highlabtab ; ++lp)
301 if(lp->stateno == l)
302 return(lp);
303
304if(++highlabtab >= labtabend)
305 fatal("too many statement numbers");
306
307lp->stateno = l;
308lp->labelno = newlabel();
309lp->blklevel = 0;
310lp->labused = NO;
311lp->labdefined = NO;
312lp->labinacc = NO;
313lp->labtype = LABUNKNOWN;
314return(lp);
315}
316
317
318newlabel()
319{
320return( ++lastlabno );
321}
322
323
324/* find or put a name in the external symbol table */
325
326struct extsym *mkext(s)
327char *s;
328{
329int i;
330register char *t;
331char n[XL];
332struct extsym *p;
333
334i = 0;
335t = n;
336while(i<XL && *s)
337 *t++ = *s++;
338while(t < n+XL)
339 *t++ = ' ';
340
341for(p = extsymtab ; p<nextext ; ++p)
342 if(eqn(XL, n, p->extname))
343 return( p );
344
345if(nextext >= lastext)
346 fatal("too many external symbols");
347
348cpn(XL, n, nextext->extname);
349nextext->extstg = STGUNKNOWN;
350nextext->extsave = NO;
351nextext->extp = 0;
352nextext->extleng = 0;
353nextext->maxleng = 0;
354nextext->extinit = NO;
355return( nextext++ );
356}
357
358
359
360
361
362
363
364
365struct addrblock *builtin(t, s)
366int t;
367char *s;
368{
369register struct extsym *p;
370register struct addrblock *q;
371
372p = mkext(s);
373if(p->extstg == STGUNKNOWN)
374 p->extstg = STGEXT;
375else if(p->extstg != STGEXT)
376 {
377 err1("improper use of builtin %s", s);
378 return(0);
379 }
380
381q = ALLOC(addrblock);
382q->tag = TADDR;
383q->vtype = t;
384q->vclass = CLPROC;
385q->vstg = STGEXT;
386q->memno = p - extsymtab;
387return(q);
388}
389
390
391
392frchain(p)
393register chainp *p;
394{
395register chainp q;
396
397if(p==0 || *p==0)
398 return;
399
400for(q = *p; q->nextp ; q = q->nextp)
401 ;
402q->nextp = chains;
403chains = *p;
404*p = 0;
405}
406
407
408ptr cpblock(n,p)
409register int n;
410register char * p;
411{
412register char *q;
413ptr q0;
414
415q = q0 = ckalloc(n);
416while(n-- > 0)
417 *q++ = *p++;
418return(q0);
419}
420
421
422
423max(a,b)
424int a,b;
425{
426return( a>b ? a : b);
427}
428
429
430ftnint lmax(a, b)
431ftnint a, b;
432{
433return( a>b ? a : b);
434}
435
436ftnint lmin(a, b)
437ftnint a, b;
438{
439return(a < b ? a : b);
440}
441
442
443
444
445maxtype(t1, t2)
446int t1, t2;
447{
448int t;
449
450t = max(t1, t2);
451if(t==TYCOMPLEX && (t1==TYDREAL || t2==TYDREAL) )
452 t = TYDCOMPLEX;
453return(t);
454}
455
456
457
458/* return log base 2 of n if n a power of 2; otherwise -1 */
459#if FAMILY == SCJ
460log2(n)
461ftnint n;
462{
463int k;
464
465/* trick based on binary representation */
466
467if(n<=0 || (n & (n-1))!=0)
468 return(-1);
469
470for(k = 0 ; n >>= 1 ; ++k)
471 ;
472return(k);
473}
474#endif
475
476
477
478frrpl()
479{
480struct rplblock *rp;
481
482while(rpllist)
483 {
484 rp = rpllist->nextp;
485 free(rpllist);
486 rpllist = rp;
487 }
488}
489
490
491popstack(p)
492register chainp *p;
493{
494register chainp q;
495
496if(p==NULL || *p==NULL)
497 fatal("popstack: stack empty");
498q = (*p)->nextp;
499free(*p);
500*p = q;
501}
502
503
504
505struct exprblock *callk(type, name, args)
506int type;
507char *name;
508chainp args;
509{
510register struct exprblock *p;
511
512p = mkexpr(OPCALL, builtin(type,name), args);
513p->vtype = type;
514return(p);
515}
516
517
518
519struct exprblock *call4(type, name, arg1, arg2, arg3, arg4)
520int type;
521char *name;
522expptr arg1, arg2, arg3, arg4;
523{
524struct listblock *args;
525args = mklist( mkchain(arg1, mkchain(arg2, mkchain(arg3, mkchain(arg4, NULL)) ) ) );
526return( callk(type, name, args) );
527}
528
529
530
531
532struct exprblock *call3(type, name, arg1, arg2, arg3)
533int type;
534char *name;
535expptr arg1, arg2, arg3;
536{
537struct listblock *args;
538args = mklist( mkchain(arg1, mkchain(arg2, mkchain(arg3, NULL) ) ) );
539return( callk(type, name, args) );
540}
541
542
543
544
545
546struct exprblock *call2(type, name, arg1, arg2)
547int type;
548char *name;
549expptr arg1, arg2;
550{
551struct listblock *args;
552
553args = mklist( mkchain(arg1, mkchain(arg2, NULL) ) );
554return( callk(type,name, args) );
555}
556
557
558
559
560struct exprblock *call1(type, name, arg)
561int type;
562char *name;
563expptr arg;
564{
565return( callk(type,name, mklist(mkchain(arg,0)) ));
566}
567
568
569struct exprblock *call0(type, name)
570int type;
571char *name;
572{
573return( callk(type, name, NULL) );
574}
575
576
577
578struct impldoblock *mkiodo(dospec, list)
579chainp dospec, list;
580{
581register struct impldoblock *q;
582
583q = ALLOC(impldoblock);
584q->tag = TIMPLDO;
585q->varnp = dospec;
586q->datalist = list;
587return(q);
588}
589
590
591
592
593ptr ckalloc(n)
594register int n;
595{
596register ptr p;
597ptr calloc();
598
599if( p = calloc(1, (unsigned) n) )
600 return(p);
601
602fatal("out of memory");
603/* NOTREACHED */
604}
605
606
607
608
609
610isaddr(p)
611register expptr p;
612{
613if(p->tag == TADDR)
614 return(YES);
615if(p->tag == TEXPR)
616 switch(p->opcode)
617 {
618 case OPCOMMA:
619 return( isaddr(p->rightp) );
620
621 case OPASSIGN:
622 case OPPLUSEQ:
623 return( isaddr(p->leftp) );
624 }
625return(NO);
626}
627
628
629
630
631
632addressable(p)
633register expptr p;
634{
635switch(p->tag)
636 {
637 case TCONST:
638 return(YES);
639
640 case TADDR:
641 return( addressable(p->memoffset) );
642
643 default:
644 return(NO);
645 }
646}
647
648
649
650hextoi(c)
651register int c;
652{
653register char *p;
654static char p0[17] = "0123456789abcdef";
655
656for(p = p0 ; *p ; ++p)
657 if(*p == c)
658 return( p-p0 );
659return(16);
660}