diff --git a/utest/CMakeLists.txt b/utest/CMakeLists.txt index 687c75ab..b1662736 100644 --- a/utest/CMakeLists.txt +++ b/utest/CMakeLists.txt @@ -7,6 +7,7 @@ set(UTEST_SRCS X1Collector.test.cpp DConstant.test.cpp DVariable.test.cpp + DApplyExpr.test.cpp ) xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS}) diff --git a/utest/DApplyExpr.test.cpp b/utest/DApplyExpr.test.cpp new file mode 100644 index 00000000..d151b776 --- /dev/null +++ b/utest/DApplyExpr.test.cpp @@ -0,0 +1,309 @@ +/** @file DApplyExpr.test.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "init_expression2.hpp" +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include + +namespace ut { + using xo::S_expression2_tag; + using xo::scm::DApplyExpr; + using xo::scm::DConstant; + using xo::scm::DFloat; + using xo::scm::AExpression; + using xo::scm::TypeRef; + using xo::scm::Primitives; + using xo::scm::DPrimitive_gco_2_gco_gco; + using xo::mm::CollectorTypeRegistry; + using xo::mm::AAllocator; + using xo::mm::ACollector; + using xo::mm::AGCObject; + using xo::mm::DX1Collector; + using xo::mm::CollectorConfig; + using xo::mm::ArenaConfig; + using xo::print::APrintable; + using xo::print::ppstate_standalone; + using xo::print::ppconfig; + using xo::facet::FacetRegistry; + using xo::facet::with_facet; + using xo::facet::obj; + using xo::reflect::Reflect; + using xo::InitEvidence; + using xo::InitSubsys; + using xo::scope; + + static InitEvidence s_init = InitSubsys::require(); + + TEST_CASE("DApplyExpr-init", "[expression2][DApplyExpr]") + { + REQUIRE(s_init.evidence()); + } + + TEST_CASE("DApplyExpr-make2", "[expression2][DApplyExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dapplyexpr_make2_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + // wrap primitive as GCObject, then as expression + obj prim_gco = with_facet::mkobj(&Primitives::s_mul_gco_gco_pm); + obj fn_expr = DConstant::make(alloc, prim_gco); + REQUIRE(fn_expr.data() != nullptr); + + // create argument expressions + obj val1 = DFloat::box(alloc, 3.0); + obj val2 = DFloat::box(alloc, 7.0); + obj arg1 = DConstant::make(alloc, val1); + obj arg2 = DConstant::make(alloc, val2); + REQUIRE(arg1.data() != nullptr); + REQUIRE(arg2.data() != nullptr); + + // create apply expression: mul(3.0, 7.0) + TypeRef result_type = TypeRef::resolved(Reflect::require()); + auto apply_expr = DApplyExpr::make2(alloc, result_type, fn_expr, arg1, arg2); + REQUIRE(apply_expr.data() != nullptr); + } + + TEST_CASE("DApplyExpr-extype", "[expression2][DApplyExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dapplyexpr_extype_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + obj prim_gco = with_facet::mkobj(&Primitives::s_mul_gco_gco_pm); + obj fn_expr = DConstant::make(alloc, prim_gco); + + obj val1 = DFloat::box(alloc, 3.0); + obj val2 = DFloat::box(alloc, 7.0); + obj arg1 = DConstant::make(alloc, val1); + obj arg2 = DConstant::make(alloc, val2); + + TypeRef result_type = TypeRef::resolved(Reflect::require()); + auto apply_expr = DApplyExpr::make2(alloc, result_type, fn_expr, arg1, arg2); + + REQUIRE(apply_expr.data()->extype() == xo::scm::exprtype::apply); + } + + TEST_CASE("DApplyExpr-n_args", "[expression2][DApplyExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dapplyexpr_n_args_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + obj prim_gco = with_facet::mkobj(&Primitives::s_mul_gco_gco_pm); + obj fn_expr = DConstant::make(alloc, prim_gco); + + obj val1 = DFloat::box(alloc, 3.0); + obj val2 = DFloat::box(alloc, 7.0); + obj arg1 = DConstant::make(alloc, val1); + obj arg2 = DConstant::make(alloc, val2); + + TypeRef result_type = TypeRef::resolved(Reflect::require()); + auto apply_expr = DApplyExpr::make2(alloc, result_type, fn_expr, arg1, arg2); + + REQUIRE(apply_expr.data()->n_args() == 2); + } + + TEST_CASE("DApplyExpr-fn", "[expression2][DApplyExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dapplyexpr_fn_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + obj prim_gco = with_facet::mkobj(&Primitives::s_mul_gco_gco_pm); + obj fn_expr = DConstant::make(alloc, prim_gco); + + obj val1 = DFloat::box(alloc, 3.0); + obj val2 = DFloat::box(alloc, 7.0); + obj arg1 = DConstant::make(alloc, val1); + obj arg2 = DConstant::make(alloc, val2); + + TypeRef result_type = TypeRef::resolved(Reflect::require()); + auto apply_expr = DApplyExpr::make2(alloc, result_type, fn_expr, arg1, arg2); + + // verify fn() returns an expression + obj fn = apply_expr.data()->fn(); + REQUIRE(fn.data() != nullptr); + REQUIRE(fn.extype() == xo::scm::exprtype::constant); + } + + TEST_CASE("DApplyExpr-arg", "[expression2][DApplyExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dapplyexpr_arg_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + obj prim_gco = with_facet::mkobj(&Primitives::s_mul_gco_gco_pm); + obj fn_expr = DConstant::make(alloc, prim_gco); + + obj val1 = DFloat::box(alloc, 3.0); + obj val2 = DFloat::box(alloc, 7.0); + obj arg1 = DConstant::make(alloc, val1); + obj arg2 = DConstant::make(alloc, val2); + + TypeRef result_type = TypeRef::resolved(Reflect::require()); + auto apply_expr = DApplyExpr::make2(alloc, result_type, fn_expr, arg1, arg2); + + // verify arg(0) and arg(1) return expressions + obj a0 = apply_expr.data()->arg(0); + obj a1 = apply_expr.data()->arg(1); + + REQUIRE(a0.data() != nullptr); + REQUIRE(a1.data() != nullptr); + REQUIRE(a0.extype() == xo::scm::exprtype::constant); + REQUIRE(a1.extype() == xo::scm::exprtype::constant); + } + + TEST_CASE("DApplyExpr-pretty", "[expression2][DApplyExpr][pp]") + { + scope log(XO_DEBUG(false)); + + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dapplyexpr_pretty_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + obj prim_gco = with_facet::mkobj(&Primitives::s_mul_gco_gco_pm); + obj fn_expr = DConstant::make(alloc, prim_gco); + + obj val1 = DFloat::box(alloc, 3.0); + obj val2 = DFloat::box(alloc, 7.0); + obj arg1 = DConstant::make(alloc, val1); + obj arg2 = DConstant::make(alloc, val2); + + TypeRef result_type = TypeRef::resolved(Reflect::require()); + auto apply_expr = DApplyExpr::make2(alloc, result_type, fn_expr, arg1, arg2); + + std::stringstream ss; + ppconfig ppc; + ppstate_standalone pps(&ss, 0, &ppc); + + obj expr_pr(apply_expr.data()); + pps.pretty(expr_pr); + + std::string output = ss.str(); + + log && log(output); + + CHECK(output.find("ApplyExpr") != std::string::npos); + } +} + +/* end DApplyExpr.test.cpp */