Klammerset: the @@@klammerset construct, its search path, and const correctness

The @@@klammerset system command formally declares a klammerset — a
named, logically related group of klammer definitions — with an
operative, idempotent declaration (:requires and :files load in order
at the declaration point, relative to the declaring file). A bare
symbol given to ktext -k, kdesc --input, or :requires resolves to
x/x.k on the search path: the document's directory, then
KLAMMERTEXT_KLAMMERSETS, then KLAMMERTEXT_HOME; kdesc --klammerset
lists the available sets. sks/sks.k is the first declared klammerset,
so `-k sks` loads the SKS by name. The engine's lookup classes were
renamed *_set → *_registry to keep the two concepts apart, and the
whole C++ tree now follows standard const-correctness conventions.
tst/ gains klammerset_test.sh (18 cases).

(from dev 64b1abf23e56)
This commit is contained in:
2026-07-30 23:50:07 +02:00
parent c42981f7e2
commit ef77f03584
83 changed files with 1429 additions and 594 deletions

View File

@@ -10,7 +10,7 @@
int State::class_id = 0;
bool Var::defined()
bool Var::defined() const
{
return !m_name.empty();
}
@@ -24,18 +24,19 @@ std::vector<std::string> Frame::names() const
return result;
}
void Frame::set(std::string name, std::string value,
std::string delim, std::string desc, Locator loc, Argtype argtype)
void Frame::set(const std::string& name, const std::string& value,
const std::string& delim, const std::string& desc, const Locator& loc,
const Argtype& argtype)
{
Var v(name, value, delim, desc, loc, argtype);
m_vars[name] = v;
}
std::pair<Var, bool> Frame::get(std::string name)
std::pair<Var, bool> Frame::get(const std::string& name) const
{
std::pair<Var, bool> result {Var(), false};
if (m_vars.contains(name)) {
result = {m_vars[name], true};
result = {m_vars.at(name), true};
}
return result;
}
@@ -43,7 +44,7 @@ std::pair<Var, bool> Frame::get(std::string name)
// State
void State::open_frame(std::string name)
void State::open_frame(const std::string& name)
{
Frame f(name);
// m_frames.push_back(f);
@@ -58,19 +59,20 @@ void State::close_frame()
}
// Preserve altered machine state:
string_map machine_state {};
for (auto [name, var] : m_frames[0].m_vars) {
for (const auto& [name, var] : m_frames[0].m_vars) {
if (contains(name, "K_")) {
machine_state[name] = var.m_value;
}
}
m_frames.erase(m_frames.begin());
for (auto [name, value] : machine_state) {
for (const auto& [name, value] : machine_state) {
set(name, value, true);
}
}
void State::set(std::string name, std::string value, bool update,
std::string delim, std::string desc, Locator loc, Argtype argtype)
void State::set(const std::string& name, const std::string& value, bool update,
const std::string& delim, const std::string& desc, const Locator& loc,
const Argtype& argtype)
{
if (m_frames.empty()) {
std::stringstream ss {};
@@ -89,9 +91,9 @@ void State::set(std::string name, std::string value, bool update,
m_frames[0].set(name, value, delim, desc, loc, argtype);
}
void State::set(std::map<std::string, std::string> varmap)
void State::set(const std::map<std::string, std::string>& varmap)
{
for (auto [k, v] : varmap) {
for (const auto& [k, v] : varmap) {
set(k, v);
}
}
@@ -107,7 +109,7 @@ void State::set(const std::map<std::string, std::string>& varmap,
}
void State::replace(std::string name, std::string value, bool error_if_not_defined)
void State::replace(const std::string& name, const std::string& value, bool error_if_not_defined)
{
if (error_if_not_defined && !get(name).defined()) {
std::stringstream ss {};
@@ -120,14 +122,14 @@ void State::replace(std::string name, std::string value, bool error_if_not_defin
void State::add_environment_frame()
{
open_frame(klammerstate::shell_environment_name);
for (auto [name, value] : environment_variables()) {
for (const auto& [name, value] : environment_variables()) {
set(name, value);
}
}
Var State::get(std::string name, bool error_if_not_defined, Locator loc)
Var State::get(const std::string& name, bool error_if_not_defined, const Locator& loc) const
{
for (auto f : m_frames) {
for (const auto& f : m_frames) {
auto [result, found] = f.get(name);
if (found) {
return result;
@@ -141,12 +143,12 @@ Var State::get(std::string name, bool error_if_not_defined, Locator loc)
}
}
std::string State::value(std::string name, bool error_if_not_defined, Locator loc)
std::string State::value(const std::string& name, bool error_if_not_defined, const Locator& loc) const
{
return get(name, error_if_not_defined, loc).m_value;
}
std::string State::subst(std::string text, bool quote_values)
std::string State::subst(const std::string& text, bool quote_values) const
{
(void)K::log(3);
std::string result = text;
@@ -198,7 +200,8 @@ void State::subst(katom_iter begin, katom_iter end)
}
void prohibit_change_of_description(
std::string name, bool defined, std::string old_desc, std::string new_desc, Locator old_loc, Locator loc)
const std::string& name, bool defined, const std::string& old_desc,
const std::string& new_desc, const Locator& old_loc, const Locator& loc)
{
if (defined && !old_desc.empty() && !new_desc.empty()) {
std::stringstream ss {};
@@ -216,7 +219,7 @@ void prohibit_change_of_description(
// Parameter_set m_parameters = Parameter_set("name :value :append :replace :delim :desc");
void State::parse_state_katoms(katom_iter begin, katom_iter end, katom_list katoms)
void State::parse_state_katoms(katom_iter begin, katom_iter end, katom_list& katoms)
{
(void)K::log(3, *begin, *(end-1));
// std::cout << "parse_katoms: " << std::pair(begin + 1, end - 1) << "\n";
@@ -246,11 +249,11 @@ void State::parse_state_katoms(katom_iter begin, katom_iter end, katom_list kato
ignore_whitespace(next_iter, katoms);
}
std::vector<std::string> State::all_names()
std::vector<std::string> State::all_names() const
{
std::vector<std::string> result {};
for (Frame f : m_frames) {
for (auto [name, var] : f.m_vars) {
for (const Frame& f : m_frames) {
for (const auto& [name, var] : f.m_vars) {
// std::cout << "Name: " << name << "\n";
result.push_back(name);
}
@@ -282,7 +285,7 @@ std::string State::python_code()
// the file whose @eval names it is found regardless of the cwd.
python_dirs.insert(python_dirs.end(),
m_search_dirs.begin(), m_search_dirs.end());
for (auto d : python_dirs) {
for (const auto& d : python_dirs) {
auto python_files = pathnames_with_extension(d, "py");
if (!python_files.empty()) {
ss << "sys.path.append('" << d << "')\n";
@@ -308,12 +311,12 @@ std::string State::describe(bool show_environment, int margin_size) const
std::string margin(margin_size, ' ');
int i = m_frames.size() - 1;
std::stringstream ss {};
for (auto f : m_frames) {
for (const auto& f : m_frames) {
int width = max_key_length(f.m_vars);
ss << margin << "Frame " << i-- << ": " << f.m_name << "\n";
if ((f.m_name != klammerstate::shell_environment_name) ||
(show_environment && f.m_name == klammerstate::shell_environment_name)) {
for (auto [key, value] : f.m_vars) {
for (const auto& [key, value] : f.m_vars) {
std::string print_value = value.m_value;
if (print_value == klammerstate::no_value) {
print_value = "<no-value>";