diff --git a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp index bb668ff3..91117888 100644 --- a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp @@ -6,6 +6,7 @@ #pragma once #include "Binding.hpp" +#include namespace xo { namespace scm { @@ -13,10 +14,21 @@ namespace xo { /** @class DGlobalSymtab * @brief symbol table for toplevel environment + * + * We're using DArenaHashMap to store pairs. + * Both of these are outside GC-space, so we don't need collector + * to traverse these. **/ - struct DGlobalSymtab { + class DGlobalSymtab { public: + using key_type = const DUniqueString *; + using value_type = Binding; + using repr_type = xo::map::DArenaHashMap; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; + public: + /** visit symtab-owned memory pools; call visitor(info) for each **/ + void visit_pools(const MemorySizeVisitor & visitor) const; public: /** @defgroup xo-expression2-symboltable-facet symboltable facet**/ @@ -31,6 +43,12 @@ namespace xo { ///@} private: + /** next binding will use this global index. See DGlobalEnv **/ + uint32_t next_binding_ix_ = 0; + + /** map symbols -> bindings **/ + repr_type map_; + }; } /*namespace scm*/ diff --git a/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp index e9f1a9c8..60fbe461 100644 --- a/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp @@ -6,26 +6,43 @@ #pragma once #include -#include #include namespace xo { namespace scm { - /** @brief runtime bindings for global variabels + * + * Implementation here uses a DArenaHashMap to hold pairs. + * The hash map has its own memory outside GC space. + * Keys are DUniqueStrings, also outside GC space. + * Values are regular gc-aware objects, generally will be in GC space. + * + * We need collector to traverse all the values in a global env + * on each cycle. Arrange that by having DGlobalEnv itself + * in GC space. + * **/ class DGlobalEnv { + public: + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; + public: DGlobalEnv() = default; + /** visit env-owned memory pools; call visitor(info) for each **/ + void visit_pools(const MemorySizeVisitor & visitor) const; + protected: // temporary, to appease compiler // absurd O(n) implementation for now // replace with gc-aware hashtable, when available. - /** globals. Slots in @ref global_v_ are numbered in DLocalSymtab **/ - DArray * global_v_ = nullptr; + /** symbol table assigns a unique index for each symbol **/ + DGlobalSymtab * symtab_; + + /** value for a symbol S will be in values_[symtab->lookup_binding(S)] **/ + DArray * values_ = nullptr; }; } } diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 7c31d645..960c1771 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -202,7 +202,8 @@ namespace xo { { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - scope log(XO_DEBUG(true), xtag("test", testname)); + constexpr bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); VsmConfig cfg; VirtualSchematikaMachine vsm(cfg); @@ -237,11 +238,52 @@ namespace xo { vsm.visit_pools(visitor); } + TEST_CASE("VirtualSchematikaMachine-if", "[interpreter2][VSM]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + VsmConfig cfg; + VirtualSchematikaMachine vsm(cfg); + + bool eof_flag = false; + + vsm.begin_interactive_session(); + VsmResultExt res = vsm.read_eval_print(span_type::from_cstr("if 123 == 123 then \"equal\" else \"notequal\";"), eof_flag); + + REQUIRE(res.is_value()); + REQUIRE(res.value()); + + log && log(xtag("res.tseq", res.value()->_typeseq())); + + auto x = obj::from(*res.value()); + + REQUIRE(x); + REQUIRE(x.data()->value() == true); + + REQUIRE(res.remaining_.size() == 1); + REQUIRE(*res.remaining_.lo() == '\n'); + + auto visitor = [&log](const MemorySizeInfo & info) { + log && log(xtag("resource", info.resource_name_), + xtag("used", info.used_), + xtag("alloc", info.allocated_), + xtag("commit", info.committed_), + xtag("resv", info.reserved_)); + }; + + FacetRegistry::instance().visit_pools(visitor); + vsm.visit_pools(visitor); + } + TEST_CASE("VirtualSchematikaMachine-lambda1", "[interpreter2][VSM]") { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - scope log(XO_DEBUG(false), xtag("test", testname)); + constexpr bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); VsmConfig cfg; VirtualSchematikaMachine vsm(cfg);