From dca0aba18375810bc13695169eb27e41494ccc58 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Mon, 25 Nov 2024 16:49:07 +0000 Subject: [PATCH] lang: ast: implement parsing 'use' statements --- lang/ast/unit-import.c | 103 ++++++++++++++++++++++++++++++++++++ lang/ast/unit.c | 8 +++ lang/include/ivy/lang/ast.h | 2 +- 3 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 lang/ast/unit-import.c diff --git a/lang/ast/unit-import.c b/lang/ast/unit-import.c new file mode 100644 index 0000000..3ffd0a1 --- /dev/null +++ b/lang/ast/unit-import.c @@ -0,0 +1,103 @@ +#include +#include +#include + +#include "ctx.h" +#include "node.h" + +struct unit_import_parser_state { + struct parser_state s_base; + int s_prev_token; +}; + +static enum ivy_status parse_dot(struct ivy_parser *ctx, struct ivy_token *tok) +{ + struct unit_import_parser_state *state + = parser_get_state(ctx, struct unit_import_parser_state); + + if (state->s_prev_token != IVY_TOK_IDENT) { + return IVY_ERR_BAD_SYNTAX; + } + + state->s_prev_token = IVY_SYM_DOT; + return IVY_OK; +} + +static enum ivy_status parse_ident(struct ivy_parser *ctx, struct ivy_token *tok) +{ + struct unit_import_parser_state *state + = parser_get_state(ctx, struct unit_import_parser_state); + + struct ivy_ast_unit_import_node *node = (struct ivy_ast_unit_import_node *)(state->s_base.s_node); + + if (state->s_prev_token == IVY_TOK_IDENT) { + return IVY_ERR_BAD_SYNTAX; + } + + b_queue_push_back(&node->n_ident, &tok->t_entry); + + state->s_prev_token = IVY_TOK_IDENT; + return IVY_OK; +} + +static enum ivy_status parse_linefeed(struct ivy_parser *ctx, struct ivy_token *tok) +{ + struct unit_import_parser_state *state + = parser_get_state(ctx, struct unit_import_parser_state); + + if (state->s_prev_token != IVY_TOK_IDENT) { + return IVY_ERR_BAD_SYNTAX; + } + + parser_pop_state(ctx, STATE_ADD_NODE_TO_PARENT); + return IVY_OK; +} + +static enum ivy_status add_child( + struct ivy_ast_node *parent, struct ivy_ast_node *child) +{ + return IVY_ERR_NOT_SUPPORTED; +} + +static void print(struct ivy_ast_node *node) +{ + struct ivy_ast_unit_import_node *unit_import = (struct ivy_ast_unit_import_node *)node; + b_string *str = b_string_create(); + + b_queue_iterator it = {0}; + b_queue_foreach (&it, &unit_import->n_ident) { + struct ivy_token *tok = b_unbox(struct ivy_token, it.entry, t_entry); + + if (b_string_get_size(str, B_STRLEN_NORMAL) > 0) { + b_string_append_cstr(str, "."); + } + + b_string_append_cstr(str, tok->t_str); + } + + printf("%s(%s)\n", ivy_ast_node_type_to_string(node->n_type), b_string_ptr(str)); + b_string_release(str); +} + +static void init_state(struct parser_state *sp) +{ + struct unit_import_parser_state *state + = (struct unit_import_parser_state *)sp; + state->s_prev_token = IVY_KW_PACKAGE; +} + +struct ast_node_type unit_import_node_ops = { + .n_add_child = add_child, + .n_print = print, + .n_init_state = init_state, + .n_state_size = sizeof(struct unit_import_parser_state), + .n_node_size = sizeof(struct ivy_ast_unit_import_node), + .n_symbol_parsers = { + [IVY_SYM_DOT] = parse_dot, + }, + .n_token_parsers = { + [IVY_TOK_IDENT] = parse_ident, + [IVY_TOK_LINEFEED] = parse_linefeed, + } + +}; diff --git a/lang/ast/unit.c b/lang/ast/unit.c index 18d8943..3dbf363 100644 --- a/lang/ast/unit.c +++ b/lang/ast/unit.c @@ -10,6 +10,13 @@ static enum ivy_status parse_package_keyword( return IVY_OK; } +static enum ivy_status parse_use_keyword( + struct ivy_parser *ctx, struct ivy_token *tok) +{ + parser_push_state(ctx, IVY_AST_UNIT_IMPORT); + return IVY_OK; +} + static enum ivy_status add_child( struct ivy_ast_node *parent, struct ivy_ast_node *child) { @@ -35,5 +42,6 @@ struct ast_node_type unit_node_ops = { .n_node_size = sizeof(struct ivy_ast_unit_node), .n_keyword_parsers = { [IVY_KW_PACKAGE] = parse_package_keyword, + [IVY_KW_USE] = parse_use_keyword, }, }; diff --git a/lang/include/ivy/lang/ast.h b/lang/include/ivy/lang/ast.h index 119719a..acf9163 100644 --- a/lang/include/ivy/lang/ast.h +++ b/lang/include/ivy/lang/ast.h @@ -153,7 +153,7 @@ struct ivy_ast_unit_package_node { b_queue n_ident; }; -struct ivy_ast_unit_use_node { +struct ivy_ast_unit_import_node { struct ivy_ast_node n_base; /* queue of struct ivy_token; list of multi-part identifier parts. */ b_queue n_ident;