From 8568b9b0795c6b56b5ce481b4879cd5b9dc9a4b5 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Mon, 19 Jul 2021 17:31:13 +0200 Subject: [PATCH] Fix right -> left associativity for assignment. --- src/compiler/parse_expr.c | 10 +++++++- .../expressions/assignment_precedence.c3t | 23 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 test/test_suite/expressions/assignment_precedence.c3t diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index 3478902d9..bcd5ac94c 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -391,7 +391,15 @@ static Expr *parse_binary(Context *context, Expr *left_side) } else { - right_side = TRY_EXPR_OR(parse_precedence(context, rules[operator_type].precedence + 1), poisoned_expr); + // Assignment operators have precedence right -> left. + if (rules[operator_type].precedence == PREC_ASSIGNMENT) + { + right_side = TRY_EXPR_OR(parse_precedence(context, PREC_ASSIGNMENT), poisoned_expr); + } + else + { + right_side = TRY_EXPR_OR(parse_precedence(context, rules[operator_type].precedence + 1), poisoned_expr); + } } Expr *expr = EXPR_NEW_EXPR(EXPR_BINARY, left_side); diff --git a/test/test_suite/expressions/assignment_precedence.c3t b/test/test_suite/expressions/assignment_precedence.c3t new file mode 100644 index 000000000..71ab108ff --- /dev/null +++ b/test/test_suite/expressions/assignment_precedence.c3t @@ -0,0 +1,23 @@ +module prec; + +func void test() +{ + int i = 1; + int j = 2; + int k = 3; + int l = i = j = k; +} + +// #expect: prec.ll + + %i = alloca i32, align 4 + %j = alloca i32, align 4 + %k = alloca i32, align 4 + %l = alloca i32, align 4 + store i32 1, i32* %i, align 4 + store i32 2, i32* %j, align 4 + store i32 3, i32* %k, align 4 + %0 = load i32, i32* %k, align 4 + store i32 %0, i32* %j, align 4 + store i32 %0, i32* %i, align 4 + store i32 %0, i32* %l, align 4 \ No newline at end of file