Continue to norm stuff and remove useless stuff

This commit is contained in:
Maieul BOYER 2024-09-02 18:33:13 +02:00
parent 62ac9f3813
commit 1a40f20f0d
No known key found for this signature in database
9 changed files with 164 additions and 195 deletions

View file

@ -6,7 +6,7 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */ /* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/24 13:56:34 by maiboyer #+# #+# */ /* Created: 2024/08/24 13:56:34 by maiboyer #+# #+# */
/* Updated: 2024/08/31 18:34:46 by maiboyer ### ########.fr */ /* Updated: 2024/09/02 18:14:43 by maiboyer ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -22,7 +22,7 @@ struct s_external_scanner_state
}; };
typedef struct s_external_scanner_state t_external_scanner_state; typedef struct s_external_scanner_state t_external_scanner_state;
typedef struct s_subtree_data t_subtree_data; typedef struct s_subtree_data t_subtree_data;
typedef const t_subtree_data *t_subtree; typedef t_subtree_data *t_subtree;
void ts_external_scanner_state_init(t_external_scanner_state *self, const t_u8 *data, t_u32 length); void ts_external_scanner_state_init(t_external_scanner_state *self, const t_u8 *data, t_u32 length);
t_external_scanner_state ts_external_scanner_state_copy(const t_external_scanner_state *self); t_external_scanner_state ts_external_scanner_state_copy(const t_external_scanner_state *self);

View file

@ -6,7 +6,7 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */ /* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/31 12:03:06 by maiboyer #+# #+# */ /* Created: 2024/08/31 12:03:06 by maiboyer #+# #+# */
/* Updated: 2024/08/31 18:37:26 by maiboyer ### ########.fr */ /* Updated: 2024/09/02 18:32:36 by maiboyer ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -84,13 +84,9 @@ struct s_subtree_data
}; };
// The fundamental building block of a syntax tree. // The fundamental building block of a syntax tree.
typedef const t_subtree_data *t_subtree; typedef t_subtree_data *t_subtree;
// Like t_subtree, but mutable.
typedef t_subtree_data *t_mut_subtree;
typedef Array(t_subtree) SubtreeArray; typedef Array(t_subtree) SubtreeArray;
typedef Array(t_mut_subtree) MutableSubtreeArray;
void ts_external_scanner_state_init(t_external_scanner_state *, const t_u8 *, t_u32); 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 *); const t_u8 *ts_external_scanner_state_data(const t_external_scanner_state *);
@ -105,16 +101,15 @@ void ts_subtree_array_reverse(SubtreeArray *);
t_subtree ts_subtree_new_leaf(TSSymbol, Length, Length, t_u32, TSStateId, bool, bool, bool, const TSLanguage *); 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_error(t_i32, Length, Length, t_u32, TSStateId, const TSLanguage *);
t_mut_subtree ts_subtree_new_node(TSSymbol, SubtreeArray *, t_u32, 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_error_node(SubtreeArray *, bool, const TSLanguage *);
t_subtree ts_subtree_new_missing_leaf(TSSymbol, Length, t_u32, const TSLanguage *); t_subtree ts_subtree_new_missing_leaf(TSSymbol, Length, t_u32, const TSLanguage *);
t_mut_subtree ts_subtree_make_mut(t_subtree); t_subtree ts_subtree_make_mut(t_subtree);
void ts_subtree_retain(t_subtree);
void ts_subtree_release(t_subtree); void ts_subtree_release(t_subtree);
int ts_subtree_compare(t_subtree, t_subtree); int ts_subtree_compare(t_subtree, t_subtree);
void ts_subtree_set_symbol(t_mut_subtree *, TSSymbol, const TSLanguage *); void ts_subtree_set_symbol(t_subtree *, TSSymbol, const TSLanguage *);
void ts_subtree_summarize(t_mut_subtree, const t_subtree *, t_u32, const TSLanguage *); void ts_subtree_summarize(t_subtree, const t_subtree *, t_u32, const TSLanguage *);
void ts_subtree_summarize_children(t_mut_subtree, const TSLanguage *); void ts_subtree_summarize_children(t_subtree, const TSLanguage *);
void ts_subtree_balance(t_subtree, const TSLanguage *); void ts_subtree_balance(t_subtree, const TSLanguage *);
t_subtree ts_subtree_edit(t_subtree, const TSInputEdit *edit); t_subtree ts_subtree_edit(t_subtree, const TSInputEdit *edit);
char *ts_subtree_string(t_subtree, TSSymbol, bool, const TSLanguage *, bool include_all); char *ts_subtree_string(t_subtree, TSSymbol, bool, const TSLanguage *, bool include_all);
@ -169,9 +164,12 @@ static inline size_t ts_subtree_alloc_size(t_u32 child_count)
// Get a subtree's children, which are allocated immediately before the // Get a subtree's children, which are allocated immediately before the
// tree's own heap data. // tree's own heap data.
#define ts_subtree_children(self) ((t_subtree *)((self)) - (self)->child_count) static inline t_subtree *ts_subtree_children(t_subtree self)
{
return ((t_subtree *)((self)) - (self)->child_count);
}
static inline void ts_subtree_set_extra(t_mut_subtree *self, bool is_extra) static inline void ts_subtree_set_extra(t_subtree *self, bool is_extra)
{ {
(*self)->extra = is_extra; (*self)->extra = is_extra;
} }
@ -272,15 +270,4 @@ static inline bool ts_subtree_is_eof(t_subtree self)
{ {
return (ts_subtree_symbol(self) == ts_builtin_sym_end); return (ts_subtree_symbol(self) == ts_builtin_sym_end);
} }
static inline t_subtree ts_subtree_from_mut(t_mut_subtree self)
{
return (self);
}
static inline t_mut_subtree ts_subtree_to_mut_unsafe(t_subtree self)
{
return ((t_mut_subtree)self);
}
#endif // SUBTREE_H #endif // SUBTREE_H

View file

@ -117,7 +117,7 @@ static bool ts_parser__breakdown_top_of_stack(TSParser *self, t_stack_version ve
state = ts_language_next_state(self->language, state, ts_subtree_symbol(child)); state = ts_language_next_state(self->language, state, ts_subtree_symbol(child));
} }
ts_subtree_retain(child); (child->ref_count++);
ts_stack_push(self->stack, slice.version, child, pending, state); ts_stack_push(self->stack, slice.version, child, pending, state);
} }
@ -447,7 +447,7 @@ static t_subtree ts_parser__lex(TSParser *self, t_stack_version version, TSState
if (found_external_token) if (found_external_token)
{ {
t_mut_subtree mut_result = ts_subtree_to_mut_unsafe(result); t_subtree mut_result = (result);
ts_external_scanner_state_init(&mut_result->external_scanner_state, self->lexer.debug_buffer, external_scanner_state_len); ts_external_scanner_state_init(&mut_result->external_scanner_state, self->lexer.debug_buffer, external_scanner_state_len);
mut_result->has_external_scanner_state_change = external_scanner_state_changed; mut_result->has_external_scanner_state_change = external_scanner_state_changed;
} }
@ -513,9 +513,9 @@ static bool ts_parser__select_children(TSParser *self, t_subtree left, const Sub
// not perform any allocation except for possibly growing the array to make // 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, // room for its own heap data. The scratch tree is never explicitly released,
// so the same 'scratch trees' array can be reused again later. // so the same 'scratch trees' array can be reused again later.
t_mut_subtree scratch_tree = ts_subtree_new_node(ts_subtree_symbol(left), &self->scratch_trees, 0, self->language); 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, ts_subtree_from_mut(scratch_tree)); 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) static void ts_parser__shift(TSParser *self, t_stack_version version, TSStateId state, t_subtree lookahead, bool extra)
@ -524,9 +524,9 @@ static void ts_parser__shift(TSParser *self, t_stack_version version, TSStateId
t_subtree subtree_to_push = lookahead; t_subtree subtree_to_push = lookahead;
if (extra != ts_subtree_extra(lookahead) && is_leaf) if (extra != ts_subtree_extra(lookahead) && is_leaf)
{ {
t_mut_subtree result = ts_subtree_make_mut(/*&self->tree_pool,*/ lookahead); t_subtree result = ts_subtree_make_mut(/*&self->tree_pool,*/ lookahead);
ts_subtree_set_extra(&result, extra); ts_subtree_set_extra(&result, extra);
subtree_to_push = ts_subtree_from_mut(result); subtree_to_push = (result);
} }
ts_stack_push(self->stack, version, subtree_to_push, !is_leaf, state); ts_stack_push(self->stack, version, subtree_to_push, !is_leaf, state);
@ -579,7 +579,7 @@ static t_stack_version ts_parser__reduce(TSParser *self, t_stack_version version
SubtreeArray children = slice.subtrees; SubtreeArray children = slice.subtrees;
ts_subtree_array_remove_trailing_extras(&children, &self->trailing_extras); ts_subtree_array_remove_trailing_extras(&children, &self->trailing_extras);
t_mut_subtree parent = ts_subtree_new_node(symbol, &children, production_id, self->language); t_subtree parent = ts_subtree_new_node(symbol, &children, production_id, self->language);
// This pop operation may have caused multiple stack versions to collapse // This pop operation may have caused multiple stack versions to collapse
// into one, because they all diverged from a common state. In that case, // into one, because they all diverged from a common state. In that case,
@ -595,10 +595,10 @@ static t_stack_version ts_parser__reduce(TSParser *self, t_stack_version version
SubtreeArray next_slice_children = next_slice.subtrees; SubtreeArray next_slice_children = next_slice.subtrees;
ts_subtree_array_remove_trailing_extras(&next_slice_children, &self->trailing_extras2); ts_subtree_array_remove_trailing_extras(&next_slice_children, &self->trailing_extras2);
if (ts_parser__select_children(self, ts_subtree_from_mut(parent), &next_slice_children)) if (ts_parser__select_children(self, (parent), &next_slice_children))
{ {
ts_subtree_array_clear(/*&self->tree_pool,*/ &self->trailing_extras); ts_subtree_array_clear(/*&self->tree_pool,*/ &self->trailing_extras);
ts_subtree_release(/*&self->tree_pool,*/ ts_subtree_from_mut(parent)); ts_subtree_release(/*&self->tree_pool,*/ (parent));
array_swap(&self->trailing_extras, &self->trailing_extras2); array_swap(&self->trailing_extras, &self->trailing_extras2);
parent = ts_subtree_new_node(symbol, &next_slice_children, production_id, self->language); parent = ts_subtree_new_node(symbol, &next_slice_children, production_id, self->language);
} }
@ -629,7 +629,7 @@ 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 // Push the parent node onto the stack, along with any extra tokens that
// were previously on top of the stack. // were previously on top of the stack.
ts_stack_push(self->stack, slice_version, ts_subtree_from_mut(parent), false, next_state); 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.size; 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.contents[j], false, next_state);
@ -671,10 +671,10 @@ static void ts_parser__accept(TSParser *self, t_stack_version version, t_subtree
const t_subtree *children = ts_subtree_children(tree); const t_subtree *children = ts_subtree_children(tree);
for (t_u32 k = 0; k < child_count; k++) for (t_u32 k = 0; k < child_count; k++)
{ {
ts_subtree_retain(children[k]); (children[k]->ref_count++);
} }
array_splice(&trees, j, 1, child_count, children); array_splice(&trees, j, 1, child_count, children);
root = ts_subtree_from_mut(ts_subtree_new_node(ts_subtree_symbol(tree), &trees, tree->production_id, self->language)); root = (ts_subtree_new_node(ts_subtree_symbol(tree), &trees, tree->production_id, self->language));
ts_subtree_release(/*&self->tree_pool, */ tree); ts_subtree_release(/*&self->tree_pool, */ tree);
break; break;
} }
@ -845,7 +845,7 @@ static bool ts_parser__recover_to_state(TSParser *self, t_stack_version version,
array_splice(&slice.subtrees, 0, 0, error_child_count, ts_subtree_children(error_tree)); array_splice(&slice.subtrees, 0, 0, error_child_count, ts_subtree_children(error_tree));
for (t_u32 j = 0; j < error_child_count; j++) for (t_u32 j = 0; j < error_child_count; j++)
{ {
ts_subtree_retain(slice.subtrees.contents[j]); (slice.subtrees.contents[j]->ref_count++);
} }
} }
ts_subtree_array_delete(/*&self->tree_pool,*/ &error_trees); ts_subtree_array_delete(/*&self->tree_pool,*/ &error_trees);
@ -999,16 +999,16 @@ 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); 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) if (n > 0 && actions[n - 1].type == TSParseActionTypeShift && actions[n - 1].shift.extra)
{ {
t_mut_subtree mutable_lookahead = ts_subtree_make_mut(/*&self->tree_pool,*/ lookahead); t_subtree mutable_lookahead = ts_subtree_make_mut(/*&self->tree_pool,*/ lookahead);
ts_subtree_set_extra(&mutable_lookahead, true); ts_subtree_set_extra(&mutable_lookahead, true);
lookahead = ts_subtree_from_mut(mutable_lookahead); lookahead = (mutable_lookahead);
} }
// Wrap the lookahead token in an ERROR. // Wrap the lookahead token in an ERROR.
SubtreeArray children = array_new(); SubtreeArray children = array_new();
array_reserve(&children, 1); array_reserve(&children, 1);
array_push(&children, lookahead); array_push(&children, lookahead);
t_mut_subtree error_repeat = ts_subtree_new_node(ts_builtin_sym_error_repeat, &children, 0, self->language); 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 // If other tokens have already been skipped, so there is already an ERROR at the top of the
// stack, then pop that ERROR off the stack and wrap the two ERRORs together into one larger // stack, then pop that ERROR off the stack and wrap the two ERRORs together into one larger
@ -1034,12 +1034,12 @@ static void ts_parser__recover(TSParser *self, t_stack_version version, t_subtre
} }
ts_stack_renumber_version(self->stack, pop.contents[0].version, version); ts_stack_renumber_version(self->stack, pop.contents[0].version, version);
array_push(&pop.contents[0].subtrees, ts_subtree_from_mut(error_repeat)); array_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); error_repeat = ts_subtree_new_node(ts_builtin_sym_error_repeat, &pop.contents[0].subtrees, 0, self->language);
} }
// Push the new ERROR onto the stack. // Push the new ERROR onto the stack.
ts_stack_push(self->stack, version, ts_subtree_from_mut(error_repeat), false, ERROR_STATE); ts_stack_push(self->stack, version, (error_repeat), false, ERROR_STATE);
if (ts_subtree_has_external_tokens(lookahead)) if (ts_subtree_has_external_tokens(lookahead))
{ {
ts_stack_set_last_external_token(self->stack, version, ts_subtree_last_external_token(lookahead)); ts_stack_set_last_external_token(self->stack, version, ts_subtree_last_external_token(lookahead));
@ -1248,9 +1248,9 @@ 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); ts_language_table_entry(self->language, state, self->language->keyword_capture_token, &table_entry);
if (table_entry.action_count > 0) if (table_entry.action_count > 0)
{ {
t_mut_subtree mutable_lookahead = ts_subtree_make_mut(/*&self->tree_pool,*/ lookahead); t_subtree mutable_lookahead = ts_subtree_make_mut(/*&self->tree_pool,*/ lookahead);
ts_subtree_set_symbol(&mutable_lookahead, self->language->keyword_capture_token, self->language); ts_subtree_set_symbol(&mutable_lookahead, self->language->keyword_capture_token, self->language);
lookahead = ts_subtree_from_mut(mutable_lookahead); lookahead = (mutable_lookahead);
continue; continue;
} }
} }

