eval.c
上传用户:yuppie_zhu
上传日期:2007-01-08
资源大小:535k
文件大小:19k
源码类别:

编译器/解释器

开发平台:

C/C++

  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 <stdio.h>
  11. #include <stdlib.h>
  12. #include <stddef.h>
  13. #include <string.h>
  14. #include <ctype.h>
  15. #include "nasm.h"
  16. #include "nasmlib.h"
  17. #include "eval.h"
  18. #include "labels.h"
  19. #define TEMPEXPRS_DELTA 128
  20. #define TEMPEXPR_DELTA 8
  21. static scanner scan; /* Address of scanner routine */
  22. static efunc error; /* Address of error reporting routine */
  23. static lfunc labelfunc; /* Address of label routine */
  24. static struct ofmt *outfmt;  /* Structure of addresses of output routines */
  25. static expr **tempexprs = NULL;
  26. static int    ntempexprs;
  27. static int    tempexprs_size = 0;
  28. static expr  *tempexpr;
  29. static int   ntempexpr;
  30. static int   tempexpr_size;
  31. static struct tokenval *tokval;   /* The current token */
  32. static int i;   /* The t_type of tokval */
  33. static void *scpriv;
  34. static loc_t *location; /* Pointer to current line's segment,offset */
  35. static int *opflags;
  36. static struct eval_hints *hint;
  37. /*
  38.  * Unimportant cleanup is done to avoid confusing people who are trying
  39.  * to debug real memory leaks
  40.  */
  41. void eval_cleanup(void) 
  42. {
  43.     while (ntempexprs)
  44. nasm_free (tempexprs[--ntempexprs]);
  45.     nasm_free (tempexprs);
  46. }
  47. /*
  48.  * Construct a temporary expression.
  49.  */
  50. static void begintemp(void) 
  51. {
  52.     tempexpr = NULL;
  53.     tempexpr_size = ntempexpr = 0;
  54. }
  55. static void addtotemp(long type, long value) 
  56. {
  57.     while (ntempexpr >= tempexpr_size) {
  58. tempexpr_size += TEMPEXPR_DELTA;
  59. tempexpr = nasm_realloc(tempexpr,
  60.  tempexpr_size*sizeof(*tempexpr));
  61.     }
  62.     tempexpr[ntempexpr].type = type;
  63.     tempexpr[ntempexpr++].value = value;
  64. }
  65. static expr *finishtemp(void) 
  66. {
  67.     addtotemp (0L, 0L);        /* terminate */
  68.     while (ntempexprs >= tempexprs_size) {
  69. tempexprs_size += TEMPEXPRS_DELTA;
  70. tempexprs = nasm_realloc(tempexprs,
  71.  tempexprs_size*sizeof(*tempexprs));
  72.     }
  73.     return tempexprs[ntempexprs++] = tempexpr;
  74. }
  75. /*
  76.  * Add two vector datatypes. We have some bizarre behaviour on far-
  77.  * absolute segment types: we preserve them during addition _only_
  78.  * if one of the segments is a truly pure scalar.
  79.  */
  80. static expr *add_vectors(expr *p, expr *q) 
  81. {
  82.     int preserve;
  83.     preserve = is_really_simple(p) || is_really_simple(q);
  84.     begintemp();
  85.     while (p->type && q->type &&
  86.    p->type < EXPR_SEGBASE+SEG_ABS &&
  87.    q->type < EXPR_SEGBASE+SEG_ABS)
  88.     {
  89. int lasttype;
  90.      if (p->type > q->type) {
  91.     addtotemp(q->type, q->value);
  92.     lasttype = q++->type;
  93. } else if (p->type < q->type) {
  94.     addtotemp(p->type, p->value);
  95.     lasttype = p++->type;
  96. } else {        /* *p and *q have same type */
  97.     long sum = p->value + q->value;
  98.     if (sum)
  99. addtotemp(p->type, sum);
  100.     lasttype = p->type;
  101.     p++, q++;
  102. }
  103. if (lasttype == EXPR_UNKNOWN) {
  104.     return finishtemp();
  105. }
  106.     }
  107.     while (p->type &&
  108.    (preserve || p->type < EXPR_SEGBASE+SEG_ABS)) 
  109.     {
  110. addtotemp(p->type, p->value);
  111. p++;
  112.     }
  113.     while (q->type &&
  114.    (preserve || q->type < EXPR_SEGBASE+SEG_ABS)) 
  115.     {
  116. addtotemp(q->type, q->value);
  117. q++;
  118.     }
  119.     return finishtemp();
  120. }
  121. /*
  122.  * Multiply a vector by a scalar. Strip far-absolute segment part
  123.  * if present.
  124.  *
  125.  * Explicit treatment of UNKNOWN is not required in this routine,
  126.  * since it will silently do the Right Thing anyway.
  127.  *
  128.  * If `affect_hints' is set, we also change the hint type to
  129.  * NOTBASE if a MAKEBASE hint points at a register being
  130.  * multiplied. This allows [eax*1+ebx] to hint EBX rather than EAX
  131.  * as the base register.
  132.  */
  133. static expr *scalar_mult(expr *vect, long scalar, int affect_hints) 
  134. {
  135.     expr *p = vect;
  136.     while (p->type && p->type < EXPR_SEGBASE+SEG_ABS) {
  137. p->value = scalar * (p->value);
  138. if (hint && hint->type == EAH_MAKEBASE &&
  139.     p->type == hint->base && affect_hints)
  140.     hint->type = EAH_NOTBASE;
  141. p++;
  142.     }
  143.     p->type = 0;
  144.     return vect;
  145. }
  146. static expr *scalarvect (long scalar) 
  147. {
  148.     begintemp();
  149.     addtotemp(EXPR_SIMPLE, scalar);
  150.     return finishtemp();
  151. }
  152. static expr *unknown_expr (void) 
  153. {
  154.     begintemp();
  155.     addtotemp(EXPR_UNKNOWN, 1L);
  156.     return finishtemp();
  157. }
  158. /*
  159.  * The SEG operator: calculate the segment part of a relocatable
  160.  * value. Return NULL, as usual, if an error occurs. Report the
  161.  * error too.
  162.  */
  163. static expr *segment_part (expr *e) 
  164. {
  165.     long seg;
  166.     if (is_unknown(e))
  167. return unknown_expr();
  168.     if (!is_reloc(e)) {
  169. error(ERR_NONFATAL, "cannot apply SEG to a non-relocatable value");
  170. return NULL;
  171.     }
  172.     seg = reloc_seg(e);
  173.     if (seg == NO_SEG) {
  174. error(ERR_NONFATAL, "cannot apply SEG to a non-relocatable value");
  175. return NULL;
  176.     } else if (seg & SEG_ABS) {
  177. return scalarvect(seg & ~SEG_ABS);
  178.     } else if (seg & 1) {
  179. error(ERR_NONFATAL, "SEG applied to something which"
  180.       " is already a segment base");
  181. return NULL;
  182.     }
  183.     else {
  184. long base = outfmt->segbase(seg+1);
  185. begintemp();
  186. addtotemp((base == NO_SEG ? EXPR_UNKNOWN : EXPR_SEGBASE+base), 1L);
  187. return finishtemp();
  188.     }
  189. }
  190. /*
  191.  * Recursive-descent parser. Called with a single boolean operand,
  192.  * which is TRUE if the evaluation is critical (i.e. unresolved
  193.  * symbols are an error condition). Must update the global `i' to
  194.  * reflect the token after the parsed string. May return NULL.
  195.  *
  196.  * evaluate() should report its own errors: on return it is assumed
  197.  * that if NULL has been returned, the error has already been
  198.  * reported.
  199.  */
  200. /*
  201.  * Grammar parsed is:
  202.  *
  203.  * expr  : bexpr [ WRT expr6 ]
  204.  * bexpr : rexp0 or expr0 depending on relative-mode setting
  205.  * rexp0 : rexp1 [ {||} rexp1...]
  206.  * rexp1 : rexp2 [ {^^} rexp2...]
  207.  * rexp2 : rexp3 [ {&&} rexp3...]
  208.  * rexp3 : expr0 [ {=,==,<>,!=,<,>,<=,>=} expr0 ]
  209.  * expr0 : expr1 [ {|} expr1...]
  210.  * expr1 : expr2 [ {^} expr2...]
  211.  * expr2 : expr3 [ {&} expr3...]
  212.  * expr3 : expr4 [ {<<,>>} expr4...]
  213.  * expr4 : expr5 [ {+,-} expr5...]
  214.  * expr5 : expr6 [ {*,/,%,//,%%} expr6...]
  215.  * expr6 : { ~,+,-,SEG } expr6
  216.  *       | (bexpr)
  217.  *       | symbol
  218.  *       | $
  219.  *       | number
  220.  */
  221. static expr *rexp0(int), *rexp1(int), *rexp2(int), *rexp3(int);
  222. static expr *expr0(int), *expr1(int), *expr2(int), *expr3(int);
  223. static expr *expr4(int), *expr5(int), *expr6(int);
  224. static expr *(*bexpr)(int);
  225. static expr *rexp0(int critical) 
  226. {
  227.     expr *e, *f;
  228.     e = rexp1(critical);
  229.     if (!e)
  230. return NULL;
  231.     while (i == TOKEN_DBL_OR) 
  232.     {
  233. i = scan(scpriv, tokval);
  234. f = rexp1(critical);
  235. if (!f)
  236.     return NULL;
  237. if (!(is_simple(e) || is_just_unknown(e)) ||
  238.     !(is_simple(f) || is_just_unknown(f))) 
  239. {
  240.     error(ERR_NONFATAL, "`|' operator may only be applied to"
  241.   " scalar values");
  242. }
  243. if (is_just_unknown(e) || is_just_unknown(f))
  244.     e = unknown_expr();
  245. else
  246.     e = scalarvect ((long) (reloc_value(e) || reloc_value(f)));
  247.     }
  248.     return e;
  249. }
  250. static expr *rexp1(int critical) 
  251. {
  252.     expr *e, *f;
  253.     e = rexp2(critical);
  254.     if (!e)
  255. return NULL;
  256.     
  257.     while (i == TOKEN_DBL_XOR) 
  258.     {
  259. i = scan(scpriv, tokval);
  260. f = rexp2(critical);
  261. if (!f)
  262.     return NULL;
  263. if (!(is_simple(e) || is_just_unknown(e)) ||
  264.     !(is_simple(f) || is_just_unknown(f))) 
  265. {
  266.     error(ERR_NONFATAL, "`^' operator may only be applied to"
  267.   " scalar values");
  268. }
  269. if (is_just_unknown(e) || is_just_unknown(f))
  270.     e = unknown_expr();
  271. else
  272.     e = scalarvect ((long) (!reloc_value(e) ^ !reloc_value(f)));
  273.     }
  274.     return e;
  275. }
  276. static expr *rexp2(int critical) 
  277. {
  278.     expr *e, *f;
  279.     e = rexp3(critical);
  280.     if (!e)
  281. return NULL;
  282.     while (i == TOKEN_DBL_AND) 
  283.     {
  284. i = scan(scpriv, tokval);
  285. f = rexp3(critical);
  286. if (!f)
  287.     return NULL;
  288. if (!(is_simple(e) || is_just_unknown(e)) ||
  289.     !(is_simple(f) || is_just_unknown(f))) 
  290. {
  291.     error(ERR_NONFATAL, "`&' operator may only be applied to"
  292.   " scalar values");
  293. }
  294. if (is_just_unknown(e) || is_just_unknown(f))
  295.     e = unknown_expr();
  296. else
  297.     e = scalarvect ((long) (reloc_value(e) && reloc_value(f)));
  298.     }
  299.     return e;
  300. }
  301. static expr *rexp3(int critical) 
  302. {
  303.     expr *e, *f;
  304.     long v;
  305.     e = expr0(critical);
  306.     if (!e)
  307. return NULL;
  308.     while (i == TOKEN_EQ || i == TOKEN_LT || i == TOKEN_GT ||
  309.    i == TOKEN_NE || i == TOKEN_LE || i == TOKEN_GE) 
  310.     {
  311. int j = i;
  312. i = scan(scpriv, tokval);
  313. f = expr0(critical);
  314. if (!f)
  315.     return NULL;
  316. e = add_vectors (e, scalar_mult(f, -1L, FALSE));
  317. switch (j) 
  318. {
  319.   case TOKEN_EQ: case TOKEN_NE:
  320.     if (is_unknown(e))
  321. v = -1;        /* means unknown */
  322.     else if (!is_really_simple(e) || reloc_value(e) != 0)
  323. v = (j == TOKEN_NE);   /* unequal, so return TRUE if NE */
  324.     else
  325. v = (j == TOKEN_EQ);   /* equal, so return TRUE if EQ */
  326.     break;
  327.   default:
  328.     if (is_unknown(e))
  329. v = -1;        /* means unknown */
  330.     else if (!is_really_simple(e)) {
  331. error(ERR_NONFATAL, "`%s': operands differ by a non-scalar",
  332.       (j == TOKEN_LE ? "<=" : j == TOKEN_LT ? "<" :
  333.        j == TOKEN_GE ? ">=" : ">"));
  334. v = 0;        /* must set it to _something_ */
  335.     } else {
  336. int vv = reloc_value(e);
  337. if (vv == 0)
  338.     v = (j == TOKEN_LE || j == TOKEN_GE);
  339. else if (vv > 0)
  340.     v = (j == TOKEN_GE || j == TOKEN_GT);
  341. else /* vv < 0 */
  342.     v = (j == TOKEN_LE || j == TOKEN_LT);
  343.     }
  344.     break;
  345. }
  346. if (v == -1)
  347.     e = unknown_expr();
  348. else
  349.     e = scalarvect(v);
  350.     }
  351.     return e;
  352. }
  353. static expr *expr0(int critical) 
  354. {
  355.     expr *e, *f;
  356.     e = expr1(critical);
  357.     if (!e)
  358. return NULL;
  359.     while (i == '|') 
  360.     {
  361. i = scan(scpriv, tokval);
  362. f = expr1(critical);
  363. if (!f)
  364.     return NULL;
  365. if (!(is_simple(e) || is_just_unknown(e)) ||
  366.     !(is_simple(f) || is_just_unknown(f))) 
  367. {
  368.     error(ERR_NONFATAL, "`|' operator may only be applied to"
  369.   " scalar values");
  370. }
  371. if (is_just_unknown(e) || is_just_unknown(f))
  372.     e = unknown_expr();
  373. else
  374.     e = scalarvect (reloc_value(e) | reloc_value(f));
  375.     }
  376.     return e;
  377. }
  378. static expr *expr1(int critical) 
  379. {
  380.     expr *e, *f;
  381.     e = expr2(critical);
  382.     if (!e)
  383. return NULL;
  384.     while (i == '^') {
  385. i = scan(scpriv, tokval);
  386. f = expr2(critical);
  387. if (!f)
  388.     return NULL;
  389. if (!(is_simple(e) || is_just_unknown(e)) ||
  390.     !(is_simple(f) || is_just_unknown(f))) 
  391. {
  392.     error(ERR_NONFATAL, "`^' operator may only be applied to"
  393.   " scalar values");
  394. }
  395. if (is_just_unknown(e) || is_just_unknown(f))
  396.     e = unknown_expr();
  397. else
  398.     e = scalarvect (reloc_value(e) ^ reloc_value(f));
  399.     }
  400.     return e;
  401. }
  402. static expr *expr2(int critical) 
  403. {
  404.     expr *e, *f;
  405.     e = expr3(critical);
  406.     if (!e)
  407. return NULL;
  408.     while (i == '&') {
  409. i = scan(scpriv, tokval);
  410. f = expr3(critical);
  411. if (!f)
  412.     return NULL;
  413. if (!(is_simple(e) || is_just_unknown(e)) ||
  414.     !(is_simple(f) || is_just_unknown(f))) 
  415. {
  416.     error(ERR_NONFATAL, "`&' operator may only be applied to"
  417.   " scalar values");
  418. }
  419. if (is_just_unknown(e) || is_just_unknown(f))
  420.     e = unknown_expr();
  421. else
  422.     e = scalarvect (reloc_value(e) & reloc_value(f));
  423.     }
  424.     return e;
  425. }
  426. static expr *expr3(int critical) 
  427. {
  428.     expr *e, *f;
  429.     e = expr4(critical);
  430.     if (!e)
  431. return NULL;
  432.     while (i == TOKEN_SHL || i == TOKEN_SHR) 
  433.     {
  434. int j = i;
  435. i = scan(scpriv, tokval);
  436. f = expr4(critical);
  437. if (!f)
  438.     return NULL;
  439. if (!(is_simple(e) || is_just_unknown(e)) ||
  440.     !(is_simple(f) || is_just_unknown(f))) 
  441. {
  442.     error(ERR_NONFATAL, "shift operator may only be applied to"
  443.   " scalar values");
  444. } else if (is_just_unknown(e) || is_just_unknown(f)) {
  445.     e = unknown_expr();
  446. } else switch (j) {
  447.   case TOKEN_SHL:
  448.     e = scalarvect (reloc_value(e) << reloc_value(f));
  449.     break;
  450.   case TOKEN_SHR:
  451.     e = scalarvect (((unsigned long)reloc_value(e)) >>
  452.     reloc_value(f));
  453.     break;
  454. }
  455.     }
  456.     return e;
  457. }
  458. static expr *expr4(int critical) 
  459. {
  460.     expr *e, *f;
  461.     e = expr5(critical);
  462.     if (!e)
  463. return NULL;
  464.     while (i == '+' || i == '-') 
  465.     {
  466. int j = i;
  467. i = scan(scpriv, tokval);
  468. f = expr5(critical);
  469. if (!f)
  470.     return NULL;
  471. switch (j) {
  472.   case '+':
  473.     e = add_vectors (e, f);
  474.     break;
  475.   case '-':
  476.     e = add_vectors (e, scalar_mult(f, -1L, FALSE));
  477.     break;
  478. }
  479.     }
  480.     return e;
  481. }
  482. static expr *expr5(int critical) 
  483. {
  484.     expr *e, *f;
  485.     e = expr6(critical);
  486.     if (!e)
  487. return NULL;
  488.     while (i == '*' || i == '/' || i == '%' ||
  489.    i == TOKEN_SDIV || i == TOKEN_SMOD) 
  490.     {
  491. int j = i;
  492. i = scan(scpriv, tokval);
  493. f = expr6(critical);
  494. if (!f)
  495.     return NULL;
  496. if (j != '*' && (!(is_simple(e) || is_just_unknown(e)) ||
  497.  !(is_simple(f) || is_just_unknown(f)))) 
  498. {
  499.     error(ERR_NONFATAL, "division operator may only be applied to"
  500.   " scalar values");
  501.     return NULL;
  502. }
  503. if (j != '*' && !is_unknown(f) && reloc_value(f) == 0) {
  504.     error(ERR_NONFATAL, "division by zero");
  505.     return NULL;
  506. }
  507. switch (j) {
  508.   case '*':
  509.     if (is_simple(e))
  510. e = scalar_mult (f, reloc_value(e), TRUE);
  511.     else if (is_simple(f))
  512. e = scalar_mult (e, reloc_value(f), TRUE);
  513.     else if (is_just_unknown(e) && is_just_unknown(f))
  514. e = unknown_expr();
  515.     else {
  516. error(ERR_NONFATAL, "unable to multiply two "
  517.       "non-scalar objects");
  518. return NULL;
  519.     }
  520.     break;
  521.   case '/':
  522.     if (is_just_unknown(e) || is_just_unknown(f))
  523. e = unknown_expr();
  524.     else
  525. e = scalarvect (((unsigned long)reloc_value(e)) /
  526. ((unsigned long)reloc_value(f)));
  527.     break;
  528.   case '%':
  529.     if (is_just_unknown(e) || is_just_unknown(f))
  530. e = unknown_expr();
  531.     else
  532. e = scalarvect (((unsigned long)reloc_value(e)) %
  533. ((unsigned long)reloc_value(f)));
  534.     break;
  535.   case TOKEN_SDIV:
  536.     if (is_just_unknown(e) || is_just_unknown(f))
  537. e = unknown_expr();
  538.     else
  539. e = scalarvect (((signed long)reloc_value(e)) /
  540. ((signed long)reloc_value(f)));
  541.     break;
  542.   case TOKEN_SMOD:
  543.     if (is_just_unknown(e) || is_just_unknown(f))
  544. e = unknown_expr();
  545.     else
  546. e = scalarvect (((signed long)reloc_value(e)) %
  547. ((signed long)reloc_value(f)));
  548.     break;
  549. }
  550.     }
  551.     return e;
  552. }
  553. static expr *expr6(int critical) 
  554. {
  555.     long type;
  556.     expr *e;
  557.     long label_seg, label_ofs;
  558.     if (i == '-') {
  559. i = scan(scpriv, tokval);
  560. e = expr6(critical);
  561. if (!e)
  562.     return NULL;
  563. return scalar_mult (e, -1L, FALSE);
  564.     } else if (i == '+') {
  565. i = scan(scpriv, tokval);
  566. return expr6(critical);
  567.     } else if (i == '~') {
  568. i = scan(scpriv, tokval);
  569. e = expr6(critical);
  570. if (!e)
  571.     return NULL;
  572. if (is_just_unknown(e))
  573.     return unknown_expr();
  574. else if (!is_simple(e)) {
  575.     error(ERR_NONFATAL, "`~' operator may only be applied to"
  576.   " scalar values");
  577.     return NULL;
  578. }
  579. return scalarvect(~reloc_value(e));
  580.     } else if (i == TOKEN_SEG) {
  581. i = scan(scpriv, tokval);
  582. e = expr6(critical);
  583. if (!e)
  584.     return NULL;
  585. e = segment_part(e);
  586. if (is_unknown(e) && critical) {
  587.     error(ERR_NONFATAL, "unable to determine segment base");
  588.     return NULL;
  589. }
  590. return e;
  591.     } else if (i == '(') {
  592. i = scan(scpriv, tokval);
  593. e = bexpr(critical);
  594. if (!e)
  595.     return NULL;
  596. if (i != ')') {
  597.     error(ERR_NONFATAL, "expecting `)'");
  598.     return NULL;
  599. }
  600. i = scan(scpriv, tokval);
  601. return e;
  602.     } 
  603.     else if (i == TOKEN_NUM || i == TOKEN_REG || i == TOKEN_ID ||
  604.      i == TOKEN_HERE || i == TOKEN_BASE) 
  605.     {
  606. begintemp();
  607. switch (i) {
  608.   case TOKEN_NUM:
  609.     addtotemp(EXPR_SIMPLE, tokval->t_integer);
  610.     break;
  611.   case TOKEN_REG:
  612.     addtotemp(tokval->t_integer, 1L);
  613.     if (hint && hint->type == EAH_NOHINT)
  614. hint->base = tokval->t_integer, hint->type = EAH_MAKEBASE;
  615.     break;
  616.   case TOKEN_ID:
  617.   case TOKEN_HERE:
  618.   case TOKEN_BASE:
  619.     /*
  620.      * If !location->known, this indicates that no
  621.      * symbol, Here or Base references are valid because we
  622.      * are in preprocess-only mode.
  623.      */
  624.     if (!location->known) {
  625. error(ERR_NONFATAL,
  626.       "%s not supported in preprocess-only mode",
  627.       (i == TOKEN_ID ? "symbol references" :
  628.        i == TOKEN_HERE ? "`$'" : "`$$'"));
  629. addtotemp(EXPR_UNKNOWN, 1L);
  630. break;
  631.     }
  632.     type = EXPR_SIMPLE;        /* might get overridden by UNKNOWN */
  633.     if (i == TOKEN_BASE)
  634.     {
  635. label_seg = location->segment;
  636. label_ofs = 0;
  637.     } else if (i == TOKEN_HERE) {
  638. label_seg = location->segment;
  639. label_ofs = location->offset;
  640.     } else {
  641. if (!labelfunc(tokval->t_charptr,&label_seg,&label_ofs))
  642. {
  643. if (critical == 2) {
  644.     error (ERR_NONFATAL, "symbol `%s' undefined",
  645.    tokval->t_charptr);
  646.     return NULL;
  647. } else if (critical == 1) {
  648. error (ERR_NONFATAL,
  649. "symbol `%s' not defined before use",
  650.    tokval->t_charptr);
  651.     return NULL;
  652. } else {
  653.     if (opflags)
  654. *opflags |= 1;
  655.     type = EXPR_UNKNOWN;
  656.     label_seg = NO_SEG;
  657.     label_ofs = 1;
  658. }
  659.     }
  660. if (opflags && is_extern (tokval->t_charptr))
  661.     *opflags |= OPFLAG_EXTERN;
  662.     }
  663.     addtotemp(type, label_ofs);
  664.     if (label_seg!=NO_SEG)
  665. addtotemp(EXPR_SEGBASE + label_seg, 1L);
  666.     break;
  667. }
  668. i = scan(scpriv, tokval);
  669. return finishtemp();
  670.     } else {
  671. error(ERR_NONFATAL, "expression syntax error");
  672. return NULL;
  673.     }
  674. }
  675. void eval_global_info (struct ofmt *output, lfunc lookup_label, loc_t *locp) 
  676. {
  677.     outfmt = output;
  678.     labelfunc = lookup_label;
  679.     location = locp;
  680. }
  681. expr *evaluate (scanner sc, void *scprivate, struct tokenval *tv,
  682. int *fwref, int critical, efunc report_error,
  683. struct eval_hints *hints) 
  684. {
  685.     expr *e;
  686.     expr *f = NULL;
  687.     hint = hints;
  688.     if (hint)
  689. hint->type = EAH_NOHINT;
  690.     if (critical & 0x10) {
  691. critical &= ~0x10;
  692. bexpr = rexp0;
  693.     } else
  694. bexpr = expr0;
  695.     scan = sc;
  696.     scpriv = scprivate;
  697.     tokval = tv;
  698.     error = report_error;
  699.     opflags = fwref;
  700.     if (tokval->t_type == TOKEN_INVALID)
  701. i = scan(scpriv, tokval);
  702.     else
  703. i = tokval->t_type;
  704.     while (ntempexprs)        /* initialise temporary storage */
  705. nasm_free (tempexprs[--ntempexprs]);
  706.     e = bexpr (critical);
  707.     if (!e)
  708. return NULL;
  709.     if (i == TOKEN_WRT) {
  710. i = scan(scpriv, tokval);      /* eat the WRT */
  711. f = expr6 (critical);
  712. if (!f)
  713.     return NULL;
  714.     }
  715.     e = scalar_mult (e, 1L, FALSE);    /* strip far-absolute segment part */
  716.     if (f) {
  717. expr *g;
  718. if (is_just_unknown(f))
  719.     g = unknown_expr();
  720. else {
  721.     long value;
  722.     begintemp();
  723.     if (!is_reloc(f)) {
  724. error(ERR_NONFATAL, "invalid right-hand operand to WRT");
  725. return NULL;
  726.     }
  727.     value = reloc_seg(f);
  728.     if (value == NO_SEG)
  729. value = reloc_value(f) | SEG_ABS;
  730.     else if (!(value & SEG_ABS) && !(value % 2) && critical) 
  731.     {
  732. error(ERR_NONFATAL, "invalid right-hand operand to WRT");
  733. return NULL;
  734.     }
  735.     addtotemp(EXPR_WRT, value);
  736.     g = finishtemp();
  737. }
  738. e = add_vectors (e, g);
  739.     }
  740.     return e;
  741. }