/* expr.c -operands, expressions-
Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001
+ 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
/* In: Input_line_pointer points to 1st char of operand, which may
be a space.
- Out: A expressionS.
+ Out: An expressionS.
The operand may have been empty: in this case X_op == O_absent.
Input_line_pointer->(next non-blank) char after operand. */
integer_constant ((NUMBERS_WITH_SUFFIX || flag_m68k_mri)
? 0 : 10,
- expressionP);
+ expressionP);
break;
#ifdef LITERAL_PREFIXDOLLAR_HEX
\f
/* Internal. Simplify a struct expression for use by expr (). */
-/* In: address of a expressionS.
+/* In: address of an expressionS.
The X_op field of the expressionS may only take certain values.
Elsewise we waste time special-case testing. Sigh. Ditto SEG_ABSENT.
Out: expressionS may have been modified:
- 'foo-foo' symbol references cancelled to 0, which changes X_op
- from O_subtract to O_constant.
Unused fields zeroed to help expr (). */
static void
case O_bit_not:
expressionP->X_op_symbol = NULL;
break;
- case O_subtract:
- if (expressionP->X_op_symbol == expressionP->X_add_symbol
- || ((symbol_get_frag (expressionP->X_op_symbol)
- == symbol_get_frag (expressionP->X_add_symbol))
- && SEG_NORMAL (S_GET_SEGMENT (expressionP->X_add_symbol))
- && (S_GET_VALUE (expressionP->X_op_symbol)
- == S_GET_VALUE (expressionP->X_add_symbol))))
- {
- addressT diff = (S_GET_VALUE (expressionP->X_add_symbol)
- - S_GET_VALUE (expressionP->X_op_symbol));
-
- expressionP->X_op = O_constant;
- expressionP->X_add_symbol = NULL;
- expressionP->X_op_symbol = NULL;
- expressionP->X_add_number += diff;
- }
- break;
default:
break;
}
Unary operators and parenthetical expressions are treated as operands.
As usual, Q==quantity==operand, O==operator, X==expression mnemonics.
- We used to do a aho/ullman shift-reduce parser, but the logic got so
+ We used to do an aho/ullman shift-reduce parser, but the logic got so
warped that I flushed it and wrote a recursive-descent parser instead.
Now things are stable, would anybody like to write a fast parser?
Most expressions are either register (which does not even reach here)
know (rank >= 0);
+ /* Save the value of dot for the fixup code. */
+ if (rank == 0)
+ dot_value = frag_now_fix ();
+
retval = operand (resultP);
/* operand () gobbles spaces. */
&& resultP->X_op == O_symbol
&& (symbol_get_frag (right.X_add_symbol)
== symbol_get_frag (resultP->X_add_symbol))
- && SEG_NORMAL (rightseg))
+ && (SEG_NORMAL (rightseg)
+ || right.X_add_symbol == resultP->X_add_symbol))
{
resultP->X_add_number -= right.X_add_number;
resultP->X_add_number += (S_GET_VALUE (resultP->X_add_symbol)