#include "ctx.h" #include bool parse_unary_msg( struct ivy_parser *parser, struct ivy_ast_node *recipient, struct ivy_ast_node **out) { struct ivy_token *selector_tok = NULL; if (!parse_word(parser, &selector_tok)) { parse_trace(parser, "expected unary message selector"); return false; } struct ivy_ast_selector_node *sel = create_node(IVY_AST_SELECTOR); sel->n_msg_name = selector_tok; struct ivy_ast_msg_node *msg = create_node(IVY_AST_MSG); msg->n_sel = sel; msg->n_recipient = recipient; *out = generic_node(msg); return true; } bool parse_keyword_msg( struct ivy_parser *parser, struct ivy_ast_node *recipient, enum expr_parse_flags flags, struct ivy_ast_node **out) { #if 0 if (!recipient) { recipient = pop_operand(expr, IVY_PRECEDENCE_KEYWORD_MSG); } if (!recipient) { parse_trace(parser, "no valid recipient for keyword msg"); return false; } #endif struct ivy_ast_selector_node *sel = create_node(IVY_AST_SELECTOR); struct ivy_ast_msg_node *msg = create_node(IVY_AST_MSG); msg->n_recipient = recipient; msg->n_sel = sel; bool ok = true; while (1) { struct ivy_token *label = NULL; if (!parse_label(parser, &label)) { break; } struct ivy_ast_node *value = NULL; flags |= EXPR_PARSE_STOP_LABEL; flags |= EXPR_PARSE_STOP_SEMICOLON; flags |= EXPR_PARSE_STOP_KW_CONTROL; flags &= ~EXPR_PARSE_CONSUME_TERMINATOR; if (!parse_expr(parser, flags, &value)) { parse_trace(parser, "invalid keyword msg arg value"); ok = false; break; } fx_queue_push_back(&sel->n_arg_labels, &label->t_entry); fx_queue_push_back(&msg->n_arg, &value->n_entry); } *out = generic_node(msg); return true; } bool parse_complex_msg( struct ivy_parser *parser, struct ivy_ast_node *msg_node, struct ivy_ast_node **out) { if (!parse_symbol(parser, IVY_SYM_LEFT_PAREN)) { parse_trace(parser, "expected `(` before complex msg arg list"); return false; } #if 0 if (!msg) { fx_queue_entry *entry = fx_queue_pop_back(&expr->expr_out_queue); if (!entry) { parse_trace( parser, "no valid recipient for complex msg"); return false; } msg = fx_unbox(struct ivy_ast_msg_node, entry, n_base.n_entry); if (msg->n_base.n_type != IVY_AST_MSG) { parse_trace( parser, "previous expression is not a unary message"); return false; } } #endif struct ivy_ast_msg_node *msg = (struct ivy_ast_msg_node *)msg_node; struct ivy_ast_selector_node *sel = msg->n_sel; msg->n_sel = sel; bool ok = true; while (1) { struct ivy_token *label = NULL; if (parse_symbol(parser, IVY_SYM_RIGHT_PAREN)) { break; } if (!fx_queue_empty(&msg->n_arg) && !parse_symbol(parser, IVY_SYM_COMMA)) { parse_trace( parser, "expected `,` after complex msg arg"); ok = false; break; } if (parse_label(parser, &label)) { fx_queue_push_back(&sel->n_arg_labels, &label->t_entry); } else { label = ivy_token_create_discard(); fx_queue_push_back(&sel->n_arg_labels, &label->t_entry); } struct ivy_ast_node *value = NULL; if (!parse_expr(parser, EXPR_PARSE_STOP_COMMA, &value)) { parse_trace(parser, "invalid complex msg arg value"); ok = false; break; } fx_queue_push_back(&msg->n_arg, &value->n_entry); } *out = generic_node(msg); return true; }