Add a way to quickly traverse the parse tree
authorLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Wed, 13 Aug 2025 19:45:29 +0000 (21:45 +0200)
committerLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Wed, 13 Aug 2025 19:45:29 +0000 (21:45 +0200)
Makefile
ft_parse/ft_get_child_deep.c [new file with mode: 0644]
ft_parse/ft_get_child_deep_size_t.c [new file with mode: 0644]
inc/ft_parse.h

index 0b80c08b850fc7aa0ea195ad941afa087fcf5afb..d54f3a28fa56da8f4782d02030f7366d0159ec1c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -64,6 +64,8 @@ SRCparse:=    ft_parse.c                                                                                              \
                        add_line.c                                                                                              \
                        actions.c                                                                                               \
                        helpers.c                                                                                               \
+                       ft_get_child_deep.c                                                                             \
+                       ft_get_child_deep_size_t.c                                                              \
 
 SRCgen :=      ft_swap.c                                                                                               \
 
diff --git a/ft_parse/ft_get_child_deep.c b/ft_parse/ft_get_child_deep.c
new file mode 100644 (file)
index 0000000..d2adcbc
--- /dev/null
@@ -0,0 +1,66 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_get_child_deep.c                                :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/08/13 21:01:34 by ljiriste          #+#    #+#             */
+/*   Updated: 2025/08/13 21:45:10 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "ft_parse.h"
+#include "libft.h"
+#include <stdarg.h>
+
+t_parse_tree_node      *ft_vget_child_deep(
+                                                       t_parse_tree_node *node, size_t depth, va_list *args)
+{
+       int     index;
+
+       index = va_arg(*args, int);
+       if (index < 0)
+               return (NULL);
+       if (!node || depth == 0)
+               return (node);
+       return (ft_vget_child_deep(ft_get_node_child(node, (size_t)index), depth - 1, args));
+}
+
+t_parse_tree_node      *ft_get_child_deep(
+                                                       t_parse_tree_node *node, size_t depth, ...)
+{
+       va_list                         args;
+       t_parse_tree_node       *res;
+
+       va_start(args, depth);
+       res = ft_vget_child_deep(node, depth, &args);
+       va_end(args);
+       return (res);
+}
+
+
+const t_parse_tree_node        *ft_vcget_child_deep(
+                                                       const t_parse_tree_node *node, size_t depth, va_list *args)
+{
+       int     index;
+
+       index = va_arg(*args, int);
+       if (index < 0)
+               return (NULL);
+       if (!node || depth == 0)
+               return (node);
+       return (ft_vcget_child_deep(ft_cget_node_child(node, (size_t)index), depth - 1, args));
+}
+
+const t_parse_tree_node        *ft_cget_child_deep(
+                                                       const t_parse_tree_node *node, size_t depth, ...)
+{
+       va_list                                 args;
+       const t_parse_tree_node *res;
+
+       va_start(args, depth);
+       res = ft_vcget_child_deep(node, depth, &args);
+       va_end(args);
+       return (res);
+}
diff --git a/ft_parse/ft_get_child_deep_size_t.c b/ft_parse/ft_get_child_deep_size_t.c
new file mode 100644 (file)
index 0000000..b0ad0f3
--- /dev/null
@@ -0,0 +1,56 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_get_child_deep_size_t.c                         :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/08/13 21:37:45 by ljiriste          #+#    #+#             */
+/*   Updated: 2025/08/13 21:44:59 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "ft_parse.h"
+#include "libft.h"
+#include <stdarg.h>
+
+t_parse_tree_node      *ft_vget_child_deep_size_t(
+                                                       t_parse_tree_node *node, size_t depth, va_list *args)
+{
+       if (!node || depth == 0)
+               return (node);
+       return (ft_vget_child_deep_size_t(ft_get_node_child(node, va_arg(*args, size_t)), depth - 1, args));
+}
+
+t_parse_tree_node      *ft_get_child_deep_size_t(
+                                                       t_parse_tree_node *node, size_t depth, ...)
+{
+       va_list                         args;
+       t_parse_tree_node       *res;
+
+       va_start(args, depth);
+       res = ft_vget_child_deep_size_t(node, depth, &args);
+       va_end(args);
+       return (res);
+}
+
+
+const t_parse_tree_node        *ft_vcget_child_deep_size_t(
+                                                       const t_parse_tree_node *node, size_t depth, va_list *args)
+{
+       if (!node || depth == 0)
+               return (node);
+       return (ft_vcget_child_deep_size_t(ft_cget_node_child(node, va_arg(*args, size_t)), depth - 1, args));
+}
+
+const t_parse_tree_node        *ft_cget_child_deep_size_t(
+                                                       const t_parse_tree_node *node, size_t depth, ...)
+{
+       va_list                                 args;
+       const t_parse_tree_node *res;
+
+       va_start(args, depth);
+       res = ft_vcget_child_deep_size_t(node, depth, &args);
+       va_end(args);
+       return (res);
+}
index f051332a335ef3d45232797d0360ad181291f836..12d85de0c8dcaecbb68ea87938ded2cc45120cb6 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/05/27 21:21:54 by ljiriste          #+#    #+#             */
-/*   Updated: 2025/07/28 11:57:21 by ljiriste         ###   ########.fr       */
+/*   Updated: 2025/08/13 21:41:14 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -117,6 +117,21 @@ t_parse_tree_node          *ft_get_node_child(
 const t_parse_tree_node        *ft_cget_node_child(
                                                        const t_parse_tree_node *node, size_t index);
 
+// Because there is no ergonomic way to tell the ellipses to cast literals to
+// size_t I opt to make these two only accept (non-negative) integers
+// If you need the size_t variant use the size_t variant,
+t_parse_tree_node              *ft_get_child_deep(
+                                                       t_parse_tree_node *node, size_t depth, ...);
+const t_parse_tree_node        *ft_cget_child_deep(
+                                                       const t_parse_tree_node *node, size_t depth, ...);
+
+// but you must cast literals (and non-size_t vars) to size_t explicitly
+// for the ellipses to work
+t_parse_tree_node              *ft_get_child_deep_size_t(
+                                                       t_parse_tree_node *node, size_t depth, ...);
+const t_parse_tree_node        *ft_cget_child_deep_size_t(
+                                                       const t_parse_tree_node *node, size_t depth, ...);
+
 void                                   ft_parse_tree_free(void *node);
 void                                   ft_parsing_table_free(t_parsing_table *table);