Rizin
unix-like reverse engineering framework and cli tools
reusable_node.h
Go to the documentation of this file.
1 #include "./subtree.h"
2 
3 typedef struct {
7 } StackEntry;
8 
9 typedef struct {
12 } ReusableNode;
13 
14 static inline ReusableNode reusable_node_new(void) {
15  return (ReusableNode) {array_new(), NULL_SUBTREE};
16 }
17 
18 static inline void reusable_node_clear(ReusableNode *self) {
19  array_clear(&self->stack);
20  self->last_external_token = NULL_SUBTREE;
21 }
22 
23 static inline Subtree reusable_node_tree(ReusableNode *self) {
24  return self->stack.size > 0
25  ? self->stack.contents[self->stack.size - 1].tree
26  : NULL_SUBTREE;
27 }
28 
30  return self->stack.size > 0
31  ? self->stack.contents[self->stack.size - 1].byte_offset
32  : UINT32_MAX;
33 }
34 
35 static inline void reusable_node_delete(ReusableNode *self) {
36  array_delete(&self->stack);
37 }
38 
39 static inline void reusable_node_advance(ReusableNode *self) {
40  StackEntry last_entry = *array_back(&self->stack);
41  uint32_t byte_offset = last_entry.byte_offset + ts_subtree_total_bytes(last_entry.tree);
42  if (ts_subtree_has_external_tokens(last_entry.tree)) {
43  self->last_external_token = ts_subtree_last_external_token(last_entry.tree);
44  }
45 
46  Subtree tree;
47  uint32_t next_index;
48  do {
49  StackEntry popped_entry = array_pop(&self->stack);
50  next_index = popped_entry.child_index + 1;
51  if (self->stack.size == 0) return;
52  tree = array_back(&self->stack)->tree;
53  } while (ts_subtree_child_count(tree) <= next_index);
54 
55  array_push(&self->stack, ((StackEntry) {
56  .tree = ts_subtree_children(tree)[next_index],
57  .child_index = next_index,
58  .byte_offset = byte_offset,
59  }));
60 }
61 
62 static inline bool reusable_node_descend(ReusableNode *self) {
63  StackEntry last_entry = *array_back(&self->stack);
64  if (ts_subtree_child_count(last_entry.tree) > 0) {
65  array_push(&self->stack, ((StackEntry) {
66  .tree = ts_subtree_children(last_entry.tree)[0],
67  .child_index = 0,
68  .byte_offset = last_entry.byte_offset,
69  }));
70  return true;
71  } else {
72  return false;
73  }
74 }
75 
76 static inline void reusable_node_advance_past_leaf(ReusableNode *self) {
77  while (reusable_node_descend(self)) {}
79 }
80 
81 static inline void reusable_node_reset(ReusableNode *self, Subtree tree) {
82  reusable_node_clear(self);
83  array_push(&self->stack, ((StackEntry) {
84  .tree = tree,
85  .child_index = 0,
86  .byte_offset = 0,
87  }));
88 
89  // Never reuse the root node, because it has a non-standard internal structure
90  // due to transformations that are applied when it is accepted: adding the EOF
91  // child and any extra children.
92  if (!reusable_node_descend(self)) {
93  reusable_node_clear(self);
94  }
95 }
#define array_new()
Definition: array.h:25
#define array_back(self)
Definition: array.h:33
#define array_push(self, element)
Definition: array.h:43
#define array_pop(self)
Definition: array.h:82
#define array_delete(self)
Definition: array.h:41
#define array_clear(self)
Definition: array.h:35
static void reusable_node_advance(ReusableNode *self)
Definition: reusable_node.h:39
static uint32_t reusable_node_byte_offset(ReusableNode *self)
Definition: reusable_node.h:29
static bool reusable_node_descend(ReusableNode *self)
Definition: reusable_node.h:62
static Subtree reusable_node_tree(ReusableNode *self)
Definition: reusable_node.h:23
static void reusable_node_advance_past_leaf(ReusableNode *self)
Definition: reusable_node.h:76
static void reusable_node_delete(ReusableNode *self)
Definition: reusable_node.h:35
static void reusable_node_reset(ReusableNode *self, Subtree tree)
Definition: reusable_node.h:81
static void reusable_node_clear(ReusableNode *self)
Definition: reusable_node.h:18
static ReusableNode reusable_node_new(void)
Definition: reusable_node.h:14
unsigned int uint32_t
Definition: sftypes.h:29
#define UINT32_MAX
Array(StackEntry) stack
Subtree last_external_token
Definition: reusable_node.h:11
uint32_t byte_offset
Definition: reusable_node.h:6
Subtree tree
Definition: reusable_node.h:4
uint32_t child_index
Definition: reusable_node.h:5
Subtree ts_subtree_last_external_token(Subtree tree)
Definition: subtree.c:802
static bool ts_subtree_has_external_tokens(Subtree self)
Definition: subtree.h:330
static uint32_t ts_subtree_total_bytes(Subtree self)
Definition: subtree.h:278
static uint32_t ts_subtree_child_count(Subtree self)
Definition: subtree.h:282
#define NULL_SUBTREE
Definition: subtree.h:19
static struct stack stack[MAX_INCLUDE]
Definition: z80asm.c:92