c01.c (5936B)
1 build(op) { 2 extern cp[], cvtab, opdope[], maprel[]; 3 auto p1[], t1, d1, p2[], t2, d2, p3[], t3, d3, t; 4 auto d, dope, leftc, cvn, pcvn; 5 char cvtab[]; 6 7 if (op==4) { /* [] */ 8 build(40); /* + */ 9 op = 36; /* * */ 10 } 11 dope = opdope[op]; 12 if ((dope&01)!=0) { /* binary */ 13 p2 = disarray(*--cp); 14 t2 = p2[1]; 15 chkfun(p2); 16 d2 = p2[2]; 17 if (*p2==20) 18 d2 = 0; 19 } 20 p1 = disarray(*--cp); 21 if (op!=100 & op!=35) /* call, * */ 22 chkfun(p1); 23 t1 = p1[1]; 24 d1 = p1[2]; 25 if (*p1==20) 26 d1 = 0; 27 pcvn = 0; 28 switch (op) { 29 30 /* : */ 31 case 8: 32 if (t1!=t2) 33 error("Type clash in conditional"); 34 t = t1; 35 goto nocv; 36 37 /* , */ 38 case 9: 39 *cp++ = block(2, 9, 0, 0, p1, p2); 40 return; 41 42 /* ? */ 43 case 90: 44 if (*p2!=8) 45 error("Illegal conditional"); 46 t = t2; 47 goto nocv; 48 49 /* call */ 50 case 100: 51 if ((t1&030) != 020) 52 error("Call of non-function"); 53 *cp++ = block(2,100,decref(t1),24,p1,p2); 54 return; 55 56 /* * */ 57 case 36: 58 if (*p1==35 | *p1==29) { /* & unary */ 59 *cp++ = p1[3]; 60 return; 61 } 62 if (*p1!=20 & d1==0) 63 d1 = 1; 64 if ((t1&030) == 020) /* function */ 65 error("Illegal indirection"); 66 *cp++ = block(1,36,decref(t1),d1,p1); 67 return; 68 69 /* & unary */ 70 case 35: 71 if (*p1==36) { /* * */ 72 *cp++ = p1[3]; 73 return; 74 } 75 if (*p1==20) { 76 *cp++ = block(1,p1[3]==5?29:35,incref(t1),1,p1); 77 return; 78 } 79 error("Illegal lvalue"); 80 break; 81 82 case 43: /* / */ 83 case 44: /* % */ 84 case 73: /* =/ */ 85 case 74: /* =% */ 86 d1++; 87 d2++; 88 89 case 42: /* * */ 90 case 72: /* =* */ 91 d1++; 92 d2++; 93 break; 94 95 case 30: /* ++ -- pre and post */ 96 case 31: 97 case 32: 98 case 33: 99 chklval(p1); 100 *cp++ = block(2,op,t1,max(d1,1),p1,plength(p1)); 101 return; 102 103 case 39: /* . (structure ref) */ 104 case 50: /* -> (indirect structure ref) */ 105 if (p2[0]!=20 | p2[3]!=4) /* not mos */ 106 error("Illegal structure ref"); 107 *cp++ = p1; 108 t = t2; 109 if ((t&030) == 030) /* array */ 110 t = decref(t); 111 setype(p1, t); 112 if (op==39) /* is "." */ 113 build(35); /* unary & */ 114 *cp++ = block(1,21,7,0,p2[5]); 115 build(40); /* + */ 116 if ((t2&030) != 030) /* not array */ 117 build(36); /* unary * */ 118 return; 119 } 120 if ((dope&02)!=0) /* lvalue needed on left? */ 121 chklval(p1); 122 if ((dope&020)!=0) /* word operand on left? */ 123 chkw(p1); 124 if ((dope&040)!=0) /* word operand on right? */ 125 chkw(p2); 126 if ((dope&01)==0) { /* unary op? */ 127 *cp++ = block(1,op,t1,max(d1,1),p1); 128 return; 129 } 130 if (t2==7) { 131 t = t1; 132 p2[1] = 0; /* no int cv for struct */ 133 t2 = 0; 134 goto nocv; 135 } 136 cvn = cvtab[11*lintyp(t1)+lintyp(t2)]; 137 leftc = cvn&0100; 138 t = leftc? t2:t1; 139 if (op==80 & t1!=4 & t2!=4) { /* = */ 140 t = t1; 141 if (leftc | cvn!=1) 142 goto nocv; 143 } 144 if (cvn =& 077) { 145 if (cvn==077) { 146 illcv: 147 error("Illegal conversion"); 148 goto nocv; 149 } 150 if (cvn>4 & cvn<10) { /* ptr conv */ 151 t = 0; /* integer result */ 152 cvn = 0; 153 if ((dope&04)!=0) /* relational? */ 154 goto nocv; 155 if (op!=41) /* - */ 156 goto illcv; 157 pcvn = cvn; 158 goto nocv; 159 } 160 if (leftc) { 161 if ((dope&010) != 0) { /* =op */ 162 if (cvn == 1) { 163 leftc = 0; 164 cvn = 8; 165 t = t1; 166 goto rcvt; 167 } else 168 goto illcv; 169 } 170 d1 = (p1=convert(p1, t, d1, cvn, plength(p2)))[2]; 171 } else { 172 rcvt: 173 d2 = (p2=convert(p2, t, d2, cvn, plength(p1)))[2]; 174 } 175 nocv:; } 176 if (d1==d2) 177 d = d1+1; else 178 d = max(d1,d2); 179 if ((dope&04)!=0) { /* relational? */ 180 if (op>61 & t>=010) 181 op =+ 4; /* ptr relation */ 182 t = 0; /* relational is integer */ 183 } 184 *cp++ = optim(block(2,op,t,d,p1,p2)); 185 if (pcvn) { 186 p1 = *--cp; 187 *cp++ = block(1,50+pcvn,0,d,p1); 188 } 189 return; 190 *cp++ = block(1,op,t1,d1==0?1:d1,p1); 191 } 192 193 setype(p, t) 194 int p[]; 195 { 196 int p1[]; 197 198 if ((p[1]&07) != 4) /* not structure */ 199 return; 200 p[1] = t; 201 switch(*p) { 202 203 case 29: /* & */ 204 case 35: 205 setype(p[3], decref(t)); 206 return; 207 208 case 36: /* * */ 209 setype(p[3], incref(t)); 210 return; 211 212 case 40: /* + */ 213 setype(p[4], t); 214 } 215 } 216 217 chkfun(p) 218 int p[]; 219 { 220 if ((p[1]&030)==020) /* func */ 221 error("Illegal use of function"); 222 } 223 224 optim(p) 225 int p[]; 226 { 227 int p1[], p2[], t; 228 229 if (*p != 40) /* + */ 230 return(p); 231 p1 = p[3]; 232 p2 = p[4]; 233 if (*p1==21) { /* const */ 234 t = p1; 235 p1 = p2; 236 p2 = t; 237 } 238 if (*p2 != 21) /* const */ 239 return(p); 240 if ((t=p2[3]) == 0) /* const 0 */ 241 return(p1); 242 if (*p1!=35 & *p1!=29) /* not & */ 243 return(p); 244 p2 = p1[3]; 245 if (*p2!=20) { /* name? */ 246 error("C error (optim)"); 247 return(p); 248 } 249 p2[4] =+ t; 250 return(p1); 251 } 252 253 disarray(p) 254 int p[]; 255 { 256 extern cp; 257 int t, cp[]; 258 259 if (((t = p[1]) & 030)!=030 | p[0]==20&p[3]==4) /* array & not MOS */ 260 return(p); 261 p[1] = decref(t); 262 *cp++ = p; 263 build(35); /* add & */ 264 return(*--cp); 265 } 266 267 convert(p, t, d, cvn, len) 268 int p[]; 269 { 270 int c, p1[]; 271 272 if (*p==21) { /* constant */ 273 c = p[3]; 274 switch(cvn) { 275 276 case 4: /* int -> double[] */ 277 c =<< 1; 278 279 case 3: /* int -> float[] */ 280 c =<< 1; 281 282 case 2: /* int -> int[] */ 283 c =<< 1; 284 p[3] = c; 285 return(p); 286 287 case 10: /* i -> s[] */ 288 p[3] = c*len; 289 return(p); 290 } 291 } 292 if (cvn==10) /* i -> s[]; retrun i*len */ 293 return(block(2,42,t,d+2,p,block(1,21,0,0,len))); 294 return(block(1, 50+cvn, t, max(1,d), p)); 295 } 296 297 chkw(p) 298 int p[]; { 299 extern error; 300 auto t; 301 302 if ((t=p[1])>1 & t<=07) 303 error("Integer operand required"); 304 return; 305 } 306 307 lintyp(t) 308 { 309 if (t<=07) 310 return(t); 311 if ((t&037)==t) 312 return((t&07)+5); 313 return(10); 314 } 315 316 error(s, p1, p2, p3, p4, p5, p6) { 317 extern line, fout, nerror; 318 int f; 319 320 nerror++; 321 flush(); 322 f = fout; 323 fout = 1; 324 printf("%d: ", line); 325 printf(s, p1, p2, p3, p4, p5, p6); 326 putchar('\n'); 327 fout = f; 328 } 329 330 block(n, op, t, d, p1,p2,p3) 331 int p1[],p2[],p3[]; { 332 int p[], ap[], space[]; 333 extern space; 334 335 ap = &op; 336 n =+ 3; 337 p = space; 338 while(n--) 339 pblock(*ap++); 340 return(p); 341 } 342 343 pblock(p) 344 { 345 extern space, osleft; 346 int space[]; 347 348 *space++ = p; 349 if (--osleft<=0) { 350 error("Expression overflow"); 351 exit(1); 352 } 353 } 354 355 chklval(p) 356 int p[]; { 357 extern error; 358 359 if (*p!=20 & *p !=36) 360 error("Lvalue required"); 361 } 362 363 max(a, b) 364 { 365 if (a>b) 366 return(a); 367 return(b); 368 } 369