Make parsing.c completely Norm compliant
authorLukas Jiriste <ljiriste@student.42prague.com>
Tue, 14 Jan 2025 14:14:46 +0000 (15:14 +0100)
committerLukas Jiriste <ljiriste@student.42prague.com>
Tue, 14 Jan 2025 14:14:46 +0000 (15:14 +0100)
Makefile
inc/miniRT.h
src/parse_elements.c [new file with mode: 0644]
src/parse_rt.c [new file with mode: 0644]
src/parse_small.c [new file with mode: 0644]
src/parsing.c
src/tokenize.c [new file with mode: 0644]

index ea2178a98841fb6471c1a325f0959ee0d873e73d..97c3156064609a224bfec49ebedf879e82b3b6fd 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -23,7 +23,11 @@ SRCDIR := src
 SOURCES :=     main.c                          \
                        scene.c                         \
                        manipulation.c          \
+                       tokenize.c                      \
                        parsing.c                       \
+                       parse_rt.c                      \
+                       parse_small.c           \
+                       parse_elements.c        \
                        vec3.c                          \
 
 SOURCES := $(addprefix $(SRCDIR)/, $(SOURCES))
index 34bccb091c5a101103c6a391a81eeb2f9809ce4b..6144fd922f3f0c0a44d826e81ea866c3654dbca7 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2025/01/13 19:51:09 by ljiriste          #+#    #+#             */
-/*   Updated: 2025/01/13 19:54:00 by ljiriste         ###   ########.fr       */
+/*   Updated: 2025/01/14 15:13:53 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -147,6 +147,24 @@ typedef struct s_obstruction
        double          distance;
 }                                      t_obstruction;
 
+void                   free_token(void *token);
+int                            tokenize(const char *filename, t_vec *tokens);
+
+double                 node_to_double(const t_parse_tree_node *double_node);
+t_color                        node_to_linear_rgb(const t_parse_tree_node *rgb_node);
+t_vec3                 node_to_vec3(const t_parse_tree_node *vec3_node);
+
+int                            add_light(const t_parse_tree_node *light_node, t_vec *lights);
+int                            add_camera(
+                                       const t_parse_tree_node *camera_node, t_vec *cameras);
+int                            add_plane(const t_parse_tree_node *plane_node, t_vec *objects);
+int                            add_sphere(
+                                       const t_parse_tree_node *sphere_node, t_vec *objects);
+int                            add_cylinder(
+                                       const t_parse_tree_node *cylinder_node, t_vec *objects);
+
+int                            parse_rt_file(const char *filename, t_scene *scene);
+
 t_color                        trace_ray(const t_ray *ray, t_scene *scene);
 t_color                        color_srgb_to_lin(t_color_srgb srgb);
 
diff --git a/src/parse_elements.c b/src/parse_elements.c
new file mode 100644 (file)
index 0000000..7899957
--- /dev/null
@@ -0,0 +1,111 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   parse_elements.c                                   :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/01/14 14:59:40 by ljiriste          #+#    #+#             */
+/*   Updated: 2025/01/14 15:12:32 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "miniRT.h"
+#include "libft.h"
+
+#ifndef M_PI
+# define M_PI 3.14159265358979323846
+#endif // M_PI
+
+int    add_light(const t_parse_tree_node *light_node, t_vec *lights)
+{
+       t_element       element;
+       t_light         *light;
+
+       element.type = LIGHT;
+       light = &element.object.light;
+       light->brightness = node_to_double(
+                       ft_cget_node_child(ft_cget_node_child(light_node, 2), 0));
+       light->position = node_to_vec3(ft_cget_node_child(
+                               ft_cget_node_child(light_node, 1), 0));
+       if (light_node->children.size == 4)
+               light->color = node_to_linear_rgb(ft_cget_node_child(light_node, 3));
+       else
+               light->color = (t_color){.x = 1, .y = 1, .z = 1};
+       return (ft_vec_append(lights, &element) != success);
+}
+
+int    add_camera(const t_parse_tree_node *camera_node, t_vec *cameras)
+{
+       t_element       element;
+       t_camera        *camera;
+
+       element.type = CAMERA;
+       camera = &element.object.camera;
+       camera->position = node_to_vec3(ft_cget_node_child(
+                               ft_cget_node_child(camera_node, 1), 0));
+       camera->orientation = node_to_vec3(ft_cget_node_child(camera_node, 2));
+       camera->orientation = vec_normalize(camera->orientation);
+       camera->up_direction = (t_vec3){.x = 0, .y = 0, .z = 1};
+       camera->up_direction = vec_vec_mul(
+                       camera->orientation, camera->up_direction);
+       if (vec_norm(camera->up_direction) < 1e-3)
+               camera->up_direction = (t_vec3){.x = 0, .y = 1, .z = 0};
+       camera->up_direction = vec_vec_mul(
+                       camera->up_direction, camera->orientation);
+       camera->up_direction = vec_normalize(camera->up_direction);
+       camera->field_of_view = node_to_double(ft_cget_node_child(
+                               ft_cget_node_child(camera_node, 3), 0)) * M_PI / 180;
+       return (ft_vec_append(cameras, &element) != success);
+}
+
+int    add_plane(const t_parse_tree_node *plane_node, t_vec *objects)
+{
+       t_object        object;
+       t_plane         *plane;
+
+       object.type = PLANE;
+       plane = &object.object.plane;
+       plane->point = node_to_vec3(
+                       ft_cget_node_child(ft_cget_node_child(plane_node, 1), 0));
+       plane->normal = node_to_vec3(ft_cget_node_child(plane_node, 2));
+       plane->color = node_to_linear_rgb(ft_cget_node_child(plane_node, 3));
+       plane->normal = vec_normalize(plane->normal);
+       return (ft_vec_append(objects, &object) != success);
+}
+
+int    add_sphere(const t_parse_tree_node *sphere_node, t_vec *objects)
+{
+       t_object        object;
+       t_sphere        *sphere;
+
+       object.type = SPHERE;
+       sphere = &object.object.sphere;
+       sphere->center = node_to_vec3(
+                       ft_cget_node_child(ft_cget_node_child(sphere_node, 1), 0));
+       sphere->radius = node_to_double(
+                       ft_cget_node_child(ft_cget_node_child(sphere_node, 2), 0)) / 2;
+       sphere->color = node_to_linear_rgb(ft_cget_node_child(sphere_node, 3));
+       return (ft_vec_append(objects, &object) != success);
+}
+
+int    add_cylinder(const t_parse_tree_node *cylinder_node, t_vec *objects)
+{
+       t_object        object;
+       t_cylinder      *cylinder;
+
+       object.type = CYLINDER;
+       cylinder = &object.object.cylinder;
+       cylinder->center = node_to_vec3(
+                       ft_cget_node_child(ft_cget_node_child(cylinder_node, 1), 0));
+       cylinder->rot_axis = node_to_vec3(ft_cget_node_child(cylinder_node, 2));
+       cylinder->rot_axis = vec_normalize(cylinder->rot_axis);
+       cylinder->color = node_to_linear_rgb(ft_cget_node_child(cylinder_node, 5));
+       cylinder->radius = node_to_double(
+                       ft_cget_node_child(ft_cget_node_child(cylinder_node, 3), 0)) / 2;
+       cylinder->height = node_to_double(
+                       ft_cget_node_child(ft_cget_node_child(cylinder_node, 4), 0));
+       object.object.sphere.color
+               = node_to_linear_rgb(ft_cget_node_child(cylinder_node, 5));
+       return (ft_vec_append(objects, &object) != success);
+}
diff --git a/src/parse_rt.c b/src/parse_rt.c
new file mode 100644 (file)
index 0000000..9c85a9f
--- /dev/null
@@ -0,0 +1,105 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   parse_rt.c                                         :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/01/14 15:09:41 by ljiriste          #+#    #+#             */
+/*   Updated: 2025/01/14 15:12:52 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "parsing_info.h"
+#include "miniRT.h"
+#include "libft.h"
+#include <stdlib.h>
+
+void   free_token(void *v_token)
+{
+       t_token *token;
+
+       token = v_token;
+       free(token->str);
+       return ;
+}
+
+static void    set_ambient_light(
+                       const t_parse_tree_node *ambient_node, t_ambient_light *ambient)
+{
+       const t_parse_tree_node *intensity_node;
+       const t_parse_tree_node *rgb_node;
+
+       intensity_node = ft_cget_node_child(ambient_node, 1);
+       rgb_node = ft_cget_node_child(ambient_node, 2);
+       ambient->brightness = node_to_double(ft_cget_node_child(intensity_node, 0));
+       ambient->color = node_to_linear_rgb(rgb_node);
+       return ;
+}
+
+static int     add_element_to_scene(
+                               const t_parse_tree_node *element, t_scene *scene)
+{
+       const char                              *type;
+       const t_parse_tree_node *specific_element;
+
+       specific_element = ft_cget_node_child(element, 0);
+       type = specific_element->token.type;
+       if (!ft_strcmp(type, "ambient_light"))
+               set_ambient_light(specific_element, &scene->ambient_light);
+       else if (!ft_strcmp(type, "light")
+               && add_light(specific_element, &scene->lights))
+               return (1);
+       else if (!ft_strcmp(type, "camera")
+               && add_camera(specific_element, &scene->cameras))
+               return (1);
+       else if (!ft_strcmp(type, "sphere")
+               && add_sphere(specific_element, &scene->objects))
+               return (1);
+       else if (!ft_strcmp(type, "plane")
+               && add_plane(specific_element, &scene->objects))
+               return (1);
+       else if (!ft_strcmp(type, "cylinder")
+               && add_cylinder(specific_element, &scene->objects))
+               return (1);
+       return (0);
+}
+
+static int     parse_tree_to_scene(const t_parse_tree_node *tree, t_scene *scene)
+{
+       if (tree->children.size == 2)
+       {
+               if (parse_tree_to_scene(ft_cget_node_child(tree, 0), scene))
+                       return (1);
+               if (add_element_to_scene(ft_cget_node_child(tree, 1), scene))
+                       return (1);
+       }
+       return (0);
+}
+
+int    parse_rt_file(const char *filename, t_scene *scene)
+{
+       int                                     res;
+       t_vec                           tokens;
+       t_parsing_table         parsing_table;
+       t_parse_tree_node       *parse_tree;
+
+       res = 1;
+       ft_vec_init(&tokens, sizeof(t_token));
+       if (!tokenize(filename, &tokens))
+       {
+               if (ft_parsing_table_init(&parsing_table) == success
+                       && ft_parsing_table_load_str
+                       (&parsing_table, g_parsing_table, g_grammar) == success)
+               {
+                       parse_tree = ft_parse(&tokens, &parsing_table);
+                       if (parse_tree && !parse_tree_to_scene(parse_tree, scene)
+                               && scene->cameras.size > 0)
+                               res = 0;
+                       ft_parse_tree_free(parse_tree);
+               }
+               ft_parsing_table_free(&parsing_table);
+       }
+       ft_vec_free(&tokens, free_token);
+       return (res);
+}
diff --git a/src/parse_small.c b/src/parse_small.c
new file mode 100644 (file)
index 0000000..65dee7f
--- /dev/null
@@ -0,0 +1,74 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   parse_small.c                                      :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/01/14 15:04:18 by ljiriste          #+#    #+#             */
+/*   Updated: 2025/01/14 15:13:05 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "miniRT.h"
+#include "libft.h"
+
+static int     node_to_int(const t_parse_tree_node *int_node)
+{
+       return (ft_atoi(int_node->token.str));
+}
+
+double node_to_double(const t_parse_tree_node *double_node)
+{
+       int                     whole;
+       int                     sign;
+       double          decimal;
+       const char      *str;
+
+       if (double_node->children.size == 1)
+               return (node_to_int(ft_cget_node_child(double_node, 0)));
+       str = ft_cget_node_child(double_node, 0)->token.str;
+       sign = 1;
+       if (str[0] == '-')
+       {
+               sign = -1;
+               ++str;
+       }
+       whole = ft_atoi(str);
+       str = ft_cget_node_child(double_node, 2)->token.str;
+       decimal = ft_atoi(str);
+       while (*str)
+       {
+               decimal /= 10;
+               ++str;
+       }
+       return (sign * (whole + decimal));
+}
+
+t_color        node_to_linear_rgb(const t_parse_tree_node *rgb_node)
+{
+       const t_parse_tree_node *int_node;
+       t_color_srgb                    color;
+
+       int_node = ft_cget_node_child(rgb_node, 0);
+       color.r = node_to_int(int_node);
+       int_node = ft_cget_node_child(rgb_node, 2);
+       color.g = node_to_int(int_node);
+       int_node = ft_cget_node_child(rgb_node, 4);
+       color.b = node_to_int(int_node);
+       return (color_srgb_to_lin(color));
+}
+
+t_vec3 node_to_vec3(const t_parse_tree_node *vec3_node)
+{
+       const t_parse_tree_node *double_node;
+       t_vec3                                  res;
+
+       double_node = ft_cget_node_child(vec3_node, 0);
+       res.x = node_to_double(double_node);
+       double_node = ft_cget_node_child(vec3_node, 2);
+       res.y = node_to_double(double_node);
+       double_node = ft_cget_node_child(vec3_node, 4);
+       res.z = node_to_double(double_node);
+       return (res);
+}
index 6b957c06e785ecbde7b4e549e948ad8b3b08ab24..047e92ed0fd68ecbf33f4316beb55c36d4af7a15 100644 (file)
 /*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/11/28 12:34:20 by ljiriste          #+#    #+#             */
