255 lines
6.7 KiB
C
255 lines
6.7 KiB
C
#ifndef COMPUTORV1_H
|
|
#define COMPUTORV1_H
|
|
|
|
#include "libft.h"
|
|
#include <stdio.h> // for printf
|
|
#include <stdarg.h> // for va_list
|
|
#include <stdbool.h>
|
|
#include <errno.h> // for errno
|
|
#include <string.h> // for strerror
|
|
|
|
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* MACROS
|
|
*/
|
|
|
|
#define DOUBLE_PRECISION 0.00001
|
|
// maximum exponent supported to avoid excessive variable-length stack allocation (VLA),
|
|
// which can lead to stack overflows, segmentation faults, and potential denial-of-service (DoS)
|
|
#define MAX_EXPONENT 1024
|
|
|
|
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* MAIN.C
|
|
*/
|
|
|
|
typedef enum
|
|
{
|
|
MODE_ARGV, //
|
|
MODE_STDIN, //
|
|
MODE_LOOP, //
|
|
} e_program_mode;
|
|
|
|
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* COMPUTORV1.C
|
|
*/
|
|
|
|
void launch_computorv1(char *input);
|
|
|
|
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* LEXER.C
|
|
*/
|
|
|
|
typedef enum
|
|
{
|
|
TOKEN_END = 0, // 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, // =
|
|
} e_token_type;
|
|
|
|
typedef enum
|
|
{
|
|
TOKEN_NO_TAG = 0,
|
|
TOKEN_NUMBER,
|
|
TOKEN_SIGN,
|
|
TOKEN_FACTOR,
|
|
} e_token_tag;
|
|
|
|
typedef struct
|
|
{
|
|
e_token_type type;
|
|
e_token_tag tag;
|
|
union
|
|
{
|
|
char value_char;
|
|
int value_int;
|
|
double value_double;
|
|
};
|
|
} s_token;
|
|
|
|
void lexerize(const char *input, s_token *tokens);
|
|
|
|
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* PARSER.C
|
|
*/
|
|
|
|
typedef enum
|
|
{
|
|
TERM_POS_END = 0, // for last term
|
|
TERM_LEFT, // a in "a = b"
|
|
TERM_RIGHT, // b in "a = b"
|
|
} e_term_position;
|
|
|
|
typedef enum
|
|
{
|
|
TERM_SIGN_END = 0, // for last term
|
|
TERM_PLUS = '+', // +
|
|
TERM_MINUS = '-', // -
|
|
} e_term_sign;
|
|
|
|
typedef struct
|
|
{
|
|
e_term_position position;
|
|
e_term_sign sign;
|
|
double coefficient;
|
|
int exponent;
|
|
} s_term;
|
|
|
|
void parse(s_token *tokens, s_term *terms, int terms_count_max);
|
|
|
|
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* REDUCE.C
|
|
*/
|
|
|
|
typedef struct
|
|
{
|
|
e_term_sign sign;
|
|
double coefficient;
|
|
int exponent;
|
|
} s_polynom;
|
|
|
|
int reduce(s_term *terms, s_polynom *polynom, int max_exponent);
|
|
|
|
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* SOLVE.C
|
|
*/
|
|
|
|
typedef enum
|
|
{
|
|
DELTA_ZERO = 0,
|
|
DELTA_PLUS = 1,
|
|
DELTA_MINUS = -1,
|
|
} e_delta_sign;
|
|
|
|
typedef enum
|
|
{
|
|
RADICAND_ZERO = 0,
|
|
RADICAND_PLUS = 1,
|
|
RADICAND_MINUS = -1,
|
|
} e_radicand_sign;
|
|
|
|
typedef struct
|
|
{
|
|
double a; // a in "ax + b"
|
|
double b; // b in "ax + b"
|
|
double solution; // double (-b / a)
|
|
} s_solution_degree_1;
|
|
|
|
typedef struct
|
|
{
|
|
double a; // a in "ax² + bx + c"
|
|
double b; // b in "ax² + bx + c"
|
|
double c; // c in "ax² + bx + c"
|
|
double delta; // Δ == b² - 4ac
|
|
e_delta_sign delta_sign; // DELTA_PLUS or DELTA_MINUS or DELTA_ZERO
|
|
double delta_absolute; // |Δ|
|
|
double delta_sqrt; // √|Δ|
|
|
double left_term; // double (-b / 2a)
|
|
double right_term; // double (√|Δ| / 2a)
|
|
bool all_int; // false if any is double : b, a, √|Δ|
|
|
int left_term_numerator; // -b / gcd
|
|
int left_term_denominator; // 2a / gcd
|
|
int right_term_numerator; // √|Δ| / gcd
|
|
int right_term_denominator; // 2a / gcd
|
|
} s_solution_degree_2;
|
|
|
|
typedef struct
|
|
{
|
|
double a; // a in "ax² + c"
|
|
double c; // c in "ax² + c"
|
|
double radicand; // x² = -c/a
|
|
e_radicand_sign radicand_sign; // RADICAND_PLUS or RADICAND_MINUS or RADICAND_ZERO
|
|
double radicand_absolute; // |radicand|
|
|
double radicand_sqrt; // √|radicand|
|
|
double numerator; // |c|
|
|
double numerator_sqrt; // √c
|
|
bool numerator_sqrt_is_int; // false if √c is a double
|
|
double denominator; // |a|
|
|
double denominator_sqrt; // √a
|
|
bool denominator_sqrt_is_int; // false if √a is a double
|
|
} s_solution_degree_2_pure;
|
|
|
|
typedef struct
|
|
{
|
|
int degree;
|
|
bool is_quadratic_pure;
|
|
union
|
|
{
|
|
s_solution_degree_1 solution_degree_1;
|
|
s_solution_degree_2 solution_degree_2;
|
|
s_solution_degree_2_pure solution_degree_2_pure;
|
|
};
|
|
} s_solution;
|
|
|
|
void solve(const s_polynom *polynom, s_solution *solution);
|
|
|
|
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* PRINTER_EQUATION.C
|
|
*/
|
|
|
|
void print_reduced_form(s_polynom *polynom, int degree);
|
|
void print_degree(s_polynom *polynom, int degree);
|
|
|
|
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* PRINTER_SOLUTIONS.C
|
|
*/
|
|
|
|
void print_solution(s_solution *solution);
|
|
|
|
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* UTILS/MATH.C
|
|
*/
|
|
|
|
bool is_nearly_equal(double num, int compare);
|
|
bool is_nearly_equal_zero(double num);
|
|
const s_polynom *get_term_of_power(const s_polynom *polynom, int power);
|
|
double positiv_zero(double num);
|
|
bool has_decimal_part(double num);
|
|
bool any_has_decimal_part(double *num, size_t len);
|
|
int gcd_int(int a, int b);
|
|
int reduce_fraction(double *numerator, double *denominator);
|
|
|
|
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* UTILS/ERRORS.C
|
|
*/
|
|
|
|
void print_state();
|
|
void stop_errors(const char *format, ...);
|
|
|
|
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* UTILS/PRINT_ENUMS.C
|
|
*/
|
|
|
|
const char *token_type_to_str(e_token_type type);
|
|
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);
|
|
const char *delta_sign_to_str(e_delta_sign sign);
|
|
const char *radicand_sign_to_str(e_radicand_sign enum_value);
|
|
|
|
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* UTILS/PRINT_DEBUG.C
|
|
*/
|
|
|
|
void print_debug(const char *description, ...);
|
|
|
|
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* GLOBALS
|
|
*/
|
|
|
|
extern char *input_g_err;
|
|
extern s_token *tokens_g_err;
|
|
extern s_term *terms_g_err;
|
|
extern s_polynom *polynom_g_err;
|
|
extern s_solution *solution_g_err;
|
|
extern bool flag_debug_mode;
|
|
extern bool flag_loop_mode;
|
|
extern bool flag_beautify_mode;
|
|
|
|
#endif |