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:
@@ -506,7 +506,8 @@ struct token_parse_result arith_parse_in(
|
||||
|
||||
if (expr_terminates_at_token(state, IVY_KW_IN)) {
|
||||
/* 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;
|
||||
return result;
|
||||
}
|
||||
@@ -592,16 +593,19 @@ struct token_parse_result arith_parse_left_paren(
|
||||
}
|
||||
|
||||
if (state->s_prev_token == IVY_TOK_IDENT) {
|
||||
/* this is the opening parenthesis for a complex message. */
|
||||
b_queue_entry *msg_entry
|
||||
= b_queue_pop_back(&state->s_operator_stack);
|
||||
/* this might be the opening parenthesis for a complex message. */
|
||||
b_queue_entry *msg_entry = b_queue_last(&state->s_operator_stack);
|
||||
struct ivy_ast_node *msg
|
||||
= b_unbox(struct ivy_ast_node, msg_entry, n_entry);
|
||||
|
||||
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 *)parser_push_state(
|
||||
ctx, IVY_AST_EXPR, 0);
|
||||
@@ -614,8 +618,28 @@ struct token_parse_result arith_parse_left_paren(
|
||||
return PARSE_RESULT(IVY_OK, 0);
|
||||
}
|
||||
|
||||
/* a sub-expression surrounded by parentheses is parsed by creating
|
||||
* a sub-expression parser state */
|
||||
not_complex_msg:
|
||||
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 *)parser_push_state(
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -696,15 +721,19 @@ struct token_parse_result arith_parse_left_bracket(
|
||||
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 */
|
||||
|
||||
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);
|
||||
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);
|
||||
index->s_subexpr_depth = state->s_subexpr_depth + 1;
|
||||
|
||||
@@ -1185,8 +1214,10 @@ struct token_parse_result arith_parse_comma(
|
||||
/* empty tuple member expression. */
|
||||
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);
|
||||
} else {
|
||||
/* 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
|
||||
* parent keyword-message parser context. */
|
||||
struct ivy_ast_node *expr = NULL;
|
||||
struct token_parse_result result = expr_finalise(ctx,
|
||||
state, IVY_PRECEDENCE_ASSIGN, &expr);
|
||||
struct token_parse_result result
|
||||
= expr_finalise(ctx, state, IVY_PRECEDENCE_ASSIGN, &expr);
|
||||
if (result.r_status != IVY_OK) {
|
||||
return result;
|
||||
}
|
||||
@@ -1336,4 +1367,4 @@ enum ivy_status arith_add_child(
|
||||
}
|
||||
|
||||
return IVY_OK;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user