#pragma once #include #include "providers/provider.hpp" #include "lang/pattern_data.hpp" #include "ast_node.hpp" #include #include #include #include namespace hex::lang { class Evaluator { public: Evaluator(prv::Provider* &provider, std::endian defaultDataEndian); std::optional> evaluate(const std::vector& ast); const std::pair& getError() { return this->m_error; } private: std::map m_types; prv::Provider* &m_provider; std::endian m_defaultDataEndian; u64 m_currOffset = 0; std::optional m_currEndian; std::vector*> m_currMembers; std::pair m_error; using EvaluateError = std::pair; [[noreturn]] static void throwEvaluateError(std::string_view error, u32 lineNumber) { throw EvaluateError(lineNumber, "Evaluator: " + std::string(error)); } [[nodiscard]] std::endian getCurrentEndian() const { return this->m_currEndian.value_or(this->m_defaultDataEndian); } ASTNodeIntegerLiteral* evaluateScopeResolution(ASTNodeScopeResolution *node); ASTNodeIntegerLiteral* evaluateRValue(ASTNodeRValue *node); ASTNodeIntegerLiteral* evaluateOperator(ASTNodeIntegerLiteral *left, ASTNodeIntegerLiteral *right, Token::Operator op); ASTNodeIntegerLiteral* evaluateMathematicalExpression(ASTNodeNumericExpression *node); PatternData* evaluateBuiltinType(ASTNodeBuiltinType *node); 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* evaluatePointer(ASTNodePointerVariableDecl *node); }; }