File indexing completed on 2024-06-23 04:27:02
0001 /* This file is part of the KDE project 0002 * SPDX-FileCopyrightText: 2007 Jan Hambrecht <jaham@gmx.net> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef KOENHANCEDPATHFORMULA_H 0008 #define KOENHANCEDPATHFORMULA_H 0009 0010 #include <QString> 0011 #include <QVariant> 0012 0013 class EnhancedPathShape; 0014 0015 class FormulaToken 0016 { 0017 public: 0018 /// token types 0019 enum Type { 0020 TypeUnknown = 0, ///< unknown type 0021 TypeNumber, ///< 14, 3, 1977, 3.141592, 1e10, 5.9e-7 0022 TypeOperator, ///< +, *, /, - 0023 TypeReference, ///< function reference, modifier reference or named variable 0024 TypeFunction ///< function name 0025 }; 0026 0027 /// operator types 0028 enum Operator { 0029 OperatorInvalid, ///< invalid operator 0030 OperatorAdd, ///< + addition 0031 OperatorSub, ///< - subtraction 0032 OperatorMul, ///< * multiplication 0033 OperatorDiv, ///< / division 0034 OperatorLeftPar, ///< (left parentheses 0035 OperatorRightPar, ///<) right parentheses 0036 OperatorComma ///< , comma 0037 }; 0038 0039 /// Constructs token with given type, text and position 0040 explicit FormulaToken(Type type = TypeUnknown, const QString &text = QString(), int position = -1); 0041 0042 /// copy constructor 0043 FormulaToken(const FormulaToken &token); 0044 0045 /// assignment operator 0046 FormulaToken &operator=(const FormulaToken &token); 0047 0048 /// Returns the type of the token 0049 Type type() const 0050 { 0051 return m_type; 0052 } 0053 /// Returns the text representation of the token 0054 QString text() const 0055 { 0056 return m_text; 0057 } 0058 /// Returns the position of the token 0059 int position() const 0060 { 0061 return m_position; 0062 } 0063 0064 /// Returns if the token is a number 0065 bool isNumber() const 0066 { 0067 return m_type == TypeNumber; 0068 } 0069 /// Returns if the token is a operator, OperatorInvalid if token is no operator 0070 bool isOperator() const 0071 { 0072 return m_type == TypeOperator; 0073 } 0074 /// Returns if token is a function 0075 bool isFunction() const 0076 { 0077 return m_type == TypeFunction; 0078 } 0079 /// Returns if token is a reference 0080 bool isReference() const 0081 { 0082 return m_type == TypeReference; 0083 } 0084 0085 /// Returns the token converted to qreal 0086 qreal asNumber() const; 0087 /// Returns the token as operator 0088 Operator asOperator() const; 0089 private: 0090 Type m_type {TypeUnknown}; ///< the token type 0091 QString m_text; ///< the token text representation 0092 int m_position {-1}; ///< the tokens position 0093 }; 0094 0095 typedef QList<FormulaToken> TokenList; 0096 0097 class Opcode; 0098 0099 class EnhancedPathFormula 0100 { 0101 public: 0102 /// predefined functions 0103 enum Function { 0104 FunctionUnknown, 0105 // unary functions 0106 FunctionAbs, 0107 FunctionSqrt, 0108 FunctionSin, 0109 FunctionCos, 0110 FunctionTan, 0111 FunctionAtan, 0112 // binary functions 0113 FunctionAtan2, 0114 FunctionMin, 0115 FunctionMax, 0116 // ternary functions 0117 FunctionIf 0118 }; 0119 0120 /// The possible error code returned by error() 0121 enum Error { 0122 ErrorNone, ///< no error 0123 ErrorValue, ///< error when converting value 0124 ErrorParse, ///< parsing error 0125 ErrorCompile, ///< compiling error 0126 ErrorName ///< invalid function name value 0127 }; 0128 0129 /// Constructs a new formula from the specified string representation 0130 EnhancedPathFormula(const QString &text, EnhancedPathShape *parent); 0131 0132 /// Destroys the formula 0133 ~EnhancedPathFormula(); 0134 0135 /** 0136 * Evaluates the formula using the given path as possible input. 0137 * 0138 * @param path the path to use as input 0139 * @return the evaluated result 0140 */ 0141 qreal evaluate(); 0142 0143 /// Returns the last occurred error 0144 Error error() const 0145 { 0146 return m_error; 0147 } 0148 0149 /// returns string representation of the formula 0150 QString toString() const; 0151 private: 0152 /// Separates the given formula text into tokens. 0153 TokenList scan(const QString &formula) const; 0154 0155 /// Compiles the formula tokens into byte code 0156 bool compile(const TokenList &tokens); 0157 0158 /** 0159 * Evaluates a predefined function. 0160 * 0161 * @param function the identifier of the function to evaluate 0162 * @param arguments the functions arguments 0163 */ 0164 qreal evaluateFunction(Function function, const QList<qreal> &arguments) const; 0165 0166 /// Prints token list 0167 void debugTokens(const TokenList &tokens); 0168 /// Prints byte code 0169 void debugOpcodes(); 0170 0171 bool m_valid; ///< flag that shows if function is valid, i.e the function was compiled successfully 0172 bool m_compiled; ///< flag that shows if function was compiled 0173 Error m_error; ///< the last occurred error 0174 QString m_text; ///< the formula text representation 0175 QList<QVariant> m_constants; ///< constant values 0176 QList<Opcode> m_codes; ///< the compiled byte code 0177 EnhancedPathShape *m_parent; 0178 }; 0179 0180 #endif // KOENHANCEDPATHFORMULA_H