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)) {
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user