Files
ivy/lang/parse/cascade.c
T

80 lines
1.7 KiB
C
Raw Normal View History

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