1 #include <u.h> 2 #include <libc.h> 3 #include "cpp.h" 4 5 #define NSTAK 32 6 #define SGN 0 7 #define UNS 1 8 #define UND 2 9 10 #define UNSMARK 0x1000 11 12 struct value { 13 long val; 14 int type; 15 }; 16 17 /* conversion types */ 18 #define RELAT 1 19 #define ARITH 2 20 #define LOGIC 3 21 #define SPCL 4 22 #define SHIFT 5 23 #define UNARY 6 24 25 /* operator priority, arity, and conversion type, indexed by tokentype */ 26 const struct pri { 27 char pri; 28 char arity; 29 char ctype; 30 } priority[] = { 31 { 0, 0, 0 }, /* END */ 32 { 0, 0, 0 }, /* UNCLASS */ 33 { 0, 0, 0 }, /* NAME */ 34 { 0, 0, 0 }, /* NUMBER */ 35 { 0, 0, 0 }, /* STRING */ 36 { 0, 0, 0 }, /* CCON */ 37 { 0, 0, 0 }, /* NL */ 38 { 0, 0, 0 }, /* WS */ 39 { 0, 0, 0 }, /* DSHARP */ 40 { 11, 2, RELAT }, /* EQ */ 41 { 11, 2, RELAT }, /* NEQ */ 42 { 12, 2, RELAT }, /* LEQ */ 43 { 12, 2, RELAT }, /* GEQ */ 44 { 13, 2, SHIFT }, /* LSH */ 45 { 13, 2, SHIFT }, /* RSH */ 46 { 7, 2, LOGIC }, /* LAND */ 47 { 6, 2, LOGIC }, /* LOR */ 48 { 0, 0, 0 }, /* PPLUS */ 49 { 0, 0, 0 }, /* MMINUS */ 50 { 0, 0, 0 }, /* ARROW */ 51 { 0, 0, 0 }, /* SBRA */ 52 { 0, 0, 0 }, /* SKET */ 53 { 3, 0, 0 }, /* LP */ 54 { 3, 0, 0 }, /* RP */ 55 { 0, 0, 0 }, /* DOT */ 56 { 10, 2, ARITH }, /* AND */ 57 { 15, 2, ARITH }, /* STAR */ 58 { 14, 2, ARITH }, /* PLUS */ 59 { 14, 2, ARITH }, /* MINUS */ 60 { 16, 1, UNARY }, /* TILDE */ 61 { 16, 1, UNARY }, /* NOT */ 62 { 15, 2, ARITH }, /* SLASH */ 63 { 15, 2, ARITH }, /* PCT */ 64 { 12, 2, RELAT }, /* LT */ 65 { 12, 2, RELAT }, /* GT */ 66 { 9, 2, ARITH }, /* CIRC */ 67 { 8, 2, ARITH }, /* OR */ 68 { 5, 2, SPCL }, /* QUEST */ 69 { 5, 2, SPCL }, /* COLON */ 70 { 0, 0, 0 }, /* ASGN */ 71 { 4, 2, 0 }, /* COMMA */ 72 { 0, 0, 0 }, /* SHARP */ 73 { 0, 0, 0 }, /* SEMIC */ 74 { 0, 0, 0 }, /* CBRA */ 75 { 0, 0, 0 }, /* CKET */ 76 { 0, 0, 0 }, /* ASPLUS */ 77 { 0, 0, 0 }, /* ASMINUS */ 78 { 0, 0, 0 }, /* ASSTAR */ 79 { 0, 0, 0 }, /* ASSLASH */ 80 { 0, 0, 0 }, /* ASPCT */ 81 { 0, 0, 0 }, /* ASCIRC */ 82 { 0, 0, 0 }, /* ASLSH */ 83 { 0, 0, 0 }, /* ASRSH */ 84 { 0, 0, 0 }, /* ASOR */ 85 { 0, 0, 0 }, /* ASAND */ 86 { 0, 0, 0 }, /* ELLIPS */ 87 { 0, 0, 0 }, /* DSHARP1 */ 88 { 0, 0, 0 }, /* NAME1 */ 89 { 16, 1, UNARY }, /* DEFINED */ 90 { 16, 0, UNARY }, /* UMINUS */ 91 }; 92 93 int evalop(struct pri); 94 struct value tokval(Token *); 95 struct value vals[NSTAK], *vp; 96 enum toktype ops[NSTAK], *op; 97 98 /* 99 * Evaluate an #if #elif #ifdef #ifndef line. trp->tp points to the keyword. 100 */ 101 long 102 eval(Tokenrow *trp, int kw) 103 { 104 Token *tp; 105 Nlist *np; 106 int ntok, rand; 107 108 trp->tp++; 109 if (kw==KIFDEF || kw==KIFNDEF) { 110 if (trp->lp - trp->bp != 4 || trp->tp->type!=NAME) { 111 error(ERROR, "Syntax error in #ifdef/#ifndef"); 112 return 0; 113 } 114 np = lookup(trp->tp, 0); 115 return (kw==KIFDEF) == (np && np->flag&(ISDEFINED|ISMAC)); 116 } 117 ntok = trp->tp - trp->bp; 118 kwdefined->val = KDEFINED; /* activate special meaning of defined */ 119 expandrow(trp, "<if>"); 120 kwdefined->val = NAME; 121 vp = vals; 122 op = ops; 123 *op++ = END; 124 for (rand=0, tp = trp->bp+ntok; tp < trp->lp; tp++) { 125 switch(tp->type) { 126 case WS: 127 case NL: 128 continue; 129 130 /* nilary */ 131 case NAME: 132 case NAME1: 133 case NUMBER: 134 case CCON: 135 case STRING: 136 if (rand) 137 goto syntax; 138 *vp++ = tokval(tp); 139 rand = 1; 140 continue; 141 142 /* unary */ 143 case DEFINED: 144 case TILDE: 145 case NOT: 146 if (rand) 147 goto syntax; 148 *op++ = tp->type; 149 continue; 150 151 /* unary-binary */ 152 case PLUS: case MINUS: case STAR: case AND: 153 if (rand==0) { 154 if (tp->type==MINUS) 155 *op++ = UMINUS; 156 if (tp->type==STAR || tp->type==AND) { 157 error(ERROR, "Illegal operator * or & in #if/#elsif"); 158 return 0; 159 } 160 continue; 161 } 162 /* flow through */ 163 164 /* plain binary */ 165 case EQ: case NEQ: case LEQ: case GEQ: case LSH: case RSH: 166 case LAND: case LOR: case SLASH: case PCT: 167 case LT: case GT: case CIRC: case OR: case QUEST: 168 case COLON: case COMMA: 169 if (rand==0) 170 goto syntax; 171 if (evalop(priority[tp->type])!=0) 172 return 0; 173 *op++ = tp->type; 174 rand = 0; 175 continue; 176 177 case LP: 178 if (rand) 179 goto syntax; 180 *op++ = LP; 181 continue; 182 183 case RP: 184 if (!rand) 185 goto syntax; 186 if (evalop(priority[RP])!=0) 187 return 0; 188 if (op<=ops || op[-1]!=LP) { 189 goto syntax; 190 } 191 op--; 192 continue; 193 194 default: 195 error(ERROR,"Bad operator (%t) in #if/#elsif", tp); 196 return 0; 197 } 198 } 199 if (rand==0) 200 goto syntax; 201 if (evalop(priority[END])!=0) 202 return 0; 203 if (op!=&ops[1] || vp!=&vals[1]) { 204 error(ERROR, "Botch in #if/#elsif"); 205 return 0; 206 } 207 if (vals[0].type==UND) 208 error(ERROR, "Undefined expression value"); 209 return vals[0].val; 210 syntax: 211 error(ERROR, "Syntax error in #if/#elsif"); 212 return 0; 213 } 214 215 int 216 evalop(struct pri pri) 217 { 218 struct value v1, v2; 219 long rv1, rv2; 220 int rtype, oper; 221 222 rv2=0; 223 rtype=0; 224 while (pri.pri < priority[op[-1]].pri) { 225 oper = *--op; 226 if (priority[oper].arity==2) { 227 v2 = *--vp; 228 rv2 = v2.val; 229 } 230 v1 = *--vp; 231 rv1 = v1.val; 232 switch (priority[oper].ctype) { 233 case 0: 234 default: 235 error(WARNING, "Syntax error in #if/#endif"); 236 return 1; 237 case ARITH: 238 case RELAT: 239 if (v1.type==UNS || v2.type==UNS) 240 rtype = UNS; 241 else 242 rtype = SGN; 243 if (v1.type==UND || v2.type==UND) 244 rtype = UND; 245 if (priority[oper].ctype==RELAT && rtype==UNS) { 246 oper |= UNSMARK; 247 rtype = SGN; 248 } 249 break; 250 case SHIFT: 251 if (v1.type==UND || v2.type==UND) 252 rtype = UND; 253 else 254 rtype = v1.type; 255 if (rtype==UNS) 256 oper |= UNSMARK; 257 break; 258 case UNARY: 259 rtype = v1.type; 260 break; 261 case LOGIC: 262 case SPCL: 263 break; 264 } 265 switch (oper) { 266 case EQ: case EQ|UNSMARK: 267 rv1 = rv1==rv2; break; 268 case NEQ: case NEQ|UNSMARK: 269 rv1 = rv1!=rv2; break; 270 case LEQ: 271 rv1 = rv1<=rv2; break; 272 case GEQ: 273 rv1 = rv1>=rv2; break; 274 case LT: 275 rv1 = rv1<rv2; break; 276 case GT: 277 rv1 = rv1>rv2; break; 278 case LEQ|UNSMARK: 279 rv1 = (unsigned long)rv1<=rv2; break; 280 case GEQ|UNSMARK: 281 rv1 = (unsigned long)rv1>=rv2; break; 282 case LT|UNSMARK: 283 rv1 = (unsigned long)rv1<rv2; break; 284 case GT|UNSMARK: 285 rv1 = (unsigned long)rv1>rv2; break; 286 case LSH: 287 rv1 <<= rv2; break; 288 case LSH|UNSMARK: 289 rv1 = (unsigned long)rv1<<rv2; break; 290 case RSH: 291 rv1 >>= rv2; break; 292 case RSH|UNSMARK: 293 rv1 = (unsigned long)rv1>>rv2; break; 294 case LAND: 295 rtype = UND; 296 if (v1.type==UND) 297 break; 298 if (rv1!=0) { 299 if (v2.type==UND) 300 break; 301 rv1 = rv2!=0; 302 } else 303 rv1 = 0; 304 rtype = SGN; 305 break; 306 case LOR: 307 rtype = UND; 308 if (v1.type==UND) 309 break; 310 if (rv1==0) { 311 if (v2.type==UND) 312 break; 313 rv1 = rv2!=0; 314 } else 315 rv1 = 1; 316 rtype = SGN; 317 break; 318 case AND: 319 rv1 &= rv2; break; 320 case STAR: 321 rv1 *= rv2; break; 322 case PLUS: 323 rv1 += rv2; break; 324 case MINUS: 325 rv1 -= rv2; break; 326 case UMINUS: 327 if (v1.type==UND) 328 rtype = UND; 329 rv1 = -rv1; break; 330 case OR: 331 rv1 |= rv2; break; 332 case CIRC: 333 rv1 ^= rv2; break; 334 case TILDE: 335 rv1 = ~rv1; break; 336 case NOT: 337 rv1 = !rv1; if (rtype!=UND) rtype = SGN; break; 338 case SLASH: 339 if (rv2==0) { 340 rtype = UND; 341 break; 342 } 343 if (rtype==UNS) 344 rv1 /= (unsigned long)rv2; 345 else 346 rv1 /= rv2; 347 break; 348 case PCT: 349 if (rv2==0) { 350 rtype = UND; 351 break; 352 } 353 if (rtype==UNS) 354 rv1 %= (unsigned long)rv2; 355 else 356 rv1 %= rv2; 357 break; 358 case COLON: 359 if (op[-1] != QUEST) 360 error(ERROR, "Bad ?: in #if/endif"); 361 else { 362 op--; 363 if ((--vp)->val==0) 364 v1 = v2; 365 rtype = v1.type; 366 rv1 = v1.val; 367 } 368 break; 369 case DEFINED: 370 break; 371 default: 372 error(ERROR, "Eval botch (unknown operator)"); 373 return 1; 374 } 375 v1.val = rv1; 376 v1.type = rtype; 377 *vp++ = v1; 378 } 379 return 0; 380 } 381 382 struct value 383 tokval(Token *tp) 384 { 385 struct value v; 386 Nlist *np; 387 int i, base, c, longcc; 388 unsigned long n; 389 Rune r; 390 uchar *p; 391 392 v.type = SGN; 393 v.val = 0; 394 switch (tp->type) { 395 396 case NAME: 397 v.val = 0; 398 break; 399 400 case NAME1: 401 if ((np = lookup(tp, 0)) && np->flag&(ISDEFINED|ISMAC)) 402 v.val = 1; 403 break; 404 405 case NUMBER: 406 n = 0; 407 base = 10; 408 p = tp->t; 409 c = p[tp->len]; 410 p[tp->len] = '\0'; 411 if (*p=='0') { 412 base = 8; 413 if (p[1]=='x' || p[1]=='X') { 414 base = 16; 415 p++; 416 } 417 p++; 418 } 419 for (;; p++) { 420 if ((i = digit(*p)) < 0) 421 break; 422 if (i>=base) 423 error(WARNING, 424 "Bad digit in number %t", tp); 425 n *= base; 426 n += i; 427 } 428 if (n>=0x80000000 && base!=10) 429 v.type = UNS; 430 for (; *p; p++) { 431 if (*p=='u' || *p=='U') 432 v.type = UNS; 433 else if (*p=='l' || *p=='L') 434 ; 435 else { 436 error(ERROR, 437 "Bad number %t in #if/#elsif", tp); 438 break; 439 } 440 } 441 v.val = n; 442 tp->t[tp->len] = c; 443 break; 444 445 case CCON: 446 n = 0; 447 p = tp->t; 448 longcc = 0; 449 if (*p=='L') { 450 p += 1; 451 longcc = 1; 452 } 453 p += 1; 454 if (*p=='\\') { 455 p += 1; 456 if ((i = digit(*p))>=0 && i<=7) { 457 n = i; 458 p += 1; 459 if ((i = digit(*p))>=0 && i<=7) { 460 p += 1; 461 n <<= 3; 462 n += i; 463 if ((i = digit(*p))>=0 && i<=7) { 464 p += 1; 465 n <<= 3; 466 n += i; 467 } 468 } 469 } else if (*p=='x') { 470 p += 1; 471 while ((i = digit(*p))>=0 && i<=15) { 472 p += 1; 473 n <<= 4; 474 n += i; 475 } 476 } else { 477 static char cvcon[] 478 = "a\ab\bf\fn\nr\rt\tv\v''\"\"??\\\\"; 479 for (i=0; i<sizeof(cvcon); i+=2) { 480 if (*p == cvcon[i]) { 481 n = cvcon[i+1]; 482 break; 483 } 484 } 485 p += 1; 486 if (i>=sizeof(cvcon)) 487 error(WARNING, 488 "Undefined escape in character constant"); 489 } 490 } else if (*p=='\'') 491 error(ERROR, "Empty character constant"); 492 else { 493 i = chartorune(&r, (char*)p); 494 n = r; 495 p += i; 496 if (i>1 && longcc==0) 497 error(WARNING, "Undefined character constant"); 498 } 499 if (*p!='\'') 500 error(WARNING, "Multibyte character constant undefined"); 501 else if (n>127 && longcc==0) 502 error(WARNING, "Character constant taken as not signed"); 503 v.val = n; 504 break; 505 506 case STRING: 507 error(ERROR, "String in #if/#elsif"); 508 break; 509 } 510 return v; 511 } 512 513 int 514 digit(int i) 515 { 516 if ('0'<=i && i<='9') 517 i -= '0'; 518 else if ('a'<=i && i<='f') 519 i -= 'a'-10; 520 else if ('A'<=i && i<='F') 521 i -= 'A'-10; 522 else 523 i = -1; 524 return i; 525 } 526