nasm-eval.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. /* eval.c expression evaluator for the Netwide Assembler
  2. *
  3. * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
  4. * Julian Hall. All rights reserved. The software is
  5. * redistributable under the licence given in the file "Licence"
  6. * distributed in the NASM archive.
  7. *
  8. * initial version 27/iii/95 by Simon Tatham
  9. */
  10. #include <util.h>
  11. #include <libyasm-stdint.h>
  12. #include <libyasm/coretype.h>
  13. #include <libyasm/intnum.h>
  14. #include <libyasm/expr.h>
  15. #include <libyasm/symrec.h>
  16. #include <ctype.h>
  17. #include "nasm.h"
  18. #include "nasmlib.h"
  19. #include "nasm-eval.h"
  20. /* The assembler symbol table. */
  21. extern yasm_symtab *nasm_symtab;
  22. static scanner scan; /* Address of scanner routine */
  23. static efunc error; /* Address of error reporting routine */
  24. static struct tokenval *tokval; /* The current token */
  25. static int i; /* The t_type of tokval */
  26. static void *scpriv;
  27. /*
  28. * Recursive-descent parser. Called with a single boolean operand,
  29. * which is TRUE if the evaluation is critical (i.e. unresolved
  30. * symbols are an error condition). Must update the global `i' to
  31. * reflect the token after the parsed string. May return NULL.
  32. *
  33. * evaluate() should report its own errors: on return it is assumed
  34. * that if NULL has been returned, the error has already been
  35. * reported.
  36. */
  37. /*
  38. * Grammar parsed is:
  39. *
  40. * expr : bexpr [ WRT expr6 ]
  41. * bexpr : rexp0 or expr0 depending on relative-mode setting
  42. * rexp0 : rexp1 [ {||} rexp1...]
  43. * rexp1 : rexp2 [ {^^} rexp2...]
  44. * rexp2 : rexp3 [ {&&} rexp3...]
  45. * rexp3 : expr0 [ {=,==,<>,!=,<,>,<=,>=} expr0 ]
  46. * expr0 : expr1 [ {|} expr1...]
  47. * expr1 : expr2 [ {^} expr2...]
  48. * expr2 : expr3 [ {&} expr3...]
  49. * expr3 : expr4 [ {<<,>>} expr4...]
  50. * expr4 : expr5 [ {+,-} expr5...]
  51. * expr5 : expr6 [ {*,/,%,//,%%} expr6...]
  52. * expr6 : { ~,+,-,SEG } expr6
  53. * | (bexpr)
  54. * | symbol
  55. * | $
  56. * | number
  57. */
  58. static yasm_expr *rexp0(void), *rexp1(void), *rexp2(void), *rexp3(void);
  59. static yasm_expr *expr0(void), *expr1(void), *expr2(void), *expr3(void);
  60. static yasm_expr *expr4(void), *expr5(void), *expr6(void);
  61. static yasm_expr *(*bexpr)(void);
  62. static yasm_expr *rexp0(void)
  63. {
  64. yasm_expr *e, *f;
  65. e = rexp1();
  66. if (!e)
  67. return NULL;
  68. while (i == TOKEN_DBL_OR)
  69. {
  70. i = scan(scpriv, tokval);
  71. f = rexp1();
  72. if (!f) {
  73. yasm_expr_destroy(e);
  74. return NULL;
  75. }
  76. e = yasm_expr_create_tree(e, YASM_EXPR_LOR, f, 0);
  77. }
  78. return e;
  79. }
  80. static yasm_expr *rexp1(void)
  81. {
  82. yasm_expr *e, *f;
  83. e = rexp2();
  84. if (!e)
  85. return NULL;
  86. while (i == TOKEN_DBL_XOR)
  87. {
  88. i = scan(scpriv, tokval);
  89. f = rexp2();
  90. if (!f) {
  91. yasm_expr_destroy(e);
  92. return NULL;
  93. }
  94. e = yasm_expr_create_tree(e, YASM_EXPR_LXOR, f, 0);
  95. }
  96. return e;
  97. }
  98. static yasm_expr *rexp2(void)
  99. {
  100. yasm_expr *e, *f;
  101. e = rexp3();
  102. if (!e)
  103. return NULL;
  104. while (i == TOKEN_DBL_AND)
  105. {
  106. i = scan(scpriv, tokval);
  107. f = rexp3();
  108. if (!f) {
  109. yasm_expr_destroy(e);
  110. return NULL;
  111. }
  112. e = yasm_expr_create_tree(e, YASM_EXPR_LAND, f, 0);
  113. }
  114. return e;
  115. }
  116. static yasm_expr *rexp3(void)
  117. {
  118. yasm_expr *e, *f;
  119. e = expr0();
  120. if (!e)
  121. return NULL;
  122. while (i == TOKEN_EQ || i == TOKEN_LT || i == TOKEN_GT ||
  123. i == TOKEN_NE || i == TOKEN_LE || i == TOKEN_GE)
  124. {
  125. int j = i;
  126. i = scan(scpriv, tokval);
  127. f = expr0();
  128. if (!f) {
  129. yasm_expr_destroy(e);
  130. return NULL;
  131. }
  132. switch (j)
  133. {
  134. case TOKEN_EQ:
  135. e = yasm_expr_create_tree(e, YASM_EXPR_EQ, f, 0);
  136. break;
  137. case TOKEN_LT:
  138. e = yasm_expr_create_tree(e, YASM_EXPR_LT, f, 0);
  139. break;
  140. case TOKEN_GT:
  141. e = yasm_expr_create_tree(e, YASM_EXPR_GT, f, 0);
  142. break;
  143. case TOKEN_NE:
  144. e = yasm_expr_create_tree(e, YASM_EXPR_NE, f, 0);
  145. break;
  146. case TOKEN_LE:
  147. e = yasm_expr_create_tree(e, YASM_EXPR_LE, f, 0);
  148. break;
  149. case TOKEN_GE:
  150. e = yasm_expr_create_tree(e, YASM_EXPR_GE, f, 0);
  151. break;
  152. }
  153. }
  154. return e;
  155. }
  156. static yasm_expr *expr0(void)
  157. {
  158. yasm_expr *e, *f;
  159. e = expr1();
  160. if (!e)
  161. return NULL;
  162. while (i == '|')
  163. {
  164. i = scan(scpriv, tokval);
  165. f = expr1();
  166. if (!f) {
  167. yasm_expr_destroy(e);
  168. return NULL;
  169. }
  170. e = yasm_expr_create_tree(e, YASM_EXPR_OR, f, 0);
  171. }
  172. return e;
  173. }
  174. static yasm_expr *expr1(void)
  175. {
  176. yasm_expr *e, *f;
  177. e = expr2();
  178. if (!e)
  179. return NULL;
  180. while (i == '^') {
  181. i = scan(scpriv, tokval);
  182. f = expr2();
  183. if (!f) {
  184. yasm_expr_destroy(e);
  185. return NULL;
  186. }
  187. e = yasm_expr_create_tree(e, YASM_EXPR_XOR, f, 0);
  188. }
  189. return e;
  190. }
  191. static yasm_expr *expr2(void)
  192. {
  193. yasm_expr *e, *f;
  194. e = expr3();
  195. if (!e)
  196. return NULL;
  197. while (i == '&') {
  198. i = scan(scpriv, tokval);
  199. f = expr3();
  200. if (!f) {
  201. yasm_expr_destroy(e);
  202. return NULL;
  203. }
  204. e = yasm_expr_create_tree(e, YASM_EXPR_AND, f, 0);
  205. }
  206. return e;
  207. }
  208. static yasm_expr *expr3(void)
  209. {
  210. yasm_expr *e, *f;
  211. e = expr4();
  212. if (!e)
  213. return NULL;
  214. while (i == TOKEN_SHL || i == TOKEN_SHR)
  215. {
  216. int j = i;
  217. i = scan(scpriv, tokval);
  218. f = expr4();
  219. if (!f) {
  220. yasm_expr_destroy(e);
  221. return NULL;
  222. }
  223. switch (j) {
  224. case TOKEN_SHL:
  225. e = yasm_expr_create_tree(e, YASM_EXPR_SHL, f, 0);
  226. break;
  227. case TOKEN_SHR:
  228. e = yasm_expr_create_tree(e, YASM_EXPR_SHR, f, 0);
  229. break;
  230. }
  231. }
  232. return e;
  233. }
  234. static yasm_expr *expr4(void)
  235. {
  236. yasm_expr *e, *f;
  237. e = expr5();
  238. if (!e)
  239. return NULL;
  240. while (i == '+' || i == '-')
  241. {
  242. int j = i;
  243. i = scan(scpriv, tokval);
  244. f = expr5();
  245. if (!f) {
  246. yasm_expr_destroy(e);
  247. return NULL;
  248. }
  249. switch (j) {
  250. case '+':
  251. e = yasm_expr_create_tree(e, YASM_EXPR_ADD, f, 0);
  252. break;
  253. case '-':
  254. e = yasm_expr_create_tree(e, YASM_EXPR_SUB, f, 0);
  255. break;
  256. }
  257. }
  258. return e;
  259. }
  260. static yasm_expr *expr5(void)
  261. {
  262. yasm_expr *e, *f;
  263. e = expr6();
  264. if (!e)
  265. return NULL;
  266. while (i == '*' || i == '/' || i == '%' ||
  267. i == TOKEN_SDIV || i == TOKEN_SMOD)
  268. {
  269. int j = i;
  270. i = scan(scpriv, tokval);
  271. f = expr6();
  272. if (!f) {
  273. yasm_expr_destroy(e);
  274. return NULL;
  275. }
  276. switch (j) {
  277. case '*':
  278. e = yasm_expr_create_tree(e, YASM_EXPR_MUL, f, 0);
  279. break;
  280. case '/':
  281. e = yasm_expr_create_tree(e, YASM_EXPR_DIV, f, 0);
  282. break;
  283. case '%':
  284. e = yasm_expr_create_tree(e, YASM_EXPR_MOD, f, 0);
  285. break;
  286. case TOKEN_SDIV:
  287. e = yasm_expr_create_tree(e, YASM_EXPR_SIGNDIV, f, 0);
  288. break;
  289. case TOKEN_SMOD:
  290. e = yasm_expr_create_tree(e, YASM_EXPR_SIGNMOD, f, 0);
  291. break;
  292. }
  293. }
  294. return e;
  295. }
  296. static yasm_expr *expr6(void)
  297. {
  298. yasm_expr *e = NULL;
  299. if (i == '-') {
  300. i = scan(scpriv, tokval);
  301. e = expr6();
  302. if (!e)
  303. return NULL;
  304. return yasm_expr_create_branch(YASM_EXPR_NEG, e, 0);
  305. } else if (i == '+') {
  306. i = scan(scpriv, tokval);
  307. return expr6();
  308. } else if (i == '~') {
  309. i = scan(scpriv, tokval);
  310. e = expr6();
  311. if (!e)
  312. return NULL;
  313. return yasm_expr_create_branch(YASM_EXPR_NOT, e, 0);
  314. } else if (i == TOKEN_SEG) {
  315. i = scan(scpriv, tokval);
  316. e = expr6();
  317. if (!e)
  318. return NULL;
  319. error(ERR_NONFATAL, "%s not supported", "SEG");
  320. return e;
  321. } else if (i == '(') {
  322. i = scan(scpriv, tokval);
  323. e = bexpr();
  324. if (!e)
  325. return NULL;
  326. if (i != ')') {
  327. error(ERR_NONFATAL, "expecting `)'");
  328. return NULL;
  329. }
  330. i = scan(scpriv, tokval);
  331. return e;
  332. }
  333. else if (i == TOKEN_NUM || i == TOKEN_ID ||
  334. i == TOKEN_HERE || i == TOKEN_BASE)
  335. {
  336. switch (i) {
  337. case TOKEN_NUM:
  338. e = yasm_expr_create_ident(yasm_expr_int(tokval->t_integer), 0);
  339. break;
  340. case TOKEN_ID:
  341. if (nasm_symtab) {
  342. yasm_symrec *sym =
  343. yasm_symtab_get(nasm_symtab, tokval->t_charptr);
  344. if (sym) {
  345. e = yasm_expr_create_ident(yasm_expr_sym(sym), 0);
  346. } else {
  347. error(ERR_NONFATAL,
  348. "undefined symbol `%s' in preprocessor",
  349. tokval->t_charptr);
  350. e = yasm_expr_create_ident(yasm_expr_int(
  351. yasm_intnum_create_int(1)), 0);
  352. }
  353. break;
  354. }
  355. /*fallthrough*/
  356. case TOKEN_HERE:
  357. case TOKEN_BASE:
  358. error(ERR_NONFATAL,
  359. "cannot reference symbol `%s' in preprocessor",
  360. (i == TOKEN_ID ? tokval->t_charptr :
  361. i == TOKEN_HERE ? "$" : "$$"));
  362. e = yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_int(1)),
  363. 0);
  364. break;
  365. }
  366. i = scan(scpriv, tokval);
  367. return e;
  368. } else {
  369. error(ERR_NONFATAL, "expression syntax error");
  370. return NULL;
  371. }
  372. }
  373. yasm_expr *nasm_evaluate (scanner sc, void *scprivate, struct tokenval *tv,
  374. int critical, efunc report_error)
  375. {
  376. if (critical & CRITICAL) {
  377. critical &= ~CRITICAL;
  378. bexpr = rexp0;
  379. } else
  380. bexpr = expr0;
  381. scan = sc;
  382. scpriv = scprivate;
  383. tokval = tv;
  384. error = report_error;
  385. if (tokval->t_type == TOKEN_INVALID)
  386. i = scan(scpriv, tokval);
  387. else
  388. i = tokval->t_type;
  389. return bexpr ();
  390. }