10 #define UNSMARK 0x1000
17 /* conversion types */
25 /* operator priority, arity, and conversion type, indexed by tokentype */
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 */
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 */
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 */
93 int evalop(struct pri);
94 struct value tokval(Token *);
95 struct value vals[NSTAK], *vp;
96 enum toktype ops[NSTAK], *op;
99 * Evaluate an #if #elif #ifdef #ifndef line. trp->tp points to the keyword.
102 eval(Tokenrow *trp, int kw)
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");
114 np = lookup(trp->tp, 0);
115 return (kw==KIFDEF) == (np && np->flag&(ISDEFINED|ISMAC));
117 ntok = trp->tp - trp->bp;
118 kwdefined->val = KDEFINED; /* activate special meaning of defined */
119 expandrow(trp, "<if>");
120 kwdefined->val = NAME;
124 for (rand=0, tp = trp->bp+ntok; tp < trp->lp; tp++) {
152 case PLUS: case MINUS: case STAR: case AND:
156 if (tp->type==STAR || tp->type==AND) {
157 error(ERROR, "Illegal operator * or & in #if/#elsif");
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:
171 if (evalop(priority[tp->type])!=0)
186 if (evalop(priority[RP])!=0)
188 if (op<=ops || op[-1]!=LP) {
195 error(ERROR,"Bad operator (%t) in #if/#elsif", tp);
201 if (evalop(priority[END])!=0)
203 if (op!=&ops[1] || vp!=&vals[1]) {
204 error(ERROR, "Botch in #if/#elsif");
207 if (vals[0].type==UND)
208 error(ERROR, "Undefined expression value");
211 error(ERROR, "Syntax error in #if/#elsif");
216 evalop(struct pri pri)
222 /* prevent compiler whining. */
224 v1.type = v2.type = 0;
228 while (pri.pri < priority[op[-1]].pri) {
230 if (priority[oper].arity==2) {
236 /*lint -e574 -e644 */
237 switch (priority[oper].ctype) {
240 error(WARNING, "Syntax error in #if/#endif");
244 if (v1.type==UNS || v2.type==UNS)
248 if (v1.type==UND || v2.type==UND)
250 if (priority[oper].ctype==RELAT && rtype==UNS) {
256 if (v1.type==UND || v2.type==UND)
271 case EQ: case EQ|UNSMARK:
272 rv1 = rv1==rv2; break;
273 case NEQ: case NEQ|UNSMARK:
274 rv1 = rv1!=rv2; break;
276 rv1 = rv1<=rv2; break;
278 rv1 = rv1>=rv2; break;
280 rv1 = rv1<rv2; break;
282 rv1 = rv1>rv2; break;
284 rv1 = (unsigned long)rv1<=rv2; break;
286 rv1 = (unsigned long)rv1>=rv2; break;
288 rv1 = (unsigned long)rv1<rv2; break;
290 rv1 = (unsigned long)rv1>rv2; break;
294 rv1 = (unsigned long)rv1<<rv2; break;
298 rv1 = (unsigned long)rv1>>rv2; break;
342 rv1 = !rv1; if (rtype!=UND) rtype = SGN; break;
349 rv1 /= (unsigned long)rv2;
359 rv1 %= (unsigned long)rv2;
365 error(ERROR, "Bad ?: in #if/endif");
377 error(ERROR, "Eval botch (unknown operator)");
380 /*lint +e574 +e644 */
406 if ((np = lookup(tp, 0)) != NULL && np->flag&(ISDEFINED|ISMAC))
418 if (p[1]=='x' || p[1]=='X') {
425 if ((i = digit(*p)) < 0)
429 "Bad digit in number %t", tp);
433 if (n>=0x80000000 && base!=10)
436 if (*p=='u' || *p=='U')
438 else if (*p=='l' || *p=='L')
442 "Bad number %t in #if/#elsif", tp);
455 error(WARNING, "Wide char constant value undefined");
460 if ((i = digit(*p))>=0 && i<=7) {
463 if ((i = digit(*p))>=0 && i<=7) {
467 if ((i = digit(*p))>=0 && i<=7) {
473 } else if (*p=='x') {
475 while ((i = digit(*p))>=0 && i<=15) {
482 = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\";
483 for (i=0; i<sizeof(cvcon); i+=2) {
484 if (*p == cvcon[i]) {
490 if (i>=sizeof(cvcon))
492 "Undefined escape in character constant");
495 error(ERROR, "Empty character constant");
499 error(WARNING, "Multibyte character constant undefined");
501 error(WARNING, "Character constant taken as not signed");
506 error(ERROR, "String in #if/#elsif");
515 if ('0'<=i && i<='9')
517 else if ('a'<=i && i<='f')
519 else if ('A'<=i && i<='F')