eval.c 9.7 KB

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