From 811d3787c488319a2350b71e394a7a6dcc2eddbf Mon Sep 17 00:00:00 2001 From: Max Wash Date: Thu, 28 Nov 2024 10:26:53 +0000 Subject: [PATCH] lang: ast: add a BLOCK ast node to hold lists of expressions --- lang/ast/block.c | 66 +++++++++++++++++++++++++++++++++++++ lang/ast/expr.c | 1 + lang/ast/msgh.c | 29 ++++++++++++++-- lang/ast/node.c | 2 +- lang/ast/node.h | 1 + lang/include/ivy/lang/ast.h | 14 ++++---- 6 files changed, 103 insertions(+), 10 deletions(-) create mode 100644 lang/ast/block.c diff --git a/lang/ast/block.c b/lang/ast/block.c new file mode 100644 index 0000000..3865445 --- /dev/null +++ b/lang/ast/block.c @@ -0,0 +1,66 @@ +#include "ctx.h" +#include "node.h" + +#include +#include +#include + +struct block_parser_state { + struct parser_state s_base; + bool s_single_expr; + unsigned int s_terminator; +}; + +static struct token_parse_result parse_end( + struct ivy_parser *ctx, struct ivy_token *tok) +{ + struct block_parser_state *state + = parser_get_state(ctx, struct class_parser_state); + + struct ivy_ast_block_node *node + = (struct ivy_ast_block_node *)(state->s_base.s_node); + + parser_pop_state(ctx, STATE_ADD_NODE_TO_PARENT); + return PARSE_RESULT(IVY_OK, 0); +} + +static struct token_parse_result parse_expr_begin( + struct ivy_parser *ctx, struct ivy_token *tok) +{ + struct block_parser_state *state + = parser_get_state(ctx, struct class_parser_state); + + struct ivy_ast_block_node *node + = (struct ivy_ast_block_node *)(state->s_base.s_node); + + parser_push_state(ctx, IVY_AST_EXPR); + return PARSE_RESULT(IVY_OK, PARSE_REPEAT_TOKEN); +} + +static enum ivy_status add_child( + struct ivy_ast_node *parent, struct ivy_ast_node *child) +{ + struct ivy_ast_block_node *block = (struct ivy_ast_block_node *)parent; + + b_queue_push_back(&block->n_expr, &child->n_entry); + + return IVY_OK; +} + +static void init_state(struct ivy_parser *ctx, struct parser_state *sp) +{ + struct class_parser_state *state = (struct class_parser_state *)sp; +} + +struct ast_node_type block_node_ops = { + .n_add_child = add_child, + .n_init_state = init_state, + .n_state_size = sizeof(struct block_parser_state), + .n_node_size = sizeof(struct ivy_ast_block_node), + .n_keyword_parsers = { + [IVY_KW_END] = parse_end, + }, + .n_expr_parser = { + .expr_begin = parse_expr_begin, + }, +}; diff --git a/lang/ast/expr.c b/lang/ast/expr.c index c1bf33f..10b5623 100644 --- a/lang/ast/expr.c +++ b/lang/ast/expr.c @@ -118,6 +118,7 @@ static enum ivy_status finalise_expr(struct expr_parser_state *state) } printf("\n"); + printf("%zu\n", sizeof(struct ast_node_type)); return IVY_OK; } diff --git a/lang/ast/msgh.c b/lang/ast/msgh.c index e3da6c9..e05f840 100644 --- a/lang/ast/msgh.c +++ b/lang/ast/msgh.c @@ -30,6 +30,24 @@ static struct token_parse_result parse_expr( return PARSE_RESULT(IVY_OK, PARSE_REPEAT_TOKEN); } + +static struct token_parse_result parse_bang( + 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); + } + + parser_pop_state(ctx, STATE_ADD_NODE_TO_PARENT); + return PARSE_RESULT(IVY_OK, 0); +} + static enum ivy_status add_child( struct ivy_ast_node *parent, struct ivy_ast_node *child) { @@ -40,7 +58,11 @@ static enum ivy_status add_child( return IVY_OK; } - b_queue_push_back(&msgh->n_body, &child->n_entry); + if (child->n_type == IVY_AST_BLOCK && !msgh->n_body) { + msgh->n_body = child; + return IVY_OK; + } + return IVY_OK; } @@ -61,5 +83,8 @@ struct ast_node_type msgh_node_ops = { .n_node_size = sizeof(struct ivy_ast_msgh_node), .n_expr_parser = { .expr_begin = parse_expr, - } + }, + .n_symbol_parsers = { + [IVY_SYM_BANG] = parse_bang, + }, }; diff --git a/lang/ast/node.c b/lang/ast/node.c index 3419503..8411ff1 100644 --- a/lang/ast/node.c +++ b/lang/ast/node.c @@ -243,7 +243,7 @@ const char *ivy_ast_node_type_to_string(enum ivy_ast_node_type v) ENUM_STR(IVY_AST_COND_GROUP); ENUM_STR(IVY_AST_COND); ENUM_STR(IVY_AST_TUPLE); - ENUM_STR(IVY_AST_DO); + ENUM_STR(IVY_AST_BLOCK); ENUM_STR(IVY_AST_TYPE_COUNT); default: return ""; diff --git a/lang/ast/node.h b/lang/ast/node.h index c050a25..649d997 100644 --- a/lang/ast/node.h +++ b/lang/ast/node.h @@ -12,6 +12,7 @@ struct parser_state; #define PARSE_RESULT(status, flags) \ ((struct token_parse_result) {.r_status = (status), .r_flags = (flags)}) + enum token_parse_flags { PARSE_REPEAT_TOKEN = 0x01u, }; diff --git a/lang/include/ivy/lang/ast.h b/lang/include/ivy/lang/ast.h index d9919fe..c51b52f 100644 --- a/lang/include/ivy/lang/ast.h +++ b/lang/include/ivy/lang/ast.h @@ -16,6 +16,7 @@ enum ivy_ast_node_type { IVY_AST_MSG, IVY_AST_CLASS, IVY_AST_MSGH, + IVY_AST_BLOCK, IVY_AST_SELECTOR, IVY_AST_PROPERTY, IVY_AST_LAMBDA, @@ -33,7 +34,6 @@ enum ivy_ast_node_type { IVY_AST_COND_GROUP, IVY_AST_COND, IVY_AST_TUPLE, - IVY_AST_DO, IVY_AST_TYPE_COUNT, }; @@ -104,8 +104,8 @@ struct ivy_ast_msgh_node { struct ivy_ast_node n_base; enum ivy_ast_msgh_recipient_type n_recipient; struct ivy_ast_selector_node *n_sel; - /* queue of struct ivy_ast_node; expressions to evaluate when message handler is executed. */ - b_queue n_body; + /* expressions to evaluate when lambda is executed. */ + struct ivy_ast_block_node *n_body; }; struct ivy_ast_property_node { @@ -129,8 +129,8 @@ struct ivy_ast_lambda_node { struct ivy_ast_node n_base; /* queue of struct lex_token; contains the names of the lambda parameters. */ b_queue n_arg; - /* queue of struct ivy_ast_node; expressions to evaluate when lambda is executed. */ - b_queue n_body; + /* expressions to evaluate when lambda is executed. */ + struct ivy_ast_block_node *n_body; }; struct ivy_ast_unit_package_node { @@ -222,10 +222,10 @@ struct ivy_ast_tuple_node { b_queue n_members; }; -struct ivy_ast_do_node { +struct ivy_ast_block_node { struct ivy_ast_node n_base; /* queue of struct ivy_ast_node. expressions to evaluate when the do node itself is evaluated. */ - b_queue n_members; + b_queue n_expr; }; typedef enum ivy_status (*ivy_ast_node_iteration_callback)(