diff --git a/plugins/libimhex/include/hex/lang/token.hpp b/plugins/libimhex/include/hex/lang/token.hpp index a01edbcc0..b5a75bcdf 100644 --- a/plugins/libimhex/include/hex/lang/token.hpp +++ b/plugins/libimhex/include/hex/lang/token.hpp @@ -102,7 +102,8 @@ namespace hex::lang { EndOfProgram }; - using IntegerLiteral = std::pair>; + using Integers = std::variant; + using IntegerLiteral = std::pair; using ValueTypes = std::variant; Token(Type type, auto value, u32 lineNumber) : type(type), value(value), lineNumber(lineNumber) { @@ -125,6 +126,27 @@ namespace hex::lang { return static_cast(type) >> 4; } + [[nodiscard]] constexpr static inline IntegerLiteral castTo(ValueType type, const Integers &literal) { + return std::visit([type](auto &&value) { + switch (type) { + case ValueType::Signed8Bit: return IntegerLiteral(type, static_cast(value)); + case ValueType::Signed16Bit: return IntegerLiteral(type, static_cast(value)); + case ValueType::Signed32Bit: return IntegerLiteral(type, static_cast(value)); + case ValueType::Signed64Bit: return IntegerLiteral(type, static_cast(value)); + case ValueType::Signed128Bit: return IntegerLiteral(type, static_cast(value)); + case ValueType::Unsigned8Bit: return IntegerLiteral(type, static_cast(value)); + case ValueType::Unsigned16Bit: return IntegerLiteral(type, static_cast(value)); + case ValueType::Unsigned32Bit: return IntegerLiteral(type, static_cast(value)); + case ValueType::Unsigned64Bit: return IntegerLiteral(type, static_cast(value)); + case ValueType::Unsigned128Bit: return IntegerLiteral(type, static_cast(value)); + case ValueType::Float: return IntegerLiteral(type, static_cast(value)); + case ValueType::Double: return IntegerLiteral(type, static_cast(value)); + case ValueType::Character: return IntegerLiteral(type, static_cast(value)); + default: __builtin_unreachable(); + } + }, literal); + } + [[nodiscard]] constexpr static auto getTypeName(const lang::Token::ValueType type) { switch (type) { case ValueType::Signed8Bit: return "s8"; diff --git a/plugins/libimhex/source/lang/evaluator.cpp b/plugins/libimhex/source/lang/evaluator.cpp index e65d31889..fc3083c41 100644 --- a/plugins/libimhex/source/lang/evaluator.cpp +++ b/plugins/libimhex/source/lang/evaluator.cpp @@ -483,6 +483,17 @@ namespace hex::lang { PatternData* Evaluator::evaluateEnum(ASTNodeEnum *node) { std::vector> entryPatterns; + auto underlyingType = dynamic_cast(node->getUnderlyingType()); + if (underlyingType == nullptr) + this->getConsole().abortEvaluation("enum underlying type was not ASTNodeTypeDecl. This is a bug"); + + size_t size; + auto builtinUnderlyingType = dynamic_cast(underlyingType->getType()); + if (builtinUnderlyingType != nullptr) + size = Token::getTypeSize(builtinUnderlyingType->getType()); + else + this->getConsole().abortEvaluation("invalid enum underlying type"); + auto startOffset = this->m_currOffset; for (auto &[name, value] : node->getEntries()) { auto expression = dynamic_cast(value); @@ -492,19 +503,9 @@ namespace hex::lang { auto valueNode = evaluateMathematicalExpression(expression); SCOPE_EXIT( delete valueNode; ); - entryPatterns.push_back({{ valueNode->getType(), valueNode->getValue() }, name }); + entryPatterns.push_back({ Token::castTo(builtinUnderlyingType->getType(), valueNode->getValue()), name }); } - auto underlyingType = dynamic_cast(node->getUnderlyingType()); - if (underlyingType == nullptr) - this->getConsole().abortEvaluation("enum underlying type was not ASTNodeTypeDecl. This is a bug"); - - size_t size; - if (auto builtinType = dynamic_cast(underlyingType->getType()); builtinType != nullptr) - size = Token::getTypeSize(builtinType->getType()); - else - this->getConsole().abortEvaluation("invalid enum underlying type"); - this->m_currOffset += size; return this->evaluateAttributes(node, new PatternDataEnum(startOffset, size, entryPatterns));