lang: ast: improve cascade operator recipient resolution
the cascade operator now uses the precedence of the last message parsed to determine the recipient of the subsequent messages, reducing the need for parentheses and making the semantics of the operator more predictable. all messages in a cascade now inherit the precedence of the first message in the cascade.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user