-/*   Updated: 2025/01/13 19:54:25 by ljiriste         ###   ########.fr       */
+/*   Updated: 2025/01/14 15:10:27 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
-#include "parsing_info.h"
 #include "miniRT.h"
 #include "libft.h"
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#ifndef M_PI
-# define M_PI 3.14159265358979323846
-#endif // M_PI
-
-const char     *extract_keyword(const char *line, size_t *i)
-{
-       if (line[*i + 1] == '\0' || ft_isspace(line[*i + 1]))
-       {
-               if (line[*i] == 'A')
-                       return ("A");
-               if (line[*i] == 'C')
-                       return ("C");
-               if (line[*i] == 'L')
-                       return ("L");
-       }
-       else if (line[*i + 2] == '\0' || ft_isspace(line[*i + 2]))
-       {
-               ++*i;
-               if (!ft_strncmp(line + *i - 1, "cy", 2))
-                       return ("CY");
-               if (!ft_strncmp(line + *i - 1, "pl", 2))
-                       return ("PL");
-               if (!ft_strncmp(line + *i - 1, "sp", 2))
-                       return ("SP");
-       }
-       return (NULL);
-}
-
-char   *extract_int(const char *line, size_t *i)
-{
-       size_t  j;
-
-       j = *i;
-       while (ft_isdigit(line[*i]) || line[*i] == '-')
-               ++*i;
-       return (ft_strndup(line + j, ((*i)--) - j));
-}
-
-void   free_token(void *v_token)
-{
-       t_token *token;
-
-       token = v_token;
-       free(token->str);
-       return ;
-}
-
-int    tokenize_line(const char *line, t_vec *tokens)
-{
-       size_t  i;
-       t_token token;
-
-       i = 0;
-       while (line[i])
-       {
-               token.str = NULL;
-               while (ft_isspace(line[i]))
-                       ++i;
-               if (!line[i])
-                       break ;
-               if (line[i] == '.')
-                       token.type = "DOT";
-               else if (line[i] == ',')
-                       token.type = "COMMA";
-               else if (ft_isdigit(line[i]) || line[i] == '-')
-               {
-                       token.type = "INT";
-                       token.str = extract_int(line, &i);
-                       if (!token.str)
-                               return (1);
-               }
-               else
-               {
-                       token.type = (char *)extract_keyword(line, &i);
-                       if (!token.type)
-                               return (1);
-               }
-               if (ft_vec_append(tokens, &token) != success)
-               {
-                       free_token(&token);
-                       return (1);
-               }
-               ++i;
-       }
-       return (0);
-}
-
-int    tokenize(const char *filename, t_vec *tokens)
-{
-       int             fd;
-       char    *line;
-
-       fd = open(filename, O_RDONLY);
-       if (fd < 0)
-               return (1);
-       line = get_next_line(fd);
-       while (line)
-       {
-               if (ft_strncmp(line, "//", 2) && tokenize_line(line, tokens))
-               {
-                       free(line);
-                       get_next_line(-1);
-                       close(fd);
-                       return (1);
-               }
-               free(line);
-               line = get_next_line(fd);
-       }
-       close(fd);
-       return (0);
-}
-
-int    node_to_int(const t_parse_tree_node *int_node)
-{
-       return (ft_atoi(int_node->token.str));
-}
-
-double node_to_double(const t_parse_tree_node *double_node)
-{
-       int                     whole;
-       int                     sign;
-       double          decimal;
-       const char      *str;
-
-       if (double_node->children.size == 1)
-               return (node_to_int(ft_cget_node_child(double_node, 0)));
-       str = ft_cget_node_child(double_node, 0)->token.str;
-       sign = 1;
-       if (str[0] == '-')
-       {
-               sign = -1;
-               ++str;
-       }
-       whole = ft_atoi(str);
-       str = ft_cget_node_child(double_node, 2)->token.str;
-       decimal = ft_atoi(str);
-       while (*str)
-       {
-               decimal /= 10;
-               ++str;
-       }
-       return (sign * (whole + decimal));
-}
-
-t_color        node_to_linear_rgb(const t_parse_tree_node *rgb_node)
-{
-       const t_parse_tree_node *int_node;
-       t_color_srgb                    color;
-
-       int_node = ft_cget_node_child(rgb_node, 0);
-       color.r = node_to_int(int_node);
-       int_node = ft_cget_node_child(rgb_node, 2);
-       color.g = node_to_int(int_node);
-       int_node = ft_cget_node_child(rgb_node, 4);
-       color.b = node_to_int(int_node);
-       return (color_srgb_to_lin(color));
-}
-
-t_vec3 node_to_vec3(const t_parse_tree_node *vec3_node)
-{
-       const t_parse_tree_node *double_node;
-       t_vec3                                  res;
-
-       double_node = ft_cget_node_child(vec3_node, 0);
-       res.x = node_to_double(double_node);
-       double_node = ft_cget_node_child(vec3_node, 2);
-       res.y = node_to_double(double_node);
-       double_node = ft_cget_node_child(vec3_node, 4);
-       res.z = node_to_double(double_node);
-       return (res);
-}
-
-void   set_ambient_light(
-                       const t_parse_tree_node *ambient_node, t_ambient_light *ambient)
-{
-       const t_parse_tree_node *intensity_node;
-       const t_parse_tree_node *rgb_node;
-
-       intensity_node = ft_cget_node_child(ambient_node, 1);
-       rgb_node = ft_cget_node_child(ambient_node, 2);
-       ambient->brightness = node_to_double(ft_cget_node_child(intensity_node, 0));
-       ambient->color = node_to_linear_rgb(rgb_node);
-       return ;
-}
-
-int    add_light(const t_parse_tree_node *light_node, t_vec *lights)
-{
-       t_element       element;
-       t_light         *light;
-
-       element.type = LIGHT;
-       light = &element.object.light;
-       light->brightness = node_to_double(
-                       ft_cget_node_child(ft_cget_node_child(light_node, 2), 0));
-       light->position = node_to_vec3(ft_cget_node_child(
-                               ft_cget_node_child(light_node, 1), 0));
-       if (light_node->children.size == 4)
-               light->color = node_to_linear_rgb(ft_cget_node_child(light_node, 3));
-       else
-               light->color = (t_color){.x = 1, .y = 1, .z = 1};
-       return (ft_vec_append(lights, &element) != success);
-}
-
-int    add_camera(const t_parse_tree_node *camera_node, t_vec *cameras)
-{
-       t_element       element;
-       t_camera        *camera;
-
-       element.type = CAMERA;
-       camera = &element.object.camera;
-       camera->position = node_to_vec3(ft_cget_node_child(
-                               ft_cget_node_child(camera_node, 1), 0));
-       camera->orientation = node_to_vec3(ft_cget_node_child(camera_node, 2));
-       camera->orientation = vec_normalize(camera->orientation);
-       camera->up_direction = (t_vec3){.x = 0, .y = 0, .z = 1};
-       camera->up_direction = vec_vec_mul(
-                       camera->orientation, camera->up_direction);
-       if (vec_norm(camera->up_direction) < 1e-3)
-               camera->up_direction = (t_vec3){.x = 0, .y = 1, .z = 0};
-       camera->up_direction = vec_vec_mul(
-                       camera->up_direction, camera->orientation);
-       camera->up_direction = vec_normalize(camera->up_direction);
-       camera->field_of_view = node_to_double(ft_cget_node_child(
-                               ft_cget_node_child(camera_node, 3), 0)) * M_PI / 180;
-       return (ft_vec_append(cameras, &element) != success);
-}
-
-int    add_plane(const t_parse_tree_node *plane_node, t_vec *objects)
-{
-       t_object        object;
-       t_plane         *plane;
-
-       object.type = PLANE;
-       plane = &object.object.plane;
-       plane->point = node_to_vec3(
-                       ft_cget_node_child(ft_cget_node_child(plane_node, 1), 0));
-       plane->normal = node_to_vec3(ft_cget_node_child(plane_node, 2));
-       plane->color = node_to_linear_rgb(ft_cget_node_child(plane_node, 3));
-       plane->normal = vec_normalize(plane->normal);
-       return (ft_vec_append(objects, &object) != success);
-}
-
-int    add_sphere(const t_parse_tree_node *sphere_node, t_vec *objects)
-{
-       t_object        object;
-       t_sphere        *sphere;
-
-       object.type = SPHERE;
-       sphere = &object.object.sphere;
-       sphere->center = node_to_vec3(
-                       ft_cget_node_child(ft_cget_node_child(sphere_node, 1), 0));
-       sphere->radius = node_to_double(
-                       ft_cget_node_child(ft_cget_node_child(sphere_node, 2), 0)) / 2;
-       sphere->color = node_to_linear_rgb(ft_cget_node_child(sphere_node, 3));
-       return (ft_vec_append(objects, &object) != success);
-}
-
-int    add_cylinder(const t_parse_tree_node *cylinder_node, t_vec *objects)
-{
-       t_object        object;
-       t_cylinder      *cylinder;
-
-       object.type = CYLINDER;
-       cylinder = &object.object.cylinder;
-       cylinder->center = node_to_vec3(
-                       ft_cget_node_child(ft_cget_node_child(cylinder_node, 1), 0));
-       cylinder->rot_axis = node_to_vec3(ft_cget_node_child(cylinder_node, 2));
-       cylinder->rot_axis = vec_normalize(cylinder->rot_axis);
-       cylinder->color = node_to_linear_rgb(ft_cget_node_child(cylinder_node, 5));
-       cylinder->radius = node_to_double(
-                       ft_cget_node_child(ft_cget_node_child(cylinder_node, 3), 0)) / 2;
-       cylinder->height = node_to_double(
-                       ft_cget_node_child(ft_cget_node_child(cylinder_node, 4), 0));
-       object.object.sphere.color
-               = node_to_linear_rgb(ft_cget_node_child(cylinder_node, 5));
-       return (ft_vec_append(objects, &object) != success);
-}
-
-int    add_element_to_scene(const t_parse_tree_node *element, t_scene *scene)
-{
-       const char                              *type;
-       const t_parse_tree_node *specific_element;
-
-       specific_element = ft_cget_node_child(element, 0);
-       type = specific_element->token.type;
-       if (!ft_strcmp(type, "ambient_light"))
-               set_ambient_light(specific_element, &scene->ambient_light);
-       else if (!ft_strcmp(type, "light")
-               && add_light(specific_element, &scene->lights))
-               return (1);
-       else if (!ft_strcmp(type, "camera")
-               && add_camera(specific_element, &scene->cameras))
-               return (1);
-       else if (!ft_strcmp(type, "sphere")
-               && add_sphere(specific_element, &scene->objects))
-               return (1);
-       else if (!ft_strcmp(type, "plane")
-               && add_plane(specific_element, &scene->objects))
-               return (1);
-       else if (!ft_strcmp(type, "cylinder")
-               && add_cylinder(specific_element, &scene->objects))
-               return (1);
-       return (0);
-}
-
-int    parse_tree_to_scene(const t_parse_tree_node *tree, t_scene *scene)
-{
-       if (tree->children.size == 2)
-       {
-               if (parse_tree_to_scene(ft_cget_node_child(tree, 0), scene))
-                       return (1);
-               if (add_element_to_scene(ft_cget_node_child(tree, 1), scene))
-                       return (1);
-       }
-       return (0);
-}
-
-int    parse_rt_file(const char *filename, t_scene *scene)
-{
-       int                                     res;
-       t_vec                           tokens;
-       t_parsing_table         parsing_table;
-       t_parse_tree_node       *parse_tree;
-
-       res = 1;
-       ft_vec_init(&tokens, sizeof(t_token));
-       if (!tokenize(filename, &tokens))
-       {
-               if (ft_parsing_table_init(&parsing_table) == success
-                       && ft_parsing_table_load_str
-                       (&parsing_table, g_parsing_table, g_grammar) == success)
-               {
-                       parse_tree = ft_parse(&tokens, &parsing_table);
-                       if (parse_tree && !parse_tree_to_scene(parse_tree, scene)
-                               && scene->cameras.size > 0)
-                               res = 0;
-                       ft_parse_tree_free(parse_tree);
-               }
-               ft_parsing_table_free(&parsing_table);
-       }
-       ft_vec_free(&tokens, free_token);
-       return (res);
-}
+#include <stddef.h>
 
 static int     parse_arg(char **argv, t_session *s, int *i)
 {
diff --git a/src/tokenize.c b/src/tokenize.c
new file mode 100644 (file)
index 0000000..11d6379
--- /dev/null
@@ -0,0 +1,123 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   tokenize.c                                         :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/01/14 14:49:32 by ljiriste          #+#    #+#             */
+/*   Updated: 2025/01/14 14:51:04 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "miniRT.h"
+#include "libft.h"
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+
+static const char      *extract_keyword(const char *line, size_t *i)
+{
+       if (line[*i + 1] == '\0' || ft_isspace(line[*i + 1]))
+       {
+               if (line[*i] == 'A')
+                       return ("A");
+               if (line[*i] == 'C')
+                       return ("C");
+               if (line[*i] == 'L')
+                       return ("L");
+       }
+       else if (line[*i + 2] == '\0' || ft_isspace(line[*i + 2]))
+       {
+               ++*i;
+               if (!ft_strncmp(line + *i - 1, "cy", 2))
+                       return ("CY");
+               if (!ft_strncmp(line + *i - 1, "pl", 2))
+                       return ("PL");
+               if (!ft_strncmp(line + *i - 1, "sp", 2))
+                       return ("SP");
+       }
+       return (NULL);
+}
+
+static char    *extract_int(const char *line, size_t *i)
+{
+       size_t  j;
+
+       j = *i;
+       while (ft_isdigit(line[*i]) || line[*i] == '-')
+               ++*i;
+       return (ft_strndup(line + j, ((*i)--) - j));
+}
+
+static int     create_token(t_token *token, const char *line, size_t *i)
+{
+       if (line[*i] == '.')
+               token->type = "DOT";
+       else if (line[*i] == ',')
+               token->type = "COMMA";
+       else if (ft_isdigit(line[*i]) || line[*i] == '-')
+       {
+               token->type = "INT";
+               token->str = extract_int(line, i);
+               if (!token->str)
+                       return (1);
+       }
+       else
+       {
+               token->type = (char *)extract_keyword(line, i);
+               if (!token->type)
+                       return (1);
+       }
+       return (0);
+}
+
+static int     tokenize_line(const char *line, t_vec *tokens)
+{
+       size_t  i;
+       t_token token;
+
+       i = 0;
+       while (line[i])
+       {
+               token.str = NULL;
+               while (ft_isspace(line[i]))
+                       ++i;
+               if (!line[i])
+                       break ;
+               if (create_token(&token, line, &i))
+                       return (1);
+               if (ft_vec_append(tokens, &token) != success)
+               {
+                       free_token(&token);
+                       return (1);
+               }
+               ++i;
+       }
+       return (0);
+}
+
+int    tokenize(const char *filename, t_vec *tokens)
+{
+       int             fd;
+       char    *line;
+
+       fd = open(filename, O_RDONLY);
+       if (fd < 0)
+               return (1);
+       line = get_next_line(fd);
+       while (line)
+       {
+               if (ft_strncmp(line, "//", 2) && tokenize_line(line, tokens))
+               {
+                       free(line);
+                       get_next_line(-1);
+                       close(fd);
+                       return (1);
+               }
+               free(line);
+               line = get_next_line(fd);
+       }
+       close(fd);
+       return (0);
+}