Initial commit: Klammertext source distribution

Curated source subset assembled by klammertext-dev's doc/make_dist.sh: the Klammermachine (mac), the Standard Klammer Set (sks), the commands (com), editor plugins and install guides (doc), a test subset (tst), and lib/bin placeholders. Builds with 'make -C com'.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-18 18:48:23 +02:00
commit 2ba7ceee7a
272 changed files with 27634 additions and 0 deletions

559
mac/show.cpp Normal file
View File

@@ -0,0 +1,559 @@
#include <algorithm>
#include <iterator>
#include "ktype.h"
#include "show.h"
#include "util.h"
#include "log.h"
#include "file.h"
std::ostream& msg(Locator loc)
{
std::cout << blue << loc.abbrev(false) << black << " ";
return std::cout;
}
std::ostream& fmsg(Locator loc)
{
std::cout << blue << loc.abbrev(false) << black
<< kall << ktype << kindex << kreplaced << " ";
return std::cout;
}
// std::vector<int>
std::ostream& operator<<(std::ostream& os, const std::vector<int>& ns)
{
if (!ns.empty()) {
auto rest = std::vector<int>(ns.begin() + 1, ns.end());
os << ns[0];
for (auto n : rest) {
os << ", " << n;
}
}
return os;
}
// strings_t
std::ostream& operator<<(std::ostream& os, const strings_t& ss)
{
if (!ss.empty()) {
for (const std::string& s : ss) {
os << "<" << s << ">";
}
}
return os;
}
// std::vector<fs::path>
std::ostream& operator<<(std::ostream& os, const std::vector<fs::path>& pp)
{
if (!pp.empty()) {
for (const fs::path& p : pp) {
os << "<" << p.string() << ">";
}
}
return os;
}
// std::map<std::string,std::string>
std::ostream& operator<<(std::ostream& os, const std::map<std::string,std::string>& sm)
{
size_t name_length = 0;
for (auto [k,v] : sm) {
name_length = std::max(k.size(), name_length);
}
for (auto [k,v] : sm) {
os << std::setfill(' ') << " " << std::setw(name_length)
<< k << sp_arrow << " " << display_string(v) << "\n";
}
return os;
}
// Katom iterator pair
std::ostream& operator<<(std::ostream& os, const std::pair<katom_iter,katom_iter>& iters)
{
for (auto e = iters.first; e < iters.second; e++) {
std::cout << e;
}
std::cout << "\n";
return os;
}
// Locator
std::ostream& operator<<(std::ostream& os, const Locator& loc)
{
os << loc.str();
return os;
}
// Katom
std::string subscript(int n)
{
strings_t chars {
"\u2080", "\u2081", "\u2082", "\u2083", "\u2084",
"\u2085", "\u2086", "\u2087", "\u2088", "\u2089" };
std::string prefix {};
if (n < 0)
prefix = "-";
std::string sn {std::to_string(std::abs(n))};
std::string result { prefix };
for (unsigned int i = 0; i < sn.size(); i++) {
std::string d {sn[i]};
result += chars[std::stoi(d)];
}
return result;
}
void os_char(std::ostream& os, katom_t type, unsigned char c)
{
if (type == katom_t::eval_result) {
os << c;
} else if ((Katom::show_all || Katom::show_whitespace) and c == ' ') {
if (is_active(type)) os << boldgreen;
const std::string space_s { "\u00B7" };
os << space_s;
if (is_active(type)) os << black;
} else if ((Katom::show_all || Katom::show_whitespace) and c == '\n') {
if (is_active(type)) os << boldgreen;
os << "/";
if (is_active(type)) os << black;
} else if (c != '\n')
os << c;
}
void os_body(std::ostream& os, const Katom& k)
{
bool bracketed = true;
if (k.is_whitespace() || k.is_word() || k.is_text() || k.is_literal() || k.is_nonascii()) {
bracketed = Katom::show_all;
}
if (bracketed)
os << left_bracket;
for (auto c : k.m_text) {
os_char(os, k.m_type, c);
}
if (bracketed) {
if (Katom::show_index) {
os << subscript(k.m_index);
}
if (Katom::show_type){
if (Katom::show_index) {
os << ".";
}
if (k.m_initial_type != k.m_type) {
os << subscript(static_cast<int>(k.m_initial_type)) << right_arrow;
}
os << subscript(static_cast<int>(k.m_type));
}
os << right_bracket;
}
}
std::ostream& operator<<(std::ostream& os, const Katom& k)
{
//const std::string space_s { "\u2423" };
/// const std::string space_s { "\u00B7" };
// const std::string tab { "\u2023" };
// const std::string left_index { "\u27EA" };
// const std::string right_index { "\u27EB" };
// const std::string diamond { "\u2B29" };
//bool in_red = mark_as_error(k.m_type);
//if (k.m_type == katom_t::ignored)
// show_type = false;
//if (in_red)
//if (is_error(k.m_type))
// os << red;
if (k.m_type == katom_t::replaced) {
os << blue; // cyan;
} else if (k.m_type == katom_t::ignored) {
os << yellow;
}
//else if (k.m_type == katom_t::literal)
// os << green;
else {
os << black;
}
if (is_active(k.m_type) or
(Katom::show_replaced and (k.m_type == katom_t::replaced)) or
(Katom::show_ignored and (k.m_type == katom_t::ignored))) {
os_body(os, k);
if (k.m_initial_type == katom_t::newline ||
(k.m_type == katom_t::ws_added && k.m_text == "\n")) {
os << "\n";
}
}
//os << black;
return os;
}
katom_list abbrev(const katom_list& ks, unsigned int max_length)
{
if (ks.size() > max_length) {
katom_list result(ks.begin(), (ks.begin())+(max_length));
Katom ellipsis = Katom("[...]", katom_t::word, Locator());
result.push_back(ellipsis);
result.push_back(ks.back());
std::for_each(result.begin(), result.end(), [](Katom& k) {
if (k.m_type == katom_t::newline) {
//std::cout << "NEWLINE\n";
k.m_type = katom_t::word;
k.m_text = "/";
k.m_src = "/";
k.m_initial_type = katom_t::word;
}
});
return result;
} else {
katom_list result(ks.begin(), ks.end());
std::for_each(result.begin(), result.end(), [](Katom& k) {
if (k.m_type == katom_t::newline) {
//std::cout << "NEWLINE\n";
k.m_type = katom_t::word;
k.m_text = "/";
k.m_initial_type = katom_t::word;
}
});
return result;
}
}
std::ostream& operator<<(std::ostream& os, const katom_lists& ks)
{
//os << double_bar;
//os << red < "|" << black;
for (const auto& k : ks) {
os << left_double_bracket << abbrev(k) << right_double_bracket << " ";
//os << k << red << "|" << black;
}
// os << "\n";
return os;
}
std::ostream& operator<<(std::ostream& os, const katom_ptr& k)
{
os << *k;
return os;
}
std::ostream& operator<<(std::ostream& os, const katom_iter& k)
{
os << *k;
return os;
}
std::ostream& operator<<(std::ostream& os, const std::vector<Katom>& ks)
{
for (const auto& k : ks) {
os << k;
}
return os;
}
std::ostream& operator<<(std::ostream& os, const std::vector<katom_iter>& ks)
{
for (const auto& k : ks) {
os << *k;
}
return os;
}
std::ostream &kindex(std::ostream &os)
{
Katom::show_index = true;
return os;
}
std::ostream &ktype(std::ostream &os)
{
Katom::show_type = true;
return os;
}
std::ostream &kws(std::ostream &os)
{
Katom::show_whitespace = true;
return os;
}
std::ostream &kall(std::ostream &os)
{
Katom::show_all = true;
return os;
}
std::ostream &kreplaced(std::ostream &os)
{
Katom::show_replaced = true;
return os;
}
std::ostream &kignored(std::ostream &os)
{
Katom::show_ignored = true;
return os;
}
std::ostream &kreset(std::ostream &os)
{
Katom::show_index = false;
Katom::show_type = false;
Katom::show_all = false;
Katom::show_replaced = false;
Katom::show_ignored = false;
Katom::show_whitespace = false;
os << black;
return os;
}
/*
std::ostream& operator<<(std::ostream& os, const std::vector<Katom> ks)
{
std::ranges::copy(ks, std::ostream_iterator<Katom>(os, ""));
return os;
}
*/
// Argtype
std::ostream& operator<<(std::ostream& os, const Argtype& a)
{
return os
<< left_bracket << "\U0001D504" << broken_bar
<< a.m_name << broken_bar
<< a.m_symbolic_pattern << broken_bar
<< a.m_count << broken_bar
<< a.m_mincount << broken_bar
<< a.m_maxcount << right_bracket;
}
// Parameter
std::ostream& operator<<(std::ostream& os, const Parameter& arg)
{
os << left_bracket << "\U0001D513" << broken_bar;
if (arg.m_optional)
os << ":";
os << arg.m_name << "." << arg.m_argtype.m_name;
//if (arg.m_default.size() != 0)
if (!arg.m_default.empty()) {
os << broken_bar << arg.m_default;
}
os << right_bracket;
return os;
}
// std::vector<Parameter>
std::ostream& operator<<(std::ostream& os, const std::vector<Parameter>& as)
{
for (const auto& a : as) {
os << a;
}
return os;
}
// Parameter_set
std::ostream& operator<<(std::ostream& os, const Parameter_set& as)
{
os << left_bracket << "\U0001D513\U0001D530" << broken_bar
<< as.m_positional.size() << broken_bar
<< as.m_optional.size() << broken_bar
// << (as.m_rest.undefined() ? "-" : "+")
<< (as.m_rest.empty() ? "-" : "+")
<< broken_bar << "[" << as.m_katoms.size() << "]"
<< right_bracket;
return os;
}
// Var
std::ostream& operator<<(std::ostream& os, const Var& v)
{
os << "<" << v.m_name << ">";
return os;
}
// Frame
std::ostream& operator<<(std::ostream& os, const Frame& f)
{
os << "{";
// for (auto [k,v] : f.m_vars) {
// os << v;
// }
os << join(f.names(), "|");
os << "}";
return os;
}
// State
std::ostream& operator<<(std::ostream& os, const State& s)
{
//for (int i = s.m_frames.size() - 1; i != 0; --i) {
for (auto f : s.m_frames) {
os << f << "\n";
}
return os;
}
// Klammer
std::ostream& operator<<(std::ostream& os, const Klammer& k)
{
std::string targets = join(k.get_target_names(), ","s);
os << left_bracket << "\U0001D50E" << broken_bar
<< k.m_name << broken_bar
<< "p" << k.m_parameters.m_positional.size() << broken_bar
<< "o" << k.m_parameters.m_optional.size() << broken_bar
<< (targets.empty() ? "?" : targets)
<< right_bracket;
return os;
}
// Klammer::variable_map_t
std::ostream& operator<<(std::ostream& os, const Klammer::variable_map_t& vm)
{
for (auto [k, v] : vm) {
os << " " << k << sp_arrow << v << "\n";
}
return os;
}
// Klammer::components
std::string katom_type_name(katom_t type)
{
// Could cache, but why bother - only for kdesc.
for (auto t : katom_types) {
if (t.m_type == type) {
return t.m_name;
}
}
throw Internal_error("Unknown katom_t: " + std::to_string((int)type));
}
std::ostream& operator<<(std::ostream& os, const Klammer::components& kc)
{
std::string del = " ";
auto [target, deftype, parameters, body, varmap, locator] = kc;
os << std::setw(4) << target << del
// << katom_types[(int)deftype].m_name << del
<< katom_type_name(deftype) << del
<< parameters << del << kall << ktype << red << body << del << locator;
return os;
}
// Klammer_set
std::ostream& operator<<(std::ostream& os, const Klammer_set& ks)
{
for (auto klam : ks.m_klammers) {
for (auto [k,v] : klam.second.m_defloc) {
os << " " << k << sp_arrow << v << "\n";
}
//klam.second.m_defloc.str() << "\n";
std::cout << " " << klam.first << sp_arrow << klam.second << " " << "\n";
}
return os;
}
// Target
void show_arrow_pair(std::ostream& os, std::pair<std::string,std::string> transform)
{
os << transform.first << sp_arrow << transform.second;
}
std::ostream& operator<<(std::ostream& os, const Target& t)
{
os << "<\U0001D517" << broken_bar << t.m_name << broken_bar << t.m_desc << broken_bar;
for (auto i : t.m_includes) {
os << i << right_arrow << t.m_name << broken_bar;
}
for (auto p : t.m_provides) {
os << t.m_name << right_arrow << p << broken_bar;
}
os << ">";
return os;
}
// Target_set
std::ostream& operator<<(std::ostream& os, const Target_set& ts)
{
size_t width = 0;
for (auto t : ts.m_targets) {
width = std::max(width, t.first.size());
}
for (auto [name, target] : ts.m_targets) {
os << std::setw(width) << name << sp_arrow << target << "\n";
}
return os;
}
// Machine
std::string describe_sources(Machine m)
{
std::stringstream ss {};
for (auto s : m.m_sources) {
if (std::holds_alternative<std::string>(s)) {
ss << " String: " << trim(std::get<std::string>(s)) << "\n";
} else {
ss << " Filename: " << std::get<fs::path>(s).string() << "\n";
}
}
return ss.str();
}
std::string label(std::string name, int count)
{
std::stringstream ss {};
ss << " " << name << " (" << count << "):\n";
return ss.str();
}
std::ostream& operator<<(std::ostream& os, const Machine& m)
{
std::string argtypes_desc = m.m_argtypes.describe(false, 8);
std::string state_desc = m.m_state.describe(false, 3);
std::string targets_desc = m.m_targets.describe(4);
std::string klammer_desc = m.m_klammers.describe(2);
std::string source_desc = describe_sources(m);
os << "\nMachine " << "\U000133DE \U00013000\n"
<< label("Sources", m.m_sources.size()) << source_desc << "\n"
<< label("Argtypes", m.m_argtypes.m_names.size()) << argtypes_desc << "\n"
<< label("Targets", m.m_targets.m_names.size()) << targets_desc << "\n"
<< label("Klammers", m.m_klammers.m_klammers.size()) << klammer_desc << "\n"
<< label("State", m.m_state.m_frames.size()) << state_desc;
return os;
}
void modify_stream(std::string name)
{
if (name == "all") std::cout << kall;
if (name == "type") std::cout << ktype;
if (name == "index") std::cout << kindex;
if (name == "ignored") std::cout << kignored;
if (name == "replaced") std::cout << kreplaced;
};