Commit | Line | Data |
---|---|---|
3097d999 BB |
1 | #include <stdio.h> |
2 | #include "1.incl.h" | |
3 | #include "def.h" | |
4 | ||
5 | ||
6 | recognize(type, ifflag) /* if ifflag = 1, statement is if()type; otherwise is type */ | |
7 | int 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; | |
230 | case entry: fprintf(debfd,"entry statement "); break; | |
231 | } | |
232 | fprintf(debfd,"\n%s\n", buffer); | |
233 | } | |
234 | } | |
235 | ||
236 | ||
237 | ||
238 | makeif(first,labe,test,arc1,arc2) /* construct IFVX with arcs to labels arc1,arc2 */ | |
239 | int first; | |
240 | long labe, arc1,arc2; | |
241 | char *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 | ||
254 | innerdo(labe) /* return number of DOVX associated with labe, or UNDEFINED */ | |
255 | long labe; | |
256 | { | |
257 | if (DEFINED(doptr)) | |
258 | {if (dostack[doptr] == labe) | |
259 | return(doloc[doptr--]); | |
260 | } | |
261 | return(UNDEFINED); | |
262 | } | |
263 | ||
264 | ||
265 | ||
266 | ||
267 | contin(labe,nest) /* handle continue statements */ | |
268 | long labe; | |
269 | int 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 | ||
289 | nesteddo(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 */ | |
293 | long labe; | |
294 | int 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 | ||
307 | compcase(ifflag) /* turn computed goto into case statement */ | |
308 | LOGICAL 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 | ||
334 | accum(str,vlist,f) /* build string of indices in compnode corr. to label f */ | |
335 | char *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 | ||
359 | distinct(vlist,count,dlist,size) /* make dlist into list of distinct labels in vlist */ | |
360 | struct lablist *vlist; long dlist[]; /*count[] gets count of each label; d distinct labels */ | |
361 | int 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 |