diff --git a/headers/errors.h b/headers/errors.h index 49ef8e2..0034387 100644 --- a/headers/errors.h +++ b/headers/errors.h @@ -1,17 +1,17 @@ #ifndef ERRORS_H #define ERRORS_H -#include "../libft/includes/libft.h" - typedef enum { - ERROR_BASIC = 0, - ERROR_UNKNOWN_TOKEN = -1, - ERROR_NUMBER_TOO_BIG = -2, - ERROR_PARSING = -3, - ERROR_TOKEN_POSITION = -4, + ERROR_BASE = 1, // Start at 1 to avoid exit(0) for errors + ERROR_UNKNOWN_TOKEN, + ERROR_NUMBER_TOO_BIG, + ERROR_PARSING, + ERROR_TOKEN_POSITION, + ERROR_VAR_DIFF, + ERROR_SENTINEL, } program_error; -int stop_errors(program_error err, const char *details); +int stop_errors(program_error err, const char *format, ...); #endif \ No newline at end of file diff --git a/libft b/libft index f86c2cf..b64ede5 160000 --- a/libft +++ b/libft @@ -1 +1 @@ -Subproject commit f86c2cf5cb805cb2bf863b27d42169c5b1f0ccd2 +Subproject commit b64ede50af8fd14ff7a55be6fbba2f34a7aa8a3e diff --git a/src/errors.c b/src/errors.c index d8a7b84..f298822 100644 --- a/src/errors.c +++ b/src/errors.c @@ -1,27 +1,38 @@ #include "errors.h" +#include "libft.h" +#include -int stop_errors(program_error err, const char *details) +int stop_errors(program_error err, const char *details, ...) { - switch (err) + // the base error message + const char *msg = "error: error type is out of range"; + + // Map error codes to messages + const char *error_messages[] = { + [ERROR_BASE] = "error: undefined error, details :", + [ERROR_UNKNOWN_TOKEN] = "error: unknown token, details :", + [ERROR_NUMBER_TOO_BIG] = "error: number is too big, details :", + [ERROR_PARSING] = "error: too much terms to parse, details :", + [ERROR_TOKEN_POSITION] = "error: token position is not good in grammar, details :", + [ERROR_VAR_DIFF] = "error: expression must only contain one variable, details :", + // ⚠️ Add new error messages here when adding new error codes! + }; + + // Override msg if err is in the error_messages array + if (err >= ERROR_BASE && err < ERROR_SENTINEL) { - case ERROR_UNKNOWN_TOKEN: - ft_putstr_fd("error: unknown token, details : ", STDERR_FILENO); - break; - case ERROR_NUMBER_TOO_BIG: - ft_putstr_fd("error: number is too big, details : ", STDERR_FILENO); - break; - case ERROR_PARSING: - ft_putstr_fd("error: too much terms to parse, details : ", STDERR_FILENO); - break; - case ERROR_TOKEN_POSITION: - ft_putstr_fd("error: token position is not good in grammar, details : ", STDERR_FILENO); - break; - default: - ft_putstr_fd("unknown error, details : ", STDERR_FILENO); - break; + msg = error_messages[err]; } - ft_putstr_fd(details, STDERR_FILENO); + // Print the base message + ft_dprintf(STDERR_FILENO, "%s (%i) - ", msg, err); + + // Print the formatted details directly + va_list args; + va_start(args, details); + ft_vdprintf(STDERR_FILENO, details, args); + va_end(args); + ft_putchar_fd('\n', STDERR_FILENO); exit(err); diff --git a/src/parser.c b/src/parser.c index 7079237..4c0f3b8 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,15 +1,16 @@ #include "parser.h" /** - TOKEN_VARIABLE, // x, y, etc. - TOKEN_NUMBER_INT, // int - TOKEN_NUMBER_DOUBLE, // double - TOKEN_POWER, // ^ or ** - TOKEN_SIGN, // + or - - TOKEN_MULTIPLICATION, // * - TOKEN_DIVISION, // / - TOKEN_EQUAL, // = - TOKEN_END // null (end of input) + 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) 1. VAR | NUMBER_I | NUMBER_D | ! POW | SIGN_P | SIGN_M | ! FACTOR_MUL | ! FACTOR_DIV | ! EQUAL | END NT | NUMBER | NT | SIGN | ! FACTOR | NT | NT @@ -17,8 +18,8 @@ 2. VAR | NUMBER_I | NUMBER_D | ! POW | ! SIGN_P | ! SIGN_M | ! FACTOR_MUL | ! FACTOR_DIV | ! EQUAL | END NT | NUMBER | NT | ! SIGN | ! FACTOR | NT | NT - 3. VAR | NUMBER_I | NUMBER_D | ! POW | SIGN_P | SIGN_M | FACTOR_MUL | FACTOR_DIV | EQUAL | END - NT | NUMBER | NT | SIGN | FACTOR | NT | NT + 3. VAR | ! NUMBER_I | ! NUMBER_D | ! POW | ! SIGN_P | ! SIGN_M | FACTOR_MUL | ! FACTOR_DIV | ! EQUAL | END + NT | ! NUMBER | NT | ! SIGN | FACTOR | NT | NT term_position position; term_sign sign; @@ -32,15 +33,15 @@ static term_sign get_sign(token *tokens, int i, int *token_count) // forbidden tokens if (tokens[i].type == TOKEN_POWER) { - stop_errors(ERROR_TOKEN_POSITION, "at begining of term, we should not have a power token : " + tokens[i].value_char); + stop_errors(ERROR_TOKEN_POSITION, "at sign place, we should not have a token 'power' : %c", tokens[i].value_char); } if (tokens[i].tag == TOKEN_FACTOR) { - stop_errors(ERROR_TOKEN_POSITION, "at begining of term, we should not have a factor token : " + tokens[i].value_char); + stop_errors(ERROR_TOKEN_POSITION, "at sign place, we should not have a token 'factor' : %c", tokens[i].value_char); } if (tokens[i].type == TOKEN_EQUAL) { - stop_errors(ERROR_TOKEN_POSITION, "at begining of term, we should not have an equal token : " + tokens[i].value_char); + stop_errors(ERROR_TOKEN_POSITION, "at sign place, we should not have a token 'equal' : %c", tokens[i].value_char); } // sign @@ -60,7 +61,7 @@ static term_sign get_sign(token *tokens, int i, int *token_count) return '+'; } - return stop_errors(ERROR_TOKEN_POSITION, "at begining of term, we should have a sign token " + tokens[i].value_char); + return stop_errors(ERROR_TOKEN_POSITION, "at begining of term, we should have a token 'sign' : %c", tokens[i].value_char); } static double get_coefficient(token *tokens, int i, int *token_count) @@ -72,19 +73,19 @@ static double get_coefficient(token *tokens, int i, int *token_count) // forbidden tokens if (tokens[i].type == TOKEN_POWER) { - stop_errors(ERROR_TOKEN_POSITION, "at coefficient place, we should not have a power token : " + tokens[i].value_char); + stop_errors(ERROR_TOKEN_POSITION, "at coefficient place, we should not have a token 'power' : %c", tokens[i].value_char); } if (tokens[i].tag == TOKEN_FACTOR) { - stop_errors(ERROR_TOKEN_POSITION, "at coefficient place, we should not have a factor token : " + tokens[i].value_char); + stop_errors(ERROR_TOKEN_POSITION, "at coefficient place, we should not have a token 'factor' : %c", tokens[i].value_char); } if (tokens[i].type == TOKEN_EQUAL) { - stop_errors(ERROR_TOKEN_POSITION, "at coefficient place, we should not have an equal token : " + tokens[i].value_char); + stop_errors(ERROR_TOKEN_POSITION, "at coefficient place, we should not have a token 'equal' : %c", tokens[i].value_char); } if (tokens[i].tag == TOKEN_SIGN) { - stop_errors(ERROR_TOKEN_POSITION, "at coefficient place, we should not have a sign token : " + tokens[i].value_char); + stop_errors(ERROR_TOKEN_POSITION, "at coefficient place, we should not have a token 'sign' : %c", tokens[i].value_char); } // if not coefficient token @@ -128,9 +129,41 @@ static double get_coefficient(token *tokens, int i, int *token_count) static int get_exponent(token *tokens, int i, int *token_count) { - if (tokens[i].type) // placeholder - *token_count = 1; // placeholder - return 1; // placeholder + /** + * power + * number + * sign + * equal + * factor_div + */ + // forbidden tokens + if (tokens[i].type == TOKEN_POWER) + { + stop_errors(ERROR_TOKEN_POSITION, "at exponent place, we should not have a token 'power' : %c", tokens[i].value_char); + } + if (tokens[i].tag == TOKEN_NUMBER) + { + stop_errors(ERROR_TOKEN_POSITION, "at exponent place, we should not have a token 'number' : %c", tokens[i].value_char); + } + if (tokens[i].tag == TOKEN_SIGN) + { + stop_errors(ERROR_TOKEN_POSITION, "at exponent place, we should not have a token 'sign' : %c", tokens[i].value_char); + } + if (tokens[i].type == TOKEN_EQUAL) + { + stop_errors(ERROR_TOKEN_POSITION, "at exponent place, we should not have a token 'equal' : %c", tokens[i].value_char); + } + if (tokens[i].type == TOKEN_FACTOR_DIV) + { + stop_errors(ERROR_TOKEN_POSITION, "at exponent place, we should not have a token 'division' : %c", tokens[i].value_char); + } + + // if 'var' -> token_count + 1 + // else if '*' + 'var' -> token_count + 2 + + token_count += 0; // placeholder + + return 1; // placeholder } int parse(token *tokens, term *terms, int terms_count_max) @@ -139,13 +172,29 @@ int parse(token *tokens, term *terms, int terms_count_max) int terms_count; int token_count; term_position term_position; + char var; terms_count = 0; token_count = 0; i = 0; term_position = TERM_LEFT; + var = 0; while (tokens[i].type != TOKEN_END && terms_count < terms_count_max) { + // variable -> all variables must be the same + if (tokens[i].type == TOKEN_VARIABLE) + { + if (!var) + { + var = tokens[i].value_char; + } + else if (var != tokens[i].value_char) + { + stop_errors(ERROR_VAR_DIFF, "old var : '%c' - new var : '%c'", var, tokens[i].value_char); + } + } + + // equal if (tokens[i].type == TOKEN_EQUAL) { term_position = TERM_RIGHT;