1 /*- 2 * %sccs.include.proprietary.c% 3 */ 4 5 #ifndef lint 6 static char sccsid[] = "@(#)1.recog.c 4.2 (Berkeley) 04/16/91"; 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