diff options
| author | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:07:58 +0200 |
|---|---|---|
| committer | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:07:58 +0200 |
| commit | 967be9e750221ab2ab783f95df79bb26d290a45e (patch) | |
| tree | 6802900a5e975f9f68b169f0f503f040056d6952 /42sh/src/ast/ast.h | |
Diffstat (limited to '42sh/src/ast/ast.h')
| -rw-r--r-- | 42sh/src/ast/ast.h | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/42sh/src/ast/ast.h b/42sh/src/ast/ast.h new file mode 100644 index 0000000..3a1d20a --- /dev/null +++ b/42sh/src/ast/ast.h @@ -0,0 +1,221 @@ +#ifndef AST_H +#define AST_H + +#include <stdlib.h> + +#include "ast/ast_redirect.h" +#include "lexer/token.h" +#include "utils/libstring.h" + +/** + * @brief Each node type represent a class of elements from the SCL grammar. + */ +enum ast_node +{ + // STEP 1 + AST_COMMAND, + AST_IF, + AST_LOGICAL, + AST_LIST, + + // STEP 2 + AST_PIPELINE, + AST_REDIRECTION, + AST_WHILE, + AST_ASSIGN, + AST_FOR, + + // STEP 3 + AST_FUNCTION, + AST_SUBSHELL +}; + +/** + * @brief Base struct for the AST implementation. + */ +struct ast +{ + enum ast_node type; /**< Type of the targeted AST. Used for inheritance. */ +}; + +/** + * @brief AST which represent any kind of `command`. + * It can be a `shell command` or a `simple command`. + * Both are evaluated the same. + */ +struct ast_command +{ + struct ast base; /**< Base struct for the AST implementation. */ + struct string **args; /**< `args` used to call the given command. */ +}; + +/** + * @brief AST which represent a `if/then/elif/else` block. + * An `if` statement may not contain an `elif` or an `else` block. + * If the `if` statement contains an `elif` block, it is stored as an + * `ast_if` in the `else_body`. + */ +struct ast_if +{ + struct ast base; /**< Base struct for the AST implementation. */ + struct ast *condition; /**< Contains the AST to evaluate as a condition. */ + struct ast *then_body; /**< Contains the AST of the `then` block. */ + struct ast *else_body; /**< Contains the AST of the `else` block. */ +}; + +/** + * @brief AST which represent a shell list. + * A list can be either a `list` or a `compound list`. + * @note Although this struct contains a `nb_children` value, + * it is parsed as a binary tree, thus `nb_children` never exceeds 2. + */ +struct ast_list +{ + struct ast base; /**< Base struct for the AST implementation. */ + size_t nb_children; /**< Number of elements in the list */ + struct ast ** + children; /** Array of ASTs which represents the elements of the list */ +}; + +/** + * @brief AST which represents any logical block. + * A logical block can be either a `not` block, a `and` block or a `or` block. + * The type of the logical block is determined by the `type` value. + * The `type` value can be either `TOKEN_AND`, `TOKEN_OR` or `TOKEN_NEG`. + * The binary logical operators are evaluated following the lazy method. + * @note If the `type` value is not one of the listed above, the evaluation + * of the tree will always exit this the code 1 and write to `stderr`. + */ +struct ast_logical +{ + struct ast base; /**< Base struct for the AST implementation. */ + enum token_type type; /**< Type of the logical operator. */ + struct ast *left; /**< First block to be evaluated (always evaluated). */ + struct ast *right; /**< Second block to be evaluated (may not be evaluated, + see `note`). */ +}; + +/** + * @brief AST which represents a pipeline. + * The pipeline evaluation creates a context in which the output of + * `left` is redirected to the input of `right`. + */ +struct ast_pipeline +{ + struct ast base; /**< Base struct for the AST implementation. */ + struct ast *left; /**< The output of this AST is given to `right`. */ + struct ast *right; /**< This AST gets its input from `left`. */ +}; + +/** + * @brief AST used to represent redirections + * Redirect is a struct used to store info about this redirection + * Expr is the expression who the output shall be redirected + */ +struct ast_redirection +{ + struct ast base; /**< Base struct for the AST implementation. */ + struct redirect redirect; + struct ast *expr; +}; + +/** + * @brief AST used to represent the while loops (and also the until loops) + * Cond is the condition used to know if the loop shall still iterate + * Body is the tree to execute while the condition is still valid + */ +struct ast_while +{ + struct ast base; + struct ast *cond; + struct ast *body; +}; + +/** + * @brief Struct used for variable assignment + * Name is the name of the variable + * Val is the value of said variable + */ +struct ast_assign +{ + struct ast base; + struct string *name; + struct string *val; +}; + +/** + * @brief Left contains the args (the `in { WORD }` part). + * Right contains the body to execute. + */ +struct ast_for +{ + struct ast base; + struct ast *left; + struct ast *right; + struct string *var; +}; + +/** + * @brief AST used for function definition. + * Name contains the name of the function + * Body contains the actual ast that will be executed each time + * the function is called + */ +struct ast_function +{ + struct ast base; + struct string *name; + struct ast *body; +}; + +/** + * @brief AST used for subshell + * Body just contains the compound list to be executed in the subshell + */ +struct ast_subshell +{ + struct ast base; + struct ast *body; +}; + +union ast_caster +{ + struct ast *ast; + struct ast_command *ast_c; + struct ast_if *ast_i; + struct ast_list *ast_l; + struct ast_logical *ast_lo; + struct ast_pipeline *ast_p; + struct ast_redirection *ast_r; + struct ast_while *ast_w; + struct ast_assign *ast_a; + struct ast_for *ast_f; + struct ast_function *ast_func; + struct ast_subshell *ast_sub; +}; + +/** + * @brief Creates a heap-allocated AST of the size of ast_`type`. + * The AST is returned as a `struct ast*` but it can be casted into the right + * ast type struct. + * @param type The type of the AST to be created. + */ +struct ast *ast_create(enum ast_node type); + +/** + * @brief Recursively frees the given AST. Any heap-allocated can be passed. + * @param ast The AST to be freed. + * @note This method does not exit when `ast` is `NULL`. + */ +void ast_free(struct ast *ast); + +/** + * @brief Creates a file named `ast.dot` in the current folder which + * contains the DOT representation of the given AST. + * @param ast The AST to represent. + * @note This function is called only when the program is called with + * the `--pretty-print` flag. + */ +void pretty_print(struct ast *ast); + +#endif /* ! AST_H */ |
