From 5ebb1d97dbb9cd0782e496be34f0c7ba0fa961f4 Mon Sep 17 00:00:00 2001 From: Lukas Jiriste Date: Tue, 14 Jan 2025 15:14:46 +0100 Subject: [PATCH] Make parsing.c completely Norm compliant --- Makefile | 4 + inc/miniRT.h | 20 ++- src/parse_elements.c | 111 ++++++++++++++ src/parse_rt.c | 105 +++++++++++++ src/parse_small.c | 74 +++++++++ src/parsing.c | 351 +------------------------------------------ src/tokenize.c | 123 +++++++++++++++ 7 files changed, 438 insertions(+), 350 deletions(-) create mode 100644 src/parse_elements.c create mode 100644 src/parse_rt.c create mode 100644 src/parse_small.c create mode 100644 src/tokenize.c diff --git a/Makefile b/Makefile index ea2178a..97c3156 100644 --- 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)) diff --git a/inc/miniRT.h b/inc/miniRT.h index 34bccb0..6144fd9 100644 --- a/inc/miniRT.h +++ b/inc/miniRT.h @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* 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 index 0000000..7899957 --- /dev/null +++ b/src/parse_elements.c @@ -0,0 +1,111 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parse_elements.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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 index 0000000..9c85a9f --- /dev/null +++ b/src/parse_rt.c @@ -0,0 +1,105 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parse_rt.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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 + +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 index 0000000..65dee7f --- /dev/null +++ b/src/parse_small.c @@ -0,0 +1,74 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parse_small.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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); +} diff --git a/src/parsing.c b/src/parsing.c index 6b957c0..047e92e 100644 --- a/src/parsing.c +++ b/src/parsing.c @@ -6,360 +6,13 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* 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 -#include -#include - -#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 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 index 0000000..11d6379 --- /dev/null +++ b/src/tokenize.c @@ -0,0 +1,123 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tokenize.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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 +#include +#include + +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); +} -- 2.30.2