break;
- case '(':
#ifndef NEED_INDEX_OPERATOR
case '[':
+# ifdef md_need_index_operator
+ if (md_need_index_operator())
+ goto de_fault;
+# endif
+ /* FALLTHROUGH */
#endif
+ case '(':
/* Didn't begin with digit & not a name. */
if (mode != expr_defer)
segment = expression (expressionP);
case '-':
case '+':
{
+#ifdef md_operator
+ unary:
+#endif
operand (expressionP, mode);
if (expressionP->X_op == O_constant)
{
#endif
default:
-#ifdef TC_M68K
+#if defined(md_need_index_operator) || defined(TC_M68K)
de_fault:
#endif
if (is_name_beginner (c)) /* Here if did not begin with a digit. */
name = --input_line_pointer;
c = get_symbol_end ();
+#ifdef md_operator
+ {
+ operatorT operator = md_operator (name, 1, &c);
+
+ switch (operator)
+ {
+ case O_uminus:
+ *input_line_pointer = c;
+ c = '-';
+ goto unary;
+ case O_bit_not:
+ *input_line_pointer = c;
+ c = '~';
+ goto unary;
+ case O_logical_not:
+ *input_line_pointer = c;
+ c = '!';
+ goto unary;
+ case O_illegal:
+ as_bad (_("invalid use of operator \"%s\""), name);
+ break;
+ default:
+ break;
+ }
+ if (operator != O_absent && operator != O_illegal)
+ {
+ *input_line_pointer = c;
+ expr (9, expressionP, mode);
+ expressionP->X_add_symbol = make_expr_symbol (expressionP);
+ expressionP->X_op_symbol = NULL;
+ expressionP->X_add_number = 0;
+ expressionP->X_op = operator;
+ break;
+ }
+ }
+#endif
+
#ifdef md_parse_name
/* This is a hook for the backend to parse certain names
specially in certain contexts. If a name always has a
}
}
+void
+expr_set_rank (operatorT operator, operator_rankT rank)
+{
+ assert (operator >= O_md1 && operator < ARRAY_SIZE (op_rank));
+ op_rank[operator] = rank;
+}
+
/* Initialize the expression parser. */
void
if (is_end_of_line[c])
return O_illegal;
+#ifdef md_operator
+ if (is_name_beginner (c))
+ {
+ char *name = input_line_pointer;
+ char c = get_symbol_end ();
+
+ ret = md_operator (name, 2, &c);
+ switch (ret)
+ {
+ case O_absent:
+ *input_line_pointer = c;
+ input_line_pointer = name;
+ break;
+ case O_uminus:
+ case O_bit_not:
+ case O_logical_not:
+ as_bad (_("invalid use of operator \"%s\""), name);
+ ret = O_illegal;
+ /* FALLTHROUGH */
+ default:
+ *input_line_pointer = c;
+ *num_chars = input_line_pointer - name;
+ input_line_pointer = name;
+ return ret;
+ }
+ }
+#endif
+
switch (c)
{
default:
- return op_encoding[c];
+ ret = op_encoding[c];
+#ifdef md_operator
+ if (ret == O_illegal)
+ {
+ char *start = input_line_pointer;
+
+ ret = md_operator (NULL, 2, NULL);
+ if (ret != O_illegal)
+ *num_chars = input_line_pointer - start;
+ input_line_pointer = start;
+ }
+#endif
+ return ret;
case '+':
case '-':
op_right = operator (&op_chars);
- know (op_right == O_illegal
+ know (op_right == O_illegal || op_left == O_index
|| op_rank[(int) op_right] <= op_rank[(int) op_left]);
- know ((int) op_left >= (int) O_multiply
- && (int) op_left <= (int) O_index);
+ know ((int) op_left >= (int) O_multiply);
+#ifndef md_operator
+ know ((int) op_left <= (int) O_index);
+#else
+ know ((int) op_left < (int) O_max);
+#endif
/* input_line_pointer->after right-hand quantity. */
/* left-hand quantity in resultP. */
}
switch (op_left)
{
- default: abort ();
+ default: goto general;
case O_multiply: resultP->X_add_number *= v; break;
case O_divide: resultP->X_add_number /= v; break;
case O_modulus: resultP->X_add_number %= v; break;
}
else
{
+ general:
/* The general case. */
resultP->X_add_symbol = make_expr_symbol (resultP);
resultP->X_op_symbol = make_expr_symbol (&right);