mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-07 00:11:39 +00:00
--traditional now "fixes" (ie, breaks) operator precedence to match qcc
except for the relationship between "=" and "&&" and "||": not sure I want to go that far towards bug compatability.
This commit is contained in:
parent
ad61e0684c
commit
ba26628b80
1 changed files with 48 additions and 12 deletions
|
@ -1508,6 +1508,52 @@ is_logic (int op)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static expr_t *
|
||||||
|
check_precedence (int op, expr_t *e1, expr_t *e2)
|
||||||
|
{
|
||||||
|
if (e1->type == ex_uexpr && e1->e.expr.op == '!' && !e1->paren) {
|
||||||
|
if (options.traditional) {
|
||||||
|
if (op != AND && op != OR && op != '=') {
|
||||||
|
notice (e1, "precedence of `!' and `%s' inverted for "
|
||||||
|
"traditional code", get_op_string (op));
|
||||||
|
e1->e.expr.e1->paren = 1;
|
||||||
|
return unary_expr ('!', binary_expr (op, e1->e.expr.e1, e2));
|
||||||
|
}
|
||||||
|
} else if (op == '&' || op == '|') {
|
||||||
|
warning (e1, "ambiguous logic. Suggest explicit parentheses with "
|
||||||
|
"expressions involving ! and %s", get_op_string (op));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (options.traditional) {
|
||||||
|
if (e2->type == ex_expr && !e2->paren) {
|
||||||
|
if (((op == '&' || op == '|')
|
||||||
|
&& (e2->e.expr.op == '*' || e2->e.expr.op == '/'
|
||||||
|
|| e2->e.expr.op == '+' || e2->e.expr.op == '-'
|
||||||
|
|| is_compare (e2->e.expr.op)))
|
||||||
|
|| (op == '='
|
||||||
|
&& (e2->e.expr.op == OR || e2->e.expr.op == AND))) {
|
||||||
|
notice (e1, "precedence of `%s' and `%s' inverted for "
|
||||||
|
"traditional code", get_op_string (op),
|
||||||
|
get_op_string (e2->e.expr.op));
|
||||||
|
e1 = binary_expr (op, e1, e2->e.expr.e1);
|
||||||
|
e1->paren = 1;
|
||||||
|
return binary_expr (e2->e.expr.op, e1, e2->e.expr.e2);
|
||||||
|
}
|
||||||
|
if (((op == EQ || op == NE) && is_compare (e2->e.expr.op))
|
||||||
|
|| (op == OR && e2->e.expr.op == AND)
|
||||||
|
|| (op == '|' && e2->e.expr.op == '&')) {
|
||||||
|
notice (e1, "precedence of `%s' raised to `%s' for "
|
||||||
|
"traditional code", get_op_string (op),
|
||||||
|
get_op_string (e2->e.expr.op));
|
||||||
|
e1 = binary_expr (op, e1, e2->e.expr.e1);
|
||||||
|
e1->paren = 1;
|
||||||
|
return binary_expr (e2->e.expr.op, e1, e2->e.expr.e2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
expr_t *
|
expr_t *
|
||||||
binary_expr (int op, expr_t *e1, expr_t *e2)
|
binary_expr (int op, expr_t *e1, expr_t *e2)
|
||||||
{
|
{
|
||||||
|
@ -1626,18 +1672,8 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
|
||||||
if (e1->type >= ex_string && e2->type >= ex_string)
|
if (e1->type >= ex_string && e2->type >= ex_string)
|
||||||
return binary_const (op, e1, e2);
|
return binary_const (op, e1, e2);
|
||||||
|
|
||||||
if ((op == '&' || op == '|' || is_compare (op))
|
if ((e = check_precedence (op, e1, e2)))
|
||||||
&& e1->type == ex_uexpr && e1->e.expr.op == '!' && !e1->paren) {
|
return e;
|
||||||
if (options.traditional) {
|
|
||||||
notice (e1, "precedence of `!' and `%s' inverted for traditional "
|
|
||||||
"code", get_op_string (op));
|
|
||||||
e1->e.expr.e1->paren = 1;
|
|
||||||
return unary_expr ('!', binary_expr (op, e1->e.expr.e1, e2));
|
|
||||||
} else if (!is_compare (op)) {
|
|
||||||
warning (e1, "ambiguous logic. Suggest explicit parentheses with "
|
|
||||||
"expressions involving ! and %s", get_op_string (op));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (t1 != t2) {
|
if (t1 != t2) {
|
||||||
switch (t1->type) {
|
switch (t1->type) {
|
||||||
|
|
Loading…
Reference in a new issue