summaryrefslogtreecommitdiff
path: root/42sh/src/ast/ast.h
diff options
context:
space:
mode:
Diffstat (limited to '42sh/src/ast/ast.h')
-rw-r--r--42sh/src/ast/ast.h221
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 */