#include "ctx.h" #include bool parse_cascade( struct ivy_parser *parser, struct ivy_ast_node *first_msg, struct ivy_ast_node **out) { if (!peek_symbol(parser, IVY_SYM_SEMICOLON)) { parse_trace(parser, "expected `;`"); return false; } struct ivy_ast_msg_node *first = (struct ivy_ast_msg_node *)first_msg; if (first->n_base.n_type != IVY_AST_MSG) { parse_trace(parser, "cascade operand is not a message"); return false; } struct ivy_ast_cascade_node *cascade = create_node(IVY_AST_CASCADE); cascade->n_recipient = first->n_recipient; first->n_recipient = NULL; fx_queue_push_back(&cascade->n_msg, &first->n_base.n_entry); bool ok = true; while (ok) { parse_linefeed(parser); if (!parse_symbol(parser, IVY_SYM_SEMICOLON)) { break; } parse_linefeed(parser); fx_queue_entry *entry = NULL; struct ivy_ast_msg_node *msg = NULL; struct ivy_token *tok = peek_token(parser); if (!tok) { break; } switch (tok->t_type) { case IVY_TOK_LABEL: ok = parse_keyword_msg( parser, cascade->n_recipient, EXPR_PARSE_STOP_SEMICOLON, (struct ivy_ast_node **)&msg); if (!ok) { break; } break; case IVY_TOK_IDENT: ok = parse_unary_msg( parser, cascade->n_recipient, (struct ivy_ast_node **)&msg); if (!ok) { break; } if (peek_symbol(parser, IVY_SYM_LEFT_PAREN)) { ok = parse_complex_msg( parser, generic_node(msg), (struct ivy_ast_node **)&msg); } break; default: parse_trace(parser, "expected message after `;`"); ok = false; break; } msg->n_recipient = NULL; fx_queue_push_back(&cascade->n_msg, &msg->n_base.n_entry); } *out = generic_node(cascade); return true; }