10 #define MAX_LINK_COUNT 8
11 #define MAX_NODE_POOL_SIZE 50
12 #define MAX_ITERATOR_COUNT 64
14 #if defined _WIN32 && !defined __GNUC__
15 #define inline __forceinline
17 #define inline static inline __attribute__((always_inline))
65 StackSliceArray slices;
67 StackNodeArray node_pool;
84 assert(self->ref_count > 0);
86 assert(self->ref_count != 0);
95 assert(self->ref_count != 0);
97 if (self->ref_count > 0)
return;
100 if (self->link_count > 0) {
101 for (
unsigned i = self->link_count - 1;
i > 0;
i--) {
117 if (first_predecessor) {
118 self = first_predecessor;
142 .
node = previous_node,
144 .is_pending = is_pending,
167 if (left.
ptr == right.
ptr)
return true;
168 if (!left.
ptr || !right.
ptr)
return false;
190 if (
link.node ==
self)
return;
192 for (
int i = 0;
i <
self->link_count;
i++) {
199 if (existing_link->
node ==
link.node) {
207 self->dynamic_precedence =
218 for (
int j = 0; j <
link.node->link_count; j++) {
221 int32_t dynamic_precedence =
link.node->dynamic_precedence;
222 if (
link.subtree.ptr) {
225 if (dynamic_precedence > self->dynamic_precedence) {
226 self->dynamic_precedence = dynamic_precedence;
236 unsigned node_count =
link.node->node_count;
237 int dynamic_precedence =
link.node->dynamic_precedence;
238 self->links[
self->link_count++] =
link;
240 if (
link.subtree.ptr) {
246 if (node_count > self->node_count)
self->node_count = node_count;
247 if (dynamic_precedence > self->dynamic_precedence)
self->dynamic_precedence = dynamic_precedence;
252 StackNodeArray *pool,
256 if (self->last_external_token.ptr) {
259 if (self->lookahead_when_paused.ptr) {
277 .node_count_at_last_error =
self->heads.contents[original_version].node_count_at_last_error,
278 .last_external_token =
self->heads.contents[original_version].last_external_token,
279 .status = StackStatusActive,
292 SubtreeArray *subtrees
294 for (
uint32_t i = self->slices.size - 1;
i + 1 > 0;
i--) {
296 if (self->heads.contents[
version].node == node) {
313 int goal_subtree_count
326 bool include_subtrees =
false;
327 if (goal_subtree_count >= 0) {
328 include_subtrees =
true;
334 while (self->iterators.size > 0) {
344 SubtreeArray subtrees =
iterator->subtrees;
371 next_iterator = &
self->iterators.contents[
i];
376 array_push(&self->iterators, current_iterator);
382 if (
link.subtree.ptr) {
383 if (include_subtrees) {
390 if (!
link.is_pending) {
417 self->subtree_pool = subtree_pool;
425 if (self->slices.contents)
427 if (self->iterators.contents)
434 if (self->node_pool.contents) {
435 for (
uint32_t i = 0;
i <
self->node_pool.size;
i++)
436 ts_free(self->node_pool.contents[
i]);
444 return self->heads.size;
463 head->last_external_token = token;
468 unsigned result =
head->node->error_cost;
470 head->status == StackStatusPaused ||
479 if (
head->node->node_count <
head->node_count_at_last_error) {
480 head->node_count_at_last_error =
head->node->node_count;
482 return head->node->node_count -
head->node_count_at_last_error;
495 head->node = new_node;
499 unsigned *goal_subtree_count = payload;
500 if (
iterator->subtree_count == *goal_subtree_count) {
528 pop.contents[0].version =
version;
535 bool *found_error = payload;
551 bool found_error =
false;
556 return pop.contents[0].subtrees;
561 return (SubtreeArray) {.size = 0};
581 unsigned depth =
iterator->subtree_count;
583 for (
unsigned i = session->
summary->size - 1;
i + 1 > 0;
i--) {
585 if (
entry.depth < depth)
break;
589 .position = iterator->node->position,
599 .max_depth = max_depth
649 if (
v1 == v2)
return;
652 StackHead *source_head = &
self->heads.contents[
v1];
653 StackHead *target_head = &
self->heads.contents[v2];
659 *target_head = *source_head;
664 StackHead temporary_head =
self->heads.contents[
v1];
665 self->heads.contents[
v1] =
self->heads.contents[v2];
666 self->heads.contents[v2] = temporary_head;
670 assert(version < self->heads.size);
676 return self->heads.size - 1;
681 StackHead *head1 = &
self->heads.contents[version1];
682 StackHead *head2 = &
self->heads.contents[version2];
694 StackHead *head1 = &
self->heads.contents[version1];
695 StackHead *head2 = &
self->heads.contents[version2];
697 head1->
status == StackStatusActive &&
698 head2->
status == StackStatusActive &&
711 head->status = StackStatusPaused;
712 head->lookahead_when_paused = lookahead;
713 head->node_count_at_last_error =
head->node->node_count;
732 head->status = StackStatusActive;
744 .node = self->base_node,
745 .status = StackStatusActive,
746 .last_external_token = NULL_SUBTREE,
747 .lookahead_when_paused = NULL_SUBTREE,
755 fprintf(
f,
"digraph stack {\n");
756 fprintf(
f,
"rankdir=\"RL\";\n");
757 fprintf(
f,
"edge [arrowhead=none]\n");
764 if (
head->status == StackStatusHalted)
continue;
766 fprintf(
f,
"node_head_%u [shape=none, label=\"\"]\n",
i);
767 fprintf(
f,
"node_head_%u -> node_%p [",
i, (
void *)
head->node);
769 if (
head->status == StackStatusPaused) {
770 fprintf(
f,
"color=red ");
773 "label=%u, fontcolor=blue, weight=10000, labeltooltip=\"node_count: %u\nerror_cost: %u",
780 fprintf(
f,
"\nsummary_size: %u",
head->summary->size);
783 if (
head->last_external_token.ptr) {
786 fprintf(
f,
"\nexternal_scanner_state:");
787 for (
uint32_t j = 0; j <
state->length; j++) fprintf(
f,
" %2X", data[j]);
796 bool all_iterators_done =
false;
797 while (!all_iterators_done) {
798 all_iterators_done =
true;
800 for (
uint32_t i = 0;
i <
self->iterators.size;
i++) {
804 for (
uint32_t j = 0; j < visited_nodes.size; j++) {
805 if (visited_nodes.contents[j] == node) {
812 all_iterators_done =
false;
814 fprintf(
f,
"node_%p [", (
void *)node);
816 fprintf(
f,
"label=\"?\"");
822 fprintf(
f,
"shape=point margin=0 label=\"\"");
824 fprintf(
f,
"label=\"%d\"", node->
state);
829 " tooltip=\"position: %u,%u\nnode_count:%u\nerror_cost: %u\ndynamic_precedence: %d\"];\n",
839 fprintf(
f,
"node_%p -> node_%p [", (
void *)node, (
void *)
link.node);
840 if (
link.is_pending) fprintf(
f,
"style=dashed ");
843 if (!
link.subtree.ptr) {
844 fprintf(
f,
"color=red");
846 fprintf(
f,
"label=\"");
848 if (quoted) fprintf(
f,
"'");
850 for (
const char *
c =
name; *
c;
c++) {
851 if (*
c ==
'\"' || *
c ==
'\\') fprintf(
f,
"\\");
852 fprintf(
f,
"%c", *
c);
854 if (quoted) fprintf(
f,
"'");
858 "labeltooltip=\"error_cost: %u\ndynamic_precedence: %u\"",
868 next_iterator = &
self->iterators.contents[
i];
const MCPhysReg * iterator
const char * ts_language_symbol_name(const TSLanguage *, TSSymbol)
#define array_erase(self, index)
#define array_get(self, index)
#define array_push(self, element)
#define array_reserve(self, new_capacity)
#define array_insert(self, index, element)
#define array_delete(self)
#define array_clear(self)
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
static static fork const void static count static fd link
#define ERROR_COST_PER_RECOVERY
static Length length_zero(void)
static Length length_add(Length len1, Length len2)
assert(limit<=UINT32_MAX/2)
Subtree last_external_token
Subtree lookahead_when_paused
unsigned node_count_at_last_error
StackLink links[MAX_LINK_COUNT]
short unsigned int link_count
bool ts_stack_can_merge(Stack *self, StackVersion version1, StackVersion version2)
void ts_stack_renumber_version(Stack *self, StackVersion v1, StackVersion v2)
static void stack_node_add_link(StackNode *self, StackLink link, SubtreePool *subtree_pool)
int ts_stack_dynamic_precedence(Stack *self, StackVersion version)
void ts_stack_swap_versions(Stack *self, StackVersion v1, StackVersion v2)
void ts_stack_record_summary(Stack *self, StackVersion version, unsigned max_depth)
StackSummary * ts_stack_get_summary(Stack *self, StackVersion version)
static void stack_node_release(StackNode *self, StackNodeArray *pool, SubtreePool *subtree_pool)
#define MAX_ITERATOR_COUNT
void ts_stack_halt(Stack *self, StackVersion version)
void ts_stack_clear(Stack *self)
bool ts_stack_has_advanced_since_error(const Stack *self, StackVersion version)
void ts_stack_pause(Stack *self, StackVersion version, Subtree lookahead)
StackAction(* StackCallback)(void *, const StackIterator *)
static bool stack__subtree_is_equivalent(Subtree left, Subtree right)
static void ts_stack__add_slice(Stack *self, StackVersion original_version, StackNode *node, SubtreeArray *subtrees)
Subtree ts_stack_resume(Stack *self, StackVersion version)
static StackNode * stack_node_new(StackNode *previous_node, Subtree subtree, bool is_pending, TSStateId state, StackNodeArray *pool)
uint32_t ts_stack_version_count(const Stack *self)
StackSliceArray stack__iter(Stack *self, StackVersion version, StackCallback callback, void *payload, int goal_subtree_count)
static StackVersion ts_stack__add_version(Stack *self, StackVersion original_version, StackNode *node)
bool ts_stack_print_dot_graph(Stack *self, const TSLanguage *language, FILE *f)
TSStateId ts_stack_state(const Stack *self, StackVersion version)
StackAction pop_all_callback(void *payload, const StackIterator *iterator)
bool ts_stack_is_active(const Stack *self, StackVersion version)
Length ts_stack_position(const Stack *self, StackVersion version)
StackSliceArray ts_stack_pop_count(Stack *self, StackVersion version, uint32_t count)
void ts_stack_push(Stack *self, StackVersion version, Subtree subtree, bool pending, TSStateId state)
static void stack_head_delete(StackHead *self, StackNodeArray *pool, SubtreePool *subtree_pool)
void ts_stack_remove_version(Stack *self, StackVersion version)
unsigned ts_stack_node_count_since_error(const Stack *self, StackVersion version)
bool ts_stack_merge(Stack *self, StackVersion version1, StackVersion version2)
StackAction pop_error_callback(void *payload, const StackIterator *iterator)
StackVersion ts_stack_copy_version(Stack *self, StackVersion version)
StackSliceArray ts_stack_pop_pending(Stack *self, StackVersion version)
StackSliceArray ts_stack_pop_all(Stack *self, StackVersion version)
Stack * ts_stack_new(SubtreePool *subtree_pool)
void ts_stack_delete(Stack *self)
#define MAX_NODE_POOL_SIZE
bool ts_stack_is_halted(const Stack *self, StackVersion version)
unsigned ts_stack_error_cost(const Stack *self, StackVersion version)
typedef Array(StackNode *)
SubtreeArray ts_stack_pop_error(Stack *self, StackVersion version)
static void stack_node_retain(StackNode *self)
Subtree ts_stack_last_external_token(const Stack *self, StackVersion version)
StackAction pop_pending_callback(void *payload, const StackIterator *iterator)
StackAction pop_count_callback(void *payload, const StackIterator *iterator)
StackAction summarize_stack_callback(void *payload, const StackIterator *iterator)
void ts_stack_set_last_external_token(Stack *self, StackVersion version, Subtree token)
bool ts_stack_is_paused(const Stack *self, StackVersion version)
struct StackNode StackNode
void ts_subtree_array_reverse(SubtreeArray *self)
bool ts_subtree_external_scanner_state_eq(Subtree self, Subtree other)
void ts_subtree_release(SubtreePool *pool, Subtree self)
void ts_subtree_retain(Subtree self)
void ts_subtree_array_delete(SubtreePool *pool, SubtreeArray *self)
const char * ts_external_scanner_state_data(const ExternalScannerState *self)
void ts_subtree_array_copy(SubtreeArray self, SubtreeArray *dest)
static size_t ts_subtree_alloc_size(uint32_t child_count)
static bool ts_subtree_visible(Subtree self)
static Length ts_subtree_total_size(Subtree self)
static uint32_t ts_subtree_total_bytes(Subtree self)
static uint32_t ts_subtree_error_cost(Subtree self)
static int32_t ts_subtree_dynamic_precedence(Subtree self)
static bool ts_subtree_extra(Subtree self)
static bool ts_subtree_is_error(Subtree self)
static Length ts_subtree_size(Subtree self)
static bool ts_subtree_named(Subtree self)
static uint32_t ts_subtree_child_count(Subtree self)
static Length ts_subtree_padding(Subtree self)
static uint32_t ts_subtree_node_count(Subtree self)
static TSSymbol ts_subtree_symbol(Subtree self)
const SubtreeHeapData * ptr