-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/topic/robin/revert-deferred'
* origin/topic/robin/revert-deferred: Remove `std::functional` from `DeferredExpression`. Revert "Remove support for deferred expressions."
- Loading branch information
Showing
13 changed files
with
304 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
1.11.0-dev.151 | ||
1.11.0-dev.160 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// Copyright (c) 2020-2023 by the Zeek Project. See LICENSE for details. | ||
|
||
#pragma once | ||
|
||
#include <string> | ||
#include <utility> | ||
|
||
#include <hilti/rt/extension-points.h> | ||
#include <hilti/rt/types/result.h> | ||
|
||
namespace hilti::rt { | ||
|
||
/** | ||
* Wrapper for an expression that's evaluation is deferred until requested. | ||
* The expression must be wrapped into a function call, and it's evaluation | ||
* is requested through the wrapper's call operator. | ||
* | ||
* The function should be stateless as it might be invoked an unspecified | ||
* number of times. | ||
*/ | ||
template<typename Result, typename Expr> | ||
class DeferredExpression { | ||
public: | ||
DeferredExpression(Expr&& expr) : _expr(std::move(expr)) {} | ||
DeferredExpression() = delete; | ||
DeferredExpression(const DeferredExpression&) = default; | ||
DeferredExpression(DeferredExpression&&) noexcept = default; | ||
|
||
~DeferredExpression() = default; | ||
|
||
DeferredExpression& operator=(const DeferredExpression&) = default; | ||
DeferredExpression& operator=(DeferredExpression&&) noexcept = default; | ||
|
||
Result operator()() const { return _expr(); } | ||
|
||
private: | ||
Expr _expr; | ||
}; | ||
|
||
template<typename Result, typename Expr> | ||
auto make_deferred(Expr&& expr) { | ||
return DeferredExpression<Result, Expr>(std::forward<Expr>(expr)); | ||
} | ||
|
||
namespace detail::adl { | ||
template<typename Result, typename Expr> | ||
inline std::string to_string(const DeferredExpression<Result, Expr>& x, adl::tag /*unused*/) { | ||
return hilti::rt::to_string(x()); | ||
} | ||
} // namespace detail::adl | ||
|
||
// This function is declared as an overload since we cannot partially specialize | ||
// `hilti::detail::to_string_for_print` for `DeferredExpression<T, Expr>`. | ||
template<typename Result, typename Expr> | ||
inline std::string to_string_for_print(const DeferredExpression<Result, Expr>& x) { | ||
return hilti::rt::to_string_for_print(x()); | ||
} | ||
|
||
template<typename Result, typename Expr> | ||
inline std::ostream& operator<<(std::ostream& out, const DeferredExpression<Result, Expr>& x) { | ||
return out << to_string_for_print(x); | ||
} | ||
|
||
} // namespace hilti::rt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// Copyright (c) 2020-2023 by the Zeek Project. See LICENSE for details. | ||
|
||
#include <cstddef> | ||
#include <type_traits> | ||
|
||
#include <hilti/rt/deferred-expression.h> | ||
#include <hilti/rt/doctest.h> | ||
#include <hilti/rt/types/integer.h> | ||
|
||
using namespace hilti::rt; | ||
|
||
TEST_SUITE_BEGIN("DeferredExpression"); | ||
|
||
TEST_CASE("assign") { | ||
int i = 0; | ||
auto expr = make_deferred<int32_t>([&]() { return ++i; }); | ||
REQUIRE_EQ(i, 0); | ||
|
||
CHECK_EQ(expr(), 1); | ||
CHECK_EQ(i, 1); | ||
|
||
SUBCASE("rvalue") { | ||
auto expr = make_deferred<int32_t>([]() { return 0; }); | ||
CHECK_EQ(expr(), 0); | ||
CHECK_EQ(i, 1); // Not incrementing anymore. | ||
} | ||
} | ||
|
||
TEST_CASE("construct") { | ||
int i = 0; | ||
auto expr = make_deferred<int>([&i]() { return ++i; }); | ||
|
||
SUBCASE("default") { | ||
// Construction does not evaluate passed function. | ||
CHECK_EQ(i, 0); | ||
} | ||
|
||
SUBCASE("copy") { | ||
auto expr2 = DeferredExpression(expr); | ||
// Copy construction does not evaluate passed function. | ||
CHECK_EQ(i, 0); | ||
|
||
// Copies share any data dependencies of original function. | ||
REQUIRE_EQ(expr(), 1); | ||
CHECK_EQ(i, 1); | ||
|
||
REQUIRE_EQ(expr2(), 2); | ||
CHECK_EQ(i, 2); | ||
} | ||
|
||
SUBCASE("move") { | ||
auto expr2 = DeferredExpression(std::move(expr)); | ||
// Move construction does not evaluate passed function. | ||
CHECK_EQ(i, 0); | ||
|
||
REQUIRE_EQ(expr2(), 1); | ||
CHECK_EQ(i, 1); | ||
} | ||
} | ||
|
||
TEST_CASE("evaluate") { | ||
int i = 0; | ||
auto expr = make_deferred<int>([&i]() { return ++i; }); | ||
|
||
CHECK_EQ(expr(), 1); | ||
CHECK_EQ(expr(), 2); | ||
} | ||
|
||
TEST_CASE("fmt") { | ||
int i = 0; | ||
auto expr = make_deferred<int>([&i]() { return ++i; }); | ||
|
||
// Stringification evaluates the expression. | ||
CHECK_EQ(fmt("%s", expr), "1"); | ||
CHECK_EQ(fmt("%s", expr), "2"); | ||
} | ||
|
||
TEST_CASE("to_string") { | ||
int i = 0; | ||
auto expr = make_deferred<int>([&i]() { return ++i; }); | ||
|
||
// Stringification evaluates the expression. | ||
CHECK_EQ(to_string(expr), "1"); | ||
CHECK_EQ(to_string(expr), "2"); | ||
} | ||
|
||
TEST_CASE("to_string_for_print") { | ||
int i = 0; | ||
auto expr = make_deferred<Bytes>([&i]() { return Bytes(fmt("\\x0%d", ++i)); }); | ||
|
||
// Stringification evaluates the expression. | ||
CHECK_EQ(to_string_for_print(expr), R"#(\\x01)#"); | ||
CHECK_EQ(to_string_for_print(expr), R"#(\\x02)#"); | ||
} | ||
|
||
TEST_SUITE_END(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright (c) 2020-2023 by the Zeek Project. See LICENSE for details. | ||
|
||
#pragma once | ||
|
||
#include <memory> | ||
#include <utility> | ||
|
||
#include <hilti/ast/expression.h> | ||
#include <hilti/ast/type.h> | ||
|
||
namespace hilti::expression { | ||
|
||
/** | ||
* AST node for an expression for which evaluation is deferred at runtime to | ||
* a later point when explicitly requested by the runtime system. Optionally, | ||
* that later evaluation can catch any exceptions and return a corresponding | ||
* ``result<T>``. | ||
*/ | ||
class Deferred : public Expression { | ||
public: | ||
auto expression() const { return child<Expression>(0); } | ||
bool catchException() const { return _catch_exception; } | ||
|
||
QualifiedType* type() const final { return child<QualifiedType>(1); } | ||
|
||
node::Properties properties() const final { | ||
auto p = node::Properties{{"catch_exception", _catch_exception}}; | ||
return Expression::properties() + p; | ||
} | ||
|
||
void setType(ASTContext* ctx, QualifiedType* t) { setChild(ctx, 1, t); } | ||
|
||
static auto create(ASTContext* ctx, Expression* expr, bool catch_exception, const Meta& meta = {}) { | ||
return ctx->make<Deferred>(ctx, {expr, QualifiedType::createAuto(ctx, meta)}, catch_exception, meta); | ||
} | ||
|
||
static auto create(ASTContext* ctx, Expression* expr, const Meta& meta = {}) { | ||
return create(ctx, expr, false, meta); | ||
} | ||
|
||
protected: | ||
Deferred(ASTContext* ctx, Nodes children, bool catch_exception, Meta meta) | ||
: Expression(ctx, NodeTags, std::move(children), std::move(meta)), _catch_exception(catch_exception) {} | ||
|
||
HILTI_NODE_1(expression::Deferred, Expression, final); | ||
|
||
private: | ||
bool _catch_exception; | ||
}; | ||
|
||
} // namespace hilti::expression |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters