fix number tokens and limits
This commit is contained in:
@@ -91,7 +91,7 @@ void launch_computorv1(char *input)
|
||||
int max_exponent;
|
||||
int nbr_of_exponents;
|
||||
int degree;
|
||||
size_t arg_len;
|
||||
size_t token_len;
|
||||
size_t terms_count_prediction;
|
||||
|
||||
// init
|
||||
@@ -99,9 +99,9 @@ void launch_computorv1(char *input)
|
||||
remove_spaces(input);
|
||||
|
||||
// lexerize
|
||||
arg_len = ft_strlen(input) + 1; // +1 for last END token
|
||||
print_debug("\n-> tokens[%i]\n", arg_len);
|
||||
s_token tokens[arg_len];
|
||||
token_len = ft_strlen(input) + 1; // +1 for last END token
|
||||
print_debug("\n-> tokens[%i]\n", token_len);
|
||||
s_token tokens[token_len];
|
||||
tokens_g_err = tokens;
|
||||
ft_bzero(tokens, sizeof(tokens));
|
||||
lexerize(input, tokens);
|
||||
|
||||
522
src/lexer.c
522
src/lexer.c
@@ -2,316 +2,344 @@
|
||||
|
||||
#include "computorv1.h"
|
||||
|
||||
/**
|
||||
* INT CHECKS
|
||||
*/
|
||||
|
||||
static bool is_number_bigger_than_int_max(const char *input, int size)
|
||||
{
|
||||
const char *int_max_str = "2147483647";
|
||||
int int_max_len = ft_strlen(int_max_str);
|
||||
|
||||
if (size < int_max_len)
|
||||
return false;
|
||||
if (size > int_max_len)
|
||||
return true;
|
||||
|
||||
return ft_strncmp(input, int_max_str, int_max_len) > 0;
|
||||
}
|
||||
static bool is_number_smaller_than_int_min(const char *input, int size)
|
||||
{
|
||||
const char *int_min_str = "-2147483648";
|
||||
int int_min_len = ft_strlen(int_min_str);
|
||||
|
||||
if (size < int_min_len)
|
||||
return false;
|
||||
if (size > int_min_len)
|
||||
return true;
|
||||
|
||||
return ft_strncmp(input, int_min_str, int_min_len) < 0;
|
||||
}
|
||||
static bool is_number_out_of_int_range(const char *input, int size)
|
||||
{
|
||||
if (input[0] == '-')
|
||||
{
|
||||
return is_number_smaller_than_int_min(input, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
return is_number_bigger_than_int_max(input, size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TOKEN CHECKS
|
||||
*/
|
||||
|
||||
// token is alphabet letter, like 'x' or 'y'
|
||||
static bool token_is_variable(const char *input, int input_pos, int *token_size)
|
||||
{
|
||||
if (ft_isalpha(input[input_pos]))
|
||||
{
|
||||
*token_size = 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (ft_isalpha(input[input_pos]))
|
||||
{
|
||||
*token_size = 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// token is int "123"
|
||||
static bool token_is_number_int(const char *input, int input_pos, int *token_size)
|
||||
{
|
||||
int number_size;
|
||||
int max_number_size;
|
||||
int number_size;
|
||||
|
||||
if (!ft_isdigit(input[input_pos]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
number_size = 0;
|
||||
|
||||
number_size = 1;
|
||||
max_number_size = 16; // max size for int
|
||||
while (number_size <= max_number_size)
|
||||
{
|
||||
if (ft_isdigit(input[input_pos + number_size]))
|
||||
{
|
||||
number_size++;
|
||||
}
|
||||
else if (input[input_pos + number_size] == '.')
|
||||
{
|
||||
if (ft_isdigit(input[input_pos + number_size + 1]))
|
||||
{
|
||||
// number is double
|
||||
return false;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (number_size > max_number_size)
|
||||
{
|
||||
stop_errors(&input[input_pos]);
|
||||
}
|
||||
*token_size = number_size;
|
||||
return true;
|
||||
// if (input[input_pos + number_size] == '-')
|
||||
// number_size++;
|
||||
|
||||
while (input[input_pos + number_size] != '\0')
|
||||
{
|
||||
if (ft_isdigit(input[input_pos + number_size]))
|
||||
{
|
||||
number_size++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (number_size == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (is_number_out_of_int_range(&input[input_pos], number_size))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*token_size = number_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
// token is double "123.456"
|
||||
// token is double "123.456" or token < MIN_INT or token > MAX_INT
|
||||
static bool token_is_number_double(const char *input, int input_pos, int *token_size)
|
||||
{
|
||||
int number_size;
|
||||
int max_number_size;
|
||||
bool has_dot;
|
||||
int number_size;
|
||||
bool has_dot;
|
||||
|
||||
if (!ft_isdigit(input[input_pos]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
has_dot = false;
|
||||
number_size = 0;
|
||||
|
||||
has_dot = false;
|
||||
number_size = 1;
|
||||
max_number_size = 24; // max char needed to represent double : 1 sign + 1 point + 17 fractinoal part + 5 exponent
|
||||
while (number_size <= max_number_size)
|
||||
{
|
||||
if (ft_isdigit(input[input_pos + number_size]))
|
||||
{
|
||||
number_size++;
|
||||
}
|
||||
else if (input[input_pos + number_size] == '.')
|
||||
{
|
||||
if (has_dot)
|
||||
{
|
||||
// number is not a valid token, it has 2 dots
|
||||
return false;
|
||||
}
|
||||
if (!ft_isdigit(input[input_pos + number_size + 1]))
|
||||
{
|
||||
// number is not valid token, it has a dot with no number after the dot
|
||||
return false;
|
||||
}
|
||||
has_dot = true;
|
||||
number_size++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (number_size > max_number_size)
|
||||
{
|
||||
stop_errors(&input[input_pos]);
|
||||
}
|
||||
*token_size = number_size;
|
||||
return true;
|
||||
// if (input[input_pos + number_size] == '-')
|
||||
// number_size++;
|
||||
|
||||
while (input[input_pos + number_size] != '\0')
|
||||
{
|
||||
if (ft_isdigit(input[input_pos + number_size]))
|
||||
{
|
||||
number_size++;
|
||||
}
|
||||
else if (input[input_pos + number_size] == '.' && !has_dot)
|
||||
{
|
||||
has_dot = true;
|
||||
number_size++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (is_number_out_of_int_range(&input[input_pos], number_size))
|
||||
{
|
||||
*token_size = number_size;
|
||||
return true;
|
||||
}
|
||||
if (!has_dot)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*token_size = number_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
// token is superscript int (e.g., ¹, ², ³, ⁴, ⁵, etc.)
|
||||
// token is superscript int e.g. ¹, ², ³, ⁴, ⁵, ⁶⁶⁶
|
||||
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
|
||||
int digit_size = 0;
|
||||
int number_size = 0;
|
||||
int superscript_len = 0;
|
||||
int superscript_len_max = 3; // max length of superscript int we want to support
|
||||
|
||||
// check if first character is superscript
|
||||
if (!ft_isdigit_superscript(input + input_pos, NULL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// iterate to find full superscript number
|
||||
while (input[input_pos + number_size] != '\0')
|
||||
{
|
||||
if (ft_isdigit_superscript(&input[input_pos + number_size], &digit_size))
|
||||
{
|
||||
superscript_len++;
|
||||
// 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;
|
||||
}
|
||||
if (superscript_len > superscript_len_max)
|
||||
{
|
||||
stop_errors("superscript int is too long (max supported length is %d), got : %s\n", superscript_len_max, &input[input_pos]);
|
||||
}
|
||||
|
||||
// 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_size = number_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
// token is '^' or "**"
|
||||
static bool token_is_power(const char *input, int input_pos, int *token_size)
|
||||
{
|
||||
if (input[input_pos] == '^')
|
||||
{
|
||||
*token_size = 1;
|
||||
return true;
|
||||
}
|
||||
if (ft_memcmp(&input[input_pos], "**", 2) == 0)
|
||||
{
|
||||
*token_size = 2;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (input[input_pos] == '^')
|
||||
{
|
||||
*token_size = 1;
|
||||
return true;
|
||||
}
|
||||
if (ft_memcmp(&input[input_pos], "**", 2) == 0)
|
||||
{
|
||||
*token_size = 2;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// token is '+'
|
||||
static bool token_is_sign_plus(const char *input, int input_pos, int *token_size)
|
||||
{
|
||||
if (input[input_pos] == '+')
|
||||
{
|
||||
*token_size = 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (input[input_pos] == '+')
|
||||
{
|
||||
*token_size = 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// token is '-'
|
||||
static bool token_is_sign_minus(const char *input, int input_pos, int *token_size)
|
||||
{
|
||||
if (input[input_pos] == '-')
|
||||
{
|
||||
*token_size = 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (input[input_pos] == '-')
|
||||
{
|
||||
*token_size = 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// token is '*'
|
||||
static bool token_is_factor_multiplication(const char *input, int input_pos, int *token_size)
|
||||
{
|
||||
if (input[input_pos] == '*')
|
||||
{
|
||||
*token_size = 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (input[input_pos] == '*')
|
||||
{
|
||||
*token_size = 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// token is '/' or ':'
|
||||
static bool token_is_factor_division(const char *input, int input_pos, int *token_size)
|
||||
{
|
||||
if (input[input_pos] == '/')
|
||||
{
|
||||
*token_size = 1;
|
||||
return true;
|
||||
}
|
||||
if (input[input_pos] == ':')
|
||||
{
|
||||
*token_size = 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (input[input_pos] == '/')
|
||||
{
|
||||
*token_size = 1;
|
||||
return true;
|
||||
}
|
||||
if (input[input_pos] == ':')
|
||||
{
|
||||
*token_size = 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// token is '='
|
||||
static bool token_is_equal(const char *input, int input_pos, int *token_size)
|
||||
{
|
||||
if (input[input_pos] == '=')
|
||||
{
|
||||
*token_size = 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (input[input_pos] == '=')
|
||||
{
|
||||
*token_size = 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* LEXER
|
||||
*/
|
||||
|
||||
void lexerize(const char *input, s_token *tokens)
|
||||
{
|
||||
int tokens_count;
|
||||
int input_pos;
|
||||
int token_size;
|
||||
bool has_equal;
|
||||
int tokens_count;
|
||||
int input_pos;
|
||||
int token_size;
|
||||
bool has_equal;
|
||||
|
||||
has_equal = false;
|
||||
tokens_count = 0;
|
||||
input_pos = 0;
|
||||
while (input[input_pos])
|
||||
{
|
||||
token_size = 0;
|
||||
has_equal = false;
|
||||
tokens_count = 0;
|
||||
input_pos = 0;
|
||||
while (input[input_pos])
|
||||
{
|
||||
token_size = 0;
|
||||
|
||||
if (input[input_pos] == '\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (input[input_pos] == '\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (token_is_variable(input, input_pos, &token_size))
|
||||
{
|
||||
tokens[tokens_count].type = TOKEN_VARIABLE;
|
||||
tokens[tokens_count].tag = TOKEN_NO_TAG;
|
||||
tokens[tokens_count].value_char = 'x';
|
||||
}
|
||||
else if (token_is_number_int(input, input_pos, &token_size))
|
||||
{
|
||||
tokens[tokens_count].type = TOKEN_NUMBER_INT;
|
||||
tokens[tokens_count].tag = TOKEN_NUMBER;
|
||||
tokens[tokens_count].value_int = ft_atoi(&input[input_pos]);
|
||||
}
|
||||
else if (token_is_number_double(input, input_pos, &token_size))
|
||||
{
|
||||
tokens[tokens_count].type = TOKEN_NUMBER_DOUBLE;
|
||||
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;
|
||||
tokens[tokens_count].tag = TOKEN_NO_TAG;
|
||||
tokens[tokens_count].value_char = '^';
|
||||
}
|
||||
else if (token_is_sign_plus(input, input_pos, &token_size))
|
||||
{
|
||||
tokens[tokens_count].type = TOKEN_SIGN_PLUS;
|
||||
tokens[tokens_count].tag = TOKEN_SIGN;
|
||||
tokens[tokens_count].value_char = input[input_pos];
|
||||
}
|
||||
else if (token_is_sign_minus(input, input_pos, &token_size))
|
||||
{
|
||||
tokens[tokens_count].type = TOKEN_SIGN_MINUS;
|
||||
tokens[tokens_count].tag = TOKEN_SIGN;
|
||||
tokens[tokens_count].value_char = input[input_pos];
|
||||
}
|
||||
else if (token_is_factor_multiplication(input, input_pos, &token_size))
|
||||
{
|
||||
tokens[tokens_count].type = TOKEN_FACTOR_MULT;
|
||||
tokens[tokens_count].tag = TOKEN_FACTOR;
|
||||
tokens[tokens_count].value_char = input[input_pos];
|
||||
}
|
||||
else if (token_is_factor_division(input, input_pos, &token_size))
|
||||
{
|
||||
tokens[tokens_count].type = TOKEN_FACTOR_DIV;
|
||||
tokens[tokens_count].tag = TOKEN_FACTOR;
|
||||
tokens[tokens_count].value_char = input[input_pos];
|
||||
}
|
||||
else if (token_is_equal(input, input_pos, &token_size))
|
||||
{
|
||||
has_equal = true;
|
||||
tokens[tokens_count].type = TOKEN_EQUAL;
|
||||
tokens[tokens_count].tag = TOKEN_NO_TAG;
|
||||
tokens[tokens_count].value_char = '=';
|
||||
}
|
||||
else
|
||||
{
|
||||
stop_errors("input[input_pos] is not any token: %s\n", &input[input_pos]);
|
||||
}
|
||||
if (token_is_variable(input, input_pos, &token_size))
|
||||
{
|
||||
tokens[tokens_count].type = TOKEN_VARIABLE;
|
||||
tokens[tokens_count].tag = TOKEN_NO_TAG;
|
||||
tokens[tokens_count].value_char = 'x';
|
||||
}
|
||||
else if (token_is_number_double(input, input_pos, &token_size))
|
||||
{
|
||||
tokens[tokens_count].type = TOKEN_NUMBER_DOUBLE;
|
||||
tokens[tokens_count].tag = TOKEN_NUMBER;
|
||||
tokens[tokens_count].value_double = ft_atof(&input[input_pos]);
|
||||
}
|
||||
else if (token_is_number_int(input, input_pos, &token_size))
|
||||
{
|
||||
tokens[tokens_count].type = TOKEN_NUMBER_INT;
|
||||
tokens[tokens_count].tag = TOKEN_NUMBER;
|
||||
tokens[tokens_count].value_int = ft_atoi(&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;
|
||||
tokens[tokens_count].tag = TOKEN_NO_TAG;
|
||||
tokens[tokens_count].value_char = '^';
|
||||
}
|
||||
else if (token_is_sign_plus(input, input_pos, &token_size))
|
||||
{
|
||||
tokens[tokens_count].type = TOKEN_SIGN_PLUS;
|
||||
tokens[tokens_count].tag = TOKEN_SIGN;
|
||||
tokens[tokens_count].value_char = input[input_pos];
|
||||
}
|
||||
else if (token_is_sign_minus(input, input_pos, &token_size))
|
||||
{
|
||||
tokens[tokens_count].type = TOKEN_SIGN_MINUS;
|
||||
tokens[tokens_count].tag = TOKEN_SIGN;
|
||||
tokens[tokens_count].value_char = input[input_pos];
|
||||
}
|
||||
else if (token_is_factor_multiplication(input, input_pos, &token_size))
|
||||
{
|
||||
tokens[tokens_count].type = TOKEN_FACTOR_MULT;
|
||||
tokens[tokens_count].tag = TOKEN_FACTOR;
|
||||
tokens[tokens_count].value_char = input[input_pos];
|
||||
}
|
||||
else if (token_is_factor_division(input, input_pos, &token_size))
|
||||
{
|
||||
tokens[tokens_count].type = TOKEN_FACTOR_DIV;
|
||||
tokens[tokens_count].tag = TOKEN_FACTOR;
|
||||
tokens[tokens_count].value_char = input[input_pos];
|
||||
}
|
||||
else if (token_is_equal(input, input_pos, &token_size))
|
||||
{
|
||||
has_equal = true;
|
||||
tokens[tokens_count].type = TOKEN_EQUAL;
|
||||
tokens[tokens_count].tag = TOKEN_NO_TAG;
|
||||
tokens[tokens_count].value_char = '=';
|
||||
}
|
||||
else
|
||||
{
|
||||
stop_errors("input[input_pos] is not any token: %s\n", &input[input_pos]);
|
||||
}
|
||||
|
||||
tokens_count++;
|
||||
if (token_size == 0)
|
||||
{
|
||||
stop_errors("token_size is 0 : %s\n", &input[input_pos]);
|
||||
}
|
||||
input_pos += token_size;
|
||||
}
|
||||
tokens_count++;
|
||||
if (token_size == 0)
|
||||
{
|
||||
stop_errors("token_size is 0 : %s\n", &input[input_pos]);
|
||||
}
|
||||
input_pos += token_size;
|
||||
}
|
||||
|
||||
if (!has_equal)
|
||||
stop_errors("the input polynomial does not contains an equal sign, it's an expression not an equation.\n");
|
||||
if (!has_equal)
|
||||
stop_errors("the input polynomial does not contains an equal sign, it's an expression not an equation.\n");
|
||||
|
||||
tokens[tokens_count].type = TOKEN_END;
|
||||
tokens[tokens_count].tag = TOKEN_NO_TAG;
|
||||
tokens[tokens_count].value_char = '\0';
|
||||
tokens[tokens_count].type = TOKEN_END;
|
||||
tokens[tokens_count].tag = TOKEN_NO_TAG;
|
||||
tokens[tokens_count].value_char = '\0';
|
||||
}
|
||||
|
||||
266
src/main.c
266
src/main.c
@@ -21,167 +21,161 @@ s_solution *solution_g_err;
|
||||
|
||||
static void print_usage()
|
||||
{
|
||||
ft_printf("USAGE :\n\n");
|
||||
ft_printf("| ./computorv1 [flags] [polynom]\n");
|
||||
ft_printf("| ./computorv1 [polynom] [flags]\n");
|
||||
ft_printf("| ./computorv1 [flags] -> interactiv mode\n\n");
|
||||
ft_printf("[flags] :\n");
|
||||
ft_printf("-d : print debug\n");
|
||||
ft_printf("-l : interactive loop\n");
|
||||
ft_printf("-b : beautify output\n");
|
||||
ft_putchar('\n');
|
||||
ft_printf("USAGE :\n\n");
|
||||
ft_printf("| ./computorv1 [flags] [polynom]\n");
|
||||
ft_printf("| ./computorv1 [polynom] [flags]\n");
|
||||
ft_printf("| ./computorv1 [flags] -> interactiv mode\n\n");
|
||||
ft_printf("[flags] :\n");
|
||||
ft_printf("-d : print debug\n");
|
||||
ft_printf("-l : interactive loop\n");
|
||||
ft_printf("-b : beautify output\n");
|
||||
ft_putchar('\n');
|
||||
}
|
||||
|
||||
// trim spaces and quotes and newlines
|
||||
static void clean_copy_input(char *input, char *line)
|
||||
{
|
||||
size_t i;
|
||||
size_t j;
|
||||
size_t len;
|
||||
size_t len_trim_end;
|
||||
size_t len_trim_start;
|
||||
size_t i;
|
||||
size_t j;
|
||||
size_t len;
|
||||
size_t len_trim_end;
|
||||
size_t len_trim_start;
|
||||
|
||||
len = ft_strlen(line);
|
||||
len = ft_strlen(line);
|
||||
|
||||
// get len minus : ' | " | \n | <space>
|
||||
i = len;
|
||||
while (i > 0)
|
||||
{
|
||||
if (ft_strchr("\"\'\n", line[i]))
|
||||
i--;
|
||||
if (ft_isspace(line[i]))
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
len_trim_end = i;
|
||||
// get len minus : ' | " | \n | <space>
|
||||
i = len;
|
||||
while (i > 0)
|
||||
{
|
||||
if (ft_strchr("\"\'\n", line[i]))
|
||||
i--;
|
||||
if (ft_isspace(line[i]))
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
len_trim_end = i;
|
||||
|
||||
// get len of leading chars : ' | " | <space> | \n
|
||||
i = 0;
|
||||
while (i < len_trim_end)
|
||||
{
|
||||
if (ft_strchr("\"\'\n", line[i]))
|
||||
i++;
|
||||
if (ft_isspace(line[i]))
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
len_trim_start = i;
|
||||
// get len of leading chars : ' | " | <space> | \n
|
||||
i = 0;
|
||||
while (i < len_trim_end)
|
||||
{
|
||||
if (ft_strchr("\"\'\n", line[i]))
|
||||
i++;
|
||||
if (ft_isspace(line[i]))
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
len_trim_start = i;
|
||||
|
||||
// copy into input
|
||||
i = len_trim_start;
|
||||
j = 0;
|
||||
while (i <= len_trim_end)
|
||||
{
|
||||
input[j] = line[i];
|
||||
j++;
|
||||
i++;
|
||||
}
|
||||
input[j] = '\0';
|
||||
// copy into input
|
||||
i = len_trim_start;
|
||||
j = 0;
|
||||
while (i <= len_trim_end)
|
||||
{
|
||||
input[j] = line[i];
|
||||
j++;
|
||||
i++;
|
||||
}
|
||||
input[j] = '\0';
|
||||
}
|
||||
|
||||
static void launch_stdin()
|
||||
{
|
||||
char *line;
|
||||
size_t len;
|
||||
char *line;
|
||||
size_t len;
|
||||
|
||||
line = NULL;
|
||||
len = 0;
|
||||
line = NULL;
|
||||
len = 0;
|
||||
|
||||
// get input
|
||||
getline(&line, &len, stdin);
|
||||
// get input
|
||||
getline(&line, &len, stdin);
|
||||
|
||||
// prepare input
|
||||
char input[len];
|
||||
clean_copy_input(input, line);
|
||||
// prepare input
|
||||
char input[len];
|
||||
clean_copy_input(input, line);
|
||||
|
||||
// launch input
|
||||
launch_computorv1(input);
|
||||
// launch input
|
||||
launch_computorv1(input);
|
||||
|
||||
// FREE LINE !
|
||||
free(line);
|
||||
// FREE LINE !
|
||||
free(line);
|
||||
}
|
||||
|
||||
static void launch_stdin_loop()
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
// for the moment it does not work since errors exit
|
||||
launch_stdin();
|
||||
}
|
||||
}
|
||||
// static void launch_stdin_loop()
|
||||
// {
|
||||
// while (1)
|
||||
// {
|
||||
// // for the moment it does not work since errors exit
|
||||
// launch_stdin();
|
||||
// }
|
||||
// }
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int i;
|
||||
char *input;
|
||||
e_program_mode program_mode;
|
||||
int i;
|
||||
char *input;
|
||||
e_program_mode program_mode;
|
||||
|
||||
// init flags
|
||||
flag_debug_mode = false;
|
||||
flag_loop_mode = false;
|
||||
flag_beautify_mode = false;
|
||||
// init flags
|
||||
flag_debug_mode = false;
|
||||
flag_loop_mode = false;
|
||||
flag_beautify_mode = false;
|
||||
|
||||
// check arguments
|
||||
program_mode = MODE_ARGV;
|
||||
if (ac == 1)
|
||||
{
|
||||
program_mode = MODE_STDIN;
|
||||
}
|
||||
else if (ac > 1)
|
||||
{
|
||||
// get flags
|
||||
input = NULL;
|
||||
i = 1;
|
||||
while (i < ac)
|
||||
{
|
||||
if ((ft_strcmp(av[i], "-d") == 0))
|
||||
{
|
||||
// flag -d : debug
|
||||
flag_debug_mode = true;
|
||||
}
|
||||
else if ((ft_strcmp(av[i], "-l") == 0))
|
||||
{
|
||||
// flag -l : interactiv loop
|
||||
flag_loop_mode = true;
|
||||
program_mode = MODE_LOOP;
|
||||
}
|
||||
else if ((ft_strcmp(av[i], "-b") == 0))
|
||||
{
|
||||
// flag -b : beautify output
|
||||
flag_beautify_mode = true;
|
||||
}
|
||||
else if (ft_strlen(av[i]) == 2 && av[i][0] == '-')
|
||||
{
|
||||
// unknown flag
|
||||
print_usage();
|
||||
stop_errors("unknwon flag '%s'", av[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
input = av[i];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
// if input was not set, it means interactiv mode
|
||||
if (input == NULL)
|
||||
{
|
||||
program_mode = MODE_STDIN;
|
||||
}
|
||||
}
|
||||
// check arguments
|
||||
program_mode = MODE_ARGV;
|
||||
|
||||
// launch calculator
|
||||
if (program_mode == MODE_ARGV)
|
||||
{
|
||||
launch_computorv1(input);
|
||||
}
|
||||
else if (program_mode == MODE_STDIN)
|
||||
{
|
||||
launch_stdin();
|
||||
}
|
||||
else if (program_mode == MODE_LOOP)
|
||||
{
|
||||
launch_stdin_loop();
|
||||
}
|
||||
// get flags
|
||||
input = NULL;
|
||||
i = 1;
|
||||
while (i < ac)
|
||||
{
|
||||
if ((ft_strcmp(av[i], "-d") == 0))
|
||||
{
|
||||
// flag -d : debug
|
||||
flag_debug_mode = true;
|
||||
}
|
||||
else if ((ft_strcmp(av[i], "-l") == 0))
|
||||
{
|
||||
// flag -l : interactiv loop
|
||||
flag_loop_mode = true;
|
||||
program_mode = MODE_LOOP;
|
||||
}
|
||||
else if ((ft_strcmp(av[i], "-b") == 0))
|
||||
{
|
||||
// flag -b : beautify output
|
||||
flag_beautify_mode = true;
|
||||
}
|
||||
else if (ft_strlen(av[i]) == 2 && av[i][0] == '-')
|
||||
{
|
||||
// unknown flag
|
||||
print_usage();
|
||||
stop_errors("unknwon flag '%s'", av[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
input = av[i];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
// if input was not set, it means interactiv mode
|
||||
if (input == NULL)
|
||||
{
|
||||
program_mode = MODE_STDIN;
|
||||
}
|
||||
|
||||
return (0);
|
||||
// launch calculator
|
||||
if (program_mode == MODE_ARGV)
|
||||
{
|
||||
launch_computorv1(input);
|
||||
}
|
||||
else if (program_mode == MODE_STDIN)
|
||||
{
|
||||
launch_stdin();
|
||||
}
|
||||
// else if (program_mode == MODE_LOOP)
|
||||
// {
|
||||
// launch_stdin_loop();
|
||||
// }
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
24
src/parser.c
24
src/parser.c
@@ -16,30 +16,44 @@
|
||||
static e_term_sign get_sign(s_token *tokens, int i, int *token_count)
|
||||
{
|
||||
*token_count = 0;
|
||||
int j;
|
||||
e_term_sign ret_sign;
|
||||
|
||||
// default to '+'
|
||||
ret_sign = TERM_PLUS;
|
||||
|
||||
// sign
|
||||
if (tokens[i].tag == TOKEN_SIGN)
|
||||
{
|
||||
*token_count = 1;
|
||||
// we cna have two signs in a row, like "3 - -2" or "3 - +2"
|
||||
j = 0;
|
||||
while (j < 2)
|
||||
{
|
||||
if (tokens[i + j].tag != TOKEN_SIGN)
|
||||
break;
|
||||
if (tokens[i + j].type == TOKEN_SIGN_MINUS)
|
||||
ret_sign = (ret_sign == TERM_PLUS) ? TERM_MINUS : TERM_PLUS;
|
||||
*token_count += 1;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
else if (i == 0)
|
||||
{
|
||||
// if most left term, the sign can be ommited for a '+' sign in front of a number or variable
|
||||
*token_count = 0;
|
||||
return TERM_PLUS;
|
||||
ret_sign = TERM_PLUS;
|
||||
}
|
||||
else if (tokens[i - 1].type == TOKEN_EQUAL)
|
||||
{
|
||||
// if first token after 'equal', the sign can be ommited for a '+' sign in front of a number or variable
|
||||
*token_count = 0;
|
||||
return TERM_PLUS;
|
||||
ret_sign = TERM_PLUS;
|
||||
}
|
||||
else
|
||||
{
|
||||
stop_errors("at begining of term, we should have a token 'sign', not '%s' (token[%i])", token_type_to_str(tokens[i].type), i);
|
||||
}
|
||||
|
||||
return tokens[i].type == TOKEN_SIGN_PLUS ? TERM_PLUS : TERM_MINUS;
|
||||
return ret_sign;
|
||||
}
|
||||
|
||||
static double get_double_value(s_token token)
|
||||
|
||||
@@ -65,7 +65,7 @@ int gcd_int(int a, int b)
|
||||
b = a % b;
|
||||
a = tmp;
|
||||
}
|
||||
return abs(a);
|
||||
return ft_abs(a);
|
||||
}
|
||||
|
||||
// returns the gcd, and modify arguments with new reduced values
|
||||
|
||||
Reference in New Issue
Block a user