lang: ast: implement () operator parsing

the () operator can be used to call lambdas in a more functional way than the standard
message-send syntax

for example, with a lambda stored in variable `x`:

	x(a:2 b:6).

is equivalent to

	x call(a:2 b:6).
This commit is contained in:
2025-03-26 21:10:12 +00:00
parent 0c500dc19b
commit 78b2eb23c3

View File

@@ -506,7 +506,8 @@ struct token_parse_result arith_parse_in(
if (expr_terminates_at_token(state, IVY_KW_IN)) { if (expr_terminates_at_token(state, IVY_KW_IN)) {
/* treat this as a statement terminator. */ /* treat this as a statement terminator. */
struct token_parse_result result = expr_finalise_and_return(ctx, state); struct token_parse_result result
= expr_finalise_and_return(ctx, state);
result.r_flags |= PARSE_REPEAT_TOKEN; result.r_flags |= PARSE_REPEAT_TOKEN;
return result; return result;
} }
@@ -592,16 +593,19 @@ struct token_parse_result arith_parse_left_paren(
} }
if (state->s_prev_token == IVY_TOK_IDENT) { if (state->s_prev_token == IVY_TOK_IDENT) {
/* this is the opening parenthesis for a complex message. */ /* this might be the opening parenthesis for a complex message. */
b_queue_entry *msg_entry b_queue_entry *msg_entry = b_queue_last(&state->s_operator_stack);
= b_queue_pop_back(&state->s_operator_stack);
struct ivy_ast_node *msg struct ivy_ast_node *msg
= b_unbox(struct ivy_ast_node, msg_entry, n_entry); = b_unbox(struct ivy_ast_node, msg_entry, n_entry);
if (msg->n_type != IVY_AST_MSG) { if (msg->n_type != IVY_AST_MSG) {
return PARSE_RESULT(IVY_ERR_INTERNAL_FAILURE, 0); /* this is not a complex message, it's probably a
* call-operator */
goto not_complex_msg;
} }
b_queue_pop_back(&state->s_operator_stack);
struct expr_parser_state *msg_expr struct expr_parser_state *msg_expr
= (struct expr_parser_state *)parser_push_state( = (struct expr_parser_state *)parser_push_state(
ctx, IVY_AST_EXPR, 0); ctx, IVY_AST_EXPR, 0);
@@ -614,8 +618,28 @@ struct token_parse_result arith_parse_left_paren(
return PARSE_RESULT(IVY_OK, 0); return PARSE_RESULT(IVY_OK, 0);
} }
/* a sub-expression surrounded by parentheses is parsed by creating not_complex_msg:
* a sub-expression parser state */ if (state->s_prev_component == EXPR_CMP_OPERAND) {
/* this is the opening parenthesis for a call-operator */
struct ivy_ast_msg_node *msg
= (struct ivy_ast_msg_node *)ast_node_create(IVY_AST_MSG);
msg->n_sel = unary_selector_from_token(
ivy_token_create_ident("call"));
struct expr_parser_state *msg_expr
= (struct expr_parser_state *)parser_push_state(
ctx, IVY_AST_EXPR, 0);
msg_expr->s_msg = (struct ivy_ast_msg_node *)msg;
msg_expr->s_sub_type = EXPR_SUBTYPE_COMPLEX_MSG;
msg_expr->s_type = EXPR_TYPE_ARITH;
msg_expr->s_subexpr_depth = state->s_subexpr_depth + 1;
return PARSE_RESULT(IVY_OK, 0);
}
/* this is a generic parenthesis-enclosed sub-expression.
* create a new sub-expr parser to handle it */
struct expr_parser_state *sub_expr struct expr_parser_state *sub_expr
= (struct expr_parser_state *)parser_push_state( = (struct expr_parser_state *)parser_push_state(
ctx, IVY_AST_EXPR, 0); ctx, IVY_AST_EXPR, 0);
@@ -666,7 +690,8 @@ struct token_parse_result arith_parse_left_brace(
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0); return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
} }
if (state->s_prev_component != EXPR_CMP_OPERATOR && state->s_prev_component != EXPR_CMP_NONE) { if (state->s_prev_component != EXPR_CMP_OPERATOR
&& state->s_prev_component != EXPR_CMP_NONE) {
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0); return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
} }
@@ -696,15 +721,19 @@ struct token_parse_result arith_parse_left_bracket(
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0); return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
} }
if (state->s_prev_component == EXPR_CMP_OPERAND || state->s_prev_component == EXPR_CMP_MSG) { if (state->s_prev_component == EXPR_CMP_OPERAND
|| state->s_prev_component == EXPR_CMP_MSG) {
/* subscript operator */ /* subscript operator */
state->s_prev_token = IVY_SYM_LEFT_BRACKET; state->s_prev_token = IVY_SYM_LEFT_BRACKET;
struct ivy_ast_op_node *subscript = (struct ivy_ast_op_node *)ast_node_create(IVY_AST_OP); struct ivy_ast_op_node *subscript
= (struct ivy_ast_op_node *)ast_node_create(IVY_AST_OP);
subscript->n_op = ivy_operator_get_by_id(IVY_OP_SUBSCRIPT); subscript->n_op = ivy_operator_get_by_id(IVY_OP_SUBSCRIPT);
arith_push_operator(state, (struct ivy_ast_node *)subscript); arith_push_operator(state, (struct ivy_ast_node *)subscript);
struct expr_parser_state *index = (struct expr_parser_state *)parser_push_state(ctx, IVY_AST_EXPR, 0); struct expr_parser_state *index
= (struct expr_parser_state *)parser_push_state(
ctx, IVY_AST_EXPR, 0);
expr_add_terminator(index, IVY_SYM_RIGHT_BRACKET); expr_add_terminator(index, IVY_SYM_RIGHT_BRACKET);
index->s_subexpr_depth = state->s_subexpr_depth + 1; index->s_subexpr_depth = state->s_subexpr_depth + 1;
@@ -1185,8 +1214,10 @@ struct token_parse_result arith_parse_comma(
/* empty tuple member expression. */ /* empty tuple member expression. */
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0); return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
} }
if (state->s_sub_type == EXPR_SUBTYPE_PAREN && b_queue_empty(&state->s_output_queue) && b_queue_empty(&state->s_operator_stack)) { if (state->s_sub_type == EXPR_SUBTYPE_PAREN
&& b_queue_empty(&state->s_output_queue)
&& b_queue_empty(&state->s_operator_stack)) {
parser_pop_state(ctx, 0); parser_pop_state(ctx, 0);
} else { } else {
/* the tuple parser will handle the parentheses for us. */ /* the tuple parser will handle the parentheses for us. */
@@ -1230,8 +1261,8 @@ struct token_parse_result arith_parse_label(
* next argument. terminate here and propagate this label to the * next argument. terminate here and propagate this label to the
* parent keyword-message parser context. */ * parent keyword-message parser context. */
struct ivy_ast_node *expr = NULL; struct ivy_ast_node *expr = NULL;
struct token_parse_result result = expr_finalise(ctx, struct token_parse_result result
state, IVY_PRECEDENCE_ASSIGN, &expr); = expr_finalise(ctx, state, IVY_PRECEDENCE_ASSIGN, &expr);
if (result.r_status != IVY_OK) { if (result.r_status != IVY_OK) {
return result; return result;
} }
@@ -1336,4 +1367,4 @@ enum ivy_status arith_add_child(
} }
return IVY_OK; return IVY_OK;
} }