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