diff --git a/Makefile b/Makefile index d09ff10..6afad06 100644 --- a/Makefile +++ b/Makefile @@ -43,6 +43,7 @@ SRCS = main.c \ parser.c \ reducer.c \ errors.c \ + printer.c \ print_enums.c # COMPILATION CONFIG : @@ -97,16 +98,24 @@ $(NAME): $(OBJS) $(CC) $(OBJS) -o $@ $(LFLAGS) run: $(NAME) - @echo $(B_PURPLE)"\n---------------------------------------------\n1. run with flag '-d' as last \n"$(RESET) - ./$(NAME) "3.4 * x^2 + 1 * x^1 - 2.0 * x^0 = 5.123 * x^1" -d @echo $(B_PURPLE)"\n---------------------------------------------\n2. run without flag \n"$(RESET) - ./$(NAME) "3 * x^2 + 5 * x^1 - 2 * x^0 = 5 * x^1" + -./$(NAME) "3 * x^2 + 5 * x^1 - 2 * x^0 = 5 * x^1" + @echo $(B_PURPLE)"\n---------------------------------------------\n1. run with flag '-d' as last \n"$(RESET) + -./$(NAME) "3.4 * x^2 + 1 * x^1 - 2.0 * x^0 = 5 * x^1" -d @echo $(B_PURPLE)"\n---------------------------------------------\n3. run with flag '-d' as first \n"$(RESET) - ./$(NAME) -d "3*x^2 + 2*x = 0" - @echo $(B_PURPLE)"\n---------------------------------------------\n4. run with wrong flag '-e' \n"$(RESET) - -./$(NAME) -d -e "3*x^2 + 2*x -7x^4 = x^4" - @echo $(B_PURPLE)"\n---------------------------------------------\n5. run \n"$(RESET) - ./$(NAME) -d "3*x^2 + 2*x -7x^3 = x^3" + -./$(NAME) -d "3 * x^2 + 2 * x^2 = 5 * x^1" + @echo $(B_PURPLE)"\n---------------------------------------------\n4. run with wrong flag '-e' SHOULD FAIL \n"$(RESET) + -./$(NAME) -d -e "3 * x^2 + 2 * x - 7 * x^4 = 1 * x^4" + @echo $(B_PURPLE)"\n---------------------------------------------\n3. run with free form \n"$(RESET) + -./$(NAME) -d "3*x^2 + 2x = 0" + @echo $(B_PURPLE)"\n---------------------------------------------\n1. run with float coefficient \n"$(RESET) + -./$(NAME) -d "3.4 * x^2 + 1 * x^1 - 2.0 * x^0 = 5.123 * x^1" + @echo $(B_PURPLE)"\n---------------------------------------------\n1. run with float exponent SHOULD FAILS \n"$(RESET) + -./$(NAME) -d "3.4 * x^2 + 1 * x^1 - 2.0 * x^0 = 5 * x^1.2" + @echo $(B_PURPLE)"\n---------------------------------------------\n4. run with power 4 \n"$(RESET) + -./$(NAME) -d "3x^2 + 2x -7x^4 = x^4" + @echo $(B_PURPLE)"\n---------------------------------------------\n5. run with utf8 \n"$(RESET) + -./$(NAME) -d "3x² + 2x -7x³ = x³" clean: $(RM_OBJS) diff --git a/headers/computorv1.h b/headers/computorv1.h index dcdf228..ee26856 100644 --- a/headers/computorv1.h +++ b/headers/computorv1.h @@ -10,9 +10,6 @@ #include // for errno #include // for strerror -#include -#include // For tcflush() and TCIFLUSH - /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * MAIN.C */ @@ -36,16 +33,17 @@ void launch_computorv1(char *input); typedef enum { - TOKEN_VARIABLE, // x, y, etc. - TOKEN_NUMBER_INT, // int - TOKEN_NUMBER_DOUBLE, // double - TOKEN_POWER, // ^ or ** - TOKEN_SIGN_PLUS, // + - TOKEN_SIGN_MINUS, // - - TOKEN_FACTOR_MULT, // * - TOKEN_FACTOR_DIV, // / or : - TOKEN_EQUAL, // = - TOKEN_END // null (end of input) + TOKEN_VARIABLE, // x, y, etc. + TOKEN_NUMBER_INT, // int + TOKEN_NUMBER_DOUBLE, // double + TOKEN_NUMBER_INT_SUPER, // superscript int, like '²' + TOKEN_POWER, // ^ or ** + TOKEN_SIGN_PLUS, // + + TOKEN_SIGN_MINUS, // - + TOKEN_FACTOR_MULT, // * + TOKEN_FACTOR_DIV, // / or : + TOKEN_EQUAL, // = + TOKEN_END // null (end of input) } e_token_type; typedef enum @@ -120,6 +118,12 @@ const char *token_tag_to_str(e_token_tag tag); const char *term_position_to_str(e_term_position pos); const char *term_sign_to_str(e_term_sign sign); +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * UTILS/PRINTER.C + */ + +void print_debug(const char *description, ...); + /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * GLOBALS */ diff --git a/libft b/libft index b64ede5..f93c635 160000 --- a/libft +++ b/libft @@ -1 +1 @@ -Subproject commit b64ede50af8fd14ff7a55be6fbba2f34a7aa8a3e +Subproject commit f93c635234a70984bcd35d2f382a4dc67d94ba67 diff --git a/src/launcher.c b/src/launcher.c index 7206aa1..f8073b3 100644 --- a/src/launcher.c +++ b/src/launcher.c @@ -1,4 +1,4 @@ -/* computorv1.c */ +/* launcher.c */ #include "computorv1.h" @@ -110,8 +110,8 @@ void launch_computorv1(char *input) remove_spaces(input); // lexerize - arg_len = ft_strlen(input) + 1; // +1 for last END token - // ft_printf("-> tokens[%i]\n", arg_len); // debug + arg_len = ft_strlen(input) + 1; // +1 for last END token + print_debug("\n-> tokens[%i]\n", arg_len); // debug s_token tokens[arg_len]; tokens_g_err = tokens; tokens_fill_null(tokens, arg_len); @@ -123,7 +123,7 @@ void launch_computorv1(char *input) // parse terms_count_prediction = count_any_of(input, "-+=") + 2; // +1 for first term that can have no leading '+', +1 for last term == NULL - // ft_printf("-> terms[%i]\n", terms_count_prediction); // debug + print_debug("-> terms[%i]\n\n", terms_count_prediction); // debug s_term terms[terms_count_prediction]; terms_g_err = terms; terms_fill_null(terms, terms_count_prediction); @@ -141,6 +141,8 @@ void launch_computorv1(char *input) polynom_fill_null(polynom, max_exponent); reduce(terms, polynom); + // solve + // debug print_state(); } diff --git a/src/lexer.c b/src/lexer.c index 040cffe..977dd66 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -100,6 +100,42 @@ static bool token_is_number_double(const char *input, int input_pos, int *token_ return true; } +// token is superscript int (e.g., ², ³, ⁴, ⁵, etc.) +static bool token_is_number_int_super(const char *input, int input_pos, int *token_size) +{ + int digit_size = 0; + int number_size = 0; + int max_number_size = 16; // same max size as regular integers + + // check if first character is superscript + if (!ft_isdigit_superscript(input + input_pos, NULL)) + { + return false; + } + + // iterate to find full superscript number + while (number_size < max_number_size) + { + if (ft_isdigit_superscript(input + input_pos + number_size, &digit_size)) + { + // Increment by the length of the UTF-8 character (2 or 3 bytes) + number_size += digit_size; + } + else + { + break; + } + } + + if (number_size == 0) + { + return false; + } + + *token_size = number_size; + return true; +} + // token is '^' or "**" static bool token_is_power(const char *input, int input_pos, int *token_size) { @@ -214,6 +250,12 @@ int lexerize(const char *input, s_token *tokens) tokens[tokens_count].tag = TOKEN_NUMBER; tokens[tokens_count].value_double = ft_atof(&input[input_pos]); } + else if (token_is_number_int_super(input, input_pos, &token_size)) + { + tokens[tokens_count].type = TOKEN_NUMBER_INT_SUPER; + tokens[tokens_count].tag = TOKEN_NUMBER; + tokens[tokens_count].value_int = ft_atoi_superscript(&input[input_pos]); + } else if (token_is_power(input, input_pos, &token_size)) { tokens[tokens_count].type = TOKEN_POWER; diff --git a/src/parser.c b/src/parser.c index a78cb5f..a89e1b7 100644 --- a/src/parser.c +++ b/src/parser.c @@ -54,7 +54,7 @@ static double get_double_value(s_token token) return token.value_int; } -static double get_coefficient_absolute(s_token *tokens, int i, int *token_count) +static double get_coefficient(s_token *tokens, int i, int *token_count) { double coefficient; @@ -140,13 +140,18 @@ static int get_exponent(s_token *tokens, int i, int *token_count) return 0; } - // then get power sign '^' + // then get power sign '^' or directly superscript power like '²' if (tokens[i].type == TOKEN_POWER) { i++; *token_count += 1; } - // else if (tokens[i].type == TOKEN_NUMBER_INT_POWER){} + else if (tokens[i].type == TOKEN_NUMBER_INT_SUPER) + { + *token_count += 1; + // return exponent directly + return tokens[i].value_int; + } else { // if token is 'x' not followed by '^' -> it's an exponent 1 @@ -201,13 +206,15 @@ int parse(s_token *tokens, s_term *terms, int terms_count_max) check_variables(tokens); + print_debug("PARSER STEPS :\n"); // debug + terms_count = 0; token_count = 0; i = 0; term_position = TERM_LEFT; while (tokens[i].type != TOKEN_END && terms_count < terms_count_max) { - // ft_printf("- token[%i]\n", i); // debug + print_debug("- token[%i]\n", i); // debug // equal if (tokens[i].type == TOKEN_EQUAL) @@ -229,19 +236,19 @@ int parse(s_token *tokens, s_term *terms, int terms_count_max) sign = -1; } i += token_count; - // ft_printf("term[%i] get_sign: (%i)[%s], token_count: [%d]\n", terms_count, ret_sign, term_sign_to_str(ret_sign), token_count); // debug + print_debug("term[%i] get_sign: (%i)[%s], token_count: [%d]\n", terms_count, ret_sign, term_sign_to_str(ret_sign), token_count); // debug // coefficient - double ret_coefficient = get_coefficient_absolute(tokens, i, &token_count); + double ret_coefficient = get_coefficient(tokens, i, &token_count); terms[terms_count].coefficient = ret_coefficient * sign; i += token_count; - // printf("term[%i] get_coefficient: [%g], token_count: [%d]\n", terms_count, ret_coefficient, token_count); // debug + print_debug("term[%i] get_coefficient: [%g], token_count: [%d]\n", terms_count, ret_coefficient, token_count); // debug // exponent int ret_exponent = get_exponent(tokens, i, &token_count); terms[terms_count].exponent = ret_exponent; i += token_count; - // ft_printf("term[%i] get_exponent: [%i], token_count: [%d]\n", terms_count, ret_exponent, token_count); // debug + print_debug("term[%i] get_exponent: [%i], token_count: [%d]\n", terms_count, ret_exponent, token_count); // debug terms_count++; } diff --git a/src/utils/errors.c b/src/utils/errors.c index f9882c1..66e1e85 100644 --- a/src/utils/errors.c +++ b/src/utils/errors.c @@ -18,25 +18,27 @@ static void print_context_tokens() ft_dprintf(STDERR_FILENO, "token[%2i] - type : ", i); if (tokens_g_err[i].type == TOKEN_VARIABLE) - ft_dprintf(STDERR_FILENO, "%20s", "TOKEN_VARIABLE"); + ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_VARIABLE"); else if (tokens_g_err[i].type == TOKEN_NUMBER_INT) - ft_dprintf(STDERR_FILENO, "%20s", "TOKEN_NUMBER_INT"); + ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_NUMBER_INT"); + else if (tokens_g_err[i].type == TOKEN_NUMBER_INT_SUPER) + ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_NUMBER_INT_SUPER"); else if (tokens_g_err[i].type == TOKEN_NUMBER_DOUBLE) - ft_dprintf(STDERR_FILENO, "%20s", "TOKEN_NUMBER_DOUBLE"); + ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_NUMBER_DOUBLE"); else if (tokens_g_err[i].type == TOKEN_POWER) - ft_dprintf(STDERR_FILENO, "%20s", "TOKEN_POWER"); + ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_POWER"); else if (tokens_g_err[i].type == TOKEN_SIGN_PLUS) - ft_dprintf(STDERR_FILENO, "%20s", "TOKEN_SIGN_PLUS"); + ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_SIGN_PLUS"); else if (tokens_g_err[i].type == TOKEN_SIGN_MINUS) - ft_dprintf(STDERR_FILENO, "%20s", "TOKEN_SIGN_MINUS"); + ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_SIGN_MINUS"); else if (tokens_g_err[i].type == TOKEN_FACTOR_MULT) - ft_dprintf(STDERR_FILENO, "%20s", "TOKEN_FACTOR_MULT"); + ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_FACTOR_MULT"); else if (tokens_g_err[i].type == TOKEN_FACTOR_DIV) - ft_dprintf(STDERR_FILENO, "%20s", "TOKEN_FACTOR_DIV"); + ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_FACTOR_DIV"); else if (tokens_g_err[i].type == TOKEN_EQUAL) - ft_dprintf(STDERR_FILENO, "%20s", "TOKEN_EQUAL"); + ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_EQUAL"); else if (tokens_g_err[i].type == TOKEN_END) - ft_dprintf(STDERR_FILENO, "%20s", "TOKEN_END"); + ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_END"); ft_putstr(" - value : "); @@ -44,6 +46,10 @@ static void print_context_tokens() { ft_dprintf(STDERR_FILENO, "%i\n", tokens_g_err[i].value_int); } + else if (tokens_g_err[i].type == TOKEN_NUMBER_INT_SUPER) + { + ft_dprintf(STDERR_FILENO, "%i\n", tokens_g_err[i].value_int); + } else if (tokens_g_err[i].type == TOKEN_NUMBER_DOUBLE) { dprintf(STDERR_FILENO, "%g\n", tokens_g_err[i].value_double); diff --git a/src/utils/printer.c b/src/utils/printer.c new file mode 100644 index 0000000..f6f8b98 --- /dev/null +++ b/src/utils/printer.c @@ -0,0 +1,16 @@ +/* printer.c */ + +#include "computorv1.h" + +void print_debug(const char *description, ...) +{ + if (!flag_debug_mode) + return; + + // print the formatted description + va_list args; + va_start(args, description); + // ft_vdprintf(STDOUT_FILENO, description, args); + vdprintf(STDOUT_FILENO, description, args); + va_end(args); +} \ No newline at end of file