PageRenderTime 53ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/src/wml_backend/p4_gm4/src/eval.c

https://bitbucket.org/shlomif/website-meta-language
C | 774 lines | 605 code | 133 blank | 36 comment | 217 complexity | 7d0948d94c0c24a3ab79a8b079f85973 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0, LGPL-2.0
  1. /* GNU m4 -- A simple macro processor
  2. Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2, or (at your option)
  6. any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. /* This file contains the functions to evaluate integer expressions for
  16. the "eval" macro. It is a little, fairly self-contained module, with
  17. its own scanner, and a recursive descent parser. The only entry point
  18. is evaluate (). */
  19. #include "m4.h"
  20. /* Evaluates token types. */
  21. typedef enum eval_token
  22. {
  23. ERROR,
  24. PLUS, MINUS,
  25. EXPONENT,
  26. TIMES, DIVIDE, MODULO,
  27. EQ, NOTEQ, GT, GTEQ, LS, LSEQ,
  28. LSHIFT, RSHIFT,
  29. LNOT, LAND, LOR,
  30. NOT, AND, OR, XOR,
  31. LEFTP, RIGHTP,
  32. NUMBER, EOTEXT
  33. }
  34. eval_token;
  35. /* Error types. */
  36. typedef enum eval_error
  37. {
  38. NO_ERROR,
  39. MISSING_RIGHT,
  40. SYNTAX_ERROR,
  41. UNKNOWN_INPUT,
  42. EXCESS_INPUT,
  43. DIVIDE_ZERO,
  44. MODULO_ZERO
  45. }
  46. eval_error;
  47. static eval_error logical_or_term _((eval_token, eval_t *));
  48. static eval_error logical_and_term _((eval_token, eval_t *));
  49. static eval_error or_term _((eval_token, eval_t *));
  50. static eval_error xor_term _((eval_token, eval_t *));
  51. static eval_error and_term _((eval_token, eval_t *));
  52. static eval_error not_term _((eval_token, eval_t *));
  53. static eval_error logical_not_term _((eval_token, eval_t *));
  54. static eval_error cmp_term _((eval_token, eval_t *));
  55. static eval_error shift_term _((eval_token, eval_t *));
  56. static eval_error add_term _((eval_token, eval_t *));
  57. static eval_error mult_term _((eval_token, eval_t *));
  58. static eval_error exp_term _((eval_token, eval_t *));
  59. static eval_error unary_term _((eval_token, eval_t *));
  60. static eval_error simple_term _((eval_token, eval_t *));
  61. /*--------------------.
  62. | Lexical functions. |
  63. `--------------------*/
  64. /* Pointer to next character of input text. */
  65. static const char *eval_text;
  66. /* Value of eval_text, from before last call of eval_lex (). This is so we
  67. can back up, if we have read too much. */
  68. static const char *last_text;
  69. static void
  70. eval_init_lex (const char *text)
  71. {
  72. eval_text = text;
  73. last_text = NULL;
  74. }
  75. static void
  76. eval_undo (void)
  77. {
  78. eval_text = last_text;
  79. }
  80. /* VAL is numerical value, if any. */
  81. static eval_token
  82. eval_lex (eval_t *val)
  83. {
  84. while (isspace (*eval_text))
  85. eval_text++;
  86. last_text = eval_text;
  87. if (*eval_text == '\0')
  88. return EOTEXT;
  89. if (isdigit (*eval_text))
  90. {
  91. int base, digit;
  92. if (*eval_text == '0')
  93. {
  94. eval_text++;
  95. switch (*eval_text)
  96. {
  97. case 'x':
  98. case 'X':
  99. base = 16;
  100. eval_text++;
  101. break;
  102. case 'b':
  103. case 'B':
  104. base = 2;
  105. eval_text++;
  106. break;
  107. case 'r':
  108. case 'R':
  109. base = 0;
  110. eval_text++;
  111. while (isdigit (*eval_text) && base <= 36)
  112. base = 10 * base + *eval_text++ - '0';
  113. if (base == 0 || base > 36 || *eval_text != ':')
  114. return ERROR;
  115. eval_text++;
  116. break;
  117. default:
  118. base = 8;
  119. }
  120. }
  121. else
  122. base = 10;
  123. (*val) = 0;
  124. for (; *eval_text; eval_text++)
  125. {
  126. if (isdigit (*eval_text))
  127. digit = *eval_text - '0';
  128. else if (islower (*eval_text))
  129. digit = *eval_text - 'a' + 10;
  130. else if (isupper (*eval_text))
  131. digit = *eval_text - 'A' + 10;
  132. else
  133. break;
  134. if (digit >= base)
  135. break;
  136. (*val) = (*val) * base + digit;
  137. }
  138. return NUMBER;
  139. }
  140. switch (*eval_text++)
  141. {
  142. case '+':
  143. return PLUS;
  144. case '-':
  145. return MINUS;
  146. case '*':
  147. if (*eval_text == '*')
  148. {
  149. eval_text++;
  150. return EXPONENT;
  151. }
  152. else
  153. return TIMES;
  154. case '/':
  155. return DIVIDE;
  156. case '%':
  157. return MODULO;
  158. case '=':
  159. if (*eval_text == '=')
  160. eval_text++;
  161. return EQ;
  162. case '!':
  163. if (*eval_text == '=')
  164. {
  165. eval_text++;
  166. return NOTEQ;
  167. }
  168. else
  169. return LNOT;
  170. case '>':
  171. if (*eval_text == '=')
  172. {
  173. eval_text++;
  174. return GTEQ;
  175. }
  176. else if (*eval_text == '>')
  177. {
  178. eval_text++;
  179. return RSHIFT;
  180. }
  181. else
  182. return GT;
  183. case '<':
  184. if (*eval_text == '=')
  185. {
  186. eval_text++;
  187. return LSEQ;
  188. }
  189. else if (*eval_text == '<')
  190. {
  191. eval_text++;
  192. return LSHIFT;
  193. }
  194. else
  195. return LS;
  196. case '^':
  197. return XOR;
  198. case '~':
  199. return NOT;
  200. case '&':
  201. if (*eval_text == '&')
  202. {
  203. eval_text++;
  204. return LAND;
  205. }
  206. else
  207. return AND;
  208. case '|':
  209. if (*eval_text == '|')
  210. {
  211. eval_text++;
  212. return LOR;
  213. }
  214. else
  215. return OR;
  216. case '(':
  217. return LEFTP;
  218. case ')':
  219. return RIGHTP;
  220. default:
  221. return ERROR;
  222. }
  223. }
  224. /*---------------------------------------.
  225. | Main entry point, called from "eval". |
  226. `---------------------------------------*/
  227. boolean
  228. evaluate (const char *expr, eval_t *val)
  229. {
  230. eval_token et;
  231. eval_error err;
  232. eval_init_lex (expr);
  233. et = eval_lex (val);
  234. err = logical_or_term (et, val);
  235. if (err == NO_ERROR && *eval_text != '\0')
  236. err = EXCESS_INPUT;
  237. switch (err)
  238. {
  239. case NO_ERROR:
  240. break;
  241. case MISSING_RIGHT:
  242. M4ERROR ((warning_status, 0,
  243. "Bad expression in eval (missing right parenthesis): %s",
  244. expr));
  245. break;
  246. case SYNTAX_ERROR:
  247. M4ERROR ((warning_status, 0,
  248. "Bad expression in eval: %s", expr));
  249. break;
  250. case UNKNOWN_INPUT:
  251. M4ERROR ((warning_status, 0,
  252. "Bad expression in eval (bad input): %s", expr));
  253. break;
  254. case EXCESS_INPUT:
  255. M4ERROR ((warning_status, 0,
  256. "Bad expression in eval (excess input): %s", expr));
  257. break;
  258. case DIVIDE_ZERO:
  259. M4ERROR ((warning_status, 0,
  260. "Divide by zero in eval: %s", expr));
  261. break;
  262. case MODULO_ZERO:
  263. M4ERROR ((warning_status, 0,
  264. "Modulo by zero in eval: %s", expr));
  265. break;
  266. default:
  267. M4ERROR ((warning_status, 0,
  268. "INTERNAL ERROR: Bad error code in evaluate ()"));
  269. abort ();
  270. }
  271. return (boolean) (err != NO_ERROR);
  272. }
  273. /*---------------------------.
  274. | Recursive descent parser. |
  275. `---------------------------*/
  276. static eval_error
  277. logical_or_term (eval_token et, eval_t *v1)
  278. {
  279. eval_t v2;
  280. eval_error er;
  281. if ((er = logical_and_term (et, v1)) != NO_ERROR)
  282. return er;
  283. while ((et = eval_lex (&v2)) == LOR)
  284. {
  285. et = eval_lex (&v2);
  286. if (et == ERROR)
  287. return UNKNOWN_INPUT;
  288. if ((er = logical_and_term (et, &v2)) != NO_ERROR)
  289. return er;
  290. *v1 = *v1 || v2;
  291. }
  292. if (et == ERROR)
  293. return UNKNOWN_INPUT;
  294. eval_undo ();
  295. return NO_ERROR;
  296. }
  297. static eval_error
  298. logical_and_term (eval_token et, eval_t *v1)
  299. {
  300. eval_t v2;
  301. eval_error er;
  302. if ((er = or_term (et, v1)) != NO_ERROR)
  303. return er;
  304. while ((et = eval_lex (&v2)) == LAND)
  305. {
  306. et = eval_lex (&v2);
  307. if (et == ERROR)
  308. return UNKNOWN_INPUT;
  309. if ((er = or_term (et, &v2)) != NO_ERROR)
  310. return er;
  311. *v1 = *v1 && v2;
  312. }
  313. if (et == ERROR)
  314. return UNKNOWN_INPUT;
  315. eval_undo ();
  316. return NO_ERROR;
  317. }
  318. static eval_error
  319. or_term (eval_token et, eval_t *v1)
  320. {
  321. eval_t v2;
  322. eval_error er;
  323. if ((er = xor_term (et, v1)) != NO_ERROR)
  324. return er;
  325. while ((et = eval_lex (&v2)) == OR)
  326. {
  327. et = eval_lex (&v2);
  328. if (et == ERROR)
  329. return UNKNOWN_INPUT;
  330. if ((er = xor_term (et, &v2)) != NO_ERROR)
  331. return er;
  332. *v1 = *v1 | v2;
  333. }
  334. if (et == ERROR)
  335. return UNKNOWN_INPUT;
  336. eval_undo ();
  337. return NO_ERROR;
  338. }
  339. static eval_error
  340. xor_term (eval_token et, eval_t *v1)
  341. {
  342. eval_t v2;
  343. eval_error er;
  344. if ((er = and_term (et, v1)) != NO_ERROR)
  345. return er;
  346. while ((et = eval_lex (&v2)) == XOR)
  347. {
  348. et = eval_lex (&v2);
  349. if (et == ERROR)
  350. return UNKNOWN_INPUT;
  351. if ((er = and_term (et, &v2)) != NO_ERROR)
  352. return er;
  353. *v1 = *v1 ^ v2;
  354. }
  355. if (et == ERROR)
  356. return UNKNOWN_INPUT;
  357. eval_undo ();
  358. return NO_ERROR;
  359. }
  360. static eval_error
  361. and_term (eval_token et, eval_t *v1)
  362. {
  363. eval_t v2;
  364. eval_error er;
  365. if ((er = not_term (et, v1)) != NO_ERROR)
  366. return er;
  367. while ((et = eval_lex (&v2)) == AND)
  368. {
  369. et = eval_lex (&v2);
  370. if (et == ERROR)
  371. return UNKNOWN_INPUT;
  372. if ((er = not_term (et, &v2)) != NO_ERROR)
  373. return er;
  374. *v1 = *v1 & v2;
  375. }
  376. if (et == ERROR)
  377. return UNKNOWN_INPUT;
  378. eval_undo ();
  379. return NO_ERROR;
  380. }
  381. static eval_error
  382. not_term (eval_token et, eval_t *v1)
  383. {
  384. eval_error er;
  385. if (et == NOT)
  386. {
  387. et = eval_lex (v1);
  388. if (et == ERROR)
  389. return UNKNOWN_INPUT;
  390. if ((er = not_term (et, v1)) != NO_ERROR)
  391. return er;
  392. *v1 = ~*v1;
  393. }
  394. else
  395. if ((er = logical_not_term (et, v1)) != NO_ERROR)
  396. return er;
  397. return NO_ERROR;
  398. }
  399. static eval_error
  400. logical_not_term (eval_token et, eval_t *v1)
  401. {
  402. eval_error er;
  403. if (et == LNOT)
  404. {
  405. et = eval_lex (v1);
  406. if (et == ERROR)
  407. return UNKNOWN_INPUT;
  408. if ((er = logical_not_term (et, v1)) != NO_ERROR)
  409. return er;
  410. *v1 = !*v1;
  411. }
  412. else
  413. if ((er = cmp_term (et, v1)) != NO_ERROR)
  414. return er;
  415. return NO_ERROR;
  416. }
  417. static eval_error
  418. cmp_term (eval_token et, eval_t *v1)
  419. {
  420. eval_token op;
  421. eval_t v2;
  422. eval_error er;
  423. if ((er = shift_term (et, v1)) != NO_ERROR)
  424. return er;
  425. while ((op = eval_lex (&v2)) == EQ || op == NOTEQ
  426. || op == GT || op == GTEQ
  427. || op == LS || op == LSEQ)
  428. {
  429. et = eval_lex (&v2);
  430. if (et == ERROR)
  431. return UNKNOWN_INPUT;
  432. if ((er = shift_term (et, &v2)) != NO_ERROR)
  433. return er;
  434. switch (op)
  435. {
  436. case EQ:
  437. *v1 = *v1 == v2;
  438. break;
  439. case NOTEQ:
  440. *v1 = *v1 != v2;
  441. break;
  442. case GT:
  443. *v1 = *v1 > v2;
  444. break;
  445. case GTEQ:
  446. *v1 = *v1 >= v2;
  447. break;
  448. case LS:
  449. *v1 = *v1 < v2;
  450. break;
  451. case LSEQ:
  452. *v1 = *v1 <= v2;
  453. break;
  454. default:
  455. M4ERROR ((warning_status, 0,
  456. "INTERNAL ERROR: Bad comparison operator in cmp_term ()"));
  457. abort ();
  458. }
  459. }
  460. if (op == ERROR)
  461. return UNKNOWN_INPUT;
  462. eval_undo ();
  463. return NO_ERROR;
  464. }
  465. static eval_error
  466. shift_term (eval_token et, eval_t *v1)
  467. {
  468. eval_token op;
  469. eval_t v2;
  470. eval_error er;
  471. if ((er = add_term (et, v1)) != NO_ERROR)
  472. return er;
  473. while ((op = eval_lex (&v2)) == LSHIFT || op == RSHIFT)
  474. {
  475. et = eval_lex (&v2);
  476. if (et == ERROR)
  477. return UNKNOWN_INPUT;
  478. if ((er = add_term (et, &v2)) != NO_ERROR)
  479. return er;
  480. switch (op)
  481. {
  482. case LSHIFT:
  483. *v1 = *v1 << v2;
  484. break;
  485. case RSHIFT:
  486. *v1 = *v1 >> v2;
  487. break;
  488. default:
  489. M4ERROR ((warning_status, 0,
  490. "INTERNAL ERROR: Bad shift operator in shift_term ()"));
  491. abort ();
  492. }
  493. }
  494. if (op == ERROR)
  495. return UNKNOWN_INPUT;
  496. eval_undo ();
  497. return NO_ERROR;
  498. }
  499. static eval_error
  500. add_term (eval_token et, eval_t *v1)
  501. {
  502. eval_token op;
  503. eval_t v2;
  504. eval_error er;
  505. if ((er = mult_term (et, v1)) != NO_ERROR)
  506. return er;
  507. while ((op = eval_lex (&v2)) == PLUS || op == MINUS)
  508. {
  509. et = eval_lex (&v2);
  510. if (et == ERROR)
  511. return UNKNOWN_INPUT;
  512. if ((er = mult_term (et, &v2)) != NO_ERROR)
  513. return er;
  514. if (op == PLUS)
  515. *v1 = *v1 + v2;
  516. else
  517. *v1 = *v1 - v2;
  518. }
  519. if (op == ERROR)
  520. return UNKNOWN_INPUT;
  521. eval_undo ();
  522. return NO_ERROR;
  523. }
  524. static eval_error
  525. mult_term (eval_token et, eval_t *v1)
  526. {
  527. eval_token op;
  528. eval_t v2;
  529. eval_error er;
  530. if ((er = exp_term (et, v1)) != NO_ERROR)
  531. return er;
  532. while ((op = eval_lex (&v2)) == TIMES || op == DIVIDE || op == MODULO)
  533. {
  534. et = eval_lex (&v2);
  535. if (et == ERROR)
  536. return UNKNOWN_INPUT;
  537. if ((er = exp_term (et, &v2)) != NO_ERROR)
  538. return er;
  539. switch (op)
  540. {
  541. case TIMES:
  542. *v1 = *v1 * v2;
  543. break;
  544. case DIVIDE:
  545. if (v2 == 0)
  546. return DIVIDE_ZERO;
  547. else
  548. *v1 = *v1 / v2;
  549. break;
  550. case MODULO:
  551. if (v2 == 0)
  552. return MODULO_ZERO;
  553. else
  554. *v1 = *v1 % v2;
  555. break;
  556. default:
  557. M4ERROR ((warning_status, 0,
  558. "INTERNAL ERROR: Bad operator in mult_term ()"));
  559. abort ();
  560. }
  561. }
  562. if (op == ERROR)
  563. return UNKNOWN_INPUT;
  564. eval_undo ();
  565. return NO_ERROR;
  566. }
  567. static eval_error
  568. exp_term (eval_token et, eval_t *v1)
  569. {
  570. register eval_t result;
  571. eval_t v2;
  572. eval_error er;
  573. if ((er = unary_term (et, v1)) != NO_ERROR)
  574. return er;
  575. result = *v1;
  576. while ((et = eval_lex (&v2)) == EXPONENT)
  577. {
  578. et = eval_lex (&v2);
  579. if (et == ERROR)
  580. return UNKNOWN_INPUT;
  581. if ((er = exp_term (et, &v2)) != NO_ERROR)
  582. return er;
  583. result = 1;
  584. while (v2-- > 0)
  585. result *= *v1;
  586. *v1 = result;
  587. }
  588. if (et == ERROR)
  589. return UNKNOWN_INPUT;
  590. eval_undo ();
  591. return NO_ERROR;
  592. }
  593. static eval_error
  594. unary_term (eval_token et, eval_t *v1)
  595. {
  596. eval_token et2 = et;
  597. eval_error er;
  598. if (et == PLUS || et == MINUS)
  599. {
  600. et2 = eval_lex (v1);
  601. if (et2 == ERROR)
  602. return UNKNOWN_INPUT;
  603. if ((er = simple_term (et2, v1)) != NO_ERROR)
  604. return er;
  605. if (et == MINUS)
  606. *v1 = -*v1;
  607. }
  608. else
  609. if ((er = simple_term (et, v1)) != NO_ERROR)
  610. return er;
  611. return NO_ERROR;
  612. }
  613. static eval_error
  614. simple_term (eval_token et, eval_t *v1)
  615. {
  616. eval_t v2;
  617. eval_error er;
  618. switch (et)
  619. {
  620. case LEFTP:
  621. et = eval_lex (v1);
  622. if (et == ERROR)
  623. return UNKNOWN_INPUT;
  624. if ((er = logical_or_term (et, v1)) != NO_ERROR)
  625. return er;
  626. et = eval_lex (&v2);
  627. if (et == ERROR)
  628. return UNKNOWN_INPUT;
  629. if (et != RIGHTP)
  630. return MISSING_RIGHT;
  631. break;
  632. case NUMBER:
  633. break;
  634. default:
  635. return SYNTAX_ERROR;
  636. }
  637. return NO_ERROR;
  638. }