parent
edd3712b5a
commit
1b2f6e4225
46 changed files with 887 additions and 378 deletions
|
|
@ -6,7 +6,7 @@
|
||||||
# By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ #
|
# By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/04/28 17:28:30 by maiboyer #+# #+# #
|
# Created: 2024/04/28 17:28:30 by maiboyer #+# #+# #
|
||||||
# Updated: 2024/04/29 14:08:10 by maiboyer ### ########.fr #
|
# Updated: 2024/04/30 14:19:46 by maiboyer ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
|
|
@ -64,7 +64,7 @@ bonus: $(OBJ) $(LIB_OBJ) $(OBJDIRNAME)/libme.a $(OBJDIRNAME)/libgmr.a
|
||||||
@mkdir -p $(OBJDIRNAME)/$(LIBDIRNAME)
|
@mkdir -p $(OBJDIRNAME)/$(LIBDIRNAME)
|
||||||
@mkdir -p $(OBJDIRNAME)/$(SRCDIRNAME)
|
@mkdir -p $(OBJDIRNAME)/$(SRCDIRNAME)
|
||||||
@printf '$(GREY) Be Carefull ur in $(END)$(GREEN)Debug Mode$(END)\n'
|
@printf '$(GREY) Be Carefull ur in $(END)$(GREEN)Debug Mode$(END)\n'
|
||||||
@cc $(CFLAGS) -D DEBUG=42 -o $(NAME) $(OBJ) -L$(OBJDIRNAME) -lme -lgmr
|
@cc $(CFLAGS) -D DEBUG=42 -o $(NAME) $(OBJ) -L$(OBJDIRNAME) -lgmr -lme
|
||||||
|
|
||||||
# Dependences for all
|
# Dependences for all
|
||||||
$(NAME): $(OBJ) $(LIB_OBJ) $(OBJDIRNAME)/libgmr.a $(OBJDIRNAME)/libme.a
|
$(NAME): $(OBJ) $(LIB_OBJ) $(OBJDIRNAME)/libgmr.a $(OBJDIRNAME)/libme.a
|
||||||
|
|
@ -72,7 +72,7 @@ $(NAME): $(OBJ) $(LIB_OBJ) $(OBJDIRNAME)/libgmr.a $(OBJDIRNAME)/libme.a
|
||||||
@mkdir -p $(OBJDIRNAME)/$(LIBDIRNAME)
|
@mkdir -p $(OBJDIRNAME)/$(LIBDIRNAME)
|
||||||
@mkdir -p $(OBJDIRNAME)/$(SRCDIRNAME)
|
@mkdir -p $(OBJDIRNAME)/$(SRCDIRNAME)
|
||||||
@echo "$(GREY) Linking $(END)$(GREEN)$(NAME)$(END)"
|
@echo "$(GREY) Linking $(END)$(GREEN)$(NAME)$(END)"
|
||||||
@cc $(CFLAGS) -o $(NAME) $(OBJ) $(LIB_OBJ) -L$(OBJDIRNAME) -lme -lgmr
|
@cc $(CFLAGS) -o $(NAME) $(OBJ) $(LIB_OBJ) -L$(OBJDIRNAME) -lgmr -lme
|
||||||
|
|
||||||
# Creating the objects
|
# Creating the objects
|
||||||
$(OBJDIRNAME)/%.o: %.c
|
$(OBJDIRNAME)/%.o: %.c
|
||||||
|
|
|
||||||
3
gen.list
3
gen.list
|
|
@ -1,3 +1,6 @@
|
||||||
|
src/vec/vec_parser_heredoc.c
|
||||||
|
src/vec/vec_parser_heredoc_functions2.c
|
||||||
|
src/vec/vec_parser_heredoc_functions3.c
|
||||||
src/vec/vec_parser_range.c
|
src/vec/vec_parser_range.c
|
||||||
src/vec/vec_parser_range_functions2.c
|
src/vec/vec_parser_range_functions2.c
|
||||||
src/vec/vec_parser_range_functions3.c
|
src/vec/vec_parser_range_functions3.c
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/04/28 18:35:22 by maiboyer #+# #+# */
|
/* Created: 2024/04/28 18:35:22 by maiboyer #+# #+# */
|
||||||
/* Updated: 2024/04/28 18:53:13 by maiboyer ### ########.fr */
|
/* Updated: 2024/04/30 13:02:06 by maiboyer ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -28,7 +28,7 @@ typedef struct s_node
|
||||||
struct s_node *childs;
|
struct s_node *childs;
|
||||||
} t_node;
|
} t_node;
|
||||||
|
|
||||||
t_node build_node(TSNode curr, t_const_str input);
|
t_node build_node(t_parse_node curr, t_const_str input);
|
||||||
t_str node_getstr(t_node *node);
|
t_str node_getstr(t_node *node);
|
||||||
void free_node(t_node t);
|
void free_node(t_node t);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,3 +44,11 @@ replace.C__TYPENAME__ = "t_parser_range"
|
||||||
replace.C__TYPEHEADER__ = '#include "parser/types/types_parser_range.h"'
|
replace.C__TYPEHEADER__ = '#include "parser/types/types_parser_range.h"'
|
||||||
replace.C__PREFIX__ = "parser_range"
|
replace.C__PREFIX__ = "parser_range"
|
||||||
replace.C__PREFIXUP__ = "PARSER_RANGE"
|
replace.C__PREFIXUP__ = "PARSER_RANGE"
|
||||||
|
|
||||||
|
[[create.vec]]
|
||||||
|
sources_output = "src/vec/"
|
||||||
|
headers_output = "include/me/vec/"
|
||||||
|
replace.C__TYPENAME__ = "t_heredoc"
|
||||||
|
replace.C__TYPEHEADER__ = '#include "parser/types/types_heredoc.h"'
|
||||||
|
replace.C__PREFIX__ = "parser_heredoc"
|
||||||
|
replace.C__PREFIXUP__ = "PARSER_HEREDOC"
|
||||||
|
|
|
||||||
58
output/include/me/vec/vec_parser_heredoc.h
Normal file
58
output/include/me/vec/vec_parser_heredoc.h
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vec_parser_heredoc.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2023/12/04 18:46:53 by maiboyer #+# #+# */
|
||||||
|
/* Updated: 2023/12/09 17:53:00 by maiboyer ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef VEC_PARSER_HEREDOC_H
|
||||||
|
#define VEC_PARSER_HEREDOC_H
|
||||||
|
|
||||||
|
#include "parser/types/types_heredoc.h"
|
||||||
|
#include "me/types.h"
|
||||||
|
|
||||||
|
typedef bool (*t_vec_parser_heredoc_sort_fn)(t_heredoc *, t_heredoc *);
|
||||||
|
typedef void (*t_free_parser_heredoc_item)(t_heredoc);
|
||||||
|
|
||||||
|
typedef struct s_vec_parser_heredoc
|
||||||
|
{
|
||||||
|
t_free_parser_heredoc_item free_func;
|
||||||
|
t_usize len;
|
||||||
|
t_usize capacity;
|
||||||
|
t_heredoc *buffer;
|
||||||
|
} t_vec_parser_heredoc;
|
||||||
|
|
||||||
|
t_vec_parser_heredoc vec_parser_heredoc_new(t_usize capacity,
|
||||||
|
t_free_parser_heredoc_item free_function);
|
||||||
|
t_error vec_parser_heredoc_push(t_vec_parser_heredoc *vec, t_heredoc element);
|
||||||
|
t_error vec_parser_heredoc_push_front(t_vec_parser_heredoc *vec,
|
||||||
|
t_heredoc element);
|
||||||
|
t_error vec_parser_heredoc_pop(t_vec_parser_heredoc *vec, t_heredoc *value);
|
||||||
|
t_error vec_parser_heredoc_pop_front(t_vec_parser_heredoc *vec, t_heredoc *value);
|
||||||
|
void vec_parser_heredoc_free(t_vec_parser_heredoc vec);
|
||||||
|
t_error vec_parser_heredoc_reserve(t_vec_parser_heredoc *vec,
|
||||||
|
t_usize wanted_capacity);
|
||||||
|
t_error vec_parser_heredoc_find(t_vec_parser_heredoc *vec,
|
||||||
|
bool (*fn)(const t_heredoc *), t_usize *index);
|
||||||
|
t_error vec_parser_heredoc_find_starting(t_vec_parser_heredoc *vec,
|
||||||
|
bool (*fn)(const t_heredoc *),
|
||||||
|
t_usize starting_index, t_usize *index);
|
||||||
|
t_error vec_parser_heredoc_all(t_vec_parser_heredoc *vec,
|
||||||
|
bool (*fn)(const t_heredoc *), bool *result);
|
||||||
|
t_error vec_parser_heredoc_any(t_vec_parser_heredoc *vec,
|
||||||
|
bool (*fn)(const t_heredoc *), bool *result);
|
||||||
|
void vec_parser_heredoc_iter(t_vec_parser_heredoc *vec,
|
||||||
|
void (*fn)(t_usize index, t_heredoc *value,
|
||||||
|
void *state),
|
||||||
|
void *state);
|
||||||
|
void vec_parser_heredoc_reverse(t_vec_parser_heredoc *vec);
|
||||||
|
void vec_parser_heredoc_sort(t_vec_parser_heredoc *vec,
|
||||||
|
t_vec_parser_heredoc_sort_fn is_sorted);
|
||||||
|
t_error vec_parser_heredoc_back(t_vec_parser_heredoc *vec, t_heredoc **out);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -53,5 +53,6 @@ void vec_parser_range_iter(t_vec_parser_range *vec,
|
||||||
void vec_parser_range_reverse(t_vec_parser_range *vec);
|
void vec_parser_range_reverse(t_vec_parser_range *vec);
|
||||||
void vec_parser_range_sort(t_vec_parser_range *vec,
|
void vec_parser_range_sort(t_vec_parser_range *vec,
|
||||||
t_vec_parser_range_sort_fn is_sorted);
|
t_vec_parser_range_sort_fn is_sorted);
|
||||||
|
t_error vec_parser_range_back(t_vec_parser_range *vec, t_parser_range **out);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
115
output/src/vec/vec_parser_heredoc.c
Normal file
115
output/src/vec/vec_parser_heredoc.c
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vec_parser_heredoc.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2023/12/05 18:46:28 by maiboyer #+# #+# */
|
||||||
|
/* Updated: 2023/12/09 17:54:11 by maiboyer ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "me/mem/mem_alloc_array.h"
|
||||||
|
#include "me/mem/mem_copy.h"
|
||||||
|
#include "me/mem/mem_set_zero.h"
|
||||||
|
#include "me/types.h"
|
||||||
|
#include "me/vec/vec_parser_heredoc.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
t_vec_parser_heredoc vec_parser_heredoc_new(t_usize capacity,
|
||||||
|
t_free_parser_heredoc_item free_function)
|
||||||
|
{
|
||||||
|
t_vec_parser_heredoc out;
|
||||||
|
|
||||||
|
out = (t_vec_parser_heredoc){0};
|
||||||
|
out.free_func = free_function;
|
||||||
|
out.buffer = mem_alloc_array(capacity, sizeof(t_heredoc));
|
||||||
|
if (out.buffer)
|
||||||
|
out.capacity = capacity;
|
||||||
|
return (out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return true in case of an error
|
||||||
|
t_error vec_parser_heredoc_push(t_vec_parser_heredoc *vec, t_heredoc element)
|
||||||
|
{
|
||||||
|
t_heredoc *temp_buffer;
|
||||||
|
size_t new_capacity;
|
||||||
|
|
||||||
|
if (vec == NULL)
|
||||||
|
return (ERROR);
|
||||||
|
if (vec->len + 1 > vec->capacity)
|
||||||
|
{
|
||||||
|
new_capacity = (vec->capacity * 3) / 2 + 1;
|
||||||
|
while (vec->len + 1 > new_capacity)
|
||||||
|
new_capacity = (new_capacity * 3) / 2 + 1;
|
||||||
|
temp_buffer = mem_alloc_array(new_capacity, sizeof(t_heredoc));
|
||||||
|
if (temp_buffer == NULL)
|
||||||
|
return (ERROR);
|
||||||
|
mem_copy(temp_buffer, vec->buffer, vec->len * sizeof(t_heredoc));
|
||||||
|
free(vec->buffer);
|
||||||
|
vec->buffer = temp_buffer;
|
||||||
|
vec->capacity = new_capacity;
|
||||||
|
}
|
||||||
|
vec->buffer[vec->len] = element;
|
||||||
|
vec->len += 1;
|
||||||
|
return (NO_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return true in case of an error
|
||||||
|
t_error vec_parser_heredoc_reserve(t_vec_parser_heredoc *vec, t_usize wanted_capacity)
|
||||||
|
{
|
||||||
|
t_heredoc *temp_buffer;
|
||||||
|
size_t new_capacity;
|
||||||
|
|
||||||
|
if (vec == NULL)
|
||||||
|
return (ERROR);
|
||||||
|
if (wanted_capacity > vec->capacity)
|
||||||
|
{
|
||||||
|
new_capacity = (vec->capacity * 3) / 2 + 1;
|
||||||
|
while (wanted_capacity > new_capacity)
|
||||||
|
new_capacity = (new_capacity * 3) / 2 + 1;
|
||||||
|
temp_buffer = mem_alloc_array(new_capacity, sizeof(t_heredoc));
|
||||||
|
if (temp_buffer == NULL)
|
||||||
|
return (ERROR);
|
||||||
|
mem_copy(temp_buffer, vec->buffer, vec->len * sizeof(t_heredoc));
|
||||||
|
free(vec->buffer);
|
||||||
|
vec->buffer = temp_buffer;
|
||||||
|
vec->capacity = new_capacity;
|
||||||
|
}
|
||||||
|
return (NO_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return true if the vector is empty
|
||||||
|
/// This function is safe to call with value being NULL
|
||||||
|
t_error vec_parser_heredoc_pop(t_vec_parser_heredoc *vec, t_heredoc *value)
|
||||||
|
{
|
||||||
|
t_heredoc temp_value;
|
||||||
|
t_heredoc *ptr;
|
||||||
|
|
||||||
|
if (vec == NULL)
|
||||||
|
return (ERROR);
|
||||||
|
ptr = value;
|
||||||
|
if (vec->len == 0)
|
||||||
|
return (ERROR);
|
||||||
|
if (value == NULL)
|
||||||
|
ptr = &temp_value;
|
||||||
|
vec->len--;
|
||||||
|
*ptr = vec->buffer[vec->len];
|
||||||
|
mem_set_zero(&vec->buffer[vec->len], sizeof(t_heredoc));
|
||||||
|
return (NO_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This function is safe to call with `free_elem` being NULL
|
||||||
|
void vec_parser_heredoc_free(t_vec_parser_heredoc vec)
|
||||||
|
{
|
||||||
|
if (vec.free_func)
|
||||||
|
{
|
||||||
|
while (vec.len)
|
||||||
|
{
|
||||||
|
vec.free_func(vec.buffer[vec.len - 1]);
|
||||||
|
vec.len--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(vec.buffer);
|
||||||
|
}
|
||||||
112
output/src/vec/vec_parser_heredoc_functions2.c
Normal file
112
output/src/vec/vec_parser_heredoc_functions2.c
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vec_parser_heredoc.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2023/12/30 17:59:28 by maiboyer #+# #+# */
|
||||||
|
/* Updated: 2023/12/30 17:59:28 by maiboyer ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "me/mem/mem_alloc_array.h"
|
||||||
|
#include "me/mem/mem_copy.h"
|
||||||
|
#include "me/mem/mem_set_zero.h"
|
||||||
|
#include "me/types.h"
|
||||||
|
#include "me/vec/vec_parser_heredoc.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
t_error vec_parser_heredoc_find(t_vec_parser_heredoc *vec,
|
||||||
|
bool (*fn)(const t_heredoc *), t_usize *index)
|
||||||
|
{
|
||||||
|
t_usize idx;
|
||||||
|
|
||||||
|
if (vec == NULL || fn == NULL || index == NULL)
|
||||||
|
return (ERROR);
|
||||||
|
idx = 0;
|
||||||
|
while (idx < vec->len)
|
||||||
|
{
|
||||||
|
if (fn(&vec->buffer[idx]))
|
||||||
|
{
|
||||||
|
*index = idx;
|
||||||
|
return (NO_ERROR);
|
||||||
|
}
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
return (ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
t_error vec_parser_heredoc_find_starting(t_vec_parser_heredoc *vec,
|
||||||
|
bool (*fn)(const t_heredoc *),
|
||||||
|
t_usize starting_index, t_usize *index)
|
||||||
|
{
|
||||||
|
t_usize idx;
|
||||||
|
|
||||||
|
if (vec == NULL || fn == NULL || index == NULL)
|
||||||
|
return (ERROR);
|
||||||
|
idx = starting_index;
|
||||||
|
while (idx < vec->len)
|
||||||
|
{
|
||||||
|
if (fn(&vec->buffer[idx]))
|
||||||
|
{
|
||||||
|
*index = idx;
|
||||||
|
return (NO_ERROR);
|
||||||
|
}
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
return (ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
t_error vec_parser_heredoc_all(t_vec_parser_heredoc *vec,
|
||||||
|
bool (*fn)(const t_heredoc *), bool *result)
|
||||||
|
{
|
||||||
|
t_usize idx;
|
||||||
|
|
||||||
|
if (vec == NULL || fn == NULL || result == NULL)
|
||||||
|
return (ERROR);
|
||||||
|
idx = 0;
|
||||||
|
*result = true;
|
||||||
|
while (*result && idx < vec->len)
|
||||||
|
{
|
||||||
|
if (!fn(&vec->buffer[idx]))
|
||||||
|
*result = false;
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
return (ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
t_error vec_parser_heredoc_any(t_vec_parser_heredoc *vec,
|
||||||
|
bool (*fn)(const t_heredoc *), bool *result)
|
||||||
|
{
|
||||||
|
t_usize idx;
|
||||||
|
|
||||||
|
if (vec == NULL || fn == NULL || result == NULL)
|
||||||
|
return (ERROR);
|
||||||
|
idx = 0;
|
||||||
|
*result = false;
|
||||||
|
while (*result && idx < vec->len)
|
||||||
|
{
|
||||||
|
if (fn(&vec->buffer[idx]))
|
||||||
|
*result = true;
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
return (ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vec_parser_heredoc_iter(t_vec_parser_heredoc *vec,
|
||||||
|
void (*fn)(t_usize index, t_heredoc *value,
|
||||||
|
void *state),
|
||||||
|
void *state)
|
||||||
|
{
|
||||||
|
t_usize idx;
|
||||||
|
|
||||||
|
if (vec == NULL || fn == NULL)
|
||||||
|
return;
|
||||||
|
idx = 0;
|
||||||
|
while (idx < vec->len)
|
||||||
|
{
|
||||||
|
fn(idx, &vec->buffer[idx], state);
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
84
output/src/vec/vec_parser_heredoc_functions3.c
Normal file
84
output/src/vec/vec_parser_heredoc_functions3.c
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vec_parser_heredoc.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2023/12/30 17:59:28 by maiboyer #+# #+# */
|
||||||
|
/* Updated: 2023/12/30 17:59:28 by maiboyer ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "me/mem/mem_alloc_array.h"
|
||||||
|
#include "me/mem/mem_copy.h"
|
||||||
|
#include "me/mem/mem_set_zero.h"
|
||||||
|
#include "me/types.h"
|
||||||
|
#include "me/vec/vec_parser_heredoc.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
t_error vec_parser_heredoc_push_front(t_vec_parser_heredoc *vec,
|
||||||
|
t_heredoc element)
|
||||||
|
{
|
||||||
|
t_usize i;
|
||||||
|
|
||||||
|
if (vec->len == 0)
|
||||||
|
return (vec_parser_heredoc_push(vec, element));
|
||||||
|
i = vec->len - 1;
|
||||||
|
if (vec->capacity < vec->len + 1 &&
|
||||||
|
vec_parser_heredoc_reserve(vec, 3 * vec->len / 2 + 1))
|
||||||
|
return (ERROR);
|
||||||
|
while (i > 0)
|
||||||
|
{
|
||||||
|
vec->buffer[i + 1] = vec->buffer[i];
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
vec->buffer[1] = vec->buffer[0];
|
||||||
|
vec->buffer[0] = element;
|
||||||
|
vec->len++;
|
||||||
|
return (NO_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
t_error vec_parser_heredoc_pop_front(t_vec_parser_heredoc *vec, t_heredoc *value)
|
||||||
|
{
|
||||||
|
t_usize i;
|
||||||
|
|
||||||
|
if (vec->len <= 1)
|
||||||
|
return (vec_parser_heredoc_pop(vec, value));
|
||||||
|
i = 0;
|
||||||
|
*value = vec->buffer[0];
|
||||||
|
vec->len--;
|
||||||
|
while (i < vec->len)
|
||||||
|
{
|
||||||
|
vec->buffer[i] = vec->buffer[i + 1];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
mem_set_zero(&vec->buffer[i], sizeof(*vec->buffer));
|
||||||
|
return (NO_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vec_parser_heredoc_reverse(t_vec_parser_heredoc *vec)
|
||||||
|
{
|
||||||
|
t_heredoc temporary;
|
||||||
|
t_usize i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < vec->len / 2)
|
||||||
|
{
|
||||||
|
temporary = vec->buffer[vec->len - 1 - i];
|
||||||
|
vec->buffer[vec->len - 1 - i] = vec->buffer[i];
|
||||||
|
vec->buffer[i] = temporary;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t_error vec_parser_heredoc_back(t_vec_parser_heredoc *vec, t_heredoc **out)
|
||||||
|
{
|
||||||
|
t_heredoc *temporary;
|
||||||
|
|
||||||
|
if (out == NULL)
|
||||||
|
out = &temporary;
|
||||||
|
if (vec->len != 0)
|
||||||
|
return (*out = &vec->buffer[vec->len - 1], true);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
@ -71,3 +71,14 @@ void vec_parser_range_reverse(t_vec_parser_range *vec)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t_error vec_parser_range_back(t_vec_parser_range *vec, t_parser_range **out)
|
||||||
|
{
|
||||||
|
t_parser_range *temporary;
|
||||||
|
|
||||||
|
if (out == NULL)
|
||||||
|
out = &temporary;
|
||||||
|
if (vec->len != 0)
|
||||||
|
return (*out = &vec->buffer[vec->len - 1], true);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
# By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ #
|
# By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2023/11/03 13:20:01 by maiboyer #+# #+# #
|
# Created: 2023/11/03 13:20:01 by maiboyer #+# #+# #
|
||||||
# Updated: 2024/04/29 14:31:52 by maiboyer ### ########.fr #
|
# Updated: 2024/04/30 13:35:56 by maiboyer ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
|
|
@ -18,7 +18,7 @@ NAME = libgmr.a
|
||||||
LIB_NAME ?=
|
LIB_NAME ?=
|
||||||
TARGET = $(BUILD_DIR)/$(NAME)
|
TARGET = $(BUILD_DIR)/$(NAME)
|
||||||
CC = cc
|
CC = cc
|
||||||
CFLAGS = -Wall -Wextra -Werror -g3 -MMD -I./includes -I../includes -I../output/include
|
CFLAGS = -Wall -Wextra -Werror -MMD -I./includes -I../includes -I../output/include
|
||||||
|
|
||||||
include ./Filelist.mk
|
include ./Filelist.mk
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,13 +36,13 @@ typedef struct s_parser t_parser;
|
||||||
typedef struct t_parse_tree t_parse_tree;
|
typedef struct t_parse_tree t_parse_tree;
|
||||||
typedef struct t_query t_query;
|
typedef struct t_query t_query;
|
||||||
typedef struct t_query_cursor t_query_cursor;
|
typedef struct t_query_cursor t_query_cursor;
|
||||||
typedef struct TSLookaheadIterator TSLookaheadIterator;
|
typedef struct t_lookahead_iterator t_lookahead_iterator;
|
||||||
|
|
||||||
typedef enum TSInputEncoding
|
typedef enum t_input_encoding
|
||||||
{
|
{
|
||||||
TSInputEncodingUTF8,
|
InputEncoding8,
|
||||||
TSInputEncodingUTF16,
|
InputEncoding16,
|
||||||
} TSInputEncoding;
|
} t_input_encoding;
|
||||||
|
|
||||||
typedef enum t_symbol_type
|
typedef enum t_symbol_type
|
||||||
{
|
{
|
||||||
|
|
@ -51,25 +51,25 @@ typedef enum t_symbol_type
|
||||||
SymbolTypeAuxiliary,
|
SymbolTypeAuxiliary,
|
||||||
} t_symbol_type;
|
} t_symbol_type;
|
||||||
|
|
||||||
typedef struct TSInput
|
typedef struct t_parse_input
|
||||||
{
|
{
|
||||||
void *payload;
|
void *payload;
|
||||||
const char *(*read)(void *payload, t_u32 byte_index, t_point position,
|
const char *(*read)(void *payload, t_u32 byte_index, t_point position,
|
||||||
t_u32 *bytes_read);
|
t_u32 *bytes_read);
|
||||||
TSInputEncoding encoding;
|
t_input_encoding encoding;
|
||||||
} TSInput;
|
} t_parse_input;
|
||||||
|
|
||||||
typedef enum TSLogType
|
typedef enum t_parse_log_type
|
||||||
{
|
{
|
||||||
TSLogTypeParse,
|
LogTypeParse,
|
||||||
TSLogTypeLex,
|
LogTypeLex,
|
||||||
} TSLogType;
|
} t_parse_log_type;
|
||||||
|
|
||||||
typedef struct TSLogger
|
typedef struct t_parse_logger
|
||||||
{
|
{
|
||||||
void *payload;
|
void *payload;
|
||||||
void (*log)(void *payload, TSLogType log_type, const char *buffer);
|
void (*log)(void *payload, t_parse_log_type log_type, const char *buffer);
|
||||||
} TSLogger;
|
} t_parse_logger;
|
||||||
|
|
||||||
typedef struct t_input_edit
|
typedef struct t_input_edit
|
||||||
{
|
{
|
||||||
|
|
@ -101,14 +101,14 @@ typedef struct t_queryCapture
|
||||||
t_u32 index;
|
t_u32 index;
|
||||||
} t_queryCapture;
|
} t_queryCapture;
|
||||||
|
|
||||||
typedef enum TSQuantifier
|
typedef enum t_parse_quantifier
|
||||||
{
|
{
|
||||||
TSQuantifierZero = 0, // must match the array initialization value
|
ParseQuantifierZero = 0, // must match the array initialization value
|
||||||
TSQuantifierZeroOrOne,
|
ParseQuantifierZeroOrOne,
|
||||||
TSQuantifierZeroOrMore,
|
ParseQuantifierZeroOrMore,
|
||||||
TSQuantifierOne,
|
ParseQuantifierOne,
|
||||||
TSQuantifierOneOrMore,
|
ParseQuantifierOneOrMore,
|
||||||
} TSQuantifier;
|
} t_parse_quantifier;
|
||||||
|
|
||||||
typedef struct t_query_match
|
typedef struct t_query_match
|
||||||
{
|
{
|
||||||
|
|
@ -221,7 +221,7 @@ const t_parser_range *ts_parser_included_ranges(const t_parser *self,
|
||||||
a
|
a
|
||||||
* way that exactly matches the source code changes.
|
* way that exactly matches the source code changes.
|
||||||
*
|
*
|
||||||
* The [`TSInput`] parameter lets you specify how to read the text. It has
|
* The [`t_parse_input`] parameter lets you specify how to read the text. It has
|
||||||
the
|
the
|
||||||
* following three fields:
|
* following three fields:
|
||||||
* 1. [`read`]: A function to retrieve a chunk of text at a given byte
|
* 1. [`read`]: A function to retrieve a chunk of text at a given byte
|
||||||
|
|
@ -237,7 +237,7 @@ const t_parser_range *ts_parser_included_ranges(const t_parser *self,
|
||||||
invocation
|
invocation
|
||||||
* of the [`read`] function.
|
* of the [`read`] function.
|
||||||
* 3. [`encoding`]: An indication of how the text is encoded. Either
|
* 3. [`encoding`]: An indication of how the text is encoded. Either
|
||||||
* `TSInputEncodingUTF8` or `TSInputEncodingUTF16`.
|
* `InputEncoding8` or `InputEncoding16`.
|
||||||
*
|
*
|
||||||
* This function returns a syntax tree on success, and `NULL` on failure.
|
* This function returns a syntax tree on success, and `NULL` on failure.
|
||||||
There
|
There
|
||||||
|
|
@ -259,13 +259,13 @@ const t_parser_range *ts_parser_included_ranges(const t_parser *self,
|
||||||
with
|
with
|
||||||
* the same arguments.
|
* the same arguments.
|
||||||
*
|
*
|
||||||
* [`read`]: TSInput::read
|
* [`read`]: t_parse_input::read
|
||||||
* [`payload`]: TSInput::payload
|
* [`payload`]: t_parse_input::payload
|
||||||
* [`encoding`]: TSInput::encoding
|
* [`encoding`]: t_parse_input::encoding
|
||||||
* [`bytes_read`]: TSInput::read
|
* [`bytes_read`]: t_parse_input::read
|
||||||
*/
|
*/
|
||||||
t_parse_tree *ts_parser_parse(t_parser *self, const t_parse_tree *old_tree,
|
t_parse_tree *ts_parser_parse(t_parser *self, const t_parse_tree *old_tree,
|
||||||
TSInput input);
|
t_parse_input input);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use the parser to parse some source code stored in one contiguous buffer.
|
* Use the parser to parse some source code stored in one contiguous buffer.
|
||||||
|
|
@ -286,7 +286,7 @@ t_parse_tree *ts_parser_parse_string(t_parser *self,
|
||||||
t_parse_tree *ts_parser_parse_string_encoding(t_parser *self,
|
t_parse_tree *ts_parser_parse_string_encoding(t_parser *self,
|
||||||
const t_parse_tree *old_tree,
|
const t_parse_tree *old_tree,
|
||||||
const char *string, t_u32 length,
|
const char *string, t_u32 length,
|
||||||
TSInputEncoding encoding);
|
t_input_encoding encoding);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instruct the parser to start the next parse from the beginning.
|
* Instruct the parser to start the next parse from the beginning.
|
||||||
|
|
@ -334,12 +334,12 @@ const size_t *ts_parser_cancellation_flag(const t_parser *self);
|
||||||
* was previously assigned, the caller is responsible for releasing any
|
* was previously assigned, the caller is responsible for releasing any
|
||||||
* memory owned by the previous logger.
|
* memory owned by the previous logger.
|
||||||
*/
|
*/
|
||||||
void ts_parser_set_logger(t_parser *self, TSLogger logger);
|
void ts_parser_set_logger(t_parser *self, t_parse_logger logger);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the parser's current logger.
|
* Get the parser's current logger.
|
||||||
*/
|
*/
|
||||||
TSLogger ts_parser_logger(const t_parser *self);
|
t_parse_logger ts_parser_logger(const t_parser *self);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the file descriptor to which the parser should write debugging graphs
|
* Set the file descriptor to which the parser should write debugging graphs
|
||||||
|
|
@ -888,7 +888,7 @@ const char *ts_query_capture_name_for_id(const t_query *self, t_u32 index,
|
||||||
* with a numeric id based on the order that it appeared in the query's
|
* with a numeric id based on the order that it appeared in the query's
|
||||||
* source.
|
* source.
|
||||||
*/
|
*/
|
||||||
TSQuantifier ts_query_capture_quantifier_for_id(const t_query *self,
|
t_parse_quantifier ts_query_capture_quantifier_for_id(const t_query *self,
|
||||||
t_u32 pattern_index,
|
t_u32 pattern_index,
|
||||||
t_u32 capture_index);
|
t_u32 capture_index);
|
||||||
|
|
||||||
|
|
@ -1110,13 +1110,13 @@ t_state_id ts_language_next_state(const t_language *self, t_state_id state,
|
||||||
* lookahead iterator created on the previous non-extra leaf node may be
|
* lookahead iterator created on the previous non-extra leaf node may be
|
||||||
* appropriate.
|
* appropriate.
|
||||||
*/
|
*/
|
||||||
TSLookaheadIterator *ts_lookahead_iterator_new(const t_language *self,
|
t_lookahead_iterator *ts_lookahead_iterator_new(const t_language *self,
|
||||||
t_state_id state);
|
t_state_id state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a lookahead iterator freeing all the memory used.
|
* Delete a lookahead iterator freeing all the memory used.
|
||||||
*/
|
*/
|
||||||
void ts_lookahead_iterator_delete(TSLookaheadIterator *self);
|
void ts_lookahead_iterator_delete(t_lookahead_iterator *self);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the lookahead iterator to another state.
|
* Reset the lookahead iterator to another state.
|
||||||
|
|
@ -1124,7 +1124,7 @@ void ts_lookahead_iterator_delete(TSLookaheadIterator *self);
|
||||||
* This returns `true` if the iterator was reset to the given state and
|
* This returns `true` if the iterator was reset to the given state and
|
||||||
* `false` otherwise.
|
* `false` otherwise.
|
||||||
*/
|
*/
|
||||||
bool ts_lookahead_iterator_reset_state(TSLookaheadIterator *self,
|
bool ts_lookahead_iterator_reset_state(t_lookahead_iterator *self,
|
||||||
t_state_id state);
|
t_state_id state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1133,33 +1133,33 @@ bool ts_lookahead_iterator_reset_state(TSLookaheadIterator *self,
|
||||||
* This returns `true` if the language was set successfully and `false`
|
* This returns `true` if the language was set successfully and `false`
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
bool ts_lookahead_iterator_reset(TSLookaheadIterator *self,
|
bool ts_lookahead_iterator_reset(t_lookahead_iterator *self,
|
||||||
const t_language *language, t_state_id state);
|
const t_language *language, t_state_id state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current language of the lookahead iterator.
|
* Get the current language of the lookahead iterator.
|
||||||
*/
|
*/
|
||||||
const t_language *ts_lookahead_iterator_language(
|
const t_language *ts_lookahead_iterator_language(
|
||||||
const TSLookaheadIterator *self);
|
const t_lookahead_iterator *self);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Advance the lookahead iterator to the next symbol.
|
* Advance the lookahead iterator to the next symbol.
|
||||||
*
|
*
|
||||||
* This returns `true` if there is a new symbol and `false` otherwise.
|
* This returns `true` if there is a new symbol and `false` otherwise.
|
||||||
*/
|
*/
|
||||||
bool ts_lookahead_iterator_next(TSLookaheadIterator *self);
|
bool ts_lookahead_iterator_next(t_lookahead_iterator *self);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current symbol of the lookahead iterator;
|
* Get the current symbol of the lookahead iterator;
|
||||||
*/
|
*/
|
||||||
t_symbol ts_lookahead_iterator_current_symbol(const TSLookaheadIterator *self);
|
t_symbol ts_lookahead_iterator_current_symbol(const t_lookahead_iterator *self);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current symbol type of the lookahead iterator as a null
|
* Get the current symbol type of the lookahead iterator as a null
|
||||||
* terminated string.
|
* terminated string.
|
||||||
*/
|
*/
|
||||||
const char *ts_lookahead_iterator_current_symbol_name(
|
const char *ts_lookahead_iterator_current_symbol_name(
|
||||||
const TSLookaheadIterator *self);
|
const t_lookahead_iterator *self);
|
||||||
|
|
||||||
/**********************************/
|
/**********************************/
|
||||||
/* Section - Global Configuration */
|
/* Section - Global Configuration */
|
||||||
|
|
|
||||||
64
parser/includes/parser_length.h
Normal file
64
parser/includes/parser_length.h
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
#ifndef TREE_SITTER_LENGTH_H_
|
||||||
|
#define TREE_SITTER_LENGTH_H_
|
||||||
|
|
||||||
|
#include "../src/point.h"
|
||||||
|
#include "parser/api.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
typedef struct s_parse_length
|
||||||
|
{
|
||||||
|
t_u32 bytes;
|
||||||
|
t_point extent;
|
||||||
|
} t_parse_length;
|
||||||
|
|
||||||
|
static const t_parse_length LENGTH_UNDEFINED = {0, {0, 1}};
|
||||||
|
static const t_parse_length LENGTH_MAX = {UINT32_MAX, {UINT32_MAX, UINT32_MAX}};
|
||||||
|
|
||||||
|
static inline bool length_is_undefined(t_parse_length length)
|
||||||
|
{
|
||||||
|
return (length.bytes == 0 && length.extent.column != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline t_parse_length length_min(t_parse_length len1,
|
||||||
|
t_parse_length len2)
|
||||||
|
{
|
||||||
|
if (len1.bytes < len2.bytes)
|
||||||
|
return (len1);
|
||||||
|
else
|
||||||
|
return (len2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline t_parse_length length_add(t_parse_length len1,
|
||||||
|
t_parse_length len2)
|
||||||
|
{
|
||||||
|
t_parse_length result;
|
||||||
|
result.bytes = len1.bytes + len2.bytes;
|
||||||
|
result.extent = point_add(len1.extent, len2.extent);
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline t_parse_length length_sub(t_parse_length len1,
|
||||||
|
t_parse_length len2)
|
||||||
|
{
|
||||||
|
t_parse_length result;
|
||||||
|
result.bytes = len1.bytes - len2.bytes;
|
||||||
|
result.extent = point_sub(len1.extent, len2.extent);
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline t_parse_length length_zero(void)
|
||||||
|
{
|
||||||
|
return ((t_parse_length){0, {0, 0}});
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline t_parse_length length_saturating_sub(t_parse_length len1,
|
||||||
|
t_parse_length len2)
|
||||||
|
{
|
||||||
|
if (len1.bytes > len2.bytes)
|
||||||
|
return (length_sub(len1, len2));
|
||||||
|
else
|
||||||
|
return (length_zero());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
28
parser/includes/types/types_heredoc.h
Normal file
28
parser/includes/types/types_heredoc.h
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* types_heredoc.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2024/04/30 13:47:07 by maiboyer #+# #+# */
|
||||||
|
/* Updated: 2024/04/30 13:48:19 by maiboyer ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef TYPES_HEREDOC_H
|
||||||
|
#define TYPES_HEREDOC_H
|
||||||
|
|
||||||
|
#include "me/buffered_str/buf_str.h"
|
||||||
|
#include "me/types.h"
|
||||||
|
|
||||||
|
typedef struct s_heredoc
|
||||||
|
{
|
||||||
|
bool is_raw;
|
||||||
|
bool started;
|
||||||
|
bool allows_indent;
|
||||||
|
t_buffer_str delimiter;
|
||||||
|
t_buffer_str current_leading_word;
|
||||||
|
} t_heredoc;
|
||||||
|
|
||||||
|
#endif /* TYPES_HEREDOC_H */
|
||||||
27
parser/includes/types/types_scanner_ctx.h
Normal file
27
parser/includes/types/types_scanner_ctx.h
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* types_scanner_ctx.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2024/04/30 13:41:02 by maiboyer #+# #+# */
|
||||||
|
/* Updated: 2024/04/30 13:50:24 by maiboyer ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef TYPES_SCANNER_CTX_H
|
||||||
|
#define TYPES_SCANNER_CTX_H
|
||||||
|
|
||||||
|
#include "me/types.h"
|
||||||
|
#include "me/vec/vec_parser_heredoc.h"
|
||||||
|
|
||||||
|
typedef struct s_scanner_ctx
|
||||||
|
{
|
||||||
|
t_u8 last_glob_paren_depth;
|
||||||
|
bool ext_was_in_double_quote;
|
||||||
|
bool ext_saw_outside_quote;
|
||||||
|
t_vec_parser_heredoc heredocs;
|
||||||
|
} t_scanner_ctx;
|
||||||
|
|
||||||
|
#endif /* TYPES_SCANNER_CTX_H */
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
|
|
||||||
// Determine endian and pointer size based on known defines.
|
|
||||||
// TS_BIG_ENDIAN and TS_PTR_SIZE can be set as -D compiler arguments
|
|
||||||
// to override this.
|
|
||||||
|
|
||||||
#if !defined(TS_BIG_ENDIAN)
|
|
||||||
#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) \
|
|
||||||
|| (defined( __APPLE_CC__) && (defined(__ppc__) || defined(__ppc64__)))
|
|
||||||
#define TS_BIG_ENDIAN 1
|
|
||||||
#else
|
|
||||||
#define TS_BIG_ENDIAN 0
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(TS_PTR_SIZE)
|
|
||||||
#if UINTPTR_MAX == 0xFFFFFFFF
|
|
||||||
#define TS_PTR_SIZE 32
|
|
||||||
#else
|
|
||||||
#define TS_PTR_SIZE 64
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
@ -169,47 +169,47 @@ t_field_id ts_language_field_id_for_name(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TSLookaheadIterator *ts_lookahead_iterator_new(const t_language *self, t_state_id state) {
|
t_lookahead_iterator *ts_lookahead_iterator_new(const t_language *self, t_state_id state) {
|
||||||
if (state >= self->state_count) return NULL;
|
if (state >= self->state_count) return NULL;
|
||||||
LookaheadIterator *iterator = malloc(sizeof(LookaheadIterator));
|
LookaheadIterator *iterator = malloc(sizeof(LookaheadIterator));
|
||||||
*iterator = ts_language_lookaheads(self, state);
|
*iterator = ts_language_lookaheads(self, state);
|
||||||
return (TSLookaheadIterator *)iterator;
|
return (t_lookahead_iterator *)iterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_lookahead_iterator_delete(TSLookaheadIterator *self) {
|
void ts_lookahead_iterator_delete(t_lookahead_iterator *self) {
|
||||||
free(self);
|
free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ts_lookahead_iterator_reset_state(TSLookaheadIterator * self, t_state_id state) {
|
bool ts_lookahead_iterator_reset_state(t_lookahead_iterator * self, t_state_id state) {
|
||||||
LookaheadIterator *iterator = (LookaheadIterator *)self;
|
LookaheadIterator *iterator = (LookaheadIterator *)self;
|
||||||
if (state >= iterator->language->state_count) return false;
|
if (state >= iterator->language->state_count) return false;
|
||||||
*iterator = ts_language_lookaheads(iterator->language, state);
|
*iterator = ts_language_lookaheads(iterator->language, state);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const t_language *ts_lookahead_iterator_language(const TSLookaheadIterator *self) {
|
const t_language *ts_lookahead_iterator_language(const t_lookahead_iterator *self) {
|
||||||
const LookaheadIterator *iterator = (const LookaheadIterator *)self;
|
const LookaheadIterator *iterator = (const LookaheadIterator *)self;
|
||||||
return iterator->language;
|
return iterator->language;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ts_lookahead_iterator_reset(TSLookaheadIterator *self, const t_language *language, t_state_id state) {
|
bool ts_lookahead_iterator_reset(t_lookahead_iterator *self, const t_language *language, t_state_id state) {
|
||||||
if (state >= language->state_count) return false;
|
if (state >= language->state_count) return false;
|
||||||
LookaheadIterator *iterator = (LookaheadIterator *)self;
|
LookaheadIterator *iterator = (LookaheadIterator *)self;
|
||||||
*iterator = ts_language_lookaheads(language, state);
|
*iterator = ts_language_lookaheads(language, state);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ts_lookahead_iterator_next(TSLookaheadIterator *self) {
|
bool ts_lookahead_iterator_next(t_lookahead_iterator *self) {
|
||||||
LookaheadIterator *iterator = (LookaheadIterator *)self;
|
LookaheadIterator *iterator = (LookaheadIterator *)self;
|
||||||
return ts_lookahead_iterator__next(iterator);
|
return ts_lookahead_iterator__next(iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
t_symbol ts_lookahead_iterator_current_symbol(const TSLookaheadIterator *self) {
|
t_symbol ts_lookahead_iterator_current_symbol(const t_lookahead_iterator *self) {
|
||||||
const LookaheadIterator *iterator = (const LookaheadIterator *)self;
|
const LookaheadIterator *iterator = (const LookaheadIterator *)self;
|
||||||
return iterator->symbol;
|
return iterator->symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *ts_lookahead_iterator_current_symbol_name(const TSLookaheadIterator *self) {
|
const char *ts_lookahead_iterator_current_symbol_name(const t_lookahead_iterator *self) {
|
||||||
const LookaheadIterator *iterator = (const LookaheadIterator *)self;
|
const LookaheadIterator *iterator = (const LookaheadIterator *)self;
|
||||||
return ts_language_symbol_name(iterator->language, iterator->symbol);
|
return ts_language_symbol_name(iterator->language, iterator->symbol);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
#ifndef TREE_SITTER_LENGTH_H_
|
|
||||||
#define TREE_SITTER_LENGTH_H_
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "./point.h"
|
|
||||||
#include "parser/api.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
t_u32 bytes;
|
|
||||||
t_point extent;
|
|
||||||
} Length;
|
|
||||||
|
|
||||||
static const Length LENGTH_UNDEFINED = {0, {0, 1}};
|
|
||||||
static const Length LENGTH_MAX = {UINT32_MAX, {UINT32_MAX, UINT32_MAX}};
|
|
||||||
|
|
||||||
static inline bool length_is_undefined(Length length) {
|
|
||||||
return length.bytes == 0 && length.extent.column != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Length length_min(Length len1, Length len2) {
|
|
||||||
return (len1.bytes < len2.bytes) ? len1 : len2;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Length length_add(Length len1, Length len2) {
|
|
||||||
Length result;
|
|
||||||
result.bytes = len1.bytes + len2.bytes;
|
|
||||||
result.extent = point_add(len1.extent, len2.extent);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Length length_sub(Length len1, Length len2) {
|
|
||||||
Length result;
|
|
||||||
result.bytes = len1.bytes - len2.bytes;
|
|
||||||
result.extent = point_sub(len1.extent, len2.extent);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Length length_zero(void) {
|
|
||||||
Length result = {0, {0, 0}};
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Length length_saturating_sub(Length len1, Length len2) {
|
|
||||||
if (len1.bytes > len2.bytes) {
|
|
||||||
return length_sub(len1, len2);
|
|
||||||
} else {
|
|
||||||
return length_zero();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#include "./lexer.h"
|
#include "./lexer.h"
|
||||||
#include "./length.h"
|
#include "parser/parser_length.h"
|
||||||
#include "./subtree.h"
|
#include "./subtree.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
" character:'%c'" \
|
" character:'%c'" \
|
||||||
: message " character:%d", \
|
: message " character:%d", \
|
||||||
character); \
|
character); \
|
||||||
self->logger.log(self->logger.payload, TSLogTypeLex, \
|
self->logger.log(self->logger.payload, LogTypeLex, \
|
||||||
self->debug_buffer); \
|
self->debug_buffer); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,7 +113,7 @@ static void ts_lexer__get_lookahead(t_liblexer *self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ts_lexer_goto(t_liblexer *self, Length position)
|
static void ts_lexer_goto(t_liblexer *self, t_parse_length position)
|
||||||
{
|
{
|
||||||
self->current_position = position;
|
self->current_position = position;
|
||||||
|
|
||||||
|
|
@ -127,7 +127,7 @@ static void ts_lexer_goto(t_liblexer *self, Length position)
|
||||||
{
|
{
|
||||||
if (included_range->start_byte >= self->current_position.bytes)
|
if (included_range->start_byte >= self->current_position.bytes)
|
||||||
{
|
{
|
||||||
self->current_position = (Length){
|
self->current_position = (t_parse_length){
|
||||||
.bytes = included_range->start_byte,
|
.bytes = included_range->start_byte,
|
||||||
.extent = included_range->start_point,
|
.extent = included_range->start_point,
|
||||||
};
|
};
|
||||||
|
|
@ -161,7 +161,7 @@ static void ts_lexer_goto(t_liblexer *self, Length position)
|
||||||
self->current_included_range_index = self->included_range_count;
|
self->current_included_range_index = self->included_range_count;
|
||||||
t_parser_range *last_included_range =
|
t_parser_range *last_included_range =
|
||||||
&self->included_ranges[self->included_range_count - 1];
|
&self->included_ranges[self->included_range_count - 1];
|
||||||
self->current_position = (Length){
|
self->current_position = (t_parse_length){
|
||||||
.bytes = last_included_range->end_byte,
|
.bytes = last_included_range->end_byte,
|
||||||
.extent = last_included_range->end_point,
|
.extent = last_included_range->end_point,
|
||||||
};
|
};
|
||||||
|
|
@ -200,7 +200,7 @@ static void ts_lexer__do_advance(t_liblexer *self, bool skip)
|
||||||
if (self->current_included_range_index < self->included_range_count)
|
if (self->current_included_range_index < self->included_range_count)
|
||||||
{
|
{
|
||||||
current_range++;
|
current_range++;
|
||||||
self->current_position = (Length){
|
self->current_position = (t_parse_length){
|
||||||
current_range->start_byte,
|
current_range->start_byte,
|
||||||
current_range->start_point,
|
current_range->start_point,
|
||||||
};
|
};
|
||||||
|
|
@ -260,7 +260,7 @@ static void ts_lexer__mark_end(t_lexer *_self)
|
||||||
{
|
{
|
||||||
t_parser_range *previous_included_range =
|
t_parser_range *previous_included_range =
|
||||||
current_included_range - 1;
|
current_included_range - 1;
|
||||||
self->token_end_position = (Length){
|
self->token_end_position = (t_parse_length){
|
||||||
previous_included_range->end_byte,
|
previous_included_range->end_byte,
|
||||||
previous_included_range->end_point,
|
previous_included_range->end_point,
|
||||||
};
|
};
|
||||||
|
|
@ -355,7 +355,7 @@ void ts_lexer_delete(t_liblexer *self)
|
||||||
free(self->included_ranges);
|
free(self->included_ranges);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_lexer_set_input(t_liblexer *self, TSInput input)
|
void ts_lexer_set_input(t_liblexer *self, t_parse_input input)
|
||||||
{
|
{
|
||||||
self->input = input;
|
self->input = input;
|
||||||
ts_lexer__clear_chunk(self);
|
ts_lexer__clear_chunk(self);
|
||||||
|
|
@ -364,7 +364,7 @@ void ts_lexer_set_input(t_liblexer *self, TSInput input)
|
||||||
|
|
||||||
// Move the lexer to the given position. This doesn't do any work
|
// Move the lexer to the given position. This doesn't do any work
|
||||||
// if the parser is already at the given position.
|
// if the parser is already at the given position.
|
||||||
void ts_lexer_reset(t_liblexer *self, Length position)
|
void ts_lexer_reset(t_liblexer *self, t_parse_length position)
|
||||||
{
|
{
|
||||||
if (position.bytes != self->current_position.bytes)
|
if (position.bytes != self->current_position.bytes)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
#ifndef TREE_SITTER_LEXER_H_
|
#ifndef TREE_SITTER_LEXER_H_
|
||||||
#define TREE_SITTER_LEXER_H_
|
#define TREE_SITTER_LEXER_H_
|
||||||
|
|
||||||
#include "./length.h"
|
#include "parser/parser_length.h"
|
||||||
#include "./parser.h"
|
#include "./parser.h"
|
||||||
#include "./subtree.h"
|
#include "./subtree.h"
|
||||||
#include "parser/api.h"
|
#include "parser/api.h"
|
||||||
|
|
@ -26,14 +26,14 @@
|
||||||
typedef struct s_liblexer
|
typedef struct s_liblexer
|
||||||
{
|
{
|
||||||
t_lexer data;
|
t_lexer data;
|
||||||
Length current_position;
|
t_parse_length current_position;
|
||||||
Length token_start_position;
|
t_parse_length token_start_position;
|
||||||
Length token_end_position;
|
t_parse_length token_end_position;
|
||||||
|
|
||||||
t_parser_range *included_ranges;
|
t_parser_range *included_ranges;
|
||||||
const char *chunk;
|
const char *chunk;
|
||||||
TSInput input;
|
t_parse_input input;
|
||||||
TSLogger logger;
|
t_parse_logger logger;
|
||||||
|
|
||||||
t_u32 included_range_count;
|
t_u32 included_range_count;
|
||||||
t_u32 current_included_range_index;
|
t_u32 current_included_range_index;
|
||||||
|
|
@ -47,8 +47,8 @@ typedef struct s_liblexer
|
||||||
|
|
||||||
void ts_lexer_init(t_liblexer *);
|
void ts_lexer_init(t_liblexer *);
|
||||||
void ts_lexer_delete(t_liblexer *);
|
void ts_lexer_delete(t_liblexer *);
|
||||||
void ts_lexer_set_input(t_liblexer *, TSInput);
|
void ts_lexer_set_input(t_liblexer *, t_parse_input);
|
||||||
void ts_lexer_reset(t_liblexer *, Length);
|
void ts_lexer_reset(t_liblexer *, t_parse_length);
|
||||||
void ts_lexer_start(t_liblexer *);
|
void ts_lexer_start(t_liblexer *);
|
||||||
void ts_lexer_finish(t_liblexer *, t_i32 *);
|
void ts_lexer_finish(t_liblexer *, t_i32 *);
|
||||||
void ts_lexer_advance_to_end(t_liblexer *);
|
void ts_lexer_advance_to_end(t_liblexer *);
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ typedef struct
|
||||||
{
|
{
|
||||||
Subtree parent;
|
Subtree parent;
|
||||||
const t_parse_tree *tree;
|
const t_parse_tree *tree;
|
||||||
Length position;
|
t_parse_length position;
|
||||||
t_u32 child_index;
|
t_u32 child_index;
|
||||||
t_u32 structural_child_index;
|
t_u32 structural_child_index;
|
||||||
const t_symbol *alias_sequence;
|
const t_symbol *alias_sequence;
|
||||||
|
|
@ -16,7 +16,7 @@ typedef struct
|
||||||
// t_parse_node - constructors
|
// t_parse_node - constructors
|
||||||
|
|
||||||
t_parse_node ts_node_new(const t_parse_tree *tree, const Subtree *subtree,
|
t_parse_node ts_node_new(const t_parse_tree *tree, const Subtree *subtree,
|
||||||
Length position, t_symbol alias)
|
t_parse_length position, t_symbol alias)
|
||||||
{
|
{
|
||||||
return (t_parse_node){
|
return (t_parse_node){
|
||||||
{position.bytes, position.extent.row, position.extent.column, alias},
|
{position.bytes, position.extent.row, position.extent.column, alias},
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include "./array.h"
|
#include "./array.h"
|
||||||
#include "./error_costs.h"
|
#include "./error_costs.h"
|
||||||
#include "./language.h"
|
#include "./language.h"
|
||||||
#include "./length.h"
|
#include "parser/parser_length.h"
|
||||||
#include "./lexer.h"
|
#include "./lexer.h"
|
||||||
#include "./reduce_action.h"
|
#include "./reduce_action.h"
|
||||||
#include "./reusable_node.h"
|
#include "./reusable_node.h"
|
||||||
|
|
@ -185,7 +185,7 @@ static void ts_parser__log(t_parser *self)
|
||||||
{
|
{
|
||||||
if (self->lexer.logger.log)
|
if (self->lexer.logger.log)
|
||||||
{
|
{
|
||||||
self->lexer.logger.log(self->lexer.logger.payload, TSLogTypeParse,
|
self->lexer.logger.log(self->lexer.logger.payload, LogTypeParse,
|
||||||
self->lexer.debug_buffer);
|
self->lexer.debug_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -367,7 +367,7 @@ static bool ts_parser__better_version_exists(t_parser *self,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Length position = ts_stack_position(self->stack, version);
|
t_parse_length position = ts_stack_position(self->stack, version);
|
||||||
t_error_status status = {
|
t_error_status status = {
|
||||||
.cost = cost,
|
.cost = cost,
|
||||||
.is_in_error = is_in_error,
|
.is_in_error = is_in_error,
|
||||||
|
|
@ -506,7 +506,7 @@ static Subtree ts_parser__lex(t_parser *self, StackVersion version,
|
||||||
return NULL_SUBTREE;
|
return NULL_SUBTREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Length start_position = ts_stack_position(self->stack, version);
|
const t_parse_length start_position = ts_stack_position(self->stack, version);
|
||||||
const Subtree external_token =
|
const Subtree external_token =
|
||||||
ts_stack_last_external_token(self->stack, version);
|
ts_stack_last_external_token(self->stack, version);
|
||||||
|
|
||||||
|
|
@ -515,8 +515,8 @@ static Subtree ts_parser__lex(t_parser *self, StackVersion version,
|
||||||
bool skipped_error = false;
|
bool skipped_error = false;
|
||||||
bool called_get_column = false;
|
bool called_get_column = false;
|
||||||
t_i32 first_error_character = 0;
|
t_i32 first_error_character = 0;
|
||||||
Length error_start_position = length_zero();
|
t_parse_length error_start_position = length_zero();
|
||||||
Length error_end_position = length_zero();
|
t_parse_length error_end_position = length_zero();
|
||||||
t_i32 lookahead_end_byte = 0;
|
t_i32 lookahead_end_byte = 0;
|
||||||
t_i32 external_scanner_state_len = 0;
|
t_i32 external_scanner_state_len = 0;
|
||||||
bool external_scanner_state_changed = false;
|
bool external_scanner_state_changed = false;
|
||||||
|
|
@ -525,7 +525,7 @@ static Subtree ts_parser__lex(t_parser *self, StackVersion version,
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
bool found_token = false;
|
bool found_token = false;
|
||||||
Length current_position = self->lexer.current_position;
|
t_parse_length current_position = self->lexer.current_position;
|
||||||
|
|
||||||
if (lex_mode.external_lex_state != 0)
|
if (lex_mode.external_lex_state != 0)
|
||||||
{
|
{
|
||||||
|
|
@ -626,8 +626,8 @@ static Subtree ts_parser__lex(t_parser *self, StackVersion version,
|
||||||
Subtree result;
|
Subtree result;
|
||||||
if (skipped_error)
|
if (skipped_error)
|
||||||
{
|
{
|
||||||
Length padding = length_sub(error_start_position, start_position);
|
t_parse_length padding = length_sub(error_start_position, start_position);
|
||||||
Length size = length_sub(error_end_position, error_start_position);
|
t_parse_length size = length_sub(error_end_position, error_start_position);
|
||||||
t_u32 lookahead_bytes =
|
t_u32 lookahead_bytes =
|
||||||
lookahead_end_byte - error_end_position.bytes;
|
lookahead_end_byte - error_end_position.bytes;
|
||||||
result = ts_subtree_new_error(&self->tree_pool, first_error_character,
|
result = ts_subtree_new_error(&self->tree_pool, first_error_character,
|
||||||
|
|
@ -638,9 +638,9 @@ static Subtree ts_parser__lex(t_parser *self, StackVersion version,
|
||||||
{
|
{
|
||||||
bool is_keyword = false;
|
bool is_keyword = false;
|
||||||
t_symbol symbol = self->lexer.data.result_symbol;
|
t_symbol symbol = self->lexer.data.result_symbol;
|
||||||
Length padding =
|
t_parse_length padding =
|
||||||
length_sub(self->lexer.token_start_position, start_position);
|
length_sub(self->lexer.token_start_position, start_position);
|
||||||
Length size = length_sub(self->lexer.token_end_position,
|
t_parse_length size = length_sub(self->lexer.token_end_position,
|
||||||
self->lexer.token_start_position);
|
self->lexer.token_start_position);
|
||||||
t_u32 lookahead_bytes =
|
t_u32 lookahead_bytes =
|
||||||
lookahead_end_byte - self->lexer.token_end_position.bytes;
|
lookahead_end_byte - self->lexer.token_end_position.bytes;
|
||||||
|
|
@ -1300,7 +1300,7 @@ static void ts_parser__recover(t_parser *self, StackVersion version,
|
||||||
{
|
{
|
||||||
bool did_recover = false;
|
bool did_recover = false;
|
||||||
unsigned previous_version_count = ts_stack_version_count(self->stack);
|
unsigned previous_version_count = ts_stack_version_count(self->stack);
|
||||||
Length position = ts_stack_position(self->stack, version);
|
t_parse_length position = ts_stack_position(self->stack, version);
|
||||||
StackSummary *summary = ts_stack_get_summary(self->stack, version);
|
StackSummary *summary = ts_stack_get_summary(self->stack, version);
|
||||||
unsigned node_count_since_error =
|
unsigned node_count_since_error =
|
||||||
ts_stack_node_count_since_error(self->stack, version);
|
ts_stack_node_count_since_error(self->stack, version);
|
||||||
|
|
@ -1515,7 +1515,7 @@ static void ts_parser__handle_error(t_parser *self, StackVersion version,
|
||||||
// find a token that would have allowed a reduction to take place.
|
// find a token that would have allowed a reduction to take place.
|
||||||
ts_parser__do_all_potential_reductions(self, version, 0);
|
ts_parser__do_all_potential_reductions(self, version, 0);
|
||||||
t_u32 version_count = ts_stack_version_count(self->stack);
|
t_u32 version_count = ts_stack_version_count(self->stack);
|
||||||
Length position = ts_stack_position(self->stack, version);
|
t_parse_length position = ts_stack_position(self->stack, version);
|
||||||
|
|
||||||
// Push a discontinuity onto the stack. Merge all of the stack versions that
|
// Push a discontinuity onto the stack. Merge all of the stack versions that
|
||||||
// were created in the previous step.
|
// were created in the previous step.
|
||||||
|
|
@ -1547,7 +1547,7 @@ static void ts_parser__handle_error(t_parser *self, StackVersion version,
|
||||||
// assigned to position it within the next included range.
|
// assigned to position it within the next included range.
|
||||||
ts_lexer_reset(&self->lexer, position);
|
ts_lexer_reset(&self->lexer, position);
|
||||||
ts_lexer_mark_end(&self->lexer);
|
ts_lexer_mark_end(&self->lexer);
|
||||||
Length padding =
|
t_parse_length padding =
|
||||||
length_sub(self->lexer.token_end_position, position);
|
length_sub(self->lexer.token_end_position, position);
|
||||||
t_u32 lookahead_bytes =
|
t_u32 lookahead_bytes =
|
||||||
ts_subtree_total_bytes(lookahead) +
|
ts_subtree_total_bytes(lookahead) +
|
||||||
|
|
@ -2053,12 +2053,12 @@ bool ts_parser_set_language(t_parser *self, const t_language *language)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TSLogger ts_parser_logger(const t_parser *self)
|
t_parse_logger ts_parser_logger(const t_parser *self)
|
||||||
{
|
{
|
||||||
return self->lexer.logger;
|
return self->lexer.logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_parser_set_logger(t_parser *self, TSLogger logger)
|
void ts_parser_set_logger(t_parser *self, t_parse_logger logger)
|
||||||
{
|
{
|
||||||
self->lexer.logger = logger;
|
self->lexer.logger = logger;
|
||||||
}
|
}
|
||||||
|
|
@ -2141,7 +2141,7 @@ void ts_parser_reset(t_parser *self)
|
||||||
self->has_scanner_error = false;
|
self->has_scanner_error = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_parse_tree *ts_parser_parse(t_parser *self, const t_parse_tree *old_tree, TSInput input)
|
t_parse_tree *ts_parser_parse(t_parser *self, const t_parse_tree *old_tree, t_parse_input input)
|
||||||
{
|
{
|
||||||
t_parse_tree *result = NULL;
|
t_parse_tree *result = NULL;
|
||||||
old_tree = NULL;
|
old_tree = NULL;
|
||||||
|
|
@ -2258,16 +2258,16 @@ t_parse_tree *ts_parser_parse_string(t_parser *self, const t_parse_tree *old_tre
|
||||||
const char *string, t_u32 length)
|
const char *string, t_u32 length)
|
||||||
{
|
{
|
||||||
return ts_parser_parse_string_encoding(self, old_tree, string, length,
|
return ts_parser_parse_string_encoding(self, old_tree, string, length,
|
||||||
TSInputEncodingUTF8);
|
InputEncoding8);
|
||||||
}
|
}
|
||||||
|
|
||||||
t_parse_tree *ts_parser_parse_string_encoding(t_parser *self, const t_parse_tree *old_tree,
|
t_parse_tree *ts_parser_parse_string_encoding(t_parser *self, const t_parse_tree *old_tree,
|
||||||
const char *string, t_u32 length,
|
const char *string, t_u32 length,
|
||||||
TSInputEncoding encoding)
|
t_input_encoding encoding)
|
||||||
{
|
{
|
||||||
t_string_input input = {string, length};
|
t_string_input input = {string, length};
|
||||||
return ts_parser_parse(self, old_tree,
|
return ts_parser_parse(self, old_tree,
|
||||||
(TSInput){
|
(t_parse_input){
|
||||||
&input,
|
&input,
|
||||||
ts_string_inpt_read,
|
ts_string_inpt_read,
|
||||||
encoding,
|
encoding,
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
#include "array.h"
|
#include "me/mem/mem_alloc.h"
|
||||||
#include "parser.h"
|
#include "me/types.h"
|
||||||
|
#include "me/vec/vec_parser_heredoc.h"
|
||||||
#include "parser/types/types_lexer.h"
|
#include "parser/types/types_lexer.h"
|
||||||
|
#include "parser/types/types_scanner_ctx.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wctype.h>
|
|
||||||
|
|
||||||
#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
|
#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
|
||||||
|
|
||||||
|
|
@ -42,37 +43,17 @@ enum TokenType
|
||||||
ERROR_RECOVERY,
|
ERROR_RECOVERY,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Array(char) t_string;
|
|
||||||
// typedef void *String;
|
|
||||||
|
|
||||||
typedef struct s_heredoc
|
|
||||||
{
|
|
||||||
bool is_raw;
|
|
||||||
bool started;
|
|
||||||
bool allows_indent;
|
|
||||||
t_string delimiter;
|
|
||||||
t_string current_leading_word;
|
|
||||||
} t_heredoc;
|
|
||||||
|
|
||||||
static inline t_heredoc heredoc_new(void)
|
static inline t_heredoc heredoc_new(void)
|
||||||
{
|
{
|
||||||
return ((t_heredoc){
|
return ((t_heredoc){
|
||||||
.is_raw = false,
|
.is_raw = false,
|
||||||
.started = false,
|
.started = false,
|
||||||
.allows_indent = false,
|
.allows_indent = false,
|
||||||
.delimiter = array_new(),
|
.delimiter = alloc_new_buffer(0),
|
||||||
.current_leading_word = array_new(),
|
.current_leading_word = alloc_new_buffer(0),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct s_scanner
|
|
||||||
{
|
|
||||||
t_u8 last_glob_paren_depth;
|
|
||||||
bool ext_was_in_double_quote;
|
|
||||||
bool ext_saw_outside_quote;
|
|
||||||
Array(t_heredoc) heredocs;
|
|
||||||
} t_scanner;
|
|
||||||
|
|
||||||
static inline void advance(t_lexer *lexer)
|
static inline void advance(t_lexer *lexer)
|
||||||
{
|
{
|
||||||
lexer->advance(lexer, false);
|
lexer->advance(lexer, false);
|
||||||
|
|
@ -88,12 +69,12 @@ static inline bool in_error_recovery(const bool *valid_symbols)
|
||||||
return valid_symbols[ERROR_RECOVERY];
|
return valid_symbols[ERROR_RECOVERY];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void reset_string(t_string *string)
|
static inline void reset_string(t_buffer_str *string)
|
||||||
{
|
{
|
||||||
if (string->size > 0)
|
if (string->len > 0)
|
||||||
{
|
{
|
||||||
memset(string->contents, 0, string->size);
|
memset(string->buf, 0, string->len);
|
||||||
array_clear(string);
|
string->len = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,58 +86,59 @@ static inline void reset_heredoc(t_heredoc *heredoc)
|
||||||
reset_string(&heredoc->delimiter);
|
reset_string(&heredoc->delimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void reset(t_scanner *scanner)
|
static inline void reset(t_scanner_ctx *scanner)
|
||||||
{
|
{
|
||||||
t_u32 i;
|
t_u32 i;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < scanner->heredocs.size)
|
while (i < scanner->heredocs.len)
|
||||||
{
|
{
|
||||||
reset_heredoc(array_get(&scanner->heredocs, i));
|
reset_heredoc(&scanner->heredocs.buffer[i]);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned serialize(t_scanner *scanner, char *buffer)
|
static unsigned serialize(t_scanner_ctx *scanner, char *buffer)
|
||||||
{
|
{
|
||||||
t_u32 size;
|
t_u32 size;
|
||||||
t_u32 i;
|
t_u32 i;
|
||||||
t_heredoc *heredoc;
|
t_heredoc *heredoc;
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
buffer[size++] = (char)scanner->last_glob_paren_depth;
|
buffer[size++] = (char)scanner->last_glob_paren_depth;
|
||||||
buffer[size++] = (char)scanner->ext_was_in_double_quote;
|
buffer[size++] = (char)scanner->ext_was_in_double_quote;
|
||||||
buffer[size++] = (char)scanner->ext_saw_outside_quote;
|
buffer[size++] = (char)scanner->ext_saw_outside_quote;
|
||||||
buffer[size++] = (char)scanner->heredocs.size;
|
buffer[size++] = (char)scanner->heredocs.len;
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < scanner->heredocs.size)
|
while (i < scanner->heredocs.len)
|
||||||
{
|
{
|
||||||
heredoc = array_get(&scanner->heredocs, i);
|
heredoc = &scanner->heredocs.buffer[i];
|
||||||
if (heredoc->delimiter.size + 3 + size >=
|
if (heredoc->delimiter.len + 3 + size >=
|
||||||
TREE_SITTER_SERIALIZATION_BUFFER_SIZE)
|
TREE_SITTER_SERIALIZATION_BUFFER_SIZE)
|
||||||
return 0;
|
return 0;
|
||||||
buffer[size++] = (char)heredoc->is_raw;
|
buffer[size++] = (char)heredoc->is_raw;
|
||||||
buffer[size++] = (char)heredoc->started;
|
buffer[size++] = (char)heredoc->started;
|
||||||
buffer[size++] = (char)heredoc->allows_indent;
|
buffer[size++] = (char)heredoc->allows_indent;
|
||||||
memcpy(&buffer[size], &heredoc->delimiter.size, sizeof(t_u32));
|
memcpy(&buffer[size], &heredoc->delimiter.len, sizeof(t_u32));
|
||||||
size += sizeof(t_u32);
|
size += sizeof(t_u32);
|
||||||
if (heredoc->delimiter.size > 0)
|
if (heredoc->delimiter.len > 0)
|
||||||
{
|
{
|
||||||
memcpy(&buffer[size], heredoc->delimiter.contents,
|
memcpy(&buffer[size], heredoc->delimiter.buf,
|
||||||
heredoc->delimiter.size);
|
heredoc->delimiter.len);
|
||||||
size += heredoc->delimiter.size;
|
size += heredoc->delimiter.len;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void deserialize(t_scanner *scanner, const char *buffer, unsigned length)
|
static void deserialize(t_scanner_ctx *scanner, const char *buffer,
|
||||||
|
unsigned length)
|
||||||
{
|
{
|
||||||
t_u32 size;
|
t_u32 size;
|
||||||
t_u32 heredoc_count;
|
t_u32 heredoc_count;
|
||||||
t_heredoc *heredoc;
|
t_heredoc *heredoc;
|
||||||
t_u32 i;
|
t_u32 i;
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
|
|
@ -171,24 +153,24 @@ static void deserialize(t_scanner *scanner, const char *buffer, unsigned length)
|
||||||
while (i < heredoc_count)
|
while (i < heredoc_count)
|
||||||
{
|
{
|
||||||
heredoc = NULL;
|
heredoc = NULL;
|
||||||
if (i < scanner->heredocs.size)
|
if (i < scanner->heredocs.len)
|
||||||
heredoc = array_get(&scanner->heredocs, i);
|
heredoc = &scanner->heredocs.buffer[i];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
array_push(&scanner->heredocs, heredoc_new());
|
vec_parser_heredoc_push(&scanner->heredocs, heredoc_new());
|
||||||
heredoc = array_back(&scanner->heredocs);
|
heredoc = &scanner->heredocs.buffer[scanner->heredocs.len - 1];
|
||||||
}
|
}
|
||||||
heredoc->is_raw = buffer[size++];
|
heredoc->is_raw = buffer[size++];
|
||||||
heredoc->started = buffer[size++];
|
heredoc->started = buffer[size++];
|
||||||
heredoc->allows_indent = buffer[size++];
|
heredoc->allows_indent = buffer[size++];
|
||||||
memcpy(&heredoc->delimiter.size, &buffer[size], sizeof(t_u32));
|
memcpy(&heredoc->delimiter.len, &buffer[size], sizeof(t_u32));
|
||||||
size += sizeof(t_u32);
|
size += sizeof(t_u32);
|
||||||
array_reserve(&heredoc->delimiter, heredoc->delimiter.size);
|
str_reserve(&heredoc->delimiter, heredoc->delimiter.len);
|
||||||
if (heredoc->delimiter.size > 0)
|
if (heredoc->delimiter.len > 0)
|
||||||
{
|
{
|
||||||
memcpy(heredoc->delimiter.contents, &buffer[size],
|
memcpy(heredoc->delimiter.buf, &buffer[size],
|
||||||
heredoc->delimiter.size);
|
heredoc->delimiter.len);
|
||||||
size += heredoc->delimiter.size;
|
size += heredoc->delimiter.len;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
@ -203,9 +185,9 @@ static void deserialize(t_scanner *scanner, const char *buffer, unsigned length)
|
||||||
* POSIX-mandated substitution, and assumes the default value for
|
* POSIX-mandated substitution, and assumes the default value for
|
||||||
* IFS.
|
* IFS.
|
||||||
*/
|
*/
|
||||||
static bool advance_word(t_lexer *lexer, t_string *unquoted_word)
|
static bool advance_word(t_lexer *lexer, t_buffer_str *unquoted_word)
|
||||||
{
|
{
|
||||||
bool empty;
|
bool empty;
|
||||||
t_i32 quote;
|
t_i32 quote;
|
||||||
|
|
||||||
quote = 0;
|
quote = 0;
|
||||||
|
|
@ -224,10 +206,9 @@ static bool advance_word(t_lexer *lexer, t_string *unquoted_word)
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
empty = false;
|
empty = false;
|
||||||
array_push(unquoted_word, lexer->lookahead);
|
push_str_char(unquoted_word, lexer->lookahead);
|
||||||
advance(lexer);
|
advance(lexer);
|
||||||
}
|
}
|
||||||
array_push(unquoted_word, '\0');
|
|
||||||
if (quote && lexer->lookahead == quote)
|
if (quote && lexer->lookahead == quote)
|
||||||
advance(lexer);
|
advance(lexer);
|
||||||
return (!empty);
|
return (!empty);
|
||||||
|
|
@ -277,31 +258,29 @@ static bool scan_heredoc_end_identifier(t_heredoc *heredoc, t_lexer *lexer)
|
||||||
t_i32 size;
|
t_i32 size;
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
if (heredoc->delimiter.size > 0)
|
if (heredoc->delimiter.len > 0)
|
||||||
{
|
{
|
||||||
while (lexer->lookahead != '\0' && lexer->lookahead != '\n' &&
|
while (lexer->lookahead != '\0' && lexer->lookahead != '\n' &&
|
||||||
(t_i32)*array_get(&heredoc->delimiter, size) ==
|
(t_i32) * (&heredoc->delimiter.buf[size]) == lexer->lookahead &&
|
||||||
lexer->lookahead &&
|
heredoc->current_leading_word.len < heredoc->delimiter.len)
|
||||||
heredoc->current_leading_word.size < heredoc->delimiter.size)
|
|
||||||
{
|
{
|
||||||
array_push(&heredoc->current_leading_word, lexer->lookahead);
|
push_str_char(&heredoc->current_leading_word, lexer->lookahead);
|
||||||
advance(lexer);
|
advance(lexer);
|
||||||
size++;
|
size++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
array_push(&heredoc->current_leading_word, '\0');
|
return heredoc->delimiter.len == 0
|
||||||
return heredoc->delimiter.size == 0
|
|
||||||
? false
|
? false
|
||||||
: strcmp(heredoc->current_leading_word.contents,
|
: strcmp(heredoc->current_leading_word.buf,
|
||||||
heredoc->delimiter.contents) == 0;
|
heredoc->delimiter.buf) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool scan_heredoc_content(t_scanner *scanner, t_lexer *lexer,
|
static bool scan_heredoc_content(t_scanner_ctx *scanner, t_lexer *lexer,
|
||||||
enum TokenType middle_type,
|
enum TokenType middle_type,
|
||||||
enum TokenType end_type)
|
enum TokenType end_type)
|
||||||
{
|
{
|
||||||
bool did_advance = false;
|
bool did_advance = false;
|
||||||
t_heredoc *heredoc = array_back(&scanner->heredocs);
|
t_heredoc *heredoc = (&scanner->heredocs.buffer[scanner->heredocs.len - 1]);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
|
@ -376,9 +355,7 @@ static bool scan_heredoc_content(t_scanner *scanner, t_lexer *lexer,
|
||||||
if (scan_heredoc_end_identifier(heredoc, lexer))
|
if (scan_heredoc_end_identifier(heredoc, lexer))
|
||||||
{
|
{
|
||||||
if (lexer->result_symbol == HEREDOC_END)
|
if (lexer->result_symbol == HEREDOC_END)
|
||||||
{
|
vec_parser_heredoc_pop(&scanner->heredocs, NULL);
|
||||||
array_pop(&scanner->heredocs);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -425,7 +402,7 @@ static bool scan_heredoc_content(t_scanner *scanner, t_lexer *lexer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static bool regex_scan(t_scanner *scanner, t_lexer *lexer,
|
static bool regex_scan(t_scanner_ctx *scanner, t_lexer *lexer,
|
||||||
const bool *valid_symbols)
|
const bool *valid_symbols)
|
||||||
{
|
{
|
||||||
(void)(scanner);
|
(void)(scanner);
|
||||||
|
|
@ -449,11 +426,11 @@ static bool regex_scan(t_scanner *scanner, t_lexer *lexer,
|
||||||
{
|
{
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
bool done;
|
bool done;
|
||||||
bool advanced_once;
|
bool advanced_once;
|
||||||
bool found_non_alnumdollarunderdash;
|
bool found_non_alnumdollarunderdash;
|
||||||
bool last_was_escape;
|
bool last_was_escape;
|
||||||
bool in_single_quote;
|
bool in_single_quote;
|
||||||
t_u32 paren_depth;
|
t_u32 paren_depth;
|
||||||
t_u32 bracket_depth;
|
t_u32 bracket_depth;
|
||||||
t_u32 brace_depth;
|
t_u32 brace_depth;
|
||||||
|
|
@ -650,7 +627,7 @@ static bool regex_scan(t_scanner *scanner, t_lexer *lexer,
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool extglob_pattern_scan(t_scanner *scanner, t_lexer *lexer,
|
static bool extglob_pattern_scan(t_scanner_ctx *scanner, t_lexer *lexer,
|
||||||
const bool *valid_symbols)
|
const bool *valid_symbols)
|
||||||
{
|
{
|
||||||
if (valid_symbols[EXTGLOB_PATTERN] && !in_error_recovery(valid_symbols))
|
if (valid_symbols[EXTGLOB_PATTERN] && !in_error_recovery(valid_symbols))
|
||||||
|
|
@ -793,8 +770,8 @@ static bool extglob_pattern_scan(t_scanner *scanner, t_lexer *lexer,
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
bool done;
|
bool done;
|
||||||
bool saw_non_alphadot;
|
bool saw_non_alphadot;
|
||||||
t_u32 paren_depth;
|
t_u32 paren_depth;
|
||||||
t_u32 bracket_depth;
|
t_u32 bracket_depth;
|
||||||
t_u32 brace_depth;
|
t_u32 brace_depth;
|
||||||
|
|
@ -926,11 +903,11 @@ static bool extglob_pattern_scan(t_scanner *scanner, t_lexer *lexer,
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool expansion_word_scan(t_scanner *scanner, t_lexer *lexer,
|
static bool expansion_word_scan(t_scanner_ctx *scanner, t_lexer *lexer,
|
||||||
const bool *valid_symbols)
|
const bool *valid_symbols)
|
||||||
{
|
{
|
||||||
(void)(scanner);
|
(void)(scanner);
|
||||||
|
|
||||||
if (valid_symbols[EXPANSION_WORD])
|
if (valid_symbols[EXPANSION_WORD])
|
||||||
{
|
{
|
||||||
bool advanced_once = false;
|
bool advanced_once = false;
|
||||||
|
|
@ -1027,14 +1004,14 @@ static bool expansion_word_scan(t_scanner *scanner, t_lexer *lexer,
|
||||||
advance(lexer);
|
advance(lexer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool brace_start_scan(t_scanner *scanner, t_lexer *lexer,
|
static bool brace_start_scan(t_scanner_ctx *scanner, t_lexer *lexer,
|
||||||
const bool *valid_symbols)
|
const bool *valid_symbols)
|
||||||
{
|
{
|
||||||
(void)(scanner);
|
(void)(scanner);
|
||||||
|
|
||||||
if (valid_symbols[BRACE_START] && !in_error_recovery(valid_symbols))
|
if (valid_symbols[BRACE_START] && !in_error_recovery(valid_symbols))
|
||||||
{
|
{
|
||||||
while (isspace(lexer->lookahead))
|
while (isspace(lexer->lookahead))
|
||||||
|
|
@ -1082,7 +1059,8 @@ static bool brace_start_scan(t_scanner *scanner, t_lexer *lexer,
|
||||||
}
|
}
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
static bool scan(t_scanner *scanner, t_lexer *lexer, const bool *valid_symbols)
|
static bool scan(t_scanner_ctx *scanner, t_lexer *lexer,
|
||||||
|
const bool *valid_symbols)
|
||||||
{
|
{
|
||||||
if (valid_symbols[CONCAT] && !in_error_recovery(valid_symbols))
|
if (valid_symbols[CONCAT] && !in_error_recovery(valid_symbols))
|
||||||
{
|
{
|
||||||
|
|
@ -1186,38 +1164,41 @@ static bool scan(t_scanner *scanner, t_lexer *lexer, const bool *valid_symbols)
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
t_heredoc *back;
|
||||||
|
vec_parser_heredoc_back(&scanner->heredocs, &back);
|
||||||
if ((valid_symbols[HEREDOC_BODY_BEGINNING] ||
|
if ((valid_symbols[HEREDOC_BODY_BEGINNING] ||
|
||||||
valid_symbols[SIMPLE_HEREDOC_BODY]) &&
|
valid_symbols[SIMPLE_HEREDOC_BODY]) &&
|
||||||
scanner->heredocs.size > 0 &&
|
scanner->heredocs.len > 0 && !back->started &&
|
||||||
!array_back(&scanner->heredocs)->started &&
|
|
||||||
!in_error_recovery(valid_symbols))
|
!in_error_recovery(valid_symbols))
|
||||||
return (scan_heredoc_content(scanner, lexer, HEREDOC_BODY_BEGINNING,
|
return (scan_heredoc_content(scanner, lexer, HEREDOC_BODY_BEGINNING,
|
||||||
SIMPLE_HEREDOC_BODY));
|
SIMPLE_HEREDOC_BODY));
|
||||||
|
|
||||||
if (valid_symbols[HEREDOC_END] && scanner->heredocs.size > 0)
|
if (valid_symbols[HEREDOC_END] && scanner->heredocs.len > 0)
|
||||||
{
|
{
|
||||||
t_heredoc *heredoc = array_back(&scanner->heredocs);
|
t_heredoc *heredoc;
|
||||||
|
vec_parser_heredoc_back(&scanner->heredocs, &heredoc);
|
||||||
if (scan_heredoc_end_identifier(heredoc, lexer))
|
if (scan_heredoc_end_identifier(heredoc, lexer))
|
||||||
{
|
{
|
||||||
array_delete(&heredoc->current_leading_word);
|
str_free(heredoc->current_leading_word);
|
||||||
array_delete(&heredoc->delimiter);
|
str_free(heredoc->delimiter);
|
||||||
array_pop(&scanner->heredocs);
|
scanner->heredocs.len -= 1;
|
||||||
lexer->result_symbol = HEREDOC_END;
|
lexer->result_symbol = HEREDOC_END;
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid_symbols[HEREDOC_CONTENT] && scanner->heredocs.size > 0 &&
|
vec_parser_heredoc_back(&scanner->heredocs, &back);
|
||||||
array_back(&scanner->heredocs)->started &&
|
if (valid_symbols[HEREDOC_CONTENT] && scanner->heredocs.len > 0 &&
|
||||||
!in_error_recovery(valid_symbols))
|
back->started && !in_error_recovery(valid_symbols))
|
||||||
return (
|
return (
|
||||||
scan_heredoc_content(scanner, lexer, HEREDOC_CONTENT, HEREDOC_END));
|
scan_heredoc_content(scanner, lexer, HEREDOC_CONTENT, HEREDOC_END));
|
||||||
|
|
||||||
if (valid_symbols[HEREDOC_START] && !in_error_recovery(valid_symbols) &&
|
if (valid_symbols[HEREDOC_START] && !in_error_recovery(valid_symbols) &&
|
||||||
scanner->heredocs.size > 0)
|
scanner->heredocs.len > 0)
|
||||||
return (scan_heredoc_start(array_back(&scanner->heredocs), lexer));
|
{
|
||||||
|
vec_parser_heredoc_back(&scanner->heredocs, &back);
|
||||||
|
return (scan_heredoc_start(back, lexer));
|
||||||
|
}
|
||||||
if (valid_symbols[TEST_OPERATOR] && !valid_symbols[EXPANSION_WORD])
|
if (valid_symbols[TEST_OPERATOR] && !valid_symbols[EXPANSION_WORD])
|
||||||
{
|
{
|
||||||
while (isspace(lexer->lookahead) && lexer->lookahead != '\n')
|
while (isspace(lexer->lookahead) && lexer->lookahead != '\n')
|
||||||
|
|
@ -1376,7 +1357,7 @@ static bool scan(t_scanner *scanner, t_lexer *lexer, const bool *valid_symbols)
|
||||||
advance(lexer);
|
advance(lexer);
|
||||||
t_heredoc heredoc = heredoc_new();
|
t_heredoc heredoc = heredoc_new();
|
||||||
heredoc.allows_indent = true;
|
heredoc.allows_indent = true;
|
||||||
array_push(&scanner->heredocs, heredoc);
|
vec_parser_heredoc_push(&scanner->heredocs, heredoc);
|
||||||
lexer->result_symbol = HEREDOC_ARROW_DASH;
|
lexer->result_symbol = HEREDOC_ARROW_DASH;
|
||||||
}
|
}
|
||||||
else if (lexer->lookahead == '<' || lexer->lookahead == '=')
|
else if (lexer->lookahead == '<' || lexer->lookahead == '=')
|
||||||
|
|
@ -1384,7 +1365,7 @@ static bool scan(t_scanner *scanner, t_lexer *lexer, const bool *valid_symbols)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
t_heredoc heredoc = heredoc_new();
|
t_heredoc heredoc = heredoc_new();
|
||||||
array_push(&scanner->heredocs, heredoc);
|
vec_parser_heredoc_push(&scanner->heredocs, heredoc);
|
||||||
lexer->result_symbol = HEREDOC_ARROW;
|
lexer->result_symbol = HEREDOC_ARROW;
|
||||||
}
|
}
|
||||||
return (true);
|
return (true);
|
||||||
|
|
@ -1483,21 +1464,21 @@ static bool scan(t_scanner *scanner, t_lexer *lexer, const bool *valid_symbols)
|
||||||
|
|
||||||
void *tree_sitter_bash_external_scanner_create()
|
void *tree_sitter_bash_external_scanner_create()
|
||||||
{
|
{
|
||||||
t_scanner *scanner = calloc(1, sizeof(t_scanner));
|
t_scanner_ctx *scanner = mem_alloc(sizeof(t_scanner_ctx));
|
||||||
array_init(&scanner->heredocs);
|
scanner->heredocs = vec_parser_heredoc_new(5, NULL);
|
||||||
return (scanner);
|
return (scanner);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tree_sitter_bash_external_scanner_scan(void *payload, t_lexer *lexer,
|
bool tree_sitter_bash_external_scanner_scan(void *payload, t_lexer *lexer,
|
||||||
const bool *valid_symbols)
|
const bool *valid_symbols)
|
||||||
{
|
{
|
||||||
t_scanner *scanner = (t_scanner *)payload;
|
t_scanner_ctx *scanner = (t_scanner_ctx *)payload;
|
||||||
return (scan(scanner, lexer, valid_symbols));
|
return (scan(scanner, lexer, valid_symbols));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned tree_sitter_bash_external_scanner_serialize(void *payload, char *state)
|
unsigned tree_sitter_bash_external_scanner_serialize(void *payload, char *state)
|
||||||
{
|
{
|
||||||
t_scanner *scanner = (t_scanner *)payload;
|
t_scanner_ctx *scanner = (t_scanner_ctx *)payload;
|
||||||
return (serialize(scanner, state));
|
return (serialize(scanner, state));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1505,19 +1486,19 @@ void tree_sitter_bash_external_scanner_deserialize(void *payload,
|
||||||
const char *state,
|
const char *state,
|
||||||
unsigned length)
|
unsigned length)
|
||||||
{
|
{
|
||||||
t_scanner *scanner = (t_scanner *)payload;
|
t_scanner_ctx *scanner = (t_scanner_ctx *)payload;
|
||||||
deserialize(scanner, state, length);
|
deserialize(scanner, state, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tree_sitter_bash_external_scanner_destroy(void *payload)
|
void tree_sitter_bash_external_scanner_destroy(void *payload)
|
||||||
{
|
{
|
||||||
t_scanner *scanner = (t_scanner *)payload;
|
t_scanner_ctx *scanner = (t_scanner_ctx *)payload;
|
||||||
for (size_t i = 0; i < scanner->heredocs.size; i++)
|
for (size_t i = 0; i < scanner->heredocs.len; i++)
|
||||||
{
|
{
|
||||||
t_heredoc *heredoc = array_get(&scanner->heredocs, i);
|
t_heredoc *heredoc = &scanner->heredocs.buffer[i];
|
||||||
array_delete(&heredoc->current_leading_word);
|
str_free(heredoc->current_leading_word);
|
||||||
array_delete(&heredoc->delimiter);
|
str_free(heredoc->delimiter);
|
||||||
}
|
}
|
||||||
array_delete(&scanner->heredocs);
|
vec_parser_heredoc_free(scanner->heredocs);
|
||||||
free(scanner);
|
free(scanner);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
#include "./subtree.h"
|
#include "./subtree.h"
|
||||||
#include "./array.h"
|
#include "./array.h"
|
||||||
#include "./stack.h"
|
#include "./stack.h"
|
||||||
#include "./length.h"
|
#include "parser/parser_length.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -28,7 +28,7 @@ typedef struct {
|
||||||
|
|
||||||
struct StackNode {
|
struct StackNode {
|
||||||
t_state_id state;
|
t_state_id state;
|
||||||
Length position;
|
t_parse_length position;
|
||||||
StackLink links[MAX_LINK_COUNT];
|
StackLink links[MAX_LINK_COUNT];
|
||||||
short unsigned int link_count;
|
short unsigned int link_count;
|
||||||
t_u32 ref_count;
|
t_u32 ref_count;
|
||||||
|
|
@ -464,7 +464,7 @@ t_state_id ts_stack_state(const Stack *self, StackVersion version) {
|
||||||
return array_get(&self->heads, version)->node->state;
|
return array_get(&self->heads, version)->node->state;
|
||||||
}
|
}
|
||||||
|
|
||||||
Length ts_stack_position(const Stack *self, StackVersion version) {
|
t_parse_length ts_stack_position(const Stack *self, StackVersion version) {
|
||||||
return array_get(&self->heads, version)->node->position;
|
return array_get(&self->heads, version)->node->position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ typedef struct {
|
||||||
typedef Array(StackSlice) StackSliceArray;
|
typedef Array(StackSlice) StackSliceArray;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Length position;
|
t_parse_length position;
|
||||||
unsigned depth;
|
unsigned depth;
|
||||||
t_state_id state;
|
t_state_id state;
|
||||||
} StackSummaryEntry;
|
} StackSummaryEntry;
|
||||||
|
|
@ -48,7 +48,7 @@ Subtree ts_stack_last_external_token(const Stack *, StackVersion);
|
||||||
void ts_stack_set_last_external_token(Stack *, StackVersion, Subtree );
|
void ts_stack_set_last_external_token(Stack *, StackVersion, Subtree );
|
||||||
|
|
||||||
// Get the position of the given version of the stack within the document.
|
// Get the position of the given version of the stack within the document.
|
||||||
Length ts_stack_position(const Stack *, StackVersion);
|
t_parse_length ts_stack_position(const Stack *, StackVersion);
|
||||||
|
|
||||||
// Push a tree and state onto the given version of the stack.
|
// Push a tree and state onto the given version of the stack.
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -9,15 +9,15 @@
|
||||||
|
|
||||||
#include "./error_costs.h"
|
#include "./error_costs.h"
|
||||||
#include "./language.h"
|
#include "./language.h"
|
||||||
#include "./length.h"
|
#include "parser/parser_length.h"
|
||||||
#include "./subtree.h"
|
#include "./subtree.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
Length start;
|
t_parse_length start;
|
||||||
Length old_end;
|
t_parse_length old_end;
|
||||||
Length new_end;
|
t_parse_length new_end;
|
||||||
} Edit;
|
} Edit;
|
||||||
|
|
||||||
#define TS_MAX_INLINE_TREE_LENGTH UINT8_MAX
|
#define TS_MAX_INLINE_TREE_LENGTH UINT8_MAX
|
||||||
|
|
@ -193,7 +193,7 @@ static void ts_subtree_pool_free(SubtreePool *self, SubtreeHeapData *tree)
|
||||||
|
|
||||||
// Subtree
|
// Subtree
|
||||||
|
|
||||||
static inline bool ts_subtree_can_inline(Length padding, Length size,
|
static inline bool ts_subtree_can_inline(t_parse_length padding, t_parse_length size,
|
||||||
t_u32 lookahead_bytes)
|
t_u32 lookahead_bytes)
|
||||||
{
|
{
|
||||||
return padding.bytes < TS_MAX_INLINE_TREE_LENGTH &&
|
return padding.bytes < TS_MAX_INLINE_TREE_LENGTH &&
|
||||||
|
|
@ -204,8 +204,8 @@ static inline bool ts_subtree_can_inline(Length padding, Length size,
|
||||||
lookahead_bytes < 16;
|
lookahead_bytes < 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
Subtree ts_subtree_new_leaf(SubtreePool *pool, t_symbol symbol, Length padding,
|
Subtree ts_subtree_new_leaf(SubtreePool *pool, t_symbol symbol, t_parse_length padding,
|
||||||
Length size, t_u32 lookahead_bytes,
|
t_parse_length size, t_u32 lookahead_bytes,
|
||||||
t_state_id parse_state, bool has_external_tokens,
|
t_state_id parse_state, bool has_external_tokens,
|
||||||
bool depends_on_column, bool is_keyword,
|
bool depends_on_column, bool is_keyword,
|
||||||
const t_language *language)
|
const t_language *language)
|
||||||
|
|
@ -283,7 +283,7 @@ void ts_subtree_set_symbol(MutableSubtree *self, t_symbol symbol,
|
||||||
}
|
}
|
||||||
|
|
||||||
Subtree ts_subtree_new_error(SubtreePool *pool, t_i32 lookahead_char,
|
Subtree ts_subtree_new_error(SubtreePool *pool, t_i32 lookahead_char,
|
||||||
Length padding, Length size,
|
t_parse_length padding, t_parse_length size,
|
||||||
t_u32 bytes_scanned, t_state_id parse_state,
|
t_u32 bytes_scanned, t_state_id parse_state,
|
||||||
const t_language *language)
|
const t_language *language)
|
||||||
{
|
{
|
||||||
|
|
@ -654,7 +654,7 @@ Subtree ts_subtree_new_error_node(SubtreeArray *children, bool extra,
|
||||||
// This node is treated as 'extra'. Its children are prevented from having
|
// This node is treated as 'extra'. Its children are prevented from having
|
||||||
// having any effect on the parse state.
|
// having any effect on the parse state.
|
||||||
Subtree ts_subtree_new_missing_leaf(SubtreePool *pool, t_symbol symbol,
|
Subtree ts_subtree_new_missing_leaf(SubtreePool *pool, t_symbol symbol,
|
||||||
Length padding, t_u32 lookahead_bytes,
|
t_parse_length padding, t_u32 lookahead_bytes,
|
||||||
const t_language *language)
|
const t_language *language)
|
||||||
{
|
{
|
||||||
Subtree result =
|
Subtree result =
|
||||||
|
|
@ -807,9 +807,9 @@ Subtree ts_subtree_edit(Subtree self, const t_input_edit *inpt_edit,
|
||||||
bool is_pure_insertion = edit.old_end.bytes == edit.start.bytes;
|
bool is_pure_insertion = edit.old_end.bytes == edit.start.bytes;
|
||||||
bool invalidate_first_row = ts_subtree_depends_on_column(*entry.tree);
|
bool invalidate_first_row = ts_subtree_depends_on_column(*entry.tree);
|
||||||
|
|
||||||
Length size = ts_subtree_size(*entry.tree);
|
t_parse_length size = ts_subtree_size(*entry.tree);
|
||||||
Length padding = ts_subtree_padding(*entry.tree);
|
t_parse_length padding = ts_subtree_padding(*entry.tree);
|
||||||
Length total_size = length_add(padding, size);
|
t_parse_length total_size = length_add(padding, size);
|
||||||
t_u32 lookahead_bytes = ts_subtree_lookahead_bytes(*entry.tree);
|
t_u32 lookahead_bytes = ts_subtree_lookahead_bytes(*entry.tree);
|
||||||
t_u32 end_byte = total_size.bytes + lookahead_bytes;
|
t_u32 end_byte = total_size.bytes + lookahead_bytes;
|
||||||
if (edit.start.bytes > end_byte ||
|
if (edit.start.bytes > end_byte ||
|
||||||
|
|
@ -895,12 +895,12 @@ Subtree ts_subtree_edit(Subtree self, const t_input_edit *inpt_edit,
|
||||||
ts_subtree_set_has_changes(&result);
|
ts_subtree_set_has_changes(&result);
|
||||||
*entry.tree = ts_subtree_from_mut(result);
|
*entry.tree = ts_subtree_from_mut(result);
|
||||||
|
|
||||||
Length child_left, child_right = length_zero();
|
t_parse_length child_left, child_right = length_zero();
|
||||||
for (t_u32 i = 0, n = ts_subtree_child_count(*entry.tree); i < n;
|
for (t_u32 i = 0, n = ts_subtree_child_count(*entry.tree); i < n;
|
||||||
i++)
|
i++)
|
||||||
{
|
{
|
||||||
Subtree *child = &ts_subtree_children(*entry.tree)[i];
|
Subtree *child = &ts_subtree_children(*entry.tree)[i];
|
||||||
Length child_size = ts_subtree_total_size(*child);
|
t_parse_length child_size = ts_subtree_total_size(*child);
|
||||||
child_left = child_right;
|
child_left = child_right;
|
||||||
child_right = length_add(child_left, child_size);
|
child_right = length_add(child_left, child_size);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,7 @@
|
||||||
|
|
||||||
#include "./array.h"
|
#include "./array.h"
|
||||||
#include "./error_costs.h"
|
#include "./error_costs.h"
|
||||||
#include "./host.h"
|
#include "parser/parser_length.h"
|
||||||
#include "./length.h"
|
|
||||||
#include "./parser.h"
|
#include "./parser.h"
|
||||||
#include "parser/api.h"
|
#include "parser/api.h"
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
@ -75,8 +74,8 @@ struct s_subtree_inline_data
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
volatile t_u32 ref_count;
|
volatile t_u32 ref_count;
|
||||||
Length padding;
|
t_parse_length padding;
|
||||||
Length size;
|
t_parse_length size;
|
||||||
t_u32 lookahead_bytes;
|
t_u32 lookahead_bytes;
|
||||||
t_u32 error_cost;
|
t_u32 error_cost;
|
||||||
t_u32 child_count;
|
t_u32 child_count;
|
||||||
|
|
@ -159,14 +158,14 @@ void ts_subtree_array_reverse(SubtreeArray *);
|
||||||
SubtreePool ts_subtree_pool_new(t_u32 capacity);
|
SubtreePool ts_subtree_pool_new(t_u32 capacity);
|
||||||
void ts_subtree_pool_delete(SubtreePool *);
|
void ts_subtree_pool_delete(SubtreePool *);
|
||||||
|
|
||||||
Subtree ts_subtree_new_leaf(SubtreePool *, t_symbol, Length, Length, t_u32,
|
Subtree ts_subtree_new_leaf(SubtreePool *, t_symbol, t_parse_length, t_parse_length, t_u32,
|
||||||
t_state_id, bool, bool, bool, const t_language *);
|
t_state_id, bool, bool, bool, const t_language *);
|
||||||
Subtree ts_subtree_new_error(SubtreePool *, t_i32, Length, Length, t_u32,
|
Subtree ts_subtree_new_error(SubtreePool *, t_i32, t_parse_length, t_parse_length, t_u32,
|
||||||
t_state_id, const t_language *);
|
t_state_id, const t_language *);
|
||||||
MutableSubtree ts_subtree_new_node(t_symbol, SubtreeArray *, unsigned,
|
MutableSubtree ts_subtree_new_node(t_symbol, SubtreeArray *, unsigned,
|
||||||
const t_language *);
|
const t_language *);
|
||||||
Subtree ts_subtree_new_error_node(SubtreeArray *, bool, const t_language *);
|
Subtree ts_subtree_new_error_node(SubtreeArray *, bool, const t_language *);
|
||||||
Subtree ts_subtree_new_missing_leaf(SubtreePool *, t_symbol, Length, t_u32,
|
Subtree ts_subtree_new_missing_leaf(SubtreePool *, t_symbol, t_parse_length, t_u32,
|
||||||
const t_language *);
|
const t_language *);
|
||||||
MutableSubtree ts_subtree_make_mut(SubtreePool *, Subtree);
|
MutableSubtree ts_subtree_make_mut(SubtreePool *, Subtree);
|
||||||
void ts_subtree_retain(Subtree);
|
void ts_subtree_retain(Subtree);
|
||||||
|
|
@ -271,11 +270,11 @@ static inline t_state_id ts_subtree_leaf_parse_state(Subtree self)
|
||||||
return self.ptr->first_leaf.parse_state;
|
return self.ptr->first_leaf.parse_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Length ts_subtree_padding(Subtree self)
|
static inline t_parse_length ts_subtree_padding(Subtree self)
|
||||||
{
|
{
|
||||||
if (self.data.is_inline)
|
if (self.data.is_inline)
|
||||||
{
|
{
|
||||||
Length result = {self.data.padding_bytes,
|
t_parse_length result = {self.data.padding_bytes,
|
||||||
{self.data.padding_rows, self.data.padding_columns}};
|
{self.data.padding_rows, self.data.padding_columns}};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -285,11 +284,11 @@ static inline Length ts_subtree_padding(Subtree self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Length ts_subtree_size(Subtree self)
|
static inline t_parse_length ts_subtree_size(Subtree self)
|
||||||
{
|
{
|
||||||
if (self.data.is_inline)
|
if (self.data.is_inline)
|
||||||
{
|
{
|
||||||
Length result = {self.data.size_bytes, {0, self.data.size_bytes}};
|
t_parse_length result = {self.data.size_bytes, {0, self.data.size_bytes}};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -298,7 +297,7 @@ static inline Length ts_subtree_size(Subtree self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Length ts_subtree_total_size(Subtree self)
|
static inline t_parse_length ts_subtree_total_size(Subtree self)
|
||||||
{
|
{
|
||||||
return length_add(ts_subtree_padding(self), ts_subtree_size(self));
|
return length_add(ts_subtree_padding(self), ts_subtree_size(self));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
#include "parser/api.h"
|
#include "parser/api.h"
|
||||||
#include "./array.h"
|
#include "./array.h"
|
||||||
|
|
||||||
#include "./length.h"
|
#include "parser/parser_length.h"
|
||||||
#include "./subtree.h"
|
#include "./subtree.h"
|
||||||
#include "./tree_cursor.h"
|
#include "./tree_cursor.h"
|
||||||
#include "./tree.h"
|
#include "./tree.h"
|
||||||
|
|
@ -46,7 +46,7 @@ t_parse_node ts_tree_root_node_with_offset(
|
||||||
t_u32 offset_bytes,
|
t_u32 offset_bytes,
|
||||||
t_point offset_extent
|
t_point offset_extent
|
||||||
) {
|
) {
|
||||||
Length offset = {offset_bytes, offset_extent};
|
t_parse_length offset = {offset_bytes, offset_extent};
|
||||||
return ts_node_new(self, &self->root, length_add(offset, ts_subtree_padding(self->root)), 0);
|
return ts_node_new(self, &self->root, length_add(offset, ts_subtree_padding(self->root)), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ extern "C" {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const Subtree *child;
|
const Subtree *child;
|
||||||
const Subtree *parent;
|
const Subtree *parent;
|
||||||
Length position;
|
t_parse_length position;
|
||||||
t_symbol alias_symbol;
|
t_symbol alias_symbol;
|
||||||
} ParentCacheEntry;
|
} ParentCacheEntry;
|
||||||
|
|
||||||
|
|
@ -22,7 +22,7 @@ struct t_parse_tree {
|
||||||
};
|
};
|
||||||
|
|
||||||
t_parse_tree *ts_tree_new(Subtree root, const t_language *language, const t_parser_range *, unsigned);
|
t_parse_tree *ts_tree_new(Subtree root, const t_language *language, const t_parser_range *, unsigned);
|
||||||
t_parse_node ts_node_new(const t_parse_tree *, const Subtree *, Length, t_symbol);
|
t_parse_node ts_node_new(const t_parse_tree *, const Subtree *, t_parse_length, t_symbol);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Subtree parent;
|
Subtree parent;
|
||||||
const t_parse_tree *tree;
|
const t_parse_tree *tree;
|
||||||
Length position;
|
t_parse_length position;
|
||||||
t_u32 child_index;
|
t_u32 child_index;
|
||||||
t_u32 structural_child_index;
|
t_u32 structural_child_index;
|
||||||
t_u32 descendant_index;
|
t_u32 descendant_index;
|
||||||
|
|
@ -101,12 +101,12 @@ static inline bool ts_tree_cursor_child_iterator_next(
|
||||||
// can only be computed if `b` has zero rows. Otherwise, this function
|
// can only be computed if `b` has zero rows. Otherwise, this function
|
||||||
// returns `LENGTH_UNDEFINED`, and the caller needs to recompute
|
// returns `LENGTH_UNDEFINED`, and the caller needs to recompute
|
||||||
// the position some other way.
|
// the position some other way.
|
||||||
static inline Length length_backtrack(Length a, Length b) {
|
static inline t_parse_length length_backtrack(t_parse_length a, t_parse_length b) {
|
||||||
if (length_is_undefined(a) || b.extent.row != 0) {
|
if (length_is_undefined(a) || b.extent.row != 0) {
|
||||||
return LENGTH_UNDEFINED;
|
return LENGTH_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Length result;
|
t_parse_length result;
|
||||||
result.bytes = a.bytes - b.bytes;
|
result.bytes = a.bytes - b.bytes;
|
||||||
result.extent.row = a.extent.row;
|
result.extent.row = a.extent.row;
|
||||||
result.extent.column = a.extent.column - b.extent.column;
|
result.extent.column = a.extent.column - b.extent.column;
|
||||||
|
|
@ -141,7 +141,7 @@ static inline bool ts_tree_cursor_child_iterator_previous(
|
||||||
// unsigned can underflow so compare it to child_count
|
// unsigned can underflow so compare it to child_count
|
||||||
if (self->child_index < self->parent.ptr->child_count) {
|
if (self->child_index < self->parent.ptr->child_count) {
|
||||||
Subtree previous_child = ts_subtree_children(self->parent)[self->child_index];
|
Subtree previous_child = ts_subtree_children(self->parent)[self->child_index];
|
||||||
Length size = ts_subtree_size(previous_child);
|
t_parse_length size = ts_subtree_size(previous_child);
|
||||||
self->position = length_backtrack(self->position, size);
|
self->position = length_backtrack(self->position, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -273,7 +273,7 @@ static inline t_i64 ts_tree_cursor_goto_first_child_for_byte_and_point(
|
||||||
TreeCursorEntry entry;
|
TreeCursorEntry entry;
|
||||||
CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);
|
CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);
|
||||||
while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
|
while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
|
||||||
Length entry_end = length_add(entry.position, ts_subtree_size(*entry.subtree));
|
t_parse_length entry_end = length_add(entry.position, ts_subtree_size(*entry.subtree));
|
||||||
bool at_goal = entry_end.bytes >= goal_byte && point_gte(entry_end.extent, goal_point);
|
bool at_goal = entry_end.bytes >= goal_byte && point_gte(entry_end.extent, goal_point);
|
||||||
t_u32 visible_child_count = ts_subtree_visible_child_count(*entry.subtree);
|
t_u32 visible_child_count = ts_subtree_visible_child_count(*entry.subtree);
|
||||||
if (at_goal) {
|
if (at_goal) {
|
||||||
|
|
@ -374,7 +374,7 @@ TreeCursorStep ts_tree_cursor_goto_previous_sibling_internal(t_parse_tree_cursor
|
||||||
|
|
||||||
// restore position from the parent node
|
// restore position from the parent node
|
||||||
const TreeCursorEntry *parent = &self->stack.contents[self->stack.size - 2];
|
const TreeCursorEntry *parent = &self->stack.contents[self->stack.size - 2];
|
||||||
Length position = parent->position;
|
t_parse_length position = parent->position;
|
||||||
t_u32 child_index = array_back(&self->stack)->child_index;
|
t_u32 child_index = array_back(&self->stack)->child_index;
|
||||||
const Subtree *children = ts_subtree_children((*(parent->subtree)));
|
const Subtree *children = ts_subtree_children((*(parent->subtree)));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const Subtree *subtree;
|
const Subtree *subtree;
|
||||||
Length position;
|
t_parse_length position;
|
||||||
t_u32 child_index;
|
t_u32 child_index;
|
||||||
t_u32 structural_child_index;
|
t_u32 structural_child_index;
|
||||||
t_u32 descendant_index;
|
t_u32 descendant_index;
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,10 @@
|
||||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/03/28 14:40:38 by rparodi #+# #+# */
|
/* Created: 2024/03/28 14:40:38 by rparodi #+# #+# */
|
||||||
/* Updated: 2024/04/29 16:06:33 by rparodi ### ########.fr */
|
/* Updated: 2024/04/30 13:02:39 by maiboyer ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
||||||
#include "app/node.h"
|
#include "app/node.h"
|
||||||
#include "me/string/str_len.h"
|
#include "me/string/str_len.h"
|
||||||
#include "parser/api.h"
|
#include "parser/api.h"
|
||||||
|
|
@ -74,50 +73,58 @@ void ft_find_path(t_str arge[], t_utils *utils)
|
||||||
utils->path = ft_split(PATH_FILES, ':');
|
utils->path = ft_split(PATH_FILES, ':');
|
||||||
}
|
}
|
||||||
|
|
||||||
TSLanguage *tree_sitter_bash(void);
|
t_language *tree_sitter_bash(void);
|
||||||
|
|
||||||
t_node parse_to_nodes(TSParser *parser, t_const_str input) {
|
t_node parse_to_nodes(t_parser *parser, t_const_str input)
|
||||||
TSTree *tree;
|
{
|
||||||
TSNode node;
|
t_parse_tree *tree;
|
||||||
t_node ret;
|
t_parse_node node;
|
||||||
|
t_node ret;
|
||||||
|
|
||||||
tree = ts_parser_parse_string(parser, NULL, input, str_len(input));
|
tree = ts_parser_parse_string(parser, NULL, input, str_len(input));
|
||||||
node = ts_tree_root_node(tree);
|
node = ts_tree_root_node(tree);
|
||||||
ret = build_node(node, input);
|
ret = build_node(node, input);
|
||||||
ts_tree_delete(tree);
|
ts_tree_delete(tree);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_node_data(t_node *t, t_usize depth) {
|
void print_node_data(t_node *t, t_usize depth)
|
||||||
t_usize idx;
|
{
|
||||||
|
t_usize idx;
|
||||||
|
|
||||||
idx = 0;
|
idx = 0;
|
||||||
while (idx++ < depth)
|
while (idx++ < depth)
|
||||||
printf("\t");
|
printf("\t");
|
||||||
idx = 0;
|
idx = 0;
|
||||||
printf("%s = %s\n", t->kind_str, node_getstr(t));
|
printf("%s = %s\n", t->kind_str, node_getstr(t));
|
||||||
while (idx < t->childs_count)
|
while (idx < t->childs_count)
|
||||||
print_node_data(&t->childs[idx++], depth + 1);
|
print_node_data(&t->childs[idx++], depth + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct s_myparser {
|
typedef struct s_myparser
|
||||||
TSParser *parser;
|
{
|
||||||
|
t_parser *parser;
|
||||||
} t_myparser;
|
} t_myparser;
|
||||||
|
|
||||||
t_myparser create_myparser(void) {
|
t_myparser create_myparser(void)
|
||||||
TSLanguage *lang;
|
{
|
||||||
TSParser *parser;
|
t_language *lang;
|
||||||
|
t_parser *parser;
|
||||||
|
|
||||||
lang = tree_sitter_bash();
|
lang = tree_sitter_bash();
|
||||||
parser = ts_parser_new();
|
parser = ts_parser_new();
|
||||||
ts_parser_set_language(parser, lang);
|
ts_parser_set_language(parser, lang);
|
||||||
return ((t_myparser){.parser = parser});
|
return ((t_myparser){.parser = parser});
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_myparser(t_myparser self) { ts_parser_delete(self.parser); }
|
void free_myparser(t_myparser self)
|
||||||
|
{
|
||||||
|
ts_parser_delete(self.parser);
|
||||||
|
}
|
||||||
|
|
||||||
t_node parse_string(t_myparser *parser, t_const_str input) {
|
t_node parse_string(t_myparser *parser, t_const_str input)
|
||||||
return (parse_to_nodes(parser->parser, input));
|
{
|
||||||
|
return (parse_to_nodes(parser->parser, input));
|
||||||
}
|
}
|
||||||
|
|
||||||
t_i32 main(t_i32 argc, t_str argv[], t_str arge[])
|
t_i32 main(t_i32 argc, t_str argv[], t_str arge[])
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,13 @@
|
||||||
#include "me/string/str_l_copy.h"
|
#include "me/string/str_l_copy.h"
|
||||||
#include "parser/api.h"
|
#include "parser/api.h"
|
||||||
|
|
||||||
t_node build_node(TSNode curr, t_const_str input);
|
t_node build_node(t_parse_node curr, t_const_str input);
|
||||||
|
|
||||||
t_node *build_childs(TSNode parent, t_const_str input, t_usize count)
|
t_node *build_childs(t_parse_node parent, t_const_str input, t_usize count)
|
||||||
{
|
{
|
||||||
t_node *ret;
|
t_node *ret;
|
||||||
t_usize idx;
|
t_usize idx;
|
||||||
TSNode child;
|
t_parse_node child;
|
||||||
|
|
||||||
ret = mem_alloc_array(sizeof(*ret), count);
|
ret = mem_alloc_array(sizeof(*ret), count);
|
||||||
if (ret == NULL)
|
if (ret == NULL)
|
||||||
|
|
@ -37,7 +37,7 @@ t_node *build_childs(TSNode parent, t_const_str input, t_usize count)
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
t_node build_node(TSNode curr, t_const_str input)
|
t_node build_node(t_parse_node curr, t_const_str input)
|
||||||
{
|
{
|
||||||
t_node out;
|
t_node out;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,5 +53,6 @@ void vec_C__PREFIX___iter(t_vec_C__PREFIX__ *vec,
|
||||||
void vec_C__PREFIX___reverse(t_vec_C__PREFIX__ *vec);
|
void vec_C__PREFIX___reverse(t_vec_C__PREFIX__ *vec);
|
||||||
void vec_C__PREFIX___sort(t_vec_C__PREFIX__ *vec,
|
void vec_C__PREFIX___sort(t_vec_C__PREFIX__ *vec,
|
||||||
t_vec_C__PREFIX___sort_fn is_sorted);
|
t_vec_C__PREFIX___sort_fn is_sorted);
|
||||||
|
t_error vec_C__PREFIX___back(t_vec_C__PREFIX__ *vec, C__TYPENAME__ **out);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -71,3 +71,14 @@ void vec_C__PREFIX___reverse(t_vec_C__PREFIX__ *vec)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t_error vec_C__PREFIX___back(t_vec_C__PREFIX__ *vec, C__TYPENAME__ **out)
|
||||||
|
{
|
||||||
|
C__TYPENAME__ *temporary;
|
||||||
|
|
||||||
|
if (out == NULL)
|
||||||
|
out = &temporary;
|
||||||
|
if (vec->len != 0)
|
||||||
|
return (*out = &vec->buffer[vec->len - 1], true);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/11/16 17:54:28 by maiboyer #+# #+# */
|
/* Created: 2023/11/16 17:54:28 by maiboyer #+# #+# */
|
||||||
/* Updated: 2023/12/31 15:34:29 by maiboyer ### ########.fr */
|
/* Updated: 2024/04/30 14:14:42 by maiboyer ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -25,6 +25,7 @@ bool push_str_buffer(t_buffer_str *buf, t_const_str to_push);
|
||||||
bool push_str_char(t_buffer_str *buf, char to_push);
|
bool push_str_char(t_buffer_str *buf, char to_push);
|
||||||
void str_clear(t_buffer_str *buf);
|
void str_clear(t_buffer_str *buf);
|
||||||
t_buffer_str alloc_new_buffer(t_usize capacity);
|
t_buffer_str alloc_new_buffer(t_usize capacity);
|
||||||
|
t_error str_reserve(t_buffer_str *buf, t_usize size);
|
||||||
|
|
||||||
static inline void str_free(t_buffer_str buf)
|
static inline void str_free(t_buffer_str buf)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -53,5 +53,6 @@ void vec_buf_str_iter(t_vec_buf_str *vec,
|
||||||
void vec_buf_str_reverse(t_vec_buf_str *vec);
|
void vec_buf_str_reverse(t_vec_buf_str *vec);
|
||||||
void vec_buf_str_sort(t_vec_buf_str *vec,
|
void vec_buf_str_sort(t_vec_buf_str *vec,
|
||||||
t_vec_buf_str_sort_fn is_sorted);
|
t_vec_buf_str_sort_fn is_sorted);
|
||||||
|
t_error vec_buf_str_back(t_vec_buf_str *vec, t_buffer_str **out);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -53,5 +53,6 @@ void vec_str_iter(t_vec_str *vec,
|
||||||
void vec_str_reverse(t_vec_str *vec);
|
void vec_str_reverse(t_vec_str *vec);
|
||||||
void vec_str_sort(t_vec_str *vec,
|
void vec_str_sort(t_vec_str *vec,
|
||||||
t_vec_str_sort_fn is_sorted);
|
t_vec_str_sort_fn is_sorted);
|
||||||
|
t_error vec_str_back(t_vec_str *vec, t_str **out);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -53,5 +53,6 @@ void vec_u8_iter(t_vec_u8 *vec,
|
||||||
void vec_u8_reverse(t_vec_u8 *vec);
|
void vec_u8_reverse(t_vec_u8 *vec);
|
||||||
void vec_u8_sort(t_vec_u8 *vec,
|
void vec_u8_sort(t_vec_u8 *vec,
|
||||||
t_vec_u8_sort_fn is_sorted);
|
t_vec_u8_sort_fn is_sorted);
|
||||||
|
t_error vec_u8_back(t_vec_u8 *vec, t_u8 **out);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -71,3 +71,14 @@ void vec_buf_str_reverse(t_vec_buf_str *vec)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t_error vec_buf_str_back(t_vec_buf_str *vec, t_buffer_str **out)
|
||||||
|
{
|
||||||
|
t_buffer_str *temporary;
|
||||||
|
|
||||||
|
if (out == NULL)
|
||||||
|
out = &temporary;
|
||||||
|
if (vec->len != 0)
|
||||||
|
return (*out = &vec->buffer[vec->len - 1], true);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,3 +71,14 @@ void vec_str_reverse(t_vec_str *vec)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t_error vec_str_back(t_vec_str *vec, t_str **out)
|
||||||
|
{
|
||||||
|
t_str *temporary;
|
||||||
|
|
||||||
|
if (out == NULL)
|
||||||
|
out = &temporary;
|
||||||
|
if (vec->len != 0)
|
||||||
|
return (*out = &vec->buffer[vec->len - 1], true);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,3 +71,14 @@ void vec_u8_reverse(t_vec_u8 *vec)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t_error vec_u8_back(t_vec_u8 *vec, t_u8 **out)
|
||||||
|
{
|
||||||
|
t_u8 *temporary;
|
||||||
|
|
||||||
|
if (out == NULL)
|
||||||
|
out = &temporary;
|
||||||
|
if (vec->len != 0)
|
||||||
|
return (*out = &vec->buffer[vec->len - 1], true);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ blx/sprite/get_pixel
|
||||||
blx/sprite/new_image
|
blx/sprite/new_image
|
||||||
blx/sprite/sprite_draw_onto_sprite
|
blx/sprite/sprite_draw_onto_sprite
|
||||||
buffered_str/mod
|
buffered_str/mod
|
||||||
|
buffered_str/push_char
|
||||||
char/isalnum
|
char/isalnum
|
||||||
char/isalpha
|
char/isalpha
|
||||||
char/isascii
|
char/isascii
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/11/16 17:52:12 by maiboyer #+# #+# */
|
/* Created: 2023/11/16 17:52:12 by maiboyer #+# #+# */
|
||||||
/* Updated: 2024/04/28 20:05:41 by maiboyer ### ########.fr */
|
/* Updated: 2024/04/30 14:14:03 by maiboyer ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -19,11 +19,32 @@
|
||||||
#include "me/types.h"
|
#include "me/types.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
bool push_str_buffer(t_buffer_str *buf, t_const_str to_push)
|
t_error str_reserve(t_buffer_str *buf, t_usize size)
|
||||||
{
|
{
|
||||||
t_usize to_push_len;
|
|
||||||
t_str temp_buffer;
|
t_str temp_buffer;
|
||||||
t_usize new_capacity;
|
t_usize new_capacity;
|
||||||
|
|
||||||
|
if (buf == NULL)
|
||||||
|
return (ERROR);
|
||||||
|
while (size > buf->capacity)
|
||||||
|
{
|
||||||
|
new_capacity = (buf->capacity * 3) / 2 + 1;
|
||||||
|
temp_buffer = mem_alloc(new_capacity);
|
||||||
|
if (temp_buffer == NULL)
|
||||||
|
return (true);
|
||||||
|
str_l_copy(temp_buffer, buf->buf, new_capacity);
|
||||||
|
free(buf->buf);
|
||||||
|
buf->buf = temp_buffer;
|
||||||
|
buf->capacity = new_capacity;
|
||||||
|
}
|
||||||
|
return (NO_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool push_str_buffer(t_buffer_str *buf, t_const_str to_push)
|
||||||
|
{
|
||||||
|
t_usize to_push_len;
|
||||||
|
t_str temp_buffer;
|
||||||
|
t_usize new_capacity;
|
||||||
|
|
||||||
if (buf == NULL || to_push == NULL)
|
if (buf == NULL || to_push == NULL)
|
||||||
return (true);
|
return (true);
|
||||||
|
|
@ -44,26 +65,26 @@ bool push_str_buffer(t_buffer_str *buf, t_const_str to_push)
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool push_str_char(t_buffer_str *buf, char to_push)
|
bool push_str_char(t_buffer_str *buf, char to_push)
|
||||||
{
|
{
|
||||||
char push_str[2];
|
char push_str[2];
|
||||||
|
|
||||||
push_str[0] = to_push;
|
push_str[0] = to_push;
|
||||||
push_str[1] = 0;
|
push_str[1] = 0;
|
||||||
return (push_str_buffer(buf, push_str));
|
return (push_str_buffer(buf, push_str));
|
||||||
}
|
}
|
||||||
|
|
||||||
void str_clear(t_buffer_str *buf)
|
void str_clear(t_buffer_str *buf)
|
||||||
{
|
{
|
||||||
mem_set_zero(buf->buf, buf->capacity);
|
mem_set_zero(buf->buf, buf->capacity);
|
||||||
buf->len = 0;
|
buf->len = 0;
|
||||||
return ;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_buffer_str alloc_new_buffer(t_usize capacity)
|
t_buffer_str alloc_new_buffer(t_usize capacity)
|
||||||
{
|
{
|
||||||
t_buffer_str out;
|
t_buffer_str out;
|
||||||
t_str buf;
|
t_str buf;
|
||||||
|
|
||||||
if (capacity == 0)
|
if (capacity == 0)
|
||||||
capacity = 16;
|
capacity = 16;
|
||||||
|
|
|
||||||
13
stdme/src/buffered_str/push_char.c
Normal file
13
stdme/src/buffered_str/push_char.c
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* push_char.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2024/04/30 14:17:47 by maiboyer #+# #+# */
|
||||||
|
/* Updated: 2024/04/30 14:17:47 by maiboyer ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue