diff --git a/lang/ast/expr/arith.c b/lang/ast/expr/arith.c index 6fb3802..729204f 100644 --- a/lang/ast/expr/arith.c +++ b/lang/ast/expr/arith.c @@ -696,10 +696,23 @@ struct token_parse_result arith_parse_left_bracket( return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0); } - if (state->s_prev_component == EXPR_CMP_OPERAND) { - return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0); + 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); + 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); + expr_add_terminator(index, IVY_SYM_RIGHT_BRACKET); + index->s_subexpr_depth = state->s_subexpr_depth + 1; + + return PARSE_RESULT(IVY_OK, 0); } + /* lambda */ + state->s_prev_token = IVY_SYM_LEFT_BRACKET; state->s_type = EXPR_TYPE_ARITH; @@ -713,6 +726,11 @@ struct token_parse_result arith_parse_right_bracket( struct expr_parser_state *state = parser_get_state(ctx, struct expr_parser_state); + if (state->s_prev_token == IVY_SYM_LEFT_BRACKET) { + /* we've just parsed a subscript operator. nothing further to do here. */ + return PARSE_RESULT(IVY_OK, 0); + } + state->s_prev_token = IVY_SYM_RIGHT_BRACKET; struct token_parse_result result = expr_finalise_and_return(ctx, state); result.r_flags = PARSE_REPEAT_TOKEN; diff --git a/lang/include/ivy/lang/operator.h b/lang/include/ivy/lang/operator.h index 5b31154..89bcbc8 100644 --- a/lang/include/ivy/lang/operator.h +++ b/lang/include/ivy/lang/operator.h @@ -78,6 +78,7 @@ enum ivy_operator_id { IVY_OP_UNDERSTANDS, IVY_OP_SELF_ACCESS, IVY_OP_PKG_ACCESS, + IVY_OP_SUBSCRIPT, /* these are not real operators, and are just used internally by the parser. */ IVY_OP_MSG, diff --git a/lang/operator.c b/lang/operator.c index 8436aeb..8663c09 100644 --- a/lang/operator.c +++ b/lang/operator.c @@ -55,6 +55,7 @@ static const struct ivy_operator operators[] = { OP(UNDERSTANDS, IS, LEFT, INFIX, BINARY), OP(SELF_ACCESS, SUBSCRIPT, LEFT, INFIX, BINARY), OP(PKG_ACCESS, SUBSCRIPT, LEFT, INFIX, BINARY), + OP(SUBSCRIPT, SUBSCRIPT, LEFT, INFIX, BINARY), /* parser-internal pseudo-operators. */ OP(MSG, UNARY_MSG, LEFT, POSTFIX, UNARY), @@ -201,6 +202,7 @@ const char *ivy_operator_id_to_string(enum ivy_operator_id op) ENUM_STR(IVY_OP_UNDERSTANDS); ENUM_STR(IVY_OP_SELF_ACCESS); ENUM_STR(IVY_OP_PKG_ACCESS); + ENUM_STR(IVY_OP_SUBSCRIPT); ENUM_STR(IVY_OP_MSG); ENUM_STR(IVY_OP_LEFT_PAREN); default: