diff --git a/bshell/ast/array.c b/bshell/ast/array.c new file mode 100644 index 0000000..7eaa59e --- /dev/null +++ b/bshell/ast/array.c @@ -0,0 +1,25 @@ +#include "../parse/token.h" +#include "ast.h" + +static enum bshell_status collect_children( + struct ast_node *node, + struct ast_iterator *it) +{ + struct array_ast_node *array = (struct array_ast_node *)node; + + fx_queue_entry *cur = fx_queue_first(&array->n_items); + while (cur) { + struct ast_node *child + = fx_unbox(struct ast_node, cur, n_entry); + ast_iterator_enqueue(it, child); + cur = fx_queue_next(cur); + } + + return BSHELL_SUCCESS; +} + +struct ast_node_definition array_ast_node = { + .def_id = AST_ARRAY, + .def_node_size = sizeof(struct array_ast_node), + .def_collect_children = collect_children, +}; diff --git a/bshell/ast/ast.c b/bshell/ast/ast.c index 668b6b3..32aef93 100644 --- a/bshell/ast/ast.c +++ b/bshell/ast/ast.c @@ -6,6 +6,7 @@ #include #include +extern struct ast_node_definition null_ast_node; extern struct ast_node_definition int_ast_node; extern struct ast_node_definition double_ast_node; extern struct ast_node_definition word_ast_node; @@ -15,8 +16,18 @@ extern struct ast_node_definition fstring_ast_node; extern struct ast_node_definition cmdcall_ast_node; extern struct ast_node_definition pipeline_ast_node; extern struct ast_node_definition redirection_ast_node; +extern struct ast_node_definition block_ast_node; +extern struct ast_node_definition stmt_list_ast_node; +extern struct ast_node_definition func_ast_node; +extern struct ast_node_definition array_ast_node; +extern struct ast_node_definition hashtable_ast_node; +extern struct ast_node_definition hashtable_item_ast_node; +extern struct ast_node_definition if_ast_node; +extern struct ast_node_definition if_branch_ast_node; +extern struct ast_node_definition op_ast_node; static const struct ast_node_definition *ast_node_defintions[] = { + [AST_NULL] = &null_ast_node, [AST_INT] = &int_ast_node, [AST_DOUBLE] = &double_ast_node, [AST_WORD] = &word_ast_node, @@ -26,6 +37,15 @@ static const struct ast_node_definition *ast_node_defintions[] = { [AST_CMDCALL] = &cmdcall_ast_node, [AST_PIPELINE] = &pipeline_ast_node, [AST_REDIRECTION] = &redirection_ast_node, + [AST_BLOCK] = &block_ast_node, + [AST_STMT_LIST] = &stmt_list_ast_node, + [AST_FUNC] = &func_ast_node, + [AST_ARRAY] = &array_ast_node, + [AST_IF] = &if_ast_node, + [AST_IF_BRANCH] = &if_branch_ast_node, + [AST_HASHTABLE] = &hashtable_ast_node, + [AST_HASHTABLE_ITEM] = &hashtable_item_ast_node, + [AST_OP] = &op_ast_node, }; static const size_t nr_ast_node_definitions = sizeof ast_node_defintions / sizeof ast_node_defintions[0]; @@ -94,6 +114,8 @@ const char *ast_node_type_to_string(enum ast_node_type type) { switch (type) { ENUM_STR(AST_NONE); + ENUM_STR(AST_NULL); + ENUM_STR(AST_STMT_LIST); ENUM_STR(AST_INT); ENUM_STR(AST_DOUBLE); ENUM_STR(AST_WORD); @@ -105,6 +127,14 @@ const char *ast_node_type_to_string(enum ast_node_type type) ENUM_STR(AST_CMDCALL); ENUM_STR(AST_PIPELINE); ENUM_STR(AST_REDIRECTION); + ENUM_STR(AST_BLOCK); + ENUM_STR(AST_FUNC); + ENUM_STR(AST_IF); + ENUM_STR(AST_IF_BRANCH); + ENUM_STR(AST_OP); + ENUM_STR(AST_ARRAY); + ENUM_STR(AST_HASHTABLE); + ENUM_STR(AST_HASHTABLE_ITEM); default: return ""; } diff --git a/bshell/ast/ast.h b/bshell/ast/ast.h index 5cc2d44..826cb3c 100644 --- a/bshell/ast/ast.h +++ b/bshell/ast/ast.h @@ -10,6 +10,8 @@ struct lex_token; enum ast_node_type { AST_NONE = 0x00u, + AST_NULL, + AST_STMT_LIST, AST_INT, AST_DOUBLE, AST_WORD, @@ -19,8 +21,17 @@ enum ast_node_type { AST_VAR_SPLAT, AST_FLAG, AST_CMDCALL, + AST_FUNCALL, AST_PIPELINE, AST_REDIRECTION, + AST_BLOCK, + AST_FUNC, + AST_ARRAY, + AST_HASHTABLE, + AST_HASHTABLE_ITEM, + AST_OP, + AST_IF, + AST_IF_BRANCH, }; struct ast_iterator_entry { @@ -35,6 +46,10 @@ struct ast_node { struct ast_iterator_entry n_it; }; +struct null_ast_node { + struct ast_node n_base; +}; + struct int_ast_node { struct ast_node n_base; struct lex_token *n_value; @@ -76,6 +91,12 @@ struct cmdcall_ast_node { fx_queue n_redirect; }; +struct funcall_ast_node { + struct ast_node n_base; + struct ast_node *n_func; + fx_queue n_args; +}; + struct pipeline_ast_node { struct ast_node n_base; fx_queue n_stages; @@ -93,6 +114,55 @@ struct redirection_ast_node { struct lex_token *n_out_tok; }; +struct stmt_list_ast_node { + struct ast_node n_base; + fx_queue n_statements; +}; + +struct block_ast_node { + struct ast_node n_base; + fx_queue n_statements; +}; + +struct func_ast_node { + struct ast_node n_base; + struct lex_token *n_name; + fx_queue n_params; + struct ast_node *n_body; +}; + +struct array_ast_node { + struct ast_node n_base; + fx_queue n_items; +}; + +struct hashtable_ast_node { + struct ast_node n_base; + fx_queue n_items; +}; + +struct hashtable_item_ast_node { + struct ast_node n_base; + struct ast_node *n_key, *n_value; +}; + +struct op_ast_node { + struct ast_node n_base; + const struct operator_info *n_op; + struct ast_node *n_left, *n_right; +}; + +struct if_branch_ast_node { + struct ast_node n_base; + struct ast_node *n_cond; + struct ast_node *n_body; +}; + +struct if_ast_node { + struct ast_node n_base; + fx_queue n_branches; +}; + struct ast_iterator { struct ast_node *it_cur; fx_queue it_queue; diff --git a/bshell/ast/block.c b/bshell/ast/block.c new file mode 100644 index 0000000..90681e3 --- /dev/null +++ b/bshell/ast/block.c @@ -0,0 +1,23 @@ +#include "ast.h" + +static enum bshell_status collect_children( + struct ast_node *node, + struct ast_iterator *it) +{ + struct block_ast_node *block = (struct block_ast_node *)node; + fx_queue_entry *cur = fx_queue_first(&block->n_statements); + while (cur) { + struct ast_node *child + = fx_unbox(struct ast_node, cur, n_entry); + ast_iterator_enqueue(it, child); + cur = fx_queue_next(cur); + } + + return BSHELL_SUCCESS; +} + +struct ast_node_definition block_ast_node = { + .def_id = AST_BLOCK, + .def_node_size = sizeof(struct block_ast_node), + .def_collect_children = collect_children, +}; diff --git a/bshell/ast/fstring.c b/bshell/ast/fstring.c index 687436f..894ba18 100644 --- a/bshell/ast/fstring.c +++ b/bshell/ast/fstring.c @@ -1,6 +1,23 @@ #include "ast.h" +static enum bshell_status collect_children( + struct ast_node *node, + struct ast_iterator *it) +{ + struct fstring_ast_node *fstring = (struct fstring_ast_node *)node; + fx_queue_entry *cur = fx_queue_first(&fstring->n_elements); + while (cur) { + struct ast_node *child + = fx_unbox(struct ast_node, cur, n_entry); + ast_iterator_enqueue(it, child); + cur = fx_queue_next(cur); + } + + return BSHELL_SUCCESS; +} + struct ast_node_definition fstring_ast_node = { .def_id = AST_FSTRING, .def_node_size = sizeof(struct fstring_ast_node), + .def_collect_children = collect_children, }; diff --git a/bshell/ast/func.c b/bshell/ast/func.c new file mode 100644 index 0000000..61c53a6 --- /dev/null +++ b/bshell/ast/func.c @@ -0,0 +1,36 @@ +#include "../parse/token.h" +#include "ast.h" + +static enum bshell_status collect_children( + struct ast_node *node, + struct ast_iterator *it) +{ + struct func_ast_node *func = (struct func_ast_node *)node; + + fx_queue_entry *cur = fx_queue_first(&func->n_params); + while (cur) { + struct ast_node *child + = fx_unbox(struct ast_node, cur, n_entry); + ast_iterator_enqueue(it, child); + cur = fx_queue_next(cur); + } + + if (func->n_body) { + ast_iterator_enqueue(it, func->n_body); + } + + return BSHELL_SUCCESS; +} + +static void to_string(const struct ast_node *node, fx_bstr *out) +{ + const struct func_ast_node *func = (const struct func_ast_node *)node; + fx_bstr_write_fmt(out, NULL, "%s", func->n_name->tok_str); +} + +struct ast_node_definition func_ast_node = { + .def_id = AST_FUNC, + .def_node_size = sizeof(struct func_ast_node), + .def_collect_children = collect_children, + .def_to_string = to_string, +}; diff --git a/bshell/ast/hashtable-item.c b/bshell/ast/hashtable-item.c new file mode 100644 index 0000000..64cd17c --- /dev/null +++ b/bshell/ast/hashtable-item.c @@ -0,0 +1,26 @@ +#include "../parse/token.h" +#include "ast.h" + +static enum bshell_status collect_children( + struct ast_node *node, + struct ast_iterator *it) +{ + struct hashtable_item_ast_node *item + = (struct hashtable_item_ast_node *)node; + + if (item->n_key) { + ast_iterator_enqueue(it, item->n_key); + } + + if (item->n_value) { + ast_iterator_enqueue(it, item->n_value); + } + + return BSHELL_SUCCESS; +} + +struct ast_node_definition hashtable_item_ast_node = { + .def_id = AST_HASHTABLE_ITEM, + .def_node_size = sizeof(struct hashtable_item_ast_node), + .def_collect_children = collect_children, +}; diff --git a/bshell/ast/hashtable.c b/bshell/ast/hashtable.c new file mode 100644 index 0000000..ab2f612 --- /dev/null +++ b/bshell/ast/hashtable.c @@ -0,0 +1,24 @@ +#include "ast.h" + +static enum bshell_status collect_children( + struct ast_node *node, + struct ast_iterator *it) +{ + struct hashtable_ast_node *hashtable + = (struct hashtable_ast_node *)node; + fx_queue_entry *cur = fx_queue_first(&hashtable->n_items); + while (cur) { + struct ast_node *child + = fx_unbox(struct ast_node, cur, n_entry); + ast_iterator_enqueue(it, child); + cur = fx_queue_next(cur); + } + + return BSHELL_SUCCESS; +} + +struct ast_node_definition hashtable_ast_node = { + .def_id = AST_HASHTABLE, + .def_node_size = sizeof(struct hashtable_ast_node), + .def_collect_children = collect_children, +}; diff --git a/bshell/ast/if-branch.c b/bshell/ast/if-branch.c new file mode 100644 index 0000000..d121bb7 --- /dev/null +++ b/bshell/ast/if-branch.c @@ -0,0 +1,24 @@ +#include "ast.h" + +static enum bshell_status collect_children( + struct ast_node *node, + struct ast_iterator *it) +{ + struct if_branch_ast_node *if_branch + = (struct if_branch_ast_node *)node; + if (if_branch->n_cond) { + ast_iterator_enqueue(it, if_branch->n_cond); + } + + if (if_branch->n_body) { + ast_iterator_enqueue(it, if_branch->n_body); + } + + return BSHELL_SUCCESS; +} + +struct ast_node_definition if_branch_ast_node = { + .def_id = AST_IF_BRANCH, + .def_node_size = sizeof(struct if_branch_ast_node), + .def_collect_children = collect_children, +}; diff --git a/bshell/ast/if.c b/bshell/ast/if.c new file mode 100644 index 0000000..db44b86 --- /dev/null +++ b/bshell/ast/if.c @@ -0,0 +1,23 @@ +#include "ast.h" + +static enum bshell_status collect_children( + struct ast_node *node, + struct ast_iterator *it) +{ + struct if_ast_node *if_group = (struct if_ast_node *)node; + fx_queue_entry *cur = fx_queue_first(&if_group->n_branches); + while (cur) { + struct ast_node *child + = fx_unbox(struct ast_node, cur, n_entry); + ast_iterator_enqueue(it, child); + cur = fx_queue_next(cur); + } + + return BSHELL_SUCCESS; +} + +struct ast_node_definition if_ast_node = { + .def_id = AST_IF, + .def_node_size = sizeof(struct if_ast_node), + .def_collect_children = collect_children, +}; diff --git a/bshell/ast/null.c b/bshell/ast/null.c new file mode 100644 index 0000000..e3f3b76 --- /dev/null +++ b/bshell/ast/null.c @@ -0,0 +1,7 @@ +#include "../parse/token.h" +#include "ast.h" + +struct ast_node_definition null_ast_node = { + .def_id = AST_NULL, + .def_node_size = sizeof(struct null_ast_node), +}; diff --git a/bshell/ast/op.c b/bshell/ast/op.c new file mode 100644 index 0000000..1c3023b --- /dev/null +++ b/bshell/ast/op.c @@ -0,0 +1,37 @@ +#include "../operator.h" +#include "../parse/token.h" +#include "ast.h" + +static enum bshell_status collect_children( + struct ast_node *node, + struct ast_iterator *it) +{ + struct op_ast_node *op = (struct op_ast_node *)node; + + if (op->n_left) { + ast_iterator_enqueue(it, op->n_left); + } + + if (op->n_right) { + ast_iterator_enqueue(it, op->n_right); + } + + return BSHELL_SUCCESS; +} + +static void to_string(const struct ast_node *node, fx_bstr *out) +{ + const struct op_ast_node *op = (const struct op_ast_node *)node; + fx_bstr_write_fmt( + out, + NULL, + "%s", + operator_id_to_string(op->n_op->op_id)); +} + +struct ast_node_definition op_ast_node = { + .def_id = AST_OP, + .def_node_size = sizeof(struct op_ast_node), + .def_collect_children = collect_children, + .def_to_string = to_string, +}; diff --git a/bshell/ast/stmt-list.c b/bshell/ast/stmt-list.c new file mode 100644 index 0000000..bd98255 --- /dev/null +++ b/bshell/ast/stmt-list.c @@ -0,0 +1,24 @@ +#include "ast.h" + +static enum bshell_status collect_children( + struct ast_node *node, + struct ast_iterator *it) +{ + struct stmt_list_ast_node *stmt_list + = (struct stmt_list_ast_node *)node; + fx_queue_entry *cur = fx_queue_first(&stmt_list->n_statements); + while (cur) { + struct ast_node *child + = fx_unbox(struct ast_node, cur, n_entry); + ast_iterator_enqueue(it, child); + cur = fx_queue_next(cur); + } + + return BSHELL_SUCCESS; +} + +struct ast_node_definition stmt_list_ast_node = { + .def_id = AST_STMT_LIST, + .def_node_size = sizeof(struct stmt_list_ast_node), + .def_collect_children = collect_children, +};