1
0
mirror of synced 2025-01-18 00:56:49 +01:00

pattern: Allow pattern function code to be executed separately

This commit is contained in:
WerWolv 2022-02-06 00:18:04 +01:00
parent b8026398e0
commit d42d87280d
4 changed files with 39 additions and 12 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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();

View File

@ -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() {