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;