Files

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;
}