diff --git a/spec/runtime/stack_spec.cc b/spec/runtime/stack_spec.cc index 34fec8d4..2a033c6c 100644 --- a/spec/runtime/stack_spec.cc +++ b/spec/runtime/stack_spec.cc @@ -37,13 +37,13 @@ int tree_selection_spy_callback(void *data, TSTree *left, TSTree *right) { return 1; } -void free_pop_results(Vector *pop_results) { +void free_pop_results(StackPopResultVector *pop_results) { for (size_t i = 0; i < pop_results->size; i++) { - StackPopResult *pop_result = (StackPopResult *)vector_get(pop_results, i); + StackPopResult *pop_result = &pop_results->contents[i]; bool matches_prior_trees = false; for (size_t j = 0; j < i; j++) { - StackPopResult *prior_result = (StackPopResult *)vector_get(pop_results, j); + StackPopResult *prior_result = &pop_results->contents[j]; if (pop_result->trees == prior_result->trees) { matches_prior_trees = true; break; @@ -141,10 +141,10 @@ describe("Stack", [&]() { /* * A0. */ - Vector results = ts_stack_pop(stack, 0, 2, false); + StackPopResultVector results = ts_stack_pop(stack, 0, 2, false); AssertThat(results.size, Equals(1)); - StackPopResult result = *(StackPopResult *)vector_get(&results, 0); + StackPopResult result = *vector_get(&results, 0); AssertThat(result.tree_count, Equals(2)); AssertThat(result.trees[0], Equals(trees[1])); AssertThat(result.trees[1], Equals(trees[2])); @@ -168,10 +168,10 @@ describe("Stack", [&]() { it("does not count 'extra' trees toward the count", [&]() { trees[1]->extra = true; - Vector results = ts_stack_pop(stack, 0, 2, false); + StackPopResultVector results = ts_stack_pop(stack, 0, 2, false); AssertThat(results.size, Equals(1)); - StackPopResult result = *(StackPopResult *)vector_get(&results, 0); + StackPopResult result = *vector_get(&results, 0); AssertThat(result.tree_count, Equals(3)); AssertThat(result.trees[0], Equals(trees[0])); AssertThat(result.trees[1], Equals(trees[1])); @@ -182,10 +182,10 @@ describe("Stack", [&]() { }); it("pops the entire stack when given a negative count", [&]() { - Vector results = ts_stack_pop(stack, 0, -1, false); + StackPopResultVector results = ts_stack_pop(stack, 0, -1, false); AssertThat(results.size, Equals(1)); - StackPopResult result = *(StackPopResult *)vector_get(&results, 0); + StackPopResult result = *vector_get(&results, 0); AssertThat(result.tree_count, Equals(3)); AssertThat(result.trees[0], Equals(trees[0])); AssertThat(result.trees[1], Equals(trees[1])); @@ -213,7 +213,7 @@ describe("Stack", [&]() { * \. */ ts_stack_push(stack, 0, stateD, trees[3]); - Vector pop_results = ts_stack_pop(stack, 1, 1, false); + StackPopResultVector pop_results = ts_stack_pop(stack, 1, 1, false); AssertThat(ts_stack_head_count(stack), Equals(2)); AssertThat(*ts_stack_head(stack, 0), Equals({trees[3], stateD, tree_len * 4})); @@ -381,16 +381,16 @@ describe("Stack", [&]() { * A0__B1__C2. * \__E4. */ - Vector pop = ts_stack_pop(stack, 0, 2, false); + StackPopResultVector results = ts_stack_pop(stack, 0, 2, false); - AssertThat(pop.size, Equals(2)); - StackPopResult pop1 = *(StackPopResult *)vector_get(&pop, 0); + AssertThat(results.size, Equals(2)); + StackPopResult pop1 = *(StackPopResult *)vector_get(&results, 0); AssertThat(pop1.head_index, Equals(0)); AssertThat(pop1.tree_count, Equals(2)); AssertThat(pop1.trees[0], Equals(trees[3])); AssertThat(pop1.trees[1], Equals(trees[6])); - StackPopResult pop2 = *(StackPopResult *)vector_get(&pop, 1); + StackPopResult pop2 = *(StackPopResult *)vector_get(&results, 1); AssertThat(pop2.head_index, Equals(1)); AssertThat(pop2.tree_count, Equals(2)); AssertThat(pop2.trees[0], Equals(trees[5])); @@ -400,7 +400,7 @@ describe("Stack", [&]() { AssertThat(*ts_stack_head(stack, 0), Equals({trees[2], stateC, tree_len * 3})); AssertThat(*ts_stack_head(stack, 1), Equals({trees[4], stateE, tree_len * 3})); - free_pop_results(&pop); + free_pop_results(&results); }); }); @@ -417,12 +417,12 @@ describe("Stack", [&]() { * A0__B1__C2__D3__G6. * \__E4__F5__/ */ - Vector pop = ts_stack_pop(stack, 0, 1, false); + StackPopResultVector results = ts_stack_pop(stack, 0, 1, false); - AssertThat(pop.size, Equals(1)); + AssertThat(results.size, Equals(1)); AssertThat(ts_stack_head_count(stack), Equals(1)); - free_pop_results(&pop); + free_pop_results(&results); }); }); @@ -439,23 +439,23 @@ describe("Stack", [&]() { * A0__B1__C2__D3. * \__E4__F5. */ - Vector pop = ts_stack_pop(stack, 0, 2, false); + StackPopResultVector results = ts_stack_pop(stack, 0, 2, false); AssertThat(ts_stack_head_count(stack), Equals(2)); - AssertThat(pop.size, Equals(2)); - StackPopResult pop1 = *(StackPopResult *)vector_get(&pop, 0); + AssertThat(results.size, Equals(2)); + StackPopResult pop1 = *(StackPopResult *)vector_get(&results, 0); AssertThat(pop1.head_index, Equals(0)); AssertThat(pop1.tree_count, Equals(2)); AssertThat(pop1.trees[0], Equals(trees[6])); AssertThat(pop1.trees[1], Equals(trees[7])); - StackPopResult pop2 = *(StackPopResult *)vector_get(&pop, 1); + StackPopResult pop2 = *(StackPopResult *)vector_get(&results, 1); AssertThat(pop2.head_index, Equals(1)); AssertThat(pop2.tree_count, Equals(2)); AssertThat(pop2.trees[0], Equals(trees[6])); AssertThat(pop2.trees[1], Equals(trees[7])); - free_pop_results(&pop); + free_pop_results(&results); }); }); @@ -467,17 +467,17 @@ describe("Stack", [&]() { /* * A0__B1. */ - Vector pop = ts_stack_pop(stack, 0, 3, false); + StackPopResultVector results = ts_stack_pop(stack, 0, 3, false); AssertThat(ts_stack_head_count(stack), Equals(1)); AssertThat(*ts_stack_head(stack, 0), Equals({trees[1], stateB, tree_len * 2})); - AssertThat(pop.size, Equals(1)); - StackPopResult pop1 = *(StackPopResult *)vector_get(&pop, 0); + AssertThat(results.size, Equals(1)); + StackPopResult pop1 = *(StackPopResult *)vector_get(&results, 0); AssertThat(pop1.tree_count, Equals(3)); AssertThat(pop1.head_index, Equals(0)); AssertThat(pop1.trees[0], Equals(trees[2])); - free_pop_results(&pop); + free_pop_results(&results); }); }); @@ -488,17 +488,17 @@ describe("Stack", [&]() { /* * A0__B1. */ - Vector pop = ts_stack_pop(stack, 0, 3, false); + StackPopResultVector results = ts_stack_pop(stack, 0, 3, false); AssertThat(ts_stack_head_count(stack), Equals(1)); AssertThat(*ts_stack_head(stack, 0), Equals({trees[1], stateB, tree_len * 2})); - AssertThat(pop.size, Equals(1)); - StackPopResult pop1 = *(StackPopResult *)vector_get(&pop, 0); + AssertThat(results.size, Equals(1)); + StackPopResult pop1 = *(StackPopResult *)vector_get(&results, 0); AssertThat(pop1.tree_count, Equals(3)); AssertThat(pop1.head_index, Equals(0)); AssertThat(pop1.trees[0], Equals(trees[4])); - free_pop_results(&pop); + free_pop_results(&results); }); }); }); @@ -540,31 +540,31 @@ describe("Stack", [&]() { * \__E4__F5. * \__G6__H7. */ - Vector pop = ts_stack_pop(stack, 0, 2, false); + StackPopResultVector results = ts_stack_pop(stack, 0, 2, false); AssertThat(ts_stack_head_count(stack), Equals(3)); - AssertThat(pop.size, Equals(3)); + AssertThat(results.size, Equals(3)); - StackPopResult pop1 = *(StackPopResult *)vector_get(&pop, 0); + StackPopResult pop1 = *(StackPopResult *)vector_get(&results, 0); AssertThat(ts_stack_top_tree(stack, 0), Equals(trees[3])); AssertThat(pop1.head_index, Equals(0)); AssertThat(pop1.tree_count, Equals(2)); AssertThat(pop1.trees[0], Equals(trees[8])); AssertThat(pop1.trees[1], Equals(trees[9])); - StackPopResult pop2 = *(StackPopResult *)vector_get(&pop, 1); + StackPopResult pop2 = *(StackPopResult *)vector_get(&results, 1); AssertThat(ts_stack_top_tree(stack, 1), Equals(trees[5])); AssertThat(pop2.head_index, Equals(1)); AssertThat(pop2.tree_count, Equals(2)); AssertThat(pop2.trees, Equals(pop1.trees)); - StackPopResult pop3 = *(StackPopResult *)vector_get(&pop, 2); + StackPopResult pop3 = *(StackPopResult *)vector_get(&results, 2); AssertThat(ts_stack_top_tree(stack, 2), Equals(trees[7])); AssertThat(pop3.head_index, Equals(2)); AssertThat(pop3.tree_count, Equals(2)); AssertThat(pop3.trees, Equals(pop1.trees)); - free_pop_results(&pop); + free_pop_results(&results); }); }); @@ -575,12 +575,12 @@ describe("Stack", [&]() { * \__E4. * \__G6. */ - Vector pop = ts_stack_pop(stack, 0, 3, false); + StackPopResultVector results = ts_stack_pop(stack, 0, 3, false); AssertThat(ts_stack_head_count(stack), Equals(3)); - AssertThat(pop.size, Equals(3)); + AssertThat(results.size, Equals(3)); - StackPopResult pop1 = *(StackPopResult *)vector_get(&pop, 0); + StackPopResult pop1 = *(StackPopResult *)vector_get(&results, 0); AssertThat(ts_stack_top_tree(stack, 0), Equals(trees[2])); AssertThat(pop1.head_index, Equals(0)); AssertThat(pop1.tree_count, Equals(3)); @@ -588,7 +588,7 @@ describe("Stack", [&]() { AssertThat(pop1.trees[1], Equals(trees[8])); AssertThat(pop1.trees[2], Equals(trees[9])); - StackPopResult pop2 = *(StackPopResult *)vector_get(&pop, 1); + StackPopResult pop2 = *(StackPopResult *)vector_get(&results, 1); AssertThat(ts_stack_top_tree(stack, 1), Equals(trees[4])); AssertThat(pop2.head_index, Equals(1)); AssertThat(pop2.tree_count, Equals(3)); @@ -596,7 +596,7 @@ describe("Stack", [&]() { AssertThat(pop2.trees[1], Equals(trees[8])); AssertThat(pop2.trees[2], Equals(trees[9])); - StackPopResult pop3 = *(StackPopResult *)vector_get(&pop, 2); + StackPopResult pop3 = *(StackPopResult *)vector_get(&results, 2); AssertThat(ts_stack_top_tree(stack, 2), Equals(trees[6])); AssertThat(pop3.head_index, Equals(2)); AssertThat(pop3.tree_count, Equals(3)); @@ -604,7 +604,7 @@ describe("Stack", [&]() { AssertThat(pop3.trees[1], Equals(trees[8])); AssertThat(pop3.trees[2], Equals(trees[9])); - free_pop_results(&pop); + free_pop_results(&results); }); }); }); diff --git a/src/runtime/parser.c b/src/runtime/parser.c index 5dcf9988..8b4aa18e 100644 --- a/src/runtime/parser.c +++ b/src/runtime/parser.c @@ -26,11 +26,11 @@ #define BOOL_STRING(value) (value ? "true" : "false") -typedef struct { +struct LookaheadState { TSTree *reusable_subtree; size_t reusable_subtree_pos; bool is_verifying; -} LookaheadState; +}; typedef enum { UpdatedStackHead, @@ -47,8 +47,8 @@ static ParseActionResult ts_parser__breakdown_top_of_stack(TSParser *self, TSTree *last_child = NULL; do { - Vector pop_results = ts_stack_pop(self->stack, head, 1, false); - if (!vector_valid(&pop_results)) + StackPopResultVector pop_results = ts_stack_pop(self->stack, head, 1, false); + if (!pop_results.size) return FailedToUpdateStackHead; assert(pop_results.size > 0); @@ -64,7 +64,7 @@ static ParseActionResult ts_parser__breakdown_top_of_stack(TSParser *self, ts_tree_total_size(parent).chars); for (size_t i = 0; i < pop_results.size; i++) { - StackPopResult *pop_result = vector_get(&pop_results, i); + StackPopResult *pop_result = &pop_results.contents[i]; assert(pop_result->trees == removed_trees); int head_index = pop_result->head_index; @@ -238,9 +238,8 @@ static TSTree *ts_parser__get_next_lookahead(TSParser *self, int head) { static int ts_parser__split(TSParser *self, int head) { int result = ts_stack_split(self->stack, head); assert(result == (int)self->lookahead_states.size); - LookaheadState lookahead_state = - *(LookaheadState *)vector_get(&self->lookahead_states, head); - vector_push(&self->lookahead_states, &lookahead_state); + LookaheadState lookahead_state = *vector_get(&self->lookahead_states, head); + vector_push(&self->lookahead_states, lookahead_state); return result; } @@ -311,14 +310,15 @@ static ParseActionResult ts_parser__reduce(TSParser *self, int head, vector_clear(&self->reduce_parents); const TSSymbolMetadata *all_metadata = self->language->symbol_metadata; TSSymbolMetadata metadata = all_metadata[symbol]; - Vector pop_results = ts_stack_pop(self->stack, head, child_count, count_extra); - if (!vector_valid(&pop_results)) + StackPopResultVector pop_results = + ts_stack_pop(self->stack, head, child_count, count_extra); + if (!pop_results.size) return FailedToUpdateStackHead; size_t removed_heads = 0; for (size_t i = 0; i < pop_results.size; i++) { - StackPopResult *pop_result = vector_get(&pop_results, i); + StackPopResult *pop_result = &pop_results.contents[i]; /* * If the same set of trees led to a previous stack head, reuse the parent @@ -328,10 +328,9 @@ static ParseActionResult ts_parser__reduce(TSParser *self, int head, TSTree *parent = NULL; size_t trailing_extra_count = 0; for (size_t j = 0; j < i; j++) { - StackPopResult *prior_result = vector_get(&pop_results, j); + StackPopResult *prior_result = &pop_results.contents[j]; if (pop_result->trees == prior_result->trees) { - TSTree **existing_parent = vector_get(&self->reduce_parents, j); - parent = *existing_parent; + parent = self->reduce_parents.contents[j]; trailing_extra_count = pop_result->tree_count - parent->child_count; ts_tree_retain(parent); for (size_t k = parent->child_count; k < pop_result->tree_count; k++) @@ -359,7 +358,7 @@ static ParseActionResult ts_parser__reduce(TSParser *self, int head, } } - if (!vector_push(&self->reduce_parents, &parent)) + if (!vector_push(&self->reduce_parents, parent)) goto error; int new_head = pop_result->head_index - removed_heads; @@ -372,13 +371,14 @@ static ParseActionResult ts_parser__reduce(TSParser *self, int head, } /* - * If the stack has split in the process of popping, create a duplicate of + * If the stack has split in the process of popping, create a duplicate + * of * the lookahead state for this head, for the new head. */ LOG("split_during_reduce new_head:%d", new_head); LookaheadState lookahead_state = - *(LookaheadState *)vector_get(&self->lookahead_states, head); - if (!vector_push(&self->lookahead_states, &lookahead_state)) + *vector_get(&self->lookahead_states, head); + if (!vector_push(&self->lookahead_states, lookahead_state)) goto error; } @@ -565,18 +565,18 @@ static ParseActionResult ts_parser__start(TSParser *self, TSInput input, .is_verifying = false, }; vector_clear(&self->lookahead_states); - vector_push(&self->lookahead_states, &lookahead_state); + vector_push(&self->lookahead_states, lookahead_state); self->finished_tree = NULL; return UpdatedStackHead; } static ParseActionResult ts_parser__accept(TSParser *self, int head) { - Vector pop_results = ts_stack_pop(self->stack, head, -1, true); + StackPopResultVector pop_results = ts_stack_pop(self->stack, head, -1, true); if (!pop_results.size) goto error; for (size_t j = 0; j < pop_results.size; j++) { - StackPopResult *pop_result = vector_get(&pop_results, j); + StackPopResult *pop_result = &pop_results.contents[j]; for (size_t i = 0; i < pop_result->tree_count; i++) { if (!pop_result->trees[i]->extra) { @@ -622,7 +622,7 @@ static ParseActionResult ts_parser__accept(TSParser *self, int head) { error: if (pop_results.size) { - StackPopResult *pop_result = vector_get(&pop_results, 0); + StackPopResult *pop_result = vector_front(&pop_results); for (size_t i = 0; i < pop_result->tree_count; i++) ts_tree_release(pop_result->trees[i]); ts_free(pop_result->trees); @@ -745,8 +745,8 @@ bool ts_parser_init(TSParser *self) { ts_lexer_init(&self->lexer); self->finished_tree = NULL; self->stack = NULL; - self->lookahead_states = vector_new(sizeof(LookaheadState)); - self->reduce_parents = vector_new(sizeof(TSTree *)); + vector_init(&self->lookahead_states); + vector_init(&self->reduce_parents); self->stack = ts_stack_new(); if (!self->stack) diff --git a/src/runtime/parser.h b/src/runtime/parser.h index 6fc83acd..7bb8aeb5 100644 --- a/src/runtime/parser.h +++ b/src/runtime/parser.h @@ -8,12 +8,14 @@ extern "C" { #include "runtime/stack.h" #include "runtime/vector.h" +typedef struct LookaheadState LookaheadState; + typedef struct { TSLexer lexer; Stack *stack; const TSLanguage *language; - Vector lookahead_states; - Vector reduce_parents; + Vector(LookaheadState) lookahead_states; + Vector(TSTree *) reduce_parents; TSTree *finished_tree; bool is_split; } TSParser; diff --git a/src/runtime/stack.c b/src/runtime/stack.c index 79893bed..33e785bd 100644 --- a/src/runtime/stack.c +++ b/src/runtime/stack.c @@ -19,23 +19,23 @@ typedef struct StackNode { short unsigned int ref_count; } StackNode; -struct Stack { - Vector heads; - Vector pop_results; - Vector pop_paths; - Vector node_pool; - void *tree_selection_payload; - TreeSelectionFunction tree_selection_function; -}; +typedef Vector(TSTree *) TreeVector; typedef struct { size_t goal_tree_count; StackNode *node; - Vector trees; + TreeVector trees; bool is_shared; } PopPath; -static StackNode *NULL_NODE = NULL; +struct Stack { + Vector(StackNode *) heads; + StackPopResultVector pop_results; + Vector(PopPath) pop_paths; + Vector(StackNode *) node_pool; + void *tree_selection_payload; + TreeSelectionFunction tree_selection_function; +}; /* * Section: Stack lifecycle @@ -50,10 +50,10 @@ Stack *ts_stack_new() { if (!self) goto error; - self->heads = vector_new(sizeof(StackNode *)); - self->pop_results = vector_new(sizeof(StackPopResult)); - self->pop_paths = vector_new(sizeof(PopPath)); - self->node_pool = vector_new(sizeof(StackNode *)); + vector_init(&self->heads); + vector_init(&self->pop_results); + vector_init(&self->pop_paths); + vector_init(&self->node_pool); self->tree_selection_payload = NULL; self->tree_selection_function = ts_stack__default_tree_selection; @@ -69,7 +69,7 @@ Stack *ts_stack_new() { if (!vector_grow(&self->node_pool, 20)) goto error; - vector_push(&self->heads, &NULL_NODE); + vector_push(&self->heads, NULL); return self; @@ -108,7 +108,7 @@ TSTree *ts_stack_top_tree(const Stack *self, int head) { } StackEntry *ts_stack_head(Stack *self, int head) { - StackNode *node = *(StackNode **)vector_get(&self->heads, head); + StackNode *node = self->heads.contents[head]; return node ? &node->entry : NULL; } @@ -148,7 +148,7 @@ static bool stack_node_release(Stack *self, StackNode *node) { if (self->node_pool.size >= MAX_NODE_POOL_SIZE) ts_free(node); else - vector_push(&self->node_pool, &node); + vector_push(&self->node_pool, node); return true; } else { @@ -156,7 +156,8 @@ static bool stack_node_release(Stack *self, StackNode *node) { } } -static StackNode *stack_node_new(Stack *self, StackNode *next, TSStateId state, TSTree *tree) { +static StackNode *stack_node_new(Stack *self, StackNode *next, TSStateId state, + TSTree *tree) { assert(tree->ref_count > 0); StackNode *node; if (self->node_pool.size == 0) { @@ -164,7 +165,7 @@ static StackNode *stack_node_new(Stack *self, StackNode *next, TSStateId state, if (!node) return NULL; } else { - node = *(StackNode **)vector_pop(&self->node_pool); + node = vector_pop(&self->node_pool); } ts_tree_retain(tree); @@ -184,8 +185,8 @@ static StackNode *stack_node_new(Stack *self, StackNode *next, TSStateId state, static void ts_stack__add_alternative_tree(Stack *self, StackNode *node, TSTree *tree) { if (tree != node->entry.tree) { - int comparison = self->tree_selection_function( - self->tree_selection_payload, node->entry.tree, tree); + int comparison = self->tree_selection_function(self->tree_selection_payload, + node->entry.tree, tree); if (comparison > 0) { ts_tree_retain(tree); @@ -211,7 +212,8 @@ static void ts_stack__add_alternative_pop_result(Stack *self, for (size_t i = 0; i < result->tree_count; i++) { TSTree *tree = result->trees[i]; TSTree *new_tree = new_result->trees[i]; - int comparison = self->tree_selection_function(self->tree_selection_payload, tree, new_tree); + int comparison = self->tree_selection_function( + self->tree_selection_payload, tree, new_tree); if (comparison < 0) { break; } else if (comparison > 0) { @@ -230,7 +232,6 @@ static void ts_stack__add_alternative_pop_result(Stack *self, } } - static void ts_stack__add_node_successor(Stack *self, StackNode *node, StackNode *new_successor) { for (int i = 0; i < node->successor_count; i++) { @@ -259,7 +260,7 @@ static void ts_stack__add_node_successor(Stack *self, StackNode *node, */ static int ts_stack__add_head(Stack *self, StackNode *node) { - if (vector_push(&self->heads, &node)) { + if (vector_push(&self->heads, node)) { stack_node_retain(node); return self->heads.size - 1; } else { @@ -269,16 +270,15 @@ static int ts_stack__add_head(Stack *self, StackNode *node) { static int ts_stack__find_head(Stack *self, StackNode *node) { for (size_t i = 0; i < self->heads.size; i++) { - StackNode **existing_node = vector_get(&self->heads, i); - if (*existing_node == node) + if (self->heads.contents[i] == node) return i; } return -1; } void ts_stack_remove_head(Stack *self, int head_index) { - StackNode **node = vector_get(&self->heads, head_index); - stack_node_release(self, *node); + StackNode *node = *vector_get(&self->heads, head_index); + stack_node_release(self, node); vector_erase(&self->heads, head_index); } @@ -288,57 +288,55 @@ void ts_stack_remove_head(Stack *self, int head_index) { StackPushResult ts_stack_push(Stack *self, int head_index, TSStateId state, TSTree *tree) { - assert((size_t)head_index < self->heads.size); - assert(tree); - TSLength position = ts_tree_total_size(tree); - StackNode **current_head = vector_get(&self->heads, head_index); - if (*current_head) - position = ts_length_add((*current_head)->entry.position, position); + StackNode *current_head = *vector_get(&self->heads, head_index); + if (current_head) + position = ts_length_add(current_head->entry.position, position); for (int i = 0; i < head_index; i++) { - StackNode **prior_node = vector_get(&self->heads, i); - StackEntry prior_entry = (*prior_node)->entry; - if (prior_entry.state == state && ts_length_eq(prior_entry.position, position)) { - ts_stack__add_alternative_tree(self, *prior_node, tree); - ts_stack__add_node_successor(self, *prior_node, *current_head); + StackNode *prior_node = self->heads.contents[i]; + StackEntry prior_entry = prior_node->entry; + if (prior_entry.state == state && + ts_length_eq(prior_entry.position, position)) { + ts_stack__add_alternative_tree(self, prior_node, tree); + ts_stack__add_node_successor(self, prior_node, current_head); ts_stack_remove_head(self, head_index); return StackPushResultMerged; } } - StackNode *new_head = stack_node_new(self, *current_head, state, tree); + StackNode *new_head = stack_node_new(self, current_head, state, tree); if (!new_head) return StackPushResultFailed; - stack_node_release(self, *current_head); - vector_set(&self->heads, head_index, &new_head); + stack_node_release(self, current_head); + self->heads.contents[head_index] = new_head; return StackPushResultContinued; } int ts_stack_split(Stack *self, int head_index) { - StackNode **head = vector_get(&self->heads, head_index); - return ts_stack__add_head(self, *head); + StackNode *head = self->heads.contents[head_index]; + return ts_stack__add_head(self, head); } -Vector ts_stack_pop(Stack *self, int head_index, int child_count, - bool count_extra) { +StackPopResultVector ts_stack_pop(Stack *self, int head_index, int child_count, + bool count_extra) { vector_clear(&self->pop_results); vector_clear(&self->pop_paths); - StackNode *previous_head = *(StackNode **)vector_get(&self->heads, head_index); + StackNode *previous_head = *vector_get(&self->heads, head_index); int capacity = (child_count == -1) ? STARTING_TREE_CAPACITY : child_count; PopPath initial_path = { .goal_tree_count = child_count, .node = previous_head, - .trees = vector_new(sizeof(TSTree *)), .is_shared = false, }; + vector_init(&initial_path.trees); if (!vector_grow(&initial_path.trees, capacity)) goto error; - if (!vector_push(&self->pop_paths, &initial_path)) + if (!vector_push(&self->pop_paths, initial_path)) goto error; /* @@ -350,7 +348,7 @@ Vector ts_stack_pop(Stack *self, int head_index, int child_count, all_paths_done = true; for (size_t i = 0; i < self->pop_paths.size; i++) { - PopPath *path = vector_get(&self->pop_paths, i); + PopPath *path = &self->pop_paths.contents[i]; StackNode *node = path->node; if (!node || path->trees.size == path->goal_tree_count) @@ -369,23 +367,19 @@ Vector ts_stack_pop(Stack *self, int head_index, int child_count, * the additional successors. */ if (path->is_shared) { - path->trees = vector_copy(&path->trees); - for (size_t j = 0; j < path->trees.size; j++) { - TSTree **tree = vector_get(&path->trees, j); - ts_tree_retain(*tree); - } - + path->trees = (TreeVector)vector_copy(&path->trees); + for (size_t j = 0; j < path->trees.size; j++) + ts_tree_retain(path->trees.contents[j]); path->is_shared = false; } ts_tree_retain(node->entry.tree); - if (!vector_push(&path->trees, &node->entry.tree)) + if (!vector_push(&path->trees, node->entry.tree)) goto error; path->node = path->node->successors[0]; - PopPath path_copy = *path; for (int j = 1; j < node->successor_count; j++) { - if (!vector_push(&self->pop_paths, &path_copy)) + if (!vector_push(&self->pop_paths, *path)) goto error; PopPath *next_path = vector_back(&self->pop_paths); @@ -396,7 +390,7 @@ Vector ts_stack_pop(Stack *self, int head_index, int child_count, } for (size_t i = 0; i < self->pop_paths.size; i++) { - PopPath *path = vector_get(&self->pop_paths, i); + PopPath *path = &self->pop_paths.contents[i]; if (!path->is_shared) vector_reverse(&path->trees); @@ -409,7 +403,7 @@ Vector ts_stack_pop(Stack *self, int head_index, int child_count, if (i == 0) { stack_node_retain(path->node); - vector_set(&self->heads, head_index, &path->node); + self->heads.contents[head_index] = path->node; result.head_index = head_index; } else { result.head_index = ts_stack__find_head(self, path->node); @@ -420,7 +414,7 @@ Vector ts_stack_pop(Stack *self, int head_index, int child_count, } else { bool merged_result = false; for (size_t j = 0; j < self->pop_results.size; j++) { - StackPopResult *prior_result = vector_get(&self->pop_results, j); + StackPopResult *prior_result = &self->pop_results.contents[j]; if (prior_result->head_index == result.head_index) { ts_stack__add_alternative_pop_result(self, prior_result, &result); merged_result = true; @@ -432,7 +426,7 @@ Vector ts_stack_pop(Stack *self, int head_index, int child_count, } } - if (!vector_push(&self->pop_results, &result)) + if (!vector_push(&self->pop_results, result)) goto error; } @@ -441,30 +435,29 @@ Vector ts_stack_pop(Stack *self, int head_index, int child_count, error: vector_delete(&initial_path.trees); - return vector_new(0); + StackPopResultVector result; + vector_init(&result); + return result; } void ts_stack_shrink(Stack *self, int head_index, int count) { - StackNode **head = vector_get(&self->heads, head_index); - StackNode *new_head = *head; + StackNode *head = *vector_get(&self->heads, head_index); + StackNode *new_head = head; for (int i = 0; i < count; i++) { if (new_head->successor_count == 0) break; new_head = new_head->successors[0]; } stack_node_retain(new_head); - stack_node_release(self, *head); - vector_set(&self->heads, head_index, new_head); + stack_node_release(self, head); + self->heads.contents[head_index] = new_head; } void ts_stack_clear(Stack *self) { - for (size_t i = 0; i < self->heads.size; i++) { - StackNode **head = vector_get(&self->heads, i); - stack_node_release(self, *head); - } - + for (size_t i = 0; i < self->heads.size; i++) + stack_node_release(self, self->heads.contents[i]); vector_clear(&self->heads); - vector_push(&self->heads, &NULL_NODE); + vector_push(&self->heads, NULL); } void ts_stack_set_tree_selection_callback(Stack *self, void *payload, @@ -479,12 +472,11 @@ void ts_stack_delete(Stack *self) { if (self->pop_paths.contents) vector_delete(&self->pop_paths); ts_stack_clear(self); - for (size_t i = 0; i < self->node_pool.size; i++) { - StackNode **node = vector_get(&self->node_pool, i); - ts_free(*node); - } - if (self->node_pool.contents) + if (self->node_pool.contents) { + for (size_t i = 0; i < self->node_pool.size; i++) + ts_free(self->node_pool.contents[i]); vector_delete(&self->node_pool); + } vector_delete(&self->heads); ts_free(self); } diff --git a/src/runtime/stack.h b/src/runtime/stack.h index 4bcdc02d..853cff34 100644 --- a/src/runtime/stack.h +++ b/src/runtime/stack.h @@ -28,6 +28,8 @@ typedef enum { StackPushResultContinued, } StackPushResult; +typedef Vector(StackPopResult) StackPopResultVector; + typedef int (*TreeSelectionFunction)(void *, TSTree *, TSTree *); /* @@ -90,7 +92,8 @@ 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. */ -Vector ts_stack_pop(Stack *, int head, int count, bool count_extra); +StackPopResultVector ts_stack_pop(Stack *, int head, int count, + bool count_extra); /* * Remove the given number of entries from the given head of the stack. diff --git a/src/runtime/vector.h b/src/runtime/vector.h index 2c89d94a..1d859165 100644 --- a/src/runtime/vector.h +++ b/src/runtime/vector.h @@ -11,120 +11,100 @@ extern "C" { #include #include "runtime/alloc.h" -typedef struct { - void *contents; - size_t size; - size_t capacity; - size_t element_size; -} Vector; +#define Vector(T) \ + struct { \ + T *contents; \ + size_t size; \ + size_t capacity; \ + } -static inline Vector vector_new(size_t element_size) { - Vector result; - result.contents = NULL; - result.size = 0; - result.capacity = 0; - result.element_size = element_size; - return result; +#define vector_init(self) \ + ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL) + +#define vector_get(self, index) \ + (assert((size_t)index < (self)->size), &(self)->contents[index]) + +#define vector_front(self) vector_get(self, 0) + +#define vector_back(self) vector_get(self, (self)->size - 1) + +#define vector_clear(self) ((self)->size = 0) + +#define vector_grow(self, new_capacity) \ + vector__grow((VoidVector *)(self), vector__elem_size(self), new_capacity) + +#define vector_erase(self, index) \ + vector__erase((VoidVector *)(self), vector__elem_size(self), index) + +#define vector_delete(self) vector__delete((VoidVector *)self) + +#define vector_push(self, element) \ + (((self)->size < (self)->capacity || \ + vector_grow((self), (self)->capacity * 2)) && \ + ((self)->contents[(self)->size++] = (element), true)) + +#define vector_pop(self) ((self)->contents[--(self)->size]) + +#define vector_reverse(self) \ + vector__reverse((VoidVector *)(self), vector__elem_size(self)) + +#define vector_copy(self) \ + { \ + memcpy(ts_calloc((self)->capacity, vector__elem_size(self)), \ + (self)->contents, (self)->size *vector__elem_size(self)), \ + (self)->size, (self)->capacity, \ + } + +// Private + +typedef Vector(void) VoidVector; + +#define vector__elem_size(self) sizeof(*(self)->contents) + +static inline void vector__delete(VoidVector *self) { + ts_free(self->contents); + self->contents = NULL; + self->size = 0; + self->capacity = 0; } -static inline bool vector_grow(Vector *self, size_t capacity) { - if (capacity == 0) +static inline void vector__erase(VoidVector *self, size_t element_size, + size_t index) { + assert(index < self->size); + char *contents = (char *)self->contents; + memmove(contents + index * element_size, contents + (index + 1) * element_size, + (self->size - index - 1) * element_size); + self->size--; +} + +static inline bool vector__grow(VoidVector *self, size_t element_size, + size_t new_capacity) { + if (new_capacity == 0) return true; void *new_contents; if (self->contents) - new_contents = ts_realloc(self->contents, capacity * self->element_size); + new_contents = ts_realloc(self->contents, new_capacity * element_size); else - new_contents = ts_calloc(capacity, self->element_size); + new_contents = ts_calloc(new_capacity, element_size); if (!new_contents) return false; - self->capacity = capacity; + self->capacity = new_capacity; self->contents = new_contents; return true; } -static inline bool vector_valid(Vector *self) { - return self->element_size > 0; -} - -static inline void vector_delete(Vector *self) { - if (self->contents) { - ts_free(self->contents); - self->contents = NULL; - self->size = 0; - self->capacity = 0; - } -} - -static inline void *vector_get(Vector *self, size_t index) { - assert(index < self->size); - return (void *)((char *)self->contents + index * self->element_size); -} - -static inline void vector_set(Vector *self, size_t index, void *entry) { - assert(index < self->size); - char *location = (char *)self->contents + index * self->element_size; - memcpy(location, (char *)entry, self->element_size); -} - -static inline void *vector_back(Vector *self) { - assert(self->size > 0); - return vector_get(self, self->size - 1); -} - -static inline void *vector_pop(Vector *self) { - void *result = vector_back(self); - self->size--; - return result; -} - -static inline void vector_clear(Vector *self) { - self->size = 0; -} - -static inline void vector_erase(Vector *self, size_t index) { - assert(index < self->size); +static inline void vector__reverse(VoidVector *self, size_t element_size) { + char swap[element_size]; char *contents = (char *)self->contents; - memmove(contents + index * self->element_size, - contents + (index + 1) * self->element_size, - (self->size - index - 1) * self->element_size); - self->size--; -} - -static inline bool vector_push(Vector *self, void *entry) { - if (self->size == self->capacity) { - self->capacity += 4; - void *contents = - ts_realloc(self->contents, self->capacity * self->element_size); - if (!contents) - return false; - self->contents = contents; + for (size_t i = 0, limit = self->size / 2; i < limit; i++) { + size_t offset = i * element_size; + size_t reverse_offset = (self->size - 1 - i) * element_size; + memcpy(&swap, contents + offset, element_size); + memcpy(contents + offset, contents + reverse_offset, element_size); + memcpy(contents + reverse_offset, &swap, element_size); } - - self->size++; - vector_set(self, self->size - 1, entry); - return true; -} - -static inline void vector_reverse(Vector *self) { - char swap[self->element_size]; - char *contents = (char *)self->contents; - size_t limit = self->size / 2; - for (size_t i = 0; i < limit; i++) { - size_t offset = i * self->element_size; - size_t reverse_offset = (self->size - 1 - i) * self->element_size; - memcpy(&swap, contents + offset, self->element_size); - memcpy(contents + offset, contents + reverse_offset, self->element_size); - memcpy(contents + reverse_offset, &swap, self->element_size); - } -} - -static inline Vector vector_copy(Vector *self) { - Vector copy = *self; - copy.contents = memcpy(ts_calloc(self->capacity, self->element_size), - self->contents, self->size * self->element_size); - return copy; } #ifdef __cplusplus