|
|
1.1 root 1: #include "defs"
2:
3: #ifdef SDB
4: # include <a.out.h>
5: #endif
6:
7: /* ROUTINES RELATED TO EQUIVALENCE CLASS PROCESSING */
8:
9: /* called at end of declarations section to process chains
10: created by EQUIVALENCE statements
11: */
12: doequiv()
13: {
14: register int i;
15: int inequiv, comno, ovarno;
16: ftnint comoffset, offset, leng;
17: register struct Equivblock *p;
18: register struct Eqvchain *q;
19: struct Primblock *itemp;
20: register struct Nameblock *np;
21: expptr offp, suboffset();
22: int ns, nsubs();
23: chainp cp;
24:
25: for(i = 0 ; i < nequiv ; ++i)
26: {
27: p = &eqvclass[i];
28: p->eqvbottom = p->eqvtop = 0;
29: comno = -1;
30:
31: for(q = p->equivs ; q ; q = q->nextp)
32: {
33: itemp = q->eqvitem;
34: vardcl(np = itemp->namep);
35: if(itemp->argsp || itemp->fcharp)
36: {
37: if(np->vdim!=NULL && np->vdim->ndim>1 &&
38: nsubs(itemp->argsp)==1 )
39: {
40: if(! ftn66flag)
41: warn("1-dim subscript in EQUIVALENCE");
42: cp = NULL;
43: ns = np->vdim->ndim;
44: while(--ns > 0)
45: cp = mkchain( ICON(1), cp);
46: itemp->argsp->listp->nextp = cp;
47: }
48: offp = suboffset(itemp);
49: }
50: else offp = ICON(0);
51: if(ISICON(offp))
52: offset = q->eqvoffset = offp->constblock.const.ci;
53: else {
54: dclerr("nonconstant subscript in equivalence ", np);
55: np = NULL;
56: goto endit;
57: }
58: if( (leng = iarrlen(np)) < 0)
59: {
60: dclerr("adjustable in equivalence", np);
61: np = NULL;
62: goto endit;
63: }
64: p->eqvbottom = lmin(p->eqvbottom, -offset);
65: p->eqvtop = lmax(p->eqvtop, leng-offset);
66:
67: switch(np->vstg)
68: {
69: case STGUNKNOWN:
70: case STGBSS:
71: case STGEQUIV:
72: break;
73:
74: case STGCOMMON:
75: comno = np->vardesc.varno;
76: comoffset = np->voffset + offset;
77: break;
78:
79: default:
80: dclerr("bad storage class in equivalence", np);
81: np = NULL;
82: goto endit;
83: }
84: endit:
85: frexpr(offp);
86: q->eqvitem = np;
87: }
88:
89: if(comno >= 0)
90: eqvcommon(p, comno, comoffset);
91: else for(q = p->equivs ; q ; q = q->nextp)
92: {
93: if(np = q->eqvitem)
94: {
95: inequiv = NO;
96: if(np->vstg==STGEQUIV)
97: if( (ovarno = np->vardesc.varno) == i)
98: {
99: if(np->voffset + q->eqvoffset != 0)
100: dclerr("inconsistent equivalence", np);
101: }
102: else {
103: offset = np->voffset;
104: inequiv = YES;
105: }
106:
107: np->vstg = STGEQUIV;
108: np->vardesc.varno = i;
109: np->voffset = - q->eqvoffset;
110:
111: if(inequiv)
112: eqveqv(i, ovarno, q->eqvoffset + offset);
113: }
114: }
115: }
116:
117: for(i = 0 ; i < nequiv ; ++i)
118: {
119: p = & eqvclass[i];
120: if(p->eqvbottom!=0 || p->eqvtop!=0) /* a live chain */
121: {
122: #ifdef SDB
123: if(sdbflag)
124: prstab(NULL, N_BCOMM, 0, 0);
125: #endif
126: for(q = p->equivs ; q; q = q->nextp)
127: {
128: np = q->eqvitem;
129: np->voffset -= p->eqvbottom;
130: if(np->voffset % typealign[np->vtype] != 0)
131: dclerr("bad alignment forced by equivalence", np);
132: #ifdef SDB
133: if(sdbflag)
134: {
135: prstssym(np);
136: prstleng(np, iarrlen(np));
137: }
138: #endif
139: }
140: p->eqvtop -= p->eqvbottom;
141: p->eqvbottom = 0;
142: #ifdef SDB
143: if(sdbflag)
144: prstab(NULL, N_ECOML, 0, memname(STGEQUIV,i) );
145: #endif
146: }
147: freqchain(p);
148: }
149: }
150:
151:
152:
153:
154:
155: /* put equivalence chain p at common block comno + comoffset */
156:
157: LOCAL eqvcommon(p, comno, comoffset)
158: struct Equivblock *p;
159: int comno;
160: ftnint comoffset;
161: {
162: int ovarno;
163: ftnint k, offq;
164: register struct Nameblock *np;
165: register struct Eqvchain *q;
166:
167: if(comoffset + p->eqvbottom < 0)
168: {
169: errstr("attempt to extend common %s backward",
170: nounder(XL, extsymtab[comno].extname) );
171: freqchain(p);
172: return;
173: }
174:
175: if( (k = comoffset + p->eqvtop) > extsymtab[comno].extleng)
176: extsymtab[comno].extleng = k;
177:
178: #ifdef SDB
179: if(sdbflag)
180: prstab( varstr(XL,extsymtab[comno].extname), N_BCOMM,0,0);
181: #endif
182:
183: for(q = p->equivs ; q ; q = q->nextp)
184: if(np = q->eqvitem)
185: {
186: switch(np->vstg)
187: {
188: case STGUNKNOWN:
189: case STGBSS:
190: np->vstg = STGCOMMON;
191: np->vardesc.varno = comno;
192: np->voffset = comoffset - q->eqvoffset;
193: #ifdef SDB
194: if(sdbflag)
195: {
196: prstssym(np);
197: prstleng(np, iarrlen(np));
198: }
199: #endif
200: break;
201:
202: case STGEQUIV:
203: ovarno = np->vardesc.varno;
204: offq = comoffset - q->eqvoffset - np->voffset;
205: np->vstg = STGCOMMON;
206: np->vardesc.varno = comno;
207: np->voffset = comoffset - q->eqvoffset;
208: if(ovarno != (p - eqvclass))
209: eqvcommon(&eqvclass[ovarno], comno, offq);
210: break;
211:
212: case STGCOMMON:
213: if(comno != np->vardesc.varno ||
214: comoffset != np->voffset+q->eqvoffset)
215: dclerr("inconsistent common usage", np);
216: break;
217:
218:
219: default:
220: fatali("eqvcommon: impossible vstg %d", np->vstg);
221: }
222: }
223:
224: #ifdef SDB
225: if(sdbflag)
226: prstab( varstr(XL,extsymtab[comno].extname), N_ECOMM,0,0);
227: #endif
228:
229: freqchain(p);
230: p->eqvbottom = p->eqvtop = 0;
231: }
232:
233:
234: /* put all items on ovarno chain on front of nvarno chain
235: * adjust offsets of ovarno elements and top and bottom of nvarno chain
236: */
237:
238: LOCAL eqveqv(nvarno, ovarno, delta)
239: int ovarno, nvarno;
240: ftnint delta;
241: {
242: register struct Equivblock *p0, *p;
243: register struct Nameblock *np;
244: struct Eqvchain *q, *q1;
245:
246: p0 = eqvclass + nvarno;
247: p = eqvclass + ovarno;
248: p0->eqvbottom = lmin(p0->eqvbottom, p->eqvbottom - delta);
249: p0->eqvtop = lmax(p0->eqvtop, p->eqvtop - delta);
250: p->eqvbottom = p->eqvtop = 0;
251:
252: for(q = p->equivs ; q ; q = q1)
253: {
254: q1 = q->nextp;
255: if( (np = q->eqvitem) && np->vardesc.varno==ovarno)
256: {
257: q->nextp = p0->equivs;
258: p0->equivs = q;
259: q->eqvoffset -= delta;
260: np->vardesc.varno = nvarno;
261: np->voffset -= delta;
262: }
263: else free(q);
264: }
265: p->equivs = NULL;
266: }
267:
268:
269:
270:
271: LOCAL freqchain(p)
272: register struct Equivblock *p;
273: {
274: register struct Eqvchain *q, *oq;
275:
276: for(q = p->equivs ; q ; q = oq)
277: {
278: oq = q->nextp;
279: free(q);
280: }
281: p->equivs = NULL;
282: }
283:
284:
285:
286:
287:
288: LOCAL nsubs(p)
289: register struct Listblock *p;
290: {
291: register int n;
292: register chainp q;
293:
294: n = 0;
295: if(p)
296: for(q = p->listp ; q ; q = q->nextp)
297: ++n;
298:
299: return(n);
300: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.