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 
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 
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 
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 
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 
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 
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 
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