pattern: Allow pattern function code to be executed separately
This commit is contained in:
parent
b8026398e0
commit
d42d87280d
@ -19,13 +19,15 @@ namespace hex::prv {
|
||||
|
||||
namespace hex::pl {
|
||||
|
||||
enum class DangerousFunctionPermission {
|
||||
enum class DangerousFunctionPermission
|
||||
{
|
||||
Ask,
|
||||
Deny,
|
||||
Allow
|
||||
};
|
||||
|
||||
enum class ControlFlowStatement {
|
||||
enum class ControlFlowStatement
|
||||
{
|
||||
None,
|
||||
Continue,
|
||||
Break,
|
||||
@ -230,6 +232,10 @@ namespace hex::pl {
|
||||
return this->m_currControlFlowStatement;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::optional<Token::Literal> getMainResult() {
|
||||
return this->m_mainResult;
|
||||
}
|
||||
|
||||
private:
|
||||
void patternCreated();
|
||||
void patternDestroyed();
|
||||
@ -254,6 +260,8 @@ namespace hex::pl {
|
||||
std::vector<ASTNode *> m_customFunctionDefinitions;
|
||||
std::vector<Token::Literal> m_stack;
|
||||
|
||||
std::optional<Token::Literal> m_mainResult;
|
||||
|
||||
std::map<std::string, Token::Literal> m_envVariables;
|
||||
std::map<std::string, Token::Literal> m_inVariables;
|
||||
std::map<std::string, size_t> m_outVariables;
|
||||
|
@ -33,8 +33,9 @@ namespace hex::pl {
|
||||
~PatternLanguage();
|
||||
|
||||
[[nodiscard]] std::optional<std::vector<ASTNode *>> parseString(const std::string &code);
|
||||
[[nodiscard]] bool executeString(prv::Provider *provider, const std::string &string, const std::map<std::string, Token::Literal> &envVars = {}, const std::map<std::string, Token::Literal> &inVariables = {});
|
||||
[[nodiscard]] bool executeString(prv::Provider *provider, const std::string &string, const std::map<std::string, Token::Literal> &envVars = {}, const std::map<std::string, Token::Literal> &inVariables = {}, bool checkResult = true);
|
||||
[[nodiscard]] bool executeFile(prv::Provider *provider, const fs::path &path, const std::map<std::string, Token::Literal> &envVars = {}, const std::map<std::string, Token::Literal> &inVariables = {});
|
||||
[[nodiscard]] std::pair<bool, std::optional<Token::Literal>> executeFunction(prv::Provider *provider, const std::string &code);
|
||||
[[nodiscard]] const std::vector<ASTNode *> &getCurrentAST() const;
|
||||
|
||||
void abort();
|
||||
|
@ -132,6 +132,7 @@ namespace hex::pl {
|
||||
this->m_stack.clear();
|
||||
this->m_customFunctions.clear();
|
||||
this->m_scopes.clear();
|
||||
this->m_mainResult.reset();
|
||||
this->m_aborted = false;
|
||||
|
||||
if (this->m_allowDangerousFunctions == DangerousFunctionPermission::Deny)
|
||||
@ -192,13 +193,7 @@ namespace hex::pl {
|
||||
if (mainFunction.parameterCount > 0)
|
||||
LogConsole::abortEvaluation("main function may not accept any arguments");
|
||||
|
||||
auto result = mainFunction.func(this, {});
|
||||
if (result) {
|
||||
auto returnCode = Token::literalToSigned(*result);
|
||||
|
||||
if (returnCode != 0)
|
||||
LogConsole::abortEvaluation(hex::format("non-success value returned from main: {}", returnCode));
|
||||
}
|
||||
this->m_mainResult = mainFunction.func(this, {});
|
||||
}
|
||||
|
||||
popScope();
|
||||
|
@ -123,7 +123,7 @@ namespace hex::pl {
|
||||
return ast;
|
||||
}
|
||||
|
||||
bool PatternLanguage::executeString(prv::Provider *provider, const std::string &code, const std::map<std::string, Token::Literal> &envVars, const std::map<std::string, Token::Literal> &inVariables) {
|
||||
bool PatternLanguage::executeString(prv::Provider *provider, const std::string &code, const std::map<std::string, Token::Literal> &envVars, const std::map<std::string, Token::Literal> &inVariables, bool checkResult) {
|
||||
this->m_running = true;
|
||||
ON_SCOPE_EXIT { this->m_running = false; };
|
||||
|
||||
@ -156,6 +156,19 @@ namespace hex::pl {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (auto mainResult = this->m_evaluator->getMainResult(); checkResult && mainResult.has_value()) {
|
||||
auto returnCode = Token::literalToSigned(*mainResult);
|
||||
|
||||
if (returnCode != 0) {
|
||||
auto errorMessage = hex::format("non-success value returned from main: {}", returnCode);
|
||||
|
||||
this->m_evaluator->getConsole().log(LogConsole::Level::Error, errorMessage);
|
||||
this->m_currError = PatternLanguageError(0, errorMessage);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
this->m_patterns = std::move(patterns.value());
|
||||
|
||||
return true;
|
||||
@ -164,7 +177,17 @@ namespace hex::pl {
|
||||
bool PatternLanguage::executeFile(prv::Provider *provider, const fs::path &path, const std::map<std::string, Token::Literal> &envVars, const std::map<std::string, Token::Literal> &inVariables) {
|
||||
File file(path, File::Mode::Read);
|
||||
|
||||
return this->executeString(provider, file.readString(), envVars, inVariables);
|
||||
return this->executeString(provider, file.readString(), envVars, inVariables, true);
|
||||
}
|
||||
|
||||
std::pair<bool, std::optional<Token::Literal>> PatternLanguage::executeFunction(prv::Provider *provider, const std::string &code) {
|
||||
|
||||
auto functionContent = hex::format("fn main() {{ {0} }};", code);
|
||||
|
||||
auto success = this->executeString(provider, functionContent, {}, {}, false);
|
||||
auto result = this->m_evaluator->getMainResult();
|
||||
|
||||
return { success, result };
|
||||
}
|
||||
|
||||
void PatternLanguage::abort() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user