From f6d6589a3a204972b859e7e83b062d9977a83982 Mon Sep 17 00:00:00 2001 From: Maieul BOYER Date: Mon, 2 Sep 2024 21:23:36 +0000 Subject: [PATCH] Updated stuff to be more normed --- Filelist.sh.mk | 5 + input.toml | 8 + output/include/me/vec/vec_ast.h | 87 ++- output/include/me/vec/vec_estr.h | 87 ++- output/include/me/vec/vec_heredoc.h | 87 ++- output/include/me/vec/vec_pid.h | 87 ++- output/include/me/vec/vec_str.h | 87 ++- output/include/me/vec/vec_subtree.h | 174 +++++ output/src/vec/ast/ast_functions4.c | 49 +- output/src/vec/estr/estr_functions4.c | 49 +- output/src/vec/heredoc/heredoc_functions4.c | 49 +- output/src/vec/pid/pid_functions4.c | 49 +- output/src/vec/str/str_functions4.c | 49 +- output/src/vec/subtree/subtree.c | 95 +++ output/src/vec/subtree/subtree_functions2.c | 112 +++ output/src/vec/subtree/subtree_functions3.c | 82 ++ output/src/vec/subtree/subtree_functions4.c | 75 ++ output/src/vec/subtree/subtree_sort.c | 41 + parser/Filelist.parser.mk | 1 + parser/include/parser/api.h | 723 ++---------------- parser/include/parser/array.h | 35 +- parser/include/parser/inner/length_inner.h | 28 + parser/include/parser/inner/point_inner.h | 27 + parser/include/parser/inner/ptypes.h | 63 ++ parser/include/parser/inner/stack.h | 4 +- parser/include/parser/inner/subtree_inner.h | 79 ++ parser/include/parser/length.h | 13 +- parser/include/parser/lexer.h | 3 +- parser/include/parser/stack.h | 4 +- parser/include/parser/subtree.h | 83 +- parser/include/parser/tree.h | 4 +- parser/src/parser.c | 109 ++- parser/src/stack/stack_funcs3.c | 2 +- parser/src/stack/stack_iter.c | 54 +- parser/src/stack/stack_manipulate3.c | 10 +- parser/src/subtree.c | 359 ++------- parser/src/subtree/subtree_funcs1.c | 117 +++ .../header/vec_C__PREFIX__.h__TEMPLATE__ | 87 ++- .../vec/C__PREFIX___functions4.c__TEMPLATE__ | 49 +- 39 files changed, 1838 insertions(+), 1288 deletions(-) create mode 100644 output/include/me/vec/vec_subtree.h create mode 100644 output/src/vec/subtree/subtree.c create mode 100644 output/src/vec/subtree/subtree_functions2.c create mode 100644 output/src/vec/subtree/subtree_functions3.c create mode 100644 output/src/vec/subtree/subtree_functions4.c create mode 100644 output/src/vec/subtree/subtree_sort.c create mode 100644 parser/include/parser/inner/length_inner.h create mode 100644 parser/include/parser/inner/point_inner.h create mode 100644 parser/include/parser/inner/ptypes.h create mode 100644 parser/include/parser/inner/subtree_inner.h create mode 100644 parser/src/subtree/subtree_funcs1.c diff --git a/Filelist.sh.mk b/Filelist.sh.mk index 35d86524..215cc381 100644 --- a/Filelist.sh.mk +++ b/Filelist.sh.mk @@ -36,4 +36,9 @@ src/vec/str/str_functions2 \ src/vec/str/str_functions3 \ src/vec/str/str_functions4 \ src/vec/str/str_sort \ +src/vec/subtree/subtree \ +src/vec/subtree/subtree_functions2 \ +src/vec/subtree/subtree_functions3 \ +src/vec/subtree/subtree_functions4 \ +src/vec/subtree/subtree_sort \ diff --git a/input.toml b/input.toml index c33827fe..316323b8 100644 --- a/input.toml +++ b/input.toml @@ -90,3 +90,11 @@ replace.C__TYPENAME__ = "t_heredoc" replace.C__TYPEHEADER__ = '#include "parser/inner/heredoc.h"' replace.C__PREFIX__ = "heredoc" replace.C__PREFIXUP__ = "HEREDOC" + +[[create.vec]] +sources_output = "src/vec/C__PREFIX__/" +headers_output = "include/me/vec/" +replace.C__TYPENAME__ = "t_subtree" +replace.C__TYPEHEADER__ = '#include "parser/inner/subtree_inner.h"' +replace.C__PREFIX__ = "subtree" +replace.C__PREFIXUP__ = "SUBTREE" diff --git a/output/include/me/vec/vec_ast.h b/output/include/me/vec/vec_ast.h index da15f4c4..6a59e3f4 100644 --- a/output/include/me/vec/vec_ast.h +++ b/output/include/me/vec/vec_ast.h @@ -22,18 +22,31 @@ typedef bool (*t_vec_ast_sort_fn)(t_ast_node *, t_ast_node *); typedef void (*t_free_ast_item)(t_ast_node); /// @brief A dynamic array of t_ast_node -typedef struct s_vec_ast +typedef struct s_vec_ast t_vec_ast; + +struct s_vec_ast { t_free_ast_item free_func; t_usize len; t_usize capacity; t_ast_node *buffer; -} t_vec_ast; +}; + +struct s_vec_ast_splice_arguments +{ + t_usize index; + t_usize old_count; + t_usize new_count; + const t_ast_node *elements; +}; /// @brief Create a new vec_ast with a given capacity -/// @param capacity The capacity of the new vec_ast (in terms of elements) -/// @param free_function The function that will be used to free the elements of the vec_ast -t_vec_ast vec_ast_new(t_usize capacity, t_free_ast_item free_function); +/// @param capacity The capacity of the new vec_ast (in terms of +/// elements) +/// @param free_function The function that will be used to free the elements of +/// the vec_ast +t_vec_ast vec_ast_new(t_usize capacity, + t_free_ast_item free_function); /// @brief Push an element to the last position of the vec_ast /// @param vec The vec_ast to push the element to /// @param element The element to push @@ -43,16 +56,18 @@ t_error vec_ast_push(t_vec_ast *vec, t_ast_node element); /// @param vec The vec_ast to push the element to /// @param element The element to push /// @note This operation is O(n) -t_error vec_ast_push_front(t_vec_ast *vec, t_ast_node element); +t_error vec_ast_push_front(t_vec_ast *vec, + t_ast_node element); -/// @brief Get the last element from the vec_ast, and remove it from the vec_ast +/// @brief Get the last element from the vec_ast, and remove it from the +/// vec_ast /// @param vec The vec_ast to get the element from /// @param[out] out The last element of the vec_ast /// @return true if the operation failed, false otherwise t_error vec_ast_pop(t_vec_ast *vec, t_ast_node *value); - -/// @brief Get the first element from the vec_ast, and remove it from the vec_ast +/// @brief Get the first element from the vec_ast, and remove it from +/// the vec_ast /// @param vec The vec_ast to get the element from /// @param[out] out The first element of the vec_ast /// @return true if the operation failed, false otherwise @@ -61,58 +76,71 @@ t_error vec_ast_pop_front(t_vec_ast *vec, t_ast_node *value); /// @brief Free the vector and all its elements /// @param vec The vec_ast to free -void vec_ast_free(t_vec_ast vec); +void vec_ast_free(t_vec_ast vec); /// @brief Make the vec_ast at least the given capacity /// @param vec The vec_ast to reserve /// @param wanted_capacity The minimum capacity to reserve /// @return true if the operation failed, false otherwise -t_error vec_ast_reserve(t_vec_ast *vec, t_usize wanted_capacity); +t_error vec_ast_reserve(t_vec_ast *vec, + t_usize wanted_capacity); -/// @brief Run the function and returns the index of the first element that returns true +/// @brief Run the function and returns the index of the first element that +/// returns true /// @param vec The vec_ast to search in /// @param fn The function to run on each element /// @param[out] index The index of the first element that returns true -t_error vec_ast_find(t_vec_ast *vec, bool (*fn)(const t_ast_node *), t_usize *index); +t_error vec_ast_find(t_vec_ast *vec, + bool (*fn)(const t_ast_node *), t_usize *index); - -/// @brief Run the function and returns the index of the first element that returns true, but starting at index starting_index +/// @brief Run the function and returns the index of the first element that +/// returns true, but starting at index starting_index /// @param vec The vec_ast to search in /// @param fn The function to run on each element /// @param starting_index The index to start the search from /// @param[out] index The index of the first element that returns true -t_error vec_ast_find_starting(t_vec_ast *vec, bool (*fn)(const t_ast_node *), t_usize starting_index, t_usize *index); +t_error vec_ast_find_starting(t_vec_ast *vec, + bool (*fn)(const t_ast_node *), + t_usize starting_index, t_usize *index); -/// @brief Run the function on every element of the vec_ast and returns if all elements returned true +/// @brief Run the function on every element of the vec_ast and returns +/// if all elements returned true /// @param vec The vec_ast to search in /// @param fn The function to run on each element /// @param[out] result The result of the operation /// @return true if the operation failed, false otherwise /// @note If the vec_ast is empty, result will be true -t_error vec_ast_all(t_vec_ast *vec, bool (*fn)(const t_ast_node *), bool *result); +t_error vec_ast_all(t_vec_ast *vec, + bool (*fn)(const t_ast_node *), bool *result); -/// @brief Run the function on every element of the vec_ast and returns if any element returned true +/// @brief Run the function on every element of the vec_ast and returns +/// if any element returned true /// @param vec The vec_ast to search in /// @param fn The function to run on each element /// @param[out] result The result of the operation /// @return true if the operation failed, false otherwise /// @note If the vec_ast is empty, result will be false -t_error vec_ast_any(t_vec_ast *vec, bool (*fn)(const t_ast_node *), bool *result); +t_error vec_ast_any(t_vec_ast *vec, + bool (*fn)(const t_ast_node *), bool *result); /// @brief Run the function on every element of the vec_ast /// @param vec The vec_ast to iterate over /// @param fn The function to run on each element /// @param state The state to pass to the function -void vec_ast_iter(t_vec_ast *vec, void (*fn)(t_usize index, t_ast_node *value, void *state), void *state); +void vec_ast_iter(t_vec_ast *vec, + void (*fn)(t_usize index, t_ast_node *value, + void *state), + void *state); /// @brief Reverse the order of the elements in the vec_ast /// @param vec The vec_ast to reverse -void vec_ast_reverse(t_vec_ast *vec); +void vec_ast_reverse(t_vec_ast *vec); /// @brief Sort the elements of the vec_ast /// @param vec The vec_ast to sort /// @param is_sorted The function to use to compare the elements -void vec_ast_sort(t_vec_ast *vec, t_vec_ast_sort_fn is_sorted); +void vec_ast_sort(t_vec_ast *vec, + t_vec_ast_sort_fn is_sorted); /// @brief Get a pointer to the last element of the vec_ast /// @param vec The vec_ast to get the element from @@ -130,4 +158,17 @@ t_ast_node *vec_ast_get(t_vec_ast *vec, t_usize i); /// @return A pointer to the last element or NULL t_ast_node *vec_ast_last(t_vec_ast *vec); +/// @brief Perform a simple bytewise copy into the other vector +/// @param vec The vec_ast to be copied from +/// @param dest The vec_ast to be copied to +void vec_ast_copy_into(t_vec_ast *vec, t_vec_ast *dest); + +/// read code lol +void vec_ast_splice(t_vec_ast *self, + struct s_vec_ast_splice_arguments args); + +struct s_vec_ast_splice_arguments vec_ast_splice_args( + t_usize index, t_usize old_count, t_usize new_count, + const t_ast_node *elements); + #endif diff --git a/output/include/me/vec/vec_estr.h b/output/include/me/vec/vec_estr.h index 904de38b..c38d4faa 100644 --- a/output/include/me/vec/vec_estr.h +++ b/output/include/me/vec/vec_estr.h @@ -22,18 +22,31 @@ typedef bool (*t_vec_estr_sort_fn)(t_expandable_str *, t_expandable_str *); typedef void (*t_free_estr_item)(t_expandable_str); /// @brief A dynamic array of t_expandable_str -typedef struct s_vec_estr +typedef struct s_vec_estr t_vec_estr; + +struct s_vec_estr { t_free_estr_item free_func; t_usize len; t_usize capacity; t_expandable_str *buffer; -} t_vec_estr; +}; + +struct s_vec_estr_splice_arguments +{ + t_usize index; + t_usize old_count; + t_usize new_count; + const t_expandable_str *elements; +}; /// @brief Create a new vec_estr with a given capacity -/// @param capacity The capacity of the new vec_estr (in terms of elements) -/// @param free_function The function that will be used to free the elements of the vec_estr -t_vec_estr vec_estr_new(t_usize capacity, t_free_estr_item free_function); +/// @param capacity The capacity of the new vec_estr (in terms of +/// elements) +/// @param free_function The function that will be used to free the elements of +/// the vec_estr +t_vec_estr vec_estr_new(t_usize capacity, + t_free_estr_item free_function); /// @brief Push an element to the last position of the vec_estr /// @param vec The vec_estr to push the element to /// @param element The element to push @@ -43,16 +56,18 @@ t_error vec_estr_push(t_vec_estr *vec, t_expandable_str element); /// @param vec The vec_estr to push the element to /// @param element The element to push /// @note This operation is O(n) -t_error vec_estr_push_front(t_vec_estr *vec, t_expandable_str element); +t_error vec_estr_push_front(t_vec_estr *vec, + t_expandable_str element); -/// @brief Get the last element from the vec_estr, and remove it from the vec_estr +/// @brief Get the last element from the vec_estr, and remove it from the +/// vec_estr /// @param vec The vec_estr to get the element from /// @param[out] out The last element of the vec_estr /// @return true if the operation failed, false otherwise t_error vec_estr_pop(t_vec_estr *vec, t_expandable_str *value); - -/// @brief Get the first element from the vec_estr, and remove it from the vec_estr +/// @brief Get the first element from the vec_estr, and remove it from +/// the vec_estr /// @param vec The vec_estr to get the element from /// @param[out] out The first element of the vec_estr /// @return true if the operation failed, false otherwise @@ -61,58 +76,71 @@ t_error vec_estr_pop_front(t_vec_estr *vec, t_expandable_str *value); /// @brief Free the vector and all its elements /// @param vec The vec_estr to free -void vec_estr_free(t_vec_estr vec); +void vec_estr_free(t_vec_estr vec); /// @brief Make the vec_estr at least the given capacity /// @param vec The vec_estr to reserve /// @param wanted_capacity The minimum capacity to reserve /// @return true if the operation failed, false otherwise -t_error vec_estr_reserve(t_vec_estr *vec, t_usize wanted_capacity); +t_error vec_estr_reserve(t_vec_estr *vec, + t_usize wanted_capacity); -/// @brief Run the function and returns the index of the first element that returns true +/// @brief Run the function and returns the index of the first element that +/// returns true /// @param vec The vec_estr to search in /// @param fn The function to run on each element /// @param[out] index The index of the first element that returns true -t_error vec_estr_find(t_vec_estr *vec, bool (*fn)(const t_expandable_str *), t_usize *index); +t_error vec_estr_find(t_vec_estr *vec, + bool (*fn)(const t_expandable_str *), t_usize *index); - -/// @brief Run the function and returns the index of the first element that returns true, but starting at index starting_index +/// @brief Run the function and returns the index of the first element that +/// returns true, but starting at index starting_index /// @param vec The vec_estr to search in /// @param fn The function to run on each element /// @param starting_index The index to start the search from /// @param[out] index The index of the first element that returns true -t_error vec_estr_find_starting(t_vec_estr *vec, bool (*fn)(const t_expandable_str *), t_usize starting_index, t_usize *index); +t_error vec_estr_find_starting(t_vec_estr *vec, + bool (*fn)(const t_expandable_str *), + t_usize starting_index, t_usize *index); -/// @brief Run the function on every element of the vec_estr and returns if all elements returned true +/// @brief Run the function on every element of the vec_estr and returns +/// if all elements returned true /// @param vec The vec_estr to search in /// @param fn The function to run on each element /// @param[out] result The result of the operation /// @return true if the operation failed, false otherwise /// @note If the vec_estr is empty, result will be true -t_error vec_estr_all(t_vec_estr *vec, bool (*fn)(const t_expandable_str *), bool *result); +t_error vec_estr_all(t_vec_estr *vec, + bool (*fn)(const t_expandable_str *), bool *result); -/// @brief Run the function on every element of the vec_estr and returns if any element returned true +/// @brief Run the function on every element of the vec_estr and returns +/// if any element returned true /// @param vec The vec_estr to search in /// @param fn The function to run on each element /// @param[out] result The result of the operation /// @return true if the operation failed, false otherwise /// @note If the vec_estr is empty, result will be false -t_error vec_estr_any(t_vec_estr *vec, bool (*fn)(const t_expandable_str *), bool *result); +t_error vec_estr_any(t_vec_estr *vec, + bool (*fn)(const t_expandable_str *), bool *result); /// @brief Run the function on every element of the vec_estr /// @param vec The vec_estr to iterate over /// @param fn The function to run on each element /// @param state The state to pass to the function -void vec_estr_iter(t_vec_estr *vec, void (*fn)(t_usize index, t_expandable_str *value, void *state), void *state); +void vec_estr_iter(t_vec_estr *vec, + void (*fn)(t_usize index, t_expandable_str *value, + void *state), + void *state); /// @brief Reverse the order of the elements in the vec_estr /// @param vec The vec_estr to reverse -void vec_estr_reverse(t_vec_estr *vec); +void vec_estr_reverse(t_vec_estr *vec); /// @brief Sort the elements of the vec_estr /// @param vec The vec_estr to sort /// @param is_sorted The function to use to compare the elements -void vec_estr_sort(t_vec_estr *vec, t_vec_estr_sort_fn is_sorted); +void vec_estr_sort(t_vec_estr *vec, + t_vec_estr_sort_fn is_sorted); /// @brief Get a pointer to the last element of the vec_estr /// @param vec The vec_estr to get the element from @@ -130,4 +158,17 @@ t_expandable_str *vec_estr_get(t_vec_estr *vec, t_usize i); /// @return A pointer to the last element or NULL t_expandable_str *vec_estr_last(t_vec_estr *vec); +/// @brief Perform a simple bytewise copy into the other vector +/// @param vec The vec_estr to be copied from +/// @param dest The vec_estr to be copied to +void vec_estr_copy_into(t_vec_estr *vec, t_vec_estr *dest); + +/// read code lol +void vec_estr_splice(t_vec_estr *self, + struct s_vec_estr_splice_arguments args); + +struct s_vec_estr_splice_arguments vec_estr_splice_args( + t_usize index, t_usize old_count, t_usize new_count, + const t_expandable_str *elements); + #endif diff --git a/output/include/me/vec/vec_heredoc.h b/output/include/me/vec/vec_heredoc.h index ee45aea1..4a68bc17 100644 --- a/output/include/me/vec/vec_heredoc.h +++ b/output/include/me/vec/vec_heredoc.h @@ -22,18 +22,31 @@ typedef bool (*t_vec_heredoc_sort_fn)(t_heredoc *, t_heredoc *); typedef void (*t_free_heredoc_item)(t_heredoc); /// @brief A dynamic array of t_heredoc -typedef struct s_vec_heredoc +typedef struct s_vec_heredoc t_vec_heredoc; + +struct s_vec_heredoc { t_free_heredoc_item free_func; t_usize len; t_usize capacity; t_heredoc *buffer; -} t_vec_heredoc; +}; + +struct s_vec_heredoc_splice_arguments +{ + t_usize index; + t_usize old_count; + t_usize new_count; + const t_heredoc *elements; +}; /// @brief Create a new vec_heredoc with a given capacity -/// @param capacity The capacity of the new vec_heredoc (in terms of elements) -/// @param free_function The function that will be used to free the elements of the vec_heredoc -t_vec_heredoc vec_heredoc_new(t_usize capacity, t_free_heredoc_item free_function); +/// @param capacity The capacity of the new vec_heredoc (in terms of +/// elements) +/// @param free_function The function that will be used to free the elements of +/// the vec_heredoc +t_vec_heredoc vec_heredoc_new(t_usize capacity, + t_free_heredoc_item free_function); /// @brief Push an element to the last position of the vec_heredoc /// @param vec The vec_heredoc to push the element to /// @param element The element to push @@ -43,16 +56,18 @@ t_error vec_heredoc_push(t_vec_heredoc *vec, t_heredoc element); /// @param vec The vec_heredoc to push the element to /// @param element The element to push /// @note This operation is O(n) -t_error vec_heredoc_push_front(t_vec_heredoc *vec, t_heredoc element); +t_error vec_heredoc_push_front(t_vec_heredoc *vec, + t_heredoc element); -/// @brief Get the last element from the vec_heredoc, and remove it from the vec_heredoc +/// @brief Get the last element from the vec_heredoc, and remove it from the +/// vec_heredoc /// @param vec The vec_heredoc to get the element from /// @param[out] out The last element of the vec_heredoc /// @return true if the operation failed, false otherwise t_error vec_heredoc_pop(t_vec_heredoc *vec, t_heredoc *value); - -/// @brief Get the first element from the vec_heredoc, and remove it from the vec_heredoc +/// @brief Get the first element from the vec_heredoc, and remove it from +/// the vec_heredoc /// @param vec The vec_heredoc to get the element from /// @param[out] out The first element of the vec_heredoc /// @return true if the operation failed, false otherwise @@ -61,58 +76,71 @@ t_error vec_heredoc_pop_front(t_vec_heredoc *vec, t_heredoc *value); /// @brief Free the vector and all its elements /// @param vec The vec_heredoc to free -void vec_heredoc_free(t_vec_heredoc vec); +void vec_heredoc_free(t_vec_heredoc vec); /// @brief Make the vec_heredoc at least the given capacity /// @param vec The vec_heredoc to reserve /// @param wanted_capacity The minimum capacity to reserve /// @return true if the operation failed, false otherwise -t_error vec_heredoc_reserve(t_vec_heredoc *vec, t_usize wanted_capacity); +t_error vec_heredoc_reserve(t_vec_heredoc *vec, + t_usize wanted_capacity); -/// @brief Run the function and returns the index of the first element that returns true +/// @brief Run the function and returns the index of the first element that +/// returns true /// @param vec The vec_heredoc to search in /// @param fn The function to run on each element /// @param[out] index The index of the first element that returns true -t_error vec_heredoc_find(t_vec_heredoc *vec, bool (*fn)(const t_heredoc *), t_usize *index); +t_error vec_heredoc_find(t_vec_heredoc *vec, + bool (*fn)(const t_heredoc *), t_usize *index); - -/// @brief Run the function and returns the index of the first element that returns true, but starting at index starting_index +/// @brief Run the function and returns the index of the first element that +/// returns true, but starting at index starting_index /// @param vec The vec_heredoc to search in /// @param fn The function to run on each element /// @param starting_index The index to start the search from /// @param[out] index The index of the first element that returns true -t_error vec_heredoc_find_starting(t_vec_heredoc *vec, bool (*fn)(const t_heredoc *), t_usize starting_index, t_usize *index); +t_error vec_heredoc_find_starting(t_vec_heredoc *vec, + bool (*fn)(const t_heredoc *), + t_usize starting_index, t_usize *index); -/// @brief Run the function on every element of the vec_heredoc and returns if all elements returned true +/// @brief Run the function on every element of the vec_heredoc and returns +/// if all elements returned true /// @param vec The vec_heredoc to search in /// @param fn The function to run on each element /// @param[out] result The result of the operation /// @return true if the operation failed, false otherwise /// @note If the vec_heredoc is empty, result will be true -t_error vec_heredoc_all(t_vec_heredoc *vec, bool (*fn)(const t_heredoc *), bool *result); +t_error vec_heredoc_all(t_vec_heredoc *vec, + bool (*fn)(const t_heredoc *), bool *result); -/// @brief Run the function on every element of the vec_heredoc and returns if any element returned true +/// @brief Run the function on every element of the vec_heredoc and returns +/// if any element returned true /// @param vec The vec_heredoc to search in /// @param fn The function to run on each element /// @param[out] result The result of the operation /// @return true if the operation failed, false otherwise /// @note If the vec_heredoc is empty, result will be false -t_error vec_heredoc_any(t_vec_heredoc *vec, bool (*fn)(const t_heredoc *), bool *result); +t_error vec_heredoc_any(t_vec_heredoc *vec, + bool (*fn)(const t_heredoc *), bool *result); /// @brief Run the function on every element of the vec_heredoc /// @param vec The vec_heredoc to iterate over /// @param fn The function to run on each element /// @param state The state to pass to the function -void vec_heredoc_iter(t_vec_heredoc *vec, void (*fn)(t_usize index, t_heredoc *value, void *state), void *state); +void vec_heredoc_iter(t_vec_heredoc *vec, + void (*fn)(t_usize index, t_heredoc *value, + void *state), + void *state); /// @brief Reverse the order of the elements in the vec_heredoc /// @param vec The vec_heredoc to reverse -void vec_heredoc_reverse(t_vec_heredoc *vec); +void vec_heredoc_reverse(t_vec_heredoc *vec); /// @brief Sort the elements of the vec_heredoc /// @param vec The vec_heredoc to sort /// @param is_sorted The function to use to compare the elements -void vec_heredoc_sort(t_vec_heredoc *vec, t_vec_heredoc_sort_fn is_sorted); +void vec_heredoc_sort(t_vec_heredoc *vec, + t_vec_heredoc_sort_fn is_sorted); /// @brief Get a pointer to the last element of the vec_heredoc /// @param vec The vec_heredoc to get the element from @@ -130,4 +158,17 @@ t_heredoc *vec_heredoc_get(t_vec_heredoc *vec, t_usize i); /// @return A pointer to the last element or NULL t_heredoc *vec_heredoc_last(t_vec_heredoc *vec); +/// @brief Perform a simple bytewise copy into the other vector +/// @param vec The vec_heredoc to be copied from +/// @param dest The vec_heredoc to be copied to +void vec_heredoc_copy_into(t_vec_heredoc *vec, t_vec_heredoc *dest); + +/// read code lol +void vec_heredoc_splice(t_vec_heredoc *self, + struct s_vec_heredoc_splice_arguments args); + +struct s_vec_heredoc_splice_arguments vec_heredoc_splice_args( + t_usize index, t_usize old_count, t_usize new_count, + const t_heredoc *elements); + #endif diff --git a/output/include/me/vec/vec_pid.h b/output/include/me/vec/vec_pid.h index b0cd2670..9d7b3364 100644 --- a/output/include/me/vec/vec_pid.h +++ b/output/include/me/vec/vec_pid.h @@ -22,18 +22,31 @@ typedef bool (*t_vec_pid_sort_fn)(t_pid *, t_pid *); typedef void (*t_free_pid_item)(t_pid); /// @brief A dynamic array of t_pid -typedef struct s_vec_pid +typedef struct s_vec_pid t_vec_pid; + +struct s_vec_pid { t_free_pid_item free_func; t_usize len; t_usize capacity; t_pid *buffer; -} t_vec_pid; +}; + +struct s_vec_pid_splice_arguments +{ + t_usize index; + t_usize old_count; + t_usize new_count; + const t_pid *elements; +}; /// @brief Create a new vec_pid with a given capacity -/// @param capacity The capacity of the new vec_pid (in terms of elements) -/// @param free_function The function that will be used to free the elements of the vec_pid -t_vec_pid vec_pid_new(t_usize capacity, t_free_pid_item free_function); +/// @param capacity The capacity of the new vec_pid (in terms of +/// elements) +/// @param free_function The function that will be used to free the elements of +/// the vec_pid +t_vec_pid vec_pid_new(t_usize capacity, + t_free_pid_item free_function); /// @brief Push an element to the last position of the vec_pid /// @param vec The vec_pid to push the element to /// @param element The element to push @@ -43,16 +56,18 @@ t_error vec_pid_push(t_vec_pid *vec, t_pid element); /// @param vec The vec_pid to push the element to /// @param element The element to push /// @note This operation is O(n) -t_error vec_pid_push_front(t_vec_pid *vec, t_pid element); +t_error vec_pid_push_front(t_vec_pid *vec, + t_pid element); -/// @brief Get the last element from the vec_pid, and remove it from the vec_pid +/// @brief Get the last element from the vec_pid, and remove it from the +/// vec_pid /// @param vec The vec_pid to get the element from /// @param[out] out The last element of the vec_pid /// @return true if the operation failed, false otherwise t_error vec_pid_pop(t_vec_pid *vec, t_pid *value); - -/// @brief Get the first element from the vec_pid, and remove it from the vec_pid +/// @brief Get the first element from the vec_pid, and remove it from +/// the vec_pid /// @param vec The vec_pid to get the element from /// @param[out] out The first element of the vec_pid /// @return true if the operation failed, false otherwise @@ -61,58 +76,71 @@ t_error vec_pid_pop_front(t_vec_pid *vec, t_pid *value); /// @brief Free the vector and all its elements /// @param vec The vec_pid to free -void vec_pid_free(t_vec_pid vec); +void vec_pid_free(t_vec_pid vec); /// @brief Make the vec_pid at least the given capacity /// @param vec The vec_pid to reserve /// @param wanted_capacity The minimum capacity to reserve /// @return true if the operation failed, false otherwise -t_error vec_pid_reserve(t_vec_pid *vec, t_usize wanted_capacity); +t_error vec_pid_reserve(t_vec_pid *vec, + t_usize wanted_capacity); -/// @brief Run the function and returns the index of the first element that returns true +/// @brief Run the function and returns the index of the first element that +/// returns true /// @param vec The vec_pid to search in /// @param fn The function to run on each element /// @param[out] index The index of the first element that returns true -t_error vec_pid_find(t_vec_pid *vec, bool (*fn)(const t_pid *), t_usize *index); +t_error vec_pid_find(t_vec_pid *vec, + bool (*fn)(const t_pid *), t_usize *index); - -/// @brief Run the function and returns the index of the first element that returns true, but starting at index starting_index +/// @brief Run the function and returns the index of the first element that +/// returns true, but starting at index starting_index /// @param vec The vec_pid to search in /// @param fn The function to run on each element /// @param starting_index The index to start the search from /// @param[out] index The index of the first element that returns true -t_error vec_pid_find_starting(t_vec_pid *vec, bool (*fn)(const t_pid *), t_usize starting_index, t_usize *index); +t_error vec_pid_find_starting(t_vec_pid *vec, + bool (*fn)(const t_pid *), + t_usize starting_index, t_usize *index); -/// @brief Run the function on every element of the vec_pid and returns if all elements returned true +/// @brief Run the function on every element of the vec_pid and returns +/// if all elements returned true /// @param vec The vec_pid to search in /// @param fn The function to run on each element /// @param[out] result The result of the operation /// @return true if the operation failed, false otherwise /// @note If the vec_pid is empty, result will be true -t_error vec_pid_all(t_vec_pid *vec, bool (*fn)(const t_pid *), bool *result); +t_error vec_pid_all(t_vec_pid *vec, + bool (*fn)(const t_pid *), bool *result); -/// @brief Run the function on every element of the vec_pid and returns if any element returned true +/// @brief Run the function on every element of the vec_pid and returns +/// if any element returned true /// @param vec The vec_pid to search in /// @param fn The function to run on each element /// @param[out] result The result of the operation /// @return true if the operation failed, false otherwise /// @note If the vec_pid is empty, result will be false -t_error vec_pid_any(t_vec_pid *vec, bool (*fn)(const t_pid *), bool *result); +t_error vec_pid_any(t_vec_pid *vec, + bool (*fn)(const t_pid *), bool *result); /// @brief Run the function on every element of the vec_pid /// @param vec The vec_pid to iterate over /// @param fn The function to run on each element /// @param state The state to pass to the function -void vec_pid_iter(t_vec_pid *vec, void (*fn)(t_usize index, t_pid *value, void *state), void *state); +void vec_pid_iter(t_vec_pid *vec, + void (*fn)(t_usize index, t_pid *value, + void *state), + void *state); /// @brief Reverse the order of the elements in the vec_pid /// @param vec The vec_pid to reverse -void vec_pid_reverse(t_vec_pid *vec); +void vec_pid_reverse(t_vec_pid *vec); /// @brief Sort the elements of the vec_pid /// @param vec The vec_pid to sort /// @param is_sorted The function to use to compare the elements -void vec_pid_sort(t_vec_pid *vec, t_vec_pid_sort_fn is_sorted); +void vec_pid_sort(t_vec_pid *vec, + t_vec_pid_sort_fn is_sorted); /// @brief Get a pointer to the last element of the vec_pid /// @param vec The vec_pid to get the element from @@ -130,4 +158,17 @@ t_pid *vec_pid_get(t_vec_pid *vec, t_usize i); /// @return A pointer to the last element or NULL t_pid *vec_pid_last(t_vec_pid *vec); +/// @brief Perform a simple bytewise copy into the other vector +/// @param vec The vec_pid to be copied from +/// @param dest The vec_pid to be copied to +void vec_pid_copy_into(t_vec_pid *vec, t_vec_pid *dest); + +/// read code lol +void vec_pid_splice(t_vec_pid *self, + struct s_vec_pid_splice_arguments args); + +struct s_vec_pid_splice_arguments vec_pid_splice_args( + t_usize index, t_usize old_count, t_usize new_count, + const t_pid *elements); + #endif diff --git a/output/include/me/vec/vec_str.h b/output/include/me/vec/vec_str.h index 74e5631a..0ea87a41 100644 --- a/output/include/me/vec/vec_str.h +++ b/output/include/me/vec/vec_str.h @@ -22,18 +22,31 @@ typedef bool (*t_vec_str_sort_fn)(t_str *, t_str *); typedef void (*t_free_str_item)(t_str); /// @brief A dynamic array of t_str -typedef struct s_vec_str +typedef struct s_vec_str t_vec_str; + +struct s_vec_str { t_free_str_item free_func; t_usize len; t_usize capacity; t_str *buffer; -} t_vec_str; +}; + +struct s_vec_str_splice_arguments +{ + t_usize index; + t_usize old_count; + t_usize new_count; + const t_str *elements; +}; /// @brief Create a new vec_str with a given capacity -/// @param capacity The capacity of the new vec_str (in terms of elements) -/// @param free_function The function that will be used to free the elements of the vec_str -t_vec_str vec_str_new(t_usize capacity, t_free_str_item free_function); +/// @param capacity The capacity of the new vec_str (in terms of +/// elements) +/// @param free_function The function that will be used to free the elements of +/// the vec_str +t_vec_str vec_str_new(t_usize capacity, + t_free_str_item free_function); /// @brief Push an element to the last position of the vec_str /// @param vec The vec_str to push the element to /// @param element The element to push @@ -43,16 +56,18 @@ t_error vec_str_push(t_vec_str *vec, t_str element); /// @param vec The vec_str to push the element to /// @param element The element to push /// @note This operation is O(n) -t_error vec_str_push_front(t_vec_str *vec, t_str element); +t_error vec_str_push_front(t_vec_str *vec, + t_str element); -/// @brief Get the last element from the vec_str, and remove it from the vec_str +/// @brief Get the last element from the vec_str, and remove it from the +/// vec_str /// @param vec The vec_str to get the element from /// @param[out] out The last element of the vec_str /// @return true if the operation failed, false otherwise t_error vec_str_pop(t_vec_str *vec, t_str *value); - -/// @brief Get the first element from the vec_str, and remove it from the vec_str +/// @brief Get the first element from the vec_str, and remove it from +/// the vec_str /// @param vec The vec_str to get the element from /// @param[out] out The first element of the vec_str /// @return true if the operation failed, false otherwise @@ -61,58 +76,71 @@ t_error vec_str_pop_front(t_vec_str *vec, t_str *value); /// @brief Free the vector and all its elements /// @param vec The vec_str to free -void vec_str_free(t_vec_str vec); +void vec_str_free(t_vec_str vec); /// @brief Make the vec_str at least the given capacity /// @param vec The vec_str to reserve /// @param wanted_capacity The minimum capacity to reserve /// @return true if the operation failed, false otherwise -t_error vec_str_reserve(t_vec_str *vec, t_usize wanted_capacity); +t_error vec_str_reserve(t_vec_str *vec, + t_usize wanted_capacity); -/// @brief Run the function and returns the index of the first element that returns true +/// @brief Run the function and returns the index of the first element that +/// returns true /// @param vec The vec_str to search in /// @param fn The function to run on each element /// @param[out] index The index of the first element that returns true -t_error vec_str_find(t_vec_str *vec, bool (*fn)(const t_str *), t_usize *index); +t_error vec_str_find(t_vec_str *vec, + bool (*fn)(const t_str *), t_usize *index); - -/// @brief Run the function and returns the index of the first element that returns true, but starting at index starting_index +/// @brief Run the function and returns the index of the first element that +/// returns true, but starting at index starting_index /// @param vec The vec_str to search in /// @param fn The function to run on each element /// @param starting_index The index to start the search from /// @param[out] index The index of the first element that returns true -t_error vec_str_find_starting(t_vec_str *vec, bool (*fn)(const t_str *), t_usize starting_index, t_usize *index); +t_error vec_str_find_starting(t_vec_str *vec, + bool (*fn)(const t_str *), + t_usize starting_index, t_usize *index); -/// @brief Run the function on every element of the vec_str and returns if all elements returned true +/// @brief Run the function on every element of the vec_str and returns +/// if all elements returned true /// @param vec The vec_str to search in /// @param fn The function to run on each element /// @param[out] result The result of the operation /// @return true if the operation failed, false otherwise /// @note If the vec_str is empty, result will be true -t_error vec_str_all(t_vec_str *vec, bool (*fn)(const t_str *), bool *result); +t_error vec_str_all(t_vec_str *vec, + bool (*fn)(const t_str *), bool *result); -/// @brief Run the function on every element of the vec_str and returns if any element returned true +/// @brief Run the function on every element of the vec_str and returns +/// if any element returned true /// @param vec The vec_str to search in /// @param fn The function to run on each element /// @param[out] result The result of the operation /// @return true if the operation failed, false otherwise /// @note If the vec_str is empty, result will be false -t_error vec_str_any(t_vec_str *vec, bool (*fn)(const t_str *), bool *result); +t_error vec_str_any(t_vec_str *vec, + bool (*fn)(const t_str *), bool *result); /// @brief Run the function on every element of the vec_str /// @param vec The vec_str to iterate over /// @param fn The function to run on each element /// @param state The state to pass to the function -void vec_str_iter(t_vec_str *vec, void (*fn)(t_usize index, t_str *value, void *state), void *state); +void vec_str_iter(t_vec_str *vec, + void (*fn)(t_usize index, t_str *value, + void *state), + void *state); /// @brief Reverse the order of the elements in the vec_str /// @param vec The vec_str to reverse -void vec_str_reverse(t_vec_str *vec); +void vec_str_reverse(t_vec_str *vec); /// @brief Sort the elements of the vec_str /// @param vec The vec_str to sort /// @param is_sorted The function to use to compare the elements -void vec_str_sort(t_vec_str *vec, t_vec_str_sort_fn is_sorted); +void vec_str_sort(t_vec_str *vec, + t_vec_str_sort_fn is_sorted); /// @brief Get a pointer to the last element of the vec_str /// @param vec The vec_str to get the element from @@ -130,4 +158,17 @@ t_str *vec_str_get(t_vec_str *vec, t_usize i); /// @return A pointer to the last element or NULL t_str *vec_str_last(t_vec_str *vec); +/// @brief Perform a simple bytewise copy into the other vector +/// @param vec The vec_str to be copied from +/// @param dest The vec_str to be copied to +void vec_str_copy_into(t_vec_str *vec, t_vec_str *dest); + +/// read code lol +void vec_str_splice(t_vec_str *self, + struct s_vec_str_splice_arguments args); + +struct s_vec_str_splice_arguments vec_str_splice_args( + t_usize index, t_usize old_count, t_usize new_count, + const t_str *elements); + #endif diff --git a/output/include/me/vec/vec_subtree.h b/output/include/me/vec/vec_subtree.h new file mode 100644 index 00000000..d4ad7aea --- /dev/null +++ b/output/include/me/vec/vec_subtree.h @@ -0,0 +1,174 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_subtree.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/04 18:46:53 by maiboyer #+# #+# */ +/* Updated: 2023/12/09 17:53:00 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef VEC_SUBTREE_H +#define VEC_SUBTREE_H + +#include "parser/inner/subtree_inner.h" +#include "me/types.h" + +/// @brief A function that takes two t_subtree and compare them +typedef bool (*t_vec_subtree_sort_fn)(t_subtree *, t_subtree *); +/// @brief A function that free an t_subtree +typedef void (*t_free_subtree_item)(t_subtree); + +/// @brief A dynamic array of t_subtree +typedef struct s_vec_subtree t_vec_subtree; + +struct s_vec_subtree +{ + t_free_subtree_item free_func; + t_usize len; + t_usize capacity; + t_subtree *buffer; +}; + +struct s_vec_subtree_splice_arguments +{ + t_usize index; + t_usize old_count; + t_usize new_count; + const t_subtree *elements; +}; + +/// @brief Create a new vec_subtree with a given capacity +/// @param capacity The capacity of the new vec_subtree (in terms of +/// elements) +/// @param free_function The function that will be used to free the elements of +/// the vec_subtree +t_vec_subtree vec_subtree_new(t_usize capacity, + t_free_subtree_item free_function); +/// @brief Push an element to the last position of the vec_subtree +/// @param vec The vec_subtree to push the element to +/// @param element The element to push +t_error vec_subtree_push(t_vec_subtree *vec, t_subtree element); + +/// @brief Push an element to the first position of the vec_subtree +/// @param vec The vec_subtree to push the element to +/// @param element The element to push +/// @note This operation is O(n) +t_error vec_subtree_push_front(t_vec_subtree *vec, + t_subtree element); + +/// @brief Get the last element from the vec_subtree, and remove it from the +/// vec_subtree +/// @param vec The vec_subtree to get the element from +/// @param[out] out The last element of the vec_subtree +/// @return true if the operation failed, false otherwise +t_error vec_subtree_pop(t_vec_subtree *vec, t_subtree *value); + +/// @brief Get the first element from the vec_subtree, and remove it from +/// the vec_subtree +/// @param vec The vec_subtree to get the element from +/// @param[out] out The first element of the vec_subtree +/// @return true if the operation failed, false otherwise +/// @note This operation is O(n) +t_error vec_subtree_pop_front(t_vec_subtree *vec, t_subtree *value); + +/// @brief Free the vector and all its elements +/// @param vec The vec_subtree to free +void vec_subtree_free(t_vec_subtree vec); + +/// @brief Make the vec_subtree at least the given capacity +/// @param vec The vec_subtree to reserve +/// @param wanted_capacity The minimum capacity to reserve +/// @return true if the operation failed, false otherwise +t_error vec_subtree_reserve(t_vec_subtree *vec, + t_usize wanted_capacity); + +/// @brief Run the function and returns the index of the first element that +/// returns true +/// @param vec The vec_subtree to search in +/// @param fn The function to run on each element +/// @param[out] index The index of the first element that returns true +t_error vec_subtree_find(t_vec_subtree *vec, + bool (*fn)(const t_subtree *), t_usize *index); + +/// @brief Run the function and returns the index of the first element that +/// returns true, but starting at index starting_index +/// @param vec The vec_subtree to search in +/// @param fn The function to run on each element +/// @param starting_index The index to start the search from +/// @param[out] index The index of the first element that returns true +t_error vec_subtree_find_starting(t_vec_subtree *vec, + bool (*fn)(const t_subtree *), + t_usize starting_index, t_usize *index); + +/// @brief Run the function on every element of the vec_subtree and returns +/// if all elements returned true +/// @param vec The vec_subtree to search in +/// @param fn The function to run on each element +/// @param[out] result The result of the operation +/// @return true if the operation failed, false otherwise +/// @note If the vec_subtree is empty, result will be true +t_error vec_subtree_all(t_vec_subtree *vec, + bool (*fn)(const t_subtree *), bool *result); + +/// @brief Run the function on every element of the vec_subtree and returns +/// if any element returned true +/// @param vec The vec_subtree to search in +/// @param fn The function to run on each element +/// @param[out] result The result of the operation +/// @return true if the operation failed, false otherwise +/// @note If the vec_subtree is empty, result will be false +t_error vec_subtree_any(t_vec_subtree *vec, + bool (*fn)(const t_subtree *), bool *result); + +/// @brief Run the function on every element of the vec_subtree +/// @param vec The vec_subtree to iterate over +/// @param fn The function to run on each element +/// @param state The state to pass to the function +void vec_subtree_iter(t_vec_subtree *vec, + void (*fn)(t_usize index, t_subtree *value, + void *state), + void *state); + +/// @brief Reverse the order of the elements in the vec_subtree +/// @param vec The vec_subtree to reverse +void vec_subtree_reverse(t_vec_subtree *vec); + +/// @brief Sort the elements of the vec_subtree +/// @param vec The vec_subtree to sort +/// @param is_sorted The function to use to compare the elements +void vec_subtree_sort(t_vec_subtree *vec, + t_vec_subtree_sort_fn is_sorted); + +/// @brief Get a pointer to the last element of the vec_subtree +/// @param vec The vec_subtree to get the element from +/// @param[out] out A pointer to the last element of the vec_subtree +/// @return true if the operation failed, false otherwise +t_error vec_subtree_back(t_vec_subtree *vec, t_subtree **out); + +/// @brief Get a pointer to the i'th element, or NULL otherwise +/// @param vec The vec_subtree to get the element from +/// @return A pointer to the element or NULL +t_subtree *vec_subtree_get(t_vec_subtree *vec, t_usize i); + +/// @brief Get a pointer to the last element, or NULL otherwise +/// @param vec The vec_subtree to get the element from +/// @return A pointer to the last element or NULL +t_subtree *vec_subtree_last(t_vec_subtree *vec); + +/// @brief Perform a simple bytewise copy into the other vector +/// @param vec The vec_subtree to be copied from +/// @param dest The vec_subtree to be copied to +void vec_subtree_copy_into(t_vec_subtree *vec, t_vec_subtree *dest); + +/// read code lol +void vec_subtree_splice(t_vec_subtree *self, + struct s_vec_subtree_splice_arguments args); + +struct s_vec_subtree_splice_arguments vec_subtree_splice_args( + t_usize index, t_usize old_count, t_usize new_count, + const t_subtree *elements); + +#endif diff --git a/output/src/vec/ast/ast_functions4.c b/output/src/vec/ast/ast_functions4.c index 3c9e3853..05e95141 100644 --- a/output/src/vec/ast/ast_functions4.c +++ b/output/src/vec/ast/ast_functions4.c @@ -17,14 +17,59 @@ t_ast_node *vec_ast_get(t_vec_ast *vec, t_usize i) { - if (vec->len >= i) + if (vec == NULL || vec->len >= i) return (NULL); return (&vec->buffer[i]); } t_ast_node *vec_ast_last(t_vec_ast *vec) { - if (vec->len == 0) + if (vec == NULL || vec->len == 0) return (NULL); return (&vec->buffer[vec->len - 1]); } + +void vec_ast_copy_into(t_vec_ast *vec, t_vec_ast *dest) +{ + if (vec == NULL || dest == NULL) + return ; + vec_ast_reserve(dest, vec->capacity); + mem_copy(dest->buffer, vec->buffer, vec->len * sizeof(t_ast_node)); +} + +struct s_vec_ast_splice_arguments vec_ast_splice_args( + t_usize index, t_usize old_count, t_usize new_count, + const t_ast_node *elements) +{ + return ((struct s_vec_ast_splice_arguments){index, old_count, + new_count, elements}); +} + +void vec_ast_splice(t_vec_ast *self, + struct s_vec_ast_splice_arguments args) +{ + t_ast_node *contents; + t_u32 new_size; + t_u32 old_end; + t_u32 new_end; + + new_size = self->len + args.new_count - args.old_count; + old_end = args.index + args.old_count; + new_end = args.index + args.new_count; + vec_ast_reserve(self, new_size); + contents = self->buffer; + if (self->len > old_end) + mem_move(contents + new_end, + contents + old_end, + (self->len - old_end) * sizeof(t_ast_node)); + if (args.new_count > 0) + { + if (args.elements) + mem_copy((contents + args.index * sizeof(t_ast_node)), + args.elements, args.new_count * sizeof(t_ast_node)); + else + mem_set_zero((contents + args.index * sizeof(t_ast_node)), + args.new_count * sizeof(t_ast_node)); + } + self->len += args.new_count - args.old_count; +} diff --git a/output/src/vec/estr/estr_functions4.c b/output/src/vec/estr/estr_functions4.c index 02f65a86..20d07509 100644 --- a/output/src/vec/estr/estr_functions4.c +++ b/output/src/vec/estr/estr_functions4.c @@ -17,14 +17,59 @@ t_expandable_str *vec_estr_get(t_vec_estr *vec, t_usize i) { - if (vec->len >= i) + if (vec == NULL || vec->len >= i) return (NULL); return (&vec->buffer[i]); } t_expandable_str *vec_estr_last(t_vec_estr *vec) { - if (vec->len == 0) + if (vec == NULL || vec->len == 0) return (NULL); return (&vec->buffer[vec->len - 1]); } + +void vec_estr_copy_into(t_vec_estr *vec, t_vec_estr *dest) +{ + if (vec == NULL || dest == NULL) + return ; + vec_estr_reserve(dest, vec->capacity); + mem_copy(dest->buffer, vec->buffer, vec->len * sizeof(t_expandable_str)); +} + +struct s_vec_estr_splice_arguments vec_estr_splice_args( + t_usize index, t_usize old_count, t_usize new_count, + const t_expandable_str *elements) +{ + return ((struct s_vec_estr_splice_arguments){index, old_count, + new_count, elements}); +} + +void vec_estr_splice(t_vec_estr *self, + struct s_vec_estr_splice_arguments args) +{ + t_expandable_str *contents; + t_u32 new_size; + t_u32 old_end; + t_u32 new_end; + + new_size = self->len + args.new_count - args.old_count; + old_end = args.index + args.old_count; + new_end = args.index + args.new_count; + vec_estr_reserve(self, new_size); + contents = self->buffer; + if (self->len > old_end) + mem_move(contents + new_end, + contents + old_end, + (self->len - old_end) * sizeof(t_expandable_str)); + if (args.new_count > 0) + { + if (args.elements) + mem_copy((contents + args.index * sizeof(t_expandable_str)), + args.elements, args.new_count * sizeof(t_expandable_str)); + else + mem_set_zero((contents + args.index * sizeof(t_expandable_str)), + args.new_count * sizeof(t_expandable_str)); + } + self->len += args.new_count - args.old_count; +} diff --git a/output/src/vec/heredoc/heredoc_functions4.c b/output/src/vec/heredoc/heredoc_functions4.c index a2d1cf73..4b4dc2b2 100644 --- a/output/src/vec/heredoc/heredoc_functions4.c +++ b/output/src/vec/heredoc/heredoc_functions4.c @@ -17,14 +17,59 @@ t_heredoc *vec_heredoc_get(t_vec_heredoc *vec, t_usize i) { - if (vec->len >= i) + if (vec == NULL || vec->len >= i) return (NULL); return (&vec->buffer[i]); } t_heredoc *vec_heredoc_last(t_vec_heredoc *vec) { - if (vec->len == 0) + if (vec == NULL || vec->len == 0) return (NULL); return (&vec->buffer[vec->len - 1]); } + +void vec_heredoc_copy_into(t_vec_heredoc *vec, t_vec_heredoc *dest) +{ + if (vec == NULL || dest == NULL) + return ; + vec_heredoc_reserve(dest, vec->capacity); + mem_copy(dest->buffer, vec->buffer, vec->len * sizeof(t_heredoc)); +} + +struct s_vec_heredoc_splice_arguments vec_heredoc_splice_args( + t_usize index, t_usize old_count, t_usize new_count, + const t_heredoc *elements) +{ + return ((struct s_vec_heredoc_splice_arguments){index, old_count, + new_count, elements}); +} + +void vec_heredoc_splice(t_vec_heredoc *self, + struct s_vec_heredoc_splice_arguments args) +{ + t_heredoc *contents; + t_u32 new_size; + t_u32 old_end; + t_u32 new_end; + + new_size = self->len + args.new_count - args.old_count; + old_end = args.index + args.old_count; + new_end = args.index + args.new_count; + vec_heredoc_reserve(self, new_size); + contents = self->buffer; + if (self->len > old_end) + mem_move(contents + new_end, + contents + old_end, + (self->len - old_end) * sizeof(t_heredoc)); + if (args.new_count > 0) + { + if (args.elements) + mem_copy((contents + args.index * sizeof(t_heredoc)), + args.elements, args.new_count * sizeof(t_heredoc)); + else + mem_set_zero((contents + args.index * sizeof(t_heredoc)), + args.new_count * sizeof(t_heredoc)); + } + self->len += args.new_count - args.old_count; +} diff --git a/output/src/vec/pid/pid_functions4.c b/output/src/vec/pid/pid_functions4.c index 3be22bfd..2022678b 100644 --- a/output/src/vec/pid/pid_functions4.c +++ b/output/src/vec/pid/pid_functions4.c @@ -17,14 +17,59 @@ t_pid *vec_pid_get(t_vec_pid *vec, t_usize i) { - if (vec->len >= i) + if (vec == NULL || vec->len >= i) return (NULL); return (&vec->buffer[i]); } t_pid *vec_pid_last(t_vec_pid *vec) { - if (vec->len == 0) + if (vec == NULL || vec->len == 0) return (NULL); return (&vec->buffer[vec->len - 1]); } + +void vec_pid_copy_into(t_vec_pid *vec, t_vec_pid *dest) +{ + if (vec == NULL || dest == NULL) + return ; + vec_pid_reserve(dest, vec->capacity); + mem_copy(dest->buffer, vec->buffer, vec->len * sizeof(t_pid)); +} + +struct s_vec_pid_splice_arguments vec_pid_splice_args( + t_usize index, t_usize old_count, t_usize new_count, + const t_pid *elements) +{ + return ((struct s_vec_pid_splice_arguments){index, old_count, + new_count, elements}); +} + +void vec_pid_splice(t_vec_pid *self, + struct s_vec_pid_splice_arguments args) +{ + t_pid *contents; + t_u32 new_size; + t_u32 old_end; + t_u32 new_end; + + new_size = self->len + args.new_count - args.old_count; + old_end = args.index + args.old_count; + new_end = args.index + args.new_count; + vec_pid_reserve(self, new_size); + contents = self->buffer; + if (self->len > old_end) + mem_move(contents + new_end, + contents + old_end, + (self->len - old_end) * sizeof(t_pid)); + if (args.new_count > 0) + { + if (args.elements) + mem_copy((contents + args.index * sizeof(t_pid)), + args.elements, args.new_count * sizeof(t_pid)); + else + mem_set_zero((contents + args.index * sizeof(t_pid)), + args.new_count * sizeof(t_pid)); + } + self->len += args.new_count - args.old_count; +} diff --git a/output/src/vec/str/str_functions4.c b/output/src/vec/str/str_functions4.c index 44e73771..cd74bb14 100644 --- a/output/src/vec/str/str_functions4.c +++ b/output/src/vec/str/str_functions4.c @@ -17,14 +17,59 @@ t_str *vec_str_get(t_vec_str *vec, t_usize i) { - if (vec->len >= i) + if (vec == NULL || vec->len >= i) return (NULL); return (&vec->buffer[i]); } t_str *vec_str_last(t_vec_str *vec) { - if (vec->len == 0) + if (vec == NULL || vec->len == 0) return (NULL); return (&vec->buffer[vec->len - 1]); } + +void vec_str_copy_into(t_vec_str *vec, t_vec_str *dest) +{ + if (vec == NULL || dest == NULL) + return ; + vec_str_reserve(dest, vec->capacity); + mem_copy(dest->buffer, vec->buffer, vec->len * sizeof(t_str)); +} + +struct s_vec_str_splice_arguments vec_str_splice_args( + t_usize index, t_usize old_count, t_usize new_count, + const t_str *elements) +{ + return ((struct s_vec_str_splice_arguments){index, old_count, + new_count, elements}); +} + +void vec_str_splice(t_vec_str *self, + struct s_vec_str_splice_arguments args) +{ + t_str *contents; + t_u32 new_size; + t_u32 old_end; + t_u32 new_end; + + new_size = self->len + args.new_count - args.old_count; + old_end = args.index + args.old_count; + new_end = args.index + args.new_count; + vec_str_reserve(self, new_size); + contents = self->buffer; + if (self->len > old_end) + mem_move(contents + new_end, + contents + old_end, + (self->len - old_end) * sizeof(t_str)); + if (args.new_count > 0) + { + if (args.elements) + mem_copy((contents + args.index * sizeof(t_str)), + args.elements, args.new_count * sizeof(t_str)); + else + mem_set_zero((contents + args.index * sizeof(t_str)), + args.new_count * sizeof(t_str)); + } + self->len += args.new_count - args.old_count; +} diff --git a/output/src/vec/subtree/subtree.c b/output/src/vec/subtree/subtree.c new file mode 100644 index 00000000..ff7fc56e --- /dev/null +++ b/output/src/vec/subtree/subtree.c @@ -0,0 +1,95 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_subtree.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/05 18:46:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/09 17:54:11 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem.h" +#include "me/types.h" +#include "me/vec/vec_subtree.h" +#include + +t_vec_subtree vec_subtree_new(t_usize capacity, + t_free_subtree_item free_function) +{ + t_vec_subtree out; + + out = (t_vec_subtree){0}; + out.free_func = free_function; + out.buffer = mem_alloc_array(capacity, sizeof(t_subtree)); + if (out.buffer) + out.capacity = capacity; + return (out); +} + +/// Return true in case of an error +t_error vec_subtree_push(t_vec_subtree *vec, t_subtree element) +{ + if (vec == NULL) + return (ERROR); + vec_subtree_reserve(vec, vec->len + 1); + vec->buffer[vec->len] = element; + vec->len += 1; + return (NO_ERROR); +} + +/// Return true in case of an error +t_error vec_subtree_reserve(t_vec_subtree *vec, t_usize wanted_capacity) +{ + size_t new_capacity; + + if (vec == NULL) + return (ERROR); + if (wanted_capacity > vec->capacity) + { + new_capacity = (vec->capacity * 3) / 2 + 1; + while (wanted_capacity > new_capacity) + new_capacity = (new_capacity * 3) / 2 + 1; + vec->buffer = + mem_realloc_array(vec->buffer, new_capacity, sizeof(t_subtree)); + vec->capacity = new_capacity; + } + return (NO_ERROR); +} + +/// Return true if the vector is empty +/// This function is safe to call with value being NULL +t_error vec_subtree_pop(t_vec_subtree *vec, t_subtree *value) +{ + t_subtree temp_value; + t_subtree *ptr; + + if (vec == NULL) + return (ERROR); + ptr = value; + if (vec->len == 0) + return (ERROR); + if (value == NULL) + ptr = &temp_value; + vec->len--; + *ptr = vec->buffer[vec->len]; + mem_set_zero(&vec->buffer[vec->len], sizeof(t_subtree)); + return (NO_ERROR); +} + +/// This function is safe to call with `free_elem` being NULL +void vec_subtree_free(t_vec_subtree vec) +{ + if (vec.buffer == NULL) + return; + if (vec.free_func) + { + while (vec.len) + { + vec.free_func(vec.buffer[vec.len - 1]); + vec.len--; + } + } + mem_free(vec.buffer); +} diff --git a/output/src/vec/subtree/subtree_functions2.c b/output/src/vec/subtree/subtree_functions2.c new file mode 100644 index 00000000..e994ea31 --- /dev/null +++ b/output/src/vec/subtree/subtree_functions2.c @@ -0,0 +1,112 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_subtree.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/30 17:59:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/30 17:59:28 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem.h" +#include "me/mem/mem.h" +#include "me/mem/mem.h" +#include "me/types.h" +#include "me/vec/vec_subtree.h" +#include + +t_error vec_subtree_find(t_vec_subtree *vec, + bool (*fn)(const t_subtree *), t_usize *index) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || index == NULL) + return (ERROR); + idx = 0; + while (idx < vec->len) + { + if (fn((const t_subtree *)&vec->buffer[idx])) + { + *index = idx; + return (NO_ERROR); + } + idx++; + } + return (ERROR); +} + +t_error vec_subtree_find_starting(t_vec_subtree *vec, + bool (*fn)(const t_subtree *), + t_usize starting_index, t_usize *index) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || index == NULL) + return (ERROR); + idx = starting_index; + while (idx < vec->len) + { + if (fn((const t_subtree *)&vec->buffer[idx])) + { + *index = idx; + return (NO_ERROR); + } + idx++; + } + return (ERROR); +} + +t_error vec_subtree_all(t_vec_subtree *vec, + bool (*fn)(const t_subtree *), bool *result) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || result == NULL) + return (ERROR); + idx = 0; + *result = true; + while (*result && idx < vec->len) + { + if (!fn((const t_subtree *)&vec->buffer[idx])) + *result = false; + idx++; + } + return (ERROR); +} + +t_error vec_subtree_any(t_vec_subtree *vec, + bool (*fn)(const t_subtree *), bool *result) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || result == NULL) + return (ERROR); + idx = 0; + *result = false; + while (*result && idx < vec->len) + { + if (fn((const t_subtree *)&vec->buffer[idx])) + *result = true; + idx++; + } + return (ERROR); +} + +void vec_subtree_iter(t_vec_subtree *vec, + void (*fn)(t_usize index, t_subtree *value, + void *state), + void *state) +{ + t_usize idx; + + if (vec == NULL || fn == NULL) + return; + idx = 0; + while (idx < vec->len) + { + fn(idx, &vec->buffer[idx], state); + idx++; + } +} diff --git a/output/src/vec/subtree/subtree_functions3.c b/output/src/vec/subtree/subtree_functions3.c new file mode 100644 index 00000000..7ef95490 --- /dev/null +++ b/output/src/vec/subtree/subtree_functions3.c @@ -0,0 +1,82 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_subtree.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/30 17:59:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/30 17:59:28 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem.h" +#include "me/types.h" +#include "me/vec/vec_subtree.h" +#include + +t_error vec_subtree_push_front(t_vec_subtree *vec, + t_subtree element) +{ + t_usize i; + + if (vec->len == 0) + return (vec_subtree_push(vec, element)); + i = vec->len - 1; + if (vec->capacity < vec->len + 1 && + vec_subtree_reserve(vec, 3 * vec->len / 2 + 1)) + return (ERROR); + while (i > 0) + { + vec->buffer[i + 1] = vec->buffer[i]; + i--; + } + vec->buffer[1] = vec->buffer[0]; + vec->buffer[0] = element; + vec->len++; + return (NO_ERROR); +} + +t_error vec_subtree_pop_front(t_vec_subtree *vec, t_subtree *value) +{ + t_usize i; + + if (vec->len <= 1) + return (vec_subtree_pop(vec, value)); + i = 0; + *value = vec->buffer[0]; + vec->len--; + while (i < vec->len) + { + vec->buffer[i] = vec->buffer[i + 1]; + i++; + } + mem_set_zero(&vec->buffer[i], sizeof(*vec->buffer)); + return (NO_ERROR); +} + +void vec_subtree_reverse(t_vec_subtree *vec) +{ + t_subtree temporary; + t_usize i; + + i = 0; + while (i < vec->len / 2) + { + temporary = vec->buffer[vec->len - 1 - i]; + vec->buffer[vec->len - 1 - i] = vec->buffer[i]; + vec->buffer[i] = temporary; + i++; + } +} + +t_error vec_subtree_back(t_vec_subtree *vec, t_subtree **out) +{ + t_subtree *temporary; + + if (out == NULL) + out = &temporary; + if (vec->len != 0) + return (*out = &vec->buffer[vec->len - 1], true); + return (false); +} diff --git a/output/src/vec/subtree/subtree_functions4.c b/output/src/vec/subtree/subtree_functions4.c new file mode 100644 index 00000000..007d1c5c --- /dev/null +++ b/output/src/vec/subtree/subtree_functions4.c @@ -0,0 +1,75 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_subtree.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/30 17:59:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/30 17:59:28 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem.h" +#include "me/types.h" +#include "me/vec/vec_subtree.h" +#include + +t_subtree *vec_subtree_get(t_vec_subtree *vec, t_usize i) +{ + if (vec == NULL || vec->len >= i) + return (NULL); + return (&vec->buffer[i]); +} + +t_subtree *vec_subtree_last(t_vec_subtree *vec) +{ + if (vec == NULL || vec->len == 0) + return (NULL); + return (&vec->buffer[vec->len - 1]); +} + +void vec_subtree_copy_into(t_vec_subtree *vec, t_vec_subtree *dest) +{ + if (vec == NULL || dest == NULL) + return ; + vec_subtree_reserve(dest, vec->capacity); + mem_copy(dest->buffer, vec->buffer, vec->len * sizeof(t_subtree)); +} + +struct s_vec_subtree_splice_arguments vec_subtree_splice_args( + t_usize index, t_usize old_count, t_usize new_count, + const t_subtree *elements) +{ + return ((struct s_vec_subtree_splice_arguments){index, old_count, + new_count, elements}); +} + +void vec_subtree_splice(t_vec_subtree *self, + struct s_vec_subtree_splice_arguments args) +{ + t_subtree *contents; + t_u32 new_size; + t_u32 old_end; + t_u32 new_end; + + new_size = self->len + args.new_count - args.old_count; + old_end = args.index + args.old_count; + new_end = args.index + args.new_count; + vec_subtree_reserve(self, new_size); + contents = self->buffer; + if (self->len > old_end) + mem_move(contents + new_end, + contents + old_end, + (self->len - old_end) * sizeof(t_subtree)); + if (args.new_count > 0) + { + if (args.elements) + mem_copy((contents + args.index * sizeof(t_subtree)), + args.elements, args.new_count * sizeof(t_subtree)); + else + mem_set_zero((contents + args.index * sizeof(t_subtree)), + args.new_count * sizeof(t_subtree)); + } + self->len += args.new_count - args.old_count; +} diff --git a/output/src/vec/subtree/subtree_sort.c b/output/src/vec/subtree/subtree_sort.c new file mode 100644 index 00000000..2d6b1a5c --- /dev/null +++ b/output/src/vec/subtree/subtree_sort.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* best_move.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/29 20:04:33 by maiboyer #+# #+# */ +/* Updated: 2024/01/31 14:25:00 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/types.h" +#include "me/vec/vec_subtree.h" + +void vec_subtree_sort(t_vec_subtree *v, + t_vec_subtree_sort_fn is_sorted_fn) +{ + t_usize sorted_part; + t_usize i; + t_subtree tmp; + + if (v == NULL) + return; + sorted_part = v->len; + while (sorted_part > 0) + { + i = 0; + while (i < sorted_part - 1) + { + if (!is_sorted_fn(&v->buffer[i], &v->buffer[i + 1])) + { + tmp = v->buffer[i]; + v->buffer[i] = v->buffer[i + 1]; + v->buffer[i + 1] = tmp; + } + i++; + } + sorted_part--; + } +} diff --git a/parser/Filelist.parser.mk b/parser/Filelist.parser.mk index 2d84a3fb..fe0263ad 100644 --- a/parser/Filelist.parser.mk +++ b/parser/Filelist.parser.mk @@ -58,6 +58,7 @@ stack/stack_node \ stack/stack_summary \ stack/stack_version \ subtree \ +subtree/subtree_funcs1 \ tree/tree_funcs1 \ tree/tree_funcs2 \ diff --git a/parser/include/parser/api.h b/parser/include/parser/api.h index 857428eb..b946a2ff 100644 --- a/parser/include/parser/api.h +++ b/parser/include/parser/api.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/22 13:54:54 by maiboyer #+# #+# */ -/* Updated: 2024/08/31 12:10:39 by maiboyer ### ########.fr */ +/* Updated: 2024/09/02 20:15:44 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,6 +14,9 @@ #define API_H #include "me/types.h" +#include "parser/inner/length_inner.h" +#include "parser/inner/point_inner.h" +#include "parser/inner/subtree_inner.h" #define ERROR_STATE 0 #define ERROR_COST_PER_RECOVERY 500 @@ -22,672 +25,76 @@ #define ERROR_COST_PER_SKIPPED_LINE 30 #define ERROR_COST_PER_SKIPPED_CHAR 1 -/****************************/ -/* Section - ABI Versioning */ -/****************************/ - -/** - * The latest ABI version that is supported by the current version of the - * library. When Languages are generated by the Tree-sitter CLI, they are - * assigned an ABI version number that corresponds to the current CLI version. - * The Tree-sitter library is generally backwards-compatible with languages - * generated using older CLI versions, but is not forwards-compatible. - */ #define TREE_SITTER_LANGUAGE_VERSION 14 - -/** - * The earliest ABI version that is supported by the current version of the - * library. - */ #define TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION 13 -/*******************/ -/* Section - Types */ -/*******************/ - -typedef t_u16 TSStateId; -typedef t_u16 TSSymbol; -typedef t_u16 TSFieldId; -typedef struct TSLanguage TSLanguage; -typedef struct TSParser TSParser; -typedef struct TSTree TSTree; -typedef struct TSQuery TSQuery; -typedef struct TSQueryCursor TSQueryCursor; -typedef struct TSLookaheadIterator TSLookaheadIterator; - -typedef enum TSInputEncoding -{ - TSInputEncodingUTF8, - TSInputEncodingUTF16, -} TSInputEncoding; - -typedef enum TSSymbolType -{ - TSSymbolTypeRegular, - TSSymbolTypeAnonymous, - TSSymbolTypeAuxiliary, -} TSSymbolType; - -typedef struct TSPoint -{ - t_u32 row; - t_u32 column; -} TSPoint; - -typedef struct TSRange -{ - TSPoint start_point; - TSPoint end_point; - t_u32 start_byte; - t_u32 end_byte; -} TSRange; - -typedef struct TSInput -{ - void *payload; - const t_u8 *(*read)(void *payload, t_u32 byte_index, TSPoint position, t_u32 *bytes_read); -} TSInput; - -typedef enum TSLogType -{ - TSLogTypeParse, - TSLogTypeLex, -} TSLogType; - -typedef struct TSLogger -{ - void *payload; - void (*log)(void *payload, TSLogType log_type, const t_u8 *buffer); -} TSLogger; - -typedef struct TSInputEdit -{ - t_u32 start_byte; - t_u32 old_end_byte; - t_u32 new_end_byte; - TSPoint start_point; - TSPoint old_end_point; - TSPoint new_end_point; -} TSInputEdit; - -typedef struct TSNode -{ - t_u32 start_byte; - t_u32 start_row; - t_u32 start_col; - t_u32 alias; - const void *id; - const TSTree *tree; -} TSNode; - -typedef TSNode t_parse_node; -typedef TSSymbol t_symbol; -typedef TSParser t_first_parser; -typedef TSLanguage t_language; -typedef TSTree t_first_tree; - -typedef struct TSTreeCursor -{ - const void *tree; - const void *id; - t_u32 context[3]; -} TSTreeCursor; - -typedef struct TSQueryCapture -{ - TSNode node; - t_u32 index; -} TSQueryCapture; - -typedef enum TSQuantifier -{ - TSQuantifierZero = 0, // must match the array initialization value - TSQuantifierZeroOrOne, - TSQuantifierZeroOrMore, - TSQuantifierOne, - TSQuantifierOneOrMore, -} TSQuantifier; - -typedef struct TSQueryMatch -{ - t_u32 id; - t_u16 pattern_index; - t_u16 capture_count; - const TSQueryCapture *captures; -} TSQueryMatch; - -typedef enum TSQueryPredicateStepType -{ - TSQueryPredicateStepTypeDone, - TSQueryPredicateStepTypeCapture, - TSQueryPredicateStepTypeString, -} TSQueryPredicateStepType; - -typedef struct TSQueryPredicateStep -{ - TSQueryPredicateStepType type; - t_u32 value_id; -} TSQueryPredicateStep; - -typedef enum TSQueryError -{ - TSQueryErrorNone = 0, - TSQueryErrorSyntax, - TSQueryErrorNodeType, - TSQueryErrorField, - TSQueryErrorCapture, - TSQueryErrorStructure, - TSQueryErrorLanguage, -} TSQueryError; - -/********************/ -/* Section - Parser */ -/********************/ - -/** - * Create a new parser. - */ -TSParser *ts_parser_new(void); - -/** - * Delete the parser, freeing all of the memory that it used. - */ -void ts_parser_delete(TSParser *self); - -/** - * Get the parser's current language. - */ +TSParser *ts_parser_new(void); +void ts_parser_delete(TSParser *self); const TSLanguage *ts_parser_language(const TSParser *self); +bool ts_parser_set_language(TSParser *self, const TSLanguage *language); +TSTree *ts_parser_parse(TSParser *self, TSInput input); +TSTree *ts_parser_parse_string(TSParser *self, t_const_str string, t_u32 length); +void ts_parser_reset(TSParser *self); -/** - * Set the language that the parser should use for parsing. - * - * Returns a boolean indicating whether or not the language was successfully - * assigned. True means assignment succeeded. False means there was a version - * mismatch: the language was generated with an incompatible version of the - * Tree-sitter CLI. Check the language's version using [`ts_language_version`] - * and compare it to this library's [`TREE_SITTER_LANGUAGE_VERSION`] and - * [`TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION`] constants. - */ -bool ts_parser_set_language(TSParser *self, const TSLanguage *language); - -/** - * Set the ranges of text that the parser should include when parsing. - * - * By default, the parser will always include entire documents. This function - * allows you to parse only a *portion* of a document but still return a syntax - * tree whose ranges match up with the document as a whole. You can also pass - * multiple disjoint ranges. - * - * The second and third parameters specify the location and length of an array - * of ranges. The parser does *not* take ownership of these ranges; it copies - * the data, so it doesn't matter how these ranges are allocated. - * - * If `count` is zero, then the entire document will be parsed. Otherwise, - * the given ranges must be ordered from earliest to latest in the document, - * and they must not overlap. That is, the following must hold for all: - * - * `i < count - 1`: `ranges[i].end_byte <= ranges[i + 1].start_byte` - * - * If this requirement is not satisfied, the operation will fail, the ranges - * will not be assigned, and this function will return `false`. On success, - * this function returns `true` - */ -bool ts_parser_set_included_ranges(TSParser *self, const TSRange *ranges, t_u32 count); - -/** - * Get the ranges of text that the parser will include when parsing. - * - * The returned pointer is owned by the parser. The caller should not free it - * or write to it. The length of the array will be written to the given - * `count` pointer. - */ -const TSRange *ts_parser_included_ranges(const TSParser *self, t_u32 *count); - -/** - * Use the parser to parse some source code and create a syntax tree. - * - * If you are parsing this document for the first time, pass `NULL` for the - * `old_tree` parameter. Otherwise, if you have already parsed an earlier - * version of this document and the document has since been edited, pass the - * previous syntax tree so that the unchanged parts of it can be reused. - * This will save time and memory. For this to work correctly, you must have - * already edited the old syntax tree using the [`ts_tree_edit`] function in a - * way that exactly matches the source code changes. - * - * The [`TSInput`] parameter lets you specify how to read the text. It has the - * following three fields: - * 1. [`read`]: A function to retrieve a chunk of text at a given byte offset - * and (row, column) position. The function should return a pointer to the - * text and write its length to the [`bytes_read`] pointer. The parser does - * not take ownership of this buffer; it just borrows it until it has - * finished reading it. The function should write a zero value to the - * [`bytes_read`] pointer to indicate the end of the document. - * 2. [`payload`]: An arbitrary pointer that will be passed to each invocation - * of the [`read`] function. - * 3. [`encoding`]: An indication of how the text is encoded. Either - * `TSInputEncodingUTF8` or `TSInputEncodingUTF16`. - * - * This function returns a syntax tree on success, and `NULL` on failure. There - * are three possible reasons for failure: - * 1. The parser does not have a language assigned. Check for this using the - [`ts_parser_language`] function. - * 2. Parsing was cancelled due to a timeout that was set by an earlier call to - * the [`ts_parser_set_timeout_micros`] function. You can resume parsing from - * where the parser left out by calling [`ts_parser_parse`] again with the - * same arguments. Or you can start parsing from scratch by first calling - * [`ts_parser_reset`]. - * 3. Parsing was cancelled using a cancellation flag that was set by an - * earlier call to [`ts_parser_set_cancellation_flag`]. You can resume parsing - * from where the parser left out by calling [`ts_parser_parse`] again with - * the same arguments. - * - * [`read`]: TSInput::read - * [`payload`]: TSInput::payload - * [`encoding`]: TSInput::encoding - * [`bytes_read`]: TSInput::read - */ -TSTree *ts_parser_parse(TSParser *self, TSInput input); - -/** - * Use the parser to parse some source code stored in one contiguous buffer. - * The first two parameters are the same as in the [`ts_parser_parse`] function - * above. The second two parameters indicate the location of the buffer and its - * length in bytes. - */ -TSTree *ts_parser_parse_string(TSParser *self, t_const_str string, t_u32 length); - -/** - * Use the parser to parse some source code stored in one contiguous buffer with - * a given encoding. The first four parameters work the same as in the - * [`ts_parser_parse_string`] method above. The final parameter indicates whether - * the text is encoded as UTF8 or UTF16. - */ -TSTree *ts_parser_parse_string_encoding(TSParser *self, t_const_str string, t_u32 length, TSInputEncoding encoding); - -/** - * Instruct the parser to start the next parse from the beginning. - * - * If the parser previously failed because of a timeout or a cancellation, then - * by default, it will resume where it left off on the next call to - * [`ts_parser_parse`] or other parsing functions. If you don't want to resume, - * and instead intend to use this parser to parse some other document, you must - * call [`ts_parser_reset`] first. - */ -void ts_parser_reset(TSParser *self); - -/******************/ -/* Section - Tree */ -/******************/ - -/** - * Create a shallow copy of the syntax tree. This is very fast. - * - * You need to copy a syntax tree in order to use it on more than one thread at - * a time, as syntax trees are not thread safe. - */ -TSTree *ts_tree_copy(const TSTree *self); - -/** - * Delete the syntax tree, freeing all of the memory that it used. - */ -void ts_tree_delete(TSTree *self); - -/** - * Get the root node of the syntax tree. - */ -TSNode ts_tree_root_node(const TSTree *self); - -/** - * Get the root node of the syntax tree, but with its position - * shifted forward by the given offset. - */ -TSNode ts_tree_root_node_with_offset(const TSTree *self, t_u32 offset_bytes, TSPoint offset_extent); - -/** - * Get the language that was used to parse the syntax tree. - */ +TSTree *ts_tree_copy(const TSTree *self); +void ts_tree_delete(TSTree *self); +TSNode ts_tree_root_node(const TSTree *self); +TSNode ts_tree_root_node_with_offset(const TSTree *self, t_u32 offset_bytes, TSPoint offset_extent); const TSLanguage *ts_tree_language(const TSTree *self); -/** - * Get the array of included ranges that was used to parse the syntax tree. - * - * The returned pointer must be freed by the caller. - */ -TSRange *ts_tree_included_ranges(const TSTree *self, t_u32 *length); - -/** - * Edit the syntax tree to keep it in sync with source code that has been - * edited. - * - * You must describe the edit both in terms of byte offsets and in terms of - * (row, column) coordinates. - */ -void ts_tree_edit(TSTree *self, const TSInputEdit *edit); - -/** - * Compare an old edited syntax tree to a new syntax tree representing the same - * document, returning an array of ranges whose syntactic structure has changed. - * - * For this to work correctly, the old syntax tree must have been edited such - * that its ranges match up to the new tree. Generally, you'll want to call - * this function right after calling one of the [`ts_parser_parse`] functions. - * You need to pass the old tree that was passed to parse, as well as the new - * tree that was returned from that function. - * - * The returned array is allocated using `malloc` and the caller is responsible - * for freeing it using `free`. The length of the array will be written to the - * given `length` pointer. - */ -TSRange *ts_tree_get_changed_ranges(const TSTree *old_tree, const TSTree *new_tree, t_u32 *length); - -/** - * Write a DOT graph describing the syntax tree to the given file. - */ -void ts_tree_print_dot_graph(const TSTree *self, int file_descriptor); - -/******************/ -/* Section - Node */ -/******************/ - -/** - * Get the node's type as a null-terminated string. - */ -t_const_str ts_node_type(TSNode self); - -/** - * Get the node's type as a numerical id. - */ -TSSymbol ts_node_symbol(TSNode self); - -/** - * Get the node's language. - */ +t_const_str ts_node_type(TSNode self); +TSSymbol ts_node_symbol(TSNode self); const TSLanguage *ts_node_language(TSNode self); +t_const_str ts_node_grammar_type(TSNode self); +TSSymbol ts_node_grammar_symbol(TSNode self); +t_u32 ts_node_start_byte(TSNode self); +TSPoint ts_node_start_point(TSNode self); +t_u32 ts_node_end_byte(TSNode self); +TSPoint ts_node_end_point(TSNode self); +char *ts_node_string(TSNode self); +bool ts_node_is_null(TSNode self); +bool ts_node_is_named(TSNode self); +bool ts_node_is_missing(TSNode self); +bool ts_node_is_extra(TSNode self); +bool ts_node_has_changes(TSNode self); +bool ts_node_has_error(TSNode self); +bool ts_node_is_error(TSNode self); +TSStateId ts_node_parse_state(TSNode self); +TSStateId ts_node_next_parse_state(TSNode self); +TSNode ts_node_parent(TSNode self); +TSNode ts_node_child_containing_descendant(TSNode self, TSNode descendant); +TSNode ts_node_child(TSNode self, t_u32 child_index); +t_const_str ts_node_field_name_for_child(TSNode self, t_u32 child_index); +TSFieldId ts_node_field_id_for_child(TSNode self, t_u32 child_index); +t_u32 ts_node_child_count(TSNode self); +TSNode ts_node_named_child(TSNode self, t_u32 child_index); +t_u32 ts_node_named_child_count(TSNode self); +TSNode ts_node_child_by_field_name(TSNode self, t_const_str name, t_u32 name_length); +TSNode ts_node_child_by_field_id(TSNode self, TSFieldId field_id); +TSNode ts_node_next_sibling(TSNode self); +TSNode ts_node_prev_sibling(TSNode self); +TSNode ts_node_next_named_sibling(TSNode self); +TSNode ts_node_prev_named_sibling(TSNode self); +TSNode ts_node_first_child_for_byte(TSNode self, t_u32 byte); +TSNode ts_node_first_named_child_for_byte(TSNode self, t_u32 byte); +t_u32 ts_node_descendant_count(TSNode self); +TSNode ts_node_descendant_for_byte_range(TSNode self, t_u32 start, t_u32 end); +TSNode ts_node_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end); +TSNode ts_node_named_descendant_for_byte_range(TSNode self, t_u32 start, t_u32 end); +TSNode ts_node_named_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end); +bool ts_node_eq(TSNode self, TSNode other); -/** - * Get the node's type as it appears in the grammar ignoring aliases as a - * null-terminated string. - */ -t_const_str ts_node_grammar_type(TSNode self); - -/** - * Get the node's type as a numerical id as it appears in the grammar ignoring - * aliases. This should be used in [`ts_language_next_state`] instead of - * [`ts_node_symbol`]. - */ -TSSymbol ts_node_grammar_symbol(TSNode self); - -/** - * Get the node's start byte. - */ -t_u32 ts_node_start_byte(TSNode self); - -/** - * Get the node's start position in terms of rows and columns. - */ -TSPoint ts_node_start_point(TSNode self); - -/** - * Get the node's end byte. - */ -t_u32 ts_node_end_byte(TSNode self); - -/** - * Get the node's end position in terms of rows and columns. - */ -TSPoint ts_node_end_point(TSNode self); - -/** - * Get an S-expression representing the node as a string. - * - * This string is allocated with `malloc` and the caller is responsible for - * freeing it using `free`. - */ -char *ts_node_string(TSNode self); - -/** - * Check if the node is null. Functions like [`ts_node_child`] and - * [`ts_node_next_sibling`] will return a null node to indicate that no such node - * was found. - */ -bool ts_node_is_null(TSNode self); - -/** - * Check if the node is *named*. Named nodes correspond to named rules in the - * grammar, whereas *anonymous* nodes correspond to string literals in the - * grammar. - */ -bool ts_node_is_named(TSNode self); - -/** - * Check if the node is *missing*. Missing nodes are inserted by the parser in - * order to recover from certain kinds of syntax errors. - */ -bool ts_node_is_missing(TSNode self); - -/** - * Check if the node is *extra*. Extra nodes represent things like comments, - * which are not required the grammar, but can appear anywhere. - */ -bool ts_node_is_extra(TSNode self); - -/** - * Check if a syntax node has been edited. - */ -bool ts_node_has_changes(TSNode self); - -/** - * Check if the node is a syntax error or contains any syntax errors. - */ -bool ts_node_has_error(TSNode self); - -/** - * Check if the node is a syntax error. - */ -bool ts_node_is_error(TSNode self); - -/** - * Get this node's parse state. - */ -TSStateId ts_node_parse_state(TSNode self); - -/** - * Get the parse state after this node. - */ -TSStateId ts_node_next_parse_state(TSNode self); - -/** - * Get the node's immediate parent. - * Prefer [`ts_node_child_containing_descendant`] for - * iterating over the node's ancestors. - */ -TSNode ts_node_parent(TSNode self); - -/** - * Get the node's child that contains `descendant`. - */ -TSNode ts_node_child_containing_descendant(TSNode self, TSNode descendant); - -/** - * Get the node's child at the given index, where zero represents the first - * child. - */ -TSNode ts_node_child(TSNode self, t_u32 child_index); - -/** - * Get the field name for node's child at the given index, where zero represents - * the first child. Returns NULL, if no field is found. - */ -t_const_str ts_node_field_name_for_child(TSNode self, t_u32 child_index); - -/** - * Get the field name for node's child at the given index, where zero represents - * the first child. Returns NULL, if no field is found. - */ -TSFieldId ts_node_field_id_for_child(TSNode self, t_u32 child_index); - -/** - * Get the node's number of children. - */ -t_u32 ts_node_child_count(TSNode self); - -/** - * Get the node's *named* child at the given index. - * - * See also [`ts_node_is_named`]. - */ -TSNode ts_node_named_child(TSNode self, t_u32 child_index); - -/** - * Get the node's number of *named* children. - * - * See also [`ts_node_is_named`]. - */ -t_u32 ts_node_named_child_count(TSNode self); - -/** - * Get the node's child with the given field name. - */ -TSNode ts_node_child_by_field_name(TSNode self, t_const_str name, t_u32 name_length); - -/** - * Get the node's child with the given numerical field id. - * - * You can convert a field name to an id using the - * [`ts_language_field_id_for_name`] function. - */ -TSNode ts_node_child_by_field_id(TSNode self, TSFieldId field_id); - -/** - * Get the node's next / previous sibling. - */ -TSNode ts_node_next_sibling(TSNode self); -TSNode ts_node_prev_sibling(TSNode self); - -/** - * Get the node's next / previous *named* sibling. - */ -TSNode ts_node_next_named_sibling(TSNode self); -TSNode ts_node_prev_named_sibling(TSNode self); - -/** - * Get the node's first child that extends beyond the given byte offset. - */ -TSNode ts_node_first_child_for_byte(TSNode self, t_u32 byte); - -/** - * Get the node's first named child that extends beyond the given byte offset. - */ -TSNode ts_node_first_named_child_for_byte(TSNode self, t_u32 byte); - -/** - * Get the node's number of descendants, including one for the node itself. - */ -t_u32 ts_node_descendant_count(TSNode self); - -/** - * Get the smallest node within this node that spans the given range of bytes - * or (row, column) positions. - */ -TSNode ts_node_descendant_for_byte_range(TSNode self, t_u32 start, t_u32 end); -TSNode ts_node_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end); - -/** - * Get the smallest named node within this node that spans the given range of - * bytes or (row, column) positions. - */ -TSNode ts_node_named_descendant_for_byte_range(TSNode self, t_u32 start, t_u32 end); -TSNode ts_node_named_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end); - -/** - * Edit the node to keep it in-sync with source code that has been edited. - * - * This function is only rarely needed. When you edit a syntax tree with the - * [`ts_tree_edit`] function, all of the nodes that you retrieve from the tree - * afterward will already reflect the edit. You only need to use [`ts_node_edit`] - * when you have a [`TSNode`] instance that you want to keep and continue to use - * after an edit. - */ -void ts_node_edit(TSNode *self, const TSInputEdit *edit); - -/** - * Check if two nodes are identical. - */ -bool ts_node_eq(TSNode self, TSNode other); - -/**********************/ -/* Section - Language */ -/**********************/ - -/** - * Get another reference to the given language. - */ const TSLanguage *ts_language_copy(const TSLanguage *self); - -/** - * Free any dynamically-allocated resources for this language, if - * this is the last reference. - */ -void ts_language_delete(const TSLanguage *self); - -/** - * Get the number of distinct node types in the language. - */ -t_u32 ts_language_symbol_count(const TSLanguage *self); - -/** - * Get the number of valid states in this language. - */ -t_u32 ts_language_state_count(const TSLanguage *self); - -/** - * Get a node type string for the given numerical id. - */ -t_const_str ts_language_symbol_name(const TSLanguage *self, TSSymbol symbol); - -/** - * Get the numerical id for the given node type string. - */ -TSSymbol ts_language_symbol_for_name(const TSLanguage *self, t_const_str string, t_u32 length, bool is_named); - -/** - * Get the number of distinct field names in the language. - */ -t_u32 ts_language_field_count(const TSLanguage *self); - -/** - * Get the field name string for the given numerical id. - */ -t_const_str ts_language_field_name_for_id(const TSLanguage *self, TSFieldId id); - -/** - * Get the numerical id for the given field name string. - */ -TSFieldId ts_language_field_id_for_name(const TSLanguage *self, t_const_str name, t_u32 name_length); - -/** - * Check whether the given node type id belongs to named nodes, anonymous nodes, - * or a hidden nodes. - * - * See also [`ts_node_is_named`]. Hidden nodes are never returned from the API. - */ -TSSymbolType ts_language_symbol_type(const TSLanguage *self, TSSymbol symbol); - -/** - * Get the ABI version number for this language. This version number is used - * to ensure that languages were generated by a compatible version of - * Tree-sitter. - * - * See also [`ts_parser_set_language`]. - */ -t_u32 ts_language_version(const TSLanguage *self); - -/** - * Get the next parse state. Combine this with lookahead iterators to generate - * completion suggestions or valid symbols in error nodes. Use - * [`ts_node_grammar_symbol`] for valid symbols. - */ -TSStateId ts_language_next_state(const TSLanguage *self, TSStateId state, TSSymbol symbol); +void ts_language_delete(const TSLanguage *self); +t_u32 ts_language_symbol_count(const TSLanguage *self); +t_u32 ts_language_state_count(const TSLanguage *self); +t_const_str ts_language_symbol_name(const TSLanguage *self, TSSymbol symbol); +TSSymbol ts_language_symbol_for_name(const TSLanguage *self, t_const_str string, t_u32 length, bool is_named); +t_u32 ts_language_field_count(const TSLanguage *self); +t_const_str ts_language_field_name_for_id(const TSLanguage *self, TSFieldId id); +TSFieldId ts_language_field_id_for_name(const TSLanguage *self, t_const_str name, t_u32 name_length); +TSSymbolType ts_language_symbol_type(const TSLanguage *self, TSSymbol symbol); +t_u32 ts_language_version(const TSLanguage *self); +TSStateId ts_language_next_state(const TSLanguage *self, TSStateId state, TSSymbol symbol); #endif // TREE_SITTER_API_H_ diff --git a/parser/include/parser/array.h b/parser/include/parser/array.h index 507af54a..9db07462 100644 --- a/parser/include/parser/array.h +++ b/parser/include/parser/array.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/31 12:03:22 by maiboyer #+# #+# */ -/* Updated: 2024/08/31 12:03:29 by maiboyer ### ########.fr */ +/* Updated: 2024/09/02 21:15:05 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -33,10 +33,7 @@ #define array_init(self) ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL) /// Create an empty array. -#define array_new() \ - { \ - NULL, 0, 0 \ - } +#define array_new() {NULL, 0, 0} /// Get a pointer to the element at a given `index` in the array. #define array_get(self, _index) (assert((t_u32)(_index) < (self)->size), &(self)->contents[_index]) @@ -127,7 +124,7 @@ #define array_insert_sorted_with(self, compare, value) \ do \ { \ - t_u32 _index, _exists; \ + t_u32 _index, _exists; \ array_search_sorted_with(self, compare, &(value), &_index, &_exists); \ if (!_exists) \ array_insert(self, _index, value); \ @@ -140,7 +137,7 @@ #define array_insert_sorted_by(self, field, value) \ do \ { \ - t_u32 _index, _exists; \ + t_u32 _index, _exists; \ array_search_sorted_by(self, field, (value)field, &_index, &_exists); \ if (!_exists) \ array_insert(self, _index, value); \ @@ -222,28 +219,24 @@ static inline void _array__grow(Array *self, t_u32 count, size_t element_size) /// This is not what you're looking for, see `array_splice`. static inline void _array__splice(Array *self, size_t element_size, t_u32 index, t_u32 old_count, t_u32 new_count, const void *elements) { - t_u32 new_size = self->size + new_count - old_count; - t_u32 old_end = index + old_count; - t_u32 new_end = index + new_count; - assert(old_end <= self->size); + char *contents; + t_u32 new_size; + t_u32 old_end; + t_u32 new_end; + new_size = self->size + new_count - old_count; + old_end = index + old_count; + new_end = index + new_count; _array__reserve(self, element_size, new_size); - - char *contents = (char *)self->contents; + contents = (char *)self->contents; if (self->size > old_end) - { - memmove(contents + new_end * element_size, contents + old_end * element_size, (self->size - old_end) * element_size); - } + mem_move(contents + new_end * element_size, contents + old_end * element_size, (self->size - old_end) * element_size); if (new_count > 0) { if (elements) - { mem_copy((contents + index * element_size), elements, new_count * element_size); - } else - { - memset((contents + index * element_size), 0, new_count * element_size); - } + mem_set_zero((contents + index * element_size), new_count * element_size); } self->size += new_count - old_count; } diff --git a/parser/include/parser/inner/length_inner.h b/parser/include/parser/inner/length_inner.h new file mode 100644 index 00000000..974a43aa --- /dev/null +++ b/parser/include/parser/inner/length_inner.h @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* length_inner.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/09/02 20:03:42 by maiboyer #+# #+# */ +/* Updated: 2024/09/02 20:16:55 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef LENGTH_INNER_H +#define LENGTH_INNER_H + +#include "me/types.h" +#include "parser/inner/point_inner.h" + +typedef struct s_length t_length; +typedef t_length Length; + +struct s_length +{ + t_u32 bytes; + t_point extent; +}; + +#endif /* LENGTH_INNER_H */ diff --git a/parser/include/parser/inner/point_inner.h b/parser/include/parser/inner/point_inner.h new file mode 100644 index 00000000..9780f5c4 --- /dev/null +++ b/parser/include/parser/inner/point_inner.h @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* point_inner.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/09/02 20:05:43 by maiboyer #+# #+# */ +/* Updated: 2024/09/02 20:07:26 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef POINT_INNER_H +#define POINT_INNER_H + +#include "me/types.h" + +typedef struct s_point t_point; +typedef t_point TSPoint; + +struct s_point +{ + t_u32 row; + t_u32 column; +}; + +#endif /* POINT_INNER_H */ diff --git a/parser/include/parser/inner/ptypes.h b/parser/include/parser/inner/ptypes.h new file mode 100644 index 00000000..81102b75 --- /dev/null +++ b/parser/include/parser/inner/ptypes.h @@ -0,0 +1,63 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ptypes.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/09/02 20:08:11 by maiboyer #+# #+# */ +/* Updated: 2024/09/02 20:20:55 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef PTYPES_H +#define PTYPES_H + +#include "me/types.h" +#include "parser/inner/length_inner.h" +#include "parser/inner/point_inner.h" + +typedef t_u16 TSStateId; +typedef t_u16 TSSymbol; +typedef t_u16 TSFieldId; +typedef struct TSLanguage TSLanguage; +typedef struct TSParser TSParser; +typedef struct s_tree TSTree; + +typedef enum TSSymbolType +{ + TSSymbolTypeRegular, + TSSymbolTypeAnonymous, + TSSymbolTypeAuxiliary, +} TSSymbolType; + +typedef struct s_srange +{ + TSPoint start_point; + TSPoint end_point; + t_u32 start_byte; + t_u32 end_byte; +} TSRange; + +typedef struct t_input +{ + void *payload; + const t_u8 *(*read)(void *payload, t_u32 byte_index, TSPoint position, t_u32 *bytes_read); +} TSInput; + +typedef struct t_parse_node +{ + t_u32 start_byte; + t_u32 start_row; + t_u32 start_col; + t_u32 alias; + const void *id; + const TSTree *tree; +} TSNode; + +typedef TSNode t_parse_node; +typedef TSSymbol t_symbol; +typedef TSParser t_first_parser; +typedef TSLanguage t_language; +typedef TSTree t_first_tree; +#endif /* PTYPES_H */ diff --git a/parser/include/parser/inner/stack.h b/parser/include/parser/inner/stack.h index 6014d7f2..7ad2b73a 100644 --- a/parser/include/parser/inner/stack.h +++ b/parser/include/parser/inner/stack.h @@ -54,7 +54,7 @@ struct s_stack_node struct s_stack_iterator { t_stack_node *node; - SubtreeArray subtrees; + t_vec_subtree subtrees; t_u32 subtree_count; bool is_pending; }; @@ -106,6 +106,6 @@ void stack_head_delete(t_stack_head *self); void stack_node_add_link(t_stack_node *self, t_stack_link link); void stack_node_release(t_stack_node *self); void stack_node_retain(t_stack_node *self); -void ts_stack__add_slice(t_stack *self, t_stack_version original_version, t_stack_node *node, SubtreeArray *subtrees); +void ts_stack__add_slice(t_stack *self, t_stack_version original_version, t_stack_node *node, t_vec_subtree *subtrees); #endif /* STACK_H */ diff --git a/parser/include/parser/inner/subtree_inner.h b/parser/include/parser/inner/subtree_inner.h new file mode 100644 index 00000000..775352f3 --- /dev/null +++ b/parser/include/parser/inner/subtree_inner.h @@ -0,0 +1,79 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* subtree_inner.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/09/02 20:01:50 by maiboyer #+# #+# */ +/* Updated: 2024/09/02 20:16:23 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef SUBTREE_INNER_H +#define SUBTREE_INNER_H + +#include "me/types.h" +#include "parser/external_scanner_state.h" +#include "parser/inner/length_inner.h" +#include "parser/inner/ptypes.h" + +// A heap-allocated representation of a subtree. +// +// This representation is used for parent nodes, external tokens, +// errors, and other leaf nodes whose data is too large to fit into +// the inline representation. +typedef struct s_subtree_data t_subtree_data; + +struct s_subtree_data +{ + t_u32 ref_count; + Length padding; + Length size; + t_u32 lookahead_bytes; + t_u32 error_cost; + t_u32 child_count; + TSSymbol symbol; + TSStateId parse_state; + + bool visible : 1; + bool named : 1; + bool extra : 1; + bool fragile_left : 1; + bool fragile_right : 1; + bool has_changes : 1; + bool has_external_tokens : 1; + bool has_external_scanner_state_change : 1; + bool depends_on_column : 1; + bool is_missing : 1; + bool is_keyword : 1; + + union { + // Non-terminal subtrees (`child_count > 0`) + struct + { + t_u32 visible_child_count; + t_u32 named_child_count; + t_u32 visible_descendant_count; + t_i32 dynamic_precedence; + t_u16 repeat_depth; + t_u16 production_id; + struct + { + TSSymbol symbol; + TSStateId parse_state; + } first_leaf; + }; + + // External terminal subtrees (`child_count == 0 && has_external_tokens`) + t_external_scanner_state external_scanner_state; + + // Error terminal subtrees (`child_count == 0 && symbol == ts_builtin_sym_error`) + t_i32 lookahead_char; + }; +}; + +// The fundamental building block of a syntax tree. +typedef t_subtree_data *t_subtree; + +#endif /* SUBTREE_INNER_H */ diff --git a/parser/include/parser/length.h b/parser/include/parser/length.h index 28819a62..80f07174 100644 --- a/parser/include/parser/length.h +++ b/parser/include/parser/length.h @@ -6,23 +6,14 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/31 12:03:16 by maiboyer #+# #+# */ -/* Updated: 2024/08/31 18:30:26 by maiboyer ### ########.fr */ +/* Updated: 2024/09/02 20:05:01 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef LENGTH_H #define LENGTH_H -#include "parser/api.h" -#include "me/types.h" - -struct s_length -{ - t_u32 bytes; - TSPoint extent; -}; - -typedef struct s_length Length; +#include "parser/inner/length_inner.h" static const Length LENGTH_UNDEFINED = {0, {0, 1}}; static const Length LENGTH_MAX = {UINT32_MAX, {UINT32_MAX, UINT32_MAX}}; diff --git a/parser/include/parser/lexer.h b/parser/include/parser/lexer.h index 70a4f6dc..58e2e311 100644 --- a/parser/include/parser/lexer.h +++ b/parser/include/parser/lexer.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/31 12:03:15 by maiboyer #+# #+# */ -/* Updated: 2024/08/31 18:39:28 by maiboyer ### ########.fr */ +/* Updated: 2024/09/02 20:21:08 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -27,7 +27,6 @@ struct s_lexer TSRange *included_ranges; const t_u8 *chunk; TSInput input; - TSLogger logger; t_u32 included_range_count; t_u32 current_included_range_index; t_u32 chunk_start; diff --git a/parser/include/parser/stack.h b/parser/include/parser/stack.h index f8dfaf17..102e38ff 100644 --- a/parser/include/parser/stack.h +++ b/parser/include/parser/stack.h @@ -28,7 +28,7 @@ typedef Array(t_stack_summary_entry) t_stack_summary; struct s_stack_slice { - SubtreeArray subtrees; + t_vec_subtree subtrees; t_stack_version version; }; @@ -48,7 +48,7 @@ void ts_stack_set_last_external_token(t_stack *, t_stack_version, t_subtree); Length ts_stack_position(const t_stack *, t_stack_version); void ts_stack_push(t_stack *, t_stack_version, t_subtree, bool, TSStateId); t_stack_slice_array ts_stack_pop_count(t_stack *, t_stack_version, t_u32 count); -SubtreeArray ts_stack_pop_error(t_stack *, t_stack_version); +t_vec_subtree ts_stack_pop_error(t_stack *, t_stack_version); t_stack_slice_array ts_stack_pop_pending(t_stack *, t_stack_version); t_stack_slice_array ts_stack_pop_all(t_stack *, t_stack_version); t_u32 ts_stack_node_count_since_error(const t_stack *, t_stack_version); diff --git a/parser/include/parser/subtree.h b/parser/include/parser/subtree.h index dcdb0068..3bf10e2f 100644 --- a/parser/include/parser/subtree.h +++ b/parser/include/parser/subtree.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/31 12:03:06 by maiboyer #+# #+# */ -/* Updated: 2024/09/02 18:32:36 by maiboyer ### ########.fr */ +/* Updated: 2024/09/02 20:25:33 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -23,97 +23,38 @@ #include #include -#define TS_BIG_ENDIAN 0 -#define TS_PTR_SIZE 64 #define TS_TREE_STATE_NONE USHRT_MAX #define NULL_SUBTREE ((t_subtree)NULL) -// A heap-allocated representation of a subtree. -// -// This representation is used for parent nodes, external tokens, -// errors, and other leaf nodes whose data is too large to fit into -// the inline representation. -typedef struct s_subtree_data t_subtree_data; +#include "me/vec/vec_subtree.h" +#include "parser/inner/subtree_inner.h" -struct s_subtree_data -{ - t_u32 ref_count; - Length padding; - Length size; - t_u32 lookahead_bytes; - t_u32 error_cost; - t_u32 child_count; - TSSymbol symbol; - TSStateId parse_state; - - bool visible : 1; - bool named : 1; - bool extra : 1; - bool fragile_left : 1; - bool fragile_right : 1; - bool has_changes : 1; - bool has_external_tokens : 1; - bool has_external_scanner_state_change : 1; - bool depends_on_column : 1; - bool is_missing : 1; - bool is_keyword : 1; - - union { - // Non-terminal subtrees (`child_count > 0`) - struct - { - t_u32 visible_child_count; - t_u32 named_child_count; - t_u32 visible_descendant_count; - t_i32 dynamic_precedence; - t_u16 repeat_depth; - t_u16 production_id; - struct - { - TSSymbol symbol; - TSStateId parse_state; - } first_leaf; - }; - - // External terminal subtrees (`child_count == 0 && has_external_tokens`) - t_external_scanner_state external_scanner_state; - - // Error terminal subtrees (`child_count == 0 && symbol == ts_builtin_sym_error`) - t_i32 lookahead_char; - }; -}; - -// The fundamental building block of a syntax tree. -typedef t_subtree_data *t_subtree; - -typedef Array(t_subtree) SubtreeArray; +typedef t_vec_subtree t_vec_subtree; void ts_external_scanner_state_init(t_external_scanner_state *, const t_u8 *, t_u32); const t_u8 *ts_external_scanner_state_data(const t_external_scanner_state *); bool ts_external_scanner_state_eq(const t_external_scanner_state *self, const t_u8 *, t_u32); void ts_external_scanner_state_delete(t_external_scanner_state *self); -void ts_subtree_array_copy(SubtreeArray, SubtreeArray *); -void ts_subtree_array_clear(SubtreeArray *); -void ts_subtree_array_delete(SubtreeArray *); -void ts_subtree_array_remove_trailing_extras(SubtreeArray *, SubtreeArray *); -void ts_subtree_array_reverse(SubtreeArray *); +void ts_subtree_array_copy(t_vec_subtree, t_vec_subtree *); +void ts_subtree_array_clear(t_vec_subtree *); +void ts_subtree_array_delete(t_vec_subtree *); +void ts_subtree_array_remove_trailing_extras(t_vec_subtree *, t_vec_subtree *); +void ts_subtree_array_reverse(t_vec_subtree *); t_subtree ts_subtree_new_leaf(TSSymbol, Length, Length, t_u32, TSStateId, bool, bool, bool, const TSLanguage *); t_subtree ts_subtree_new_error(t_i32, Length, Length, t_u32, TSStateId, const TSLanguage *); -t_subtree ts_subtree_new_node(TSSymbol, SubtreeArray *, t_u32, const TSLanguage *); -t_subtree ts_subtree_new_error_node(SubtreeArray *, bool, const TSLanguage *); +t_subtree ts_subtree_new_node(TSSymbol, t_vec_subtree *, t_u32, const TSLanguage *); +t_subtree ts_subtree_new_error_node(t_vec_subtree *, bool, const TSLanguage *); t_subtree ts_subtree_new_missing_leaf(TSSymbol, Length, t_u32, const TSLanguage *); -t_subtree ts_subtree_make_mut(t_subtree); +t_subtree ts_subtree_ensure_owner(t_subtree); void ts_subtree_release(t_subtree); int ts_subtree_compare(t_subtree, t_subtree); void ts_subtree_set_symbol(t_subtree *, TSSymbol, const TSLanguage *); void ts_subtree_summarize(t_subtree, const t_subtree *, t_u32, const TSLanguage *); void ts_subtree_summarize_children(t_subtree, const TSLanguage *); void ts_subtree_balance(t_subtree, const TSLanguage *); -t_subtree ts_subtree_edit(t_subtree, const TSInputEdit *edit); char *ts_subtree_string(t_subtree, TSSymbol, bool, const TSLanguage *, bool include_all); -void ts_subtree_print_dot_graph(t_subtree, const TSLanguage *, FILE *); t_subtree ts_subtree_last_external_token(t_subtree); const t_external_scanner_state *ts_subtree_external_scanner_state(t_subtree self); bool ts_subtree_external_scanner_state_eq(t_subtree, t_subtree); diff --git a/parser/include/parser/tree.h b/parser/include/parser/tree.h index b4ed946b..882a86fe 100644 --- a/parser/include/parser/tree.h +++ b/parser/include/parser/tree.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/31 12:03:04 by maiboyer #+# #+# */ -/* Updated: 2024/08/31 18:38:49 by maiboyer ### ########.fr */ +/* Updated: 2024/09/02 20:18:46 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,7 +16,7 @@ #include "me/types.h" #include "parser/subtree.h" -struct TSTree +struct s_tree { t_subtree root; const TSLanguage *language; diff --git a/parser/src/parser.c b/parser/src/parser.c index 422d6ae1..70fc1d37 100644 --- a/parser/src/parser.c +++ b/parser/src/parser.c @@ -1,5 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/09/02 20:48:07 by maiboyer #+# #+# */ +/* Updated: 2024/09/02 21:14:40 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + #include "me/mem/mem.h" #include "me/types.h" +#include "me/vec/vec_subtree.h" #include "parser/api.h" #include "parser/array.h" #include "parser/language.h" @@ -30,9 +43,9 @@ struct TSParser const TSLanguage *language; ReduceActionSet reduce_actions; t_subtree finished_tree; - SubtreeArray trailing_extras; - SubtreeArray trailing_extras2; - SubtreeArray scratch_trees; + t_vec_subtree trailing_extras; + t_vec_subtree trailing_extras2; + t_vec_subtree scratch_trees; void *external_scanner_payload; t_u32 accept_count; t_u32 operation_count; @@ -101,7 +114,7 @@ static bool ts_parser__breakdown_top_of_stack(TSParser *self, t_stack_version ve { t_stack_slice slice = pop.contents[i]; TSStateId state = ts_stack_state(self->stack, slice.version); - t_subtree parent = *array_front(&slice.subtrees); + t_subtree parent = *slice.subtrees.buffer; for (t_u32 j = 0, n = ts_subtree_child_count(parent); j < n; j++) { @@ -121,9 +134,9 @@ static bool ts_parser__breakdown_top_of_stack(TSParser *self, t_stack_version ve ts_stack_push(self->stack, slice.version, child, pending, state); } - for (t_u32 j = 1; j < slice.subtrees.size; j++) + for (t_u32 j = 1; j < slice.subtrees.len; j++) { - t_subtree tree = slice.subtrees.contents[j]; + t_subtree tree = slice.subtrees.buffer[j]; ts_stack_push(self->stack, slice.version, tree, false, state); } @@ -505,17 +518,13 @@ static bool ts_parser__select_tree(TSParser *self, t_subtree left, t_subtree rig // Determine if a given tree's children should be replaced by an alternative // array of children. -static bool ts_parser__select_children(TSParser *self, t_subtree left, const SubtreeArray *children) +static bool ts_parser__select_children(TSParser *self, t_subtree left, const t_vec_subtree *children) { - array_assign(&self->scratch_trees, children); + t_subtree scratch_tree; - // Create a temporary subtree using the scratch trees array. This node does - // not perform any allocation except for possibly growing the array to make - // room for its own heap data. The scratch tree is never explicitly released, - // so the same 'scratch trees' array can be reused again later. - t_subtree scratch_tree = ts_subtree_new_node(ts_subtree_symbol(left), &self->scratch_trees, 0, self->language); - - return ts_parser__select_tree(self, left, (scratch_tree)); + vec_subtree_copy_into(&self->scratch_trees, (void *)children); + scratch_tree = ts_subtree_new_node(ts_subtree_symbol(left), &self->scratch_trees, 0, self->language); + return (ts_parser__select_tree(self, left, (scratch_tree))); } static void ts_parser__shift(TSParser *self, t_stack_version version, TSStateId state, t_subtree lookahead, bool extra) @@ -524,7 +533,7 @@ static void ts_parser__shift(TSParser *self, t_stack_version version, TSStateId t_subtree subtree_to_push = lookahead; if (extra != ts_subtree_extra(lookahead) && is_leaf) { - t_subtree result = ts_subtree_make_mut(/*&self->tree_pool,*/ lookahead); + t_subtree result = ts_subtree_ensure_owner(/*&self->tree_pool,*/ lookahead); ts_subtree_set_extra(&result, extra); subtree_to_push = (result); } @@ -576,7 +585,7 @@ static t_stack_version ts_parser__reduce(TSParser *self, t_stack_version version // Extra tokens on top of the stack should not be included in this new parent // node. They will be re-pushed onto the stack after the parent node is // created and pushed. - SubtreeArray children = slice.subtrees; + t_vec_subtree children = slice.subtrees; ts_subtree_array_remove_trailing_extras(&children, &self->trailing_extras); t_subtree parent = ts_subtree_new_node(symbol, &children, production_id, self->language); @@ -592,7 +601,7 @@ static t_stack_version ts_parser__reduce(TSParser *self, t_stack_version version break; i++; - SubtreeArray next_slice_children = next_slice.subtrees; + t_vec_subtree next_slice_children = next_slice.subtrees; ts_subtree_array_remove_trailing_extras(&next_slice_children, &self->trailing_extras2); if (ts_parser__select_children(self, (parent), &next_slice_children)) @@ -604,7 +613,7 @@ static t_stack_version ts_parser__reduce(TSParser *self, t_stack_version version } else { - array_clear(&self->trailing_extras2); + self->trailing_extras2.len = 0; ts_subtree_array_delete(/*&self->tree_pool,*/ &next_slice.subtrees); } } @@ -630,9 +639,9 @@ static t_stack_version ts_parser__reduce(TSParser *self, t_stack_version version // Push the parent node onto the stack, along with any extra tokens that // were previously on top of the stack. ts_stack_push(self->stack, slice_version, (parent), false, next_state); - for (t_u32 j = 0; j < self->trailing_extras.size; j++) + for (t_u32 j = 0; j < self->trailing_extras.len; j++) { - ts_stack_push(self->stack, slice_version, self->trailing_extras.contents[j], false, next_state); + ts_stack_push(self->stack, slice_version, self->trailing_extras.buffer[j], false, next_state); } for (t_stack_version j = 0; j < slice_version; j++) @@ -659,46 +668,37 @@ static void ts_parser__accept(TSParser *self, t_stack_version version, t_subtree t_stack_slice_array pop = ts_stack_pop_all(self->stack, version); for (t_u32 i = 0; i < pop.size; i++) { - SubtreeArray trees = pop.contents[i].subtrees; + t_vec_subtree trees = pop.contents[i].subtrees; + t_subtree root = NULL; - t_subtree root = NULL; - for (t_u32 j = trees.size - 1; j + 1 > 0; j--) + for (t_u32 j = trees.len - 1; j + 1 > 0; j--) { - t_subtree tree = trees.contents[j]; + t_subtree tree = trees.buffer[j]; if (!ts_subtree_extra(tree)) { t_u32 child_count = ts_subtree_child_count(tree); const t_subtree *children = ts_subtree_children(tree); for (t_u32 k = 0; k < child_count; k++) - { - (children[k]->ref_count++); - } - array_splice(&trees, j, 1, child_count, children); + children[k]->ref_count++; + vec_subtree_splice(&trees, vec_subtree_splice_args(j, 1, child_count, children)); root = (ts_subtree_new_node(ts_subtree_symbol(tree), &trees, tree->production_id, self->language)); ts_subtree_release(/*&self->tree_pool, */ tree); break; } } - - assert(root); self->accept_count++; - if (self->finished_tree) { if (ts_parser__select_tree(self, self->finished_tree, root)) { - ts_subtree_release(/*&self->tree_pool,*/ self->finished_tree); + ts_subtree_release(self->finished_tree); self->finished_tree = root; } else - { - ts_subtree_release(/*&self->tree_pool,*/ root); - } + ts_subtree_release(root); } else - { self->finished_tree = root; - } } ts_stack_remove_version(self->stack, pop.contents[0].version); @@ -834,18 +834,17 @@ static bool ts_parser__recover_to_state(TSParser *self, t_stack_version version, continue; } - SubtreeArray error_trees = ts_stack_pop_error(self->stack, slice.version); - if (error_trees.size > 0) + t_vec_subtree error_trees = ts_stack_pop_error(self->stack, slice.version); + if (error_trees.len > 0) { - assert(error_trees.size == 1); - t_subtree error_tree = error_trees.contents[0]; + t_subtree error_tree = error_trees.buffer[0]; t_u32 error_child_count = ts_subtree_child_count(error_tree); if (error_child_count > 0) { - array_splice(&slice.subtrees, 0, 0, error_child_count, ts_subtree_children(error_tree)); + vec_subtree_splice(&slice.subtrees, vec_subtree_splice_args(0, 0, error_child_count, ts_subtree_children(error_tree))); for (t_u32 j = 0; j < error_child_count; j++) { - (slice.subtrees.contents[j]->ref_count++); + (slice.subtrees.buffer[j]->ref_count++); } } ts_subtree_array_delete(/*&self->tree_pool,*/ &error_trees); @@ -853,19 +852,19 @@ static bool ts_parser__recover_to_state(TSParser *self, t_stack_version version, ts_subtree_array_remove_trailing_extras(&slice.subtrees, &self->trailing_extras); - if (slice.subtrees.size > 0) + if (slice.subtrees.len > 0) { t_subtree error = ts_subtree_new_error_node(&slice.subtrees, true, self->language); ts_stack_push(self->stack, slice.version, error, false, goal_state); } else { - array_delete(&slice.subtrees); + vec_subtree_free(slice.subtrees); } - for (t_u32 j = 0; j < self->trailing_extras.size; j++) + for (t_u32 j = 0; j < self->trailing_extras.len; j++) { - t_subtree tree = self->trailing_extras.contents[j]; + t_subtree tree = self->trailing_extras.buffer[j]; ts_stack_push(self->stack, slice.version, tree, false, goal_state); } @@ -976,7 +975,7 @@ static void ts_parser__recover(TSParser *self, t_stack_version version, t_subtre // in an ERROR node and terminate. if (ts_subtree_is_eof(lookahead)) { - SubtreeArray children = array_new(); + t_vec_subtree children = vec_subtree_new(16, NULL); t_subtree parent = ts_subtree_new_error_node(&children, false, self->language); ts_stack_push(self->stack, version, parent, false, 1); ts_parser__accept(self, version, lookahead); @@ -999,15 +998,14 @@ static void ts_parser__recover(TSParser *self, t_stack_version version, t_subtre const TSParseAction *actions = ts_language_actions(self->language, 1, ts_subtree_symbol(lookahead), &n); if (n > 0 && actions[n - 1].type == TSParseActionTypeShift && actions[n - 1].shift.extra) { - t_subtree mutable_lookahead = ts_subtree_make_mut(/*&self->tree_pool,*/ lookahead); + t_subtree mutable_lookahead = ts_subtree_ensure_owner(/*&self->tree_pool,*/ lookahead); ts_subtree_set_extra(&mutable_lookahead, true); lookahead = (mutable_lookahead); } // Wrap the lookahead token in an ERROR. - SubtreeArray children = array_new(); - array_reserve(&children, 1); - array_push(&children, lookahead); + t_vec_subtree children = vec_subtree_new(1, NULL); + vec_subtree_push(&children, lookahead); t_subtree error_repeat = ts_subtree_new_node(ts_builtin_sym_error_repeat, &children, 0, self->language); // If other tokens have already been skipped, so there is already an ERROR at the top of the @@ -1034,7 +1032,7 @@ static void ts_parser__recover(TSParser *self, t_stack_version version, t_subtre } ts_stack_renumber_version(self->stack, pop.contents[0].version, version); - array_push(&pop.contents[0].subtrees, (error_repeat)); + vec_subtree_push(&pop.contents[0].subtrees, (error_repeat)); error_repeat = ts_subtree_new_node(ts_builtin_sym_error_repeat, &pop.contents[0].subtrees, 0, self->language); } @@ -1248,7 +1246,7 @@ static bool ts_parser__advance(TSParser *self, t_stack_version version, bool all ts_language_table_entry(self->language, state, self->language->keyword_capture_token, &table_entry); if (table_entry.action_count > 0) { - t_subtree mutable_lookahead = ts_subtree_make_mut(/*&self->tree_pool,*/ lookahead); + t_subtree mutable_lookahead = ts_subtree_ensure_owner(/*&self->tree_pool,*/ lookahead); ts_subtree_set_symbol(&mutable_lookahead, self->language->keyword_capture_token, self->language); lookahead = (mutable_lookahead); continue; @@ -1526,7 +1524,6 @@ TSTree *ts_parser_parse(TSParser *self, TSInput input) if (self->finished_tree == NULL) me_abort("self->finished_tree == NULL"); - ts_subtree_balance(self->finished_tree, self->language); result = ts_tree_new(self->finished_tree, self->language); self->finished_tree = NULL; ts_parser_reset(self); diff --git a/parser/src/stack/stack_funcs3.c b/parser/src/stack/stack_funcs3.c index c549c418..e3204b40 100644 --- a/parser/src/stack/stack_funcs3.c +++ b/parser/src/stack/stack_funcs3.c @@ -73,7 +73,7 @@ t_stack_version ts_stack__add_version(t_stack *self, } void ts_stack__add_slice(t_stack *self, \ -t_stack_version original_version, t_stack_node *node, SubtreeArray *subtrees) +t_stack_version original_version, t_stack_node *node, t_vec_subtree *subtrees) { t_u32 i; t_stack_version version; diff --git a/parser/src/stack/stack_iter.c b/parser/src/stack/stack_iter.c index 96189b96..043155b7 100644 --- a/parser/src/stack/stack_iter.c +++ b/parser/src/stack/stack_iter.c @@ -6,38 +6,38 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/31 16:46:43 by maiboyer #+# #+# */ -/* Updated: 2024/08/31 16:47:21 by maiboyer ### ########.fr */ +/* Updated: 2024/09/02 21:22:19 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ +#include "me/vec/vec_subtree.h" #include "parser/inner/stack.h" #include "parser/stack.h" -t_stack_slice_array stack__iter(t_stack *self, t_stack_version version, - t_stack_callback callback, void *payload, int goal_subtree_count) +t_stack_slice_array stack__iter(t_stack *self, t_stack_version version, t_stack_callback callback, void *payload, int goal_subtree_count) { - t_stack_head *head; - bool include_subtrees; - t_stack_iterator *iterator; - t_stack_node *node; - t_stack_action action; - bool should_pop; - bool should_stop; - SubtreeArray subtrees; - t_stack_iterator *next_iterator; - t_stack_link link; - t_stack_iterator current_iterator; - t_stack_iterator new_iterator; - t_usize i; - t_usize j; - t_usize size; + t_stack_head *head; + bool include_subtrees; + t_stack_iterator *iterator; + t_stack_node *node; + t_stack_action action; + bool should_pop; + bool should_stop; + t_vec_subtree subtrees; + t_stack_iterator *next_iterator; + t_stack_link link; + t_stack_iterator current_iterator; + t_stack_iterator new_iterator; + t_usize i; + t_usize j; + t_usize size; array_clear(&self->slices); array_clear(&self->iterators); head = array_get(&self->heads, version); new_iterator = (t_stack_iterator){ .node = head->node, - .subtrees = array_new(), + .subtrees = vec_subtree_new(16, NULL), .subtree_count = 0, .is_pending = true, }; @@ -45,8 +45,7 @@ t_stack_slice_array stack__iter(t_stack *self, t_stack_version version, if (goal_subtree_count >= 0) { include_subtrees = true; - array_reserve(&new_iterator.subtrees, - (t_u32)ts_subtree_alloc_size(goal_subtree_count) / sizeof(t_subtree)); + vec_subtree_reserve(&new_iterator.subtrees, ts_subtree_alloc_size(goal_subtree_count) / sizeof(t_subtree)); } array_push(&self->iterators, new_iterator); while (self->iterators.size > 0) @@ -65,7 +64,7 @@ t_stack_slice_array stack__iter(t_stack *self, t_stack_version version, subtrees = iterator->subtrees; if (!should_stop) ts_subtree_array_copy(subtrees, &subtrees); - ts_subtree_array_reverse(&subtrees); + vec_subtree_reverse(&subtrees); ts_stack__add_slice(self, version, node, &subtrees); } if (should_stop) @@ -76,7 +75,7 @@ t_stack_slice_array stack__iter(t_stack *self, t_stack_version version, i--; i++; size--; - continue ; + continue; } j = 1; while (j <= node->link_count) @@ -91,22 +90,21 @@ t_stack_slice_array stack__iter(t_stack *self, t_stack_version version, if (self->iterators.size >= MAX_ITERATOR_COUNT) { j++; - continue ; + continue; } link = node->links[j]; current_iterator = self->iterators.contents[i]; array_push(&self->iterators, current_iterator); next_iterator = array_back(&self->iterators); - ts_subtree_array_copy(next_iterator->subtrees, - &next_iterator->subtrees); + ts_subtree_array_copy(next_iterator->subtrees, &next_iterator->subtrees); } next_iterator->node = link.node; if (link.subtree) { if (include_subtrees) { - array_push(&next_iterator->subtrees, link.subtree); - (link.subtree->ref_count++); + vec_subtree_push(&next_iterator->subtrees, link.subtree); + link.subtree->ref_count++; } if (!ts_subtree_extra(link.subtree)) { diff --git a/parser/src/stack/stack_manipulate3.c b/parser/src/stack/stack_manipulate3.c index 584472f5..6c341bb3 100644 --- a/parser/src/stack/stack_manipulate3.c +++ b/parser/src/stack/stack_manipulate3.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/31 17:00:07 by maiboyer #+# #+# */ -/* Updated: 2024/08/31 17:00:41 by maiboyer ### ########.fr */ +/* Updated: 2024/09/02 20:53:54 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,11 +18,11 @@ t_stack_action pop_error_callback(void *payload, { bool *found_error; - if (iterator->subtrees.size > 0) + if (iterator->subtrees.len > 0) { found_error = payload; if (!*found_error - && ts_subtree_is_error(iterator->subtrees.contents[0])) + && ts_subtree_is_error(iterator->subtrees.buffer[0])) { *found_error = true; return (SActionPop | SActionStop); @@ -34,7 +34,7 @@ t_stack_action pop_error_callback(void *payload, return (SActionNone); } -SubtreeArray ts_stack_pop_error(t_stack *self, t_stack_version version) +t_vec_subtree ts_stack_pop_error(t_stack *self, t_stack_version version) { t_stack_node *node; bool found_error; @@ -62,7 +62,7 @@ SubtreeArray ts_stack_pop_error(t_stack *self, t_stack_version version) } i++; } - return ((SubtreeArray){.size = 0}); + return ((t_vec_subtree){NULL, 0, 0, NULL}); } t_stack_action pop_all_callback(void *payload, diff --git a/parser/src/subtree.c b/parser/src/subtree.c index 97adfe34..96262497 100644 --- a/parser/src/subtree.c +++ b/parser/src/subtree.c @@ -3,97 +3,94 @@ #include "me/mem/mem.h" #include "me/types.h" +#include "me/vec/vec_subtree.h" #include "parser/array.h" #include "parser/external_scanner_state.h" #include "parser/language.h" #include "parser/length.h" #include "parser/subtree.h" -void ts_subtree_array_copy(SubtreeArray self, SubtreeArray *dest) +void ts_subtree_array_copy(t_vec_subtree self, t_vec_subtree *dest) { - dest->size = self.size; + t_usize i; + + dest->len = self.len; dest->capacity = self.capacity; - dest->contents = self.contents; + dest->buffer = self.buffer; if (self.capacity > 0) { - dest->contents = mem_alloc_array(self.capacity, sizeof(t_subtree)); - mem_copy(dest->contents, self.contents, self.size * sizeof(t_subtree)); - for (t_u32 i = 0; i < self.size; i++) - (dest->contents[i]->ref_count++); + dest->buffer = mem_alloc_array(self.capacity, sizeof(t_subtree)); + mem_copy(dest->buffer, self.buffer, self.len * sizeof(t_subtree)); + i = 0; + while (i < self.len) + dest->buffer[i++]->ref_count++; } } -void ts_subtree_array_clear(SubtreeArray *self) +void ts_subtree_array_clear(t_vec_subtree *self) { - for (t_u32 i = 0; i < self->size; i++) - ts_subtree_release(self->contents[i]); - array_clear(self); + t_usize i; + i = 0; + while (i < self->len) + ts_subtree_release(self->buffer[i++]); } -void ts_subtree_array_delete(SubtreeArray *self) +void ts_subtree_array_delete(t_vec_subtree *self) { ts_subtree_array_clear(self); - array_delete(self); + vec_subtree_free(*self); } -void ts_subtree_array_remove_trailing_extras(SubtreeArray *self, SubtreeArray *destination) +void ts_subtree_array_remove_trailing_extras(t_vec_subtree *self, t_vec_subtree *destination) { - array_clear(destination); - while (self->size > 0) + t_subtree last; + + destination->len = 0; + while (self->len > 0) { - t_subtree last = self->contents[self->size - 1]; + last = self->buffer[self->len - 1]; if (ts_subtree_extra(last)) { - self->size--; - array_push(destination, last); + self->len--; + vec_subtree_push(destination, last); } else break; } - ts_subtree_array_reverse(destination); -} - -void ts_subtree_array_reverse(SubtreeArray *self) -{ - for (t_u32 i = 0, limit = self->size / 2; i < limit; i++) - { - size_t reverse_index = self->size - 1 - i; - t_subtree swap = self->contents[i]; - self->contents[i] = self->contents[reverse_index]; - self->contents[reverse_index] = swap; - } + vec_subtree_reverse(destination); } t_subtree ts_subtree_new_leaf(TSSymbol symbol, Length padding, Length size, t_u32 lookahead_bytes, TSStateId parse_state, bool has_external_tokens, bool depends_on_column, bool is_keyword, const TSLanguage *language) { - TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol); - bool extra = symbol == ts_builtin_sym_end; + TSSymbolMetadata metadata; + bool extra; + t_subtree_data *data; - { - t_subtree_data *data = mem_alloc(sizeof(*data)); - *data = (t_subtree_data){.ref_count = 1, - .padding = padding, - .size = size, - .lookahead_bytes = lookahead_bytes, - .error_cost = 0, - .child_count = 0, - .symbol = symbol, - .parse_state = parse_state, - .visible = metadata.visible, - .named = metadata.named, - .extra = extra, - .fragile_left = false, - .fragile_right = false, - .has_changes = false, - .has_external_tokens = has_external_tokens, - .has_external_scanner_state_change = false, - .depends_on_column = depends_on_column, - .is_missing = false, - .is_keyword = is_keyword, - {{.first_leaf = {.symbol = 0, .parse_state = 0}}}}; - return (t_subtree)data; - } + extra = symbol == ts_builtin_sym_end; + metadata = ts_language_symbol_metadata(language, symbol); + data = mem_alloc(sizeof(*data)); + *data = (t_subtree_data){.ref_count = 1, + .padding = padding, + .size = size, + .lookahead_bytes = lookahead_bytes, + .error_cost = 0, + .child_count = 0, + .symbol = symbol, + .parse_state = parse_state, + .visible = metadata.visible, + .named = metadata.named, + .extra = extra, + .fragile_left = false, + .fragile_right = false, + .has_changes = false, + .has_external_tokens = has_external_tokens, + .has_external_scanner_state_change = false, + .depends_on_column = depends_on_column, + .is_missing = false, + .is_keyword = is_keyword, + {{.first_leaf = {.symbol = 0, .parse_state = 0}}}}; + return ((t_subtree)data); } void ts_subtree_set_symbol(t_subtree *self, TSSymbol symbol, const TSLanguage *language) @@ -115,7 +112,7 @@ t_subtree ts_subtree_new_error(t_i32 lookahead_char, Length padding, Length size result->fragile_left = true; result->fragile_right = true; result->lookahead_char = lookahead_char; - return result; + return (result); } // Clone a subtree. @@ -147,7 +144,7 @@ t_subtree ts_subtree_clone(t_subtree self) // This takes ownership of the subtree. If the subtree has only one owner, // this will directly convert it into a mutable version. Otherwise, it will // perform a copy. -t_subtree ts_subtree_make_mut(t_subtree self) +t_subtree ts_subtree_ensure_owner(t_subtree self) { t_subtree result; @@ -156,88 +153,6 @@ t_subtree ts_subtree_make_mut(t_subtree self) return result; } -static void ts_subtree__compress(t_subtree self, t_u32 count, const TSLanguage *language, SubtreeArray *stack) -{ - t_u32 initial_stack_size; - t_subtree tree; - TSSymbol symbol; - t_usize i; - t_subtree child_grandchild[2]; - - initial_stack_size = stack->size; - tree = self; - symbol = tree->symbol; - i = 0; - while (i < count) - { - if (tree->ref_count > 1 || tree->child_count < 2) - break; - child_grandchild[0] = (ts_subtree_children(tree)[0]); - if (child_grandchild[0]->child_count < 2 || child_grandchild[0]->ref_count > 1 || child_grandchild[0]->symbol != symbol) - break; - child_grandchild[1] = (ts_subtree_children(child_grandchild[0])[0]); - if (child_grandchild[1]->child_count < 2 || child_grandchild[1]->ref_count > 1 || child_grandchild[1]->symbol != symbol) - break; - ts_subtree_children(tree)[0] = (child_grandchild[1]); - ts_subtree_children(child_grandchild[0])[0] = ts_subtree_children(child_grandchild[1])[child_grandchild[1]->child_count - 1]; - ts_subtree_children(child_grandchild[1])[child_grandchild[1]->child_count - 1] = (child_grandchild[0]); - array_push(stack, tree); - tree = child_grandchild[1]; - i++; - } - - while (stack->size > initial_stack_size) - { - tree = array_pop(stack); - child_grandchild[0] = (ts_subtree_children(tree)[0]); - child_grandchild[1] = (ts_subtree_children(child_grandchild[0])[child_grandchild[0]->child_count - 1]); - ts_subtree_summarize_children(child_grandchild[1], language); - ts_subtree_summarize_children(child_grandchild[0], language); - ts_subtree_summarize_children(tree, language); - } -} - -void ts_subtree_balance(t_subtree self, const TSLanguage *language) -{ - - SubtreeArray balance_stack; - - balance_stack = (SubtreeArray)array_new(); - array_clear(&balance_stack); - - if (ts_subtree_child_count(self) > 0 && self->ref_count == 1) - array_push(&balance_stack, self); - - while (balance_stack.size > 0) - { - t_subtree tree = array_pop(&balance_stack); - - if (tree->repeat_depth > 0) - { - t_subtree child1 = ts_subtree_children(tree)[0]; - t_subtree child2 = ts_subtree_children(tree)[tree->child_count - 1]; - long repeat_delta = (long)ts_subtree_repeat_depth(child1) - (long)ts_subtree_repeat_depth(child2); - if (repeat_delta > 0) - { - t_u32 n = (t_u32)repeat_delta; - for (t_u32 i = n / 2; i > 0; i /= 2) - { - ts_subtree__compress(tree, i, language, &balance_stack); - n -= i; - } - } - } - - for (t_u32 i = 0; i < tree->child_count; i++) - { - t_subtree child = ts_subtree_children(tree)[i]; - if (ts_subtree_child_count(child) > 0 && child->ref_count == 1) - array_push(&balance_stack, child); - } - } - array_delete(&balance_stack); -} - // Assign all of the node's properties that depend on its children. void ts_subtree_summarize_children(t_subtree self, const TSLanguage *language) { @@ -255,20 +170,16 @@ void ts_subtree_summarize_children(t_subtree self, const TSLanguage *language) const TSSymbol *alias_sequence = ts_language_alias_sequence(language, self->production_id); t_u32 lookahead_end_byte = 0; - const t_subtree *children = ts_subtree_children(self); + t_subtree *children = ts_subtree_children(self); for (t_u32 i = 0; i < self->child_count; i++) { t_subtree child = children[i]; if (self->size.extent.row == 0 && ts_subtree_depends_on_column(child)) - { self->depends_on_column = true; - } if (ts_subtree_has_external_scanner_state_change(child)) - { self->has_external_scanner_state_change = true; - } if (i == 0) { @@ -276,20 +187,14 @@ void ts_subtree_summarize_children(t_subtree self, const TSLanguage *language) self->size = ts_subtree_size(child); } else - { self->size = length_add(self->size, ts_subtree_total_size(child)); - } t_u32 child_lookahead_end_byte = self->padding.bytes + self->size.bytes + ts_subtree_lookahead_bytes(child); if (child_lookahead_end_byte > lookahead_end_byte) - { lookahead_end_byte = child_lookahead_end_byte; - } if (ts_subtree_symbol(child) != ts_builtin_sym_error_repeat) - { self->error_cost += ts_subtree_error_cost(child); - } t_u32 grandchild_count = ts_subtree_child_count(child); if (self->symbol == ts_builtin_sym_error || self->symbol == ts_builtin_sym_error_repeat) @@ -297,13 +202,9 @@ void ts_subtree_summarize_children(t_subtree self, const TSLanguage *language) if (!ts_subtree_extra(child) && !(ts_subtree_is_error(child) && grandchild_count == 0)) { if (ts_subtree_visible(child)) - { self->error_cost += ERROR_COST_PER_SKIPPED_TREE; - } else if (grandchild_count > 0) - { self->error_cost += ERROR_COST_PER_SKIPPED_TREE * child->visible_child_count; - } } } @@ -315,9 +216,7 @@ void ts_subtree_summarize_children(t_subtree self, const TSLanguage *language) self->visible_descendant_count++; self->visible_child_count++; if (ts_language_symbol_metadata(language, alias_sequence[structural_index]).named) - { self->named_child_count++; - } } else if (ts_subtree_visible(child)) { @@ -348,10 +247,8 @@ void ts_subtree_summarize_children(t_subtree self, const TSLanguage *language) self->lookahead_bytes = lookahead_end_byte - self->size.bytes - self->padding.bytes; if (self->symbol == ts_builtin_sym_error || self->symbol == ts_builtin_sym_error_repeat) - { self->error_cost += ERROR_COST_PER_RECOVERY + ERROR_COST_PER_SKIPPED_CHAR * self->size.bytes + ERROR_COST_PER_SKIPPED_LINE * self->size.extent.row; - } if (self->child_count > 0) { @@ -369,13 +266,9 @@ void ts_subtree_summarize_children(t_subtree self, const TSLanguage *language) if (self->child_count >= 2 && !self->visible && !self->named && ts_subtree_symbol(first_child) == self->symbol) { if (ts_subtree_repeat_depth(first_child) > ts_subtree_repeat_depth(last_child)) - { self->repeat_depth = ts_subtree_repeat_depth(first_child) + 1; - } else - { self->repeat_depth = ts_subtree_repeat_depth(last_child) + 1; - } } } } @@ -383,23 +276,25 @@ void ts_subtree_summarize_children(t_subtree self, const TSLanguage *language) // Create a new parent node with the given children. // // This takes ownership of the children array. -t_subtree ts_subtree_new_node(TSSymbol symbol, SubtreeArray *children, t_u32 production_id, const TSLanguage *language) +t_subtree ts_subtree_new_node(TSSymbol symbol, t_vec_subtree *children, t_u32 production_id, const TSLanguage *language) { - TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol); - bool fragile = symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat; + TSSymbolMetadata metadata; + bool fragile; + t_usize new_byte_size; + t_subtree data; - // Allocate the node's data at the end of the array of children. - size_t new_byte_size = ts_subtree_alloc_size(children->size); + metadata = ts_language_symbol_metadata(language, symbol); + fragile = symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat; + new_byte_size = ts_subtree_alloc_size(children->len); if (children->capacity * sizeof(t_subtree) < new_byte_size) { - children->contents = mem_realloc(children->contents, new_byte_size); + children->buffer = mem_realloc(children->buffer, new_byte_size); children->capacity = (t_u32)(new_byte_size / sizeof(t_subtree)); } - t_subtree_data *data = (t_subtree_data *)&children->contents[children->size]; - + data = (t_subtree)&children->buffer[children->len]; *data = (t_subtree_data){.ref_count = 1, .symbol = symbol, - .child_count = children->size, + .child_count = children->len, .visible = metadata.visible, .named = metadata.named, .has_changes = false, @@ -412,20 +307,21 @@ t_subtree ts_subtree_new_node(TSSymbol symbol, SubtreeArray *children, t_u32 pro .production_id = production_id, .first_leaf = {.symbol = 0, .parse_state = 0}, }}}; - t_subtree result = data; - ts_subtree_summarize_children(result, language); - return result; + ts_subtree_summarize_children(data, language); + return (data); } // Create a new error node containing the given children. // // This node is treated as 'extra'. Its children are prevented from having // having any effect on the parse state. -t_subtree ts_subtree_new_error_node(SubtreeArray *children, bool extra, const TSLanguage *language) +t_subtree ts_subtree_new_error_node(t_vec_subtree *children, bool extra, const TSLanguage *language) { - t_subtree result = ts_subtree_new_node(ts_builtin_sym_error, children, 0, language); + t_subtree result; + + result = ts_subtree_new_node(ts_builtin_sym_error, children, 0, language); result->extra = extra; - return ((result)); + return (result); } // Create a new 'missing leaf' node. @@ -434,104 +330,9 @@ t_subtree ts_subtree_new_error_node(SubtreeArray *children, bool extra, const TS // having any effect on the parse state. t_subtree ts_subtree_new_missing_leaf(TSSymbol symbol, Length padding, t_u32 lookahead_bytes, const TSLanguage *language) { - t_subtree result = ts_subtree_new_leaf(symbol, padding, length_zero(), lookahead_bytes, 0, false, false, false, language); - ((t_subtree_data *)result)->is_missing = true; - return result; -} - -void ts_subtree_release(t_subtree self) -{ - SubtreeArray to_free; - - to_free = (SubtreeArray)array_new(); - - array_clear(&to_free); - - assert(self->ref_count > 0); - if (--(*(t_u32 *)(&self->ref_count)) == 0) - array_push(&to_free, (self)); - - while (to_free.size > 0) - { - t_subtree tree = array_pop(&to_free); - if (tree->child_count > 0) - { - t_subtree *children = ts_subtree_children(tree); - for (t_u32 i = 0; i < tree->child_count; i++) - { - t_subtree child = children[i]; - assert(child->ref_count > 0); - if (--(*(t_u32 *)(&child->ref_count)) == 0) - array_push(&to_free, (child)); - } - mem_free(children); - } - else - { - if (tree->has_external_tokens) - ts_external_scanner_state_delete(&tree->external_scanner_state); - mem_free(tree); - } - } - array_delete(&to_free); -} - -int ts_subtree_compare(t_subtree left, t_subtree right) -{ - SubtreeArray compare_stack = array_new(); - - array_push(&compare_stack, (left)); - array_push(&compare_stack, (right)); - - while (compare_stack.size > 0) - { - right = (array_pop(&compare_stack)); - left = (array_pop(&compare_stack)); - - int result = 0; - if (ts_subtree_symbol(left) < ts_subtree_symbol(right)) - result = -1; - else if (ts_subtree_symbol(right) < ts_subtree_symbol(left)) - result = 1; - else if (ts_subtree_child_count(left) < ts_subtree_child_count(right)) - result = -1; - else if (ts_subtree_child_count(right) < ts_subtree_child_count(left)) - result = 1; - if (result != 0) - { - array_clear(&compare_stack); - array_delete(&compare_stack); - return result; - } - - for (t_u32 i = ts_subtree_child_count(left); i > 0; i--) - { - t_subtree left_child = ts_subtree_children(left)[i - 1]; - t_subtree right_child = ts_subtree_children(right)[i - 1]; - array_push(&compare_stack, (left_child)); - array_push(&compare_stack, (right_child)); - } - } - - array_delete(&compare_stack); - return 0; -} - -t_subtree ts_subtree_last_external_token(t_subtree tree) -{ - if (!ts_subtree_has_external_tokens(tree)) - return NULL; - while (tree->child_count > 0) - { - for (t_u32 i = tree->child_count - 1; i + 1 > 0; i--) - { - t_subtree child = ts_subtree_children(tree)[i]; - if (ts_subtree_has_external_tokens(child)) - { - tree = child; - break; - } - } - } - return tree; + t_subtree result; + + result = ts_subtree_new_leaf(symbol, padding, length_zero(), lookahead_bytes, 0, false, false, false, language); + result->is_missing = true; + return (result); } diff --git a/parser/src/subtree/subtree_funcs1.c b/parser/src/subtree/subtree_funcs1.c new file mode 100644 index 00000000..76f82175 --- /dev/null +++ b/parser/src/subtree/subtree_funcs1.c @@ -0,0 +1,117 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* subtree_funcs1.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/09/02 20:36:10 by maiboyer #+# #+# */ +/* Updated: 2024/09/02 20:39:57 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/vec/vec_subtree.h" +#include "parser/subtree.h" + +void ts_subtree_release(t_subtree self) +{ + t_vec_subtree to_free; + t_subtree tree; + t_subtree *children; + t_usize i; + + to_free = vec_subtree_new(16, NULL); + if (--self->ref_count == 0) + vec_subtree_push(&to_free, self); + while (to_free.len > 0) + { + vec_subtree_pop(&to_free, &tree); + if (tree->child_count > 0) + { + i = 0; + children = ts_subtree_children(tree); + while (i < tree->child_count) + { + if (--(children[i])->ref_count == 0) + vec_subtree_push(&to_free, children[i]); + i++; + } + mem_free(children); + } + else + { + if (tree->has_external_tokens) + ts_external_scanner_state_delete(&tree->external_scanner_state); + mem_free(tree); + } + } + vec_subtree_free(to_free); +} + +int subtree_compare_func(t_subtree left, t_subtree right) +{ + int result; + + result = 0; + if (ts_subtree_symbol(left) < ts_subtree_symbol(right)) + result = -1; + else if (ts_subtree_symbol(right) < ts_subtree_symbol(left)) + result = 1; + else if (ts_subtree_child_count(left) < ts_subtree_child_count(right)) + result = -1; + else if (ts_subtree_child_count(right) < ts_subtree_child_count(left)) + result = 1; + return (result); +} + +int ts_subtree_compare(t_subtree left, t_subtree right) +{ + t_vec_subtree cmp_stack; + t_i8 result = 0; + t_usize i; + + cmp_stack = vec_subtree_new(16, NULL); + vec_subtree_push(&cmp_stack, (left)); + vec_subtree_push(&cmp_stack, (right)); + while (cmp_stack.len >= 2) + { + vec_subtree_pop(&cmp_stack, &left); + vec_subtree_pop(&cmp_stack, &right); + + result = subtree_compare_func(left, right); + if (result != 0) + return (vec_subtree_free(cmp_stack), result); + i = ts_subtree_child_count(left); + while (i > 0) + { + vec_subtree_push(&cmp_stack, ts_subtree_children(left)[i - 1]); + vec_subtree_push(&cmp_stack, ts_subtree_children(right)[i - 1]); + i--; + } + } + return (vec_subtree_free(cmp_stack), 0); +} + +t_subtree ts_subtree_last_external_token(t_subtree tree) +{ + t_usize i; + t_subtree child; + + if (!ts_subtree_has_external_tokens(tree)) + return (NULL); + while (tree->child_count > 0) + { + i = tree->child_count - 1; + while (i + 1 > 0) + { + child = ts_subtree_children(tree)[i]; + if (ts_subtree_has_external_tokens(child)) + { + tree = child; + break; + } + i--; + } + } + return (tree); +} diff --git a/stdme/generic_sources/header/vec_C__PREFIX__.h__TEMPLATE__ b/stdme/generic_sources/header/vec_C__PREFIX__.h__TEMPLATE__ index 797272bb..549b12f7 100644 --- a/stdme/generic_sources/header/vec_C__PREFIX__.h__TEMPLATE__ +++ b/stdme/generic_sources/header/vec_C__PREFIX__.h__TEMPLATE__ @@ -22,18 +22,31 @@ typedef bool (*t_vec_C__PREFIX___sort_fn)(C__TYPENAME__ *, C__TYPENAME__ *); typedef void (*t_free_C__PREFIX___item)(C__TYPENAME__); /// @brief A dynamic array of C__TYPENAME__ -typedef struct s_vec_C__PREFIX__ +typedef struct s_vec_C__PREFIX__ t_vec_C__PREFIX__; + +struct s_vec_C__PREFIX__ { t_free_C__PREFIX___item free_func; t_usize len; t_usize capacity; C__TYPENAME__ *buffer; -} t_vec_C__PREFIX__; +}; + +struct s_vec_C__PREFIX___splice_arguments +{ + t_usize index; + t_usize old_count; + t_usize new_count; + const C__TYPENAME__ *elements; +}; /// @brief Create a new vec_C__PREFIX__ with a given capacity -/// @param capacity The capacity of the new vec_C__PREFIX__ (in terms of elements) -/// @param free_function The function that will be used to free the elements of the vec_C__PREFIX__ -t_vec_C__PREFIX__ vec_C__PREFIX___new(t_usize capacity, t_free_C__PREFIX___item free_function); +/// @param capacity The capacity of the new vec_C__PREFIX__ (in terms of +/// elements) +/// @param free_function The function that will be used to free the elements of +/// the vec_C__PREFIX__ +t_vec_C__PREFIX__ vec_C__PREFIX___new(t_usize capacity, + t_free_C__PREFIX___item free_function); /// @brief Push an element to the last position of the vec_C__PREFIX__ /// @param vec The vec_C__PREFIX__ to push the element to /// @param element The element to push @@ -43,16 +56,18 @@ t_error vec_C__PREFIX___push(t_vec_C__PREFIX__ *vec, C__TYPENAME__ element); /// @param vec The vec_C__PREFIX__ to push the element to /// @param element The element to push /// @note This operation is O(n) -t_error vec_C__PREFIX___push_front(t_vec_C__PREFIX__ *vec, C__TYPENAME__ element); +t_error vec_C__PREFIX___push_front(t_vec_C__PREFIX__ *vec, + C__TYPENAME__ element); -/// @brief Get the last element from the vec_C__PREFIX__, and remove it from the vec_C__PREFIX__ +/// @brief Get the last element from the vec_C__PREFIX__, and remove it from the +/// vec_C__PREFIX__ /// @param vec The vec_C__PREFIX__ to get the element from /// @param[out] out The last element of the vec_C__PREFIX__ /// @return true if the operation failed, false otherwise t_error vec_C__PREFIX___pop(t_vec_C__PREFIX__ *vec, C__TYPENAME__ *value); - -/// @brief Get the first element from the vec_C__PREFIX__, and remove it from the vec_C__PREFIX__ +/// @brief Get the first element from the vec_C__PREFIX__, and remove it from +/// the vec_C__PREFIX__ /// @param vec The vec_C__PREFIX__ to get the element from /// @param[out] out The first element of the vec_C__PREFIX__ /// @return true if the operation failed, false otherwise @@ -61,58 +76,71 @@ t_error vec_C__PREFIX___pop_front(t_vec_C__PREFIX__ *vec, C__TYPENAME__ *value); /// @brief Free the vector and all its elements /// @param vec The vec_C__PREFIX__ to free -void vec_C__PREFIX___free(t_vec_C__PREFIX__ vec); +void vec_C__PREFIX___free(t_vec_C__PREFIX__ vec); /// @brief Make the vec_C__PREFIX__ at least the given capacity /// @param vec The vec_C__PREFIX__ to reserve /// @param wanted_capacity The minimum capacity to reserve /// @return true if the operation failed, false otherwise -t_error vec_C__PREFIX___reserve(t_vec_C__PREFIX__ *vec, t_usize wanted_capacity); +t_error vec_C__PREFIX___reserve(t_vec_C__PREFIX__ *vec, + t_usize wanted_capacity); -/// @brief Run the function and returns the index of the first element that returns true +/// @brief Run the function and returns the index of the first element that +/// returns true /// @param vec The vec_C__PREFIX__ to search in /// @param fn The function to run on each element /// @param[out] index The index of the first element that returns true -t_error vec_C__PREFIX___find(t_vec_C__PREFIX__ *vec, bool (*fn)(const C__TYPENAME__ *), t_usize *index); +t_error vec_C__PREFIX___find(t_vec_C__PREFIX__ *vec, + bool (*fn)(const C__TYPENAME__ *), t_usize *index); - -/// @brief Run the function and returns the index of the first element that returns true, but starting at index starting_index +/// @brief Run the function and returns the index of the first element that +/// returns true, but starting at index starting_index /// @param vec The vec_C__PREFIX__ to search in /// @param fn The function to run on each element /// @param starting_index The index to start the search from /// @param[out] index The index of the first element that returns true -t_error vec_C__PREFIX___find_starting(t_vec_C__PREFIX__ *vec, bool (*fn)(const C__TYPENAME__ *), t_usize starting_index, t_usize *index); +t_error vec_C__PREFIX___find_starting(t_vec_C__PREFIX__ *vec, + bool (*fn)(const C__TYPENAME__ *), + t_usize starting_index, t_usize *index); -/// @brief Run the function on every element of the vec_C__PREFIX__ and returns if all elements returned true +/// @brief Run the function on every element of the vec_C__PREFIX__ and returns +/// if all elements returned true /// @param vec The vec_C__PREFIX__ to search in /// @param fn The function to run on each element /// @param[out] result The result of the operation /// @return true if the operation failed, false otherwise /// @note If the vec_C__PREFIX__ is empty, result will be true -t_error vec_C__PREFIX___all(t_vec_C__PREFIX__ *vec, bool (*fn)(const C__TYPENAME__ *), bool *result); +t_error vec_C__PREFIX___all(t_vec_C__PREFIX__ *vec, + bool (*fn)(const C__TYPENAME__ *), bool *result); -/// @brief Run the function on every element of the vec_C__PREFIX__ and returns if any element returned true +/// @brief Run the function on every element of the vec_C__PREFIX__ and returns +/// if any element returned true /// @param vec The vec_C__PREFIX__ to search in /// @param fn The function to run on each element /// @param[out] result The result of the operation /// @return true if the operation failed, false otherwise /// @note If the vec_C__PREFIX__ is empty, result will be false -t_error vec_C__PREFIX___any(t_vec_C__PREFIX__ *vec, bool (*fn)(const C__TYPENAME__ *), bool *result); +t_error vec_C__PREFIX___any(t_vec_C__PREFIX__ *vec, + bool (*fn)(const C__TYPENAME__ *), bool *result); /// @brief Run the function on every element of the vec_C__PREFIX__ /// @param vec The vec_C__PREFIX__ to iterate over /// @param fn The function to run on each element /// @param state The state to pass to the function -void vec_C__PREFIX___iter(t_vec_C__PREFIX__ *vec, void (*fn)(t_usize index, C__TYPENAME__ *value, void *state), void *state); +void vec_C__PREFIX___iter(t_vec_C__PREFIX__ *vec, + void (*fn)(t_usize index, C__TYPENAME__ *value, + void *state), + void *state); /// @brief Reverse the order of the elements in the vec_C__PREFIX__ /// @param vec The vec_C__PREFIX__ to reverse -void vec_C__PREFIX___reverse(t_vec_C__PREFIX__ *vec); +void vec_C__PREFIX___reverse(t_vec_C__PREFIX__ *vec); /// @brief Sort the elements of the vec_C__PREFIX__ /// @param vec The vec_C__PREFIX__ to sort /// @param is_sorted The function to use to compare the elements -void vec_C__PREFIX___sort(t_vec_C__PREFIX__ *vec, t_vec_C__PREFIX___sort_fn is_sorted); +void vec_C__PREFIX___sort(t_vec_C__PREFIX__ *vec, + t_vec_C__PREFIX___sort_fn is_sorted); /// @brief Get a pointer to the last element of the vec_C__PREFIX__ /// @param vec The vec_C__PREFIX__ to get the element from @@ -130,4 +158,17 @@ C__TYPENAME__ *vec_C__PREFIX___get(t_vec_C__PREFIX__ *vec, t_usize i); /// @return A pointer to the last element or NULL C__TYPENAME__ *vec_C__PREFIX___last(t_vec_C__PREFIX__ *vec); +/// @brief Perform a simple bytewise copy into the other vector +/// @param vec The vec_C__PREFIX__ to be copied from +/// @param dest The vec_C__PREFIX__ to be copied to +void vec_C__PREFIX___copy_into(t_vec_C__PREFIX__ *vec, t_vec_C__PREFIX__ *dest); + +/// read code lol +void vec_C__PREFIX___splice(t_vec_C__PREFIX__ *self, + struct s_vec_C__PREFIX___splice_arguments args); + +struct s_vec_C__PREFIX___splice_arguments vec_C__PREFIX___splice_args( + t_usize index, t_usize old_count, t_usize new_count, + const C__TYPENAME__ *elements); + #endif diff --git a/stdme/generic_sources/src/vec/C__PREFIX___functions4.c__TEMPLATE__ b/stdme/generic_sources/src/vec/C__PREFIX___functions4.c__TEMPLATE__ index ee9ac8f8..3d2abd7b 100644 --- a/stdme/generic_sources/src/vec/C__PREFIX___functions4.c__TEMPLATE__ +++ b/stdme/generic_sources/src/vec/C__PREFIX___functions4.c__TEMPLATE__ @@ -17,14 +17,59 @@ C__TYPENAME__ *vec_C__PREFIX___get(t_vec_C__PREFIX__ *vec, t_usize i) { - if (vec->len >= i) + if (vec == NULL || vec->len >= i) return (NULL); return (&vec->buffer[i]); } C__TYPENAME__ *vec_C__PREFIX___last(t_vec_C__PREFIX__ *vec) { - if (vec->len == 0) + if (vec == NULL || vec->len == 0) return (NULL); return (&vec->buffer[vec->len - 1]); } + +void vec_C__PREFIX___copy_into(t_vec_C__PREFIX__ *vec, t_vec_C__PREFIX__ *dest) +{ + if (vec == NULL || dest == NULL) + return ; + vec_C__PREFIX___reserve(dest, vec->capacity); + mem_copy(dest->buffer, vec->buffer, vec->len * sizeof(C__TYPENAME__)); +} + +struct s_vec_C__PREFIX___splice_arguments vec_C__PREFIX___splice_args( + t_usize index, t_usize old_count, t_usize new_count, + const C__TYPENAME__ *elements) +{ + return ((struct s_vec_C__PREFIX___splice_arguments){index, old_count, + new_count, elements}); +} + +void vec_C__PREFIX___splice(t_vec_C__PREFIX__ *self, + struct s_vec_C__PREFIX___splice_arguments args) +{ + C__TYPENAME__ *contents; + t_u32 new_size; + t_u32 old_end; + t_u32 new_end; + + new_size = self->len + args.new_count - args.old_count; + old_end = args.index + args.old_count; + new_end = args.index + args.new_count; + vec_C__PREFIX___reserve(self, new_size); + contents = self->buffer; + if (self->len > old_end) + mem_move(contents + new_end, + contents + old_end, + (self->len - old_end) * sizeof(C__TYPENAME__)); + if (args.new_count > 0) + { + if (args.elements) + mem_copy((contents + args.index * sizeof(C__TYPENAME__)), + args.elements, args.new_count * sizeof(C__TYPENAME__)); + else + mem_set_zero((contents + args.index * sizeof(C__TYPENAME__)), + args.new_count * sizeof(C__TYPENAME__)); + } + self->len += args.new_count - args.old_count; +}