summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Newton <[email protected]>2024-04-02 15:54:32 -0400
committerKevin Newton <[email protected]>2024-04-03 17:34:12 -0400
commit1fb11824f31472bda09812af5532b2d63c0f95a5 (patch)
tree4d90bfc64c122585889ebdbae83f9e0f84832cee
parent198d197aeb79566673db2440a3b90ff87ff279cd (diff)
[ruby/prism] Introduce PM_NODE_LIST_FOREACH to make it easier to iterate over node lists
https://github.com/ruby/prism/commit/5d4da7c69c
-rw-r--r--prism/node.h7
-rw-r--r--prism/prism.c43
-rw-r--r--prism/templates/src/node.c.erb14
3 files changed, 35 insertions, 29 deletions
diff --git a/prism/node.h b/prism/node.h
index a001b4a9e4..f2f5d21133 100644
--- a/prism/node.h
+++ b/prism/node.h
@@ -11,6 +11,13 @@
#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++)
+
+/**
* Attempts to grow the node list to the next size. If there is already
* capacity in the list, this function does nothing. Otherwise it reallocates
* the list to be twice as large as it was before. If the reallocation fails,
diff --git a/prism/prism.c b/prism/prism.c
index c6971fbd88..f8d52a88a8 100644
--- a/prism/prism.c
+++ b/prism/prism.c
@@ -833,11 +833,14 @@ pm_conditional_predicate_warn_write_literal_p(const pm_node_t *node) {
switch (PM_NODE_TYPE(node)) {
case PM_ARRAY_NODE: {
const pm_array_node_t *cast = (const pm_array_node_t *) node;
- for (size_t index = 0; index < cast->elements.size; index++) {
- if (!pm_conditional_predicate_warn_write_literal_p(cast->elements.nodes[index])) {
+ const pm_node_t *element;
+
+ PM_NODE_LIST_FOREACH(&cast->elements, index, element) {
+ if (!pm_conditional_predicate_warn_write_literal_p(element)) {
return false;
}
}
+
return true;
}
case PM_FALSE_NODE:
@@ -1611,9 +1614,9 @@ pm_array_pattern_node_node_list_create(pm_parser_t *parser, pm_node_list_t *node
// For now we're going to just copy over each pointer manually. This could be
// much more efficient, as we could instead resize the node list.
bool found_rest = false;
- for (size_t index = 0; index < nodes->size; index++) {
- pm_node_t *child = nodes->nodes[index];
+ pm_node_t *child;
+ PM_NODE_LIST_FOREACH(nodes, index, child) {
if (!found_rest && (PM_NODE_TYPE_P(child, PM_SPLAT_NODE) || PM_NODE_TYPE_P(child, PM_IMPLICIT_REST_NODE))) {
node->rest = child;
found_rest = true;
@@ -3728,8 +3731,8 @@ pm_hash_pattern_node_node_list_create(pm_parser_t *parser, pm_node_list_t *eleme
.closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE
};
- for (size_t index = 0; index < elements->size; index++) {
- pm_node_t *element = elements->nodes[index];
+ pm_node_t *element;
+ PM_NODE_LIST_FOREACH(elements, index, element) {
pm_node_list_append(&node->elements, element);
}
@@ -4487,8 +4490,9 @@ pm_interpolated_string_node_create(pm_parser_t *parser, const pm_token_t *openin
};
if (parts != NULL) {
- for (size_t index = 0; index < parts->size; index++) {
- pm_interpolated_string_node_append(parser, node, parts->nodes[index]);
+ pm_node_t *part;
+ PM_NODE_LIST_FOREACH(parts, index, part) {
+ pm_interpolated_string_node_append(parser, node, part);
}
}
@@ -4550,8 +4554,9 @@ pm_interpolated_symbol_node_create(pm_parser_t *parser, const pm_token_t *openin
};
if (parts != NULL) {
- for (size_t index = 0; index < parts->size; index++) {
- pm_interpolated_symbol_node_append(node, parts->nodes[index]);
+ pm_node_t *part;
+ PM_NODE_LIST_FOREACH(parts, index, part) {
+ pm_interpolated_symbol_node_append(node, part);
}
}
@@ -14600,9 +14605,8 @@ parse_heredoc_dedent(pm_parser_t *parser, pm_node_list_t *nodes, size_t common_w
// the whitespace from a node, then we'll drop it from the list entirely.
size_t write_index = 0;
- for (size_t read_index = 0; read_index < nodes->size; read_index++) {
- pm_node_t *node = nodes->nodes[read_index];
-
+ pm_node_t *node;
+ PM_NODE_LIST_FOREACH(nodes, read_index, node) {
// We're not manipulating child nodes that aren't strings. In this case
// we'll skip past it and indicate that the subsequent node should not
// be dedented.
@@ -16801,8 +16805,8 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
if (!match2(parser, PM_TOKEN_KEYWORD_WHILE_MODIFIER, PM_TOKEN_KEYWORD_UNTIL_MODIFIER)) {
// If we didn't find a while or until modifier, then we need to
// go back in and mark all of the block exits as invalid.
- for (size_t block_exit_index = 0; block_exit_index < current_block_exits.size; block_exit_index++) {
- pm_node_t *block_exit = current_block_exits.nodes[block_exit_index];
+ pm_node_t *block_exit;
+ PM_NODE_LIST_FOREACH(&current_block_exits, block_exit_index, block_exit) {
const char *type;
switch (PM_NODE_TYPE(block_exit)) {
@@ -18981,9 +18985,8 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
bool interpolated = false;
size_t total_length = 0;
- for (size_t index = 0; index < parts->size; index++) {
- pm_node_t *part = parts->nodes[index];
-
+ pm_node_t *part;
+ PM_NODE_LIST_FOREACH(parts, index, part) {
if (PM_NODE_TYPE_P(part, PM_STRING_NODE)) {
total_length += pm_string_length(&((pm_string_node_t *) part)->unescaped);
} else {
@@ -18997,8 +19000,8 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
if (!memory) abort();
uint8_t *cursor = memory;
- for (size_t index = 0; index < parts->size; index++) {
- pm_string_t *unescaped = &((pm_string_node_t *) parts->nodes[index])->unescaped;
+ PM_NODE_LIST_FOREACH(parts, index, part) {
+ pm_string_t *unescaped = &((pm_string_node_t *) part)->unescaped;
size_t length = pm_string_length(unescaped);
memcpy(cursor, pm_string_source(unescaped), length);
diff --git a/prism/templates/src/node.c.erb b/prism/templates/src/node.c.erb
index 99a0c92fa9..967f156e6d 100644
--- a/prism/templates/src/node.c.erb
+++ b/prism/templates/src/node.c.erb
@@ -9,11 +9,9 @@ pm_node_memsize_node(pm_node_t *node, pm_memsize_t *memsize);
*/
static size_t
pm_node_list_memsize(pm_node_list_t *node_list, pm_memsize_t *memsize) {
- size_t size = sizeof(pm_node_list_t) + (node_list->capacity * sizeof(pm_node_t *));
- for (size_t index = 0; index < node_list->size; index++) {
- pm_node_memsize_node(node_list->nodes[index], memsize);
- }
- return size;
+ pm_node_t *node;
+ PM_NODE_LIST_FOREACH(node_list, index, node) pm_node_memsize_node(node, memsize);
+ return sizeof(pm_node_list_t) + (node_list->capacity * sizeof(pm_node_t *));
}
/**
@@ -73,10 +71,8 @@ pm_node_destroy(pm_parser_t *parser, pm_node_t *node);
*/
static void
pm_node_list_destroy(pm_parser_t *parser, pm_node_list_t *list) {
- for (size_t index = 0; index < list->size; index++) {
- pm_node_destroy(parser, list->nodes[index]);
- }
-
+ pm_node_t *node;
+ PM_NODE_LIST_FOREACH(list, index, node) pm_node_destroy(parser, node);
pm_node_list_free(list);
}