Revert "Store trees' children in TreeArrays, not w/ separate pointer and length"
This reverts commit 09be0b6ef5.
This commit is contained in:
parent
69c815107f
commit
77e4caef4f
9 changed files with 154 additions and 153 deletions
|
|
@ -12,18 +12,18 @@ extern "C" {
|
|||
#include <stdbool.h>
|
||||
#include "runtime/alloc.h"
|
||||
|
||||
#define Array(T) \
|
||||
struct { \
|
||||
#define Array(T) \
|
||||
struct { \
|
||||
T *contents; \
|
||||
uint32_t size; \
|
||||
uint32_t capacity; \
|
||||
T *contents; \
|
||||
}
|
||||
|
||||
#define array_init(self) \
|
||||
((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL)
|
||||
|
||||
#define array_new() \
|
||||
{ 0, 0, NULL }
|
||||
{ NULL, 0, 0 }
|
||||
|
||||
#define array_get(self, index) \
|
||||
(assert((uint32_t)index < (self)->size), &(self)->contents[index])
|
||||
|
|
@ -47,11 +47,11 @@ extern "C" {
|
|||
(self)->contents[(self)->size++] = (element))
|
||||
|
||||
#define array_push_all(self, other) \
|
||||
array_splice((self), (self)->size, 0, (other))
|
||||
array_splice((self), (self)->size, 0, (other)->size, (other)->contents)
|
||||
|
||||
#define array_splice(self, index, old_count, new_array) \
|
||||
#define array_splice(self, index, old_count, new_count, new_contents) \
|
||||
array__splice((VoidArray *)(self), array__elem_size(self), index, old_count, \
|
||||
(new_array)->size, (new_array)->contents)
|
||||
new_count, new_contents)
|
||||
|
||||
#define array_insert(self, index, element) \
|
||||
array__splice((VoidArray *)(self), array__elem_size(self), index, 0, 1, &element)
|
||||
|
|
|
|||
|
|
@ -129,8 +129,8 @@ static bool iterator_descend(Iterator *self, uint32_t goal_position) {
|
|||
TreeCursorEntry entry = *array_back(&self->cursor.stack);
|
||||
Length position = entry.position;
|
||||
uint32_t structural_child_index = 0;
|
||||
for (uint32_t i = 0; i < entry.subtree->children.size; i++) {
|
||||
const Subtree *child = entry.subtree->children.contents[i];
|
||||
for (uint32_t i = 0; i < entry.subtree->child_count; i++) {
|
||||
const Subtree *child = entry.subtree->children[i];
|
||||
Length child_left = length_add(position, child->padding);
|
||||
Length child_right = length_add(child_left, child->size);
|
||||
|
||||
|
|
@ -181,11 +181,11 @@ static void iterator_advance(Iterator *self) {
|
|||
|
||||
const Subtree *parent = array_back(&self->cursor.stack)->subtree;
|
||||
uint32_t child_index = entry.child_index + 1;
|
||||
if (parent->children.size > child_index) {
|
||||
if (parent->child_count > child_index) {
|
||||
Length position = length_add(entry.position, ts_subtree_total_size(entry.subtree));
|
||||
uint32_t structural_child_index = entry.structural_child_index;
|
||||
if (!entry.subtree->extra) structural_child_index++;
|
||||
const Subtree *next_child = parent->children.contents[child_index];
|
||||
const Subtree *next_child = parent->children[child_index];
|
||||
|
||||
array_push(&self->cursor.stack, ((TreeCursorEntry){
|
||||
.subtree = next_child,
|
||||
|
|
|
|||
|
|
@ -63,8 +63,8 @@ static inline ChildIterator ts_node_iterate_children(const TSNode *node) {
|
|||
}
|
||||
|
||||
static inline bool ts_node_child_iterator_next(ChildIterator *self, TSNode *result) {
|
||||
if (self->child_index == self->parent->children.size) return false;
|
||||
const Subtree *child = self->parent->children.contents[self->child_index];
|
||||
if (self->child_index == self->parent->child_count) return false;
|
||||
const Subtree *child = self->parent->children[self->child_index];
|
||||
TSSymbol alias_symbol = 0;
|
||||
if (!child->extra) {
|
||||
if (self->alias_sequence) {
|
||||
|
|
@ -108,7 +108,7 @@ static inline bool ts_node__is_relevant(TSNode self, bool include_anonymous) {
|
|||
|
||||
static inline uint32_t ts_node__relevant_child_count(TSNode self, bool include_anonymous) {
|
||||
const Subtree *tree = ts_node__subtree(self);
|
||||
if (tree->children.size > 0) {
|
||||
if (tree->child_count > 0) {
|
||||
if (include_anonymous) {
|
||||
return tree->visible_child_count;
|
||||
} else {
|
||||
|
|
@ -154,8 +154,8 @@ static inline TSNode ts_node__child(TSNode self, uint32_t child_index, bool incl
|
|||
}
|
||||
|
||||
static bool ts_subtree_has_trailing_empty_descendant(const Subtree *self, const Subtree *other) {
|
||||
for (unsigned i = self->children.size - 1; i + 1 > 0; i--) {
|
||||
const Subtree *child = self->children.contents[i];
|
||||
for (unsigned i = self->child_count - 1; i + 1 > 0; i--) {
|
||||
const Subtree *child = self->children[i];
|
||||
if (child->size.bytes > 0 || child->padding.bytes > 0) break;
|
||||
if (child == other || ts_subtree_has_trailing_empty_descendant(child, other)) return true;
|
||||
}
|
||||
|
|
@ -453,7 +453,7 @@ TSNode ts_node_named_child(TSNode self, uint32_t child_index) {
|
|||
|
||||
uint32_t ts_node_child_count(TSNode self) {
|
||||
const Subtree *tree = ts_node__subtree(self);
|
||||
if (tree->children.size > 0) {
|
||||
if (tree->child_count > 0) {
|
||||
return tree->visible_child_count;
|
||||
} else {
|
||||
return 0;
|
||||
|
|
@ -462,7 +462,7 @@ uint32_t ts_node_child_count(TSNode self) {
|
|||
|
||||
uint32_t ts_node_named_child_count(TSNode self) {
|
||||
const Subtree *tree = ts_node__subtree(self);
|
||||
if (tree->children.size > 0) {
|
||||
if (tree->child_count > 0) {
|
||||
return tree->named_child_count;
|
||||
} else {
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -134,9 +134,9 @@ static bool ts_parser__breakdown_top_of_stack(TSParser *self, StackVersion versi
|
|||
TSStateId state = ts_stack_state(self->stack, slice.version);
|
||||
const Subtree *parent = *array_front(&slice.subtrees);
|
||||
|
||||
for (uint32_t j = 0; j < parent->children.size; j++) {
|
||||
const Subtree *child = parent->children.contents[j];
|
||||
pending = child->children.size > 0;
|
||||
for (uint32_t j = 0; j < parent->child_count; j++) {
|
||||
const Subtree *child = parent->children[j];
|
||||
pending = child->child_count > 0;
|
||||
|
||||
if (child->symbol == ts_builtin_sym_error) {
|
||||
state = ERROR_STATE;
|
||||
|
|
@ -168,7 +168,7 @@ static void ts_parser__breakdown_lookahead(TSParser *self, const Subtree **looka
|
|||
TSStateId state, ReusableNode *reusable_node) {
|
||||
bool did_descend = false;
|
||||
const Subtree *tree = reusable_node_tree(reusable_node);
|
||||
while (tree->children.size > 0 && tree->parse_state != state) {
|
||||
while (tree->child_count > 0 && tree->parse_state != state) {
|
||||
LOG("state_mismatch sym:%s", SYM_NAME(tree->symbol));
|
||||
reusable_node_descend(reusable_node);
|
||||
tree = reusable_node_tree(reusable_node);
|
||||
|
|
@ -599,7 +599,7 @@ static void ts_parser__shift(TSParser *self, StackVersion version, TSStateId sta
|
|||
subtree_to_push = lookahead;
|
||||
}
|
||||
|
||||
bool is_pending = subtree_to_push->children.size > 0;
|
||||
bool is_pending = subtree_to_push->child_count > 0;
|
||||
ts_stack_push(self->stack, version, subtree_to_push, is_pending, state);
|
||||
if (subtree_to_push->has_external_tokens) {
|
||||
ts_stack_set_last_external_token(
|
||||
|
|
@ -610,8 +610,8 @@ static void ts_parser__shift(TSParser *self, StackVersion version, TSStateId sta
|
|||
|
||||
static bool ts_parser__replace_children(TSParser *self, Subtree *tree, SubtreeArray *children) {
|
||||
self->scratch_tree = *tree;
|
||||
self->scratch_tree.children.size = 0;
|
||||
ts_subtree_set_children(&self->scratch_tree, children, self->language);
|
||||
self->scratch_tree.child_count = 0;
|
||||
ts_subtree_set_children(&self->scratch_tree, children->contents, children->size, self->language);
|
||||
if (ts_parser__select_tree(self, tree, &self->scratch_tree)) {
|
||||
*tree = self->scratch_tree;
|
||||
return true;
|
||||
|
|
@ -697,7 +697,7 @@ static StackVersion ts_parser__reduce(TSParser *self, StackVersion version, TSSy
|
|||
// 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 (uint32_t j = parent->children.size; j < slice.subtrees.size; j++) {
|
||||
for (uint32_t j = parent->child_count; j < slice.subtrees.size; j++) {
|
||||
ts_stack_push(self->stack, slice_version, slice.subtrees.contents[j], false, next_state);
|
||||
}
|
||||
|
||||
|
|
@ -728,10 +728,10 @@ static void ts_parser__accept(TSParser *self, StackVersion version, const Subtre
|
|||
for (uint32_t j = trees.size - 1; j + 1 > 0; j--) {
|
||||
const Subtree *child = trees.contents[j];
|
||||
if (!child->extra) {
|
||||
for (uint32_t k = 0; k < child->children.size; k++) {
|
||||
ts_subtree_retain(child->children.contents[k]);
|
||||
for (uint32_t k = 0; k < child->child_count; k++) {
|
||||
ts_subtree_retain(child->children[k]);
|
||||
}
|
||||
array_splice(&trees, j, 1, &child->children);
|
||||
array_splice(&trees, j, 1, child->child_count, child->children);
|
||||
root = ts_subtree_new_node(
|
||||
&self->tree_pool, child->symbol, &trees,
|
||||
child->alias_sequence_id, self->language
|
||||
|
|
@ -957,8 +957,9 @@ static bool ts_parser__recover_to_state(TSParser *self, StackVersion version, un
|
|||
SubtreeArray error_trees = ts_stack_pop_error(self->stack, slice.version);
|
||||
if (error_trees.size > 0) {
|
||||
assert(error_trees.size == 1);
|
||||
array_splice(&slice.subtrees, 0, 0, &error_trees.contents[0]->children);
|
||||
for (unsigned j = 0; j < error_trees.contents[0]->children.size; j++) {
|
||||
const Subtree *error_tree = error_trees.contents[0];
|
||||
array_splice(&slice.subtrees, 0, 0, error_tree->child_count, error_tree->children);
|
||||
for (unsigned j = 0; j < error_tree->child_count; j++) {
|
||||
ts_subtree_retain(slice.subtrees.contents[j]);
|
||||
}
|
||||
ts_subtree_array_delete(&self->tree_pool, &error_trees);
|
||||
|
|
@ -1163,7 +1164,7 @@ static void ts_parser__advance(TSParser *self, StackVersion version, bool allow_
|
|||
LOG("shift state:%u", next_state);
|
||||
}
|
||||
|
||||
if (lookahead->children.size > 0) {
|
||||
if (lookahead->child_count > 0) {
|
||||
ts_parser__breakdown_lookahead(self, &lookahead, state, &self->reusable_node);
|
||||
next_state = ts_language_next_state(self->language, state, lookahead->symbol);
|
||||
}
|
||||
|
|
@ -1194,7 +1195,7 @@ static void ts_parser__advance(TSParser *self, StackVersion version, bool allow_
|
|||
}
|
||||
|
||||
case TSParseActionTypeRecover: {
|
||||
if (lookahead->children.size > 0) {
|
||||
if (lookahead->child_count > 0) {
|
||||
ts_parser__breakdown_lookahead(self, &lookahead, ERROR_STATE, &self->reusable_node);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,10 +59,10 @@ static inline void reusable_node_advance(ReusableNode *self) {
|
|||
next_index = popped_entry.child_index + 1;
|
||||
if (self->stack.size == 0) return;
|
||||
tree = array_back(&self->stack)->tree;
|
||||
} while (tree->children.size <= next_index);
|
||||
} while (tree->child_count <= next_index);
|
||||
|
||||
array_push(&self->stack, ((StackEntry) {
|
||||
.tree = tree->children.contents[next_index],
|
||||
.tree = tree->children[next_index],
|
||||
.child_index = next_index,
|
||||
.byte_offset = byte_offset,
|
||||
}));
|
||||
|
|
@ -70,9 +70,9 @@ static inline void reusable_node_advance(ReusableNode *self) {
|
|||
|
||||
static inline bool reusable_node_descend(ReusableNode *self) {
|
||||
StackEntry last_entry = *array_back(&self->stack);
|
||||
if (last_entry.tree->children.size > 0) {
|
||||
if (last_entry.tree->child_count > 0) {
|
||||
array_push(&self->stack, ((StackEntry) {
|
||||
.tree = last_entry.tree->children.contents[0],
|
||||
.tree = last_entry.tree->children[0],
|
||||
.child_index = 0,
|
||||
.byte_offset = last_entry.byte_offset,
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -186,8 +186,12 @@ Subtree *ts_subtree_new_error(SubtreePool *pool, Length size, Length padding,
|
|||
Subtree *ts_subtree_new_copy(SubtreePool *pool, const Subtree *self) {
|
||||
Subtree *result = ts_subtree_pool_allocate(pool);
|
||||
*result = *self;
|
||||
if (result->children.size > 0) {
|
||||
ts_subtree_array_copy(self->children, &result->children);
|
||||
if (result->child_count > 0) {
|
||||
result->children = ts_calloc(self->child_count, sizeof(const Subtree *));
|
||||
memcpy(result->children, self->children, self->child_count * sizeof(const Subtree *));
|
||||
for (uint32_t i = 0; i < result->child_count; i++) {
|
||||
ts_subtree_retain(result->children[i]);
|
||||
}
|
||||
} else if (result->has_external_tokens) {
|
||||
result->external_scanner_state = ts_external_scanner_state_copy(&self->external_scanner_state);
|
||||
}
|
||||
|
|
@ -211,25 +215,25 @@ static void ts_subtree__compress(Subtree *self, unsigned count, const TSLanguage
|
|||
|
||||
Subtree *tree = self;
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
if (tree->ref_count > 1 || tree->children.size != 2) break;
|
||||
if (tree->ref_count > 1 || tree->child_count != 2) break;
|
||||
|
||||
Subtree *child = (Subtree *)tree->children.contents[0];
|
||||
Subtree *child = (Subtree *)tree->children[0];
|
||||
if (
|
||||
child->ref_count > 1 ||
|
||||
child->children.size != 2 ||
|
||||
child->child_count != 2 ||
|
||||
child->symbol != tree->symbol
|
||||
) break;
|
||||
|
||||
Subtree *grandchild = (Subtree *)child->children.contents[0];
|
||||
Subtree *grandchild = (Subtree *)child->children[0];
|
||||
if (
|
||||
grandchild->ref_count > 1 ||
|
||||
grandchild->children.size != 2 ||
|
||||
grandchild->child_count != 2 ||
|
||||
grandchild->symbol != tree->symbol
|
||||
) break;
|
||||
|
||||
tree->children.contents[0] = grandchild;
|
||||
child->children.contents[0] = grandchild->children.contents[1];
|
||||
grandchild->children.contents[1] = child;
|
||||
tree->children[0] = grandchild;
|
||||
child->children[0] = grandchild->children[1];
|
||||
grandchild->children[1] = child;
|
||||
array_push(stack, tree);
|
||||
tree = grandchild;
|
||||
}
|
||||
|
|
@ -237,11 +241,11 @@ static void ts_subtree__compress(Subtree *self, unsigned count, const TSLanguage
|
|||
while (stack->size > initial_stack_size) {
|
||||
tree = array_pop(stack);
|
||||
assert(tree);
|
||||
Subtree *child = (Subtree *)tree->children.contents[0];
|
||||
Subtree *grandchild = (Subtree *)child->children.contents[1];
|
||||
ts_subtree_set_children(grandchild, &grandchild->children, language);
|
||||
ts_subtree_set_children(child, &child->children, language);
|
||||
ts_subtree_set_children(tree, &tree->children, language);
|
||||
Subtree *child = (Subtree *)tree->children[0];
|
||||
Subtree *grandchild = (Subtree *)child->children[1];
|
||||
ts_subtree_set_children(grandchild, grandchild->children, grandchild->child_count, language);
|
||||
ts_subtree_set_children(child, child->children, child->child_count, language);
|
||||
ts_subtree_set_children(tree, tree->children, tree->child_count, language);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -257,10 +261,10 @@ void ts_subtree_balance(const Subtree *self, SubtreePool *pool, const TSLanguage
|
|||
assert(tree);
|
||||
|
||||
if (tree->repeat_depth > 0 &&
|
||||
tree->children.contents[0]->repeat_depth > tree->children.contents[1]->repeat_depth) {
|
||||
tree->children[0]->repeat_depth > tree->children[1]->repeat_depth) {
|
||||
unsigned n = (
|
||||
tree->children.contents[0]->repeat_depth -
|
||||
tree->children.contents[1]->repeat_depth
|
||||
tree->children[0]->repeat_depth -
|
||||
tree->children[1]->repeat_depth
|
||||
);
|
||||
for (unsigned i = n / 2; i > 0; i /= 2) {
|
||||
ts_subtree__compress(tree, i, language, &pool->tree_stack);
|
||||
|
|
@ -268,8 +272,8 @@ void ts_subtree_balance(const Subtree *self, SubtreePool *pool, const TSLanguage
|
|||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < tree->children.size; i++) {
|
||||
const Subtree *child = tree->children.contents[i];
|
||||
for (uint32_t i = 0; i < tree->child_count; i++) {
|
||||
const Subtree *child = tree->children[i];
|
||||
if (child->ref_count == 1) {
|
||||
array_push(&pool->tree_stack, (Subtree *)child);
|
||||
}
|
||||
|
|
@ -277,12 +281,13 @@ void ts_subtree_balance(const Subtree *self, SubtreePool *pool, const TSLanguage
|
|||
}
|
||||
}
|
||||
|
||||
void ts_subtree_set_children(Subtree *self, SubtreeArray *children, const TSLanguage *language) {
|
||||
if (self->children.size > 0 && children->contents != self->children.contents) {
|
||||
array_delete(&self->children);
|
||||
void ts_subtree_set_children(Subtree *self, const Subtree **children, uint32_t child_count, const TSLanguage *language) {
|
||||
if (self->child_count > 0 && children != self->children) {
|
||||
ts_free(self->children);
|
||||
}
|
||||
|
||||
self->children = *children;
|
||||
self->child_count = child_count;
|
||||
self->children = children;
|
||||
self->named_child_count = 0;
|
||||
self->visible_child_count = 0;
|
||||
self->error_cost = 0;
|
||||
|
|
@ -294,8 +299,8 @@ void ts_subtree_set_children(Subtree *self, SubtreeArray *children, const TSLang
|
|||
uint32_t non_extra_index = 0;
|
||||
const TSSymbol *alias_sequence = ts_language_alias_sequence(language, self->alias_sequence_id);
|
||||
|
||||
for (uint32_t i = 0; i < self->children.size; i++) {
|
||||
const Subtree *child = self->children.contents[i];
|
||||
for (uint32_t i = 0; i < self->child_count; i++) {
|
||||
const Subtree *child = self->children[i];
|
||||
|
||||
if (i == 0) {
|
||||
self->padding = child->padding;
|
||||
|
|
@ -321,7 +326,7 @@ void ts_subtree_set_children(Subtree *self, SubtreeArray *children, const TSLang
|
|||
} else if (child->visible) {
|
||||
self->visible_child_count++;
|
||||
if (child->named) self->named_child_count++;
|
||||
} else if (child->children.size > 0) {
|
||||
} else if (child->child_count > 0) {
|
||||
self->visible_child_count += child->visible_child_count;
|
||||
self->named_child_count += child->named_child_count;
|
||||
}
|
||||
|
|
@ -340,10 +345,10 @@ void ts_subtree_set_children(Subtree *self, SubtreeArray *children, const TSLang
|
|||
self->error_cost += ERROR_COST_PER_RECOVERY +
|
||||
ERROR_COST_PER_SKIPPED_CHAR * self->size.bytes +
|
||||
ERROR_COST_PER_SKIPPED_LINE * self->size.extent.row;
|
||||
for (uint32_t i = 0; i < self->children.size; i++) {
|
||||
const Subtree *child = self->children.contents[i];
|
||||
for (uint32_t i = 0; i < self->child_count; i++) {
|
||||
const Subtree *child = self->children[i];
|
||||
if (child->extra) continue;
|
||||
if (child->symbol == ts_builtin_sym_error && child->children.size == 0) continue;
|
||||
if (child->symbol == ts_builtin_sym_error && child->child_count == 0) continue;
|
||||
if (child->visible) {
|
||||
self->error_cost += ERROR_COST_PER_SKIPPED_TREE;
|
||||
} else {
|
||||
|
|
@ -352,14 +357,14 @@ void ts_subtree_set_children(Subtree *self, SubtreeArray *children, const TSLang
|
|||
}
|
||||
}
|
||||
|
||||
if (self->children.size > 0) {
|
||||
const Subtree *first_child = self->children.contents[0];
|
||||
const Subtree *last_child = self->children.contents[self->children.size - 1];
|
||||
if (self->child_count > 0) {
|
||||
const Subtree *first_child = self->children[0];
|
||||
const Subtree *last_child = self->children[self->child_count - 1];
|
||||
self->first_leaf = first_child->first_leaf;
|
||||
if (first_child->fragile_left) self->fragile_left = true;
|
||||
if (last_child->fragile_right) self->fragile_right = true;
|
||||
if (
|
||||
self->children.size == 2 &&
|
||||
self->child_count == 2 &&
|
||||
!self->visible && !self->named &&
|
||||
first_child->symbol == self->symbol &&
|
||||
last_child->symbol == self->symbol
|
||||
|
|
@ -381,7 +386,7 @@ Subtree *ts_subtree_new_node(SubtreePool *pool, TSSymbol symbol, SubtreeArray *c
|
|||
result->fragile_left = true;
|
||||
result->fragile_right = true;
|
||||
}
|
||||
ts_subtree_set_children(result, children, language);
|
||||
ts_subtree_set_children(result, children->contents, children->size, language);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -414,14 +419,14 @@ void ts_subtree_release(SubtreePool *pool, const Subtree *self) {
|
|||
|
||||
while (pool->tree_stack.size > 0) {
|
||||
Subtree *tree = array_pop(&pool->tree_stack);
|
||||
if (tree->children.size > 0) {
|
||||
for (uint32_t i = 0; i < tree->children.size; i++) {
|
||||
const Subtree *child = tree->children.contents[i];
|
||||
if (tree->child_count > 0) {
|
||||
for (uint32_t i = 0; i < tree->child_count; i++) {
|
||||
const Subtree *child = tree->children[i];
|
||||
if (atomic_dec((volatile uint32_t *)&child->ref_count) == 0) {
|
||||
array_push(&pool->tree_stack, (Subtree *)child);
|
||||
}
|
||||
}
|
||||
array_delete(&tree->children);
|
||||
ts_free(tree->children);
|
||||
} else if (tree->has_external_tokens) {
|
||||
ts_external_scanner_state_delete(&tree->external_scanner_state);
|
||||
}
|
||||
|
|
@ -442,12 +447,12 @@ bool ts_subtree_eq(const Subtree *self, const Subtree *other) {
|
|||
if (self->padding.bytes != other->padding.bytes) return false;
|
||||
if (self->size.bytes != other->size.bytes) return false;
|
||||
if (self->symbol == ts_builtin_sym_error) return self->lookahead_char == other->lookahead_char;
|
||||
if (self->children.size != other->children.size) return false;
|
||||
if (self->child_count != other->child_count) return false;
|
||||
if (self->visible_child_count != other->visible_child_count) return false;
|
||||
if (self->named_child_count != other->named_child_count) return false;
|
||||
|
||||
for (uint32_t i = 0; i < self->children.size; i++) {
|
||||
if (!ts_subtree_eq(self->children.contents[i], other->children.contents[i])) {
|
||||
for (uint32_t i = 0; i < self->child_count; i++) {
|
||||
if (!ts_subtree_eq(self->children[i], other->children[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -459,13 +464,13 @@ int ts_subtree_compare(const Subtree *left, const Subtree *right) {
|
|||
return -1;
|
||||
if (right->symbol < left->symbol)
|
||||
return 1;
|
||||
if (left->children.size < right->children.size)
|
||||
if (left->child_count < right->child_count)
|
||||
return -1;
|
||||
if (right->children.size < left->children.size)
|
||||
if (right->child_count < left->child_count)
|
||||
return 1;
|
||||
for (uint32_t i = 0; i < left->children.size; i++) {
|
||||
const Subtree *left_child = left->children.contents[i];
|
||||
const Subtree *right_child = right->children.contents[i];
|
||||
for (uint32_t i = 0; i < left->child_count; i++) {
|
||||
const Subtree *left_child = left->children[i];
|
||||
const Subtree *right_child = right->children[i];
|
||||
switch (ts_subtree_compare(left_child, right_child)) {
|
||||
case -1:
|
||||
return -1;
|
||||
|
|
@ -538,8 +543,8 @@ const Subtree *ts_subtree_edit(const Subtree *self, const TSInputEdit *edit, Sub
|
|||
result->has_changes = true;
|
||||
|
||||
Length child_left, child_right = length_zero();
|
||||
for (uint32_t i = 0; i < result->children.size; i++) {
|
||||
const Subtree **child = &result->children.contents[i];
|
||||
for (uint32_t i = 0; i < result->child_count; i++) {
|
||||
const Subtree **child = &result->children[i];
|
||||
Length child_size = ts_subtree_total_size(*child);
|
||||
child_left = child_right;
|
||||
child_right = length_add(child_left, child_size);
|
||||
|
|
@ -589,9 +594,9 @@ const Subtree *ts_subtree_edit(const Subtree *self, const TSInputEdit *edit, Sub
|
|||
|
||||
const Subtree *ts_subtree_last_external_token(const Subtree *tree) {
|
||||
if (!tree->has_external_tokens) return NULL;
|
||||
while (tree->children.size > 0) {
|
||||
for (uint32_t i = tree->children.size - 1; i + 1 > 0; i--) {
|
||||
const Subtree *child = tree->children.contents[i];
|
||||
while (tree->child_count > 0) {
|
||||
for (uint32_t i = tree->child_count - 1; i + 1 > 0; i--) {
|
||||
const Subtree *child = tree->children[i];
|
||||
if (child->has_external_tokens) {
|
||||
tree = child;
|
||||
break;
|
||||
|
|
@ -638,7 +643,7 @@ static size_t ts_subtree__write_to_string(const Subtree *self, char *string, siz
|
|||
}
|
||||
|
||||
if (visible) {
|
||||
if (self->symbol == ts_builtin_sym_error && self->children.size == 0 && self->size.bytes > 0) {
|
||||
if (self->symbol == ts_builtin_sym_error && self->child_count == 0 && self->size.bytes > 0) {
|
||||
cursor += snprintf(*writer, limit, "(UNEXPECTED ");
|
||||
cursor += ts_subtree__write_char_to_string(*writer, limit, self->lookahead_char);
|
||||
} else if (self->is_missing) {
|
||||
|
|
@ -652,8 +657,8 @@ static size_t ts_subtree__write_to_string(const Subtree *self, char *string, siz
|
|||
|
||||
const TSSymbol *alias_sequence = ts_language_alias_sequence(language, self->alias_sequence_id);
|
||||
uint32_t structural_child_index = 0;
|
||||
for (uint32_t i = 0; i < self->children.size; i++) {
|
||||
const Subtree *child = self->children.contents[i];
|
||||
for (uint32_t i = 0; i < self->child_count; i++) {
|
||||
const Subtree *child = self->children[i];
|
||||
if (child->extra) {
|
||||
cursor += ts_subtree__write_to_string(
|
||||
child, *writer, limit,
|
||||
|
|
@ -694,7 +699,7 @@ void ts_subtree__print_dot_graph(const Subtree *self, uint32_t byte_offset,
|
|||
TSSymbol symbol = alias_symbol ? alias_symbol : self->symbol;
|
||||
fprintf(f, "tree_%p [label=\"%s\"", self, ts_language_symbol_name(language, symbol));
|
||||
|
||||
if (self->children.size == 0)
|
||||
if (self->child_count == 0)
|
||||
fprintf(f, ", shape=plaintext");
|
||||
if (self->extra)
|
||||
fprintf(f, ", fontcolor=gray");
|
||||
|
|
@ -716,8 +721,8 @@ void ts_subtree__print_dot_graph(const Subtree *self, uint32_t byte_offset,
|
|||
|
||||
const TSSymbol *alias_sequence = ts_language_alias_sequence(language, self->alias_sequence_id);
|
||||
uint32_t structural_child_index = 0;
|
||||
for (uint32_t i = 0; i < self->children.size; i++) {
|
||||
const Subtree *child = self->children.contents[i];
|
||||
for (uint32_t i = 0; i < self->child_count; i++) {
|
||||
const Subtree *child = self->children[i];
|
||||
if (child->extra) {
|
||||
ts_subtree__print_dot_graph(child, byte_offset, language, 0, f);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ struct Subtree {
|
|||
uint32_t node_count;
|
||||
uint32_t repeat_depth;
|
||||
int32_t dynamic_precedence;
|
||||
uint32_t child_count;
|
||||
|
||||
bool visible : 1;
|
||||
bool named : 1;
|
||||
|
|
@ -55,19 +56,13 @@ struct Subtree {
|
|||
|
||||
union {
|
||||
struct {
|
||||
SubtreeArray children;
|
||||
const Subtree **children;
|
||||
uint32_t visible_child_count;
|
||||
uint32_t named_child_count;
|
||||
uint16_t alias_sequence_id;
|
||||
};
|
||||
struct {
|
||||
uint32_t _2;
|
||||
ExternalScannerState external_scanner_state;
|
||||
};
|
||||
struct {
|
||||
uint32_t _1;
|
||||
int32_t lookahead_char;
|
||||
};
|
||||
ExternalScannerState external_scanner_state;
|
||||
int32_t lookahead_char;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -100,7 +95,7 @@ void ts_subtree_retain(const Subtree *tree);
|
|||
void ts_subtree_release(SubtreePool *, const Subtree *tree);
|
||||
bool ts_subtree_eq(const Subtree *tree1, const Subtree *tree2);
|
||||
int ts_subtree_compare(const Subtree *tree1, const Subtree *tree2);
|
||||
void ts_subtree_set_children(Subtree *, SubtreeArray *, const TSLanguage *);
|
||||
void ts_subtree_set_children(Subtree *, const Subtree **, uint32_t, const TSLanguage *);
|
||||
void ts_subtree_balance(const Subtree *, SubtreePool *, const TSLanguage *);
|
||||
const Subtree *ts_subtree_edit(const Subtree *, const TSInputEdit *edit, SubtreePool *);
|
||||
char *ts_subtree_string(const Subtree *, const TSLanguage *, bool include_all);
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ static inline ChildIterator ts_tree_cursor_iterate_children(const TreeCursor *se
|
|||
static inline bool ts_tree_cursor_child_iterator_next(ChildIterator *self,
|
||||
TreeCursorEntry *result,
|
||||
bool *visible) {
|
||||
if (self->child_index == self->parent->children.size) return false;
|
||||
const Subtree *child = self->parent->children.contents[self->child_index];
|
||||
if (self->child_index == self->parent->child_count) return false;
|
||||
const Subtree *child = self->parent->children[self->child_index];
|
||||
*result = (TreeCursorEntry) {
|
||||
.subtree = child,
|
||||
.position = self->position,
|
||||
|
|
@ -51,8 +51,8 @@ static inline bool ts_tree_cursor_child_iterator_next(ChildIterator *self,
|
|||
self->child_index++;
|
||||
if (!child->extra) self->structural_child_index++;
|
||||
|
||||
if (self->child_index < self->parent->children.size) {
|
||||
const Subtree *child = self->parent->children.contents[self->child_index];
|
||||
if (self->child_index < self->parent->child_count) {
|
||||
const Subtree *child = self->parent->children[self->child_index];
|
||||
self->position = length_add(self->position, child->padding);
|
||||
}
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ bool ts_tree_cursor_goto_first_child(TSTreeCursor *_self) {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (entry.subtree->children.size > 0 && entry.subtree->visible_child_count > 0) {
|
||||
if (entry.subtree->child_count > 0 && entry.subtree->visible_child_count > 0) {
|
||||
array_push(&self->stack, entry);
|
||||
did_descend = true;
|
||||
break;
|
||||
|
|
@ -130,7 +130,7 @@ int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *_self, uint32_t g
|
|||
while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
|
||||
uint32_t end_byte = entry.position.bytes + entry.subtree->size.bytes;
|
||||
bool at_goal = end_byte > goal_byte;
|
||||
uint32_t visible_child_count = entry.subtree->children.size > 0
|
||||
uint32_t visible_child_count = entry.subtree->child_count > 0
|
||||
? entry.subtree->visible_child_count
|
||||
: 0;
|
||||
|
||||
|
|
@ -183,7 +183,7 @@ bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *_self) {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (entry.subtree->children.size > 0 && entry.subtree->visible_child_count > 0) {
|
||||
if (entry.subtree->child_count > 0 && entry.subtree->visible_child_count > 0) {
|
||||
array_push(&self->stack, entry);
|
||||
ts_tree_cursor_goto_first_child(_self);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@
|
|||
#include "runtime/length.h"
|
||||
|
||||
void assert_consistent(const Subtree *tree) {
|
||||
if (tree->children.size == 0) return;
|
||||
AssertThat(tree->children.contents[0]->padding, Equals<Length>(tree->padding));
|
||||
if (tree->child_count == 0) return;
|
||||
AssertThat(tree->children[0]->padding, Equals<Length>(tree->padding));
|
||||
|
||||
Length total_children_size = length_zero();
|
||||
for (size_t i = 0; i < tree->children.size; i++) {
|
||||
const Subtree *child = tree->children.contents[i];
|
||||
for (size_t i = 0; i < tree->child_count; i++) {
|
||||
const Subtree *child = tree->children[i];
|
||||
assert_consistent(child);
|
||||
total_children_size = length_add(total_children_size, ts_subtree_total_size(child));
|
||||
}
|
||||
|
|
@ -217,13 +217,13 @@ describe("Subtree", []() {
|
|||
AssertThat(tree->padding, Equals<Length>({2, {0, 2}}));
|
||||
AssertThat(tree->size, Equals<Length>({13, {0, 13}}));
|
||||
|
||||
AssertThat(tree->children.contents[0]->has_changes, IsFalse());
|
||||
AssertThat(tree->children.contents[0]->padding, Equals<Length>({2, {0, 2}}));
|
||||
AssertThat(tree->children.contents[0]->size, Equals<Length>({3, {0, 3}}));
|
||||
AssertThat(tree->children[0]->has_changes, IsFalse());
|
||||
AssertThat(tree->children[0]->padding, Equals<Length>({2, {0, 2}}));
|
||||
AssertThat(tree->children[0]->size, Equals<Length>({3, {0, 3}}));
|
||||
|
||||
AssertThat(tree->children.contents[1]->has_changes, IsFalse());
|
||||
AssertThat(tree->children.contents[1]->padding, Equals<Length>({2, {0, 2}}));
|
||||
AssertThat(tree->children.contents[1]->size, Equals<Length>({3, {0, 3}}));
|
||||
AssertThat(tree->children[1]->has_changes, IsFalse());
|
||||
AssertThat(tree->children[1]->padding, Equals<Length>({2, {0, 2}}));
|
||||
AssertThat(tree->children[1]->size, Equals<Length>({3, {0, 3}}));
|
||||
|
||||
ts_subtree_release(&pool, new_tree);
|
||||
});
|
||||
|
|
@ -245,13 +245,13 @@ describe("Subtree", []() {
|
|||
AssertThat(tree->padding, Equals<Length>({3, {0, 3}}));
|
||||
AssertThat(tree->size, Equals<Length>({13, {0, 13}}));
|
||||
|
||||
AssertThat(tree->children.contents[0]->has_changes, IsTrue());
|
||||
AssertThat(tree->children.contents[0]->padding, Equals<Length>({3, {0, 3}}));
|
||||
AssertThat(tree->children.contents[0]->size, Equals<Length>({3, {0, 3}}));
|
||||
AssertThat(tree->children[0]->has_changes, IsTrue());
|
||||
AssertThat(tree->children[0]->padding, Equals<Length>({3, {0, 3}}));
|
||||
AssertThat(tree->children[0]->size, Equals<Length>({3, {0, 3}}));
|
||||
|
||||
AssertThat(tree->children.contents[1]->has_changes, IsFalse());
|
||||
AssertThat(tree->children.contents[1]->padding, Equals<Length>({2, {0, 2}}));
|
||||
AssertThat(tree->children.contents[1]->size, Equals<Length>({3, {0, 3}}));
|
||||
AssertThat(tree->children[1]->has_changes, IsFalse());
|
||||
AssertThat(tree->children[1]->padding, Equals<Length>({2, {0, 2}}));
|
||||
AssertThat(tree->children[1]->size, Equals<Length>({3, {0, 3}}));
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -272,9 +272,9 @@ describe("Subtree", []() {
|
|||
AssertThat(tree->padding, Equals<Length>({5, {0, 5}}));
|
||||
AssertThat(tree->size, Equals<Length>({11, {0, 11}}));
|
||||
|
||||
AssertThat(tree->children.contents[0]->has_changes, IsTrue());
|
||||
AssertThat(tree->children.contents[0]->padding, Equals<Length>({5, {0, 5}}));
|
||||
AssertThat(tree->children.contents[0]->size, Equals<Length>({1, {0, 1}}));
|
||||
AssertThat(tree->children[0]->has_changes, IsTrue());
|
||||
AssertThat(tree->children[0]->padding, Equals<Length>({5, {0, 5}}));
|
||||
AssertThat(tree->children[0]->size, Equals<Length>({1, {0, 1}}));
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -295,11 +295,11 @@ describe("Subtree", []() {
|
|||
AssertThat(tree->padding, Equals<Length>({4, {0, 4}}));
|
||||
AssertThat(tree->size, Equals<Length>({13, {0, 13}}));
|
||||
|
||||
AssertThat(tree->children.contents[0]->has_changes, IsTrue());
|
||||
AssertThat(tree->children.contents[0]->padding, Equals<Length>({4, {0, 4}}));
|
||||
AssertThat(tree->children.contents[0]->size, Equals<Length>({3, {0, 3}}));
|
||||
AssertThat(tree->children[0]->has_changes, IsTrue());
|
||||
AssertThat(tree->children[0]->padding, Equals<Length>({4, {0, 4}}));
|
||||
AssertThat(tree->children[0]->size, Equals<Length>({3, {0, 3}}));
|
||||
|
||||
AssertThat(tree->children.contents[1]->has_changes, IsFalse());
|
||||
AssertThat(tree->children[1]->has_changes, IsFalse());
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -320,11 +320,11 @@ describe("Subtree", []() {
|
|||
AssertThat(tree->padding, Equals<Length>({2, {0, 2}}));
|
||||
AssertThat(tree->size, Equals<Length>({16, {0, 16}}));
|
||||
|
||||
AssertThat(tree->children.contents[0]->has_changes, IsTrue());
|
||||
AssertThat(tree->children.contents[0]->padding, Equals<Length>({2, {0, 2}}));
|
||||
AssertThat(tree->children.contents[0]->size, Equals<Length>({6, {0, 6}}));
|
||||
AssertThat(tree->children[0]->has_changes, IsTrue());
|
||||
AssertThat(tree->children[0]->padding, Equals<Length>({2, {0, 2}}));
|
||||
AssertThat(tree->children[0]->size, Equals<Length>({6, {0, 6}}));
|
||||
|
||||
AssertThat(tree->children.contents[1]->has_changes, IsFalse());
|
||||
AssertThat(tree->children[1]->has_changes, IsFalse());
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -345,23 +345,23 @@ describe("Subtree", []() {
|
|||
AssertThat(tree->padding, Equals<Length>({4, {0, 4}}));
|
||||
AssertThat(tree->size, Equals<Length>({4, {0, 4}}));
|
||||
|
||||
AssertThat(tree->children.contents[0]->has_changes, IsTrue());
|
||||
AssertThat(tree->children.contents[0]->padding, Equals<Length>({4, {0, 4}}));
|
||||
AssertThat(tree->children.contents[0]->size, Equals<Length>({0, {0, 0}}));
|
||||
AssertThat(tree->children[0]->has_changes, IsTrue());
|
||||
AssertThat(tree->children[0]->padding, Equals<Length>({4, {0, 4}}));
|
||||
AssertThat(tree->children[0]->size, Equals<Length>({0, {0, 0}}));
|
||||
|
||||
AssertThat(tree->children.contents[1]->has_changes, IsTrue());
|
||||
AssertThat(tree->children.contents[1]->padding, Equals<Length>({0, {0, 0}}));
|
||||
AssertThat(tree->children.contents[1]->size, Equals<Length>({0, {0, 0}}));
|
||||
AssertThat(tree->children[1]->has_changes, IsTrue());
|
||||
AssertThat(tree->children[1]->padding, Equals<Length>({0, {0, 0}}));
|
||||
AssertThat(tree->children[1]->size, Equals<Length>({0, {0, 0}}));
|
||||
|
||||
AssertThat(tree->children.contents[2]->has_changes, IsTrue());
|
||||
AssertThat(tree->children.contents[2]->padding, Equals<Length>({1, {0, 1}}));
|
||||
AssertThat(tree->children.contents[2]->size, Equals<Length>({3, {0, 3}}));
|
||||
AssertThat(tree->children[2]->has_changes, IsTrue());
|
||||
AssertThat(tree->children[2]->padding, Equals<Length>({1, {0, 1}}));
|
||||
AssertThat(tree->children[2]->size, Equals<Length>({3, {0, 3}}));
|
||||
});
|
||||
});
|
||||
|
||||
describe("edits within a tree's range of scanned bytes", [&]() {
|
||||
it("marks preceding trees as changed", [&]() {
|
||||
Subtree *mutable_child = (Subtree *)tree->children.contents[0];
|
||||
Subtree *mutable_child = (Subtree *)tree->children[0];
|
||||
mutable_child->bytes_scanned = 7;
|
||||
|
||||
TSInputEdit edit;
|
||||
|
|
@ -375,7 +375,7 @@ describe("Subtree", []() {
|
|||
tree = ts_subtree_edit(tree, &edit, &pool);
|
||||
assert_consistent(tree);
|
||||
|
||||
AssertThat(tree->children.contents[0]->has_changes, IsTrue());
|
||||
AssertThat(tree->children[0]->has_changes, IsTrue());
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -393,8 +393,8 @@ describe("Subtree", []() {
|
|||
assert_consistent(tree);
|
||||
|
||||
AssertThat(tree->size.bytes, Equals(14u));
|
||||
AssertThat(tree->children.contents[2]->has_changes, IsTrue());
|
||||
AssertThat(tree->children.contents[2]->size.bytes, Equals(4u));
|
||||
AssertThat(tree->children[2]->has_changes, IsTrue());
|
||||
AssertThat(tree->children[2]->size.bytes, Equals(4u));
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -412,7 +412,7 @@ describe("Subtree", []() {
|
|||
assert_consistent(tree);
|
||||
|
||||
AssertThat(tree->size.bytes, Equals(13u));
|
||||
AssertThat(tree->children.contents[2]->size.bytes, Equals(3u));
|
||||
AssertThat(tree->children[2]->size.bytes, Equals(3u));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue