diff --git a/xo-expression2/utest/CMakeLists.txt b/xo-expression2/utest/CMakeLists.txt index b1662736..f464708e 100644 --- a/xo-expression2/utest/CMakeLists.txt +++ b/xo-expression2/utest/CMakeLists.txt @@ -8,6 +8,7 @@ set(UTEST_SRCS DConstant.test.cpp DVariable.test.cpp DApplyExpr.test.cpp + DDefineExpr.test.cpp ) xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS}) diff --git a/xo-expression2/utest/DDefineExpr.test.cpp b/xo-expression2/utest/DDefineExpr.test.cpp new file mode 100644 index 00000000..5bb91582 --- /dev/null +++ b/xo-expression2/utest/DDefineExpr.test.cpp @@ -0,0 +1,317 @@ +/** @file DDefineExpr.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 + +namespace ut { + using xo::S_expression2_tag; + using xo::scm::DDefineExpr; + using xo::scm::DConstant; + using xo::scm::DFloat; + using xo::scm::DVariable; + using xo::scm::DUniqueString; + using xo::scm::StringTable; + using xo::scm::AExpression; + 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("DDefineExpr-init", "[expression2][DDefineExpr]") + { + REQUIRE(s_init.evidence()); + } + + TEST_CASE("DDefineExpr-make", "[expression2][DDefineExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "ddefineexpr_make_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); + + StringTable table(1024); + const DUniqueString * name = table.intern("x"); + REQUIRE(name != nullptr); + + // Create rhs expression: constant 42.0 + obj fval = DFloat::box(alloc, 42.0); + auto rhs_expr = DConstant::make(alloc, fval); + REQUIRE(rhs_expr.data() != nullptr); + + // Create define expression: def x = 42.0 + DDefineExpr * def = DDefineExpr::make(alloc, name, rhs_expr); + REQUIRE(def != nullptr); + } + + TEST_CASE("DDefineExpr-lhs", "[expression2][DDefineExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "ddefineexpr_lhs_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); + + StringTable table(1024); + const DUniqueString * name = table.intern("myvar"); + + obj fval = DFloat::box(alloc, 3.14); + auto rhs_expr = DConstant::make(alloc, fval); + + DDefineExpr * def = DDefineExpr::make(alloc, name, rhs_expr); + REQUIRE(def != nullptr); + + DVariable * lhs = def->lhs(); + REQUIRE(lhs != nullptr); + REQUIRE(lhs->name() == name); + } + + TEST_CASE("DDefineExpr-rhs", "[expression2][DDefineExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "ddefineexpr_rhs_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); + + StringTable table(1024); + const DUniqueString * name = table.intern("y"); + + obj fval = DFloat::box(alloc, 2.718); + auto rhs_expr = DConstant::make(alloc, fval); + + DDefineExpr * def = DDefineExpr::make(alloc, name, rhs_expr); + REQUIRE(def != nullptr); + + obj rhs = def->rhs(); + REQUIRE(rhs.data() != nullptr); + // Verify rhs expression type is constant + REQUIRE(rhs.extype() == xo::scm::exprtype::constant); + } + + TEST_CASE("DDefineExpr-name", "[expression2][DDefineExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "ddefineexpr_name_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); + + StringTable table(1024); + const DUniqueString * name = table.intern("foo"); + + obj fval = DFloat::box(alloc, 1.0); + auto rhs_expr = DConstant::make(alloc, fval); + + DDefineExpr * def = DDefineExpr::make(alloc, name, rhs_expr); + REQUIRE(def != nullptr); + REQUIRE(def->name() == name); + REQUIRE(std::strcmp(def->name()->chars(), "foo") == 0); + } + + TEST_CASE("DDefineExpr-extype", "[expression2][DDefineExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "ddefineexpr_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); + + StringTable table(1024); + const DUniqueString * name = table.intern("z"); + + obj fval = DFloat::box(alloc, 0.0); + auto rhs_expr = DConstant::make(alloc, fval); + + DDefineExpr * def = DDefineExpr::make(alloc, name, rhs_expr); + REQUIRE(def != nullptr); + REQUIRE(def->extype() == xo::scm::exprtype::define); + } + + TEST_CASE("DDefineExpr-valuetype", "[expression2][DDefineExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "ddefineexpr_valuetype_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); + + StringTable table(1024); + const DUniqueString * name = table.intern("w"); + + obj fval = DFloat::box(alloc, 99.9); + auto rhs_expr = DConstant::make(alloc, fval); + + DDefineExpr * def = DDefineExpr::make(alloc, name, rhs_expr); + REQUIRE(def != nullptr); + REQUIRE(def->valuetype() == Reflect::require()); + } + + TEST_CASE("DDefineExpr-pretty", "[expression2][DDefineExpr][pp]") + { + scope log(XO_DEBUG(true)); + + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "ddefineexpr_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); + + StringTable table(1024); + const DUniqueString * name = table.intern("bar"); + + obj fval = DFloat::box(alloc, 123.456); + auto rhs_expr = DConstant::make(alloc, fval); + + DDefineExpr * def = DDefineExpr::make(alloc, name, rhs_expr); + REQUIRE(def != nullptr); + + std::stringstream ss; + ppconfig ppc; + ppstate_standalone pps(&ss, 0, &ppc); + + obj def_pr(def); + pps.pretty(def_pr); + + std::string output = ss.str(); + + log && log(output); + + CHECK(output.find("DDefineExpr") != std::string::npos); + } +} + +/* end DDefineExpr.test.cpp */