From 826879c517fbc82aeddc0a1274db68f2d6c7a0cf Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 15:33:58 -0500 Subject: [PATCH] xo-expression2: + DConstant utest --- .../include/xo/expression2/DConstant.hpp | 12 +- xo-expression2/src/expression2/DConstant.cpp | 11 +- xo-expression2/utest/CMakeLists.txt | 1 + xo-expression2/utest/DConstant.test.cpp | 232 ++++++++++++++++++ xo-reader2/src/reader2/DExpectExprSsm.cpp | 2 +- xo-reader2/src/reader2/DExprSeqState.cpp | 12 +- xo-reader2/src/reader2/DProgressSsm.cpp | 3 + 7 files changed, 261 insertions(+), 12 deletions(-) create mode 100644 xo-expression2/utest/DConstant.test.cpp diff --git a/xo-expression2/include/xo/expression2/DConstant.hpp b/xo-expression2/include/xo/expression2/DConstant.hpp index 81561e68..50f0e38f 100644 --- a/xo-expression2/include/xo/expression2/DConstant.hpp +++ b/xo-expression2/include/xo/expression2/DConstant.hpp @@ -5,6 +5,7 @@ #pragma once +#include "Expression.hpp" #include "TypeRef.hpp" #include "exprtype.hpp" #include @@ -27,12 +28,19 @@ namespace xo { public: explicit DConstant(obj value) noexcept; + /** create isntance + * @p mm memory allocator + * @p value literal constant + **/ + static obj make(obj mm, + obj value); + /** create instance * @p mm memory allocator * @p value literal constant **/ - static DConstant * make(obj mm, - obj value); + static DConstant * _make(obj mm, + obj value); bool is_resolved() const noexcept { return typeref_.is_resolved(); } diff --git a/xo-expression2/src/expression2/DConstant.cpp b/xo-expression2/src/expression2/DConstant.cpp index f65ba013..f03fe625 100644 --- a/xo-expression2/src/expression2/DConstant.cpp +++ b/xo-expression2/src/expression2/DConstant.cpp @@ -4,10 +4,12 @@ **/ #include "DConstant.hpp" +#include "detail/IExpression_DConstant.hpp" #include "TypeDescr.hpp" #include #include #include +#include #include #include #include @@ -38,9 +40,16 @@ namespace xo { } } - DConstant * + obj DConstant::make(obj mm, obj value) + { + return obj(_make(mm, value)); + } + + DConstant * + DConstant::_make(obj mm, + obj value) { void * mem = mm.alloc(typeseq::id(), sizeof(DConstant)); diff --git a/xo-expression2/utest/CMakeLists.txt b/xo-expression2/utest/CMakeLists.txt index 2b8bceec..aefc8c8c 100644 --- a/xo-expression2/utest/CMakeLists.txt +++ b/xo-expression2/utest/CMakeLists.txt @@ -5,6 +5,7 @@ set(UTEST_SRCS expression2_utest_main.cpp StringTable.test.cpp X1Collector.test.cpp + DConstant.test.cpp ) xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS}) diff --git a/xo-expression2/utest/DConstant.test.cpp b/xo-expression2/utest/DConstant.test.cpp new file mode 100644 index 00000000..ddff5b20 --- /dev/null +++ b/xo-expression2/utest/DConstant.test.cpp @@ -0,0 +1,232 @@ +/** @file DConstant.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 + +namespace ut { + using xo::S_expression2_tag; + using xo::scm::DConstant; + using xo::scm::DFloat; + using xo::scm::DInteger; + 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::facet::typeseq; + using xo::reflect::Reflect; + using xo::InitEvidence; + using xo::InitSubsys; + using xo::scope; + + // Ensure subsystem initialized before tests + static InitEvidence s_init = InitSubsys::require(); + + TEST_CASE("DConstant-init", "[expression2][DConstant]") + { + // Verify subsystem initialization succeeded + REQUIRE(s_init.evidence()); + } + + TEST_CASE("DConstant-from-float", "[expression2][DConstant]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dconstant_float_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); + + // Box a float value + obj fval = DFloat::box(alloc, 3.14); + REQUIRE(fval.data() != nullptr); + + // Create DConstant from the boxed float + auto expr = DConstant::make(alloc, fval); + REQUIRE(expr.data() != nullptr); + + // Verify expression type + REQUIRE(expr.data()->extype() == xo::scm::exprtype::constant); + + // Verify valuetype is double (DFloat::value_type) + REQUIRE(expr.data()->valuetype() == Reflect::require()); + + // Verify value is accessible + REQUIRE(expr.data()->value().data() != nullptr); + } + + TEST_CASE("DConstant-from-integer", "[expression2][DConstant]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dconstant_int_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); + + // Box an integer value + obj ival = DInteger::box(alloc, 42); + REQUIRE(ival.data() != nullptr); + + // Create DConstant from the boxed integer + auto expr = DConstant::make(alloc, ival); + REQUIRE(expr.data() != nullptr); + + // Verify expression type + REQUIRE(expr.data()->extype() == xo::scm::exprtype::constant); + + // Verify valuetype is long (DInteger::value_type) + REQUIRE(expr.data()->valuetype() == Reflect::require()); + + // Verify value is accessible + REQUIRE(expr.data()->value().data() != nullptr); + } + + TEST_CASE("DConstant-pretty-float", "[expression2][DConstant][pp]") + { + scope log(XO_DEBUG(true)); + + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dconstant_pp_float_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); + + // Box a float value + obj fval = DFloat::box(alloc, 2.718); + auto expr = DConstant::make(alloc, fval); + REQUIRE(expr.data() != nullptr); + + // Pretty print + std::stringstream ss; + ppconfig ppc; + ppstate_standalone pps(&ss, 0, &ppc); + + obj expr_pr(expr.data()); + pps.pretty(expr_pr); + + std::string output = ss.str(); + + log && log(output); + + // Output should contain "DConstant" struct name + CHECK(output.find("DConstant") != std::string::npos); + } + + TEST_CASE("DConstant-pretty-integer", "[expression2][DConstant][pp]") + { + scope log(XO_DEBUG(false)); + + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dconstant_pp_int_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); + + // Box an integer value + obj ival = DInteger::box(alloc, 123); + auto expr = DConstant::make(alloc, ival); + REQUIRE(expr.data() != nullptr); + + // Pretty print + std::stringstream ss; + ppconfig ppc; + ppstate_standalone pps(&ss, 0, &ppc); + + obj expr_pr(expr.data()); + pps.pretty(expr_pr); + + std::string output = ss.str(); + + log && log(output); + + // Output should contain "DConstant" struct name + CHECK(output.find("DConstant") != std::string::npos); + } +} + +/* end DConstant.test.cpp */ diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index 49e95296..66eb41cd 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -248,7 +248,7 @@ namespace xo { auto f64o = DFloat::box(p_psm->expr_alloc(), tk.f64_value()); - auto expr = with_facet::mkobj(DConstant::make(p_psm->expr_alloc(), f64o)); + auto expr = DConstant::make(p_psm->expr_alloc(), f64o); // DProgressSsm responsible for resolving cases like // 1.9, diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index d6037908..e926565d 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -290,8 +290,7 @@ namespace xo { DString * dstr = DString::from_cstr(p_psm->expr_alloc(), tk.text().c_str()); obj str(dstr); - auto * dconst = DConstant::make(p_psm->expr_alloc(), str); - obj expr(dconst); + obj expr = DConstant::make(p_psm->expr_alloc(), str); DProgressSsm::start(p_psm->parser_alloc(), expr, @@ -319,8 +318,7 @@ namespace xo { { auto f64o = DFloat::box(p_psm->expr_alloc(), tk.f64_value()); - auto * dconst = DConstant::make(p_psm->expr_alloc(), f64o); - auto expr = with_facet::mkobj(dconst); + auto expr = DConstant::make(p_psm->expr_alloc(), f64o); DProgressSsm::start(p_psm->parser_alloc(), expr, @@ -348,8 +346,7 @@ namespace xo { { auto i64o = DFloat::box(p_psm->expr_alloc(), tk.i64_value()); - auto * dconst = DConstant::make(p_psm->expr_alloc(), i64o); - auto expr = with_facet::mkobj(dconst); + auto expr = DConstant::make(p_psm->expr_alloc(), i64o); DProgressSsm::start(p_psm->parser_alloc(), expr, @@ -377,8 +374,7 @@ namespace xo { { auto dvalue = DBoolean::box(p_psm->expr_alloc(), tk.bool_value()); - auto * dconst = DConstant::make(p_psm->expr_alloc(), dvalue); - auto expr = with_facet::mkobj(dconst); + auto expr = DConstant::make(p_psm->expr_alloc(), dvalue); DProgressSsm::start(p_psm->parser_alloc(), expr, diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 830dd30e..cfed858f 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -9,6 +9,9 @@ #include "DExpectExprSsm.hpp" #include "ssm/ISyntaxStateMachine_DExpectExprSsm.hpp" + +#include +#include #ifdef NOT_YET #include "DApplySsm.hpp" #include "ssm/ISyntaxStateMachine_DApplySsm.hpp"