mirror of
https://github.com/ChaiScript/ChaiScript.git
synced 2026-04-30 19:09:26 +08:00
Address review: use :: instead of . as nested namespace separator
Switch from dotted names (e.g. "constants.si") to C++-style :: separator (e.g. "constants::si") for nested namespace declarations, both in the C++ API (register_namespace) and in script (namespace()). The original implementation used . because namespace members are accessed via dot notation at runtime (constants.si.mu_B), making the declaration separator match the access syntax. However, :: is more consistent with C++ namespace conventions and aligns with ChaiScript's existing use of :: for method (def Class::method) and attribute (attr Class::attr) declarations. Member access in scripts remains dot-based (constants.si.mu_B) since that is ChaiScript's member access operator. Requested by @lefticus in PR #675 review. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
42ecde5197
commit
dd9afc832e
@ -190,8 +190,8 @@ namespace chaiscript {
|
||||
|
||||
m_engine.add(fun([this](const std::string &t_namespace_name) {
|
||||
register_namespace([](Namespace & /*space*/) noexcept {}, t_namespace_name);
|
||||
const auto dot_pos = t_namespace_name.find('.');
|
||||
const std::string root_name = (dot_pos != std::string::npos) ? t_namespace_name.substr(0, dot_pos) : t_namespace_name;
|
||||
const auto sep_pos = t_namespace_name.find("::");
|
||||
const std::string root_name = (sep_pos != std::string::npos) ? t_namespace_name.substr(0, sep_pos) : t_namespace_name;
|
||||
if (!m_engine.get_scripting_objects().count(root_name)) {
|
||||
import(root_name);
|
||||
} else if (m_namespace_generators.count(root_name)) {
|
||||
@ -744,9 +744,9 @@ namespace chaiscript {
|
||||
}
|
||||
|
||||
/// \brief Registers a namespace generator, which delays generation of the namespace until it is imported, saving memory if it is never
|
||||
/// used. Supports dotted names (e.g. "constants.si") for nested namespaces; parent namespaces are auto-registered if absent.
|
||||
/// used. Supports C++-style nested names (e.g. "constants::si") for nested namespaces; parent namespaces are auto-registered if absent.
|
||||
/// \param[in] t_namespace_generator Namespace generator function.
|
||||
/// \param[in] t_namespace_name Name of the Namespace function being registered (may contain dots for nesting).
|
||||
/// \param[in] t_namespace_name Name of the Namespace function being registered (may contain :: for nesting).
|
||||
/// \throw std::runtime_error In the case that the namespace name was already registered.
|
||||
void register_namespace(const std::function<void(Namespace &)> &t_namespace_generator, const std::string &t_namespace_name) {
|
||||
chaiscript::detail::threading::unique_lock<chaiscript::detail::threading::recursive_mutex> l(m_use_mutex);
|
||||
@ -760,7 +760,7 @@ namespace chaiscript {
|
||||
return space;
|
||||
}));
|
||||
|
||||
auto pos = t_namespace_name.rfind('.');
|
||||
auto pos = t_namespace_name.rfind("::");
|
||||
while (pos != std::string::npos) {
|
||||
const std::string parent = t_namespace_name.substr(0, pos);
|
||||
if (!m_namespace_generators.count(parent)) {
|
||||
@ -768,17 +768,17 @@ namespace chaiscript {
|
||||
return space;
|
||||
}));
|
||||
}
|
||||
pos = parent.rfind('.');
|
||||
pos = parent.rfind("::");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void nest_children(const std::string &t_parent_name, Namespace &t_parent) {
|
||||
const std::string prefix = t_parent_name + ".";
|
||||
const std::string prefix = t_parent_name + "::";
|
||||
for (auto &[name, generator] : m_namespace_generators) {
|
||||
if (name.size() > prefix.size() && name.compare(0, prefix.size(), prefix) == 0) {
|
||||
const std::string remainder = name.substr(prefix.size());
|
||||
if (remainder.find('.') == std::string::npos) {
|
||||
if (remainder.find("::") == std::string::npos) {
|
||||
auto &child_ns = generator();
|
||||
nest_children(name, child_ns);
|
||||
t_parent[remainder] = var(std::ref(child_ns));
|
||||
|
||||
@ -1783,20 +1783,20 @@ TEST_CASE("eval_error with AST_Node_Trace call stack compiles in C++20") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Nested namespaces via register_namespace with dotted names") {
|
||||
TEST_CASE("Nested namespaces via register_namespace with :: separator") {
|
||||
chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(), create_chaiscript_parser());
|
||||
|
||||
chai.register_namespace(
|
||||
[](chaiscript::Namespace &si) {
|
||||
si["mu_B"] = chaiscript::const_var(9.274);
|
||||
},
|
||||
"constants.si");
|
||||
"constants::si");
|
||||
|
||||
chai.register_namespace(
|
||||
[](chaiscript::Namespace &mm) {
|
||||
mm["mu_B"] = chaiscript::const_var(0.05788);
|
||||
},
|
||||
"constants.mm");
|
||||
"constants::mm");
|
||||
|
||||
chai.import("constants");
|
||||
|
||||
@ -1811,7 +1811,7 @@ TEST_CASE("Deeply nested namespaces via register_namespace") {
|
||||
[](chaiscript::Namespace &leaf) {
|
||||
leaf["val"] = chaiscript::const_var(42);
|
||||
},
|
||||
"a.b.c");
|
||||
"a::b::c");
|
||||
|
||||
chai.import("a");
|
||||
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
// Test nested namespaces using dotted names
|
||||
namespace("constants.si")
|
||||
// Test nested namespaces using C++-style :: separator
|
||||
namespace("constants::si")
|
||||
constants.si.mu_B = 1.0
|
||||
|
||||
namespace("constants.mm")
|
||||
namespace("constants::mm")
|
||||
constants.mm.mu_B = 2.0
|
||||
|
||||
assert_equal(1.0, constants.si.mu_B)
|
||||
assert_equal(2.0, constants.mm.mu_B)
|
||||
|
||||
// Test deeper nesting
|
||||
namespace("a.b.c")
|
||||
namespace("a::b::c")
|
||||
a.b.c.val = 42
|
||||
|
||||
assert_equal(42, a.b.c.val)
|
||||
@ -18,7 +18,7 @@ assert_equal(42, a.b.c.val)
|
||||
namespace("math")
|
||||
math.square = fun(x) { x * x }
|
||||
|
||||
namespace("math.trig")
|
||||
namespace("math::trig")
|
||||
math.trig.double_angle = fun(x) { 2.0 * x }
|
||||
|
||||
assert_equal(16, math.square(4))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user