Don't store tree's hidden children in a separate array

Just mark hidden trees as such, and skip them when
pretty-printing a tree
This commit is contained in:
Max Brunsfeld 2014-07-16 18:38:06 -07:00
parent 95fbdb6fdb
commit 779bf0d745
17 changed files with 167 additions and 243 deletions

View file

@ -52,62 +52,32 @@ size_t ts_stack_right_position(const TSStack *stack) {
}
TSTree * ts_stack_reduce(TSStack *stack,
TSSymbol symbol,
size_t immediate_child_count,
const int *hidden_symbol_flags,
int gather_extra) {
TSSymbol symbol,
size_t child_count,
const int *hidden_symbol_flags,
int dont_count_extras) {
// First, walk down the stack to determine which symbols will be reduced.
// The child node count is known ahead of time, but some of the
// nodes at the top of the stack might be hidden nodes, in which
// case we 'collapse' them. Some may also be extra tokens,
// which don't count towards the child node count.
static int collapse_flags[100];
int child_count = 0;
for (size_t i = 0; i < immediate_child_count; i++) {
size_t stack_index = stack->size - 1 - i;
TSTree *child = stack->entries[stack_index].node;
size_t grandchild_count;
TSTree **grandchildren = ts_tree_children(child, &grandchild_count);
TSSymbol child_symbol = child->symbol;
collapse_flags[i] = (
hidden_symbol_flags[child_symbol] ||
(grandchild_count == 1 && child->size == grandchildren[0]->size)
);
child_count += collapse_flags[i] ? grandchild_count : 1;
if (gather_extra && child->is_extra)
immediate_child_count++;
}
// Walk down the stack again, building up the array of children.
// Though we collapse the hidden child nodes, we also need to
// keep track of the actual immediate children so that we can
// later collapse the stack again when the document is edited.
// We store the children and immediate children in the same array,
// to reduce allocations.
size_t child_index = child_count;
TSTree **children = malloc((child_count + immediate_child_count) * sizeof(TSTree *));
TSTree **immediate_children = children + child_count;
for (size_t i = 0; i < immediate_child_count; i++) {
// The child node count is known ahead of time, but some children may be
// extra tokens, which don't count towards the child node count.
for (size_t i = 0; i < child_count; i++) {
TSTree *child = stack->entries[stack->size - 1 - i].node;
immediate_children[immediate_child_count - 1 - i] = child;
if (collapse_flags[i]) {
size_t grandchild_count;
TSTree **grandchildren = ts_tree_children(child, &grandchild_count);
child_index -= grandchild_count;
memcpy(children + child_index, grandchildren, (grandchild_count * sizeof(TSTree *)));
} else {
child_index--;
children[child_index] = child;
}
if (dont_count_extras && ts_tree_is_extra(child))
child_count++;
}
TSTree *lookahead = ts_tree_make_node(symbol, child_count, immediate_child_count, children);
ts_stack_shrink(stack, stack->size - immediate_child_count);
size_t start_index = stack->size - child_count;
TSTree **children = calloc(child_count, sizeof(TSTree *));
for (size_t i = 0; i < child_count; i++)
children[i] = stack->entries[start_index + i].node;
TSTree *lookahead = ts_tree_make_node(
symbol,
child_count,
children,
hidden_symbol_flags[symbol]
);
ts_stack_shrink(stack, stack->size - child_count);
return lookahead;
}