summaryrefslogtreecommitdiff
path: root/prism/node.h
blob: e8686a327c7c950cb4023e14d10fb98a0ffede5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
 * @file node.h
 *
 * Functions related to nodes in the AST.
 */
#ifndef PRISM_NODE_H
#define PRISM_NODE_H

#include "prism/defines.h"
#include "prism/parser.h"
#include "prism/util/pm_buffer.h"

/**
 * Loop through each node in the node list, writing each node to the given
 * pm_node_t pointer.
 */
#define PM_NODE_LIST_FOREACH(list, index, node) \
    for (size_t index = 0; index < (list)->size && ((node) = (list)->nodes[index]); index++)

/**
 * Append a new node onto the end of the node list.
 *
 * @param list The list to append to.
 * @param node The node to append.
 */
void pm_node_list_append(pm_node_list_t *list, pm_node_t *node);

/**
 * Prepend a new node onto the beginning of the node list.
 *
 * @param list The list to prepend to.
 * @param node The node to prepend.
 */
void pm_node_list_prepend(pm_node_list_t *list, pm_node_t *node);

/**
 * Concatenate the given node list onto the end of the other node list.
 *
 * @param list The list to concatenate onto.
 * @param other The list to concatenate.
 */
void pm_node_list_concat(pm_node_list_t *list, pm_node_list_t *other);

/**
 * Free the internal memory associated with the given node list.
 *
 * @param list The list to free.
 */
void pm_node_list_free(pm_node_list_t *list);

/**
 * Deallocate a node and all of its children.
 *
 * @param parser The parser that owns the node.
 * @param node The node to deallocate.
 */
PRISM_EXPORTED_FUNCTION void pm_node_destroy(pm_parser_t *parser, struct pm_node *node);

/**
 * Returns a string representation of the given node type.
 *
 * @param node_type The node type to convert to a string.
 * @return A string representation of the given node type.
 */
PRISM_EXPORTED_FUNCTION const char * pm_node_type_to_str(pm_node_type_t node_type);

/**
 * Visit each of the nodes in this subtree using the given visitor callback. The
 * callback function will be called for each node in the subtree. If it returns
 * false, then that node's children will not be visited. If it returns true,
 * then the children will be visited. The data parameter is treated as an opaque
 * pointer and is passed to the visitor callback for consumers to use as they
 * see fit.
 *
 * As an example:
 *
 * ```c
 * #include "prism.h"
 *
 * bool visit(const pm_node_t *node, void *data) {
 *     size_t *indent = (size_t *) data;
 *     for (size_t i = 0; i < *indent * 2; i++) putc(' ', stdout);
 *     printf("%s\n", pm_node_type_to_str(node->type));
 *
 *     size_t next_indent = *indent + 1;
 *     size_t *next_data = &next_indent;
 *     pm_visit_child_nodes(node, visit, next_data);
 *
 *     return false;
 * }
 *
 * int main(void) {
 *     const char *source = "1 + 2; 3 + 4";
 *     size_t size = strlen(source);
 *
 *     pm_parser_t parser;
 *     pm_options_t options = { 0 };
 *     pm_parser_init(&parser, (const uint8_t *) source, size, &options);
 *
 *     size_t indent = 0;
 *     pm_node_t *node = pm_parse(&parser);
 *
 *     size_t *data = &indent;
 *     pm_visit_node(node, visit, data);
 *
 *     pm_node_destroy(&parser, node);
 *     pm_parser_free(&parser);
 *     return EXIT_SUCCESS;
 * }
 * ```
 *
 * @param node The root node to start visiting from.
 * @param visitor The callback to call for each node in the subtree.
 * @param data An opaque pointer that is passed to the visitor callback.
 */
PRISM_EXPORTED_FUNCTION void pm_visit_node(const pm_node_t *node, bool (*visitor)(const pm_node_t *node, void *data), void *data);

/**
 * Visit the children of the given node with the given callback. This is the
 * default behavior for walking the tree that is called from pm_visit_node if
 * the callback returns true.
 *
 * @param node The node to visit the children of.
 * @param visitor The callback to call for each child node.
 * @param data An opaque pointer that is passed to the visitor callback.
 */
PRISM_EXPORTED_FUNCTION void pm_visit_child_nodes(const pm_node_t *node, bool (*visitor)(const pm_node_t *node, void *data), void *data);

#endif