From 4304b94491e9eb3678e7e38a561170a136564a12 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Thu, 28 Nov 2024 16:57:10 +0000 Subject: [PATCH] lang: ast: implement single-expression message handler parsing --- lang/ast/msgh.c | 57 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/lang/ast/msgh.c b/lang/ast/msgh.c index fa4e38f..cc983d6 100644 --- a/lang/ast/msgh.c +++ b/lang/ast/msgh.c @@ -1,6 +1,8 @@ #include "ctx.h" #include "ivy/status.h" #include "node.h" +#include "block.h" +#include "iterate.h" #include #include @@ -13,8 +15,8 @@ struct msgh_parser_state { unsigned int s_prev; }; -static struct token_parse_result parse_expr( - struct ivy_parser* ctx, struct ivy_token* tok) +static struct token_parse_result parse_linefeed( + struct ivy_parser *ctx, struct ivy_token *tok) { struct msgh_parser_state *state = parser_get_state(ctx, struct msgh_parser_state); @@ -22,14 +24,24 @@ static struct token_parse_result parse_expr( struct ivy_ast_msgh_node *msgh = (struct ivy_ast_msgh_node *)state->s_base.s_node; + if (state->s_oneline) { + if (msgh->n_body) { + parser_pop_state(ctx, STATE_ADD_NODE_TO_PARENT); + return PARSE_RESULT(IVY_OK, 0); + } + + return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0); + } + if (!msgh->n_sel) { return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0); } - parser_push_state(ctx, IVY_AST_EXPR); - return PARSE_RESULT(IVY_OK, PARSE_REPEAT_TOKEN); -} + struct block_parser_state *block_state = (struct block_parser_state *)parser_push_state(ctx, IVY_AST_BLOCK); + block_state->s_terminator = IVY_SYM_BANG; + return PARSE_RESULT(IVY_OK, 0); +} static struct token_parse_result parse_bang( struct ivy_parser *ctx, struct ivy_token *tok) @@ -44,10 +56,29 @@ static struct token_parse_result parse_bang( return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0); } + parser_pop_state(ctx, STATE_ADD_NODE_TO_PARENT); return PARSE_RESULT(IVY_OK, 0); } +static struct token_parse_result parse_pipe( + struct ivy_parser *ctx, struct ivy_token *tok) +{ + struct msgh_parser_state *state + = parser_get_state(ctx, struct msgh_parser_state); + + struct ivy_ast_msgh_node *msgh + = (struct ivy_ast_msgh_node *)state->s_base.s_node; + + if (!msgh->n_sel || state->s_oneline) { + return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0); + } + + state->s_oneline = true; + parser_push_state(ctx, IVY_AST_EXPR); + return PARSE_RESULT(IVY_OK, 0); +} + static enum ivy_status add_child( struct ivy_ast_node *parent, struct ivy_ast_node *child) { @@ -58,7 +89,7 @@ static enum ivy_status add_child( return IVY_OK; } - if (child->n_type == IVY_AST_BLOCK && !msgh->n_body) { + if (!msgh->n_body) { msgh->n_body = child; return IVY_OK; } @@ -76,15 +107,25 @@ static void init_state(struct ivy_parser *ctx, struct parser_state *sp) parser_push_state(ctx, IVY_AST_SELECTOR); } +static void collect_children( + struct ivy_ast_node *node, struct ivy_ast_node_iterator *iterator) +{ + struct ivy_ast_msgh_node *msgh = (struct ivy_ast_msgh_node *)node; + ast_node_iterator_enqueue_node(iterator, node, &msgh->n_sel->n_base); + ast_node_iterator_enqueue_node(iterator, node, &msgh->n_body->n_base); +} + struct ast_node_type msgh_node_ops = { .n_add_child = add_child, .n_init_state = init_state, + .n_collect_children = collect_children, .n_state_size = sizeof(struct msgh_parser_state), .n_node_size = sizeof(struct ivy_ast_msgh_node), - .n_expr_parser = { - .expr_begin = parse_expr, + .n_token_parsers = { + TOK_PARSER(LINEFEED, parse_linefeed), }, .n_symbol_parsers = { SYM_PARSER(BANG, parse_bang), + SYM_PARSER(PIPE, parse_pipe), }, };