diff --git a/lang/ast/expr/arith.c b/lang/ast/expr/arith.c index 4bfaa62..eb548de 100644 --- a/lang/ast/expr/arith.c +++ b/lang/ast/expr/arith.c @@ -670,14 +670,32 @@ static enum ivy_status begin_cascade_operation(struct ivy_parser *ctx) first_msg = expr_finalise_keyword_msg(state); parser_pop_state(ctx, 0); } else { + /* we need to find who the first message in the cascade is being sent to. */ + enum ivy_operator_precedence min_precedence = IVY_PRECEDENCE_CASCADE; + + struct ivy_ast_node *prev = b_unbox( + struct ivy_ast_node, + b_queue_last(&state->s_operator_stack), n_entry); + if (prev && prev->n_type == IVY_AST_MSG) { + /* unary complex messages (which will be found on the operator stack) have a very high + * precedence (much higher than most arithmetic operators), so the recipient will be much + * narrower. this also means that any subsequent messages in the cascade inherit this high + * precedence, regardless of their type. */ + min_precedence = IVY_PRECEDENCE_UNARY_MSG; + } + struct ivy_ast_node *expr = NULL; enum ivy_status status - = expr_finalise_arith(state, &expr, IVY_PRECEDENCE_CASCADE); + = expr_finalise_arith(state, &expr, min_precedence); if (status != IVY_OK) { return status; } if (expr->n_type != IVY_AST_MSG) { + /* the recipient and first message of the cascade operation is ambiguous due + * to operator precedence. this is usually resolved by adding parentheses + * (either around the recipient or around the cascade) to make the recipient + * and first message clear. */ return IVY_ERR_BAD_SYNTAX; }