gas-eval.c 10 KB

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