Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
@@ -0,0 +1,257 @@
|
||||
// **************************************************************************
|
||||
//
|
||||
// (C) Copyright 2009 Swiss SIMTEC AG
|
||||
//
|
||||
// **************************************************************************
|
||||
//
|
||||
// $HeadURL$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $LastChangedRevision$
|
||||
//
|
||||
// **************************************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace N_SST
|
||||
{
|
||||
/**
|
||||
* This class calculates algebraic texts with integer values and returns its
|
||||
* result as a signed value. It handles the operations - +, -, *, /, %, <<, >>. It
|
||||
* understands the paranthesis and priorities of operations, like * before -. It
|
||||
* also computes with variables, which names are case-sensitive. The values can be
|
||||
* decimal, hexadecimal (0x) or binary (0b). The variable-system implemented
|
||||
* virtual, so you can implement your own variable system (see getVariableValue()).
|
||||
*
|
||||
*
|
||||
* @author alois.wismer
|
||||
* @version 1.0
|
||||
* @created 12-Mai-2010 16:26:43
|
||||
*/
|
||||
class IntegerCalculator
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Describes the error happend while calculation of an expression
|
||||
*
|
||||
* @author alois.wismer
|
||||
* @version 1.0
|
||||
* @created 17-Mai-2010 16:38:24
|
||||
*/
|
||||
enum E_Error
|
||||
{
|
||||
/**
|
||||
* No error happend
|
||||
*/
|
||||
e_Ok,
|
||||
/**
|
||||
* The divisor is 0
|
||||
*/
|
||||
e_DivisionByZero,
|
||||
/**
|
||||
* The operation/variable is not known. a_addErrorText will contain the unknown
|
||||
* operation/variable.
|
||||
*/
|
||||
e_UnknownOperationOrVariable,
|
||||
/**
|
||||
* Between to operators no variable/operand exists. a_addErrorText contains the 2
|
||||
* operations.
|
||||
*/
|
||||
e_NoOperandBetweenOperators,
|
||||
/**
|
||||
* The operand contains invalid characters. a_addErrorText contains the invalid
|
||||
* operand.
|
||||
*/
|
||||
e_InvalidOperand,
|
||||
/**
|
||||
* There are more ) than (
|
||||
*/
|
||||
e_MissingLeftParanthesis,
|
||||
/**
|
||||
* There are more ) than (
|
||||
*/
|
||||
e_MissingRightParanthesis,
|
||||
/**
|
||||
* Something else went wrong
|
||||
*/
|
||||
e_UnknownError
|
||||
};
|
||||
|
||||
|
||||
IntegerCalculator();
|
||||
virtual ~IntegerCalculator() = default;
|
||||
|
||||
/**
|
||||
* Converts the expressen in a_calcText into a signed value. Returns whether an
|
||||
* error happend in the variable a_error. If an error happend, the variable
|
||||
* a_addErrorText can contain more informaition about the error (see E_Error for
|
||||
* more information about errors).
|
||||
*
|
||||
* @param a_calcText
|
||||
* @param a_error
|
||||
* @param a_addErrorText
|
||||
*/
|
||||
int64_t calc(const std::string& a_calcText, E_Error& a_error, std::string* a_addErrorText = nullptr);
|
||||
|
||||
/**
|
||||
* Adds or changes a case-sensitive variable to the calculator.
|
||||
*
|
||||
* @param a_name
|
||||
* @param a_value
|
||||
*/
|
||||
void addVariable(const std::string& a_name, const int64_t a_value);
|
||||
|
||||
/**
|
||||
* Removes a case-sensitive variable from the calculator.
|
||||
*
|
||||
* @param a_name
|
||||
*/
|
||||
void removeVariable(const std::string& a_name);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Contains all supported operations
|
||||
*/
|
||||
const std::map<std::string, int> m_OperationList;
|
||||
/**
|
||||
* Contains all variables
|
||||
*/
|
||||
std::map<std::string, int64_t> m_VariableList;
|
||||
/**
|
||||
* The additional text for errors
|
||||
*/
|
||||
std::string m_AdditionalErrorText;
|
||||
/**
|
||||
* The number of open paranthesis
|
||||
*/
|
||||
int32_t m_ParanthesisCount;
|
||||
E_Error m_Error;
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the expression (recursive)
|
||||
*
|
||||
* @param a_calcText
|
||||
* @param a_pos
|
||||
* @param a_IsEndParanthesis
|
||||
* @param a_prevOp
|
||||
* @param a_prevValue
|
||||
* @param a_initOp
|
||||
*/
|
||||
int64_t calc(const std::string& a_calcText, size_t& a_pos, bool& a_IsEndParanthesis,
|
||||
const std::string& a_prevOp = std::string(), const int64_t a_prevValue = 0,
|
||||
const std::string& a_initOp = std::string());
|
||||
|
||||
/**
|
||||
* Calculates an operation with respecting the priority of operations. This will
|
||||
* be done with recursion.
|
||||
*
|
||||
* @param a_calcText
|
||||
* @param a_pos
|
||||
* @param a_value1
|
||||
* @param a_operation
|
||||
* @param a_value2
|
||||
* @param a_prevOp
|
||||
*/
|
||||
bool calcWithPriority(const std::string& a_calcText, size_t& a_pos, int64_t& a_value1,
|
||||
std::string& a_operation, int64_t a_value2, const std::string& a_prevOp);
|
||||
|
||||
/**
|
||||
* Returns the inverted a_value if a_isNegative is true. a_isNegative will be
|
||||
* false after calling this function.
|
||||
* If a_isNegative is true, the NOT inverted a_value will be returned.
|
||||
*
|
||||
* @param a_value
|
||||
* @param a_isNegative
|
||||
*/
|
||||
static int64_t calcSign(const int64_t a_value, bool& a_isNegative);
|
||||
|
||||
/**
|
||||
* Converts the value in form of text to a number. The Text can be decimal, hex
|
||||
* (0x) or binary (0b).
|
||||
*
|
||||
* @param a_valueText
|
||||
* @param a_pos
|
||||
*/
|
||||
int64_t convertValue(const std::string& a_valueText, size_t& a_pos);
|
||||
|
||||
/**
|
||||
* Returns the next token (with space as separator). Heading spaces will be
|
||||
* ignored.
|
||||
*
|
||||
* @param a_calcText
|
||||
* @param a_pos
|
||||
*/
|
||||
static std::string getToken(const std::string& a_calcText, size_t& a_pos);
|
||||
|
||||
/**
|
||||
* returns true if a_operation is a known operation.
|
||||
*
|
||||
* @param a_operation
|
||||
*/
|
||||
bool isOperation(const std::string& a_operation) const;
|
||||
|
||||
/**
|
||||
* Calculates the opeation a_operations with a_value1 as first and a_value2 as
|
||||
* second operand.
|
||||
*
|
||||
* @param a_value1
|
||||
* @param a_operation
|
||||
* @param a_value2
|
||||
*/
|
||||
int64_t doOperation(const int64_t a_value1, const std::string& a_operation, const int64_t a_value2);
|
||||
|
||||
/**
|
||||
* returns true if priority of a_opeation1 is higher than priority of a_operation2.
|
||||
*
|
||||
*
|
||||
* @param a_operation1
|
||||
* @param a_operation2
|
||||
*/
|
||||
bool isOperationPriorityHigher(const std::string& a_operation1, const std::string& a_operation2) const;
|
||||
|
||||
/**
|
||||
* Returns true if the variable named a_variableName is known and a_value will be
|
||||
* filled with its value. If the variable is not found false will be returned.
|
||||
* Overload this virtual function if you want to implement your own variable-list.
|
||||
*
|
||||
* @param a_variableName
|
||||
* @param a_value
|
||||
*/
|
||||
virtual bool getVariableValue(const std::string& a_variableName, int64_t& a_value) const;
|
||||
|
||||
/**
|
||||
* Returns true if a_char is a digit. When a_isHex is true, also the charactes a-f
|
||||
* will be accepted as digits. When a_isBin is true, only 0 and 1 will be treated
|
||||
* as digit.
|
||||
*
|
||||
* @param a_char
|
||||
* @param a_isHex
|
||||
* @param a_isBin
|
||||
*/
|
||||
static bool isDigit(const char a_char, const bool a_isHex = false, const bool a_isBin = false);
|
||||
|
||||
/**
|
||||
* Returns the priority of the operation. A higher value means more priority.
|
||||
*
|
||||
* @param a_operation
|
||||
*/
|
||||
int16_t getPriority(const std::string& a_operation) const;
|
||||
|
||||
/**
|
||||
* replaces in a_haystack all a_searchText with a_replaceText (not greedy).
|
||||
*
|
||||
* @param a_haystack
|
||||
* @param a_searchText
|
||||
* @param a_replaceText
|
||||
*/
|
||||
static void replace(std::string& a_haystack, const std::string& a_searchText, const std::string& a_replaceText);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user