mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Forced parentheses on unclear precedence (#109)
forced parentheses to resolve issue #97
This commit is contained in:
@@ -6,6 +6,21 @@
|
||||
#include "parser_internal.h"
|
||||
#include "bigint.h"
|
||||
|
||||
#define BINOP_PREC_REQ_LEN 40
|
||||
int BINOP_PREC_REQ[BINOP_PREC_REQ_LEN] = {
|
||||
// bitwise operations
|
||||
[BINARYOP_BIT_OR] = 1,
|
||||
[BINARYOP_BIT_XOR] = 1,
|
||||
[BINARYOP_BIT_AND] = 1,
|
||||
|
||||
// comparison operations
|
||||
[BINARYOP_GT] = 2,
|
||||
[BINARYOP_GE] = 2,
|
||||
[BINARYOP_LT] = 2,
|
||||
[BINARYOP_LE] = 2,
|
||||
[BINARYOP_NE] = 2,
|
||||
[BINARYOP_EQ] = 2
|
||||
};
|
||||
|
||||
typedef Expr *(*ParseFn)(Context *context, Expr *);
|
||||
|
||||
@@ -367,6 +382,23 @@ static Expr *parse_failable(Context *context, Expr *left_side)
|
||||
return failable;
|
||||
}
|
||||
|
||||
|
||||
bool plain_op_precedence(Expr *left_side, Expr * main_expr, Expr *right_side)
|
||||
{
|
||||
int precedence_main = BINOP_PREC_REQ[main_expr->binary_expr.operator];
|
||||
if (left_side->expr_kind == EXPR_BINARY)
|
||||
{
|
||||
int precedence_left = BINOP_PREC_REQ[left_side->binary_expr.operator];
|
||||
return !(precedence_left && (precedence_left == precedence_main));
|
||||
}
|
||||
if (right_side->expr_kind == EXPR_BINARY)
|
||||
{
|
||||
int precedence_right = BINOP_PREC_REQ[right_side->binary_expr.operator];
|
||||
return !(precedence_right && (precedence_right == precedence_main));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static Expr *parse_binary(Context *context, Expr *left_side)
|
||||
{
|
||||
assert(left_side && expr_ok(left_side));
|
||||
@@ -390,6 +422,13 @@ static Expr *parse_binary(Context *context, Expr *left_side)
|
||||
expr->binary_expr.operator = binaryop_from_token(operator_type);
|
||||
expr->binary_expr.left = left_side;
|
||||
expr->binary_expr.right = right_side;
|
||||
|
||||
// check if both sides have a binary operation where the precedence is unclear. Example: a ^ b | c
|
||||
if (!plain_op_precedence(left_side, expr, right_side))
|
||||
{
|
||||
SEMA_TOKEN_ERROR(context->tok, "You need to add explicit parentheses.");
|
||||
}
|
||||
|
||||
expr->span.end_loc = right_side->span.end_loc;
|
||||
return expr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user