144 lines
3.2 KiB
C
144 lines
3.2 KiB
C
#include "ctx.h"
|
|
|
|
#include <ivy/lang/ast.h>
|
|
|
|
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;
|
|
}
|