summaryrefslogtreecommitdiff
path: root/src/buildtool/build_engine/base_maps/expression_function.hpp
diff options
context:
space:
mode:
authorKlaus Aehlig <klaus.aehlig@huawei.com>2022-02-22 17:03:21 +0100
committerKlaus Aehlig <klaus.aehlig@huawei.com>2022-02-22 17:03:21 +0100
commit619def44c1cca9f3cdf63544d5f24f2c7a7d9b77 (patch)
tree01868de723cb82c86842f33743fa7b14e24c1fa3 /src/buildtool/build_engine/base_maps/expression_function.hpp
downloadjustbuild-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.hpp103
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