#include "ctx.h" #include bool is_tuple_terminator(struct ivy_token *tok) { const struct ivy_operator *op = get_operator_from_token(tok); switch (tok->t_type) { case IVY_TOK_SYMBOL: switch (tok->t_symbol) { case IVY_SYM_DOT: case IVY_SYM_RIGHT_PAREN: case IVY_SYM_RIGHT_BRACE: case IVY_SYM_RIGHT_BRACKET: return true; default: op = get_operator_from_token(tok); break; } break; default: break; } if (op && op->op_precedence < IVY_PRECEDENCE_KEYWORD_MSG) { return true; } return false; } bool parse_tuple( struct ivy_parser *parser, struct ivy_ast_node *first_item, struct ivy_ast_node **out) { struct ivy_ast_tuple_node *tuple = create_node(IVY_AST_TUPLE); fx_queue_push_back(&tuple->n_members, &first_item->n_entry); bool ok = true; bool done = false; while (!done) { struct ivy_token *tok = peek_token(parser); if (!tok) { parse_trace( parser, "unexpected EOF while parsing tuple"); ok = false; break; } if (is_tuple_terminator(tok)) { break; } if (!parse_symbol(parser, IVY_SYM_COMMA)) { parse_trace(parser, "expected `,` after tuple item"); ok = false; break; } struct ivy_ast_node *value = NULL; if (!parse_expr( parser, EXPR_PARSE_STOP_COMMA | EXPR_PARSE_STOP_TUPLE_TERMINATOR, &value)) { parse_trace(parser, "invalid tuple item"); ok = false; break; } fx_queue_push_back(&tuple->n_members, &value->n_entry); } *out = generic_node(tuple); return true; }