diff options
author | Klaus Aehlig <klaus.aehlig@huawei.com> | 2022-02-22 17:03:21 +0100 |
---|---|---|
committer | Klaus Aehlig <klaus.aehlig@huawei.com> | 2022-02-22 17:03:21 +0100 |
commit | 619def44c1cca9f3cdf63544d5f24f2c7a7d9b77 (patch) | |
tree | 01868de723cb82c86842f33743fa7b14e24c1fa3 /src/buildtool/build_engine/base_maps/expression_function.hpp | |
download | justbuild-619def44c1cca9f3cdf63544d5f24f2c7a7d9b77.tar.gz |
Initial self-hosting commit
This is the initial version of our tool that is able to
build itself. In can be bootstrapped by
./bin/bootstrap.py
Co-authored-by: Oliver Reiche <oliver.reiche@huawei.com>
Co-authored-by: Victor Moreno <victor.moreno1@huawei.com>
Diffstat (limited to 'src/buildtool/build_engine/base_maps/expression_function.hpp')
-rw-r--r-- | src/buildtool/build_engine/base_maps/expression_function.hpp | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/buildtool/build_engine/base_maps/expression_function.hpp b/src/buildtool/build_engine/base_maps/expression_function.hpp new file mode 100644 index 00000000..0eb07a88 --- /dev/null +++ b/src/buildtool/build_engine/base_maps/expression_function.hpp @@ -0,0 +1,103 @@ +#ifndef INCLUDED_SRC_BUILDTOOL_BUILD_ENGINE_BASE_MAPS_EXPRESSION_FUNCTION_HPP +#define INCLUDED_SRC_BUILDTOOL_BUILD_ENGINE_BASE_MAPS_EXPRESSION_FUNCTION_HPP + +#include <memory> +#include <string> +#include <unordered_map> +#include <vector> + +#include "fmt/core.h" +#include "gsl-lite/gsl-lite.hpp" +#include "src/buildtool/build_engine/expression/configuration.hpp" +#include "src/buildtool/build_engine/expression/evaluator.hpp" +#include "src/buildtool/build_engine/expression/expression.hpp" +#include "src/buildtool/logging/logger.hpp" + +namespace BuildMaps::Base { + +class ExpressionFunction { + public: + using Ptr = std::shared_ptr<ExpressionFunction>; + using imports_t = std::unordered_map<std::string, gsl::not_null<Ptr>>; + + ExpressionFunction(std::vector<std::string> vars, + imports_t imports, + ExpressionPtr expr) noexcept + : vars_{std::move(vars)}, + imports_{std::move(imports)}, + expr_{std::move(expr)} {} + + [[nodiscard]] auto Evaluate( + Configuration const& env, + FunctionMapPtr const& functions, + std::function<void(std::string const&)> const& logger = + [](std::string const& error) noexcept -> void { + Logger::Log(LogLevel::Error, error); + }, + std::function<void(void)> const& note_user_context = + []() noexcept -> void {}) const noexcept -> ExpressionPtr { + try { // try-catch to silence clang-tidy's bugprone-exception-escape, + // only imports_caller can throw but it is not called here. + auto imports_caller = [this, &functions]( + SubExprEvaluator&& /*eval*/, + ExpressionPtr const& expr, + Configuration const& env) { + auto name_expr = expr["name"]; + auto const& name = name_expr->String(); + auto it = imports_.find(name); + if (it != imports_.end()) { + std::stringstream ss{}; + bool user_context = false; + auto result = it->second->Evaluate( + env, + functions, + [&ss](auto const& msg) { ss << msg; }, + [&user_context]() { user_context = true; } + + ); + if (result) { + return result; + } + if (user_context) { + throw Evaluator::EvaluationError(ss.str(), true, true); + } + throw Evaluator::EvaluationError( + fmt::format( + "This call to {} failed in the following way:\n{}", + name_expr->ToString(), + ss.str()), + true); + } + throw Evaluator::EvaluationError( + fmt::format("Unknown expression '{}'.", name)); + }; + auto newenv = env.Prune(vars_); + return expr_.Evaluate( + newenv, + FunctionMap::MakePtr( + functions, "CALL_EXPRESSION", imports_caller), + logger, + note_user_context); + } catch (...) { + gsl_EnsuresAudit(false); // ensure that the try-block never throws + return ExpressionPtr{nullptr}; + } + } + + inline static Ptr const kEmptyTransition = + std::make_shared<ExpressionFunction>( + std::vector<std::string>{}, + ExpressionFunction::imports_t{}, + Expression::FromJson(R"([{"type": "empty_map"}])"_json)); + + private: + std::vector<std::string> vars_{}; + imports_t imports_{}; + ExpressionPtr expr_{}; +}; + +using ExpressionFunctionPtr = ExpressionFunction::Ptr; + +} // namespace BuildMaps::Base + +#endif // INCLUDED_SRC_BUILDTOOL_BUILD_ENGINE_BASE_MAPS_EXPRESSION_FUNCTION_HPP |