#pragma once #include #include #include #include #include #include #include #include #define LITERAL_COMPARE(literal, cond) std::visit([&](auto &&literal) { return (cond) != 0; }, literal) #define AS_TYPE(type, value) ctx.template asType(value) namespace hex::prv { class Provider; } namespace hex::pl { class PatternData; class Evaluator { public: Evaluator() = default; std::optional> evaluate(const std::vector& ast); LogConsole& getConsole() { return this->m_console; } void setDefaultEndian(std::endian endian) { this->m_defaultDataEndian = endian; } void setRecursionLimit(u32 limit) { this->m_recursionLimit = limit; } void setProvider(prv::Provider *provider) { this->m_provider = provider; } [[nodiscard]] std::endian getCurrentEndian() const { return this->m_endianStack.back(); } PatternData* patternFromName(const ASTNodeRValue::Path &name); template T* asType(ASTNode *param) { if (auto evaluatedParam = dynamic_cast(param); evaluatedParam != nullptr) return evaluatedParam; else this->getConsole().abortEvaluation("function got wrong type of parameter"); } private: std::map m_types; prv::Provider* m_provider = nullptr; std::endian m_defaultDataEndian = std::endian::native; u64 m_currOffset = 0; std::vector m_endianStack; std::vector m_globalMembers; std::vector*> m_currMembers; std::vector*> m_localVariables; std::vector m_currMemberScope; std::vector m_localStack; std::map m_definedFunctions; LogConsole m_console; u32 m_recursionLimit; u32 m_currRecursionDepth; void createLocalVariable(const std::string &varName, PatternData *pattern); void setLocalVariableValue(const std::string &varName, const void *value, size_t size); ASTNodeIntegerLiteral* evaluateScopeResolution(ASTNodeScopeResolution *node); ASTNodeIntegerLiteral* evaluateRValue(ASTNodeRValue *node); ASTNode* evaluateFunctionCall(ASTNodeFunctionCall *node); ASTNodeIntegerLiteral* evaluateTypeOperator(ASTNodeTypeOperator *typeOperatorNode); ASTNodeIntegerLiteral* evaluateOperator(ASTNodeIntegerLiteral *left, ASTNodeIntegerLiteral *right, Token::Operator op); ASTNodeIntegerLiteral* evaluateOperand(ASTNode *node); ASTNodeIntegerLiteral* evaluateTernaryExpression(ASTNodeTernaryExpression *node); ASTNodeIntegerLiteral* evaluateMathematicalExpression(ASTNodeNumericExpression *node); void evaluateFunctionDefinition(ASTNodeFunctionDefinition *node); std::optional evaluateFunctionBody(const std::vector &body); PatternData* findPattern(std::vector currMembers, const ASTNodeRValue::Path &path); PatternData* evaluateAttributes(ASTNode *currNode, PatternData *currPattern); PatternData* evaluateBuiltinType(ASTNodeBuiltinType *node); void evaluateMember(ASTNode *node, std::vector &currMembers, bool increaseOffset); PatternData* evaluateStruct(ASTNodeStruct *node); PatternData* evaluateUnion(ASTNodeUnion *node); PatternData* evaluateEnum(ASTNodeEnum *node); PatternData* evaluateBitfield(ASTNodeBitfield *node); PatternData* evaluateType(ASTNodeTypeDecl *node); PatternData* evaluateVariable(ASTNodeVariableDecl *node); PatternData* evaluateArray(ASTNodeArrayVariableDecl *node); PatternData* evaluateStaticArray(ASTNodeArrayVariableDecl *node); PatternData* evaluateDynamicArray(ASTNodeArrayVariableDecl *node); PatternData* evaluatePointer(ASTNodePointerVariableDecl *node); }; }