build: Updated libwolv
This commit is contained in:
parent
f26076fb90
commit
2cf642a2a4
@ -503,6 +503,7 @@ macro(addBundledLibraries)
|
|||||||
set_property(TARGET libwolv-hash PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET libwolv-hash PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
set_property(TARGET libwolv-containers PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET libwolv-containers PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
set_property(TARGET libwolv-net PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET libwolv-net PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
set_property(TARGET libwolv-math_eval PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
set(XDGPP_INCLUDE_DIRS "${THIRD_PARTY_LIBS_FOLDER}/xdgpp")
|
set(XDGPP_INCLUDE_DIRS "${THIRD_PARTY_LIBS_FOLDER}/xdgpp")
|
||||||
set(FPHSA_NAME_MISMATCHED ON CACHE BOOL "")
|
set(FPHSA_NAME_MISMATCHED ON CACHE BOOL "")
|
||||||
|
2
lib/external/libwolv
vendored
2
lib/external/libwolv
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 25430e1ad1b6061cd64c5afa8bb7ba71c234a22a
|
Subproject commit 71cddb8d45763168b701dfcd671e9f47f27ac897
|
2
lib/external/pattern_language
vendored
2
lib/external/pattern_language
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 7721876463431f9790c8e2ad0b87a37b6ab40889
|
Subproject commit 6021148991238aad9cb5deb465e19f0c82202a36
|
@ -94,7 +94,7 @@ elseif (APPLE)
|
|||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
target_link_libraries(libimhex PRIVATE ${FMT_LIBRARIES})
|
target_link_libraries(libimhex PRIVATE ${FMT_LIBRARIES})
|
||||||
target_link_libraries(libimhex PUBLIC dl ${IMGUI_LIBRARIES} ${NFD_LIBRARIES} magic ${CAPSTONE_LIBRARIES} LLVMDemangle microtar ${NLOHMANN_JSON_LIBRARIES} ${YARA_LIBRARIES} ${MBEDTLS_LIBRARIES} ${LIBBACKTRACE_LIBRARIES} plcli libpl libpl-gen ${MINIAUDIO_LIBRARIES} ${JTHREAD_LIBRARIES} libwolv-utils libwolv-io libwolv-hash libwolv-net libwolv-containers)
|
target_link_libraries(libimhex PUBLIC dl ${IMGUI_LIBRARIES} ${NFD_LIBRARIES} magic ${CAPSTONE_LIBRARIES} LLVMDemangle microtar ${NLOHMANN_JSON_LIBRARIES} ${YARA_LIBRARIES} ${MBEDTLS_LIBRARIES} ${LIBBACKTRACE_LIBRARIES} plcli libpl libpl-gen ${MINIAUDIO_LIBRARIES} ${JTHREAD_LIBRARIES} wolv::utils wolv::io wolv::hash wolv::net wolv::containers wolv::math_eval)
|
||||||
|
|
||||||
set_property(TARGET libimhex PROPERTY INTERPROCEDURAL_OPTIMIZATION FALSE)
|
set_property(TARGET libimhex PROPERTY INTERPROCEDURAL_OPTIMIZATION FALSE)
|
||||||
|
|
||||||
|
@ -42,11 +42,13 @@ namespace hex {
|
|||||||
this->m_functions.setImGuiContextFunction = getPluginFunction<PluginFunctions::SetImGuiContextFunc>("setImGuiContext");
|
this->m_functions.setImGuiContextFunction = getPluginFunction<PluginFunctions::SetImGuiContextFunc>("setImGuiContext");
|
||||||
this->m_functions.isBuiltinPluginFunction = getPluginFunction<PluginFunctions::IsBuiltinPluginFunc>("isBuiltinPlugin");
|
this->m_functions.isBuiltinPluginFunction = getPluginFunction<PluginFunctions::IsBuiltinPluginFunc>("isBuiltinPlugin");
|
||||||
this->m_functions.getSubCommandsFunction = getPluginFunction<PluginFunctions::GetSubCommandsFunc>("getSubCommands");
|
this->m_functions.getSubCommandsFunction = getPluginFunction<PluginFunctions::GetSubCommandsFunc>("getSubCommands");
|
||||||
|
|
||||||
|
log::info("Loaded plugin '{}'", wolv::util::toUTF8String(path.filename()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Plugin::Plugin(hex::PluginFunctions functions) {
|
Plugin::Plugin(hex::PluginFunctions functions) {
|
||||||
this->m_handle = 0;
|
this->m_handle = 0;
|
||||||
this->m_functions = std::move(functions);
|
this->m_functions = functions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -97,6 +99,8 @@ namespace hex {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log::info("Plugin '{}' initialized successfully", pluginName);
|
||||||
|
|
||||||
this->m_initialized = true;
|
this->m_initialized = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ add_executable(main-forwarder
|
|||||||
${IMHEX_ICON}
|
${IMHEX_ICON}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(main-forwarder PRIVATE libwolv-io ${FMT_LIBRARIES})
|
target_link_libraries(main-forwarder PRIVATE wolv::io ${FMT_LIBRARIES})
|
||||||
add_dependencies(imhex_all main-forwarder)
|
add_dependencies(imhex_all main-forwarder)
|
||||||
set_target_properties(main-forwarder PROPERTIES
|
set_target_properties(main-forwarder PROPERTIES
|
||||||
OUTPUT_NAME "imhex"
|
OUTPUT_NAME "imhex"
|
||||||
|
@ -5,7 +5,7 @@ add_executable(updater ${APPLICATION_TYPE}
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_compile_definitions(IMHEX_PROJECT_NAME="${PROJECT_NAME}")
|
add_compile_definitions(IMHEX_PROJECT_NAME="${PROJECT_NAME}")
|
||||||
target_link_libraries(updater PRIVATE libimhex libwolv-io ${FMT_LIBRARIES})
|
target_link_libraries(updater PRIVATE libimhex wolv::io ${FMT_LIBRARIES})
|
||||||
add_dependencies(imhex_all updater)
|
add_dependencies(imhex_all updater)
|
||||||
set_target_properties(updater PROPERTIES
|
set_target_properties(updater PROPERTIES
|
||||||
OUTPUT_NAME "imhex-updater"
|
OUTPUT_NAME "imhex-updater"
|
||||||
|
@ -104,7 +104,6 @@ add_imhex_plugin(
|
|||||||
source/content/views/view_achievements.cpp
|
source/content/views/view_achievements.cpp
|
||||||
source/content/views/view_yara.cpp
|
source/content/views/view_yara.cpp
|
||||||
|
|
||||||
source/content/helpers/math_evaluator.cpp
|
|
||||||
source/content/helpers/notification.cpp
|
source/content/helpers/notification.cpp
|
||||||
|
|
||||||
source/ui/hex_editor.cpp
|
source/ui/hex_editor.cpp
|
||||||
|
@ -1,127 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <hex.hpp>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <queue>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <functional>
|
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
namespace hex {
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
class MathEvaluator {
|
|
||||||
public:
|
|
||||||
MathEvaluator() = default;
|
|
||||||
|
|
||||||
struct Variable {
|
|
||||||
T value;
|
|
||||||
bool constant;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::optional<T> evaluate(const std::string &input);
|
|
||||||
|
|
||||||
void registerStandardVariables();
|
|
||||||
void registerStandardFunctions();
|
|
||||||
|
|
||||||
void setVariable(const std::string &name, T value, bool constant = false);
|
|
||||||
void setFunction(const std::string &name, const std::function<std::optional<T>(std::vector<T>)> &function, size_t minNumArgs, size_t maxNumArgs);
|
|
||||||
|
|
||||||
std::unordered_map<std::string, Variable> &getVariables() { return this->m_variables; }
|
|
||||||
|
|
||||||
[[nodiscard]] bool hasError() const {
|
|
||||||
return this->m_lastError.has_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] std::optional<std::string> getLastError() const {
|
|
||||||
return this->m_lastError;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void setError(const std::string &error) {
|
|
||||||
this->m_lastError = error;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum class TokenType
|
|
||||||
{
|
|
||||||
Number,
|
|
||||||
Variable,
|
|
||||||
Function,
|
|
||||||
Operator,
|
|
||||||
Bracket
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class Operator : u16
|
|
||||||
{
|
|
||||||
Invalid = 0x000,
|
|
||||||
Assign = 0x010,
|
|
||||||
Or = 0x020,
|
|
||||||
Xor = 0x030,
|
|
||||||
And = 0x040,
|
|
||||||
BitwiseOr = 0x050,
|
|
||||||
BitwiseXor = 0x060,
|
|
||||||
BitwiseAnd = 0x070,
|
|
||||||
Equals = 0x080,
|
|
||||||
NotEquals = 0x081,
|
|
||||||
GreaterThan = 0x090,
|
|
||||||
LessThan = 0x091,
|
|
||||||
GreaterThanOrEquals = 0x092,
|
|
||||||
LessThanOrEquals = 0x093,
|
|
||||||
ShiftLeft = 0x0A0,
|
|
||||||
ShiftRight = 0x0A1,
|
|
||||||
Addition = 0x0B0,
|
|
||||||
Subtraction = 0x0B1,
|
|
||||||
Multiplication = 0x0C0,
|
|
||||||
Division = 0x0C1,
|
|
||||||
Modulus = 0x0C2,
|
|
||||||
Exponentiation = 0x1D0,
|
|
||||||
Combine = 0x0E0,
|
|
||||||
BitwiseNot = 0x2F0,
|
|
||||||
Not = 0x2F1,
|
|
||||||
Plus = 0x2F2,
|
|
||||||
Minus = 0x2F3
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class BracketType : std::uint8_t
|
|
||||||
{
|
|
||||||
Left,
|
|
||||||
Right
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Token {
|
|
||||||
TokenType type;
|
|
||||||
|
|
||||||
union {
|
|
||||||
T number;
|
|
||||||
Operator op;
|
|
||||||
BracketType bracketType;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string name;
|
|
||||||
std::vector<T> arguments;
|
|
||||||
};
|
|
||||||
|
|
||||||
static i16 comparePrecedence(const Operator &a, const Operator &b);
|
|
||||||
static bool isLeftAssociative(const Operator &op);
|
|
||||||
static bool isUnary(const Operator &op);
|
|
||||||
static std::pair<Operator, size_t> toOperator(const std::string &input);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::optional<std::queue<Token>> parseInput(std::string input);
|
|
||||||
std::optional<std::queue<Token>> toPostfix(std::queue<Token> inputQueue);
|
|
||||||
std::optional<T> evaluate(std::queue<Token> postfixTokens);
|
|
||||||
|
|
||||||
std::unordered_map<std::string, Variable> m_variables;
|
|
||||||
std::unordered_map<std::string, std::function<std::optional<T>(std::vector<T>)>> m_functions;
|
|
||||||
|
|
||||||
std::optional<std::string> m_lastError;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern template class MathEvaluator<long double>;
|
|
||||||
extern template class MathEvaluator<i128>;
|
|
||||||
extern template class MathEvaluator<u128>;
|
|
||||||
|
|
||||||
}
|
|
@ -14,8 +14,7 @@
|
|||||||
#include <hex/subcommands/subcommands.hpp>
|
#include <hex/subcommands/subcommands.hpp>
|
||||||
|
|
||||||
#include <wolv/utils/string.hpp>
|
#include <wolv/utils/string.hpp>
|
||||||
|
#include <wolv/math_eval/math_evaluator.hpp>
|
||||||
#include "content/helpers/math_evaluator.hpp"
|
|
||||||
|
|
||||||
#include <pl/cli/cli.hpp>
|
#include <pl/cli/cli.hpp>
|
||||||
|
|
||||||
@ -94,7 +93,7 @@ namespace hex::plugin::builtin {
|
|||||||
std::exit(EXIT_FAILURE);
|
std::exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
MathEvaluator<long double> evaluator;
|
wolv::math_eval::MathEvaluator<long double> evaluator;
|
||||||
|
|
||||||
auto input = hex::format("{}", fmt::join(args, " "));
|
auto input = hex::format("{}", fmt::join(args, " "));
|
||||||
auto result = evaluator.evaluate(input);
|
auto result = evaluator.evaluate(input);
|
||||||
|
@ -6,8 +6,7 @@
|
|||||||
#include <hex/helpers/utils.hpp>
|
#include <hex/helpers/utils.hpp>
|
||||||
#include <hex/helpers/fmt.hpp>
|
#include <hex/helpers/fmt.hpp>
|
||||||
|
|
||||||
#include <content/helpers/math_evaluator.hpp>
|
#include <wolv/math_eval/math_evaluator.hpp>
|
||||||
|
|
||||||
#include <wolv/utils/string.hpp>
|
#include <wolv/utils/string.hpp>
|
||||||
|
|
||||||
namespace hex::plugin::builtin {
|
namespace hex::plugin::builtin {
|
||||||
@ -19,7 +18,7 @@ namespace hex::plugin::builtin {
|
|||||||
"#",
|
"#",
|
||||||
"hex.builtin.command.calc.desc",
|
"hex.builtin.command.calc.desc",
|
||||||
[](auto input) {
|
[](auto input) {
|
||||||
hex::MathEvaluator<long double> evaluator;
|
wolv::math_eval::MathEvaluator<long double> evaluator;
|
||||||
evaluator.registerStandardVariables();
|
evaluator.registerStandardVariables();
|
||||||
evaluator.registerStandardFunctions();
|
evaluator.registerStandardFunctions();
|
||||||
|
|
||||||
|
@ -1,501 +0,0 @@
|
|||||||
#include <content/helpers/math_evaluator.hpp>
|
|
||||||
|
|
||||||
#include <hex/helpers/utils.hpp>
|
|
||||||
#include <hex/helpers/concepts.hpp>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <queue>
|
|
||||||
#include <stack>
|
|
||||||
#include <cmath>
|
|
||||||
#include <optional>
|
|
||||||
#include <numbers>
|
|
||||||
|
|
||||||
namespace hex {
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
i16 MathEvaluator<T>::comparePrecedence(const Operator &a, const Operator &b) {
|
|
||||||
return (static_cast<i8>(a) & 0x0F0) - (static_cast<i8>(b) & 0x0F0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
bool MathEvaluator<T>::isLeftAssociative(const Operator &op) {
|
|
||||||
return (static_cast<u32>(op) & 0x100) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
bool MathEvaluator<T>::isUnary(const Operator &op) {
|
|
||||||
return (static_cast<u32>(op) & 0x200) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
std::pair<typename MathEvaluator<T>::Operator, size_t> MathEvaluator<T>::toOperator(const std::string &input) {
|
|
||||||
if (input.starts_with("##")) return { Operator::Combine, 2 };
|
|
||||||
if (input.starts_with("==")) return { Operator::Equals, 2 };
|
|
||||||
if (input.starts_with("!=")) return { Operator::NotEquals, 2 };
|
|
||||||
if (input.starts_with(">=")) return { Operator::GreaterThanOrEquals, 2 };
|
|
||||||
if (input.starts_with("<=")) return { Operator::LessThanOrEquals, 2 };
|
|
||||||
if (input.starts_with(">>")) return { Operator::ShiftRight, 2 };
|
|
||||||
if (input.starts_with("<<")) return { Operator::ShiftLeft, 2 };
|
|
||||||
if (input.starts_with("||")) return { Operator::Or, 2 };
|
|
||||||
if (input.starts_with("^^")) return { Operator::Xor, 2 };
|
|
||||||
if (input.starts_with("&&")) return { Operator::And, 2 };
|
|
||||||
if (input.starts_with("**")) return { Operator::Exponentiation, 2 };
|
|
||||||
if (input.starts_with(">")) return { Operator::GreaterThan, 1 };
|
|
||||||
if (input.starts_with("<")) return { Operator::LessThan, 1 };
|
|
||||||
if (input.starts_with("!")) return { Operator::Not, 1 };
|
|
||||||
if (input.starts_with("|")) return { Operator::BitwiseOr, 1 };
|
|
||||||
if (input.starts_with("^")) return { Operator::BitwiseXor, 1 };
|
|
||||||
if (input.starts_with("&")) return { Operator::BitwiseAnd, 1 };
|
|
||||||
if (input.starts_with("~")) return { Operator::BitwiseNot, 1 };
|
|
||||||
if (input.starts_with("+")) return { Operator::Addition, 1 };
|
|
||||||
if (input.starts_with("-")) return { Operator::Subtraction, 1 };
|
|
||||||
if (input.starts_with("*")) return { Operator::Multiplication, 1 };
|
|
||||||
if (input.starts_with("/")) return { Operator::Division, 1 };
|
|
||||||
if (input.starts_with("%")) return { Operator::Modulus, 1 };
|
|
||||||
if (input.starts_with("=")) return { Operator::Assign, 1 };
|
|
||||||
|
|
||||||
return { Operator::Invalid, 0 };
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
std::optional<std::queue<typename MathEvaluator<T>::Token>> MathEvaluator<T>::toPostfix(std::queue<Token> inputQueue) {
|
|
||||||
std::queue<Token> outputQueue;
|
|
||||||
std::stack<Token> operatorStack;
|
|
||||||
|
|
||||||
while (!inputQueue.empty()) {
|
|
||||||
Token currToken = inputQueue.front();
|
|
||||||
inputQueue.pop();
|
|
||||||
|
|
||||||
if (currToken.type == TokenType::Number || currToken.type == TokenType::Variable || currToken.type == TokenType::Function)
|
|
||||||
outputQueue.push(currToken);
|
|
||||||
else if (currToken.type == TokenType::Operator) {
|
|
||||||
while ((!operatorStack.empty()) && ((operatorStack.top().type == TokenType::Operator && currToken.type == TokenType::Operator && (comparePrecedence(operatorStack.top().op, currToken.op) > 0)) || (comparePrecedence(operatorStack.top().op, currToken.op) == 0 && isLeftAssociative(currToken.op))) && operatorStack.top().type != TokenType::Bracket) {
|
|
||||||
outputQueue.push(operatorStack.top());
|
|
||||||
operatorStack.pop();
|
|
||||||
}
|
|
||||||
operatorStack.push(currToken);
|
|
||||||
} else if (currToken.type == TokenType::Bracket) {
|
|
||||||
if (currToken.bracketType == BracketType::Left)
|
|
||||||
operatorStack.push(currToken);
|
|
||||||
else {
|
|
||||||
if (operatorStack.empty()) {
|
|
||||||
this->setError("Mismatching parenthesis!");
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (operatorStack.top().type != TokenType::Bracket || (operatorStack.top().type == TokenType::Bracket && operatorStack.top().bracketType != BracketType::Left)) {
|
|
||||||
if (operatorStack.empty()) {
|
|
||||||
this->setError("Mismatching parenthesis!");
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
outputQueue.push(operatorStack.top());
|
|
||||||
operatorStack.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
operatorStack.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!operatorStack.empty()) {
|
|
||||||
auto top = operatorStack.top();
|
|
||||||
|
|
||||||
if (top.type == TokenType::Bracket) {
|
|
||||||
this->setError("Mismatching parenthesis!");
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
outputQueue.push(top);
|
|
||||||
operatorStack.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
return outputQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
std::optional<std::queue<typename MathEvaluator<T>::Token>> MathEvaluator<T>::parseInput(std::string input) {
|
|
||||||
std::queue<Token> inputQueue;
|
|
||||||
|
|
||||||
char *prevPos = input.data();
|
|
||||||
for (char *pos = prevPos; *pos != 0x00;) {
|
|
||||||
if (std::isdigit(*pos) || *pos == '.') {
|
|
||||||
auto number = [&] {
|
|
||||||
if constexpr (std::floating_point<T>)
|
|
||||||
return std::strtold(pos, &pos);
|
|
||||||
else if constexpr (std::signed_integral<T>)
|
|
||||||
return std::strtoll(pos, &pos, 10);
|
|
||||||
else if constexpr (std::unsigned_integral<T>)
|
|
||||||
return std::strtoull(pos, &pos, 10);
|
|
||||||
else
|
|
||||||
static_assert(hex::always_false<T>::value, "Can't parse literal of this type");
|
|
||||||
}();
|
|
||||||
|
|
||||||
if (*pos == 'x') {
|
|
||||||
pos--;
|
|
||||||
number = std::strtoull(pos, &pos, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
inputQueue.push(Token { .type = TokenType::Number, .number = number, .name = "", .arguments = { } });
|
|
||||||
} else if (*pos == '(') {
|
|
||||||
inputQueue.push(Token { .type = TokenType::Bracket, .bracketType = BracketType::Left, .name = "", .arguments = { } });
|
|
||||||
pos++;
|
|
||||||
} else if (*pos == ')') {
|
|
||||||
inputQueue.push(Token { .type = TokenType::Bracket, .bracketType = BracketType::Right, .name = "", .arguments = { } });
|
|
||||||
pos++;
|
|
||||||
} else if (std::isspace(*pos)) {
|
|
||||||
pos++;
|
|
||||||
} else {
|
|
||||||
auto [op, width] = toOperator(pos);
|
|
||||||
|
|
||||||
if (!inputQueue.empty()) {
|
|
||||||
auto token = inputQueue.back();
|
|
||||||
|
|
||||||
if (token.type == TokenType::Operator || (token.type == TokenType::Bracket && token.bracketType == BracketType::Left)) {
|
|
||||||
if (op == Operator::Addition)
|
|
||||||
op = Operator::Plus;
|
|
||||||
else if (op == Operator::Subtraction)
|
|
||||||
op = Operator::Minus;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (op != Operator::Invalid) {
|
|
||||||
inputQueue.push(Token { .type = TokenType::Operator, .op = op, .name = "", .arguments = { } });
|
|
||||||
pos += width;
|
|
||||||
} else {
|
|
||||||
Token token;
|
|
||||||
|
|
||||||
while (std::isalpha(*pos) || *pos == '_') {
|
|
||||||
token.name += *pos;
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*pos == '(') {
|
|
||||||
pos++;
|
|
||||||
|
|
||||||
u32 depth = 1;
|
|
||||||
std::vector<std::string> expressions;
|
|
||||||
expressions.emplace_back();
|
|
||||||
|
|
||||||
while (*pos != 0x00) {
|
|
||||||
if (*pos == '(') depth++;
|
|
||||||
else if (*pos == ')') depth--;
|
|
||||||
|
|
||||||
if (depth == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (depth == 1 && *pos == ',') {
|
|
||||||
expressions.emplace_back();
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
expressions.back() += *pos;
|
|
||||||
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos++;
|
|
||||||
|
|
||||||
for (const auto &expression : expressions) {
|
|
||||||
if (expression.empty() && expressions.size() > 1) {
|
|
||||||
this->setError("Invalid function call syntax!");
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
else if (expression.empty())
|
|
||||||
break;
|
|
||||||
|
|
||||||
auto newInputQueue = parseInput(expression);
|
|
||||||
if (!newInputQueue.has_value())
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
auto postfixTokens = toPostfix(*newInputQueue);
|
|
||||||
if (!postfixTokens.has_value())
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
auto result = evaluate(*postfixTokens);
|
|
||||||
if (!result.has_value()) {
|
|
||||||
this->setError("Invalid argument for function!");
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
token.arguments.push_back(result.value());
|
|
||||||
}
|
|
||||||
|
|
||||||
token.type = TokenType::Function;
|
|
||||||
inputQueue.push(token);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
token.type = TokenType::Variable;
|
|
||||||
inputQueue.push(token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prevPos == pos) {
|
|
||||||
this->setError("Invalid syntax!");
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
prevPos = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
return inputQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
std::optional<T> MathEvaluator<T>::evaluate(std::queue<Token> postfixTokens) {
|
|
||||||
std::stack<T> evaluationStack;
|
|
||||||
|
|
||||||
while (!postfixTokens.empty()) {
|
|
||||||
auto front = postfixTokens.front();
|
|
||||||
postfixTokens.pop();
|
|
||||||
|
|
||||||
if (front.type == TokenType::Number)
|
|
||||||
evaluationStack.push(front.number);
|
|
||||||
else if (front.type == TokenType::Operator) {
|
|
||||||
T rightOperand, leftOperand;
|
|
||||||
if (isUnary(front.op)) {
|
|
||||||
if (evaluationStack.size() < 1) {
|
|
||||||
this->setError("Not enough operands for operator!");
|
|
||||||
return std::nullopt;
|
|
||||||
} else {
|
|
||||||
rightOperand = evaluationStack.top();
|
|
||||||
evaluationStack.pop();
|
|
||||||
leftOperand = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (evaluationStack.size() < 2) {
|
|
||||||
this->setError("Not enough operands for operator!");
|
|
||||||
return std::nullopt;
|
|
||||||
} else {
|
|
||||||
rightOperand = evaluationStack.top();
|
|
||||||
evaluationStack.pop();
|
|
||||||
leftOperand = evaluationStack.top();
|
|
||||||
evaluationStack.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
T result = [] {
|
|
||||||
if constexpr (std::numeric_limits<T>::has_quiet_NaN)
|
|
||||||
return std::numeric_limits<T>::quiet_NaN();
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}();
|
|
||||||
switch (front.op) {
|
|
||||||
default:
|
|
||||||
case Operator::Invalid:
|
|
||||||
this->setError("Invalid operator!");
|
|
||||||
return std::nullopt;
|
|
||||||
case Operator::And:
|
|
||||||
result = static_cast<i64>(leftOperand) && static_cast<i64>(rightOperand);
|
|
||||||
break;
|
|
||||||
case Operator::Or:
|
|
||||||
result = static_cast<i64>(leftOperand) || static_cast<i64>(rightOperand);
|
|
||||||
break;
|
|
||||||
case Operator::Xor:
|
|
||||||
result = (static_cast<i64>(leftOperand) ^ static_cast<i64>(rightOperand)) > 0;
|
|
||||||
break;
|
|
||||||
case Operator::GreaterThan:
|
|
||||||
result = leftOperand > rightOperand;
|
|
||||||
break;
|
|
||||||
case Operator::LessThan:
|
|
||||||
result = leftOperand < rightOperand;
|
|
||||||
break;
|
|
||||||
case Operator::GreaterThanOrEquals:
|
|
||||||
result = leftOperand >= rightOperand;
|
|
||||||
break;
|
|
||||||
case Operator::LessThanOrEquals:
|
|
||||||
result = leftOperand <= rightOperand;
|
|
||||||
break;
|
|
||||||
case Operator::Equals:
|
|
||||||
result = leftOperand == rightOperand;
|
|
||||||
break;
|
|
||||||
case Operator::NotEquals:
|
|
||||||
result = leftOperand != rightOperand;
|
|
||||||
break;
|
|
||||||
case Operator::Not:
|
|
||||||
result = !static_cast<i64>(rightOperand);
|
|
||||||
break;
|
|
||||||
case Operator::BitwiseOr:
|
|
||||||
result = static_cast<i64>(leftOperand) | static_cast<i64>(rightOperand);
|
|
||||||
break;
|
|
||||||
case Operator::BitwiseXor:
|
|
||||||
result = static_cast<i64>(leftOperand) ^ static_cast<i64>(rightOperand);
|
|
||||||
break;
|
|
||||||
case Operator::BitwiseAnd:
|
|
||||||
result = static_cast<i64>(leftOperand) & static_cast<i64>(rightOperand);
|
|
||||||
break;
|
|
||||||
case Operator::BitwiseNot:
|
|
||||||
result = ~static_cast<i64>(rightOperand);
|
|
||||||
break;
|
|
||||||
case Operator::ShiftLeft:
|
|
||||||
result = static_cast<i64>(leftOperand) << static_cast<i64>(rightOperand);
|
|
||||||
break;
|
|
||||||
case Operator::ShiftRight:
|
|
||||||
result = static_cast<i64>(leftOperand) >> static_cast<i64>(rightOperand);
|
|
||||||
break;
|
|
||||||
case Operator::Addition:
|
|
||||||
result = leftOperand + rightOperand;
|
|
||||||
break;
|
|
||||||
case Operator::Subtraction:
|
|
||||||
result = leftOperand - rightOperand;
|
|
||||||
break;
|
|
||||||
case Operator::Multiplication:
|
|
||||||
result = leftOperand * rightOperand;
|
|
||||||
break;
|
|
||||||
case Operator::Division:
|
|
||||||
result = leftOperand / rightOperand;
|
|
||||||
break;
|
|
||||||
case Operator::Modulus:
|
|
||||||
if constexpr (std::floating_point<T>)
|
|
||||||
result = std::fmod(leftOperand, rightOperand);
|
|
||||||
else
|
|
||||||
result = leftOperand % rightOperand;
|
|
||||||
break;
|
|
||||||
case Operator::Exponentiation:
|
|
||||||
if constexpr (std::floating_point<T>)
|
|
||||||
result = std::pow(leftOperand, rightOperand);
|
|
||||||
else
|
|
||||||
result = hex::powi(leftOperand, rightOperand);
|
|
||||||
break;
|
|
||||||
case Operator::Combine:
|
|
||||||
result = (static_cast<u64>(leftOperand) << (64 - __builtin_clzll(static_cast<u64>(rightOperand)))) | static_cast<u64>(rightOperand);
|
|
||||||
break;
|
|
||||||
case Operator::Plus:
|
|
||||||
result = +rightOperand;
|
|
||||||
break;
|
|
||||||
case Operator::Minus:
|
|
||||||
result = -rightOperand;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
evaluationStack.push(result);
|
|
||||||
} else if (front.type == TokenType::Variable) {
|
|
||||||
if (this->m_variables.contains(front.name))
|
|
||||||
evaluationStack.push(this->m_variables.at(front.name).value);
|
|
||||||
else {
|
|
||||||
this->setError("Unknown variable!");
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
} else if (front.type == TokenType::Function) {
|
|
||||||
if (!this->m_functions[front.name]) {
|
|
||||||
this->setError("Unknown function called!");
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto result = this->m_functions[front.name](front.arguments);
|
|
||||||
|
|
||||||
if (result.has_value())
|
|
||||||
evaluationStack.push(result.value());
|
|
||||||
} else {
|
|
||||||
this->setError("Parenthesis in postfix expression!");
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (evaluationStack.empty()) {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
else if (evaluationStack.size() > 1) {
|
|
||||||
this->setError("Undigested input left!");
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return evaluationStack.top();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
std::optional<T> MathEvaluator<T>::evaluate(const std::string &input) {
|
|
||||||
auto inputQueue = parseInput(input);
|
|
||||||
if (!inputQueue.has_value() || inputQueue->empty())
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
std::string resultVariable = "ans";
|
|
||||||
|
|
||||||
{
|
|
||||||
auto queueCopy = *inputQueue;
|
|
||||||
if (queueCopy.front().type == TokenType::Variable && queueCopy.size() > 2) {
|
|
||||||
resultVariable = queueCopy.front().name;
|
|
||||||
queueCopy.pop();
|
|
||||||
if (queueCopy.front().type != TokenType::Operator || queueCopy.front().op != Operator::Assign)
|
|
||||||
resultVariable = "ans";
|
|
||||||
else {
|
|
||||||
inputQueue->pop();
|
|
||||||
inputQueue->pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto postfixTokens = toPostfix(*inputQueue);
|
|
||||||
if (!postfixTokens.has_value())
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
auto result = evaluate(*postfixTokens);
|
|
||||||
|
|
||||||
if (result.has_value() && !this->getVariables()[resultVariable].constant)
|
|
||||||
this->setVariable(resultVariable, result.value());
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void MathEvaluator<T>::setVariable(const std::string &name, T value, bool constant) {
|
|
||||||
this->m_variables[name] = { value, constant };
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void MathEvaluator<T>::setFunction(const std::string &name, const std::function<std::optional<T>(std::vector<T>)> &function, size_t minNumArgs, size_t maxNumArgs) {
|
|
||||||
this->m_functions[name] = [this, minNumArgs, maxNumArgs, function](auto args) -> std::optional<T> {
|
|
||||||
if (args.size() < minNumArgs || args.size() > maxNumArgs) {
|
|
||||||
this->setError("Invalid number of function arguments!");
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
return function(args);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void MathEvaluator<T>::registerStandardVariables() {
|
|
||||||
this->setVariable("ans", 0);
|
|
||||||
this->setVariable("pi", std::numbers::pi, true);
|
|
||||||
this->setVariable("e", std::numbers::e, true);
|
|
||||||
this->setVariable("phi", std::numbers::phi, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void MathEvaluator<T>::registerStandardFunctions() {
|
|
||||||
if constexpr (std::floating_point<T>) {
|
|
||||||
this->setFunction(
|
|
||||||
"sin", [](auto args) { return std::sin(args[0]); }, 1, 1);
|
|
||||||
this->setFunction(
|
|
||||||
"cos", [](auto args) { return std::cos(args[0]); }, 1, 1);
|
|
||||||
this->setFunction(
|
|
||||||
"tan", [](auto args) { return std::tan(args[0]); }, 1, 1);
|
|
||||||
this->setFunction(
|
|
||||||
"sqrt", [](auto args) { return std::sqrt(args[0]); }, 1, 1);
|
|
||||||
this->setFunction(
|
|
||||||
"ceil", [](auto args) { return std::ceil(args[0]); }, 1, 1);
|
|
||||||
this->setFunction(
|
|
||||||
"floor", [](auto args) { return std::floor(args[0]); }, 1, 1);
|
|
||||||
this->setFunction(
|
|
||||||
"sign", [](auto args) { return (args[0] > 0) ? 1 : (args[0] == 0) ? 0 : -1; }, 1, 1);
|
|
||||||
this->setFunction(
|
|
||||||
"abs", [](auto args) { return std::abs(args[0]); }, 1, 1);
|
|
||||||
this->setFunction(
|
|
||||||
"ln", [](auto args) { return std::log(args[0]); }, 1, 1);
|
|
||||||
this->setFunction(
|
|
||||||
"lb", [](auto args) { return std::log2(args[0]); }, 1, 1);
|
|
||||||
this->setFunction(
|
|
||||||
"log", [](auto args) { return args.size() == 1 ? std::log10(args[0]) : std::log(args[1]) / std::log(args[0]); }, 1, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template class MathEvaluator<long double>;
|
|
||||||
template class MathEvaluator<i128>;
|
|
||||||
template class MathEvaluator<u128>;
|
|
||||||
|
|
||||||
}
|
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <hex/api/localization_manager.hpp>
|
#include <hex/api/localization_manager.hpp>
|
||||||
|
|
||||||
#include <content/helpers/math_evaluator.hpp>
|
#include <wolv/math_eval/math_evaluator.hpp>
|
||||||
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <hex/helpers/http_requests.hpp>
|
#include <hex/helpers/http_requests.hpp>
|
||||||
|
|
||||||
#include <content/helpers/math_evaluator.hpp>
|
#include <wolv/math_eval/math_evaluator.hpp>
|
||||||
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <implot.h>
|
#include <implot.h>
|
||||||
@ -31,7 +31,7 @@ namespace hex::plugin::builtin {
|
|||||||
ImGui::PopItemWidth();
|
ImGui::PopItemWidth();
|
||||||
|
|
||||||
if ((prevPos != limits.X.Min && (ImGui::IsMouseReleased(ImGuiMouseButton_Left) || ImGui::GetIO().MouseWheel != 0)) || (ImGui::IsItemFocused() && ImGui::IsKeyPressed(ImGuiKey_Enter))) {
|
if ((prevPos != limits.X.Min && (ImGui::IsMouseReleased(ImGuiMouseButton_Left) || ImGui::GetIO().MouseWheel != 0)) || (ImGui::IsItemFocused() && ImGui::IsKeyPressed(ImGuiKey_Enter))) {
|
||||||
MathEvaluator<long double> evaluator;
|
wolv::math_eval::MathEvaluator<long double> evaluator;
|
||||||
|
|
||||||
y = {};
|
y = {};
|
||||||
|
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
#include <hex/api/imhex_api.hpp>
|
#include <hex/api/imhex_api.hpp>
|
||||||
#include <hex/providers/provider.hpp>
|
#include <hex/providers/provider.hpp>
|
||||||
#include <hex/helpers/utils.hpp>
|
#include <hex/helpers/utils.hpp>
|
||||||
#include <content/helpers/math_evaluator.hpp>
|
|
||||||
|
#include <wolv/math_eval/math_evaluator.hpp>
|
||||||
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <hex/ui/imgui_imhex_extensions.h>
|
#include <hex/ui/imgui_imhex_extensions.h>
|
||||||
@ -20,8 +21,8 @@ namespace hex::plugin::builtin {
|
|||||||
static std::string mathInput;
|
static std::string mathInput;
|
||||||
bool evaluate = false;
|
bool evaluate = false;
|
||||||
|
|
||||||
static MathEvaluator<long double> mathEvaluator = [&] {
|
static wolv::math_eval::MathEvaluator<long double> mathEvaluator = [&] {
|
||||||
MathEvaluator<long double> evaluator;
|
wolv::math_eval::MathEvaluator<long double> evaluator;
|
||||||
|
|
||||||
evaluator.registerStandardVariables();
|
evaluator.registerStandardVariables();
|
||||||
evaluator.registerStandardFunctions();
|
evaluator.registerStandardFunctions();
|
||||||
|
@ -10,8 +10,9 @@
|
|||||||
|
|
||||||
#include <hex/providers/buffered_reader.hpp>
|
#include <hex/providers/buffered_reader.hpp>
|
||||||
|
|
||||||
|
#include <wolv/math_eval/math_evaluator.hpp>
|
||||||
|
|
||||||
#include <content/providers/view_provider.hpp>
|
#include <content/providers/view_provider.hpp>
|
||||||
#include <content/helpers/math_evaluator.hpp>
|
|
||||||
#include <content/popups/popup_file_chooser.hpp>
|
#include <content/popups/popup_file_chooser.hpp>
|
||||||
|
|
||||||
#include <imgui_internal.h>
|
#include <imgui_internal.h>
|
||||||
@ -101,7 +102,7 @@ namespace hex::plugin::builtin {
|
|||||||
|
|
||||||
bool m_requestFocus = true;
|
bool m_requestFocus = true;
|
||||||
std::string m_input;
|
std::string m_input;
|
||||||
MathEvaluator<i128> m_evaluator;
|
wolv::math_eval::MathEvaluator<i128> m_evaluator;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PopupSelect : public ViewHexEditor::Popup {
|
class PopupSelect : public ViewHexEditor::Popup {
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include <hex/api/localization_manager.hpp>
|
#include <hex/api/localization_manager.hpp>
|
||||||
|
|
||||||
#include <hex/helpers/utils.hpp>
|
#include <hex/helpers/utils.hpp>
|
||||||
#include <content/helpers/math_evaluator.hpp>
|
#include <wolv/math_eval/math_evaluator.hpp>
|
||||||
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <hex/ui/imgui_imhex_extensions.h>
|
#include <hex/ui/imgui_imhex_extensions.h>
|
||||||
@ -450,7 +450,7 @@ namespace hex::plugin::builtin::ui {
|
|||||||
}
|
}
|
||||||
} else if (std::holds_alternative<i128>(value)) {
|
} else if (std::holds_alternative<i128>(value)) {
|
||||||
if (ImGui::InputText("##Value", valueString, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) {
|
if (ImGui::InputText("##Value", valueString, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) {
|
||||||
MathEvaluator<i128> mathEvaluator;
|
wolv::math_eval::MathEvaluator<i128> mathEvaluator;
|
||||||
|
|
||||||
if (auto result = mathEvaluator.evaluate(valueString); result.has_value())
|
if (auto result = mathEvaluator.evaluate(valueString); result.has_value())
|
||||||
pattern.setValue(result.value());
|
pattern.setValue(result.value());
|
||||||
@ -459,7 +459,7 @@ namespace hex::plugin::builtin::ui {
|
|||||||
}
|
}
|
||||||
} else if (std::holds_alternative<u128>(value)) {
|
} else if (std::holds_alternative<u128>(value)) {
|
||||||
if (ImGui::InputText("##Value", valueString, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) {
|
if (ImGui::InputText("##Value", valueString, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) {
|
||||||
MathEvaluator<u128> mathEvaluator;
|
wolv::math_eval::MathEvaluator<u128> mathEvaluator;
|
||||||
|
|
||||||
if (auto result = mathEvaluator.evaluate(valueString); result.has_value())
|
if (auto result = mathEvaluator.evaluate(valueString); result.has_value())
|
||||||
pattern.setValue(result.value());
|
pattern.setValue(result.value());
|
||||||
@ -614,7 +614,7 @@ namespace hex::plugin::builtin::ui {
|
|||||||
|
|
||||||
auto value = pattern.toString();
|
auto value = pattern.toString();
|
||||||
if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) {
|
if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) {
|
||||||
MathEvaluator<long double> mathEvaluator;
|
wolv::math_eval::MathEvaluator<long double> mathEvaluator;
|
||||||
|
|
||||||
if (auto result = mathEvaluator.evaluate(value); result.has_value())
|
if (auto result = mathEvaluator.evaluate(value); result.has_value())
|
||||||
pattern.setValue(double(result.value()));
|
pattern.setValue(double(result.value()));
|
||||||
@ -670,7 +670,7 @@ namespace hex::plugin::builtin::ui {
|
|||||||
|
|
||||||
auto value = pattern.getFormattedValue();
|
auto value = pattern.getFormattedValue();
|
||||||
if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) {
|
if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) {
|
||||||
MathEvaluator<i128> mathEvaluator;
|
wolv::math_eval::MathEvaluator<i128> mathEvaluator;
|
||||||
|
|
||||||
if (auto result = mathEvaluator.evaluate(value); result.has_value())
|
if (auto result = mathEvaluator.evaluate(value); result.has_value())
|
||||||
pattern.setValue(result.value());
|
pattern.setValue(result.value());
|
||||||
@ -817,7 +817,7 @@ namespace hex::plugin::builtin::ui {
|
|||||||
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
|
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
auto value = pattern.toString();
|
auto value = pattern.toString();
|
||||||
if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) {
|
if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) {
|
||||||
MathEvaluator<u128> mathEvaluator;
|
wolv::math_eval::MathEvaluator<u128> mathEvaluator;
|
||||||
|
|
||||||
if (auto result = mathEvaluator.evaluate(value); result.has_value())
|
if (auto result = mathEvaluator.evaluate(value); result.has_value())
|
||||||
pattern.setValue(result.value());
|
pattern.setValue(result.value());
|
||||||
|
Loading…
Reference in New Issue
Block a user