static void floating_constant PARAMS ((expressionS * expressionP));
static void integer_constant PARAMS ((int radix, expressionS * expressionP));
static void mri_char_constant PARAMS ((expressionS *));
+static void current_location PARAMS ((expressionS *));
static void clean_up_expression PARAMS ((expressionS * expressionP));
extern const char EXP_CHARS[], FLT_CHARS[];
++input_line_pointer;
}
+/* Return an expression representing the current location. This
+ handles the magic symbol `.'. */
+
+static void
+current_location (expressionp)
+ expressionS *expressionp;
+{
+ if (now_seg == absolute_section)
+ {
+ expressionp->X_op = O_constant;
+ expressionp->X_add_number = abs_section_offset;
+ }
+ else
+ {
+ symbolS *symbolp;
+
+ symbolp = symbol_new (FAKE_LABEL_NAME, now_seg,
+ (valueT) frag_now_fix (),
+ frag_now);
+ expressionp->X_op = O_symbol;
+ expressionp->X_add_symbol = symbolp;
+ expressionp->X_add_number = 0;
+ }
+}
+
/*
* Summary of operand().
*
c = *input_line_pointer;
switch (c)
{
+ case '8':
+ case '9':
+ if (flag_mri)
+ {
+ integer_constant (0, expressionP);
+ break;
+ }
+ /* Fall through. */
default:
default_case:
if (c && strchr (FLT_CHARS, c))
integer_constant (16, expressionP);
break;
}
- /* Fall through. */
+
+ if (is_part_of_name (*input_line_pointer))
+ goto isname;
+
+ current_location (expressionP);
+ break;
+
case '.':
if (!is_part_of_name (*input_line_pointer))
{
- const char *fake;
+ current_location (expressionP);
+ break;
+ }
+ else if ((strncasecmp (input_line_pointer, "startof.", 8) == 0
+ && ! is_part_of_name (input_line_pointer[8]))
+ || (strncasecmp (input_line_pointer, "sizeof.", 7) == 0
+ && ! is_part_of_name (input_line_pointer[7])))
+ {
+ int start;
+
+ start = (input_line_pointer[1] == 't'
+ || input_line_pointer[1] == 'T');
+ input_line_pointer += start ? 8 : 7;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '(')
+ as_bad ("syntax error in .startof. or .sizeof.");
+ else
+ {
+ char *buf;
- /* JF: '.' is pseudo symbol with value of current location
- in current segment. */
- fake = FAKE_LABEL_NAME;
- symbolP = symbol_new (fake,
- now_seg,
- (valueT) frag_now_fix (),
- frag_now);
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ buf = (char *) xmalloc (strlen (name) + 10);
+ if (start)
+ sprintf (buf, ".startof.%s", name);
+ else
+ sprintf (buf, ".sizeof.%s", name);
+ symbolP = symbol_make (buf);
+ free (buf);
- expressionP->X_op = O_symbol;
- expressionP->X_add_symbol = symbolP;
- expressionP->X_add_number = 0;
+ expressionP->X_op = O_symbol;
+ expressionP->X_add_symbol = symbolP;
+ expressionP->X_add_number = 0;
+
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ')')
+ as_bad ("syntax error in .startof. or .sizeof.");
+ else
+ ++input_line_pointer;
+ }
break;
}
else
integer_constant (16, expressionP);
break;
+ case '*':
+ if (! flag_mri || is_part_of_name (*input_line_pointer))
+ goto de_fault;
+
+ current_location (expressionP);
+ break;
+
default:
de_fault:
if (is_end_of_line[(unsigned char) c])
#undef __
#define __ O_illegal
-static const operatorT op_encoding[256] =
+static operatorT op_encoding[256] =
{ /* maps ASCII->operators */
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
- __, O_bit_or_not, O_bit_not, __, __, O_modulus, O_bit_and, __,
+ __, O_bit_or_not, __, __, __, O_modulus, O_bit_and, __,
__, __, O_multiply, O_add, __, O_subtract, __, O_divide,
__, __, __, __, __, __, __, __,
__, __, __, __, O_lt, __, O_gt, __,
op_rank[O_multiply] = 3;
op_rank[O_divide] = 3;
op_rank[O_modulus] = 3;
+ op_encoding['"'] = O_bit_not;
}
}
\f
op_right = operator ();
know (op_right == O_illegal || op_rank[(int) op_right] <= op_rank[(int) op_left]);
- know ((int) op_left >= (int) O_multiply && (int) op_left <= (int) O_subtract);
+ know ((int) op_left >= (int) O_multiply && (int) op_left <= (int) O_gt);
/* input_line_pointer->after right-hand quantity. */
/* left-hand quantity in resultP */
{
char c;
- while (is_part_of_name (c = *input_line_pointer++))
+ /* We accept \001 in a name in case this is being called with a
+ constructed string. */
+ while (is_part_of_name (c = *input_line_pointer++)
+ || c == '\001')
;
*--input_line_pointer = 0;
return (c);