lang: ast: complex-msg args are now separated by commas
additionally, unnamed complex-msg args no longer need to be prefixed with a colon. this allows complex-msgs to more closely emulate traditional function calls. this also applies to the call-operator. for example, take the following lambda: var f = [ :x :y | ^x * 2 + y ]. before, this lambda would be invoked using the following syntax: f(:2 :4). now, this syntax is used instead: f(2, 4).
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include <ivy/lang/lex.h>
|
||||
#include <ivy/lang/operator.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void print_operand(struct ivy_ast_node *node)
|
||||
{
|
||||
@@ -448,6 +449,33 @@ struct token_parse_result arith_parse_operand(
|
||||
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
|
||||
}
|
||||
|
||||
if (state->s_sub_type == EXPR_SUBTYPE_COMPLEX_MSG) {
|
||||
/* this is an unlabeled complex message arg */
|
||||
if (state->s_prev_token != IVY_SYM_COMMA
|
||||
&& state->s_prev_token != IVY_SYM_LEFT_PAREN) {
|
||||
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
|
||||
}
|
||||
|
||||
struct ivy_token *empty_label = malloc(sizeof *empty_label);
|
||||
if (!empty_label) {
|
||||
return PARSE_RESULT(IVY_ERR_NO_MEMORY, 0);
|
||||
}
|
||||
memset(empty_label, 0x0, sizeof *empty_label);
|
||||
empty_label->t_type = IVY_TOK_LABEL;
|
||||
|
||||
b_queue_push_back(&state->s_labels, &empty_label->t_entry);
|
||||
|
||||
struct expr_parser_state *arg_expr
|
||||
= (struct expr_parser_state *)parser_push_state(
|
||||
ctx, IVY_AST_EXPR, 0);
|
||||
expr_copy_terminators(state, arg_expr);
|
||||
expr_add_terminator(arg_expr, IVY_SYM_COMMA);
|
||||
arg_expr->s_sub_type = EXPR_SUBTYPE_COMPLEX_ARG;
|
||||
arg_expr->s_subexpr_depth = state->s_subexpr_depth + 1;
|
||||
|
||||
return PARSE_RESULT(IVY_OK, PARSE_REPEAT_TOKEN);
|
||||
}
|
||||
|
||||
if (state->s_prev_component == EXPR_CMP_OPERAND) {
|
||||
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
|
||||
}
|
||||
@@ -623,11 +651,14 @@ struct token_parse_result arith_parse_left_paren(
|
||||
= (struct expr_parser_state *)parser_push_state(
|
||||
ctx, IVY_AST_EXPR, 0);
|
||||
|
||||
expr_add_terminator(msg_expr, IVY_SYM_COMMA);
|
||||
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;
|
||||
|
||||
msg_expr->s_prev_token = state->s_prev_token = IVY_SYM_LEFT_PAREN;
|
||||
|
||||
return PARSE_RESULT(IVY_OK, 0);
|
||||
}
|
||||
|
||||
@@ -648,6 +679,8 @@ not_complex_msg:
|
||||
msg_expr->s_type = EXPR_TYPE_ARITH;
|
||||
msg_expr->s_subexpr_depth = state->s_subexpr_depth + 1;
|
||||
|
||||
msg_expr->s_prev_token = state->s_prev_token = IVY_SYM_LEFT_PAREN;
|
||||
|
||||
return PARSE_RESULT(IVY_OK, 0);
|
||||
}
|
||||
|
||||
@@ -974,6 +1007,7 @@ struct token_parse_result arith_parse_semicolon(
|
||||
break;
|
||||
case EXPR_SUBTYPE_KEYWORD_MSG:
|
||||
case EXPR_SUBTYPE_CASCADE:
|
||||
case EXPR_SUBTYPE_COMPLEX_ARG:
|
||||
case EXPR_SUBTYPE_NONE:
|
||||
break;
|
||||
default:
|
||||
@@ -1217,6 +1251,12 @@ struct token_parse_result arith_parse_comma(
|
||||
struct expr_parser_state *state
|
||||
= parser_get_state(ctx, struct expr_parser_state);
|
||||
|
||||
if (state->s_sub_type == EXPR_SUBTYPE_COMPLEX_MSG) {
|
||||
/* this is a comma separator between two complex message args */
|
||||
state->s_prev_token = IVY_SYM_COMMA;
|
||||
return PARSE_RESULT(IVY_OK, 0);
|
||||
}
|
||||
|
||||
if (expr_terminates_at_token(state, IVY_SYM_COMMA)) {
|
||||
struct token_parse_result result
|
||||
= expr_finalise_and_return(ctx, state);
|
||||
@@ -1348,8 +1388,23 @@ struct token_parse_result arith_parse_label(
|
||||
state = msg_expr;
|
||||
}
|
||||
|
||||
if (state->s_sub_type == EXPR_SUBTYPE_KEYWORD_MSG
|
||||
|| state->s_sub_type == EXPR_SUBTYPE_COMPLEX_MSG) {
|
||||
if (state->s_sub_type == EXPR_SUBTYPE_COMPLEX_MSG) {
|
||||
/* this label denotes the start of a complex message arg */
|
||||
if (state->s_prev_token != IVY_SYM_COMMA
|
||||
&& state->s_prev_token != IVY_SYM_LEFT_PAREN) {
|
||||
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
|
||||
}
|
||||
|
||||
b_queue_push_back(&state->s_labels, &tok->t_entry);
|
||||
|
||||
struct expr_parser_state *arg_expr
|
||||
= (struct expr_parser_state *)parser_push_state(
|
||||
ctx, IVY_AST_EXPR, 0);
|
||||
expr_copy_terminators(state, arg_expr);
|
||||
expr_add_terminator(arg_expr, IVY_SYM_COMMA);
|
||||
arg_expr->s_sub_type = EXPR_SUBTYPE_COMPLEX_ARG;
|
||||
arg_expr->s_subexpr_depth = state->s_subexpr_depth + 1;
|
||||
} else if (state->s_sub_type == EXPR_SUBTYPE_KEYWORD_MSG) {
|
||||
/* we may have just finished parsing a keyword-message argument,
|
||||
* and this label marks the start of a new one. store the label
|
||||
* and create a new argument parsing context. */
|
||||
|
||||
@@ -33,6 +33,8 @@ enum expr_subtype {
|
||||
EXPR_SUBTYPE_KEYWORD_ARG,
|
||||
/* complex messages */
|
||||
EXPR_SUBTYPE_COMPLEX_MSG,
|
||||
/* expression delimited by commas */
|
||||
EXPR_SUBTYPE_COMPLEX_ARG,
|
||||
/* message cascade operation */
|
||||
EXPR_SUBTYPE_CASCADE,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user