Commit 9ee70313 by Neil Booth Committed by Neil Booth

cppexp.c: (_cpp_parse_expr): Numerical constants are pushed within the switch statement.

        * cppexp.c: (_cpp_parse_expr): Numerical constants are pushed
        within the switch statement.  Binary operations break out of
        the switch naturally.  '(' tokens handled by forcing
        immediate shift.  ')' handled by forcing immediate reduce to
        the previous '('.  New error messages.

From-SVN: r32854
parent 81eace42
2000-04-01 Neil Booth <NeilB@earthling.net>
* cppexp.c: (_cpp_parse_expr): Numerical constants are pushed
within the switch statement. Binary operations break out of
the switch naturally. '(' tokens handled by forcing
immediate shift. ')' handled by forcing immediate reduce to
the previous '('. New error messages.
2000-03-31 Geoff Keating <geoffk@cygnus.com> 2000-03-31 Geoff Keating <geoffk@cygnus.com>
* config/rs6000/rs6000.c (print_operand): Don't use %l for 'low * config/rs6000/rs6000.c (print_operand): Don't use %l for 'low
......
...@@ -699,7 +699,7 @@ _cpp_parse_expr (pfile) ...@@ -699,7 +699,7 @@ _cpp_parse_expr (pfile)
U_CHAR flags = 0; U_CHAR flags = 0;
/* Read a token */ /* Read a token */
op = lex (pfile, skip_evaluation); op = lex (pfile, skip_evaluation);
/* See if the token is an operand, in which case go to set_value. /* See if the token is an operand, in which case go to set_value.
If the token is an operator, figure out its left and right If the token is an operator, figure out its left and right
...@@ -710,16 +710,29 @@ _cpp_parse_expr (pfile) ...@@ -710,16 +710,29 @@ _cpp_parse_expr (pfile)
case NAME: case NAME:
cpp_ice (pfile, "lex returns a NAME"); cpp_ice (pfile, "lex returns a NAME");
goto syntax_error; goto syntax_error;
case ERROR:
goto syntax_error;
default:
cpp_error (pfile, "invalid character in #if");
goto syntax_error;
case INT: case CHAR: case INT: case CHAR:
goto set_value; push_immediate:
case 0: /* Push a value onto the stack. */
lprio = 0; goto maybe_reduce;
case '+': case '-':
if (top->flags & HAVE_VALUE) if (top->flags & HAVE_VALUE)
{ {
lprio = PLUS_PRIO; cpp_error (pfile, "suspected missing binary operator in #if");
goto binop; goto syntax_error;
} }
top->value = op.value;
top->unsignedp = op.unsignedp;
top->flags |= HAVE_VALUE;
continue;
case '+': case '-':
lprio = PLUS_PRIO;
if (top->flags & HAVE_VALUE)
break;
if (top->flags & SIGN_QUALIFIED) if (top->flags & SIGN_QUALIFIED)
{ {
cpp_error (pfile, "more than one sign operator given"); cpp_error (pfile, "more than one sign operator given");
...@@ -730,24 +743,25 @@ _cpp_parse_expr (pfile) ...@@ -730,24 +743,25 @@ _cpp_parse_expr (pfile)
case '!': case '~': case '!': case '~':
flags |= RIGHT_OPERAND_REQUIRED; flags |= RIGHT_OPERAND_REQUIRED;
rprio = UNARY_PRIO; lprio = rprio + 1; goto maybe_reduce; rprio = UNARY_PRIO; lprio = rprio + 1; goto maybe_reduce;
case '*': case '/': case '%': case '*': case '/': case '%':
lprio = MUL_PRIO; goto binop; lprio = MUL_PRIO; break;
case '<': case '>': case LEQ: case GEQ: case '<': case '>': case LEQ: case GEQ:
lprio = LESS_PRIO; goto binop; lprio = LESS_PRIO; break;
case EQUAL: case NOTEQUAL: case EQUAL: case NOTEQUAL:
lprio = EQUAL_PRIO; goto binop; lprio = EQUAL_PRIO; break;
case LSH: case RSH: case LSH: case RSH:
lprio = SHIFT_PRIO; goto binop; lprio = SHIFT_PRIO; break;
case '&': lprio = AND_PRIO; goto binop; case '&': lprio = AND_PRIO; break;
case '^': lprio = XOR_PRIO; goto binop; case '^': lprio = XOR_PRIO; break;
case '|': lprio = OR_PRIO; goto binop; case '|': lprio = OR_PRIO; break;
case ANDAND: lprio = ANDAND_PRIO; goto binop; case ANDAND: lprio = ANDAND_PRIO; break;
case OROR: lprio = OROR_PRIO; goto binop; case OROR: lprio = OROR_PRIO; break;
case ',': case ',':
lprio = COMMA_PRIO; goto binop; lprio = COMMA_PRIO; break;
case '(': case '(':
lprio = PAREN_OUTER_PRIO; rprio = PAREN_INNER_PRIO; lprio = PAREN_OUTER_PRIO; rprio = PAREN_INNER_PRIO + 1;
goto maybe_reduce; goto skip_reduction;
case ')': case ')':
lprio = PAREN_INNER_PRIO; rprio = PAREN_OUTER_PRIO; lprio = PAREN_INNER_PRIO; rprio = PAREN_OUTER_PRIO;
flags = HAVE_VALUE; /* At least, we will have after reduction. */ flags = HAVE_VALUE; /* At least, we will have after reduction. */
...@@ -758,26 +772,11 @@ _cpp_parse_expr (pfile) ...@@ -758,26 +772,11 @@ _cpp_parse_expr (pfile)
case '?': case '?':
lprio = COND_PRIO; rprio = COND_PRIO; lprio = COND_PRIO; rprio = COND_PRIO;
goto maybe_reduce; goto maybe_reduce;
case ERROR: case 0:
goto syntax_error; lprio = 0; goto maybe_reduce;
default:
cpp_error (pfile, "invalid character in #if");
goto syntax_error;
}
set_value:
/* Push a value onto the stack. */
if (top->flags & HAVE_VALUE)
{
cpp_error (pfile, "syntax error in #if");
goto syntax_error;
} }
top->value = op.value;
top->unsignedp = op.unsignedp;
top->flags |= HAVE_VALUE;
continue;
binop: /* Binary operation. */
flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED; flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED;
rprio = lprio + 1; rprio = lprio + 1;
...@@ -953,7 +952,7 @@ _cpp_parse_expr (pfile) ...@@ -953,7 +952,7 @@ _cpp_parse_expr (pfile)
top->value = v2; top->value = v2;
top->unsignedp = unsigned2; top->unsignedp = unsigned2;
break; break;
case '(': case '?': case '?':
cpp_error (pfile, "syntax error in #if"); cpp_error (pfile, "syntax error in #if");
goto syntax_error; goto syntax_error;
case ':': case ':':
...@@ -979,21 +978,22 @@ _cpp_parse_expr (pfile) ...@@ -979,21 +978,22 @@ _cpp_parse_expr (pfile)
} }
break; break;
case ')': case ')':
if (! (top[0].flags & HAVE_VALUE) cpp_error (pfile, "missing '(' in expression");
|| top[0].op != '(' goto syntax_error;
|| (top[-1].flags & HAVE_VALUE)) case '(':
if (op.op != ')')
{ {
cpp_error (pfile, "mismatched parentheses in #if"); cpp_error (pfile, "missing ')' in expression");
goto syntax_error; goto syntax_error;
} }
else if (!(top[1].flags & HAVE_VALUE))
{ {
top--; cpp_error (pfile, "void expression between '(' and ')'");
top->value = v1; goto syntax_error;
top->unsignedp = unsigned1;
top->flags |= HAVE_VALUE;
} }
break; op.value = v2;
op.unsignedp = unsigned2;
goto push_immediate;
default: default:
if (ISGRAPH (top[1].op)) if (ISGRAPH (top[1].op))
cpp_error (pfile, "unimplemented operator '%c'\n", top[1].op); cpp_error (pfile, "unimplemented operator '%c'\n", top[1].op);
...@@ -1002,18 +1002,13 @@ _cpp_parse_expr (pfile) ...@@ -1002,18 +1002,13 @@ _cpp_parse_expr (pfile)
top[1].op); top[1].op);
} }
} }
if (op.op == 0) if (op.op == 0)
{ break;
if (top != stack)
cpp_ice (pfile, "unbalanced stack in #if expression"); skip_reduction:
if (!(top->flags & HAVE_VALUE))
cpp_error (pfile, "#if with no expression");
result = (top->value != 0);
goto done;
}
top++;
/* Check for and handle stack overflow. */ /* Check for and handle stack overflow. */
top++;
if (top == limit) if (top == limit)
{ {
struct operation *new_stack; struct operation *new_stack;
...@@ -1034,6 +1029,8 @@ _cpp_parse_expr (pfile) ...@@ -1034,6 +1029,8 @@ _cpp_parse_expr (pfile)
top->flags = flags; top->flags = flags;
top->rprio = rprio; top->rprio = rprio;
top->op = op.op; top->op = op.op;
/* Handle short circuiting. */
if ((op.op == OROR && top[-1].value) if ((op.op == OROR && top[-1].value)
|| (op.op == ANDAND && !top[-1].value) || (op.op == ANDAND && !top[-1].value)
|| (op.op == '?' && !top[-1].value)) || (op.op == '?' && !top[-1].value))
...@@ -1048,13 +1045,22 @@ _cpp_parse_expr (pfile) ...@@ -1048,13 +1045,22 @@ _cpp_parse_expr (pfile)
skip_evaluation--; skip_evaluation--;
} }
} }
syntax_error:
_cpp_skip_rest_of_line (pfile); if (top != stack)
result = 0; cpp_ice (pfile, "unbalanced stack in #if expression");
done: if (!(top->flags & HAVE_VALUE))
cpp_error (pfile, "#if with no expression");
result = (top->value != 0);
tidy_up:
pfile->parsing_if_directive--; pfile->parsing_if_directive--;
CPP_SET_WRITTEN (pfile, old_written); CPP_SET_WRITTEN (pfile, old_written);
if (stack != init_stack) if (stack != init_stack)
free (stack); free (stack);
return result; return result;
syntax_error:
_cpp_skip_rest_of_line (pfile);
result = 0;
goto tidy_up;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment