home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / nasm097s.zip / EVAL.C < prev    next >
C/C++ Source or Header  |  1997-11-06  |  20KB  |  762 lines

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