Clean up stack

This commit is contained in:
Max Brunsfeld 2016-02-25 21:46:13 -08:00
parent 1850951b4f
commit 5a34d74702
5 changed files with 117 additions and 116 deletions

View file

@ -102,7 +102,7 @@ describe("Stack", [&]() {
/*
* . <--0-- A*
*/
ts_stack_push(stack, 0, stateA, trees[0]);
ts_stack_push(stack, 0, trees[0], stateA);
const StackEntry *entry1 = ts_stack_head(stack, 0);
AssertThat(*entry1, Equals<StackEntry>({stateA, tree_len}));
AssertThat(ts_stack_entry_next_count(entry1), Equals(1));
@ -111,7 +111,7 @@ describe("Stack", [&]() {
/*
* . <--0-- A <--1-- B*
*/
ts_stack_push(stack, 0, stateB, trees[1]);
ts_stack_push(stack, 0, trees[1], stateB);
const StackEntry *entry2 = ts_stack_head(stack, 0);
AssertThat(*entry2, Equals<StackEntry>({stateB, tree_len * 2}));
AssertThat(ts_stack_entry_next_count(entry2), Equals(1));
@ -120,7 +120,7 @@ describe("Stack", [&]() {
/*
* . <--0-- A <--1-- B <--2-- C*
*/
ts_stack_push(stack, 0, stateC, trees[2]);
ts_stack_push(stack, 0, trees[2], stateC);
const StackEntry *entry3 = ts_stack_head(stack, 0);
AssertThat(*entry3, Equals<StackEntry>({stateC, tree_len * 3}));
AssertThat(ts_stack_entry_next_count(entry3), Equals(1));
@ -133,9 +133,9 @@ describe("Stack", [&]() {
/*
* . <--0-- A <--1-- B <--2-- C*
*/
ts_stack_push(stack, 0, stateA, trees[0]);
ts_stack_push(stack, 0, stateB, trees[1]);
ts_stack_push(stack, 0, stateC, trees[2]);
ts_stack_push(stack, 0, trees[0], stateA);
ts_stack_push(stack, 0, trees[1], stateB);
ts_stack_push(stack, 0, trees[2], stateC);
});
it("removes the given number of nodes from the stack", [&]() {
@ -198,9 +198,9 @@ describe("Stack", [&]() {
/*
* . <--0-- A <--1-- B <--2-- C*
*/
ts_stack_push(stack, 0, stateA, trees[0]);
ts_stack_push(stack, 0, stateB, trees[1]);
ts_stack_push(stack, 0, stateC, trees[2]);
ts_stack_push(stack, 0, trees[0], stateA);
ts_stack_push(stack, 0, trees[1], stateB);
ts_stack_push(stack, 0, trees[2], stateC);
/*
* . <--0-- A <--1-- B <--2-- C*
@ -217,7 +217,7 @@ describe("Stack", [&]() {
*
* `-*
*/
ts_stack_push(stack, 0, stateD, trees[3]);
ts_stack_push(stack, 0, trees[3], stateD);
StackPopResultArray pop_results = ts_stack_pop(stack, 1, 1, false);
AssertThat(ts_stack_head_count(stack), Equals(2));
@ -233,8 +233,8 @@ describe("Stack", [&]() {
*
* `---4--- E <--5-- F*
*/
ts_stack_push(stack, 1, stateE, trees[4]);
ts_stack_push(stack, 1, stateF, trees[5]);
ts_stack_push(stack, 1, trees[4], stateE);
ts_stack_push(stack, 1, trees[5], stateF);
AssertThat(ts_stack_head_count(stack), Equals(2));
AssertThat(*ts_stack_head(stack, 0), Equals<StackEntry>({stateD, tree_len * 4}));
@ -249,13 +249,13 @@ describe("Stack", [&]() {
*
* `---4--- E <--5-- F*
*/
ts_stack_push(stack, 0, stateA, trees[0]);
ts_stack_push(stack, 0, stateB, trees[1]);
ts_stack_push(stack, 0, trees[0], stateA);
ts_stack_push(stack, 0, trees[1], stateB);
ts_stack_split(stack, 0);
ts_stack_push(stack, 0, stateC, trees[2]);
ts_stack_push(stack, 0, stateD, trees[3]);
ts_stack_push(stack, 1, stateE, trees[4]);
ts_stack_push(stack, 1, stateF, trees[5]);
ts_stack_push(stack, 0, trees[2], stateC);
ts_stack_push(stack, 0, trees[3], stateD);
ts_stack_push(stack, 1, trees[4], stateE);
ts_stack_push(stack, 1, trees[5], stateF);
AssertThat(ts_stack_head_count(stack), Equals(2));
AssertThat(*ts_stack_head(stack, 0), Equals<StackEntry>({stateD, tree_len * 4}));
@ -268,8 +268,8 @@ describe("Stack", [&]() {
* ^ |
* `---4--- E <--5-- F <--7---'
*/
AssertThat(ts_stack_push(stack, 0, stateG, trees[6]), Equals(StackPushResultContinued));
AssertThat(ts_stack_push(stack, 1, stateG, trees[7]), Equals(StackPushResultMerged));
AssertThat(ts_stack_push(stack, 0, trees[6], stateG), Equals(StackPushResultContinued));
AssertThat(ts_stack_push(stack, 1, trees[7], stateG), Equals(StackPushResultMerged));
AssertThat(ts_stack_head_count(stack), Equals(1));
const StackEntry *entry1 = ts_stack_head(stack, 0);
@ -286,16 +286,16 @@ describe("Stack", [&]() {
*
* `---4--- E <--5-- F <--8-- G*
*/
AssertThat(ts_stack_push(stack, 0, stateG, trees[6]), Equals(StackPushResultContinued));
AssertThat(ts_stack_push(stack, 0, stateH, trees[7]), Equals(StackPushResultContinued));
AssertThat(ts_stack_push(stack, 1, stateG, trees[6]), Equals(StackPushResultContinued));
AssertThat(ts_stack_push(stack, 0, trees[6], stateG), Equals(StackPushResultContinued));
AssertThat(ts_stack_push(stack, 0, trees[7], stateH), Equals(StackPushResultContinued));
AssertThat(ts_stack_push(stack, 1, trees[6], stateG), Equals(StackPushResultContinued));
/*
* . <--0-- A <--1-- B <--2-- C <--3-- D <--6-- G <--7--H*
* |
* `---4--- E <--5-- F <--8---'
*/
AssertThat(ts_stack_push(stack, 1, stateH, trees[7]), Equals(StackPushResultMerged));
AssertThat(ts_stack_push(stack, 1, trees[7], stateH), Equals(StackPushResultMerged));
AssertThat(ts_stack_head_count(stack), Equals(1));
StackEntry *head = ts_stack_head(stack, 0);
@ -321,9 +321,9 @@ describe("Stack", [&]() {
*/
ts_stack_clear(stack);
ts_stack_split(stack, 0);
AssertThat(ts_stack_push(stack, 0, stateC, parent), Equals(StackPushResultContinued));
AssertThat(ts_stack_push(stack, 1, stateB, trees[2]), Equals(StackPushResultContinued));
AssertThat(ts_stack_push(stack, 1, stateC, trees[3]), Equals(StackPushResultMerged));
AssertThat(ts_stack_push(stack, 0, parent, stateC), Equals(StackPushResultContinued));
AssertThat(ts_stack_push(stack, 1, trees[2], stateB), Equals(StackPushResultContinued));
AssertThat(ts_stack_push(stack, 1, trees[3], stateC), Equals(StackPushResultMerged));
AssertThat(ts_stack_head_count(stack), Equals(1));
StackEntry *head = ts_stack_head(stack, 0);
@ -345,15 +345,15 @@ describe("Stack", [&]() {
* ^ |
* `---5--- F <--6-- G <--7---'
*/
ts_stack_push(stack, 0, stateA, trees[0]);
ts_stack_push(stack, 0, stateB, trees[1]);
ts_stack_push(stack, 0, trees[0], stateA);
ts_stack_push(stack, 0, trees[1], stateB);
ts_stack_split(stack, 0);
ts_stack_push(stack, 0, stateC, trees[2]);
ts_stack_push(stack, 0, stateD, trees[3]);
ts_stack_push(stack, 0, stateE, trees[4]);
ts_stack_push(stack, 1, stateF, trees[5]);
ts_stack_push(stack, 1, stateG, trees[6]);
ts_stack_push(stack, 1, stateE, trees[7]);
ts_stack_push(stack, 0, trees[2], stateC);
ts_stack_push(stack, 0, trees[3], stateD);
ts_stack_push(stack, 0, trees[4], stateE);
ts_stack_push(stack, 1, trees[5], stateF);
ts_stack_push(stack, 1, trees[6], stateG);
ts_stack_push(stack, 1, trees[7], stateE);
AssertThat(ts_stack_head_count(stack), Equals(1));
AssertThat(ts_stack_top_state(stack, 0), Equals(stateE));
@ -395,7 +395,7 @@ describe("Stack", [&]() {
* ^ |
* `---5--- F <--6-- G <--7---'
*/
AssertThat(ts_stack_push(stack, 0, stateH, trees[8]), Equals(StackPushResultContinued));
AssertThat(ts_stack_push(stack, 0, trees[8], stateH), Equals(StackPushResultContinued));
AssertThat(ts_stack_head_count(stack), Equals(1));
AssertThat(ts_stack_top_state(stack, 0), Equals(stateH));
@ -470,21 +470,21 @@ describe("Stack", [&]() {
* `---7--- G <--8-- H <--9---'
*/
ts_stack_clear(stack);
ts_stack_push(stack, 0, stateA, trees[0]);
ts_stack_push(stack, 0, trees[0], stateA);
ts_stack_split(stack, 0);
ts_stack_split(stack, 1);
ts_stack_push(stack, 0, stateB, trees[1]);
ts_stack_push(stack, 0, stateC, trees[2]);
ts_stack_push(stack, 0, stateD, trees[3]);
ts_stack_push(stack, 1, stateE, trees[4]);
ts_stack_push(stack, 1, stateF, trees[5]);
ts_stack_push(stack, 1, stateD, trees[6]);
ts_stack_push(stack, 1, stateG, trees[7]);
ts_stack_push(stack, 1, stateH, trees[8]);
ts_stack_push(stack, 1, stateD, trees[9]);
ts_stack_push(stack, 0, trees[1], stateB);
ts_stack_push(stack, 0, trees[2], stateC);
ts_stack_push(stack, 0, trees[3], stateD);
ts_stack_push(stack, 1, trees[4], stateE);
ts_stack_push(stack, 1, trees[5], stateF);
ts_stack_push(stack, 1, trees[6], stateD);
ts_stack_push(stack, 1, trees[7], stateG);
ts_stack_push(stack, 1, trees[8], stateH);
ts_stack_push(stack, 1, trees[9], stateD);
AssertThat(ts_stack_head_count(stack), Equals(1));
AssertThat(ts_stack_entry_next_count(ts_stack_head(stack, 0)), Equals(3));
ts_stack_push(stack, 0, stateI, trees[10]);
ts_stack_push(stack, 0, trees[10], stateI);
AssertThat(ts_stack_entry_next_count(ts_stack_head(stack, 0)), Equals(1));
});

View file

@ -38,8 +38,8 @@ extern "C" {
#define array_delete(self) array__delete((VoidArray *)self)
#define array_push(self, element) \
(((self)->size < (self)->capacity || \
#define array_push(self, element) \
(((self)->size < (self)->capacity || \
array_grow((self), (self)->capacity ? (self)->capacity * 2 : 4)) && \
((self)->contents[(self)->size++] = (element), true))

View file

@ -94,14 +94,14 @@ static ParseActionResult ts_parser__breakdown_top_of_stack(TSParser *self,
LOG("breakdown_push sym:%s, size:%lu", SYM_NAME(last_child->symbol),
ts_tree_total_size(last_child).chars);
last_push = ts_stack_push(self->stack, head_index, state, last_child);
last_push = ts_stack_push(self->stack, head_index, last_child, state);
if (last_push == StackPushResultFailed)
goto error;
}
for (size_t j = 1, count = pop_result.trees.size; j < count; j++) {
TSTree *tree = pop_result.trees.contents[j];
last_push = ts_stack_push(self->stack, head_index, state, tree);
last_push = ts_stack_push(self->stack, head_index, tree, state);
if (last_push == StackPushResultFailed)
goto error;
}
@ -286,7 +286,7 @@ static int ts_parser__select_tree(void *data, TSTree *left, TSTree *right) {
static ParseActionResult ts_parser__shift(TSParser *self, int head,
TSStateId parse_state,
TSTree *lookahead) {
switch (ts_stack_push(self->stack, head, parse_state, lookahead)) {
switch (ts_stack_push(self->stack, head, lookahead, parse_state)) {
case StackPushResultFailed:
return FailedToUpdateStackHead;
case StackPushResultMerged:
@ -348,8 +348,8 @@ static ParseActionResult ts_parser__reduce(TSParser *self, int head,
}
size_t popped_child_count = pop_result.trees.size - trailing_extra_count;
parent = ts_tree_make_node(symbol, popped_child_count, pop_result.trees.contents,
metadata);
parent = ts_tree_make_node(symbol, popped_child_count,
pop_result.trees.contents, metadata);
if (!parent) {
for (size_t i = 0; i < pop_result.trees.size; i++)
ts_tree_release(pop_result.trees.contents[i]);
@ -409,7 +409,7 @@ static ParseActionResult ts_parser__reduce(TSParser *self, int head,
* If the given state already existed at a different head of the stack,
* then remove the lookahead state for the head.
*/
switch (ts_stack_push(self->stack, new_head, state, parent)) {
switch (ts_stack_push(self->stack, new_head, parent, state)) {
case StackPushResultFailed:
ts_tree_release(parent);
goto error;
@ -426,7 +426,7 @@ static ParseActionResult ts_parser__reduce(TSParser *self, int head,
for (size_t j = 0; j < trailing_extra_count; j++) {
size_t index = pop_result.trees.size - trailing_extra_count + j;
TSTree *tree = pop_result.trees.contents[index];
switch (ts_stack_push(self->stack, new_head, state, tree)) {
switch (ts_stack_push(self->stack, new_head, tree, state)) {
case StackPushResultFailed:
return FailedToUpdateStackHead;
case StackPushResultMerged:
@ -812,8 +812,8 @@ TSTree *ts_parser_parse(TSParser *self, TSInput input, TSTree *previous_tree) {
return NULL;
}
LOG("lookahead sym:(%s,%d), size:%lu", SYM_NAME(lookahead->symbol), lookahead->symbol,
ts_tree_total_chars(lookahead));
LOG("lookahead sym:(%s,%d), size:%lu", SYM_NAME(lookahead->symbol),
lookahead->symbol, ts_tree_total_chars(lookahead));
switch (ts_parser__consume_lookahead(self, head, lookahead)) {
case FailedToUpdateStackHead:

View file

@ -33,11 +33,13 @@ typedef struct {
bool is_shared;
} PopPath;
typedef Array(StackNode *) StackNodeArray;
struct Stack {
Array(StackNode *) heads;
StackPopResultArray pop_results;
Array(PopPath) pop_paths;
Array(StackNode *) node_pool;
StackNodeArray node_pool;
void *tree_selection_payload;
TreeSelectionFunction tree_selection_function;
};
@ -97,18 +99,18 @@ error:
* Section: Reading from the stack
*/
TSStateId ts_stack_top_state(const Stack *self, int head) {
StackEntry *entry = ts_stack_head((Stack *)self, head);
TSStateId ts_stack_top_state(const Stack *self, int head_index) {
StackEntry *entry = ts_stack_head((Stack *)self, head_index);
return entry ? entry->state : 0;
}
TSLength ts_stack_top_position(const Stack *self, int head) {
StackEntry *entry = ts_stack_head((Stack *)self, head);
TSLength ts_stack_top_position(const Stack *self, int head_index) {
StackEntry *entry = ts_stack_head((Stack *)self, head_index);
return entry ? entry->position : ts_length_zero();
}
StackEntry *ts_stack_head(Stack *self, int head) {
StackNode *node = self->heads.contents[head];
StackEntry *ts_stack_head(Stack *self, int head_index) {
StackNode *node = self->heads.contents[head_index];
return node ? &node->entry : NULL;
}
@ -120,8 +122,8 @@ int ts_stack_entry_next_count(const StackEntry *entry) {
return ((const StackNode *)entry)->successor_count;
}
StackEntry *ts_stack_entry_next(const StackEntry *entry, int i) {
return &((const StackNode *)entry)->successors[i].node->entry;
StackEntry *ts_stack_entry_next(const StackEntry *entry, int successor_index) {
return &((const StackNode *)entry)->successors[successor_index].node->entry;
}
/*
@ -135,38 +137,34 @@ static void stack_node_retain(StackNode *self) {
self->ref_count++;
}
static bool stack_node_release(Stack *self, StackNode *node) {
if (!node)
return false;
assert(node->ref_count != 0);
node->ref_count--;
if (node->ref_count == 0) {
for (int i = 0; i < node->successor_count; i++) {
stack_node_release(self, node->successors[i].node);
ts_tree_release(node->successors[i].tree);
static void stack_node_release(StackNode *self, StackNodeArray *pool) {
if (!self)
return;
assert(self->ref_count != 0);
self->ref_count--;
if (self->ref_count == 0) {
for (int i = 0; i < self->successor_count; i++) {
stack_node_release(self->successors[i].node, pool);
ts_tree_release(self->successors[i].tree);
}
if (self->node_pool.size >= MAX_NODE_POOL_SIZE)
ts_free(node);
if (pool->size >= MAX_NODE_POOL_SIZE)
ts_free(self);
else
array_push(&self->node_pool, node);
return true;
} else {
return false;
array_push(pool, self);
}
}
static StackNode *stack_node_new(Stack *self, StackNode *next, TSStateId state,
TSTree *tree) {
static StackNode *stack_node_new(StackNode *next, TSTree *tree, TSStateId state,
StackNodeArray *pool) {
assert(tree->ref_count > 0);
StackNode *node;
if (self->node_pool.size == 0) {
if (pool->size == 0) {
node = ts_malloc(sizeof(StackNode));
if (!node)
return NULL;
} else {
node = array_pop(&self->node_pool);
node = array_pop(pool);
}
ts_tree_retain(tree);
@ -177,7 +175,7 @@ static StackNode *stack_node_new(Stack *self, StackNode *next, TSStateId state,
*node = (StackNode){
.ref_count = 1,
.successor_count = 1,
.successors = { {next, tree} },
.successors = { { next, tree } },
.entry = {.state = state, .position = position },
};
return node;
@ -219,8 +217,7 @@ static void ts_stack__add_alternative_pop_result(Stack *self,
}
}
static void stack_node__add_successor(StackNode *self,
TSTree *new_tree,
static void stack_node__add_successor(StackNode *self, TSTree *new_tree,
StackNode *new_node) {
for (int i = 0; i < self->successor_count; i++) {
StackLink successor = self->successors[i];
@ -230,8 +227,8 @@ static void stack_node__add_successor(StackNode *self,
if (successor.node && new_node &&
successor.node->entry.state == new_node->entry.state) {
for (int j = 0; j < new_node->successor_count; j++) {
stack_node__add_successor(successor.node,
new_node->successors[j].tree, new_node->successors[j].node);
stack_node__add_successor(successor.node, new_node->successors[j].tree,
new_node->successors[j].node);
}
return;
}
@ -241,8 +238,7 @@ static void stack_node__add_successor(StackNode *self,
stack_node_retain(new_node);
ts_tree_retain(new_tree);
self->successors[self->successor_count++] = (StackLink){
new_node,
new_tree,
new_node, new_tree,
};
}
@ -269,7 +265,7 @@ static int ts_stack__find_head(Stack *self, StackNode *node) {
void ts_stack_remove_head(Stack *self, int head_index) {
StackNode *node = *array_get(&self->heads, head_index);
stack_node_release(self, node);
stack_node_release(node, &self->node_pool);
array_erase(&self->heads, head_index);
}
@ -277,8 +273,8 @@ void ts_stack_remove_head(Stack *self, int head_index) {
* Section: Mutating the stack (Public)
*/
StackPushResult ts_stack_push(Stack *self, int head_index, TSStateId state,
TSTree *tree) {
StackPushResult ts_stack_push(Stack *self, int head_index, TSTree *tree,
TSStateId state) {
TSLength position = ts_tree_total_size(tree);
StackNode *current_head = *array_get(&self->heads, head_index);
if (current_head)
@ -295,11 +291,12 @@ StackPushResult ts_stack_push(Stack *self, int head_index, TSStateId state,
}
}
StackNode *new_head = stack_node_new(self, current_head, state, tree);
StackNode *new_head =
stack_node_new(current_head, tree, state, &self->node_pool);
if (!new_head)
return StackPushResultFailed;
stack_node_release(self, current_head);
stack_node_release(current_head, &self->node_pool);
self->heads.contents[head_index] = new_head;
return StackPushResultContinued;
}
@ -374,7 +371,8 @@ StackPopResultArray ts_stack_pop(Stack *self, int head_index, int child_count,
goto error;
/*
* Children that are 'extra' do not count towards the total child count.
* Children that are 'extra' do not count towards the total child
* count.
*/
if (successor.tree->extra && !count_extra)
next_path->goal_tree_count++;
@ -421,7 +419,7 @@ StackPopResultArray ts_stack_pop(Stack *self, int head_index, int child_count,
goto error;
}
stack_node_release(self, previous_head);
stack_node_release(previous_head, &self->node_pool);
return self->pop_results;
error:
@ -440,13 +438,13 @@ void ts_stack_shrink(Stack *self, int head_index, int count) {
new_head = new_head->successors[0].node;
}
stack_node_retain(new_head);
stack_node_release(self, head);
stack_node_release(head, &self->node_pool);
self->heads.contents[head_index] = new_head;
}
void ts_stack_clear(Stack *self) {
for (size_t i = 0; i < self->heads.size; i++)
stack_node_release(self, self->heads.contents[i]);
stack_node_release(self->heads.contents[i], &self->node_pool);
array_clear(&self->heads);
array_push(&self->heads, NULL);
}
@ -485,7 +483,7 @@ size_t ts_stack__write_dot_graph(Stack *self, char *string, size_t n,
cursor += snprintf(*s, n, "digraph stack {\n");
cursor += snprintf(*s, n, "rankdir=\"RL\";\n");
Array(StackNode *) visited_nodes;
Array(StackNode *)visited_nodes;
array_init(&visited_nodes);
array_clear(&self->pop_paths);
@ -493,7 +491,7 @@ size_t ts_stack__write_dot_graph(Stack *self, char *string, size_t n,
StackNode *node = self->heads.contents[i];
const char *color = COLORS[i % COLOR_COUNT];
cursor += snprintf(*s, n, "node_%p [color=%s];\n", node, color);
array_push(&self->pop_paths, ((PopPath){ .node = node }));
array_push(&self->pop_paths, ((PopPath){.node = node }));
}
bool all_paths_done = false;
@ -515,11 +513,13 @@ size_t ts_stack__write_dot_graph(Stack *self, char *string, size_t n,
continue;
all_paths_done = false;
cursor += snprintf(*s, n, "node_%p [label=%d];\n", node, node->entry.state);
cursor +=
snprintf(*s, n, "node_%p [label=%d];\n", node, node->entry.state);
for (int j = 0; j < node->successor_count; j++) {
StackLink successor = node->successors[j];
cursor += snprintf(*s, n, "node_%p -> node_%p [label=\"", node, successor.node);
cursor +=
snprintf(*s, n, "node_%p -> node_%p [label=\"", node, successor.node);
const char *name = symbol_names[successor.tree->symbol];
for (const char *c = name; *c; c++) {

View file

@ -50,18 +50,18 @@ int ts_stack_head_count(const Stack *);
* Get the state at given head of the stack. If the stack is empty, this
* returns the initial state (0).
*/
TSStateId ts_stack_top_state(const Stack *, int head);
TSStateId ts_stack_top_state(const Stack *, int head_index);
/*
* Get the position of the given head of the stack. If the stack is empty, this
* returns {0, 0}.
*/
TSLength ts_stack_top_position(const Stack *, int head);
TSLength ts_stack_top_position(const Stack *, int head_index);
/*
* Get the entry at the given head of the stack.
*/
StackEntry *ts_stack_head(Stack *, int head);
StackEntry *ts_stack_head(Stack *, int head_index);
/*
* Get the number of successors for the parse stack entry.
@ -71,13 +71,13 @@ int ts_stack_entry_next_count(const StackEntry *);
/*
* Get the given successor for the parse stack entry.
*/
StackEntry *ts_stack_entry_next(const StackEntry *, int);
StackEntry *ts_stack_entry_next(const StackEntry *, int head_index);
/*
* Push a (tree, state) pair onto the given head of the stack. This could cause
* the head to merge with an existing head.
*/
StackPushResult ts_stack_push(Stack *, int head, TSStateId, TSTree *);
StackPushResult ts_stack_push(Stack *, int head_index, TSTree *, TSStateId);
/*
* Pop the given number of entries from the given head of the stack. This
@ -85,24 +85,25 @@ StackPushResult ts_stack_push(Stack *, int head, TSStateId, TSTree *);
* which had previously been merged. It returns a struct that indicates the
* index of each revealed head and the trees removed from that head.
*/
StackPopResultArray ts_stack_pop(Stack *, int head, int count, bool count_extra);
StackPopResultArray ts_stack_pop(Stack *, int head_index, int count,
bool count_extra);
/*
* Remove the given number of entries from the given head of the stack.
*/
void ts_stack_shrink(Stack *, int head, int count);
void ts_stack_shrink(Stack *, int head_index, int count);
/*
* Split the given stack head into two heads, so that the stack can be
* transformed from its current state in multiple alternative ways. Returns
* the index of the newly-created head.
*/
int ts_stack_split(Stack *, int head);
int ts_stack_split(Stack *, int head_index);
/*
* Remove the given head from the stack.
*/
void ts_stack_remove_head(Stack *, int head);
void ts_stack_remove_head(Stack *, int head_index);
/*
* Remove all entries from the stack.