1 /*-
2 * %sccs.include.proprietary.c%
3 */
4
5 #ifndef lint
6 static char sccsid[] = "@(#)1.recog.c 8.1 (Berkeley) 06/06/93";
7 #endif /* not lint */
8
9 #include <stdio.h>
10 #include "1.incl.h"
11 #include "def.h"
12
13
recognize(type,ifflag)14 recognize(type, ifflag) /* if ifflag = 1, statement is if()type; otherwise is type */
15 int type, ifflag; /* do whatever is needed for this statement */
16 {
17 int *arctype, i, sp;
18 VERT num, num1, nest, loophead;
19 extern long label();
20 long *arclab;
21 if (nlabs > 3) sp = nlabs; else sp = 3;
22 arctype = challoc(sizeof(*arctype) * sp); arclab = challoc(sizeof(*arclab) * sp);
23 for( i=0; i < endbuf; i++) {if (buffer[i] == '~') buffer[i] = ' ';}
24 loophead = nest = innerdo(label(0));
25 if (DEFINED(nest))
26 {
27 /* this statement is last line of do loop */
28 nest = ARC(nest,0); /* nest is ITERVX of the innermost do ending here */
29 }
30
31
32 if (ifflag)
33 {
34 if (type == ungo)
35 {
36 arctype[0] = -2;
37 arclab[0] = label(1);
38 }
39 else
40 arctype[0] = 0;
41
42 arctype[1] = (nest >= 0) ? nest : -2;
43 arclab[1] = implicit;
44 num1 = makenode(IFVX,TRUE,TRUE,label(0),2,arctype,arclab);
45 PRED(num1) = pred;
46 }
47
48 arctype[0] = (nest >= 0) ? nest : -2;
49 arclab[0] = implicit;
50
51 switch(type)
52 {
53 case ungo:
54 if (!ifflag)
55 {
56 connect(label(1),implicit);
57 if (label(0) != implicit) connect(label(1),label(0));
58 }
59 break;
60 case RETVX:
61 case STOPVX:
62 if (type == RETVX)
63 {
64 if (retvert == UNDEFINED)
65 retvert = makenode(type,FALSE,FALSE,implicit,0,arctype,arclab);
66 num = retvert;
67 }
68 else
69 {
70 if (stopvert == UNDEFINED)
71 stopvert = makenode(type,FALSE,FALSE,implicit,0,arctype,arclab);
72 num = stopvert;
73 }
74 if (!ifflag)
75 {
76 fixvalue(implicit,num);
77 clear(implicit);
78 if (label(0) != implicit) fixvalue(label(0),num);
79 }
80 break;
81
82
83 case contst:
84 contin(label(0),loophead);
85 break;
86
87 case FMTVX:
88 num = makenode(FMTVX,FALSE,TRUE,implicit,0,arctype,arclab);
89 BEGCODE(num) = comchar + 1 - rtnbeg;
90 ONDISK(num) = endline - endcom;
91 if (label(0) != implicit)
92 fixvalue(label(0),num);
93 FMTLST = append(num,FMTLST);
94 break;
95 case STLNVX:
96 if (DEFINED(stflag) && !ifflag && (label(0) == implicit))
97 {
98 ++CODELINES(stflag);
99 ONDISK(stflag) += endline - begline + 1;
100 }
101 else
102 {
103 num = makenode(STLNVX,!ifflag,!ifflag,label(0),1,arctype,arclab);
104 if (!ifflag)
105 {
106 stflag = num;
107 BEGCODE(num) = comchar + 1 - rtnbeg;
108 ONDISK(num) = endline - endcom;
109 CODELINES(num) = 1;
110 }
111 else
112 {
113 BEGCODE(num) = stcode;
114 ONDISK(num) = FALSE;
115 CODELINES(num) = 1;
116 }
117 }
118 break;
119
120 case DOVX:
121 if (arctype[0] != -2)
122 {
123 error("illegal do range, ","","");
124 fprintf(stderr," between lines %d and %d\n",begline, endline);
125 exit(1);
126 }
127 arctype[1] = UNDEFINED;
128 num1 = makenode(DOVX,TRUE,TRUE,label(0),2,arctype,arclab);
129 if (++doptr >= maxdo)
130 {
131 faterr("in parsing:\n","do loops nested deeper than allowed","");
132 }
133 dostack[doptr] = label(1);
134 doloc[doptr] = num1; /* stack link to node after loop */
135 INC(num1) = inc;
136 num = makenode(ITERVX,TRUE,FALSE,implicit,1,arctype,arclab);
137 ARC(num1,0) = num;
138 FATH(num) = UNDEFINED; /* number of DOVX can change so leave UNDEFINED until later */
139 break;
140 case arithif:
141 if (label(1) == label(2) || label(1) == 0L)
142 makeif(1,label(0),concat(pred," > 0"),label(3),label(2));
143 else if (label(1) == label(3) || label(3) == 0L)
144 makeif(1,label(0),concat(pred," == 0"),label(2),label(1));
145 else if (label(2) == label(3) || label(2) == 0L)
146 makeif(1,label(0),concat(pred," < 0"),label(1),label(3));
147 else
148 {
149 makeif(1,label(0),concat(pred," < 0"),label(1),implicit);
150 makeif(1,implicit,concat(pred," == 0"),label(2),label(3));
151 }
152 break;
153
154 case IOVX:
155 if (endlab)
156 {
157 arctype[1] = -2;
158 arclab[1] = endlab->labelt;
159 }
160 else
161 arctype[1] = UNDEFINED;
162 if (errlab)
163 {
164 arctype[2] = -2;
165 arclab[2] = errlab->labelt;
166 }
167 else
168 arctype[2] = UNDEFINED;
169 num = makenode(IOVX,!ifflag,!ifflag,label(0),3,arctype,arclab);
170 PRERW(num) = prerw;
171 POSTRW(num) = postrw;
172 if (reflab)
173 addref(reflab->labelt, &FMTREF(num));
174 else
175 FMTREF(num) = UNDEFINED;
176 break;
177
178 case COMPVX:
179 if (intcase)
180 {
181 num = compcase(ifflag);
182 break;
183 }
184 case ASGOVX:
185 for (i = 0; i < nlabs - 1; i++)
186 {
187 arctype[i] = -2;
188 arclab[i] = label(nlabs-i-1);
189 }
190 num = makenode(type,!ifflag,!ifflag,label(0),nlabs - 1, arctype, arclab);
191 EXP(num) = exp;
192 break;
193 case ASVX:
194 num = makenode(ASVX,!ifflag,!ifflag,label(0),1,arctype,arclab);
195 EXP(num) = exp;
196 addref(label(1),&LABREF(num));
197 break;
198 case entry:
199 num = makenode(STLNVX,FALSE,TRUE,label(0),1,arctype,arclab);
200 BEGCODE(num) = comchar + 1 - rtnbeg;
201 ONDISK(num) = endline - endcom;
202 CODELINES(num) = 1;
203 ENTLST = append(num,ENTLST);
204 break;
205 }
206 if (ifflag && type != ungo)
207 {
208 ARC(num1,0) = num;
209 }
210 if (DEFINED(loophead)) nesteddo(label(0), loophead);
211 if (ifflag || DEFINED(loophead) || type != STLNVX) stflag = UNDEFINED;
212
213
214 chfree(arctype,sizeof(*arctype) * sp); chfree(arclab,sizeof(*arclab) * sp);
215 if (debug)
216 {
217 fprintf(debfd,"line %d: ", begline);
218 if (ifflag) fprintf(debfd,"if() ");
219 switch(type)
220 {case RETVX: fprintf(debfd,"return"); break;
221 case STOPVX: fprintf(debfd,"stop"); break;
222 case contst: fprintf(debfd,"continue"); break;
223 case ungo: fprintf(debfd,"uncond. goto"); break;
224 case COMPVX: fprintf(debfd,"comp. goto"); break;
225 case ASGOVX: fprintf(debfd,"ass. goto, labs"); break;
226 case ASVX: fprintf(debfd,"label assignment"); break;
227 case STLNVX: fprintf(debfd,"simple statement"); break;
228 case arithif: fprintf(debfd,"arith if"); break;
229 case DOVX: fprintf(debfd,"do "); break;
230 case FMTVX: fprintf(debfd,"format st"); break;
231 case IOVX: fprintf(debfd,"IOVX statement "); break;
232 case entry: fprintf(debfd,"entry statement "); break;
233 }
234 fprintf(debfd,"\n%s\n", buffer);
235 }
236 }
237
238
239
makeif(first,labe,test,arc1,arc2)240 makeif(first,labe,test,arc1,arc2) /* construct IFVX with arcs to labels arc1,arc2 */
241 int first;
242 long labe, arc1,arc2;
243 char *test;
244 {
245 int num, arctype[2];
246 long arclab[2];
247 arctype[0] = arctype[1] = -2;
248 arclab[0] = arc1;
249 arclab[1] = arc2;
250 num = makenode(IFVX,first,first,labe,2,arctype,arclab);
251 PRED(num) = test;
252 return(num);
253 }
254
255
innerdo(labe)256 innerdo(labe) /* return number of DOVX associated with labe, or UNDEFINED */
257 long labe;
258 {
259 if (DEFINED(doptr))
260 {if (dostack[doptr] == labe)
261 return(doloc[doptr--]);
262 }
263 return(UNDEFINED);
264 }
265
266
267
268
contin(labe,nest)269 contin(labe,nest) /* handle continue statements */
270 long labe;
271 int nest;
272 {
273 VERT y;
274
275 if (!DEFINED(nest))
276 { /* not nested */
277 if (labe != implicit) connect(implicit,labe); /* labe pts to next node */
278 }
279 else
280 { /* nested */
281 y = ARC(nest,0);
282 fixvalue(labe,y); /* labe pts to ITERVX */
283 fixvalue(implicit, y); /* implicit links pt to ITERVX */
284 clear(implicit);
285 }
286 }
287
288
289
290
nesteddo(labe,v)291 nesteddo(labe,v)
292 /* if multiple do's end on same label, add arc from inner DOVX
293 to enclosing DOVX;
294 add implicit link out of outermost DOVX with this label */
295 long labe;
296 int v;
297 {
298
299 while (DEFINED(doptr) && dostack[doptr] == labe)
300 {
301 ARC(v,1) = ARC(doloc[doptr],0); /*set inner DOVX to point to outer ITERVX */
302 v = doloc[doptr--];
303 }
304 addref(implicit, &ARC(v,1));
305 }
306
307
308
compcase(ifflag)309 compcase(ifflag) /* turn computed goto into case statement */
310 LOGICAL ifflag;
311 {
312 int *arctype, i, num, d, arct;
313 extern long label();
314 long *arclab;
315 char *str;
316 arctype = challoc(sizeof(*arctype) * nlabs);
317 arclab = challoc (sizeof(*arclab) * nlabs);
318
319 d = distinct(linelabs->nxtlab,arctype,arclab,nlabs-1);
320 /* puts distinct labels in arclab, count of each in arctype */
321 arct = -2;
322 for (i = 0; i < d; ++i)
323 arctype[i] = makenode(ICASVX,FALSE,FALSE,implicit,1,&arct,&arclab[i]);
324 num = makenode(SWCHVX,!ifflag,!ifflag,label(0),d,arctype,arclab);
325 EXP(num) = exp;
326
327 str = challoc(6*(nlabs-1)); /* 5 digits + , or \0 per label */
328 for (i = 0; i < d; ++i) /* construct list of values for each label */
329 EXP(arctype[i]) = stralloc(str,accum(str,linelabs->nxtlab,arclab[i]));
330 chfree(str,6*(nlabs-1));
331 chfree(arctype,sizeof(*arctype) * nlabs); chfree(arclab,sizeof(*arclab) * nlabs);
332 return(num);
333 }
334
335
accum(str,vlist,f)336 accum(str,vlist,f) /* build string of indices in compnode corr. to label f */
337 char *str; long f; struct lablist *vlist;
338 {
339 int s,j; struct lablist *p;
340
341 s = 0;
342 j = 1;
343 for (p = vlist; p ; p = p->nxtlab) /* search for occurrences of f */
344 {
345 if (p->labelt ==f)
346 {
347 if (s)
348 {
349 str[s] = ',';
350 ++s;
351 }
352 sprintf(&str[s],"%d",j);
353 while (str[s] != '\0') ++s;
354 }
355 ++j;
356 }
357 return(s+1);
358 }
359
360
361 distinct(vlist,count,dlist,size) /* make dlist into list of distinct labels in vlist */
362 struct lablist *vlist; long dlist[]; /*count[] gets count of each label; d distinct labels */
363 int count[],size;
364 {int d,i;
365 d = 0;
366 for(i = 0; i < size; i++) count[i] = 0;
367
368 for (;vlist && vlist->labelt != 0L; vlist = vlist ->nxtlab)
369 {
370 for (i = 0; ;i++)
371 {
372 if (i == d) dlist[d++] = vlist->labelt;
373 if (dlist[i] == vlist->labelt)
374 {
375 ++count[i]; break;
376 }
377 }
378 }
379 return(d);
380 }
381
382
383