File indexing completed on 2024-04-28 05:49:45

0001 /*
0002     SPDX-FileCopyrightText: 2023 Gabriel Barrantes <gabriel.barrantes.dev@outlook.com>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "kcalc_token.h"
0007 #include "kcalc_core_p.h"
0008 #include <QDebug>
0009 
0010 //------------------------------------------------------------------------------
0011 // Name: KCalcToken
0012 // Desc: constructor
0013 //------------------------------------------------------------------------------
0014 KCalcToken::KCalcToken()
0015 {
0016     this->resetToken_();
0017 }
0018 
0019 KCalcToken::KCalcToken(const KNumber &kNumber)
0020     : KCalcToken()
0021 {
0022     kNumber_ = kNumber;
0023     token_Code_ = KNUMBER;
0024     is_KNumber_ = true;
0025     token_Type_ = KNUMBER_TYPE;
0026 }
0027 
0028 KCalcToken::KCalcToken(const KNumber &kNumber, int stringIndex)
0029     : KCalcToken(kNumber)
0030 {
0031     string_index_ = stringIndex;
0032 }
0033 
0034 KCalcToken::KCalcToken(TokenCode tokenCode)
0035     : KCalcToken()
0036 {
0037     this->setToken_(tokenCode);
0038 }
0039 
0040 KCalcToken::KCalcToken(TokenCode tokenCode, int stringIndex)
0041     : KCalcToken(tokenCode)
0042 {
0043     string_index_ = stringIndex;
0044 }
0045 
0046 void KCalcToken::updateToken(const KNumber &kNumber)
0047 {
0048     this->resetToken_();
0049     kNumber_ = kNumber;
0050     token_Code_ = KNUMBER;
0051     is_KNumber_ = true;
0052     token_Type_ = KNUMBER_TYPE;
0053 }
0054 
0055 void KCalcToken::updateToken(TokenCode tokenCode)
0056 {
0057     this->resetToken_();
0058     this->setToken_(tokenCode);
0059 }
0060 
0061 void KCalcToken::setToken_(TokenCode tokenCode)
0062 {
0063     token_Code_ = tokenCode;
0064 
0065     switch (tokenCode) {
0066     case KNUMBER:
0067         is_KNumber_ = true;
0068         token_Type_ = KNUMBER_TYPE;
0069         break;
0070     case DECIMAL_POINT:
0071         break;
0072     case PLUS:
0073         set_Binary_Token_(CalcEngine_p::ExecAdd, ADD_PRIORITY_LEVEL);
0074         break;
0075     case MINUS:
0076         set_Binary_Token_(CalcEngine_p::ExecSubtract, SUB_PRIORITY_LEVEL);
0077         break;
0078     case DIVISION:
0079     case SLASH:
0080         set_Binary_Token_(CalcEngine_p::ExecDivide, DIV_PRIORITY_LEVEL);
0081         break;
0082     case MULTIPLICATION:
0083     case DOT:
0084     case ASTERISK:
0085         set_Binary_Token_(CalcEngine_p::ExecMultiply, MUL_PRIORITY_LEVEL);
0086         break;
0087     case PERCENTAGE:
0088         set_Left_Unary_Token_(CalcEngine_p::Percentage, PERCENTAGE_PRIORITY_LEVEL);
0089         break;
0090     case OPENING_PARENTHESIS:
0091         is_Opening_Parentheses_ = true;
0092         token_Type_ = OPENING_PARENTHESES_TYPE;
0093         break;
0094     case CLOSING_PARENTHESIS:
0095         is_Closing_Parentheses_ = true;
0096         token_Type_ = CLOSING_PARENTHESES_TYPE;
0097         break;
0098     case SQUARE:
0099         set_Left_Unary_Token_(CalcEngine_p::Square, SQUARE_PRIORITY_LEVEL);
0100         break;
0101     case CUBE:
0102         set_Left_Unary_Token_(CalcEngine_p::Cube, CUBE_PRIORITY_LEVEL);
0103         break;
0104     case SQUARE_ROOT:
0105         set_Right_UnaryToken_(CalcEngine_p::SquareRoot, SQUARE_ROOT_PRIORITY_LEVEL);
0106         break;
0107     case CUBIC_ROOT:
0108         set_Right_UnaryToken_(CalcEngine_p::CubeRoot, CUBIC_ROOT_PRIORITY_LEVEL);
0109         break;
0110     case SIN:
0111     case SIN_RAD:
0112         set_Right_UnaryToken_(CalcEngine_p::SinRad, SIN_PRIORITY_LEVEL);
0113         break;
0114     case COS:
0115     case COS_RAD:
0116         set_Right_UnaryToken_(CalcEngine_p::CosRad, COS_PRIORITY_LEVEL);
0117         break;
0118     case TAN:
0119     case TAN_RAD:
0120         set_Right_UnaryToken_(CalcEngine_p::TangensRad, TAN_PRIORITY_LEVEL);
0121         break;
0122     case SIN_DEG:
0123         set_Right_UnaryToken_(CalcEngine_p::SinDeg, SIN_PRIORITY_LEVEL);
0124         break;
0125     case COS_DEG:
0126         set_Right_UnaryToken_(CalcEngine_p::CosDeg, COS_PRIORITY_LEVEL);
0127         break;
0128     case TAN_DEG:
0129         set_Right_UnaryToken_(CalcEngine_p::TangensDeg, TAN_PRIORITY_LEVEL);
0130         break;
0131     case SIN_GRAD:
0132         set_Right_UnaryToken_(CalcEngine_p::SinGrad, SIN_PRIORITY_LEVEL);
0133         break;
0134     case COS_GRAD:
0135         set_Right_UnaryToken_(CalcEngine_p::CosGrad, COS_PRIORITY_LEVEL);
0136         break;
0137     case TAN_GRAD:
0138         set_Right_UnaryToken_(CalcEngine_p::TangensGrad, TAN_PRIORITY_LEVEL);
0139         break;
0140     case ASIN:
0141     case ASIN_RAD:
0142         set_Right_UnaryToken_(CalcEngine_p::ArcSinRad, ASIN_PRIORITY_LEVEL);
0143         break;
0144     case ASIN_DEG:
0145         set_Right_UnaryToken_(CalcEngine_p::ArcSinDeg, ASIN_PRIORITY_LEVEL);
0146         break;
0147     case ASIN_GRAD:
0148         set_Right_UnaryToken_(CalcEngine_p::ArcSinGrad, ASIN_PRIORITY_LEVEL);
0149         break;
0150     case ACOS:
0151     case ACOS_RAD:
0152         set_Right_UnaryToken_(CalcEngine_p::ArcCosRad, ACOS_PRIORITY_LEVEL);
0153         break;
0154     case ACOS_DEG:
0155         set_Right_UnaryToken_(CalcEngine_p::ArcCosDeg, ACOS_PRIORITY_LEVEL);
0156         break;
0157     case ACOS_GRAD:
0158         set_Right_UnaryToken_(CalcEngine_p::ArcCosGrad, ACOS_PRIORITY_LEVEL);
0159         break;
0160     case ATAN:
0161     case ATAN_RAD:
0162         set_Right_UnaryToken_(CalcEngine_p::ArcTangensRad, ATAN_PRIORITY_LEVEL);
0163         break;
0164     case ATAN_DEG:
0165         set_Right_UnaryToken_(CalcEngine_p::ArcTangensDeg, ATAN_PRIORITY_LEVEL);
0166         break;
0167     case ATAN_GRAD:
0168         set_Right_UnaryToken_(CalcEngine_p::ArcTangensGrad, ATAN_PRIORITY_LEVEL);
0169         break;
0170     case SINH:
0171         set_Right_UnaryToken_(CalcEngine_p::SinHyp, SINH_PRIORITY_LEVEL);
0172         break;
0173     case COSH:
0174         set_Right_UnaryToken_(CalcEngine_p::CosHyp, COSH_PRIORITY_LEVEL);
0175         break;
0176     case TANH:
0177         set_Right_UnaryToken_(CalcEngine_p::TangensHyp, TANH_PRIORITY_LEVEL);
0178         break;
0179     case ASINH:
0180         set_Right_UnaryToken_(CalcEngine_p::AreaSinHyp, ASINH_PRIORITY_LEVEL);
0181         break;
0182     case ACOSH:
0183         set_Right_UnaryToken_(CalcEngine_p::AreaCosHyp, ACOSH_PRIORITY_LEVEL);
0184         break;
0185     case ATANH:
0186         set_Right_UnaryToken_(CalcEngine_p::AreaTangensHyp, ATANH_PRIORITY_LEVEL);
0187         break;
0188     case GAMMA:
0189         set_Right_UnaryToken_(CalcEngine_p::Gamma, GAMMA_PRIORITY_LEVEL);
0190         break;
0191     case FACTORIAL:
0192         set_Left_Unary_Token_(CalcEngine_p::Factorial, FACTORIAL_PRIORITY_LEVEL);
0193         break;
0194     case POWER:
0195         set_Binary_Token_(CalcEngine_p::ExecPower, POWER_PRIORITY_LEVEL);
0196         break;
0197     case POWER_ROOT:
0198         set_Binary_Token_(CalcEngine_p::ExecPwrRoot, POWER_ROOT_PRIORITY_LEVEL);
0199         break;
0200     case EXP:
0201         set_Right_UnaryToken_(CalcEngine_p::Exp, EXP_PRIORITY_LEVEL);
0202         break;
0203     case EXP_10:
0204         set_Right_UnaryToken_(CalcEngine_p::Exp10, EXP_10_PRIORITY_LEVEL);
0205         break;
0206     case LN:
0207         set_Right_UnaryToken_(CalcEngine_p::Ln, LN_PRIORITY_LEVEL);
0208         break;
0209     case LOG_10:
0210         set_Right_UnaryToken_(CalcEngine_p::Log10, LOG_10_PRIORITY_LEVEL);
0211         break;
0212     case INVERT_SIGN:
0213         set_Right_UnaryToken_(CalcEngine_p::InvertSign, INVERTSIGN_PRIORITY_LEVEL);
0214         break;
0215     case RECIPROCAL:
0216         set_Left_Unary_Token_(CalcEngine_p::Reciprocal, RECIPROCAL_ROOT_PRIORITY_LEVEL);
0217         break;
0218     case BINOMIAL:
0219         set_Binary_Token_(CalcEngine_p::ExecBinom, BINOMIAL_PRIORITY_LEVEL);
0220         break;
0221     case MODULO:
0222         set_Binary_Token_(CalcEngine_p::ExecMod, MODULO_PRIORITY_LEVEL);
0223         break;
0224     case INTEGER_DIVISION:
0225         set_Binary_Token_(CalcEngine_p::ExecIntDiv, INTEGER_DIVISION_PRIORITY_LEVEL);
0226         break;
0227     case AND:
0228         set_Binary_Token_(CalcEngine_p::ExecAnd, AND_PRIORITY_LEVEL);
0229         break;
0230     case OR:
0231         set_Binary_Token_(CalcEngine_p::ExecOr, OR_PRIORITY_LEVEL);
0232         break;
0233     case XOR:
0234         set_Binary_Token_(CalcEngine_p::ExecXor, XOR_PRIORITY_LEVEL);
0235         break;
0236     case ONE_S_COMPLEMENT:
0237         set_Right_UnaryToken_(CalcEngine_p::Complement, ONE_S_COMPLEMENT_PRIORITY_LEVEL);
0238         break;
0239     case RSH:
0240         set_Binary_Token_(CalcEngine_p::ExecRsh, RSH_STR_PRIORITY_LEVEL);
0241         break;
0242     case LSH:
0243         set_Binary_Token_(CalcEngine_p::ExecLsh, LSH_STR_PRIORITY_LEVEL);
0244         break;
0245     case ANS:
0246         is_KNumber_ = true;
0247         token_Type_ = KNUMBER_TYPE;
0248         break;
0249     case EQUAL:
0250         break;
0251     case INVALID_TOKEN:
0252         break;
0253     case PERMILLE:
0254     case TWO_S_COMPLEMENT:
0255     case DOUBLE_FACTORIAL:
0256     case DEGREE:
0257     case GRADIAN:
0258     case RADIAN:
0259     default:
0260         qDebug() << "Not implemented token ";
0261         break;
0262     }
0263 }
0264 
0265 void inline KCalcToken::set_Left_Unary_Token_(Unary_Function_Ptr function, int priorityLevel)
0266 {
0267     unary_Function_Ptr_ = function;
0268     priority_level_ = priorityLevel;
0269     is_Left_Unary_Function_ = true;
0270     token_Type_ = LEFT_UNARY_FUNCTION_TYPE;
0271 }
0272 
0273 void inline KCalcToken::set_Right_UnaryToken_(Unary_Function_Ptr function, int priorityLevel)
0274 {
0275     unary_Function_Ptr_ = function;
0276     priority_level_ = priorityLevel;
0277     is_Right_Unary_Function_ = true;
0278     token_Type_ = RIGHT_UNARY_FUNCTION_TYPE;
0279 }
0280 
0281 void inline KCalcToken::set_Binary_Token_(Binary_Function_Ptr function, int priorityLevel)
0282 {
0283     binary_Function_Ptr_ = function;
0284     is_Binary_Function_ = true;
0285     token_Type_ = BINARY_FUNCTION_TYPE;
0286     priority_level_ = priorityLevel;
0287 }
0288 
0289 void KCalcToken::resetToken_()
0290 {
0291     key_ = (nullptr);
0292     kNumber_ = KNumber::NaN;
0293     token_Code_ = INVALID_TOKEN;
0294 
0295     unary_Function_Ptr_ = nullptr;
0296     binary_Function_Ptr_ = nullptr;
0297 
0298     is_KNumber_ = false;
0299     is_Right_Unary_Function_ = false;
0300     is_Left_Unary_Function_ = false;
0301     is_Binary_Function_ = false;
0302     is_Opening_Parentheses_ = false;
0303     is_Closing_Parentheses_ = false;
0304 
0305     invert_Sign_First_Arg_ = false;
0306     invert_Sign_Second_Arg_ = false;
0307 
0308     priority_level_ = NO_LEVEL;
0309 
0310     string_index_ = -1;
0311 }
0312 
0313 bool KCalcToken::isKNumber() const
0314 {
0315     return is_KNumber_;
0316 }
0317 
0318 bool KCalcToken::isRightUnaryFunction() const
0319 {
0320     return is_Right_Unary_Function_;
0321 }
0322 
0323 bool KCalcToken::isLeftUnaryFunction() const
0324 {
0325     return is_Left_Unary_Function_;
0326 }
0327 
0328 bool KCalcToken::isBinaryFunction() const
0329 {
0330     return is_Binary_Function_;
0331 }
0332 
0333 bool KCalcToken::isOpeningParentheses() const
0334 {
0335     return is_Opening_Parentheses_;
0336 }
0337 
0338 bool KCalcToken::isClosingParentheses() const
0339 {
0340     return is_Closing_Parentheses_;
0341 }
0342 
0343 const KNumber KCalcToken::getKNumber() const
0344 {
0345     return kNumber_;
0346 }
0347 
0348 KCalcToken::TokenCode KCalcToken::getTokenCode() const
0349 {
0350     return token_Code_;
0351 }
0352 
0353 KCalcToken::TokenType KCalcToken::getTokenType() const
0354 {
0355     return token_Type_;
0356 }
0357 
0358 int KCalcToken::getPriorityLevel() const
0359 {
0360     return priority_level_;
0361 }
0362 
0363 int KCalcToken::getStringIndex() const
0364 {
0365     return string_index_;
0366 }
0367 
0368 KNumber KCalcToken::evaluate(const KNumber &kNumber) const
0369 {
0370     if (unary_Function_Ptr_ == nullptr) {
0371         return KNumber::NaN; // safety code
0372     } else {
0373         if (invert_Sign_First_Arg_) {
0374             return unary_Function_Ptr_(-kNumber);
0375         } else {
0376             return unary_Function_Ptr_(kNumber);
0377         }
0378     }
0379 }
0380 
0381 KNumber KCalcToken::evaluate(const KNumber &kNumberLeft, const KNumber &kNumberRight) const
0382 {
0383     if (binary_Function_Ptr_ == nullptr) {
0384         return KNumber::NaN; // safety code
0385     } else {
0386         if (!invert_Sign_First_Arg_ && !invert_Sign_Second_Arg_) {
0387             return binary_Function_Ptr_(kNumberLeft, kNumberRight);
0388         } else if (invert_Sign_First_Arg_ && !invert_Sign_Second_Arg_) {
0389             return binary_Function_Ptr_(-kNumberLeft, kNumberRight);
0390         } else if (!invert_Sign_First_Arg_ && invert_Sign_Second_Arg_) {
0391             return binary_Function_Ptr_(kNumberLeft, -kNumberRight);
0392         } else {
0393             return binary_Function_Ptr_(-kNumberLeft, -kNumberRight);
0394         }
0395     }
0396 }
0397 
0398 void KCalcToken::invertSignFirstArg()
0399 {
0400     invert_Sign_First_Arg_ = !invert_Sign_First_Arg_;
0401 }
0402 
0403 void KCalcToken::invertSignSecondArg()
0404 {
0405     invert_Sign_Second_Arg_ = !invert_Sign_Second_Arg_;
0406 }
0407 
0408 //------------------------------------------------------------------------------
0409 // Name: ~KCalcToken
0410 // Desc: destructor
0411 //------------------------------------------------------------------------------
0412 KCalcToken::~KCalcToken() = default;