View file

@ -39,7 +39,7 @@ void stack_node_add_link(t_stack_node *self, t_stack_link link)
if (ts_subtree_dynamic_precedence(\ if (ts_subtree_dynamic_precedence(\
link.subtree) > ts_subtree_dynamic_precedence(existing_link->subtree)) link.subtree) > ts_subtree_dynamic_precedence(existing_link->subtree))
{ {
ts_subtree_retain(link.subtree); (link.subtree->ref_count++);
ts_subtree_release(existing_link->subtree); ts_subtree_release(existing_link->subtree);
existing_link->subtree = link.subtree; existing_link->subtree = link.subtree;
self->dynamic_precedence = link.node->dynamic_precedence self->dynamic_precedence = link.node->dynamic_precedence
@ -74,7 +74,7 @@ void stack_node_add_link(t_stack_node *self, t_stack_link link)
self->links[self->link_count++] = link; self->links[self->link_count++] = link;
if (link.subtree) if (link.subtree)
{ {
ts_subtree_retain(link.subtree); (link.subtree->ref_count++);
node_count += stack__subtree_node_count(link.subtree); node_count += stack__subtree_node_count(link.subtree);
dynamic_precedence += ts_subtree_dynamic_precedence(link.subtree); dynamic_precedence += ts_subtree_dynamic_precedence(link.subtree);
} }

View file

@ -68,7 +68,7 @@ t_stack_version ts_stack__add_version(t_stack *self,
array_push(&self->heads, head); array_push(&self->heads, head);
stack_node_retain(node); stack_node_retain(node);
if (head.last_external_token) if (head.last_external_token)
ts_subtree_retain(head.last_external_token); (head.last_external_token->ref_count++);
return ((t_stack_version)(self->heads.size - 1)); return ((t_stack_version)(self->heads.size - 1));
} }
@ -103,7 +103,7 @@ void ts_stack_set_last_external_token(t_stack *self, t_stack_version version,
head = array_get(&self->heads, version); head = array_get(&self->heads, version);
if (token) if (token)
ts_subtree_retain(token); (token->ref_count++);
if (head->last_external_token) if (head->last_external_token)
ts_subtree_release(head->last_external_token); ts_subtree_release(head->last_external_token);
head->last_external_token = token; head->last_external_token = token;

View file

@ -106,7 +106,7 @@ t_stack_slice_array stack__iter(t_stack *self, t_stack_version version,
if (include_subtrees) if (include_subtrees)
{ {
array_push(&next_iterator->subtrees, link.subtree); array_push(&next_iterator->subtrees, link.subtree);
ts_subtree_retain(link.subtree); (link.subtree->ref_count++);
} }
if (!ts_subtree_extra(link.subtree)) if (!ts_subtree_extra(link.subtree))
{ {

View file

@ -60,7 +60,7 @@ t_stack_version ts_stack_copy_version(t_stack *self, t_stack_version version)
head = array_back(&self->heads); head = array_back(&self->heads);
stack_node_retain(head->node); stack_node_retain(head->node);
if (head->last_external_token) if (head->last_external_token)
ts_subtree_retain(head->last_external_token); (head->last_external_token->ref_count++);
head->summary = NULL; head->summary = NULL;
return (self->heads.size - 1); return (self->heads.size - 1);
} }

View file

@ -9,11 +9,6 @@
#include "parser/length.h" #include "parser/length.h"
#include "parser/subtree.h" #include "parser/subtree.h"
#define TS_MAX_INLINE_TREE_LENGTH 0
#define TS_MAX_TREE_POOL_SIZE 0
// SubtreeArray
void ts_subtree_array_copy(SubtreeArray self, SubtreeArray *dest) void ts_subtree_array_copy(SubtreeArray self, SubtreeArray *dest)
{ {
dest->size = self.size; dest->size = self.size;
@ -24,18 +19,14 @@ void ts_subtree_array_copy(SubtreeArray self, SubtreeArray *dest)
dest->contents = mem_alloc_array(self.capacity, sizeof(t_subtree)); dest->contents = mem_alloc_array(self.capacity, sizeof(t_subtree));
mem_copy(dest->contents, self.contents, self.size * sizeof(t_subtree)); mem_copy(dest->contents, self.contents, self.size * sizeof(t_subtree));
for (t_u32 i = 0; i < self.size; i++) for (t_u32 i = 0; i < self.size; i++)
{ (dest->contents[i]->ref_count++);
ts_subtree_retain(dest->contents[i]);
}
} }
} }
void ts_subtree_array_clear(SubtreeArray *self) void ts_subtree_array_clear(SubtreeArray *self)
{ {
for (t_u32 i = 0; i < self->size; i++) for (t_u32 i = 0; i < self->size; i++)
{
ts_subtree_release(self->contents[i]); ts_subtree_release(self->contents[i]);
}
array_clear(self); array_clear(self);
} }
@ -57,10 +48,8 @@ void ts_subtree_array_remove_trailing_extras(SubtreeArray *self, SubtreeArray *d
array_push(destination, last); array_push(destination, last);
} }
else else
{
break; break;
} }
}
ts_subtree_array_reverse(destination); ts_subtree_array_reverse(destination);
} }
@ -107,48 +96,50 @@ t_subtree ts_subtree_new_leaf(TSSymbol symbol, Length padding, Length size, t_u3
} }
} }
void ts_subtree_set_symbol(t_mut_subtree *self, TSSymbol symbol, const TSLanguage *language) void ts_subtree_set_symbol(t_subtree *self, TSSymbol symbol, const TSLanguage *language)
{ {
TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol); TSSymbolMetadata metadata;
{
metadata = ts_language_symbol_metadata(language, symbol);
(*self)->symbol = symbol; (*self)->symbol = symbol;
(*self)->named = metadata.named; (*self)->named = metadata.named;
(*self)->visible = metadata.visible; (*self)->visible = metadata.visible;
}
} }
t_subtree ts_subtree_new_error(t_i32 lookahead_char, Length padding, Length size, t_u32 bytes_scanned, TSStateId parse_state, t_subtree ts_subtree_new_error(t_i32 lookahead_char, Length padding, Length size, t_u32 bytes_scanned, TSStateId parse_state,
const TSLanguage *language) const TSLanguage *language)
{ {
t_subtree result = ts_subtree_new_leaf(ts_builtin_sym_error, padding, size, bytes_scanned, parse_state, false, false, false, language); t_subtree result;
t_subtree_data *data = (t_subtree_data *)result;
data->fragile_left = true; result = ts_subtree_new_leaf(ts_builtin_sym_error, padding, size, bytes_scanned, parse_state, false, false, false, language);
data->fragile_right = true; result->fragile_left = true;
data->lookahead_char = lookahead_char; result->fragile_right = true;
result->lookahead_char = lookahead_char;
return result; return result;
} }
// Clone a subtree. // Clone a subtree.
t_mut_subtree ts_subtree_clone(t_subtree self) t_subtree ts_subtree_clone(t_subtree self)
{ {
size_t alloc_size = ts_subtree_alloc_size(self->child_count); t_usize alloc_size;
t_subtree *new_children = mem_alloc(alloc_size); t_usize i;
t_subtree *old_children = ts_subtree_children(self); t_subtree *new_children;
t_subtree *old_children;
t_subtree_data *result;
alloc_size = ts_subtree_alloc_size(self->child_count);
new_children = mem_alloc(alloc_size);
old_children = ts_subtree_children(self);
mem_copy(new_children, old_children, alloc_size); mem_copy(new_children, old_children, alloc_size);
t_subtree_data *result = (t_subtree_data *)&new_children[self->child_count]; result = (t_subtree_data *)&new_children[self->child_count];
i = 0;
if (self->child_count > 0) if (self->child_count > 0)
{ while (i < self->child_count)
for (t_u32 i = 0; i < self->child_count; i++) (new_children[i++]->ref_count++);
{
ts_subtree_retain(new_children[i]);
}
}
else if (self->has_external_tokens) else if (self->has_external_tokens)
{
result->external_scanner_state = ts_external_scanner_state_copy(&self->external_scanner_state); result->external_scanner_state = ts_external_scanner_state_copy(&self->external_scanner_state);
}
result->ref_count = 1; result->ref_count = 1;
return (t_mut_subtree)result; return ((t_subtree)result);
} }
// Get mutable version of a subtree. // Get mutable version of a subtree.
@ -156,48 +147,52 @@ t_mut_subtree ts_subtree_clone(t_subtree self)
// This takes ownership of the subtree. If the subtree has only one owner, // 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 // this will directly convert it into a mutable version. Otherwise, it will
// perform a copy. // perform a copy.
t_mut_subtree ts_subtree_make_mut(t_subtree self) t_subtree ts_subtree_make_mut(t_subtree self)
{ {
if (self->ref_count == 1) t_subtree result;
return ts_subtree_to_mut_unsafe(self);
t_mut_subtree result = ts_subtree_clone(self); result = ts_subtree_clone(self);
ts_subtree_release(self); ts_subtree_release(self);
return result; return result;
} }
static void ts_subtree__compress(t_mut_subtree self, t_u32 count, const TSLanguage *language, MutableSubtreeArray *stack) static void ts_subtree__compress(t_subtree self, t_u32 count, const TSLanguage *language, SubtreeArray *stack)
{ {
t_u32 initial_stack_size = stack->size; t_u32 initial_stack_size;
t_subtree tree;
TSSymbol symbol;
t_usize i;
t_subtree child_grandchild[2];
t_mut_subtree tree = self; initial_stack_size = stack->size;
TSSymbol symbol = tree->symbol; tree = self;
for (t_u32 i = 0; i < count; i++) symbol = tree->symbol;
i = 0;
while (i < count)
{ {
if (tree->ref_count > 1 || tree->child_count < 2) if (tree->ref_count > 1 || tree->child_count < 2)
break; break;
child_grandchild[0] = (ts_subtree_children(tree)[0]);
t_mut_subtree child = ts_subtree_to_mut_unsafe(ts_subtree_children(tree)[0]); if (child_grandchild[0]->child_count < 2 || child_grandchild[0]->ref_count > 1 || child_grandchild[0]->symbol != symbol)
if (child->child_count < 2 || child->ref_count > 1 || child->symbol != symbol)
break; break;
child_grandchild[1] = (ts_subtree_children(child_grandchild[0])[0]);
t_mut_subtree grandchild = ts_subtree_to_mut_unsafe(ts_subtree_children(child)[0]); if (child_grandchild[1]->child_count < 2 || child_grandchild[1]->ref_count > 1 || child_grandchild[1]->symbol != symbol)
if (grandchild->child_count < 2 || grandchild->ref_count > 1 || grandchild->symbol != symbol)
break; break;
ts_subtree_children(tree)[0] = (child_grandchild[1]);
ts_subtree_children(tree)[0] = ts_subtree_from_mut(grandchild); ts_subtree_children(child_grandchild[0])[0] = ts_subtree_children(child_grandchild[1])[child_grandchild[1]->child_count - 1];
ts_subtree_children(child)[0] = ts_subtree_children(grandchild)[grandchild->child_count - 1]; ts_subtree_children(child_grandchild[1])[child_grandchild[1]->child_count - 1] = (child_grandchild[0]);
ts_subtree_children(grandchild)[grandchild->child_count - 1] = ts_subtree_from_mut(child);
array_push(stack, tree); array_push(stack, tree);
tree = grandchild; tree = child_grandchild[1];
i++;
} }
while (stack->size > initial_stack_size) while (stack->size > initial_stack_size)
{ {
tree = array_pop(stack); tree = array_pop(stack);
t_mut_subtree child = ts_subtree_to_mut_unsafe(ts_subtree_children(tree)[0]); child_grandchild[0] = (ts_subtree_children(tree)[0]);
t_mut_subtree grandchild = ts_subtree_to_mut_unsafe(ts_subtree_children(child)[child->child_count - 1]); child_grandchild[1] = (ts_subtree_children(child_grandchild[0])[child_grandchild[0]->child_count - 1]);
ts_subtree_summarize_children(grandchild, language); ts_subtree_summarize_children(child_grandchild[1], language);
ts_subtree_summarize_children(child, language); ts_subtree_summarize_children(child_grandchild[0], language);
ts_subtree_summarize_children(tree, language); ts_subtree_summarize_children(tree, language);
} }
} }
@ -205,17 +200,17 @@ static void ts_subtree__compress(t_mut_subtree self, t_u32 count, const TSLangua
void ts_subtree_balance(t_subtree self, const TSLanguage *language) void ts_subtree_balance(t_subtree self, const TSLanguage *language)
{ {
MutableSubtreeArray balance_stack = array_new(); SubtreeArray balance_stack;
balance_stack = (SubtreeArray)array_new();
array_clear(&balance_stack); array_clear(&balance_stack);
if (ts_subtree_child_count(self) > 0 && self->ref_count == 1) if (ts_subtree_child_count(self) > 0 && self->ref_count == 1)
{ array_push(&balance_stack, self);
array_push(&balance_stack, ts_subtree_to_mut_unsafe(self));
}
while (balance_stack.size > 0) while (balance_stack.size > 0)
{ {
t_mut_subtree tree = array_pop(&balance_stack); t_subtree tree = array_pop(&balance_stack);
if (tree->repeat_depth > 0) if (tree->repeat_depth > 0)
{ {
@ -237,16 +232,14 @@ void ts_subtree_balance(t_subtree self, const TSLanguage *language)
{ {
t_subtree child = ts_subtree_children(tree)[i]; t_subtree child = ts_subtree_children(tree)[i];
if (ts_subtree_child_count(child) > 0 && child->ref_count == 1) if (ts_subtree_child_count(child) > 0 && child->ref_count == 1)
{ array_push(&balance_stack, child);
array_push(&balance_stack, ts_subtree_to_mut_unsafe(child));
}
} }
} }
array_delete(&balance_stack); array_delete(&balance_stack);
} }
// Assign all of the node's properties that depend on its children. // Assign all of the node's properties that depend on its children.
void ts_subtree_summarize_children(t_mut_subtree self, const TSLanguage *language) void ts_subtree_summarize_children(t_subtree self, const TSLanguage *language)
{ {
self->named_child_count = 0; self->named_child_count = 0;
self->visible_child_count = 0; self->visible_child_count = 0;
@ -390,7 +383,7 @@ void ts_subtree_summarize_children(t_mut_subtree self, const TSLanguage *languag
// Create a new parent node with the given children. // Create a new parent node with the given children.
// //
// This takes ownership of the children array. // This takes ownership of the children array.
t_mut_subtree ts_subtree_new_node(TSSymbol symbol, SubtreeArray *children, t_u32 production_id, const TSLanguage *language) t_subtree ts_subtree_new_node(TSSymbol symbol, SubtreeArray *children, t_u32 production_id, const TSLanguage *language)
{ {
TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol); TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);
bool fragile = symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat; bool fragile = symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat;
@ -419,7 +412,7 @@ t_mut_subtree ts_subtree_new_node(TSSymbol symbol, SubtreeArray *children, t_u32
.production_id = production_id, .production_id = production_id,
.first_leaf = {.symbol = 0, .parse_state = 0}, .first_leaf = {.symbol = 0, .parse_state = 0},
}}}; }}};
t_mut_subtree result = data; t_subtree result = data;
ts_subtree_summarize_children(result, language); ts_subtree_summarize_children(result, language);
return result; return result;
} }
@ -430,9 +423,9 @@ t_mut_subtree ts_subtree_new_node(TSSymbol symbol, SubtreeArray *children, t_u32
// having any effect on the parse state. // 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(SubtreeArray *children, bool extra, const TSLanguage *language)
{ {
t_mut_subtree result = ts_subtree_new_node(ts_builtin_sym_error, children, 0, language); t_subtree result = ts_subtree_new_node(ts_builtin_sym_error, children, 0, language);
result->extra = extra; result->extra = extra;
return ts_subtree_from_mut(result); return ((result));
} }
// Create a new 'missing leaf' node. // Create a new 'missing leaf' node.
@ -446,30 +439,21 @@ t_subtree ts_subtree_new_missing_leaf(TSSymbol symbol, Length padding, t_u32 loo
return result; return result;
} }
void ts_subtree_retain(t_subtree self)
{
assert(self->ref_count > 0);
(*(t_u32 *)(&self->ref_count))++;
assert(self->ref_count != 0);
}
void ts_subtree_release(t_subtree self) void ts_subtree_release(t_subtree self)
{ {
MutableSubtreeArray to_free; SubtreeArray to_free;
to_free = (MutableSubtreeArray)array_new(); to_free = (SubtreeArray)array_new();
array_clear(&to_free); array_clear(&to_free);
assert(self->ref_count > 0); assert(self->ref_count > 0);
if (--(*(t_u32 *)(&self->ref_count)) == 0) if (--(*(t_u32 *)(&self->ref_count)) == 0)
{ array_push(&to_free, (self));
array_push(&to_free, ts_subtree_to_mut_unsafe(self));
}
while (to_free.size > 0) while (to_free.size > 0)
{ {
t_mut_subtree tree = array_pop(&to_free); t_subtree tree = array_pop(&to_free);
if (tree->child_count > 0) if (tree->child_count > 0)
{ {
t_subtree *children = ts_subtree_children(tree); t_subtree *children = ts_subtree_children(tree);
@ -478,9 +462,7 @@ void ts_subtree_release(t_subtree self)
t_subtree child = children[i]; t_subtree child = children[i];
assert(child->ref_count > 0); assert(child->ref_count > 0);
if (--(*(t_u32 *)(&child->ref_count)) == 0) if (--(*(t_u32 *)(&child->ref_count)) == 0)
{ array_push(&to_free, (child));
array_push(&to_free, ts_subtree_to_mut_unsafe(child));
}
} }
mem_free(children); mem_free(children);
} }
@ -496,15 +478,15 @@ void ts_subtree_release(t_subtree self)
int ts_subtree_compare(t_subtree left, t_subtree right) int ts_subtree_compare(t_subtree left, t_subtree right)
{ {
MutableSubtreeArray compare_stack = array_new(); SubtreeArray compare_stack = array_new();
array_push(&compare_stack, ts_subtree_to_mut_unsafe(left)); array_push(&compare_stack, (left));
array_push(&compare_stack, ts_subtree_to_mut_unsafe(right)); array_push(&compare_stack, (right));
while (compare_stack.size > 0) while (compare_stack.size > 0)
{ {
right = ts_subtree_from_mut(array_pop(&compare_stack)); right = (array_pop(&compare_stack));
left = ts_subtree_from_mut(array_pop(&compare_stack)); left = (array_pop(&compare_stack));
int result = 0; int result = 0;
if (ts_subtree_symbol(left) < ts_subtree_symbol(right)) if (ts_subtree_symbol(left) < ts_subtree_symbol(right))
@ -526,8 +508,8 @@ int ts_subtree_compare(t_subtree left, t_subtree right)
{ {
t_subtree left_child = ts_subtree_children(left)[i - 1]; t_subtree left_child = ts_subtree_children(left)[i - 1];
t_subtree right_child = ts_subtree_children(right)[i - 1]; t_subtree right_child = ts_subtree_children(right)[i - 1];
array_push(&compare_stack, ts_subtree_to_mut_unsafe(left_child)); array_push(&compare_stack, (left_child));
array_push(&compare_stack, ts_subtree_to_mut_unsafe(right_child)); array_push(&compare_stack, (right_child));
} }
} }

View file

@ -26,7 +26,7 @@ TSTree *ts_tree_new(t_subtree root, const TSLanguage *language)
TSTree *ts_tree_copy(const TSTree *self) TSTree *ts_tree_copy(const TSTree *self)
{ {
ts_subtree_retain(self->root); (self->root->ref_count++);
return (ts_tree_new(self->root, self->language)); return (ts_tree_new(self->root, self->language));
} }