├── .gitignore ├── Libft ├── Makefile ├── README.md ├── ctype │ ├── ft_ctype.h │ ├── ft_isalnum.c │ ├── ft_isalpha.c │ ├── ft_isascii.c │ ├── ft_isdigit.c │ ├── ft_islower.c │ ├── ft_isprint.c │ ├── ft_isspace.c │ ├── ft_isupper.c │ ├── ft_tolower.c │ ├── ft_toupper.c │ ├── to_lower.c │ └── to_upper.c ├── libft.h ├── memory │ ├── ft_memory.h │ └── leaks_curr.c ├── stdio │ ├── ft_fprintf.c │ ├── ft_printf.c │ ├── ft_stdio.h │ └── utils.c ├── stdlib │ ├── ft_atoi.c │ ├── ft_calloc.c │ ├── ft_itoa.c │ ├── ft_readline.c │ ├── ft_realloc.c │ └── ft_stdlib.h └── string │ ├── ft_arrlen.c │ ├── ft_charjoin.c │ ├── ft_convert_base.c │ ├── ft_memcmp.c │ ├── ft_memcpy.c │ ├── ft_memmove.c │ ├── ft_memset.c │ ├── ft_split.c │ ├── ft_strchr.c │ ├── ft_strcmp.c │ ├── ft_strcpy.c │ ├── ft_strdup.c │ ├── ft_string.h │ ├── ft_strjoin.c │ ├── ft_strlcat.c │ ├── ft_strlcpy.c │ ├── ft_strlen.c │ ├── ft_strncmp.c │ ├── ft_strncpy.c │ ├── ft_strrchr.c │ ├── ft_strstr.c │ ├── ft_strtrim.c │ └── ft_substr.c ├── Makefile ├── README.md ├── debug.c ├── global.c ├── header.h ├── interpret.c ├── main.c ├── parsing.c ├── test_mini ├── atoi.mini ├── endswith.mini ├── increment.mini ├── indexof.mini ├── is_negative.mini ├── isalpha.mini ├── ischaracter.mini ├── ischaracter2.mini ├── isdigit.mini ├── isdigit2.mini ├── isuppercase.mini ├── iteration.mini ├── itoa.mini ├── memcpy.mini ├── memove.mini ├── print_comb.mini ├── print_comb2.mini ├── putnbrbase.mini ├── range.mini ├── reverse_iteration.mini ├── split.mini ├── startswith.mini ├── strcat.mini ├── strcmp.mini ├── strcmp1.mini ├── strcpy.mini ├── strjoin.mini ├── strjoin2.mini ├── strlen.mini ├── strlen1.mini ├── strmap.mini ├── strncpy.mini ├── strstr.mini ├── strtrim.mini ├── tolower.mini ├── tolower1.mini ├── toupper.mini └── toupper1.mini ├── todo.md └── tokenize.c /.gitignore: -------------------------------------------------------------------------------- 1 | **/*.dSYM 2 | **/a.out 3 | .DS_Store 4 | .vscode/ -------------------------------------------------------------------------------- /Libft/Makefile: -------------------------------------------------------------------------------- 1 | # **************************************************************************** # 2 | # # 3 | # ::: :::::::: # 4 | # Makefile :+: :+: :+: # 5 | # +:+ +:+ +:+ # 6 | # By: mhrima +#+ +:+ +#+ # 7 | # +#+#+#+#+#+ +#+ # 8 | # Created: 2022/12/24 05:24:40 by mhrima #+# #+# # 9 | # Updated: 2023/11/14 13:25:35 by mhrima ### ########.fr # 10 | # # 11 | # **************************************************************************** # 12 | 13 | NAME = libft.a 14 | CC = cc 15 | CFLAGS = #-Wall -Wextra -Werror -fsanitize=address -g3 16 | AR = ar rcs 17 | RM = rm -rf 18 | OBJDIR = objects 19 | 20 | # List of subdirectories 21 | SUBDIRS = ctype stdlib string printf memory stdio 22 | 23 | # Collect source files from subdirectories 24 | SRCS0 = $(foreach dir,$(SUBDIRS),$(wildcard $(dir)/*.c)) 25 | OBJS0 = $(addprefix $(OBJDIR)/,$(notdir $(SRCS0:.c=.o))) 26 | 27 | .PHONY: all clean fclean re 28 | 29 | all: $(NAME) 30 | 31 | $(NAME): $(OBJS0) 32 | $(AR) $(NAME) $(OBJS0) 33 | 34 | $(OBJS0): | $(OBJDIR) 35 | 36 | $(OBJDIR): 37 | mkdir -p $(OBJDIR) 38 | 39 | $(OBJDIR)/%.o: */%.c 40 | $(CC) $(CFLAGS) -c $< -o $@ 41 | 42 | clean: 43 | $(RM) $(OBJDIR) 44 | 45 | fclean: clean 46 | $(RM) $(NAME) 47 | 48 | re: fclean all -------------------------------------------------------------------------------- /Libft/README.md: -------------------------------------------------------------------------------- 1 | # LIBFT 2 | 3 | + based on 42-libft projects, does contains most a of functions I use in my c projects 4 | 5 | + how to use 6 | ```bash 7 | make 8 | ``` 9 | ```bash 10 | cc your_file.c -o exe -L. -l:libft.a 11 | ``` 12 | 13 | -------------------------------------------------------------------------------- /Libft/ctype/ft_ctype.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_ctype.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 08:07:06 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/22 12:21:34 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef FT_CTYPE_H__ 14 | #define FT_CTYPE_H__ 15 | 16 | #include 17 | #include "../libft.h" 18 | 19 | bool ft_isalpha(int c); 20 | bool ft_isdigit(int c); 21 | bool ft_isalnum(int c); 22 | bool ft_isascii(int c); 23 | bool ft_isprint(int c); 24 | bool ft_isspace(int c); 25 | bool ft_islower(int c); 26 | bool ft_isupper(int c); 27 | int to_lower(int c); 28 | int to_upper(int c); 29 | #endif -------------------------------------------------------------------------------- /Libft/ctype/ft_isalnum.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isalnum.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 08:09:28 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 08:29:06 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_ctype.h" 14 | 15 | bool ft_isalnum(int c) 16 | { 17 | return (ft_isalpha(c) || ft_isdigit(c)); 18 | } 19 | -------------------------------------------------------------------------------- /Libft/ctype/ft_isalpha.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isalpha.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 08:09:26 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 08:29:11 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_ctype.h" 14 | 15 | bool ft_isalpha(int c) 16 | { 17 | return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); 18 | } -------------------------------------------------------------------------------- /Libft/ctype/ft_isascii.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isascii.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 08:09:23 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 08:29:13 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_ctype.h" 14 | 15 | bool ft_isascii(int c) 16 | { 17 | return (c >= 0 && c <= 127); 18 | } -------------------------------------------------------------------------------- /Libft/ctype/ft_isdigit.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isdigit.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 08:09:20 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 08:29:16 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_ctype.h" 14 | 15 | bool ft_isdigit(int c) 16 | { 17 | return (c >= '0' && c <= '9'); 18 | } -------------------------------------------------------------------------------- /Libft/ctype/ft_islower.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_islower.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/22 12:15:16 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/22 12:18:40 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_ctype.h" 14 | 15 | bool ft_islower(int c) 16 | { 17 | return (c >= 'a' && c <= 'z'); 18 | } -------------------------------------------------------------------------------- /Libft/ctype/ft_isprint.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isprint.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 08:09:17 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 08:29:18 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_ctype.h" 14 | 15 | bool ft_isprint(int c) 16 | { 17 | return (c > 31 && c < 127); 18 | } 19 | -------------------------------------------------------------------------------- /Libft/ctype/ft_isspace.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isspace.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 08:09:15 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 08:29:20 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_ctype.h" 14 | 15 | bool ft_isspace(int c) 16 | { 17 | return (ft_strchr("\t\n\v\f\r ", c)); 18 | } -------------------------------------------------------------------------------- /Libft/ctype/ft_isupper.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isupper.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/22 12:16:27 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/22 12:19:04 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_ctype.h" 14 | 15 | bool ft_isupper(int c) 16 | { 17 | return (c >= 'A' && c <= 'Z'); 18 | } -------------------------------------------------------------------------------- /Libft/ctype/ft_tolower.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_tolower.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 08:09:12 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 08:29:22 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_ctype.h" 14 | 15 | int ft_tolower(int c) 16 | { 17 | if (c >= 'A' && c <= 'Z') 18 | c += 32; 19 | return (c); 20 | } -------------------------------------------------------------------------------- /Libft/ctype/ft_toupper.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_toupper.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 08:09:09 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 08:29:24 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_ctype.h" 14 | 15 | int ft_toupper(int c) 16 | { 17 | if (c >= 'a' && c <= 'z') 18 | c -= 32; 19 | return (c); 20 | } 21 | -------------------------------------------------------------------------------- /Libft/ctype/to_lower.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* to_lower.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/22 12:20:05 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/22 12:20:34 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_ctype.h" 14 | 15 | int to_lower(int c) { return ft_isupper(c) ? (c + 32) : ft_islower(c) ? (c) : (0); } -------------------------------------------------------------------------------- /Libft/ctype/to_upper.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* to_upper.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/22 12:19:26 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/22 12:20:39 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_ctype.h" 14 | 15 | int to_upper(int c) { return ft_islower(c) ? (c - 32) : ft_isupper(c) ? (c): (0); } -------------------------------------------------------------------------------- /Libft/libft.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* libft.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/10/09 10:45:22 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/26 02:18:18 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef LIBFT_H 14 | #define LIBFT_H 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #define ERROR -1 31 | 32 | #ifndef BUFFER_SIZE 33 | #define BUFFER_SIZE 1 34 | #endif 35 | 36 | #ifndef in 37 | #define in STDIN_FILENO 38 | #endif 39 | #ifndef out 40 | #define out STDOUT_FILENO 41 | #endif 42 | #ifndef err 43 | #define err STDERR_FILENO 44 | #endif 45 | 46 | #ifndef OPEN_MAX 47 | #define OPEN_MAX FOPEN_MAX 48 | #endif 49 | 50 | #include "ctype/ft_ctype.h" 51 | #include "memory/ft_memory.h" 52 | #include "stdlib/ft_stdlib.h" 53 | #include "string/ft_string.h" 54 | #include "stdio/ft_stdio.h" 55 | 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /Libft/memory/ft_memory.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_memory.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 08:16:41 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/26 03:28:41 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef ft_MEMORY_H__ 14 | #define ft_MEMORY_H__ 15 | 16 | #include "../libft.h" 17 | 18 | typedef struct s_mal 19 | { 20 | int pos; 21 | uintptr_t *ptr; 22 | int len; 23 | } t_mal; 24 | 25 | void *my_malloc(size_t size); 26 | void my_free(void *address); 27 | void my_free_all(void); 28 | #endif -------------------------------------------------------------------------------- /Libft/memory/leaks_curr.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* leaks_curr.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 08:17:32 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/26 06:01:15 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_memory.h" 14 | 15 | // first thing to put in mind 16 | // memory leaks means allocating 17 | // space in heap and losing its address 18 | 19 | // static varibale are stored in data segment in memory 20 | // data segment is the last space that get freed in memory when main exit 21 | 22 | // when main is exiting and find that there is a static variable pointing 23 | // on a memory on the heap, its frees it 24 | 25 | t_mal *head(void) 26 | { 27 | static t_mal curr; 28 | 29 | if (curr.ptr == NULL) 30 | { 31 | curr.len = 100; 32 | curr.ptr = malloc(curr.len * sizeof(uintptr_t)); 33 | } 34 | return (&curr); 35 | } 36 | 37 | // in case you freed a pointer before 38 | // I use the same pointer to save the new allocate space 39 | int get_available_pos(void) 40 | { 41 | t_mal *curr; 42 | int pos; 43 | 44 | pos = 0; 45 | curr = head(); 46 | while (pos < curr->pos) 47 | { 48 | if (curr->ptr[pos] == 0) 49 | break ; 50 | pos++; 51 | } 52 | return (pos); 53 | } 54 | 55 | void *my_malloc(size_t size) 56 | { 57 | t_mal *curr; 58 | void *new; 59 | uintptr_t *ptr; 60 | int pos; 61 | 62 | new = malloc(size); 63 | ft_memset(new, 0, size); 64 | pos = get_available_pos(); 65 | curr = head(); 66 | curr->ptr[pos] = (uintptr_t) new; 67 | if (pos == curr->pos) 68 | curr->pos++; 69 | if (curr->pos + 2 >= curr->len) 70 | { 71 | ptr = malloc(curr->len * 2 * sizeof(uintptr_t)); 72 | ft_memcpy(ptr, curr->ptr, curr->len * sizeof(uintptr_t)); 73 | free(curr->ptr); 74 | curr->ptr = ptr; 75 | curr->len *= 2; 76 | } 77 | return (new); 78 | } 79 | 80 | void my_free(void *address) 81 | { 82 | t_mal *curr; 83 | int i; 84 | 85 | curr = head(); 86 | i = 0; 87 | while (i < curr->pos && curr->ptr[i] != (uintptr_t)address) 88 | i++; 89 | if (curr->ptr[i] == (uintptr_t)address) 90 | { 91 | free((void *)curr->ptr[i]); 92 | curr->ptr[i] = 0; 93 | } 94 | } 95 | 96 | void my_free_all(void) 97 | { 98 | t_mal *curr; 99 | int i; 100 | 101 | curr = head(); 102 | i = 0; 103 | while (i < curr->pos) 104 | { 105 | if(curr->ptr[i]) 106 | free((void *)curr->ptr[i]); 107 | curr->ptr[i] = 0; 108 | i++; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /Libft/stdio/ft_fprintf.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_fprintf.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/22 08:43:50 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/22 09:46:47 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_stdio.h" 14 | 15 | void ft_fprintf(int fd, char *conv, ...) 16 | { 17 | int len = ft_strlen(conv); 18 | int i; 19 | 20 | va_list args; 21 | va_start(args, conv); 22 | i = 0; 23 | while (i < len) 24 | { 25 | if (conv[i] == '%') 26 | { 27 | i++; 28 | if (conv[i] == 'c') 29 | ft_putchar(fd, va_arg(args, int)); 30 | if (conv[i] == 's') 31 | ft_putstr(fd, va_arg(args, char *)); 32 | if (conv[i] == 'p') 33 | { 34 | ft_putstr(fd, "0x"); 35 | convertfromDec_P(fd, (unsigned long long)(va_arg(args, void *)), "0123456789abcdef"); 36 | } 37 | if (conv[i] == 'x') 38 | convertfromDec_P(fd, (unsigned long long)va_arg(args, void *), "0123456789abcdef"); 39 | if (conv[i] == 'X') 40 | convertfromDec_P(fd, (unsigned long long)va_arg(args, void *), "0123456789ABCDEF"); 41 | if (conv[i] == 'd' || conv[i] == 'i') 42 | ft_putnbr(fd, (long int)va_arg(args, int)); 43 | if (conv[i] == 'f') 44 | ft_putfloat(1, (double)va_arg(args, int), 10); 45 | if (conv[i] == 'u') 46 | ft_putunsignednbr(fd, va_arg(args, unsigned)); 47 | if (conv[i] == '%') 48 | ft_putchar(fd, '%'); 49 | } 50 | else 51 | ft_putchar(fd, conv[i]); 52 | i++; 53 | } 54 | va_end(args); 55 | if(fd == 2) 56 | exit(-1); 57 | } -------------------------------------------------------------------------------- /Libft/stdio/ft_printf.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_printf.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 08:14:50 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/22 09:46:38 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_stdio.h" 14 | 15 | void ft_printf(char *conv, ...) 16 | { 17 | int len = ft_strlen(conv); 18 | int i; 19 | 20 | va_list args; 21 | va_start(args, conv); 22 | i = 0; 23 | while (i < len) 24 | { 25 | if (conv[i] == '%') 26 | { 27 | i++; 28 | if (conv[i] == 'c') 29 | ft_putchar(1, va_arg(args, int)); 30 | if (conv[i] == 's') 31 | ft_putstr(1, va_arg(args, char *)); 32 | if (conv[i] == 'p') 33 | { 34 | ft_putstr(1, "0x"); 35 | convertfromDec_P(1, (unsigned long long)(va_arg(args, void *)), "0123456789abcdef"); 36 | } 37 | if (conv[i] == 'x') 38 | convertfromDec_P(1, (unsigned long long)va_arg(args, void *), "0123456789abcdef"); 39 | if (conv[i] == 'X') 40 | convertfromDec_P(1, (unsigned long long)va_arg(args, void *), "0123456789ABCDEF"); 41 | if (conv[i] == 'd' || conv[i] == 'i') 42 | ft_putnbr(1, (long int)va_arg(args, int)); 43 | if (conv[i] == 'f') 44 | ft_putfloat(1, (double)va_arg(args, int), 10); 45 | if (conv[i] == 'u') 46 | ft_putunsignednbr(1, va_arg(args, unsigned)); 47 | if (conv[i] == '%') 48 | ft_putchar(1, '%'); 49 | } 50 | else 51 | ft_putchar(1, conv[i]); 52 | i++; 53 | } 54 | va_end(args); 55 | } -------------------------------------------------------------------------------- /Libft/stdio/ft_stdio.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_stdio.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 08:14:27 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/26 00:10:23 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef FT_STDIO_H__ 14 | #define FT_STDIO_H__ 15 | 16 | #include "../libft.h" 17 | #include 18 | void ft_printf(char *conv, ...); 19 | void ft_fprintf(int fd, char *conv, ...); 20 | void ft_putchar(int fd, int c); 21 | void ft_putstr(int fd, char *str); 22 | void ft_putnbr(int fd, long int num); 23 | void ft_putunsignednbr(int fd, unsigned int num); 24 | bool ft_putfloat(int fd, double num, int decimal_places); 25 | void convertfromDec_P(int fd, unsigned long long num, char *to); 26 | void convertfromDec_X(int fd, unsigned int num, char *to); 27 | void print_space(int len); 28 | 29 | #endif -------------------------------------------------------------------------------- /Libft/stdio/utils.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* utils.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/22 08:43:01 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/22 09:20:41 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_stdio.h" 14 | 15 | void ft_putchar(int fd, int c) 16 | { 17 | write(fd, &c, 1); 18 | } 19 | 20 | void ft_putstr(int fd, char *str) 21 | { 22 | if (!str) 23 | return (ft_putstr(fd ,"(null)")); 24 | write(fd, str, ft_strlen(str)); 25 | } 26 | 27 | void ft_putnbr(int fd, long int num) 28 | { 29 | if (num < 0) 30 | { 31 | ft_putchar(fd, '-'); 32 | num = -num; 33 | } 34 | if (num >= 0 && num < 10) 35 | ft_putchar(fd, '0' + num); 36 | if (num >= 10) 37 | { 38 | ft_putnbr(fd, num / 10); 39 | ft_putchar(fd, num % 10 + '0'); 40 | } 41 | } 42 | 43 | void ft_putunsignednbr(int fd, unsigned int num) 44 | { 45 | if (num < 10) 46 | ft_putchar(fd, '0' + num); 47 | if (num >= 10) 48 | { 49 | ft_putunsignednbr(fd, num / 10); 50 | ft_putchar(fd, num % 10 + '0'); 51 | } 52 | } 53 | 54 | void convertfromDec_P(int fd, unsigned long long num, char *to) 55 | { 56 | unsigned long long len = (unsigned long long)ft_strlen(to); 57 | 58 | if (num < len) 59 | ft_putchar(fd, to[num]); 60 | if (num >= len) 61 | { 62 | convertfromDec_P(fd, num / len, to); 63 | ft_putchar(fd, to[num % len]); 64 | } 65 | } 66 | 67 | void convertfromDec_X(int fd, unsigned int num, char *to) 68 | { 69 | unsigned int len = (unsigned)ft_strlen(to); 70 | 71 | if (num < len) 72 | ft_putchar(fd, to[num]); 73 | if (num >= len) 74 | { 75 | convertfromDec_X(fd, num / len, to); 76 | ft_putchar(fd, to[num % len]); 77 | } 78 | } 79 | 80 | bool ft_putfloat(int fd, double num, int decimal_places) 81 | { 82 | bool is_float = true; 83 | if (num < 0.0) 84 | { 85 | ft_putchar(fd, '-'); 86 | num = -num; 87 | } 88 | long int_part = (long)num; 89 | double float_part = num - (double)int_part; 90 | while (decimal_places > 0) 91 | { 92 | float_part *= 10; 93 | decimal_places--; 94 | } 95 | ft_putnbr(fd, int_part); 96 | if (decimal_places) 97 | { 98 | ft_putchar(fd, '.'); 99 | ft_putnbr(fd, (long)round(float_part)); 100 | } 101 | else 102 | is_float = false; 103 | return is_float; 104 | } 105 | 106 | void print_space(int len) 107 | { 108 | int i = 0; 109 | while (i < len) 110 | { 111 | ft_putchar(out, ' '); 112 | i++; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /Libft/stdlib/ft_atoi.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_atoi.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:58:30 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 07:59:44 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_stdlib.h" 14 | 15 | int ft_atoi(char *string) 16 | { 17 | int i; 18 | int sign; 19 | int number; 20 | 21 | i = 0; 22 | sign = 1; 23 | number = 0; 24 | while (ft_isspace(string[i])) 25 | i++; 26 | if(ft_strchr("+-", string[i])) 27 | { 28 | if(string[i] == '-') 29 | sign = -1; 30 | i++; 31 | } 32 | while (ft_isdigit(string[i])) 33 | { 34 | number = number * 10 + sign * (string[i] - '0'); 35 | if (sign == 1 && ft_isdigit(string[i + 1]) && number > LONG_MAX - sign * (string[i + 1] - '0')) 36 | return (-1); 37 | if (sign == -1 && ft_isdigit(string[i + 1]) && number < LONG_MIN - sign * (string[i + 1] - '0')) 38 | return (0); 39 | i++; 40 | } 41 | return (number); 42 | } 43 | -------------------------------------------------------------------------------- /Libft/stdlib/ft_calloc.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_calloc.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:59:20 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/26 03:27:58 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_stdlib.h" 14 | 15 | void *ft_calloc(size_t count, size_t size) 16 | { 17 | #if 0 18 | void *array; 19 | 20 | if (count && size > SIZE_MAX / count) 21 | return (NULL); 22 | array = (void *)malloc(count * size); 23 | if (!array) 24 | { 25 | printf("Error allocation in calloc\n"); 26 | exit(ERROR); 27 | } 28 | ft_memset(array, 0, count * size); 29 | return (array); 30 | #endif 31 | return my_malloc(count * size); 32 | } -------------------------------------------------------------------------------- /Libft/stdlib/ft_itoa.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_itoa.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:59:09 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 07:59:10 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_stdlib.h" 14 | 15 | char *ft_itoa(int number) 16 | { 17 | char *string; 18 | bool is_negative; 19 | size_t i; 20 | char c; 21 | 22 | i = 0; 23 | is_negative = false; 24 | if (number == -2147483648) 25 | return (ft_strdup("-2147483648")); 26 | if(number == 0) 27 | return (ft_strdup("0")); 28 | string = NULL; 29 | if (number < 0) 30 | { 31 | is_negative = true; 32 | number = -number; 33 | } 34 | while(number > 0) 35 | { 36 | string = ft_charjoin(string, number % 10); 37 | number /= 10; 38 | } 39 | if(is_negative) 40 | string = ft_strjoin0(string, ft_strdup("-")); 41 | i = 0; 42 | while(i < ft_strlen(string) / 2) 43 | { 44 | c = string[i]; 45 | string[i] = string[ft_strlen(string) - i - 1]; 46 | string[ft_strlen(string) - i - 1] = c; 47 | i++; 48 | } 49 | return (string); 50 | } -------------------------------------------------------------------------------- /Libft/stdlib/ft_readline.c: -------------------------------------------------------------------------------- 1 | #include "ft_stdlib.h" 2 | 3 | char *ft_readline(int fd) 4 | { 5 | char *res = NULL; 6 | char c = 0; 7 | 8 | while (1) 9 | { 10 | int n = read(fd, &c, sizeof(char)); 11 | if (n <= 0) 12 | break; 13 | if (c == '\n' || c == '\0') 14 | break; 15 | res = ft_charjoin(res, c); 16 | } 17 | return res; 18 | } -------------------------------------------------------------------------------- /Libft/stdlib/ft_realloc.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_realloc.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:59:28 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/26 03:30:25 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_stdlib.h" 14 | 15 | void *ft_realloc(void *pointer, size_t oldsize, size_t newsize) 16 | { 17 | void *new; 18 | 19 | new = ft_calloc(1, newsize); 20 | if (pointer) 21 | { 22 | ft_memcpy(new, pointer, oldsize); 23 | // free(pointer); 24 | } 25 | return (new); 26 | } -------------------------------------------------------------------------------- /Libft/stdlib/ft_stdlib.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_stdlib.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:57:53 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/22 08:32:39 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef FT_STDLIB_H__ 14 | #define FT_STDLIB_H__ 15 | 16 | #include "../libft.h" 17 | 18 | int ft_atoi(char *string); 19 | void *ft_calloc(size_t count, size_t size); 20 | char *ft_itoa(int number); 21 | void *ft_realloc(void *pointer, size_t oldsize, size_t newsize); 22 | char *ft_readline(int fd); 23 | #endif -------------------------------------------------------------------------------- /Libft/string/ft_arrlen.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_arrlen.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:54:26 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 07:56:39 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | int ft_arrlen(char **array) 16 | { 17 | int i; 18 | 19 | i = 0; 20 | while (array && array[i]) 21 | i++; 22 | return (i); 23 | } -------------------------------------------------------------------------------- /Libft/string/ft_charjoin.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_charjoin.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:54:28 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/28 07:00:00 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | char *ft_charjoin(char *string, char c) 16 | { 17 | char *res = ft_calloc(ft_strlen(string) + 2, sizeof(char)); 18 | if(string) 19 | ft_strcpy(res, string); 20 | res[ft_strlen(res)] = c; 21 | return res; 22 | } -------------------------------------------------------------------------------- /Libft/string/ft_convert_base.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_convert_base.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/22 08:27:10 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/22 08:28:45 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | char *convert_base(long long number, char *base) 16 | { 17 | char *converted; 18 | int index = 0; 19 | int size = 64; 20 | 21 | converted = ft_calloc(size + 1, sizeof(char)); 22 | 23 | if (number == 0) 24 | { 25 | converted[index++] = base[0]; 26 | } 27 | int base_length = ft_strlen(base); 28 | while (number != 0) 29 | { 30 | int remainder = number % base_length; 31 | converted[index++] = base[remainder]; 32 | number /= base_length; 33 | if (index >= size) 34 | { 35 | converted = ft_realloc(converted, size, 2 * size * sizeof(char)); 36 | size *= 2; 37 | } 38 | } 39 | int start = 0; 40 | int end = index - 1; 41 | while (start < end) 42 | { 43 | char temp = converted[start]; 44 | converted[start] = converted[end]; 45 | converted[end] = temp; 46 | start++; 47 | end--; 48 | } 49 | return converted; 50 | } -------------------------------------------------------------------------------- /Libft/string/ft_memcmp.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_memcmp.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:54:31 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 07:56:53 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | int ft_memcmp(void *pointer1, void *pointer2, size_t len) 16 | { 17 | size_t i; 18 | unsigned char *string1; 19 | unsigned char *string2; 20 | 21 | string1 = (unsigned char *)pointer1; 22 | string2 = (unsigned char *)pointer2; 23 | if(!string1 && string2) 24 | return string2[0]; 25 | if(!string2 && string1) 26 | return string1[0]; 27 | i = 0; 28 | while (i < len && string1[i] && string1[i] == string2[i]) 29 | i++; 30 | return (string1[i] - string2[i]); 31 | } -------------------------------------------------------------------------------- /Libft/string/ft_memcpy.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_memcpy.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:54:34 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 07:56:56 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | void *ft_memcpy(void *destination, void *source, size_t len) 16 | { 17 | size_t i; 18 | char *pointer1; 19 | char *pointer2; 20 | 21 | if (!destination) 22 | return (source); 23 | if (!source) 24 | return (destination); 25 | pointer1 = (char *)destination; 26 | pointer2 = (char *)source; 27 | i = 0; 28 | while (i < len) 29 | { 30 | pointer1[i] = pointer2[i]; 31 | i++; 32 | } 33 | return (destination); 34 | } -------------------------------------------------------------------------------- /Libft/string/ft_memmove.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_memmove.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:54:37 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 07:56:58 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | void *ft_memmove(void *destination, void *source, size_t len) 16 | { 17 | unsigned char* destptr; 18 | unsigned char* srcptr; 19 | size_t i; 20 | 21 | i = 0; 22 | destptr = (unsigned char *)destination; 23 | srcptr = (unsigned char *)source; 24 | while(i < len) 25 | { 26 | if(destptr < srcptr) 27 | destptr[i] = srcptr[i]; 28 | else 29 | destptr[len - i] = srcptr[len - i]; 30 | i++; 31 | } 32 | return (destination); 33 | } -------------------------------------------------------------------------------- /Libft/string/ft_memset.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_memset.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:54:41 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 07:57:00 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | void *ft_memset(void *pointer, int c, size_t len) 16 | { 17 | size_t i; 18 | unsigned char *destionation; 19 | 20 | destionation = (unsigned char *)pointer; 21 | i = 0; 22 | while (i < len) 23 | { 24 | *destionation = (unsigned char)c; 25 | destionation++; 26 | i++; 27 | } 28 | return (pointer); 29 | } -------------------------------------------------------------------------------- /Libft/string/ft_split.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_split.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:54:44 by mhrima #+# #+# */ 9 | /* Updated: 2023/11/14 13:14:56 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | char **ft_split(char *string, char *spliter) 16 | { 17 | int i; 18 | int j; 19 | char **res; 20 | int start; 21 | 22 | i = 0; 23 | j = 0; 24 | res = NULL; 25 | while (string && string[i]) 26 | { 27 | while (ft_strncmp(string + i, spliter, ft_strlen(spliter)) == 0) 28 | i += ft_strlen(spliter); 29 | start = i; 30 | while (string[i] && ft_strncmp(string + i, spliter, ft_strlen(spliter))) 31 | i++; 32 | if (res == NULL) 33 | res = ft_calloc(j + 2, sizeof(char *)); 34 | else 35 | res = ft_realloc(res, j * sizeof(char *), (j + 2) * sizeof(char *)); 36 | res[j] = ft_calloc(i - start + 2, sizeof(char)); 37 | ft_strncpy(res[j], string + start, i - start); 38 | j++; 39 | res[j] = NULL; 40 | } 41 | return (res); 42 | } -------------------------------------------------------------------------------- /Libft/string/ft_strchr.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strchr.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:54:46 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 07:57:04 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | char *ft_strchr(char *string, int c) 16 | { 17 | int i; 18 | 19 | i = 0; 20 | if (!string) 21 | return (NULL); 22 | while (string[i]) 23 | { 24 | if (string[i] == (char)c) 25 | return (string + i); 26 | i++; 27 | } 28 | if (c == 0 && string[i] == 0) 29 | return (string + i); 30 | return (NULL); 31 | } 32 | -------------------------------------------------------------------------------- /Libft/string/ft_strcmp.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strcmp.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:54:49 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 07:57:06 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | int ft_strcmp(char *string1, char *string2) 16 | { 17 | size_t i; 18 | 19 | i = 0; 20 | if (!string1) 21 | return (ft_strlen(string2)); 22 | if (!string2) 23 | return (ft_strlen(string1)); 24 | while (string1 && string2 && string1[i] && string1[i] == string2[i]) 25 | i++; 26 | return (string1[i] - string2[i]); 27 | } -------------------------------------------------------------------------------- /Libft/string/ft_strcpy.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strcpy.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:54:52 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/28 06:50:43 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | void ft_strcpy(char *destination, char *source) 16 | { 17 | // int len = ft_strlen(destination); 18 | int i = 0; 19 | while (source[i]) 20 | { 21 | destination[i] = source[i]; 22 | i++; 23 | } 24 | } -------------------------------------------------------------------------------- /Libft/string/ft_strdup.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strdup.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:54:55 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 07:57:12 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | char *ft_strdup(char *string) 16 | { 17 | char *pointer; 18 | int i; 19 | 20 | if (!string) 21 | return (NULL); 22 | pointer = ft_calloc((ft_strlen(string) + 1), sizeof(char)); 23 | i = 0; 24 | while (string && string[i]) 25 | { 26 | pointer[i] = string[i]; 27 | i++; 28 | } 29 | return (pointer); 30 | } -------------------------------------------------------------------------------- /Libft/string/ft_string.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_string.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:57:58 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/22 08:29:41 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef FT_STRING_H__ 14 | #define FT_STRING_H__ 15 | 16 | #include "../libft.h" 17 | 18 | int ft_arrlen(char **array); 19 | size_t ft_strlen(char *string); 20 | int ft_memcmp(void *pointer1, void *pointer2, size_t len); 21 | void *ft_memcpy(void *destination, void *source, size_t len); 22 | void *ft_memmove(void *destination, void *source, size_t len); 23 | void *ft_memset(void *pointer, int c, size_t len); 24 | void ft_strcpy(char *destination, char *source); 25 | void ft_strncpy(char *destination, char *source, int size); 26 | char *ft_charjoin(char *string, char c); 27 | char *ft_strchr(char *string, int c); 28 | int ft_strcmp(char *string1, char *string2); 29 | int ft_strncmp(char *string1, char *string2, size_t len); 30 | char *ft_strdup(char *string); 31 | char *ft_strtrim(char *str, char *set); 32 | char *ft_strjoin0(char *string1, char *string2); 33 | char *ft_strjoin1(char *string1, char *string2); 34 | char *ft_strjoin2(char *string1, char *string2, char *string3); 35 | size_t ft_strlcat(char *destination, char *source, size_t size); 36 | size_t ft_strlcpy(char *destination, char *source, size_t size); 37 | char *ft_strrchr(char *string, int c); 38 | char *ft_strstr(char *from, char *to_find); 39 | char *ft_substr(char *string, unsigned int start, size_t len); 40 | char **ft_split(char *string, char *spliter); 41 | char *convert_base(long long number, char *base); 42 | 43 | #endif -------------------------------------------------------------------------------- /Libft/string/ft_strjoin.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strjoin.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:54:57 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/28 06:54:30 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | char *ft_strjoin0(char *string1, char *string2) 16 | { 17 | char *string; 18 | 19 | if (!string1) 20 | return (string2); 21 | if (!string2) 22 | return (string1); 23 | string = ft_calloc((ft_strlen(string1) + ft_strlen(string2) + 1), sizeof(char)); 24 | ft_strcpy(string, string1); 25 | ft_strcpy(string + ft_strlen(string), string2); 26 | // free(string1); 27 | // free(string2); 28 | return (string); 29 | } 30 | 31 | char *ft_strjoin1(char *string1, char *string2) 32 | { 33 | char *string; 34 | 35 | if (!string1) 36 | return (ft_strdup(string2)); 37 | if (!string2) 38 | return (ft_strdup(string1)); 39 | string = ft_calloc((ft_strlen(string1) + ft_strlen(string2) + 1), sizeof(char)); 40 | ft_strcpy(string, string1); 41 | ft_strcpy(string + ft_strlen(string), string2); 42 | return (string); 43 | } 44 | 45 | char *ft_strjoin2(char *string1, char *string2, char *string3) 46 | { 47 | char *string; 48 | 49 | string = ft_calloc(ft_strlen(string1) + ft_strlen(string2) + ft_strlen(string3) + 1, sizeof(char)); 50 | if (string1) 51 | ft_strncpy(string, string1, ft_strlen(string1)); 52 | if (string2) 53 | ft_strncpy(string + ft_strlen(string), string2, ft_strlen(string2)); 54 | if (string3) 55 | ft_strncpy(string + ft_strlen(string), string3, ft_strlen(string3)); 56 | return (string); 57 | } 58 | -------------------------------------------------------------------------------- /Libft/string/ft_strlcat.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strlcat.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:55:00 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 07:57:22 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | size_t ft_strlcat(char *destination, char *source, size_t size) 16 | { 17 | size_t j; 18 | size_t len; 19 | 20 | j = 0; 21 | if (!size || size <= ft_strlen(destination)) 22 | return (ft_strlen(source) + size); 23 | len = ft_strlen(destination); 24 | while (j < size - len - 1 && source[j] != '\0') 25 | { 26 | destination[len + j] = source[j]; 27 | j++; 28 | } 29 | destination[len + j] = '\0'; 30 | return (ft_strlen(source) + len); 31 | } -------------------------------------------------------------------------------- /Libft/string/ft_strlcpy.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strlcpy.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:55:02 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 07:57:25 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | size_t ft_strlcpy(char *destination, char *source, size_t size) 16 | { 17 | unsigned int j; 18 | 19 | j = 0; 20 | if (!size) 21 | return (ft_strlen(source)); 22 | while (j < size - 1 && source[j] != '\0') 23 | { 24 | destination[j] = source[j]; 25 | j++; 26 | } 27 | destination[j] = '\0'; 28 | return (ft_strlen(source)); 29 | } 30 | -------------------------------------------------------------------------------- /Libft/string/ft_strlen.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strlen.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:55:05 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 07:57:28 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | size_t ft_strlen(char *string) 16 | { 17 | size_t i; 18 | 19 | i = 0; 20 | while(string && string[i]) 21 | i++; 22 | return i; 23 | } 24 | -------------------------------------------------------------------------------- /Libft/string/ft_strncmp.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strncmp.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:55:08 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/26 02:03:55 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | int ft_strncmp(char *string1, char *string2, size_t len) 16 | { 17 | size_t i; 18 | 19 | i = 0; 20 | if (!string1) 21 | return (ft_strlen(string2)); 22 | if (!string2) 23 | return (ft_strlen(string1)); 24 | while (i < len && string1 && string2 && string1[i] && string1[i] == string2[i]) 25 | i++; 26 | if(i == len) return 0; 27 | return (string1[i] - string2[i]); 28 | } -------------------------------------------------------------------------------- /Libft/string/ft_strncpy.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strncpy.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:55:10 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 07:57:34 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | void ft_strncpy(char *destination, char *source, int size) 16 | { 17 | int len = ft_strlen(destination); 18 | int i = 0; 19 | while (destination && source && source[i] && i < size) 20 | { 21 | destination[len + i] = source[i]; 22 | i++; 23 | } 24 | } -------------------------------------------------------------------------------- /Libft/string/ft_strrchr.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strrchr.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:55:13 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 07:57:36 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | char *ft_strrchr(char *string, int c) 16 | { 17 | int len; 18 | 19 | len = ft_strlen(string); 20 | string += len; 21 | if (c == 0) 22 | return ((char *)string); 23 | while (len >= 0) 24 | { 25 | if (*string == (char)c) 26 | return ((char *)string); 27 | string--; 28 | len--; 29 | } 30 | return (NULL); 31 | } -------------------------------------------------------------------------------- /Libft/string/ft_strstr.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strstr.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:55:15 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/21 07:57:39 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | char *ft_strstr(char *from, char *to_find) 16 | { 17 | int i; 18 | int k; 19 | int j; 20 | 21 | if (!from || !to_find) 22 | return (NULL); 23 | i = 0; 24 | while (from[i]) 25 | { 26 | k = i; 27 | j = 0; 28 | while (from[k] == to_find[j] && to_find[j] && from[k]) 29 | { 30 | k++; 31 | j++; 32 | } 33 | if (!to_find[j]) 34 | return (from + i); 35 | i++; 36 | } 37 | return (NULL); 38 | } -------------------------------------------------------------------------------- /Libft/string/ft_strtrim.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strtrim.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/22 08:22:20 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/26 06:06:56 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | char *ft_strtrim(char *str, char *set) 16 | { 17 | int i = 0; 18 | int start = 0; 19 | int end = ft_strlen(str); 20 | while(str && str[i]) 21 | { 22 | if(ft_strncmp(str + i, set, ft_strlen(set)) == 0) 23 | { 24 | start = i + ft_strlen(set); 25 | break; 26 | } 27 | i++; 28 | } 29 | i = ft_strlen(str); 30 | if(i) 31 | i -= 1; // protection from segfault 32 | while(i > start && str && str[i]) 33 | { 34 | if(ft_strncmp(str + i, set, ft_strlen(set)) == 0) 35 | { 36 | end = i; 37 | break; 38 | } 39 | i--; 40 | } 41 | char *res = ft_calloc(end - start + 1, sizeof(char)); 42 | ft_strncpy(res , str + start, end - start); 43 | return res; 44 | } 45 | -------------------------------------------------------------------------------- /Libft/string/ft_substr.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_substr.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: mhrima +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/08/21 07:55:18 by mhrima #+# #+# */ 9 | /* Updated: 2023/08/26 05:56:26 by mhrima ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "ft_string.h" 14 | 15 | char *ft_substr(char *string, unsigned int start, size_t len) 16 | { 17 | char *ptr; 18 | char *s1; 19 | unsigned int i; 20 | 21 | if (!string || start >= ft_strlen(string)) 22 | return (NULL); 23 | if (len > ft_strlen(string) - start) 24 | len = ft_strlen(string) - start; 25 | ptr = (char *)ft_calloc(len + 1, sizeof(char)); 26 | if (ptr == NULL) 27 | return (NULL); 28 | i = 0; 29 | s1 = ft_strdup(string); 30 | while (i < len && string[start]) 31 | { 32 | ptr[i] = s1[start]; 33 | start++; 34 | i++; 35 | } 36 | // free(s1); 37 | ptr[i] = '\0'; 38 | return (ptr); 39 | } -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # **************************************************************************** # 2 | # # 3 | # ::: :::::::: # 4 | # Makefile :+: :+: :+: # 5 | # +:+ +:+ +:+ # 6 | # By: mhrima +#+ +:+ +#+ # 7 | # +#+#+#+#+#+ +#+ # 8 | # Created: 2022/12/24 05:24:40 by mhrima #+# #+# # 9 | # Updated: 2023/11/14 13:25:25 by mhrima ### ########.fr # 10 | # # 11 | # **************************************************************************** # 12 | 13 | CC = cc 14 | CFLAGS = #-fsanitize=address -g3 #-Wall -Wextra -Werror 15 | RM = rm -rf 16 | OBJDIR = objects 17 | LIB = Libft/libft.a 18 | EXEC = mini 19 | 20 | SRCS = main.c global.c debug.c tokenize.c parsing.c interpret.c 21 | OBJS = $(addprefix $(OBJDIR)/,$(notdir $(SRCS:.c=.o))) 22 | 23 | .PHONY: all lib clean fclean re 24 | 25 | all: lib $(EXEC) 26 | 27 | lib: 28 | @if [ ! -f $(LIB) ]; then \ 29 | make -C Libft; \ 30 | fi 31 | 32 | $(OBJS): $(SRCS) header.h 33 | $(EXEC): $(OBJS) 34 | $(CC) $(CFLAGS) $(OBJS) $(LIB) -lm -o $(EXEC) 35 | 36 | $(OBJDIR): 37 | mkdir -p $(OBJDIR) 38 | 39 | $(OBJDIR)/%.o: %.c | $(OBJDIR) 40 | $(CC) $(CFLAGS) -c $< -o $@ 41 | 42 | clean: 43 | $(RM) $(OBJDIR) 44 | make -C Libft clean 45 | 46 | fclean: clean 47 | $(RM) $(EXEC) 48 | make -C Libft fclean 49 | 50 | re: fclean all 51 | make re -C Libft 52 | 53 | #cc -c main.c -o objects/main.o 54 | #cc objects/main.o -L./Libft -l:libft.a -lm -o exe -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | - I tried to build a mini programming language that has syntax similar to python with C 2 | - And redo some exercices from 42pool and Libft project with it 3 | - I've also borrow some attributes from javascript X'D 4 | - You can check the tutorial for more details 5 | - This project was made for fun 6 | - The folder /test_mini contains lot of examples, feel free to check it 7 | 8 | ## How to use 9 | 10 | - installation 11 | + clone the repo cd to it 12 | ```bash 13 | make 14 | ``` 15 | - then run command 16 | ```bash 17 | ./mini path_to_your_file.mini # create a file with .mini as extention 18 | ``` 19 | 20 | ## Introduction 21 | #### 1- hello world 22 | - first hello word: 23 | ```python 24 | output("hello world") 25 | ``` 26 | 27 | - comments: 28 | ```c 29 | // this is line of comment 30 | ``` 31 | 32 | ```python 33 | """ 34 | this is 35 | bloc of 36 | comments X'D 37 | """ 38 | ``` 39 | 40 | #### 2- data types: 41 | - variable declaration and data types: 42 | - number: 43 | ```python 44 | num = 123 45 | output("num is ", num, "\n") 46 | ``` 47 | - characters (one character or string): 48 | ```python 49 | str = "hello world" 50 | output("str is ", str, "\n") 51 | ``` 52 | - array: 53 | ```python 54 | array = [1, 2, 3, 4, 5] 55 | output("array has value: ", array, "\n") 56 | ``` 57 | - object: 58 | ```python 59 | obj = { 60 | stname: "mohammed", 61 | ndname:"hrima", 62 | age:25 63 | } 64 | 65 | output("obj is ", obj, "\n") 66 | 67 | // in case you want to access one of object attributes 68 | output("obj has stname ", obj.stname, " and ndname ", obj.ndname, " and age ", obj.age, "\n") 69 | ``` 70 | ps: you can split data types with comma ',' in ouput function like print does in python 71 | 72 | - boolean: 73 | ```python 74 | boolean = true 75 | output("this is boolean with value ", boolean, "\n") 76 | boolean = false 77 | output("this is boolean with value ", boolean, "\n") 78 | ``` 79 | 80 | 81 | - Wait there is something else you may need to check 82 | - All data types has an attribute "type" that return data type name as string 83 | ```python 84 | output("str has type ", str.type, "\n") 85 | output("num has type ", num.type, "\n") 86 | output("obj has type ", obj.type, "\n") 87 | output("array has type ", array.type, "\n") 88 | output("boolean has type ", boolean.type, "\n") 89 | ``` 90 | 91 | #### 3- take input: 92 | - example: 93 | ```python 94 | stname = input("Enter first name: ") 95 | ndname = input("Enter second name: ") 96 | ``` 97 | - to output the current input: \ 98 | method 1 : 99 | ```python 100 | output("Your full name is ", stname, " ", ndname, "\n") 101 | ``` 102 | method 2: 103 | ```python 104 | fullname = stname + " " + ndname // you can use + operator to concatinate two strings 105 | 106 | output("Your full name is ", fullname, "\n") 107 | 108 | // here is another aproach 109 | output("Your full name is " + fullname + "\n") 110 | ``` 111 | 112 | - input does read input as string and assign it to left variable, in case you want to read a number,\ 113 | you can use tonum attribute, and here is what to do it 114 | 115 | ```python 116 | num = input("Enter your birthyear > ").tonum 117 | output("Your age is: ", 2023 - num, "\n") 118 | 119 | // here is anotehr aproach 120 | num1 = input("Enter your birthyear > ") 121 | output("Your age is: ", 2023 - num1.tonum, "\n") 122 | ``` 123 | 124 | ## Iterations and attributes 125 | #### 1- characters: 126 | - Iteration: 127 | ```python 128 | str = "this is a string" 129 | output("str[0] is ", str[0], "\n") 130 | ``` 131 | - concatination: 132 | ```python 133 | str1 = "hello " 134 | str2 = "world" 135 | output("str1 + str2 is ", str1 + str2) 136 | ```` 137 | - indexof: 138 | ```python 139 | str = "abcdefghijklmno" 140 | output("index of de in str ", str.indexof("de"), "\n") 141 | output("index of fe in str ", str.indexof("fe"), "\n") // return -1 if doesn't exist 142 | ``` 143 | - count: 144 | ```python 145 | str = "abcdefgahijaklmno" 146 | output("there is ",str.count("a")," a in str", "\n") 147 | output("there is ",str.count("z")," z in str", "\n") 148 | ``` 149 | - split: 150 | ```python 151 | str = "abcdefgahijaklmno" 152 | array = str.split("a") 153 | output("array is: ", array, "\n") 154 | ```` 155 | - trim: 156 | ```python 157 | str = "abcdefgahijaklmnoabc" 158 | output("trim str by 'abc' ", str ,"\n") 159 | output("str after triming ", str.trim("abc") ,"\n") 160 | ``` 161 | - startswith: (return boolean value) 162 | ```python 163 | str = "abcdefgahijaklmnoabc" 164 | output(str.startswith("abc") ,"\n") 165 | output(str.startswith("abce") ,"\n") 166 | ``` 167 | - endswith: (return boolean value) 168 | ```python 169 | str = "abcdefgahijaklmno" 170 | output(str.endswith("mno") ,"\n") 171 | output(str.endswith("mnop") ,"\n") 172 | ``` 173 | - toupper: 174 | ```python 175 | str = "abcdefg" 176 | output("to upper: ", str.toup, "\n") 177 | ``` 178 | - tolower: 179 | ```python 180 | str = "RSTUVWX" 181 | output("to low: ", str.tolow, "\n\n") 182 | ``` 183 | - tonumber: 184 | ```python 185 | str = "123" 186 | output(str.tonum, "\n\n") 187 | ``` 188 | - isupper: 189 | ```python 190 | str = "ABC" 191 | output(str.isup, "\n\n") 192 | ``` 193 | - islower: 194 | ```python 195 | str = "abc" 196 | output(str.islow, "\n\n") 197 | ``` 198 | - ischaracter: 199 | ```python 200 | str = "abc" 201 | output(str.ischar, "\n\n") 202 | ``` 203 | - isnum: 204 | ```python 205 | str = "123" 206 | output(str.isnum, "\n\n") 207 | ``` 208 | - len: 209 | ```python 210 | str = "abcdefgi" 211 | output(str.len, "\n\n") 212 | ``` 213 | - type: 214 | ```python 215 | str = "abcd" 216 | output(str.type, "\n\n") 217 | ``` 218 | 219 | #### 2- number: 220 | - base: 221 | ```python 222 | n = 10 223 | output("n in base 10 is: ", n.base("0123456789"), "\n") 224 | output("n in base 16 is: ", n.base("0123456789ABCDEF"), "\n") 225 | output("n in base 2 is: ", n.base("01"), "\n") 226 | ``` 227 | - tocharacter: 228 | ```python 229 | output("n to characters ", n.tochar,"\n") 230 | ``` 231 | - type: 232 | ```python 233 | output(n.type, "\n") 234 | ``` 235 | #### 3- array: 236 | - iteration: 237 | ```python 238 | array = ["h", "e", "l", "l", "o", "\n"] 239 | output("array[0] is ", array[0], "\n") 240 | ```` 241 | - concatination: 242 | ```python 243 | array1 = [1,2,3] 244 | array2 = [4,5,6] 245 | array3 = array1 + array2 246 | output("array1 + array2 is ", array3) 247 | ``` 248 | - indexof: 249 | ```python 250 | array = [11,22,33] 251 | output("index of 22 in array ", array.indexof(22), "\n") 252 | ``` 253 | - count: 254 | ```python 255 | array = [11,22,33, 44, 55, 11, 22, 33, 11] 256 | output("there is ",array.count(11)," 11 in array", "\n") 257 | ``` 258 | - len: 259 | ```python 260 | array = [11,22,33, 44, 55, 11, 22, 33, 11] 261 | output(array.len, "\n") 262 | ``` 263 | - type: 264 | ```python 265 | array = [11,22,33, 44, 55, 11, 22, 33, 11] 266 | output(array.type, "\n") 267 | ``` 268 | 269 | #### 4- boolean: 270 | - type: 271 | ```python 272 | value = true 273 | value = false 274 | output(value.type, "\n") 275 | ``` 276 | 277 | #### 5- object: 278 | - you can access object values by there keys: 279 | ```python 280 | obj = { 281 | name: "mohammed", 282 | age: 25 283 | } 284 | output(obj, "\n") 285 | output("obj has name: ", obj.name, " and age ", obj.age,"\n") 286 | output("obj name has len ", obj.name.len,"\n") 287 | ``` 288 | 289 | ## Logic operator 290 | #### 1- equality: 291 | - to check if two strings are the stname 292 | ```python 293 | str1 = "abcdef" 294 | str2 = "abcdef" 295 | ``` 296 | - method 1: 297 | ```python 298 | res = str1 == str2 299 | output("1st method: check if str1 is same as str2: ", res, "\n") 300 | ``` 301 | - method 2: 302 | ```python 303 | res = str1 is str2 304 | output("2nd method: check if str1 is same as str2: ", res, "\n") 305 | ``` 306 | ```python 307 | x = 1 308 | y = 12 309 | output("check if x is equal to y: ", x == y, "\n") 310 | ``` 311 | #### 2- comparision: 312 | - examples: 313 | ```python 314 | res = 6 < 66 315 | output("check if 6 is less than 66: ", res, "\n") 316 | ``` 317 | ```python 318 | x = 1 319 | y = 12 320 | output("check if x is equal to y: ", x < y, "\n") 321 | ``` 322 | #### 3- and or: 323 | - examples: 324 | - and: 325 | ```python 326 | res = 0 < 1 and 1 < 2 327 | output("test 'and': ", res, "\n") 328 | ``` 329 | ```python 330 | res = 10 < 1 && 1 < 2 331 | output("test '&&': ", res, "\n") 332 | ``` 333 | - or: 334 | ```python 335 | res = 10 < 1 or 1 < 2 336 | output("test 'or': ", res, "\n") 337 | ``` 338 | ```python 339 | res = 10 < 1 || 1 < 2 340 | output("test '||': ", res, "\n") 341 | ``` 342 | 343 | ## Loops and statements: 344 | #### 1- if statament: 345 | - examples: 346 | ```python 347 | x = 10 348 | if x % 2 == 0: 349 | output("is odd\n") 350 | else: 351 | output("is even\n") 352 | ``` 353 | ```python 354 | y = -10 355 | if y == 0: 356 | output("is zero\n") 357 | elif y > 0: 358 | output("is more than zero\n") 359 | else: 360 | output("is less than zero\n") 361 | ``` 362 | #### 2- while loop: 363 | - examples: 364 | ```python 365 | x = 0 366 | while x < 10: 367 | output("increment x: ", x ,"\n") 368 | x += 1 369 | ``` 370 | ```python 371 | y = 10 372 | while y > 0: 373 | output("decrement y: ", y, "\n") 374 | y -= 1 375 | ``` 376 | #### 3- for loop: 377 | - examples: 378 | ```python 379 | array = [11,22,33,44,55] 380 | for x in range(0, array.len): 381 | output("array[",x, "] is ", array[x], "\n") 382 | ``` 383 | - range function: return array of number 384 | ```python 385 | range(0, 10) // return [0,1,2,3,4,6,7,8,9] 386 | range(10, 0) // return [10,9,8,7,6,5,4,3,2,1] 387 | ``` 388 | - you can use 'in' keyword to iterate over array: 389 | ```python 390 | array = [11,22,33,44,55] 391 | for x in range(0, array.len): 392 | output("array[",x, "] is ", array[x], "\n") 393 | ``` 394 | - to iterate over string with for loop 395 | ```python 396 | str = "abcdefghijklmnop" 397 | for z in range(str.len - 1, 0): 398 | output("str[",z,"] is ", str[z], "\n") 399 | ``` 400 | 401 | ## Functions: 402 | - examples: 403 | ```python 404 | func sayHi(str): 405 | output("hello ",str, "\n") 406 | 407 | sayHi("Kidoo") 408 | ``` 409 | - return keyword: 410 | ```python 411 | func add(x,y): 412 | return x + y 413 | 414 | output("2 + 5 is ", add(2, 5), "\n") 415 | ``` 416 | -------------------------------------------------------------------------------- /debug.c: -------------------------------------------------------------------------------- 1 | #include "header.h" 2 | 3 | char *type_to_string(Type type) 4 | { 5 | struct 6 | { 7 | char *string; 8 | Type type; 9 | } Types[] = { 10 | // data types 11 | {"IDENTIFIER", identifier_}, 12 | {"CHARACTERS", characters_}, 13 | {"BOOLEAN", boolean_}, 14 | {"NUMBER", number_}, 15 | {"ARRAY", array_}, 16 | {"OBJ", obj_}, 17 | {"VOID", void_}, 18 | {"TUPLE", tuple_}, 19 | // assigns 20 | {"ASSIGNEMENT", assign_}, 21 | {"ADD ASSIGN", add_assign_}, 22 | {"SUB ASSIGN", sub_assign_}, 23 | {"MUL ASSIGN", mul_assign_}, 24 | {"DIV ASSIGN", div_assign_}, 25 | {"MOD ASSIGN", mod_assign_}, 26 | // statements 27 | {"WHILE", while_}, 28 | {"IF", if_}, 29 | {"ELIF", elif_}, 30 | {"ELSE", else_}, 31 | {"FOR", for_}, 32 | {"IN", in_}, 33 | // end statements 34 | {"DOTS", dots_}, 35 | {"COMMA", comma_}, 36 | // parents, brackets 37 | {"LEFT PARENT", lparent_}, 38 | {"RIGHT PARENT", rparent_}, 39 | {"LEFT BRACKET", lbracket_}, 40 | {"RIGHT BRACKET", rbracket_}, 41 | {"LEFT CURLY BRACKET", lcbracket_}, 42 | {"RIGHT CURLY BRACKET", rcbracket_}, 43 | // built in functions 44 | {"INPUT", input_}, 45 | {"OUTPUT", output_}, 46 | {"RANGE", range_}, 47 | // math operators 48 | {"ADDITION", add_}, 49 | {"SUBSTRACTION", sub_}, 50 | {"MULTIPLACTION", mul_}, 51 | {"DIVISION", div_}, 52 | {"MODULO", mod_}, 53 | {"MORE THAN", more_than_}, 54 | {"LESS THAN", less_than_}, 55 | {"MORE THAN OR EQUAL", more_than_or_equal_}, 56 | {"LESS THAN OR EQUAL", less_than_or_equal_}, 57 | // logic operators 58 | {"AND", and_}, 59 | {"OR", or_}, 60 | {"NOT", not_}, 61 | {"COMPARE", equal_}, 62 | {"NOT EQUAL", not_equal_}, 63 | // functions 64 | {"FUNCTION DECLARATION", func_dec_}, 65 | {"FUNCTION CALL", func_call_}, 66 | // key words 67 | {"BREAK", break_}, 68 | {"CONTINUE", continue_}, 69 | {"RETURN", return_}, 70 | // attributes 71 | {"DOT", dot_}, 72 | {"ATTRIBUTE NODE", attribute_}, 73 | {"ATTRIBUTE TYPE", att_type_}, 74 | // built in attributes 75 | {"indexof", indexof_}, 76 | {"split", split_}, 77 | {"trim", trim_}, 78 | {"count", count_}, 79 | {"base", base_}, 80 | {"starts with", starts_with_}, 81 | {"ends with", ends_with_}, 82 | // EOF 83 | {"EOF", eof_}, 84 | {0, 0}, 85 | }; 86 | for (int i = 0; Types[i].string; i++) 87 | { 88 | if (Types[i].type == type) 89 | return (Types[i].string); 90 | } 91 | ft_putstr(err, "Error: type not found '"); 92 | ft_putnbr(err, type); 93 | ft_putstr(err, "'\n"); 94 | my_free_all(); 95 | exit(1); 96 | return NULL; 97 | } 98 | 99 | void undeclared_error(char *location, Token *token, char *type) 100 | { 101 | ft_putchar(out, '\n'); 102 | txt_pos = token->txt_pos; 103 | while (txt_pos > 0 && text[txt_pos - 1] != '\n') 104 | txt_pos--; 105 | while (text[txt_pos] && text[txt_pos] != '\n') 106 | { 107 | ft_putchar(out, text[txt_pos]); 108 | txt_pos++; 109 | } 110 | ft_putchar(out, '\n'); 111 | print_space(token->column - ft_strlen(token->name)); 112 | ft_putstr(out, "^\n"); 113 | ft_fprintf(err, "Error %s: Undeclared %s in line '%d'\n", location, type, token->line); 114 | } 115 | 116 | int numberOfDigits(long long n) 117 | { 118 | int count = 0; 119 | while (n != 0) 120 | { 121 | count++; 122 | n /= 10; 123 | } 124 | return count; 125 | } 126 | 127 | void printFixedPoint(long number, int exponent) 128 | { 129 | long int_part = exponent ? number / pow_ten(exponent) : number; 130 | long frac_part = exponent ? number % pow_ten(exponent) : 0; 131 | ft_putnbr(out, int_part); 132 | if (exponent) 133 | { 134 | for (int i = 0; i < exponent - numberOfDigits(frac_part); i++) 135 | ft_putchar(out, '0'); 136 | ft_putnbr(out, frac_part); 137 | } 138 | } 139 | 140 | // built in functions 141 | void output(Token *token) 142 | { 143 | int fd = 0; 144 | ft_putstr(fd, "\033[31m"); 145 | if (token) 146 | { 147 | switch (token->type) 148 | { 149 | case identifier_: 150 | #if DEBUG 151 | ft_printf("identifier: has name %s\n", token->name); 152 | #else 153 | undeclared_error("output", token, "variable"); 154 | #endif 155 | break; 156 | case characters_: 157 | { 158 | char *string = token->characters; 159 | if (token->is_char) 160 | ft_putchar(fd, string[0]); 161 | else 162 | { 163 | int i = 0; 164 | while (string[i]) 165 | { 166 | for (int j = 0; special_characters[j].special; j++) 167 | { 168 | if (ft_strncmp(&string[i], special_characters[j].special, ft_strlen(special_characters[j].special)) == 0) 169 | { 170 | ft_putchar(fd, special_characters[j].replace); 171 | i += ft_strlen(special_characters[j].special); 172 | break; 173 | } 174 | else 175 | { 176 | ft_putchar(fd, string[i]); 177 | i++; 178 | break; 179 | } 180 | } 181 | if (string[i] == '\0') 182 | break; 183 | } 184 | } 185 | break; 186 | } 187 | case number_: 188 | { 189 | // token->is_float = ft_putfloat(fd, token->number, 6); 190 | // ft_printf("hey fix printing float\n"); 191 | printFixedPoint(token->number, token->exponent); 192 | break; 193 | } 194 | case boolean_: 195 | { 196 | if (token->boolean) 197 | ft_putstr(fd, "true"); 198 | else 199 | ft_putstr(fd, "false"); 200 | break; 201 | } 202 | case array_: 203 | { 204 | ft_putstr(fd, "[ "); 205 | for (int i = 0; token->array && token->array[i]; i++) 206 | { 207 | output(token->array[i]); 208 | if (token->array[i + 1]) 209 | ft_putstr(fd, "\033[31m, "); 210 | } 211 | ft_putstr(fd, " \033[31m]"); 212 | break; 213 | } 214 | case obj_: 215 | { 216 | ft_putstr(fd, " { "); 217 | for (int i = 0; token->object && token->object[i]; i++) 218 | { 219 | ft_putstr(fd, token->keys[i]); 220 | ft_putstr(fd, ": "); 221 | output(token->object[i]); 222 | if (token->object[i + 1]) 223 | ft_putstr(fd, "\033[31m,"); 224 | } 225 | ft_putstr(fd, " \033[31m}"); 226 | break; 227 | } 228 | case void_: 229 | { 230 | ft_putstr(fd, "(void)\n"); 231 | break; 232 | } 233 | case func_dec_: 234 | { 235 | ft_fprintf(out, "function declaration has name: %s\n", token->name); 236 | break; 237 | } 238 | default: 239 | { 240 | ft_putstr(err, "Error in output can't output "); 241 | ft_putstr(err, type_to_string(token->type)); 242 | ft_putstr(err, "\n"); 243 | my_free_all(); 244 | exit(1); 245 | } 246 | } 247 | } 248 | else 249 | ft_putstr(fd, "NULL"); 250 | ft_putstr(fd, "\033[0m"); 251 | } 252 | 253 | void see_token(Token *token) 254 | { 255 | #if DEBUG 256 | if (token) 257 | { 258 | ft_printf("%s in line [", type_to_string(token->type)); 259 | if (token->line < 10) 260 | ft_putstr(out, "00"); 261 | else if (token->line < 100) 262 | ft_putstr(out, "0"); 263 | ft_printf("%d] in column [", token->line); 264 | if (token->column < 10) 265 | ft_putstr(out, "0"); 266 | ft_printf("%d]", token->column); 267 | 268 | ft_printf(" in tab ["); 269 | if (token->tab < 10) 270 | ft_putstr(out, "0"); 271 | ft_printf("%d]", token->tab); 272 | 273 | if (token->name) 274 | ft_printf(" name: %s, ", token->name); 275 | switch (token->type) 276 | { 277 | case characters_: 278 | { 279 | ft_putstr(out, " value: "); 280 | output(token); 281 | break; 282 | } 283 | case number_: 284 | { 285 | ft_putstr(out, " value: "); 286 | output(token); 287 | break; 288 | } 289 | case boolean_: 290 | { 291 | ft_putstr(out, " value: "); 292 | output(token); 293 | break; 294 | } 295 | case array_: 296 | { 297 | ft_putstr(out, " value: \n"); 298 | ft_putstr(out, " "); 299 | output(token); 300 | break; 301 | } 302 | case obj_: 303 | { 304 | ft_putstr(out, " value: \n"); 305 | for (int i = 0; token->object && token->object[i]; i++) 306 | { 307 | ft_printf(" %s : ", token->keys[i]); 308 | output(token->object[i]); 309 | ft_putchar(out, '\n'); 310 | } 311 | ft_putstr(out, " "); 312 | break; 313 | } 314 | case void_: 315 | { 316 | ft_putstr(out, " (void)\n"); 317 | break; 318 | } 319 | default: 320 | { 321 | if (type_to_string(token->type) == NULL) 322 | { 323 | ft_putstr(err, "Unkown token type: "); 324 | ft_putstr(err, type_to_string(token->type)); 325 | my_free_all(); 326 | exit(1); 327 | } 328 | } 329 | } 330 | } 331 | else 332 | ft_putstr(out, "(null token)"); 333 | ft_putchar(out, '\n'); 334 | #endif 335 | } 336 | 337 | void visualize_variables(void) 338 | { 339 | #if DEBUG 340 | int i = 0; 341 | ft_fprintf(out, "\n\nvariables: \n"); 342 | List *tmp = current; 343 | while (tmp->prev) 344 | tmp = tmp->prev; 345 | // var_level is changeable don't think about putting it here 346 | while (tmp) 347 | { 348 | ft_fprintf(out, " level %d, has %d variables:\n", i, tmp->val_index); 349 | int j = 0; 350 | while (j < tmp->val_index) 351 | { 352 | ft_putstr(out, " "); 353 | output(tmp->variables[j]); 354 | ft_putchar(out, '\n'); 355 | j++; 356 | } 357 | tmp = tmp->next; 358 | i++; 359 | } 360 | if (FUNCTIONS[0]) 361 | { 362 | ft_fprintf(out, "\nfunctions: \n"); 363 | i = 0; 364 | while (FUNCTIONS[i]) 365 | { 366 | ft_putstr(out, " "); 367 | output(FUNCTIONS[i]->token); 368 | ft_putchar(out, '\n'); 369 | i++; 370 | } 371 | } 372 | ft_fprintf(out, "\n"); 373 | #endif 374 | } 375 | -------------------------------------------------------------------------------- /global.c: -------------------------------------------------------------------------------- 1 | #include "header.h" 2 | 3 | // alpha tokens, will be gotten as identifiers 4 | // then I compare them to the values here to check if it's one of them to change its type 5 | // else it will be stored as identifier 6 | Typed_token *alpha_tokens = (Typed_token[]){ 7 | // data types 8 | {"true", boolean_}, 9 | {"false", boolean_}, 10 | {"void", void_}, 11 | // statements 12 | {"if", if_}, 13 | {"elif", elif_}, 14 | {"else", else_}, 15 | {"while", while_}, 16 | {"for", for_}, 17 | {"in", in_}, 18 | // built in functions 19 | {"output", output_}, 20 | {"input", input_}, 21 | {"range", range_}, 22 | // logic operators 23 | {"and", and_}, 24 | {"or", or_}, 25 | {"not", not_}, 26 | {"is", equal_}, 27 | {"isnot", not_equal_}, 28 | // key words 29 | {"break", break_}, 30 | {"continue", continue_}, 31 | {"return", return_}, 32 | // functions 33 | {"func", func_dec_}, 34 | // func attributes 35 | {"indexof", indexof_}, 36 | {"count", count_}, 37 | {"split", split_}, 38 | {"trim", trim_}, 39 | {"base", base_}, 40 | {"startswith", starts_with_}, 41 | {"endswith", ends_with_}, 42 | {0, 0}, 43 | }; 44 | 45 | Typed_token *operators_tokens = (Typed_token[]){ 46 | // logic operators 47 | {"&&", and_}, 48 | {"||", or_}, 49 | {"==", equal_}, 50 | {"!=", not_equal_}, 51 | {"!", not_}, 52 | // assignements 53 | {"+=", add_assign_}, 54 | {"-=", sub_assign_}, 55 | {"*=", mul_assign_}, 56 | {"/=", div_assign_}, 57 | // math operators 58 | {"<=", less_than_or_equal_}, 59 | {">=", more_than_or_equal_}, 60 | {"<", less_than_}, 61 | {">", more_than_}, 62 | {"=", assign_}, 63 | // parents, brackets 64 | {"(", lparent_}, 65 | {")", rparent_}, 66 | {"[", lbracket_}, 67 | {"]", rbracket_}, 68 | {"{", lcbracket_}, 69 | {"}", rcbracket_}, 70 | {",", comma_}, 71 | // math operators 72 | {"+", add_}, 73 | {"-", sub_}, 74 | {"*", mul_}, 75 | {"/", div_}, 76 | {"%", mod_}, 77 | {":", dots_}, 78 | {".", dot_}, 79 | {0, 0}, 80 | }; 81 | 82 | Special_characters *special_characters = (Special_characters[]){ 83 | {"\\n", '\n'}, 84 | {"\\\"", '\"'}, 85 | {"\\\'", '\''}, 86 | {"\\\\", '\\'}, 87 | {0, 0}, 88 | }; 89 | -------------------------------------------------------------------------------- /header.h: -------------------------------------------------------------------------------- 1 | #ifndef MINI_HEADER_H 2 | #define MINI_HEADER_H 3 | 4 | #include "Libft/libft.h" 5 | // c headers 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | // macros 16 | #define in STDIN_FILENO 17 | #define out STDOUT_FILENO 18 | #define err STDERR_FILENO 19 | #define DEBUG 0 20 | 21 | // typedefs 22 | typedef struct Node Node; 23 | typedef struct Token Token; 24 | typedef struct Token Value; 25 | typedef struct List List; 26 | typedef enum Type Type; 27 | 28 | // for the stupid implicit declaration error 29 | char *type_to_string(Type type); 30 | Token *evaluate(Node *node); 31 | void visualize_variables(void); 32 | void undeclared_error(char *location, Token *token, char *type); 33 | void see_token(Token *token); 34 | void build_tokens(); 35 | Token *new_token(Type type); 36 | long pow_ten(long exponent); 37 | void output(Token *token); 38 | bool check(Type to_find, ...); 39 | void visualize_variables(void); 40 | 41 | Node **bloc(); // bloc of code 42 | Node *expr(); // expression 43 | Node *assign(); // = += -= *= /= 44 | Node *conditions(); // while, if, elif, else 45 | Node *logic_or(); // || or 46 | Node *logic_and(); // && and 47 | Node *equality(); // == != 48 | Node *comparison(); // < > <= >= 49 | Node *add_sub(); // + - 50 | Node *mul_div(); // * / 51 | Node *sign(); // sign - 52 | Node *iteration(); // .len ... [0] 53 | Node *prime(); // primary 54 | Node *parents(); // () 55 | 56 | enum Type 57 | { 58 | zero_, 59 | // like none data type 60 | void_, 61 | // data types 62 | identifier_, 63 | characters_, 64 | boolean_, 65 | number_, 66 | array_, 67 | obj_, 68 | tuple_, 69 | // asssigns 70 | assign_, 71 | add_assign_, 72 | sub_assign_, 73 | mul_assign_, 74 | div_assign_, 75 | mod_assign_, 76 | // statements 77 | while_, 78 | if_, 79 | elif_, 80 | else_, 81 | for_, 82 | in_, 83 | // end statement 84 | dots_, 85 | comma_, 86 | // parents, brackets 87 | lparent_, 88 | rparent_, 89 | lbracket_, 90 | rbracket_, 91 | lcbracket_, 92 | rcbracket_, 93 | // built in functions 94 | output_, 95 | input_, 96 | range_, 97 | // math operator 98 | add_, 99 | sub_, 100 | mul_, 101 | div_, 102 | mod_, 103 | less_than_, 104 | more_than_, 105 | less_than_or_equal_, 106 | more_than_or_equal_, 107 | // logic operator 108 | and_, 109 | or_, 110 | not_, 111 | equal_, 112 | not_equal_, 113 | // functions 114 | func_dec_, 115 | func_call_, 116 | // key words 117 | break_, 118 | continue_, 119 | return_, 120 | // attribute 121 | dot_, 122 | attribute_, 123 | att_type_, 124 | key_iter, 125 | index_iter, 126 | // built in attributes 127 | indexof_, 128 | count_, 129 | split_, 130 | trim_, 131 | base_, 132 | starts_with_, 133 | ends_with_, 134 | // EOF 135 | eof_, 136 | }; 137 | 138 | struct Token 139 | { 140 | char *name; 141 | Type type; 142 | // positions 143 | int line; // line where the var exists 144 | int column; // column by index 145 | int tab; // by tabs 146 | int txt_pos; 147 | union 148 | { 149 | // number 150 | struct 151 | { 152 | long long number; 153 | int exponent; 154 | // bool is_float; 155 | }; 156 | // characters 157 | struct 158 | { 159 | char *characters; 160 | bool is_char; 161 | }; 162 | // array 163 | struct 164 | { 165 | Node **array_head; 166 | Token **array; 167 | int array_len; 168 | }; 169 | // object 170 | struct 171 | { 172 | Node **object_head; 173 | char **keys; 174 | Token **object; 175 | }; 176 | // params value 177 | struct 178 | { 179 | Node **params_head; 180 | Token **params; 181 | int params_len; 182 | }; 183 | // block 184 | Node **bloc_head; 185 | // data type value 186 | Type value_type; 187 | // boolean value 188 | bool boolean; 189 | }; 190 | }; 191 | 192 | typedef struct 193 | { 194 | char *name; 195 | Type type; 196 | } Typed_token; 197 | 198 | typedef struct 199 | { 200 | char *special; 201 | char replace; 202 | } Special_characters; 203 | 204 | struct Node 205 | { 206 | Node *left; 207 | Node *right; 208 | Token *token; 209 | }; 210 | 211 | struct List 212 | { 213 | int val_index; 214 | Token *variables[5000]; // to be modify after 215 | List *next; 216 | List *prev; 217 | }; 218 | 219 | // globals 220 | extern Special_characters *special_characters; 221 | extern Typed_token *operators_tokens; 222 | extern Typed_token *alpha_tokens; 223 | extern char *text; 224 | 225 | // text 226 | extern char *text; 227 | extern int txt_pos; 228 | 229 | // tokens 230 | extern Token **tokens; 231 | extern int tk_len; 232 | extern int tk_pos; 233 | 234 | // position in file 235 | extern int line; 236 | extern int column; 237 | extern int tab; 238 | extern int start; 239 | extern int exe_pos; 240 | extern char *tab_space; 241 | extern List *current; 242 | extern Node *FUNCTIONS[5000]; // to be modified after 243 | extern int func_index; 244 | extern int scoop; 245 | 246 | #endif -------------------------------------------------------------------------------- /interpret.c: -------------------------------------------------------------------------------- 1 | #include "header.h" 2 | 3 | List *current; 4 | Node *FUNCTIONS[5000]; // to be modified after 5 | int func_index; 6 | int scoop; 7 | 8 | int Value_len(Value **ptr) 9 | { 10 | int i = 0; 11 | while (ptr && ptr[i]) 12 | i++; 13 | return (i); 14 | } 15 | 16 | void access_next_scoop() 17 | { 18 | current->next = ft_calloc(1, sizeof(List)); 19 | List *tmp = current; 20 | current = current->next; 21 | current->prev = tmp; 22 | scoop++; 23 | } 24 | 25 | void exit_current_scoop() 26 | { 27 | if (current->prev == NULL) 28 | ft_fprintf(err, "Error in exiting level\n"); 29 | current = current->prev; 30 | scoop--; 31 | } 32 | 33 | // Variable 34 | Token *new_variable(Token *var) 35 | { 36 | #if 0 37 | Token *new = var; 38 | #else 39 | Token *new = ft_calloc(1, sizeof(Token)); 40 | memcpy(new, var, sizeof(Token)); 41 | #endif 42 | current->variables[current->val_index] = new; 43 | // new->level = scoop; 44 | current->val_index++; 45 | return (new); 46 | } 47 | 48 | List *tmp; 49 | Token *get_var(char *name) 50 | { 51 | visualize_variables(); 52 | tmp = current; 53 | while (tmp) 54 | { 55 | for (int i = tmp->val_index - 1; i >= 0; i--) 56 | { 57 | if (ft_strcmp(tmp->variables[i]->name, name) == 0) 58 | return tmp->variables[i]; 59 | } 60 | tmp = tmp->prev; 61 | } 62 | return NULL; 63 | } 64 | 65 | // Function 66 | Node *new_func(Node *func) 67 | { 68 | // ft_printf(out, "New function with name %s\n", func->token->name); 69 | FUNCTIONS[func_index] = func; 70 | func_index++; 71 | return (func); 72 | } 73 | Node *get_func(char *name) 74 | { 75 | for (int i = 0; i < func_index; i++) 76 | { 77 | if (ft_strcmp(FUNCTIONS[i]->token->name, name) == 0) 78 | return (FUNCTIONS[i]); 79 | } 80 | // ft_fprintf(err, "Undeclared function %s\n", name); 81 | return NULL; 82 | } 83 | 84 | long pow_ten(long exponent) 85 | { 86 | if (exponent < 0) 87 | return 0; // negative exponents are not handled in this simple example 88 | 89 | long result = 1; 90 | for (long i = 0; i < exponent; i++) 91 | result *= 10; 92 | return result; 93 | } 94 | 95 | Value *evaluate(Node *node) 96 | { 97 | // ft_printf(out, "Evaluate %k\n", node->token); 98 | switch (node->token->type) 99 | { 100 | // assignement 101 | case assign_: 102 | { 103 | Value *left = evaluate(node->left); 104 | Value *right = evaluate(node->right); 105 | // ft_printf(out, "Do assignemnt between %k and %k\n", left, right); 106 | // skip this error for function because i can set global variable to idenitifer from params 107 | if (right->type == identifier_) 108 | undeclared_error("assign", right, "variable"); 109 | if (left->type != identifier_ && left->type != right->type) 110 | ft_fprintf(err, "can't assign '%s' type %s to '%s' type %s in line %d\n", left->name, type_to_string(left->type), right->name, type_to_string(right->type), left->line); 111 | 112 | char *name = left->name; 113 | if (right->type == characters_ && right->is_char == true) 114 | { 115 | if (left->type == identifier_) 116 | { 117 | left->type = characters_; 118 | left->is_char = true; 119 | left->characters = ft_calloc(2, sizeof(char)); 120 | left->characters[0] = right->characters[0]; 121 | } 122 | else if (left->type == characters_ && left->is_char) 123 | { 124 | left->characters[0] = right->characters[0]; 125 | } 126 | else if (left->type == characters_ && left->is_char == false) 127 | { 128 | left->characters[0] = right->characters[0]; 129 | } 130 | } 131 | else if (right->type == characters_ && right->is_char == false) 132 | { 133 | if (left->type == identifier_) 134 | { 135 | left->type = characters_; 136 | left->characters = ft_calloc(ft_strlen(right->characters) + 1, sizeof(char)); 137 | memcpy(left->characters, right->characters, ft_strlen(right->characters)); 138 | } 139 | else if (left->type == characters_ && left->is_char) 140 | { 141 | if (ft_strlen(right->characters) == 1) 142 | left->characters[0] = right->characters[0]; 143 | else 144 | ft_fprintf(err, "Error: can't assign string to character\n"); 145 | } 146 | else if (left->type == characters_ && left->is_char == false) 147 | { 148 | // protect it from leaks after 149 | left->characters = ft_calloc(ft_strlen(right->characters) + 1, sizeof(char)); 150 | memcpy(left->characters, right->characters, ft_strlen(right->characters)); 151 | } 152 | } 153 | else 154 | memcpy(left, right, sizeof(Value)); // to be changed after, change only for characters, I guess !!! 155 | left->name = name; 156 | return left; 157 | } 158 | // identifier 159 | case identifier_: 160 | { 161 | Value *identifier = get_var(node->token->name); 162 | if (identifier) 163 | return (identifier); 164 | else 165 | return (new_variable(node->token)); 166 | } 167 | // values and some keywords 168 | case number_: 169 | case characters_: 170 | case boolean_: 171 | case break_: 172 | case continue_: 173 | case indexof_: 174 | case count_: 175 | case split_: 176 | case trim_: 177 | case base_: 178 | case starts_with_: 179 | case ends_with_: 180 | case att_type_: 181 | { 182 | return (node->token); 183 | } 184 | // array 185 | case array_: 186 | { 187 | Node **head = node->token->array_head; 188 | int i = 0; 189 | 190 | Token **array = ft_calloc(i + 1, sizeof(Token *)); 191 | while (head[i]) 192 | { 193 | Value *to_assign = evaluate(head[i]); 194 | if (to_assign->type == identifier_) 195 | undeclared_error("array:", to_assign, "variable"); 196 | array[i] = to_assign; 197 | i++; 198 | array = ft_realloc(array, (i) * sizeof(Token *), (i + 1) * sizeof(Token *)); 199 | array[i] = NULL; 200 | } 201 | node->token->array = array; 202 | return (node->token); 203 | } 204 | // object 205 | case obj_: 206 | { 207 | Node **head = node->token->object_head; 208 | int i = 0; 209 | 210 | Token **object = ft_calloc(i + 1, sizeof(Token *)); 211 | while (head[i]) 212 | { 213 | Value *to_assign = evaluate(head[i]); 214 | if (to_assign->type == identifier_) 215 | ft_fprintf(err, "key '%s', has no valid value\n", to_assign->name); 216 | object[i] = to_assign; 217 | i++; 218 | object = ft_realloc(object, (i) * sizeof(Token *), (i + 1) * sizeof(Token *)); 219 | object[i] = NULL; 220 | } 221 | node->token->object = object; 222 | return (node->token); 223 | } 224 | // math operator 225 | case add_: 226 | case sub_: 227 | case mul_: 228 | case div_: 229 | case mod_: 230 | { 231 | Value *left = evaluate(node->left); 232 | Value *right = evaluate(node->right); 233 | 234 | if (left->type == identifier_) 235 | undeclared_error("math operation", left, "variable"); 236 | if (right->type == identifier_) 237 | undeclared_error("math operation", right, "variable"); 238 | Value *ret = ft_calloc(1, sizeof(Value)); 239 | if (left->type == number_ && right->type == number_) 240 | { 241 | long long number = 0; 242 | int tmp_right; 243 | int tmp_left; 244 | if (left->exponent > right->exponent) 245 | { 246 | right->number *= pow_ten(left->exponent - right->exponent); 247 | right->exponent = left->exponent; 248 | } 249 | else if (left->exponent < right->exponent) 250 | { 251 | left->number *= pow_ten(right->exponent - left->exponent); 252 | left->exponent = right->exponent; 253 | } 254 | 255 | switch (node->token->type) 256 | { 257 | case add_: 258 | number = left->number + right->number; 259 | break; 260 | case sub_: 261 | number = left->number - right->number; 262 | break; 263 | case mul_: 264 | ret->exponent = left->exponent + right->exponent; 265 | number = left->number * right->number; 266 | break; 267 | case div_: 268 | ret->exponent = left->exponent - right->exponent; 269 | number = left->number / right->number; 270 | break; 271 | case mod_: 272 | number = left->number % right->number; 273 | break; 274 | default: 275 | break; 276 | } 277 | 278 | ret->type = number_; 279 | ret->number = number; 280 | 281 | return (ret); 282 | } 283 | else if (node->token->type == add_ && left->type == characters_ && right->type == characters_) 284 | { 285 | ret->type = characters_; 286 | ret->is_char = left->is_char && right->is_char; 287 | ret->characters = ft_calloc(ft_strlen(left->characters) + ft_strlen(right->characters) + 1, sizeof(char)); 288 | if (left->is_char) 289 | ft_strncpy(ret->characters, left->characters, sizeof(char)); 290 | else 291 | ft_strcpy(ret->characters, left->characters); 292 | if (right->is_char) 293 | ft_strncpy(ret->characters + ft_strlen(ret->characters), right->characters, sizeof(char)); 294 | else 295 | ft_strcpy(ret->characters + ft_strlen(ret->characters), right->characters); 296 | return (ret); 297 | } 298 | else if (node->token->type == add_ && (left->type == array_ && right->type == array_)) 299 | { 300 | int left_len = Value_len(left->array); 301 | int right_len = Value_len(right->array); 302 | ret->type = array_; 303 | ret->array = ft_calloc(left_len + right_len + 1, sizeof(Token *)); 304 | memcpy(ret->array, left->array, left_len * sizeof(Token *)); 305 | memcpy(&ret->array[left_len], right->array, right_len * sizeof(Token *)); 306 | return (ret); 307 | } 308 | else 309 | ft_fprintf(err, "Error 1: can't do '%s' between '%s' and '%s'\n", type_to_string(node->token->type), type_to_string(left->type), type_to_string(right->type)); 310 | break; 311 | } 312 | // math assign operator 313 | case add_assign_: 314 | case sub_assign_: 315 | case mul_assign_: 316 | case div_assign_: 317 | case mod_assign_: 318 | { 319 | Value *left = evaluate(node->left); 320 | Value *right = evaluate(node->right); 321 | if (left->type == identifier_) 322 | undeclared_error("operaned assign", left, "variable"); 323 | if (right->type == identifier_) 324 | undeclared_error("operaned assign", right, "variable"); 325 | Value *ret = ft_calloc(1, sizeof(Value)); 326 | if (left->type == number_ && right->type == number_) 327 | { 328 | long long number = 0; 329 | int exponent_difference = 0; 330 | 331 | // Making exponents same before operations 332 | if (left->exponent > right->exponent) 333 | { 334 | exponent_difference = left->exponent - right->exponent; 335 | right->number *= pow_ten(exponent_difference); 336 | right->exponent = left->exponent; 337 | } 338 | else if (left->exponent < right->exponent) 339 | { 340 | exponent_difference = right->exponent - left->exponent; 341 | left->number *= pow_ten(exponent_difference); 342 | left->exponent = right->exponent; 343 | } 344 | 345 | switch (node->token->type) 346 | { 347 | case add_: 348 | case add_assign_: 349 | number = left->number + right->number; 350 | break; 351 | case sub_: 352 | case sub_assign_: 353 | number = left->number - right->number; 354 | break; 355 | case mul_: 356 | case mul_assign_: 357 | ret->exponent = left->exponent + right->exponent; 358 | number = left->number * right->number; 359 | break; 360 | case div_: 361 | case div_assign_: 362 | ret->exponent = left->exponent - right->exponent; 363 | number = left->number / right->number; 364 | break; 365 | case mod_: 366 | case mod_assign_: 367 | number = left->number % right->number; 368 | break; 369 | default: 370 | break; 371 | } 372 | 373 | ret->type = number_; 374 | ret->number = number; 375 | 376 | // Storing result back to left operand for compound assignments 377 | if (node->token->type == add_assign_ || node->token->type == sub_assign_ || 378 | node->token->type == mul_assign_ || node->token->type == div_assign_ || 379 | node->token->type == mod_assign_) 380 | { 381 | left->number = ret->number; 382 | left->exponent = ret->exponent; 383 | } 384 | } 385 | else if (node->token->type == add_assign_ && left->type == characters_ && right->type == characters_) 386 | { 387 | ret->type = left->is_char || right->is_char; 388 | ret->characters = ft_calloc(ft_strlen(left->characters) + ft_strlen(right->characters) + 1, sizeof(char)); 389 | ft_strcpy(ret->characters, left->characters); 390 | ft_strcpy(ret->characters + ft_strlen(ret->characters), right->characters); 391 | left->characters = ret->characters; 392 | } 393 | else if (node->token->type == add_assign_ && (left->type == array_ && right->type == array_)) 394 | { 395 | int left_len = Value_len(left->array); 396 | int right_len = Value_len(right->array); 397 | ret->type = array_; 398 | ret->array = ft_calloc(left_len + right_len + 1, sizeof(Token *)); 399 | memcpy(ret->array, left->array, left_len * sizeof(Token *)); 400 | memcpy(&ret->array[left_len], right->array, right_len * sizeof(Token *)); 401 | left->array = ret->array; 402 | } 403 | else 404 | { 405 | ft_putchar(out, '\n'); 406 | txt_pos = node->token->txt_pos; 407 | while (txt_pos > 0 && text[txt_pos - 1] != '\n') 408 | txt_pos--; 409 | while (text[txt_pos] && text[txt_pos] != '\n') 410 | { 411 | ft_putchar(out, text[txt_pos]); 412 | txt_pos++; 413 | } 414 | ft_putchar(out, '\n'); 415 | print_space(node->token->column - ft_strlen(node->token->name)); 416 | ft_putstr(out, "^\n"); 417 | ft_fprintf(err, "Error 2: can't do '%t' between '%t' and '%t'\n", node->token->type, type_to_string(left->type), type_to_string(right->type)); 418 | } 419 | break; 420 | } 421 | // statements 422 | case if_: 423 | case elif_: 424 | { 425 | // ft_printf(out, "enter if\n"); 426 | Value *condition = evaluate(node->left); 427 | Value *ret = NULL; 428 | if (condition->type != boolean_) 429 | ft_fprintf(err, "Error in if_ elif_, exepected boolean value\n"); 430 | if (condition->boolean) 431 | { 432 | Node **bloc_head = node->token->bloc_head; 433 | int i = 0; 434 | while (bloc_head[i]) 435 | { 436 | #if 1 437 | if (bloc_head[i]->token->type == return_) 438 | { 439 | // ft_printf(out, "found return in if_ elif_\n"); 440 | // exit(0); 441 | return bloc_head[i]->token; 442 | } 443 | ret = evaluate(bloc_head[i]); 444 | #else 445 | ret = evaluate(bloc_head[i]); 446 | if (ret && ret->type == return_) 447 | { 448 | ft_printf(out, "if, elif_ return %v\n", ret); 449 | return ret; 450 | } 451 | #endif 452 | i++; 453 | } 454 | } 455 | else if (node->right) 456 | { 457 | return (evaluate(node->right)); // t obe veirfied after 458 | } 459 | ret = new_token(void_); 460 | // ft_printf(out, "if return %v\n", ret); 461 | return (ret); // to be verified 462 | } 463 | case else_: 464 | { 465 | #if 1 466 | Node **bloc_head = node->token->bloc_head; 467 | Value *ret = NULL; 468 | int i = 0; 469 | while (bloc_head[i]) 470 | { 471 | #if 1 472 | if (bloc_head[i]->token->type == return_) 473 | { 474 | return bloc_head[i]->token; 475 | } 476 | ret = evaluate(bloc_head[i]); 477 | #else 478 | ret = evaluate(bloc_head[i]); 479 | if (ret && ret->type == return_) 480 | { 481 | ft_printf(out, "else return %v\n", ret); 482 | return ret; 483 | } 484 | #endif 485 | i++; 486 | } 487 | #endif 488 | ret = new_token(void_); 489 | return (ret); 490 | } 491 | case while_: 492 | { 493 | Value *condition = evaluate(node->left); 494 | Value *ret; 495 | if (condition->type != boolean_) 496 | ft_fprintf(err, "Error in while_, exepected boolean value\n"); 497 | while (condition->boolean) 498 | { 499 | Node **bloc_head = node->token->bloc_head; 500 | int i = 0; 501 | while (bloc_head[i]) 502 | { 503 | if (bloc_head[i]->token->type == return_) 504 | { 505 | return bloc_head[i]->token; 506 | } 507 | ret = evaluate(bloc_head[i]); 508 | if (ret && ret->type == break_) 509 | { 510 | condition->boolean = false; 511 | break; 512 | } 513 | if (ret && ret->type == continue_) 514 | break; 515 | i++; 516 | } 517 | if (condition->boolean == false) 518 | break; 519 | condition = evaluate(node->left); 520 | } 521 | return (ret); 522 | } 523 | case for_: 524 | { 525 | 526 | Value *right = evaluate(node->right); 527 | right->array_len = Value_len(right->array); 528 | Value *ret; 529 | if (right->type != array_ && right->type != range_) 530 | ft_fprintf(err, "Expected an array to iterate over it in for loop\n"); 531 | 532 | int j = 0; 533 | access_next_scoop(); 534 | while (j < right->array_len) 535 | { 536 | right->array[j]->name = node->left->token->name; 537 | Token *value = get_var(node->left->token->name); 538 | if (value == NULL) 539 | new_variable(right->array[j]); 540 | else 541 | *value = *right->array[j]; 542 | 543 | ret = NULL; 544 | int i = 0; 545 | Node **bloc_head = node->token->bloc_head; 546 | while (bloc_head[i]) 547 | { 548 | if (bloc_head[i]->token->type == return_) 549 | { 550 | return bloc_head[i]->token; 551 | } 552 | ret = evaluate(bloc_head[i]); 553 | if (ret && ret->type == break_) 554 | break; 555 | if (ret && ret->type == continue_) // to be verified 556 | break; 557 | i++; 558 | } 559 | j++; 560 | } 561 | exit_current_scoop(); 562 | return ret; 563 | } 564 | // logic operator 565 | case equal_: 566 | case not_equal_: 567 | case more_than_: 568 | case less_than_: 569 | case more_than_or_equal_: 570 | case less_than_or_equal_: 571 | { 572 | Value *left = evaluate(node->left); 573 | Value *right = evaluate(node->right); 574 | if (left->type == identifier_) 575 | undeclared_error("logic assign", left, "variable"); 576 | if (right->type == identifier_) 577 | undeclared_error("logic assign", right, "variable"); 578 | Value *ret = ft_calloc(1, sizeof(Value)); 579 | if (left->type == number_ && right->type == number_) 580 | { 581 | switch (node->token->type) 582 | { 583 | case equal_: 584 | ret->boolean = left->number == right->number; 585 | break; 586 | case not_equal_: 587 | ret->boolean = left->number != right->number; 588 | break; 589 | case more_than_: 590 | ret->boolean = left->number > right->number; 591 | break; 592 | case less_than_: 593 | ret->boolean = left->number < right->number; 594 | break; 595 | case more_than_or_equal_: 596 | ret->boolean = left->number >= right->number; 597 | break; 598 | case less_than_or_equal_: 599 | ret->boolean = left->number <= right->number; 600 | break; 601 | default: 602 | break; 603 | } 604 | ret->type = boolean_; 605 | return (ret); 606 | } 607 | else if (node->token->type == equal_ && left->type == characters_ && right->type == characters_) 608 | { 609 | ret->type = boolean_; 610 | ret->boolean = ft_strcmp(left->characters, right->characters) == 0; 611 | return (ret); 612 | } 613 | else 614 | ft_fprintf(err, "Error 3: can't do '%t' between '%t' and '%t'\n", node->token->type, left->type, right->type); 615 | break; 616 | } 617 | case and_: 618 | case or_: 619 | { 620 | Value *left = evaluate(node->left); 621 | Value *right = evaluate(node->right); 622 | if (left->type == identifier_) 623 | undeclared_error("logic assign", left, "variable"); 624 | if (right->type == identifier_) 625 | undeclared_error("logic assign", right, "variable"); 626 | Value *ret = ft_calloc(1, sizeof(Value)); 627 | if (left->type != boolean_ || right->type != boolean_) 628 | ft_fprintf(err, "in %t operation, expected boolean values\n", node->token->type); 629 | 630 | switch (node->token->type) 631 | { 632 | case and_: 633 | ret->boolean = left->boolean && right->boolean; 634 | break; 635 | case or_: 636 | ret->boolean = left->boolean || right->boolean; 637 | break; 638 | default: 639 | ft_fprintf(err, "Error ...\n"); 640 | break; 641 | } 642 | ret->type = boolean_; 643 | return (ret); 644 | } 645 | case output_: 646 | { 647 | Node **head = node->token->array_head; 648 | int i = 0; 649 | while (head[i]) 650 | { 651 | // verify return_ it may cause problems or something 652 | output(evaluate(head[i])); 653 | i++; 654 | } 655 | return (node->token); // to be verified 656 | } 657 | case input_: 658 | { 659 | // ft_printf(out, "call input\n"); 660 | Node **head = node->token->array_head; 661 | int i = 0; 662 | while (head[i]) 663 | { 664 | // verify return_ it may cause problems or something 665 | output(evaluate(head[i])); 666 | i++; 667 | } 668 | // exit(0); 669 | char *string = ft_readline(out); 670 | Value *new = ft_calloc(1, sizeof(Value)); 671 | new->type = characters_; 672 | new->characters = string; 673 | return (new); 674 | } 675 | case range_: 676 | { 677 | Value *start = evaluate(node->left); 678 | Value *end = evaluate(node->right); 679 | // ft_printf(out, "range from %k to %k\n", start, end); 680 | Value *ret = ft_calloc(1, sizeof(Value)); 681 | ret->type = array_; 682 | ret->array_len = end->number > start->number ? end->number - start->number : start->number - end->number; 683 | ret->array = ft_calloc(ret->array_len + 1, sizeof(Value *)); 684 | 685 | long double n = start->number; 686 | long double step = end->number > start->number ? 1.0 : -1.0; 687 | 688 | int i = 0; 689 | while (i < ret->array_len) 690 | { 691 | ret->array[i] = ft_calloc(1, sizeof(Value)); 692 | ret->array[i]->type = number_; 693 | ret->array[i]->number = n; 694 | n += step; 695 | i++; 696 | } 697 | return ret; 698 | } 699 | 700 | case func_dec_: 701 | { 702 | Node *func_dec = new_func(node); 703 | break; 704 | } 705 | case func_call_: 706 | { 707 | // find function 708 | Node *existed_func = get_func(node->token->name); 709 | if (existed_func == NULL) 710 | undeclared_error("function call", node->token, "function"); 711 | Node **existed_params = existed_func->left->token->array_head; 712 | Node **new_params = node->left->token->array_head; 713 | // access next scoop 714 | // evaluate params of original function, and set hem to those in call 715 | int i = 0; 716 | access_next_scoop(); 717 | while (existed_params[i]) 718 | { 719 | Token *value = evaluate(new_params[i]); 720 | value = new_variable(value); 721 | value->name = existed_params[i]->token->name; 722 | i++; 723 | } 724 | visualize_variables(); 725 | Node **bloc_head = existed_func->token->bloc_head; 726 | Value *ret = NULL; 727 | i = 0; 728 | while (bloc_head[i]) 729 | { 730 | #if 0 731 | if(bloc_head[i]->token->type == return_) 732 | { 733 | return bloc_head[i]->token; 734 | } 735 | ret = evaluate(bloc_head[i]); 736 | #else 737 | ret = evaluate(bloc_head[i]); 738 | if (ret && ret->type == return_) 739 | { 740 | Node **ret_head = ret->bloc_head; 741 | // ft_printf(out, "Evaluate bloc in function\n"); 742 | int j = 0; 743 | while (ret_head[j]) 744 | { 745 | ret = evaluate(ret_head[j]); 746 | j++; 747 | } 748 | exit_current_scoop(); 749 | return ret; 750 | } 751 | #endif 752 | i++; 753 | } 754 | exit_current_scoop(); 755 | ret = new_token(void_); 756 | return ret; 757 | break; 758 | } 759 | case return_: 760 | return (node->token); 761 | case attribute_: 762 | { 763 | // len, isnumber, isalpha, indexof ... 764 | // it's better to check left type then check right attribute 765 | // iteration over characters and arrays 766 | // iteration with number 767 | // attribute with key (identifier) 768 | // or with characters !!! 769 | Value *left = evaluate(node->left); // variable 770 | Value *right = evaluate(node->right); 771 | // ft_printf(out, "do itteration between %k and %k\n",left, right); 772 | // exit(0); 773 | char *key = NULL; 774 | int val_index = 0; 775 | Type type = void_; 776 | 777 | if (right->type == identifier_) 778 | { 779 | key = right->name; 780 | type = key_iter; 781 | } 782 | else if (right->type == characters_) 783 | { 784 | key = right->characters; 785 | type = key_iter; 786 | } 787 | else if (right->type == att_type_) 788 | { 789 | key = right->name; 790 | type = key_iter; 791 | } 792 | else if (right->type == number_) 793 | { 794 | val_index = (long)right->number; 795 | type = index_iter; 796 | } 797 | else if (check(right->type, indexof_, split_, count_, base_, trim_, starts_with_, ends_with_)) 798 | { 799 | type = right->type; 800 | } 801 | else 802 | { 803 | ft_fprintf(err, "Error in iteration\n"); 804 | } 805 | // ft_printf(out, "left: %v\nright: %v\n", left, right); 806 | if (left->type == identifier_) 807 | undeclared_error("attribute", left, "variable"); 808 | 809 | if (type == key_iter) 810 | { 811 | if (ft_strcmp(key, "type") == 0) 812 | { 813 | Value *ret = ft_calloc(1, sizeof(Value)); 814 | ret->type = characters_; 815 | ret->characters = type_to_string(left->type); 816 | return ret; 817 | } 818 | if (left->type == obj_) 819 | { 820 | int i = 0; 821 | while (left->keys && left->keys[i]) 822 | { 823 | if (strcmp(key, left->keys[i]) == 0) 824 | { 825 | Value *ret = ft_calloc(1, sizeof(Value)); 826 | // ft_printf(out, "iterate return %v\n", left->object[i]); 827 | // exit(0); 828 | memcpy(ret, left->object[i], sizeof(Value)); 829 | return ret; 830 | } 831 | i++; 832 | } 833 | if (ft_strcmp(key, "type") == 0) 834 | { 835 | Value *ret = ft_calloc(1, sizeof(Value)); 836 | ret->type = characters_; 837 | ret->characters = type_to_string(left->type); 838 | return ret; 839 | } 840 | ft_fprintf(err, "Error: %s has no attribute '%s'\n", left->name, right->name); 841 | } 842 | if (left->type == characters_) 843 | { 844 | int i = 0; 845 | if (ft_strcmp(key, "len") == 0) 846 | { 847 | Value *ret = ft_calloc(1, sizeof(Value)); 848 | ret->type = number_; 849 | ret->number = (long double)ft_strlen(left->characters); 850 | return ret; 851 | } 852 | if (ft_strcmp(key, "toup") == 0) 853 | { 854 | Value *ret = ft_calloc(1, sizeof(Value)); 855 | ret->characters = ft_calloc(ft_strlen(left->characters) + 1, sizeof(char)); 856 | ret->type = characters_; 857 | while (left->characters && left->characters[i]) 858 | { 859 | if (ft_isalpha(left->characters[i])) 860 | ret->characters[i] = to_upper(left->characters[i]); 861 | else 862 | ret->characters[i] = left->characters[i]; 863 | i++; 864 | } 865 | return ret; 866 | } 867 | if (ft_strcmp(key, "tolow") == 0) 868 | { 869 | Value *ret = ft_calloc(1, sizeof(Value)); 870 | ret->characters = ft_calloc(ft_strlen(left->characters) + 1, sizeof(char)); 871 | ret->type = characters_; 872 | while (left->characters && left->characters[i]) 873 | { 874 | if (ft_isalpha(left->characters[i])) 875 | ret->characters[i] = to_lower(left->characters[i]); 876 | else 877 | ret->characters[i] = left->characters[i]; 878 | i++; 879 | } 880 | return ret; 881 | } 882 | if (ft_strcmp(key, "tonum") == 0) 883 | { 884 | Value *ret = ft_calloc(1, sizeof(Value)); 885 | ret->type = number_; 886 | // to verify after 887 | ret->number = atof(left->characters); 888 | return ret; 889 | } 890 | if (ft_strcmp(key, "isup") == 0) 891 | { 892 | Value *ret = ft_calloc(1, sizeof(Value)); 893 | ret->type = boolean_; 894 | while (left->characters && left->characters[i]) 895 | { 896 | if (!ft_isupper(left->characters[i])) 897 | { 898 | ret->boolean = false; 899 | return ret; 900 | } 901 | i++; 902 | } 903 | ret->boolean = true; 904 | return ret; 905 | } 906 | if (ft_strcmp(key, "islow") == 0) 907 | { 908 | Value *ret = ft_calloc(1, sizeof(Value)); 909 | ret->type = boolean_; 910 | while (left->characters && left->characters[i]) 911 | { 912 | if (!ft_islower(left->characters[i])) 913 | { 914 | ret->boolean = false; 915 | return ret; 916 | } 917 | i++; 918 | } 919 | ret->boolean = true; 920 | return ret; 921 | } 922 | if (ft_strcmp(key, "ischar") == 0) 923 | { 924 | Value *ret = ft_calloc(1, sizeof(Value)); 925 | ret->type = boolean_; 926 | while (left->characters && left->characters[i]) 927 | { 928 | if (!ft_isalpha(left->characters[i])) 929 | { 930 | ret->boolean = false; 931 | return ret; 932 | } 933 | i++; 934 | } 935 | ret->boolean = true; 936 | return ret; 937 | } 938 | if (ft_strcmp(key, "isnum") == 0) 939 | { 940 | Value *ret = ft_calloc(1, sizeof(Value)); 941 | ret->type = boolean_; 942 | ret->boolean = true; 943 | while (left->characters && left->characters[i] && ft_isdigit(left->characters[i])) 944 | i++; 945 | if (left->characters && left->characters[i] == '.') 946 | i++; 947 | while (left->characters && left->characters[i] && ft_isdigit(left->characters[i])) 948 | i++; 949 | if (left->characters[i]) 950 | ret->boolean = false; 951 | return ret; 952 | } 953 | if (ft_strcmp(key, "type") == 0) 954 | { 955 | Value *ret = ft_calloc(1, sizeof(Value)); 956 | ret->type = characters_; 957 | ret->characters = type_to_string(left->type); 958 | return ret; 959 | } 960 | ft_fprintf(err, "%s has no attribute %s\n", left->name, right->name); 961 | } 962 | if (left->type == number_) 963 | { 964 | if (ft_strcmp(key, "type") == 0) 965 | { 966 | Value *ret = ft_calloc(1, sizeof(Value)); 967 | ret->type = characters_; 968 | ret->characters = type_to_string(left->type); 969 | return ret; 970 | } 971 | if (ft_strcmp(key, "tochar") == 0) 972 | { 973 | Value *ret = ft_calloc(1, sizeof(Value)); 974 | ret->type = characters_; 975 | ret->characters = convert_base(left->number, "0123456789"); 976 | return ret; 977 | } 978 | ft_fprintf(err, "%s has no attribute %s\n", left->name, right->name); 979 | } 980 | if (left->type == array_) 981 | { 982 | if (ft_strcmp(key, "len") == 0) 983 | { 984 | Value *ret = ft_calloc(1, sizeof(Value)); 985 | ret->type = number_; 986 | long i = 0; 987 | while (left->array && left->array[i]) 988 | i++; 989 | ret->number = i; 990 | return ret; 991 | } 992 | if (ft_strcmp(key, "type") == 0) 993 | { 994 | Value *ret = ft_calloc(1, sizeof(Value)); 995 | ret->type = characters_; 996 | ret->characters = type_to_string(left->type); 997 | return ret; 998 | } 999 | output(left); 1000 | ft_fprintf(err, " has no attribute %s\n", left, key); 1001 | } 1002 | } 1003 | if (type == index_iter) 1004 | { 1005 | if (left->type == characters_) 1006 | { 1007 | long i = 0; 1008 | Value *ret = ft_calloc(1, sizeof(Value)); 1009 | ret->type = characters_; 1010 | ret->is_char = true; 1011 | if (i < ft_strlen(left->characters)) 1012 | { 1013 | ret->characters = left->characters + val_index; 1014 | return ret; 1015 | } 1016 | ft_fprintf(err, "Index out of range\n"); 1017 | } 1018 | if (left->type == array_) 1019 | { 1020 | long i = 0; 1021 | while (left->array && left->array[i]) 1022 | { 1023 | if (i == right->number) 1024 | return left->array[i]; 1025 | i++; 1026 | } 1027 | ft_fprintf(err, "Index out of range\n"); 1028 | } 1029 | ft_fprintf(err, "Can't iterate over %t\n", left->type); 1030 | } 1031 | 1032 | if (type == indexof_) 1033 | { 1034 | // check if is array or string only 1035 | Value *to_find = evaluate(node->right->right); 1036 | Value *ret = ft_calloc(1, sizeof(Value)); 1037 | ret->type = number_; 1038 | if (to_find->type == array_) 1039 | ft_fprintf(err, "can't search of val_index of array (it's not suported for now)\n"); 1040 | if (left->type == characters_) 1041 | { 1042 | if (to_find->type != characters_) 1043 | ft_fprintf(err, "can't do indexof between %t and %t\n", left->type, to_find->type); 1044 | int i = 0; 1045 | while (left->characters && left->characters[i]) 1046 | { 1047 | if (ft_strncmp(left->characters + i, to_find->characters, ft_strlen(to_find->characters)) == 0) 1048 | { 1049 | ret->number = (long double)i; 1050 | return ret; 1051 | } 1052 | i++; 1053 | } 1054 | } 1055 | else if (left->type == array_) 1056 | { 1057 | if (left->array[0]->type != to_find->type) 1058 | ft_fprintf(err, "can't do indexof between %t and %t\n", left->array[0]->type, to_find->type); 1059 | int i = 0; 1060 | while (left->array && left->array[i]) 1061 | { 1062 | if (left->array[i]->type == characters_) 1063 | { 1064 | if (ft_strncmp(left->array[i]->characters + i, to_find->characters, ft_strlen(to_find->characters)) == 0) 1065 | { 1066 | ret->number = (long double)i; 1067 | return ret; 1068 | } 1069 | } 1070 | if (left->array[i]->type == number_) 1071 | { 1072 | if (left->array[i]->number == to_find->number) 1073 | { 1074 | ret->number = (long double)i; 1075 | return ret; 1076 | } 1077 | } 1078 | i++; 1079 | } 1080 | } 1081 | ret->number = -1; 1082 | return ret; 1083 | } 1084 | if (type == count_) 1085 | { 1086 | Value *to_find = evaluate(node->right->right); 1087 | Value *ret = ft_calloc(1, sizeof(Value)); 1088 | ret->type = number_; 1089 | ret->number = 0; 1090 | int i = 0; 1091 | // check if is array or string only 1092 | if (left->type == characters_) 1093 | { 1094 | if (to_find->type != characters_) 1095 | ft_fprintf(err, "can't do indexof between %t and %t\n", left->type, to_find->type); 1096 | int i = 0; 1097 | while (left->characters && left->characters[i]) 1098 | { 1099 | if (ft_strncmp(left->characters + i, to_find->characters, ft_strlen(to_find->characters)) == 0) 1100 | ret->number++; 1101 | i++; 1102 | } 1103 | } 1104 | else if (left->type == array_) 1105 | { 1106 | if (left->array[0]->type != to_find->type) 1107 | ft_fprintf(err, "can't do indexof between %t and %t\n", left->array[0]->type, to_find->type); 1108 | while (left->array && left->array[i]) 1109 | { 1110 | if (left->array[i]->type == characters_) 1111 | { 1112 | if (ft_strncmp(left->array[i]->characters + i, to_find->characters, ft_strlen(to_find->characters)) == 0) 1113 | ret->number++; 1114 | } 1115 | if (left->array[i]->type == number_) 1116 | { 1117 | if (left->array[i]->number == to_find->number) 1118 | ret->number++; 1119 | } 1120 | i++; 1121 | } 1122 | } 1123 | else 1124 | ft_fprintf(err, "%t has no attribute count\n", left->type); 1125 | return ret; 1126 | } 1127 | if (type == split_) 1128 | { 1129 | if (left->type == characters_) 1130 | { 1131 | // chekc if is array or string only 1132 | Value *spliter_value = evaluate(node->right->right); 1133 | Value *ret = ft_calloc(1, sizeof(Value)); 1134 | ret->type = array_; 1135 | ret->array = NULL; 1136 | // printf("split: %s, by: '%s'\n", left->characters, spliter_value->characters); 1137 | // exit(0); 1138 | char *spliter = spliter_value->characters; 1139 | char **string_array = ft_split(left->characters, spliter); 1140 | int i = 0; 1141 | while (string_array && string_array[i]) 1142 | i++; 1143 | ret->array = ft_calloc(i + 1, sizeof(Token *)); 1144 | i = 0; 1145 | while (string_array && string_array[i]) 1146 | { 1147 | ret->array[i] = ft_calloc(1, sizeof(Token)); 1148 | ret->array[i]->type = characters_; 1149 | ret->array[i]->characters = string_array[i]; 1150 | i++; 1151 | } 1152 | ret->array[i] = NULL; 1153 | return ret; 1154 | } 1155 | else 1156 | ft_fprintf(err, "%t has no attribute split\n", left->type); 1157 | } 1158 | if (type == trim_) 1159 | { 1160 | if (left->type == characters_) 1161 | { 1162 | // chekc if is array or string only 1163 | Value *set_value = evaluate(node->right->right); 1164 | Value *ret = ft_calloc(1, sizeof(Value)); 1165 | ret->type = characters_; 1166 | char *set = set_value->characters; 1167 | ret->characters = ft_strtrim(left->characters, set); 1168 | return ret; 1169 | } 1170 | else 1171 | ft_fprintf(err, "%t has no attribute trim\n", left->type); 1172 | } 1173 | if (type == starts_with_) 1174 | { 1175 | if (left->type == characters_) 1176 | { 1177 | Value *to_find_value = evaluate(node->right->right); 1178 | Value *ret = ft_calloc(1, sizeof(Value)); 1179 | ret->type = boolean_; 1180 | char *to_find = to_find_value->characters; 1181 | ret->boolean = false; 1182 | if (ft_strlen(to_find) < ft_strlen(left->characters)) 1183 | ret->boolean = (ft_strncmp(left->characters, to_find, ft_strlen(to_find)) == 0); 1184 | return ret; 1185 | } 1186 | else 1187 | ft_fprintf(err, "%t has no attribute startswith\n", left->type); 1188 | } 1189 | if (type == ends_with_) 1190 | { 1191 | if (left->type == characters_) 1192 | { 1193 | Value *to_find_value = evaluate(node->right->right); 1194 | Value *ret = ft_calloc(1, sizeof(Value)); 1195 | ret->type = boolean_; 1196 | char *to_find = to_find_value->characters; 1197 | ret->boolean = false; 1198 | if (ft_strlen(to_find) < ft_strlen(left->characters)) 1199 | ret->boolean = (ft_strncmp(left->characters + ft_strlen(left->characters) - ft_strlen(to_find), to_find, ft_strlen(to_find)) == 0); 1200 | return ret; 1201 | } 1202 | else 1203 | ft_fprintf(err, "%t has no attribute endswith\n", left->type); 1204 | } 1205 | if (type == base_) 1206 | { 1207 | if (left->type == number_) 1208 | { 1209 | // chekc if is array or string only 1210 | Value *base = evaluate(node->right->right); 1211 | Value *ret = ft_calloc(1, sizeof(Value)); 1212 | ret->type = characters_; 1213 | ret->characters = convert_base(left->number, base->characters); 1214 | // ft_printf(out, "return %k\n", ret); 1215 | return ret; 1216 | } 1217 | else 1218 | ft_fprintf(err, "%t has no attribute base\n", left->type); 1219 | } 1220 | output(left); 1221 | ft_fprintf(err, " has no attribute %s\n", left, type_to_string(type)); 1222 | break; 1223 | } 1224 | default: 1225 | ft_fprintf(err, "Error: eval received unknown type '%t' \n", node->token->type); 1226 | } 1227 | return NULL; 1228 | } 1229 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include "header.h" 2 | 3 | int exe_pos = 0; 4 | void execute() 5 | { 6 | current = ft_calloc(1, sizeof(List)); 7 | while (tokens[exe_pos]->type != eof_) 8 | { 9 | Node *curr = expr(); 10 | evaluate(curr); 11 | } 12 | } 13 | 14 | 15 | int main(int argc, char **argv) 16 | { 17 | FILE *fp = NULL; 18 | long file_size = 0; 19 | 20 | // open file and read it and feed the text 21 | fp = fopen(argv[1], "r"); 22 | if (fp == NULL) 23 | ft_fprintf(err, "Error openning file\n"); 24 | fseek(fp, 0, SEEK_END); 25 | file_size = ftell(fp); 26 | text = ft_calloc(file_size + 1, sizeof(char)); 27 | fseek(fp, 0, SEEK_SET); 28 | fread(text, file_size, sizeof(char), fp); 29 | fclose(fp); 30 | 31 | // start interpreting 32 | // ft_fprintf(out, "%s\n", text); 33 | 34 | // tokenize 35 | build_tokens(); 36 | tk_pos++; // verify it after 37 | execute(); 38 | my_free_all(); 39 | } 40 | 41 | -------------------------------------------------------------------------------- /parsing.c: -------------------------------------------------------------------------------- 1 | #include "header.h" 2 | 3 | // building Nodes 4 | 5 | Node *new_node(Token *token) 6 | { 7 | Node *new = ft_calloc(1, sizeof(Token)); 8 | new->token = token; 9 | see_token(new->token); 10 | return (new); 11 | } 12 | 13 | void skip(Type type) 14 | { 15 | if (tokens[exe_pos]->type != type) 16 | { 17 | // try getting back then print all those who have the same line attribute; 18 | ft_putchar(out, '\n'); 19 | txt_pos = tokens[exe_pos - 1]->txt_pos; 20 | while (txt_pos > 0 && text[txt_pos - 1] != '\n') 21 | txt_pos--; 22 | while (text[txt_pos] && text[txt_pos] != '\n') 23 | { 24 | ft_putchar(out, text[txt_pos]); 25 | txt_pos++; 26 | } 27 | ft_putchar(out, '\n'); 28 | print_space(tokens[exe_pos - 1]->column); 29 | ft_putstr(out, "^\n"); 30 | ft_fprintf(err, "syntax error: Expected '%t' in line '%d'\n", type, tokens[exe_pos - 1]->line); 31 | } 32 | exe_pos++; 33 | } 34 | 35 | bool check(Type to_find, ...) 36 | { 37 | va_list ap; 38 | va_start(ap, to_find); 39 | while (1) 40 | { 41 | Type type = va_arg(ap, Type); 42 | if (type == to_find) 43 | return true; 44 | if (type == 0) 45 | break; 46 | } 47 | return false; 48 | } 49 | 50 | // bloc 51 | Node **bloc(int tab) 52 | { 53 | if (tokens[exe_pos]->tab < tab) 54 | ft_fprintf(err, "syntax error: Expected %d tab in line '%d'\n", tokens[exe_pos - 1]->tab + 1, tokens[exe_pos]->line); 55 | int len = 0; 56 | Node **list = ft_calloc(len + 1, sizeof(Node *)); 57 | list[len] = expr(); 58 | len++; 59 | list = ft_realloc(list, (len) * sizeof(Node *), (len + 1) * sizeof(Node *)); 60 | while (tokens[exe_pos]->type != eof_ && tokens[exe_pos]->tab == tab) 61 | { 62 | list[len] = expr(); 63 | len++; 64 | list = ft_realloc(list, (len) * sizeof(Node *), (len + 1) * sizeof(Node *)); 65 | } 66 | list[len] = NULL; 67 | return list; 68 | } 69 | // expression 70 | Node *expr() 71 | { 72 | if (check(tokens[exe_pos]->type, return_, 0)) 73 | { 74 | Node *node = new_node(tokens[exe_pos]); 75 | skip(tokens[exe_pos]->type); 76 | node->token->bloc_head = bloc(node->token->tab + 1); 77 | return node; 78 | } 79 | return assign(); 80 | } 81 | // = += -= *= /= %= 82 | Node *assign() 83 | { 84 | Node *left = conditions(); 85 | if (check(tokens[exe_pos]->type, assign_, add_assign_, sub_assign_, mul_assign_, div_assign_, mod_assign_, 0)) 86 | { 87 | Node *node = new_node(tokens[exe_pos]); 88 | skip(tokens[exe_pos]->type); 89 | node->left = left; 90 | node->right = conditions(); 91 | return node; 92 | } 93 | return left; 94 | } 95 | // while, if, elif, else 96 | Node *conditions() 97 | { 98 | if (check(tokens[exe_pos]->type, if_, elif_, 0)) 99 | { 100 | Node *node = new_node(tokens[exe_pos]); 101 | skip(tokens[exe_pos]->type); 102 | 103 | // left is condition 104 | node->left = logic_or(); 105 | if (node->left == NULL) 106 | ft_fprintf(err, "Expected condition\n"); 107 | skip(dots_); 108 | 109 | // if bloc to execute 110 | node->token->bloc_head = bloc(node->token->tab + 1); 111 | if (check(tokens[exe_pos]->type, elif_, 0)) 112 | { 113 | node->right = conditions(); 114 | // edit level here of node->right 115 | } 116 | if (check(tokens[exe_pos]->type, else_, 0)) 117 | { 118 | node->right = new_node(tokens[exe_pos]); 119 | // edit level here of node->right 120 | skip(tokens[exe_pos]->type); 121 | skip(dots_); 122 | node->right->token->bloc_head = bloc(node->token->tab + 1); 123 | } 124 | return node; 125 | } 126 | else if (check(tokens[exe_pos]->type, while_, 0)) 127 | { 128 | Node *node = new_node(tokens[exe_pos]); 129 | skip(tokens[exe_pos]->type); 130 | 131 | // left is condition 132 | node->left = logic_or(); 133 | if (node->left == NULL) 134 | ft_fprintf(err, "Expected condition\n"); 135 | skip(dots_); 136 | 137 | // while bloc to execute 138 | node->token->bloc_head = bloc(node->token->tab + 1); 139 | return node; 140 | } 141 | else if (check(tokens[exe_pos]->type, for_, 0)) 142 | { 143 | Node *node = new_node(tokens[exe_pos]); 144 | skip(tokens[exe_pos]->type); 145 | 146 | // left is condition 147 | node->left = prime(); 148 | if (node->left->token->type != identifier_) 149 | ft_fprintf(err, "can't loop over %s\n", type_to_string(node->left->token->type)); 150 | skip(in_); 151 | // array to iterate over it 152 | node->right = prime(); 153 | skip(dots_); 154 | // bloc to execute 155 | node->token->bloc_head = bloc(node->token->tab + 1); 156 | return node; 157 | } 158 | return logic_or(); 159 | } 160 | 161 | // || or 162 | Node *logic_or() 163 | { 164 | Node *left = logic_and(); 165 | while (check(tokens[exe_pos]->type, or_, 0)) 166 | { 167 | Node *node = new_node(tokens[exe_pos]); 168 | skip(tokens[exe_pos]->type); 169 | node->left = left; 170 | node->right = logic_and(); 171 | left = node; 172 | } 173 | return left; 174 | } 175 | 176 | // && and 177 | Node *logic_and() 178 | { 179 | Node *left = equality(); 180 | while (check(tokens[exe_pos]->type, and_, 0)) 181 | { 182 | Node *node = new_node(tokens[exe_pos]); 183 | skip(tokens[exe_pos]->type); 184 | node->left = left; 185 | node->right = equality(); 186 | left = node; 187 | } 188 | return left; 189 | } 190 | 191 | // == != 192 | Node *equality() 193 | { 194 | Node *left = comparison(); 195 | while (check(tokens[exe_pos]->type, equal_, not_equal_, 0)) 196 | { 197 | Node *node = new_node(tokens[exe_pos]); 198 | skip(tokens[exe_pos]->type); 199 | node->left = left; 200 | node->right = comparison(); 201 | left = node; 202 | } 203 | return left; 204 | } 205 | 206 | // < > <= >= 207 | Node *comparison() 208 | { 209 | Node *left = add_sub(); 210 | while (check(tokens[exe_pos]->type, less_than_, more_than_, less_than_or_equal_, more_than_or_equal_, 0)) 211 | { 212 | Node *node = new_node(tokens[exe_pos]); 213 | skip(tokens[exe_pos]->type); 214 | node->left = left; 215 | node->right = add_sub(); 216 | left = node; 217 | } 218 | return left; 219 | } 220 | 221 | // + - 222 | Node *add_sub() 223 | { 224 | Node *left = mul_div(); 225 | while (check(tokens[exe_pos]->type, add_, sub_, 0)) 226 | { 227 | Node *node = new_node(tokens[exe_pos]); 228 | skip(tokens[exe_pos]->type); 229 | node->left = left; 230 | node->right = mul_div(); 231 | left = node; 232 | } 233 | return left; 234 | } 235 | 236 | // * / % 237 | Node *mul_div() 238 | { 239 | Node *left = sign(); 240 | while (check(tokens[exe_pos]->type, mul_, div_, mod_, 0)) 241 | { 242 | Node *node = new_node(tokens[exe_pos]); 243 | skip(tokens[exe_pos]->type); 244 | node->left = left; 245 | node->right = sign(); 246 | left = node; 247 | } 248 | return left; 249 | } 250 | 251 | // sign - 252 | Node *sign() 253 | { 254 | if (tokens[exe_pos]->type == sub_) 255 | { 256 | Node *node = new_node(tokens[exe_pos]); 257 | skip(tokens[exe_pos]->type); 258 | node->token->type = mul_; 259 | node->left = new_node(new_token(number_)); 260 | node->left->token->number = -1; 261 | node->right = iteration(); 262 | return node; 263 | } 264 | return iteration(); 265 | } 266 | 267 | // iteration 268 | Node *iteration() 269 | { 270 | Node *left = prime(); 271 | if (check(left->token->type, identifier_, characters_, func_call_, input_, 0) && (tokens[exe_pos]->type == lbracket_ || tokens[exe_pos]->type == dot_)) 272 | { 273 | while (tokens[exe_pos]->type == dot_ || tokens[exe_pos]->type == lbracket_) 274 | { 275 | // ft_printf(err, "%t\n", tokens[exe_pos]->type); 276 | while (tokens[exe_pos]->type == lbracket_) 277 | { 278 | Node *node = new_node(tokens[exe_pos]); 279 | skip(lbracket_); 280 | node->left = left; // element to iterate over it 281 | node->right = expr(); 282 | // if(tokens[exe_pos]->type == dots_) 283 | // node->right->token->type = att_type_; // it get declared as identifier 284 | skip(rbracket_); 285 | node->token->type = attribute_; 286 | left = node; 287 | } 288 | while (tokens[exe_pos]->type == dot_) 289 | { 290 | Node *node = new_node(tokens[exe_pos]); 291 | skip(dot_); 292 | node->left = left; // element to iterate over it 293 | node->right = prime(); 294 | if (node->right->token->type == identifier_) 295 | node->right->token->type = att_type_; // it get decared sometimes as identifier 296 | node->token->type = attribute_; 297 | left = node; 298 | } 299 | } 300 | } 301 | return left; 302 | } 303 | 304 | // primary 305 | Node *prime() 306 | { 307 | if (check(tokens[exe_pos]->type, lparent_, 0)) 308 | { 309 | skip(lparent_); 310 | Node *node = expr(); 311 | skip(rparent_); 312 | return node; 313 | } 314 | // function declaration 315 | if (check(tokens[exe_pos]->type, func_dec_, 0)) 316 | { 317 | // ft_fprintf(out, "found function declaration \n"); 318 | skip(func_dec_); 319 | Node *node = new_node(tokens[exe_pos]); 320 | skip(identifier_); 321 | node->token->type = func_dec_; 322 | // function parameters on left 323 | skip(lparent_); 324 | exe_pos--; 325 | // parameters 326 | node->left = parents(prime, identifier_, lparent_, rparent_); 327 | // expect : 328 | skip(dots_); 329 | // current is bloc of code to execute 330 | node->token->bloc_head = bloc(node->token->tab + 1); 331 | return node; 332 | } 333 | // we can't iterate over type_ number_ break_ continue_ 334 | if (check(tokens[exe_pos]->type, boolean_, number_, break_, continue_, 0)) 335 | { 336 | Node *node = new_node(tokens[exe_pos]); 337 | skip(tokens[exe_pos]->type); 338 | return node; 339 | } 340 | // we can iterate over string 341 | if (check(tokens[exe_pos]->type, characters_, 0)) 342 | { 343 | Node *node = new_node(tokens[exe_pos]); 344 | skip(characters_); 345 | return node; 346 | #if 0 347 | Node *left = node; 348 | // it's possible to iterate over characters 349 | while(tokens[exe_pos]->type == dot_ || tokens[exe_pos]->type == lbracket_) 350 | { 351 | // ft_printf(err, "%t\n", tokens[exe_pos]->type); 352 | while (tokens[exe_pos]->type == lbracket_) 353 | { 354 | node = new_node(tokens[exe_pos]); 355 | skip(lbracket_); 356 | node->left = left; // element to iterate over it 357 | node->right = expr(); 358 | node->right->token->type = att_type_; // it get declared as identifier 359 | skip(rbracket_); 360 | node->token->type = attribute_; 361 | left = node; 362 | } 363 | while (tokens[exe_pos]->type == dot_) 364 | { 365 | node = new_node(tokens[exe_pos]); 366 | skip(dot_); 367 | node->left = left; // element to iterate over it 368 | node->right = expr(); 369 | if(node->right->token->type == identifier_) 370 | node->right->token->type = att_type_; // it get decared sometimes as identifier 371 | node->token->type = attribute_; 372 | left = node; 373 | } 374 | } 375 | return left; 376 | #endif 377 | } 378 | // array 379 | if (check(tokens[exe_pos]->type, lbracket_, 0)) 380 | return (parents(assign, 0, lbracket_, rbracket_)); 381 | // object, check if you can optimize it 382 | if (check(tokens[exe_pos]->type, lcbracket_, 0)) 383 | { 384 | Node *node = new_node(tokens[exe_pos]); 385 | skip(lcbracket_); 386 | node->token->type = obj_; 387 | int i = 0; 388 | Node **list = NULL; 389 | char **keys = NULL; 390 | if (tokens[exe_pos]->type != rcbracket_) // enter if object is not empty 391 | { 392 | list = ft_calloc(i + 1, sizeof(Node *)); 393 | keys = ft_calloc(i + 1, sizeof(char *)); 394 | Token *identifier = tokens[exe_pos]; // expect identifier 395 | skip(identifier_); 396 | skip(dots_); // expect dots 397 | keys[i] = identifier->name; 398 | list[i] = add_sub(); 399 | i++; 400 | list = ft_realloc(list,(i ) * sizeof(Node *) ,(i + 1) * sizeof(Node *)); 401 | keys = ft_realloc(keys, (i ) * sizeof(char *), (i + 1) * sizeof(char *)); 402 | while (tokens[exe_pos]->type != rcbracket_ && tokens[exe_pos]->type != eof_) 403 | { 404 | skip(comma_); 405 | identifier = tokens[exe_pos]; // expect identifier 406 | skip(identifier_); 407 | skip(dots_); // expect dots : 408 | keys[i] = identifier->name; 409 | list[i] = add_sub(); 410 | i++; 411 | list = ft_realloc(list, (i) * sizeof(Node *) ,(i + 1) * sizeof(Node *)); 412 | keys = ft_realloc(keys, (i) * sizeof(char *), (i + 1) * sizeof(char *)); 413 | } 414 | } 415 | keys[i] = NULL; 416 | list[i] = NULL; 417 | skip(rcbracket_); 418 | node->token->keys = keys; 419 | node->token->object_head = list; 420 | return node; 421 | } 422 | // range 423 | if (check(tokens[exe_pos]->type, range_, 0)) 424 | { 425 | Node *node = new_node(tokens[exe_pos]); 426 | skip(range_); 427 | skip(lparent_); 428 | node->left = expr(); // maybe it shouldn't be expr 429 | skip(comma_); 430 | node->right = expr(); 431 | skip(rparent_); 432 | return node; 433 | } 434 | // built in attributes 435 | if (check(tokens[exe_pos]->type, indexof_, count_, split_, base_, trim_, starts_with_, ends_with_, 0)) 436 | { 437 | // call it and let iretun rigth value 438 | // and handle it in attribute 439 | Node *node = new_node(tokens[exe_pos]); 440 | skip(tokens[exe_pos]->type); 441 | skip(lparent_); 442 | node->right = expr(); // maybe it shouldn't be expr 443 | skip(rparent_); 444 | return node; 445 | } 446 | // output function 447 | if (check(tokens[exe_pos]->type, output_, input_, 0)) 448 | { 449 | Node *node = new_node(tokens[exe_pos]); 450 | Node **list = NULL; 451 | Type type = tokens[exe_pos]->type; 452 | 453 | skip(tokens[exe_pos]->type); 454 | skip(lparent_); 455 | if (tokens[exe_pos]->type == rparent_) 456 | ft_fprintf(err, "expected something to output\n"); 457 | exe_pos--; 458 | node->token = parents(expr, 0, lparent_, rparent_)->token; 459 | node->token->type = type; 460 | return node; 461 | #if 0 462 | Node *left = node; 463 | // to be verified 464 | while(tokens[exe_pos]->type == dot_ || tokens[exe_pos]->type == lbracket_) 465 | { 466 | //ft_printf(err, "%t\n", tokens[exe_pos]->type); 467 | while (tokens[exe_pos]->type == lbracket_) 468 | { 469 | Node *node = new_node(tokens[exe_pos]); 470 | skip(lbracket_); 471 | node->left = left; // element to iterate over it 472 | node->right = expr(); 473 | skip(rbracket_); 474 | node->token->type = attribute_; 475 | left = node; 476 | } 477 | while (tokens[exe_pos]->type == dot_) 478 | { 479 | Node *node = new_node(tokens[exe_pos]); 480 | skip(dot_); 481 | node->left = left; // element to iterate over it 482 | node->right = expr(); 483 | if(node->right->token->type == identifier_) 484 | node->right->token->type = att_type_; // it get decared sometimes as identifier 485 | node->token->type = attribute_; 486 | left = node; 487 | } 488 | } 489 | return left; 490 | #endif 491 | } 492 | // identifier 493 | if (check(tokens[exe_pos]->type, identifier_, 0)) 494 | { 495 | Node *node = new_node(tokens[exe_pos]); 496 | // Node *left = node; 497 | skip(identifier_); 498 | if (tokens[exe_pos]->type == lparent_) 499 | { 500 | node->token->type = func_call_; 501 | node->left = parents(expr, 0, lparent_, rparent_); 502 | // left = node; 503 | } 504 | return node; 505 | #if 0 506 | // iterate over identifier than can be array or stirng in future 507 | // or iterate over function in case function call 508 | while(tokens[exe_pos]->type == dot_ || tokens[exe_pos]->type == lbracket_) 509 | { 510 | // ft_printf(err, "%t\n", tokens[exe_pos]->type); 511 | while (tokens[exe_pos]->type == lbracket_) 512 | { 513 | Node *node = new_node(tokens[exe_pos]); 514 | skip(lbracket_); 515 | node->left = left; // element to iterate over it 516 | node->right = expr(); 517 | skip(rbracket_); 518 | node->token->type = attribute_; 519 | left = node; 520 | } 521 | while (tokens[exe_pos]->type == dot_) 522 | { 523 | Node *node = new_node(tokens[exe_pos]); 524 | skip(dot_); 525 | node->left = left; // element to iterate over it 526 | node->right = expr(); 527 | if(node->right->token->type == identifier_) 528 | node->right->token->type = att_type_; // it get decared sometimes as identifier 529 | node->token->type = attribute_; 530 | left = node; 531 | } 532 | } 533 | return left; 534 | #endif 535 | } 536 | ft_putchar(out, '\n'); 537 | txt_pos = tokens[exe_pos]->txt_pos; 538 | while (txt_pos > 0 && text[txt_pos - 1] != '\n') 539 | txt_pos--; 540 | while (text[txt_pos] && text[txt_pos] != '\n') 541 | { 542 | ft_putchar(out, text[txt_pos]); 543 | txt_pos++; 544 | } 545 | ft_putchar(out, '\n'); 546 | print_space(tokens[exe_pos - 1]->column); 547 | ft_putstr(out, "^\n"); 548 | ft_fprintf(err, "Error: Unexpected %s in line '%d'\n", type_to_string(tokens[exe_pos]->type), tokens[exe_pos]->line); 549 | 550 | return NULL; 551 | } 552 | 553 | // parentises 554 | Node *parents(Node *call_node(void), Type to_find, Type left_, Type right_) 555 | { 556 | if (check(tokens[exe_pos]->type, left_)) 557 | { 558 | Node *node = new_node(tokens[exe_pos]); 559 | skip(left_); 560 | node->token->type = array_; 561 | int i = 0; 562 | Node **array = ft_calloc(i + 1, sizeof(Node *)); 563 | if (tokens[exe_pos]->type != right_) // enter if there is params to hold 564 | { 565 | array[i] = call_node(); // to be checked after 566 | i++; 567 | array = ft_realloc(array, (i) * sizeof(Node *), (i + 1) * sizeof(Node *)); 568 | while (tokens[exe_pos]->type != right_ && tokens[exe_pos]->type != eof_) 569 | { 570 | skip(comma_); 571 | array[i] = call_node(); 572 | if (to_find && array[i]->token->type != to_find) 573 | ft_fprintf(err, "Error in parents\n"); 574 | i++; 575 | array = ft_realloc(array, (i) * sizeof(Node *), (i + 1) * sizeof(Node *)); 576 | } 577 | } 578 | array[i] = NULL; 579 | skip(right_); 580 | node->token->array_head = array; 581 | node->token->array_len = i; 582 | return node; 583 | } 584 | return NULL; 585 | } 586 | -------------------------------------------------------------------------------- /test_mini/atoi.mini: -------------------------------------------------------------------------------- 1 | func ft_atoi(str): 2 | return str.tonum 3 | 4 | str = input("enter a number: ") 5 | output(ft_atoi(str) * 2, "\n") -------------------------------------------------------------------------------- /test_mini/endswith.mini: -------------------------------------------------------------------------------- 1 | str1 = input("enter string: ") 2 | str2 = input("enter substring: ") 3 | 4 | output(str1.endswith(str2)) -------------------------------------------------------------------------------- /test_mini/increment.mini: -------------------------------------------------------------------------------- 1 | n = 0 2 | while n < 10: 3 | output(n, "\n") 4 | n += 1 -------------------------------------------------------------------------------- /test_mini/indexof.mini: -------------------------------------------------------------------------------- 1 | string = input("enter string: ") 2 | to_find = input("enter substring: ") 3 | output(string.indexof(to_find)) -------------------------------------------------------------------------------- /test_mini/is_negative.mini: -------------------------------------------------------------------------------- 1 | func is_negative(c): 2 | return c < 0 3 | 4 | x = is_negative(-1) 5 | output(x) -------------------------------------------------------------------------------- /test_mini/isalpha.mini: -------------------------------------------------------------------------------- 1 | str = input("enter string: ") 2 | output(str.ischar) -------------------------------------------------------------------------------- /test_mini/ischaracter.mini: -------------------------------------------------------------------------------- 1 | 2 | str = "abc" 3 | res = str.ischar 4 | output(res) -------------------------------------------------------------------------------- /test_mini/ischaracter2.mini: -------------------------------------------------------------------------------- 1 | str = "12345" 2 | res = str.ischar 3 | 4 | output(res, "\n") -------------------------------------------------------------------------------- /test_mini/isdigit.mini: -------------------------------------------------------------------------------- 1 | str = input("enter string: ") 2 | output(str.isnum) -------------------------------------------------------------------------------- /test_mini/isdigit2.mini: -------------------------------------------------------------------------------- 1 | 2 | str = "123" 3 | res = str.isnum 4 | output(res) -------------------------------------------------------------------------------- /test_mini/isuppercase.mini: -------------------------------------------------------------------------------- 1 | str = "ABCDE" 2 | res = str.isup 3 | output(res) -------------------------------------------------------------------------------- /test_mini/iteration.mini: -------------------------------------------------------------------------------- 1 | x = "abcdefghijklmnopqrstuvwxyz" 2 | i = 0 3 | while i < x.len: 4 | output(x[i]," ") 5 | i += 1 -------------------------------------------------------------------------------- /test_mini/itoa.mini: -------------------------------------------------------------------------------- 1 | num = 10 2 | str = num.tochar 3 | output("str is ", str, " has type: ", str.type) -------------------------------------------------------------------------------- /test_mini/memcpy.mini: -------------------------------------------------------------------------------- 1 | func memcpy(src, dest): 2 | i = 0 3 | output("src len is: ", src.len, "\n") 4 | while i < src.len and i < dest.len: 5 | dest[i] = src[i] 6 | i += 1 7 | while i < src.len: 8 | dest = dest + [src[i]] 9 | i += 1 10 | return dest 11 | 12 | res = memcpy([0, 1, 5], [7,8,9,10]) 13 | output(res) 14 | -------------------------------------------------------------------------------- /test_mini/memove.mini: -------------------------------------------------------------------------------- 1 | func memcpy(src, dest): 2 | i = 0 3 | output("src len is: ", src.len, "\n") 4 | while i < src.len and i < dest.len: 5 | dest[i] = src[i] 6 | output("i is: ", i, "\n") 7 | i += 1 8 | if i < src.len: 9 | if src[i].type == dest.type: 10 | output("i is: ", i, "\n") 11 | dest = dest + src[i] 12 | return dest 13 | 14 | func memove(src, dest, start): 15 | i = start 16 | while i < src.len: 17 | dest = dest + [src[i]] 18 | i += 1 19 | return dest 20 | 21 | array = [1, 2, 3, 4] 22 | dest = [] 23 | dest = memove(array, dest, 2) 24 | output(dest) 25 | -------------------------------------------------------------------------------- /test_mini/print_comb.mini: -------------------------------------------------------------------------------- 1 | 2 | func print_comb(): 3 | a = 0 4 | while a < 10: 5 | b = a + 1 6 | while b < 10: 7 | c = b + 1 8 | while c < 10: 9 | output(a,b,c," ") 10 | c += 1 11 | b += 1 12 | a += 1 13 | 14 | print_comb() -------------------------------------------------------------------------------- /test_mini/print_comb2.mini: -------------------------------------------------------------------------------- 1 | 2 | func make_comb(x, y): 3 | output(x/10, x%10, " ", y/10, y%10) 4 | if x != 98 or y != 99: 5 | output(", ") 6 | 7 | x = 0 8 | while x <= 99: 9 | y = x + 1 10 | while y <= 99: 11 | make_comb(x,y) 12 | y += 1 13 | x += 1 14 | -------------------------------------------------------------------------------- /test_mini/putnbrbase.mini: -------------------------------------------------------------------------------- 1 | num = 12 2 | output(num.base("0123456789ABCDEF")) -------------------------------------------------------------------------------- /test_mini/range.mini: -------------------------------------------------------------------------------- 1 | n = range(10, 25) 2 | output(n) -------------------------------------------------------------------------------- /test_mini/reverse_iteration.mini: -------------------------------------------------------------------------------- 1 | x = "abcdefghijklmnopqrstuvwxyz" 2 | i = x.len 3 | 4 | while i > 0: 5 | i -= 1 6 | output(x[i]) -------------------------------------------------------------------------------- /test_mini/split.mini: -------------------------------------------------------------------------------- 1 | str = "hello everyone I'm split attribute" 2 | res = str.split(" ") 3 | output(res) -------------------------------------------------------------------------------- /test_mini/startswith.mini: -------------------------------------------------------------------------------- 1 | str1 = input("enter string: ") 2 | str2 = input("enter substring: ") 3 | 4 | output(str1.startswith(str2)) -------------------------------------------------------------------------------- /test_mini/strcat.mini: -------------------------------------------------------------------------------- 1 | func concat(left, right): 2 | return left + right 3 | 4 | output(concat("abcd","efgh"), "\n") 5 | output(concat([1,2,3],[4,5,6]), "\n") 6 | -------------------------------------------------------------------------------- /test_mini/strcmp.mini: -------------------------------------------------------------------------------- 1 | func compare(left, right): 2 | return left == right 3 | 4 | output(compare("abcd","abcd")) -------------------------------------------------------------------------------- /test_mini/strcmp1.mini: -------------------------------------------------------------------------------- 1 | str1 = input("enter 1st string: ") 2 | str2 = input("enter 2nd string: ") 3 | 4 | output(str1 == str2) -------------------------------------------------------------------------------- /test_mini/strcpy.mini: -------------------------------------------------------------------------------- 1 | func ft_strcpy(dest, src): 2 | i = 0 3 | while i < src.len and i < dest.len: 4 | dest[i] = src[i] 5 | i += 1 6 | if i < src.len: 7 | dest = dest + src[i] 8 | return dest 9 | 10 | res = ft_strcpy("abcdefgh","123456") 11 | output("res: ",res, "\n") -------------------------------------------------------------------------------- /test_mini/strjoin.mini: -------------------------------------------------------------------------------- 1 | func strjoin(left, right): 2 | return left + right 3 | 4 | res = strjoin("abcdef", "ghijklm") 5 | output(res) -------------------------------------------------------------------------------- /test_mini/strjoin2.mini: -------------------------------------------------------------------------------- 1 | func strjoin(left, right): 2 | return left + right 3 | 4 | str1 = "hello" 5 | str2 = " world" 6 | output(strjoin(str1, str2)) 7 | -------------------------------------------------------------------------------- /test_mini/strlen.mini: -------------------------------------------------------------------------------- 1 | func ft_strlen(str): 2 | return str.len 3 | 4 | n = ft_strlen("hello") 5 | 6 | output("n: ", n) -------------------------------------------------------------------------------- /test_mini/strlen1.mini: -------------------------------------------------------------------------------- 1 | str = input("enter string: ") 2 | output(str.len) -------------------------------------------------------------------------------- /test_mini/strmap.mini: -------------------------------------------------------------------------------- 1 | s = "abcdefghi" 2 | 3 | for x in range(0, s.len): 4 | output("s[",x,"] is ", s[x], "\n") -------------------------------------------------------------------------------- /test_mini/strncpy.mini: -------------------------------------------------------------------------------- 1 | func ft_strncpy(dest, src, n): 2 | i = 0 3 | 4 | while i < src.len and i < dest.len and i < n: 5 | dest[i] = src[i] 6 | i += 1 7 | if i < src.len and i < n: 8 | dest = dest + src[i] 9 | return dest 10 | 11 | res = ft_strncpy("abcdefgh","123456", 2) 12 | output("res: ",res, "\n") -------------------------------------------------------------------------------- /test_mini/strstr.mini: -------------------------------------------------------------------------------- 1 | func ft_strstr(str, to_find): 2 | return str.indexof(to_find) 3 | 4 | str = "abcdef" 5 | i = ft_strstr(str, "ef") 6 | 7 | res = "" 8 | while i < str.len - 1: 9 | res += str[i] 10 | i+=1 11 | 12 | output( res ,"\n") 13 | -------------------------------------------------------------------------------- /test_mini/strtrim.mini: -------------------------------------------------------------------------------- 1 | str = "abcdefghab" 2 | output(str.trim("ab")) -------------------------------------------------------------------------------- /test_mini/tolower.mini: -------------------------------------------------------------------------------- 1 | str = "ABcD" 2 | 3 | output(str.tolow) -------------------------------------------------------------------------------- /test_mini/tolower1.mini: -------------------------------------------------------------------------------- 1 | str = input("enter string: ") 2 | output(str.tolow) -------------------------------------------------------------------------------- /test_mini/toupper.mini: -------------------------------------------------------------------------------- 1 | str = "abc" 2 | 3 | output(str.toup) -------------------------------------------------------------------------------- /test_mini/toupper1.mini: -------------------------------------------------------------------------------- 1 | str = input("enter string: ") 2 | output(str.toup) -------------------------------------------------------------------------------- /todo.md: -------------------------------------------------------------------------------- 1 | + I did convert float to fixed point, verify that -------------------------------------------------------------------------------- /tokenize.c: -------------------------------------------------------------------------------- 1 | #include "header.h" 2 | 3 | /*==============================Tokenizing==============================*/ 4 | // text 5 | char *text = NULL; 6 | int txt_pos = 0; 7 | 8 | // tokens 9 | Token **tokens = NULL; 10 | int tk_len = 50; 11 | int tk_pos = 0; 12 | 13 | // position in file 14 | int line = 1; 15 | int column = 0; 16 | int tab = 0; 17 | int start = 0; 18 | 19 | // tab space 20 | char *tab_space = " "; 21 | 22 | Token *new_token(Type type) 23 | { 24 | Token *new = ft_calloc(1, sizeof(Token)); 25 | new->type = type; 26 | new->line = line; 27 | new->column = txt_pos - column; 28 | new->txt_pos = txt_pos; 29 | new->tab = tab; 30 | switch (type) 31 | { 32 | case identifier_: 33 | { 34 | type = 0; 35 | char *value = ft_calloc(txt_pos - start + 1, sizeof(char)); 36 | ft_strncpy(value, text + start, txt_pos - start); 37 | for (int i = 0; alpha_tokens[i].name; i++) 38 | if (ft_strcmp(value, alpha_tokens[i].name) == 0) 39 | { 40 | type = alpha_tokens[i].type; 41 | break; 42 | } 43 | if (type) 44 | { 45 | new->type = type; 46 | if (type == boolean_) 47 | { 48 | if (ft_strcmp(value, "true") == 0) 49 | new->boolean = true; 50 | else if (ft_strcmp(value, "false") == 0) 51 | new->boolean = false; 52 | } 53 | } 54 | else 55 | new->name = value; 56 | break; 57 | } 58 | case characters_: 59 | { 60 | new->characters = ft_calloc(txt_pos - start + 1, sizeof(char)); 61 | ft_strncpy(new->characters, text + start, txt_pos - start); 62 | break; 63 | } 64 | case number_: 65 | { 66 | long long num = 0; 67 | int exponent = 0; 68 | int after_decimal = 0; // Flag to check if we're after a decimal point 69 | 70 | while (ft_isdigit(text[start]) || text[start] == '.') 71 | { 72 | if (text[start] == '.') 73 | { 74 | after_decimal = 1; 75 | start++; 76 | continue; 77 | } 78 | 79 | num = 10 * num + text[start] - '0'; 80 | start++; 81 | 82 | if (after_decimal) 83 | { 84 | exponent++; 85 | } 86 | } 87 | new->number = num; 88 | new->exponent = exponent; 89 | // printf("-> %llu\n", new->number); 90 | // printf("-> %d\n", new->exponent); 91 | // exit(0); 92 | break; 93 | } 94 | default: 95 | break; 96 | } 97 | if (tokens == NULL) 98 | tokens = ft_calloc(tk_len, sizeof(Token)); 99 | if (tk_pos + 10 == tk_len) 100 | { 101 | tokens = ft_realloc(tokens, tk_len * sizeof(Token *), 2 * tk_len * sizeof(Token *)); 102 | tk_len *= 2; 103 | } 104 | tokens[tk_pos] = new; 105 | tk_pos++; 106 | tokens[tk_pos] = NULL; 107 | see_token(new); 108 | start = 0; 109 | return new; 110 | } 111 | 112 | void build_tokens() 113 | { 114 | column = txt_pos; 115 | while (text[txt_pos]) 116 | { 117 | if (ft_strncmp(text + txt_pos, tab_space, ft_strlen(tab_space)) == 0) 118 | { 119 | txt_pos += ft_strlen(tab_space); 120 | tab++; 121 | continue; 122 | } 123 | if (ft_isspace(text[txt_pos])) 124 | { 125 | if (text[txt_pos] == '\n') 126 | { 127 | line++; 128 | tab = 0; 129 | column = txt_pos + 1; 130 | } 131 | txt_pos++; 132 | continue; 133 | } 134 | // skip comments /* */ 135 | if (ft_strncmp(text + txt_pos, "/*", ft_strlen("/*")) == 0) 136 | { 137 | txt_pos += ft_strlen("/*"); 138 | while (text[txt_pos] && ft_strncmp(text + txt_pos, "*/", ft_strlen("*/"))) 139 | txt_pos++; 140 | txt_pos += ft_strlen("*/"); 141 | continue; 142 | } 143 | // // skip comments / 144 | if (ft_strncmp(&text[txt_pos], "//", ft_strlen("//")) == 0) 145 | { 146 | while (text[txt_pos] && text[txt_pos] != '\n') 147 | txt_pos++; 148 | continue; 149 | } 150 | int type = 0; 151 | for (int i = 0; operators_tokens[i].name; i++) 152 | { 153 | if (ft_strncmp(operators_tokens[i].name, text + txt_pos, ft_strlen(operators_tokens[i].name)) == 0) 154 | { 155 | start = txt_pos; 156 | type = operators_tokens[i].type; 157 | txt_pos += ft_strlen(operators_tokens[i].name); 158 | new_token(type); 159 | break; 160 | } 161 | } 162 | if (type) 163 | { 164 | if (type == dots_) 165 | tab++; // for if statements and while loops ... 166 | continue; 167 | } 168 | if (ft_isalpha(text[txt_pos]) || text[txt_pos] == '_') 169 | { 170 | start = txt_pos; 171 | while (ft_isalnum(text[txt_pos]) || text[txt_pos] == '_') 172 | txt_pos++; 173 | Token *token = new_token(identifier_); 174 | if (token->type == return_) 175 | tab++; 176 | continue; 177 | } 178 | if (ft_isdigit(text[txt_pos])) 179 | { 180 | start = txt_pos; 181 | while (ft_isdigit(text[txt_pos])) 182 | txt_pos++; 183 | if (text[txt_pos] == '.') 184 | txt_pos++; 185 | while (ft_isdigit(text[txt_pos])) 186 | txt_pos++; 187 | new_token(number_); 188 | continue; 189 | } 190 | if (text[txt_pos] == '"' || text[txt_pos] == '\'') 191 | { 192 | start = txt_pos; 193 | txt_pos++; 194 | // ft_putchar(out, '\n'); 195 | while (text[txt_pos] && text[txt_pos] != text[start]) 196 | txt_pos++; 197 | if (text[txt_pos] != text[start]) 198 | { 199 | ft_putchar(out, '\n'); 200 | while (txt_pos > 0 && text[txt_pos - 1] != '\n') 201 | txt_pos--; 202 | int i = txt_pos; 203 | while (text[txt_pos] && text[txt_pos] != '\n') 204 | { 205 | ft_putchar(out, text[txt_pos]); 206 | txt_pos++; 207 | } 208 | ft_putchar(out, '\n'); 209 | print_space(txt_pos - i); 210 | ft_putstr(out, "^\n"); 211 | ft_fprintf(err, "Syntax error expected '%c'\n", text[start]); 212 | } 213 | start++; 214 | new_token(characters_); 215 | txt_pos++; 216 | continue; 217 | } 218 | if (text[txt_pos]) 219 | { 220 | ft_printf("found this '%c'\n", text[txt_pos]); 221 | ft_putchar(out, '\n'); 222 | while (txt_pos > 0 && text[txt_pos - 1] != '\n') 223 | txt_pos--; 224 | int i = txt_pos; 225 | while (text[txt_pos] && text[txt_pos] != '\n') 226 | { 227 | ft_putchar(out, text[txt_pos]); 228 | txt_pos++; 229 | } 230 | ft_putchar(out, '\n'); 231 | print_space(txt_pos - i); 232 | ft_putstr(out, "^\n"); 233 | ft_fprintf(err, "Syntax error\n"); 234 | } 235 | } 236 | new_token(eof_); 237 | } --------------------------------------------------------------------------------