#include "ast_accessors.h" static struct ast *_get_from_command(struct ast *ast, size_t index) { (void)ast; (void)index; return NULL; } static struct ast *_get_from_if(struct ast *ast, size_t index) { switch (index) { case 0: return ((struct ast_if *)ast)->condition; case 1: return ((struct ast_if *)ast)->then_body; case 2: return ((struct ast_if *)ast)->else_body; default: return NULL; } } static struct ast *_get_from_list(struct ast *ast, size_t index) { if (index >= ((struct ast_list *)ast)->nb_children) { return NULL; } return ((struct ast_list *)ast)->children[index]; } static struct ast *_get_from_logical(struct ast *ast, size_t index) { switch (index) { case 0: return ((struct ast_logical *)ast)->left; case 1: return ((struct ast_logical *)ast)->right; default: return NULL; } } static struct ast *_get_from_pipeline(struct ast *ast, size_t index) { switch (index) { case 0: return ((struct ast_pipeline *)ast)->left; case 1: return ((struct ast_pipeline *)ast)->right; default: return NULL; } } static struct ast *_get_from_redirection(struct ast *ast, size_t index) { switch (index) { case 0: return ((struct ast_redirection *)ast)->expr; default: return NULL; } } static struct ast *_get_from_while(struct ast *ast, size_t index) { switch (index) { case 0: return ((struct ast_while *)ast)->cond; case 1: return ((struct ast_while *)ast)->body; default: return NULL; } } static struct ast *_get_from_assign(struct ast *ast, size_t index) { (void)ast; (void)index; return NULL; } static struct ast *_get_from_for(struct ast *ast, size_t index) { switch (index) { case 0: return ((struct ast_for *)ast)->left; case 1: return ((struct ast_for *)ast)->right; default: return NULL; } } static struct ast *_get_from_function(struct ast *ast, size_t index) { switch (index) { case 0: return ((struct ast_function *)ast)->body; default: return NULL; } } static struct ast *_get_from_subshell(struct ast *ast, size_t index) { switch (index) { case 0: return ((struct ast_subshell *)ast)->body; default: return NULL; } } typedef struct ast *(*ast_getters)(struct ast *, size_t); static const ast_getters ast_getters_ltable[] = { [AST_COMMAND] = _get_from_command, [AST_IF] = _get_from_if, [AST_LOGICAL] = _get_from_logical, [AST_LIST] = _get_from_list, [AST_PIPELINE] = _get_from_pipeline, [AST_REDIRECTION] = _get_from_redirection, [AST_WHILE] = _get_from_while, [AST_ASSIGN] = _get_from_assign, [AST_FOR] = _get_from_for, [AST_FUNCTION] = _get_from_function, [AST_SUBSHELL] = _get_from_subshell }; struct ast *get_i(struct ast *ast, size_t index) { return ast_getters_ltable[ast->type](ast, index); } struct ast *get_left(struct ast *ast) { return get_i(ast, 0); } struct ast *get_right(struct ast *ast) { return get_i(ast, 1); } static void _set_on_command(struct ast *ast, struct ast *child, size_t index) { (void)ast; (void)child; (void)index; return; } static void _set_on_if(struct ast *ast, struct ast *child, size_t index) { switch (index) { case 0: ((struct ast_if *)ast)->condition = child; return; case 1: ((struct ast_if *)ast)->then_body = child; return; case 2: ((struct ast_if *)ast)->else_body = child; return; default: return; } } static void _set_on_logical(struct ast *ast, struct ast *child, size_t index) { switch (index) { case 0: ((struct ast_logical *)ast)->left = child; break; case 1: ((struct ast_logical *)ast)->right = child; break; default: return; } } static void _set_on_list(struct ast *ast, struct ast *child, size_t index) { if (index > ((struct ast_list *)ast)->nb_children) { return; } if (index == ((struct ast_list *)ast)->nb_children) { ((struct ast_list *)ast)->nb_children++; ((struct ast_list *)ast)->children = realloc( ((struct ast_list *)ast)->children, ((struct ast_list *)ast)->nb_children * sizeof(struct ast_command)); } ((struct ast_list *)ast)->children[index] = child; } static void _set_on_pipeline(struct ast *ast, struct ast *child, size_t index) { switch (index) { case 0: ((struct ast_pipeline *)ast)->left = child; break; case 1: ((struct ast_pipeline *)ast)->right = child; break; default: return; } } static void _set_on_redirection(struct ast *ast, struct ast *child, size_t index) { switch (index) { case 0: ((struct ast_redirection *)ast)->expr = child; break; default: return; } } static void _set_on_while(struct ast *ast, struct ast *child, size_t index) { switch (index) { case 0: ((struct ast_while *)ast)->cond = child; break; case 1: ((struct ast_while *)ast)->body = child; break; default: return; } } static void _set_on_assign(struct ast *ast, struct ast *child, size_t index) { (void)ast; (void)child; (void)index; return; } static void _set_on_for(struct ast *ast, struct ast *child, size_t index) { switch (index) { case 0: ((struct ast_for *)ast)->left = child; return; case 1: ((struct ast_for *)ast)->right = child; return; default: return; } } static void _set_on_function(struct ast *ast, struct ast *child, size_t index) { switch (index) { case 0: ((struct ast_function *)ast)->body = child; default: return; } } static void _set_on_subshell(struct ast *ast, struct ast *child, size_t index) { switch (index) { case 0: ((struct ast_subshell *)ast)->body = child; default: return; } } typedef void (*ast_setters)(struct ast *, struct ast *, size_t); static const ast_setters ast_setters_ltable[] = { [AST_COMMAND] = _set_on_command, [AST_IF] = _set_on_if, [AST_LOGICAL] = _set_on_logical, [AST_LIST] = _set_on_list, [AST_PIPELINE] = _set_on_pipeline, [AST_REDIRECTION] = _set_on_redirection, [AST_WHILE] = _set_on_while, [AST_ASSIGN] = _set_on_assign, [AST_FOR] = _set_on_for, [AST_FUNCTION] = _set_on_function, [AST_SUBSHELL] = _set_on_subshell }; void set_i(struct ast *ast, struct ast *child, size_t index) { ast_setters_ltable[ast->type](ast, child, index); } void set_left(struct ast *ast, struct ast *child) { set_i(ast, child, 0); } void set_right(struct ast *ast, struct ast *child) { set_i(ast, child, 1); }