handle superscript powers
This commit is contained in:
25
Makefile
25
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)
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
#include <errno.h> // for errno
|
||||
#include <string.h> // for strerror
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <termios.h> // For tcflush() and TCIFLUSH
|
||||
|
||||
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* MAIN.C
|
||||
*/
|
||||
@@ -39,6 +36,7 @@ typedef enum
|
||||
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, // -
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
2
libft
2
libft
Submodule libft updated: b64ede50af...f93c635234
@@ -1,4 +1,4 @@
|
||||
/* computorv1.c */
|
||||
/* launcher.c */
|
||||
|
||||
#include "computorv1.h"
|
||||
|
||||
@@ -111,7 +111,7 @@ void launch_computorv1(char *input)
|
||||
|
||||
// lexerize
|
||||
arg_len = ft_strlen(input) + 1; // +1 for last END token
|
||||
// ft_printf("-> tokens[%i]\n", arg_len); // debug
|
||||
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();
|
||||
}
|
||||
|
||||
42
src/lexer.c
42
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;
|
||||
|
||||
23
src/parser.c
23
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++;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
16
src/utils/printer.c
Normal file
16
src/utils/printer.c
Normal file
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user