patterns: Added [[transform]] and [[pointer_base]] attributes
This commit is contained in:
parent
2f6e91cd9e
commit
08c2e1cd4e
@ -589,7 +589,41 @@ namespace hex::pl {
|
|||||||
if (function.parameterCount != 1)
|
if (function.parameterCount != 1)
|
||||||
LogConsole::abortEvaluation("formatter function needs exactly one parameter", node);
|
LogConsole::abortEvaluation("formatter function needs exactly one parameter", node);
|
||||||
|
|
||||||
pattern->setFormatterFunction(function, evaluator);
|
pattern->setEvaluator(evaluator);
|
||||||
|
pattern->setFormatterFunction(function);
|
||||||
|
} else if (name == "transform" && requiresValue()) {
|
||||||
|
auto functions = evaluator->getCustomFunctions();
|
||||||
|
if (!functions.contains(*value))
|
||||||
|
LogConsole::abortEvaluation(hex::format("cannot find transform function '{}'", *value), node);
|
||||||
|
|
||||||
|
const auto &function = functions[*value];
|
||||||
|
if (function.parameterCount != 1)
|
||||||
|
LogConsole::abortEvaluation("transform function needs exactly one parameter", node);
|
||||||
|
|
||||||
|
pattern->setEvaluator(evaluator);
|
||||||
|
pattern->setTransformFunction(function);
|
||||||
|
} else if (name == "pointer_base" && requiresValue()) {
|
||||||
|
auto functions = evaluator->getCustomFunctions();
|
||||||
|
if (!functions.contains(*value))
|
||||||
|
LogConsole::abortEvaluation(hex::format("cannot find pointer base function '{}'", *value), node);
|
||||||
|
|
||||||
|
const auto &function = functions[*value];
|
||||||
|
if (function.parameterCount != 1)
|
||||||
|
LogConsole::abortEvaluation("pointer base function needs exactly one parameter", node);
|
||||||
|
|
||||||
|
if (auto pointerPattern = dynamic_cast<PatternDataPointer*>(pattern)) {
|
||||||
|
u128 value = 0;
|
||||||
|
evaluator->getProvider()->read(pattern->getOffset(), &value, pattern->getSize());
|
||||||
|
|
||||||
|
auto result = function.func(evaluator, { value });
|
||||||
|
|
||||||
|
if (!result.has_value())
|
||||||
|
LogConsole::abortEvaluation("pointer base function did not return a value", node);
|
||||||
|
|
||||||
|
pointerPattern->rebase(Token::literalToUnsigned(result.value()));
|
||||||
|
} else {
|
||||||
|
LogConsole::abortEvaluation("pointer_base attribute may only be applied to a pointer");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -957,6 +991,7 @@ namespace hex::pl {
|
|||||||
|
|
||||||
{
|
{
|
||||||
auto pointedAtPattern = this->m_type->createPatterns(evaluator).front();
|
auto pointedAtPattern = this->m_type->createPatterns(evaluator).front();
|
||||||
|
|
||||||
u128 pointerAddress = 0;
|
u128 pointerAddress = 0;
|
||||||
evaluator->getProvider()->read(pattern->getOffset(), &pointerAddress, pattern->getSize());
|
evaluator->getProvider()->read(pattern->getOffset(), &pointerAddress, pattern->getSize());
|
||||||
pointedAtPattern->setOffset(pointerAddress);
|
pointedAtPattern->setOffset(pointerAddress);
|
||||||
@ -964,12 +999,12 @@ namespace hex::pl {
|
|||||||
pattern->setPointedAtPattern(pointedAtPattern);
|
pattern->setPointedAtPattern(pointedAtPattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
evaluator->dataOffset() = offset;
|
||||||
|
|
||||||
pattern->setVariableName(this->m_name);
|
pattern->setVariableName(this->m_name);
|
||||||
|
|
||||||
applyVariableAttributes(evaluator, this, pattern);
|
applyVariableAttributes(evaluator, this, pattern);
|
||||||
|
|
||||||
evaluator->dataOffset() = offset;
|
|
||||||
|
|
||||||
return { pattern };
|
return { pattern };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1357,6 +1392,14 @@ namespace hex::pl {
|
|||||||
literal = pattern->clone();
|
literal = pattern->clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (auto transformFunc = pattern->getTransformFunction(); transformFunc.has_value()) {
|
||||||
|
auto result = transformFunc->func(evaluator, { literal });
|
||||||
|
|
||||||
|
if (!result.has_value())
|
||||||
|
LogConsole::abortEvaluation("transform function did not return a value", this);
|
||||||
|
literal = result.value();
|
||||||
|
}
|
||||||
|
|
||||||
return new ASTNodeLiteral(literal);
|
return new ASTNodeLiteral(literal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1375,7 +1418,13 @@ namespace hex::pl {
|
|||||||
if (name == "parent") {
|
if (name == "parent") {
|
||||||
scopeIndex--;
|
scopeIndex--;
|
||||||
searchScope = *evaluator->getScope(scopeIndex).scope;
|
searchScope = *evaluator->getScope(scopeIndex).scope;
|
||||||
currPattern = searchScope.front()->getParent();
|
auto currParent = evaluator->getScope(scopeIndex).parent;
|
||||||
|
|
||||||
|
if (currParent == nullptr)
|
||||||
|
LogConsole::abortEvaluation("no parent available", this);
|
||||||
|
|
||||||
|
currPattern = currParent->clone();
|
||||||
|
continue;
|
||||||
} else if (name == "this") {
|
} else if (name == "this") {
|
||||||
searchScope = *evaluator->getScope(scopeIndex).scope;
|
searchScope = *evaluator->getScope(scopeIndex).scope;
|
||||||
|
|
||||||
|
@ -99,9 +99,13 @@ namespace hex::pl {
|
|||||||
[[nodiscard]] std::string getDisplayName() const { return this->m_displayName.value_or(this->m_variableName); }
|
[[nodiscard]] std::string getDisplayName() const { return this->m_displayName.value_or(this->m_variableName); }
|
||||||
void setDisplayName(const std::string &name) { this->m_displayName = name; }
|
void setDisplayName(const std::string &name) { this->m_displayName = name; }
|
||||||
|
|
||||||
void setFormatterFunction(const ContentRegistry::PatternLanguageFunctions::Function &function, Evaluator *evaluator) {
|
[[nodiscard]] Evaluator* getEvaluator() const { return this->m_evaluator; }
|
||||||
this->m_formatterFunction = { function, evaluator };
|
void setEvaluator(Evaluator *evaluator) { this->m_evaluator = evaluator; }
|
||||||
}
|
|
||||||
|
[[nodiscard]] const auto& getTransformFunction() const { return this->m_transformFunction; }
|
||||||
|
void setTransformFunction(const ContentRegistry::PatternLanguageFunctions::Function &function) { this->m_transformFunction = function; }
|
||||||
|
[[nodiscard]] const auto& getFormatterFunction() const { return this->m_formatterFunction; }
|
||||||
|
void setFormatterFunction(const ContentRegistry::PatternLanguageFunctions::Function &function) { this->m_formatterFunction = function; }
|
||||||
|
|
||||||
virtual void createEntry(prv::Provider* &provider) = 0;
|
virtual void createEntry(prv::Provider* &provider) = 0;
|
||||||
[[nodiscard]] virtual std::string getFormattedName() const = 0;
|
[[nodiscard]] virtual std::string getFormattedName() const = 0;
|
||||||
@ -247,8 +251,7 @@ namespace hex::pl {
|
|||||||
if (!this->m_formatterFunction.has_value())
|
if (!this->m_formatterFunction.has_value())
|
||||||
ImGui::Text("%s", value.c_str());
|
ImGui::Text("%s", value.c_str());
|
||||||
else {
|
else {
|
||||||
auto &[func, evaluator] = this->m_formatterFunction.value();
|
auto result = this->m_formatterFunction->func(this->getEvaluator(), { literal });
|
||||||
auto result = func.func(evaluator, { literal });
|
|
||||||
|
|
||||||
if (result.has_value()) {
|
if (result.has_value()) {
|
||||||
if (auto displayValue = std::get_if<std::string>(&result.value()); displayValue != nullptr)
|
if (auto displayValue = std::get_if<std::string>(&result.value()); displayValue != nullptr)
|
||||||
@ -282,7 +285,9 @@ namespace hex::pl {
|
|||||||
std::optional<std::string> m_comment;
|
std::optional<std::string> m_comment;
|
||||||
std::string m_typeName;
|
std::string m_typeName;
|
||||||
|
|
||||||
std::optional<std::pair<ContentRegistry::PatternLanguageFunctions::Function, Evaluator*>> m_formatterFunction;
|
Evaluator *m_evaluator = nullptr;
|
||||||
|
std::optional<ContentRegistry::PatternLanguageFunctions::Function> m_formatterFunction;
|
||||||
|
std::optional<ContentRegistry::PatternLanguageFunctions::Function> m_transformFunction;
|
||||||
|
|
||||||
PatternData *m_parent;
|
PatternData *m_parent;
|
||||||
bool m_local = false;
|
bool m_local = false;
|
||||||
@ -397,8 +402,14 @@ namespace hex::pl {
|
|||||||
*static_cast<const PatternDataPointer*>(&other)->m_pointedAt == *this->m_pointedAt;
|
*static_cast<const PatternDataPointer*>(&other)->m_pointedAt == *this->m_pointedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rebase(u64 base) {
|
||||||
|
this->m_pointedAt->setOffset((this->m_pointedAt->getOffset() - this->m_pointerBase) + base);
|
||||||
|
this->m_pointerBase = base;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PatternData *m_pointedAt;
|
PatternData *m_pointedAt;
|
||||||
|
u64 m_pointerBase = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PatternDataUnsigned : public PatternData {
|
class PatternDataUnsigned : public PatternData {
|
||||||
|
@ -11,7 +11,9 @@ namespace hex::pl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto startOffset = this->dataOffset();
|
||||||
auto pattern = type->createPatterns(this).front();
|
auto pattern = type->createPatterns(this).front();
|
||||||
|
this->dataOffset() = startOffset;
|
||||||
|
|
||||||
if (pattern == nullptr) {
|
if (pattern == nullptr) {
|
||||||
// Handle auto variables
|
// Handle auto variables
|
||||||
|
Loading…
x
Reference in New Issue
Block a user