Argtype descriptions name a literal parameter's cost, a phase's error is the phase's report, the ^-code table's grave-accent and dieresis rows (from dev ee86ca467512)

This commit is contained in:
ack committed 2026-10-18 23:19:37 +02:00
1 parent f4dcdf3ffd
commit 35ca469e4d
7 files changed
+65 -5

No files matched your search

+1 -1
View File
@@ -53,7 +53,7 @@ are regenerated on each release — patches cannot be merged directly.
Report problems (or send patches) to the author; accepted changes are Report problems (or send patches) to the author; accepted changes are
applied to the development tree and appear in a following snapshot. applied to the development tree and appear in a following snapshot.
This snapshot was assembled from development commit `831455f36fcd`. This snapshot was assembled from development commit `ee86ca467512`.
## License ## License
+16 -2
View File
@@ -87,7 +87,18 @@ std::vector<std::tuple<std::string, std::string, std::string, std::string, modif
R"((?:.|\n)*)", R"((lambda s : __import__("kutil").rest_split(s, N)))", R"((?:.|\n)*)", R"((lambda s : __import__("kutil").rest_split(s, N)))",
nullptr }, nullptr },
{ "literal", "literal text passed without interpretation", // A description is Klammertext source (desc.klammertext in
// Argtype_registry::parameters()), rendered by ref/ for kdesc --argtypes:
// a special it mentions is caret-quoted (^@c), and it is one line, since
// the programmer's dump (kdiag --machine) shows the first line only.
// kdesc --argtypes is where klammertext_description.md sends a reader
// for the argtypes, so the practical consequence of declaring a literal
// parameter -- the named close -- is stated here, not only on @c
// (TODO 76, 2026-10-13).
{ "literal", "literal text passed without interpretation; a klammer with a "
"literal parameter (always its last positional one) is closed by its "
"name, as ^@c ... c^@ is, because the content may hold ^@ and the end "
"cannot be found by counting",
R"((?:.|\n)*)", "str", R"((?:.|\n)*)", "str",
pyformat_string }, pyformat_string },
@@ -97,7 +108,10 @@ std::vector<std::tuple<std::string, std::string, std::string, std::string, modif
// has its "^" forms processed as the value is built, this keeps them: // has its "^" forms processed as the value is built, this keeps them:
// "^@date" stays "^@date", so it re-reads as the text "@date" rather // "^@date" stays "^@date", so it re-reads as the text "@date" rather
// than as a klammer application. (2026-09-13) // than as a klammer application. (2026-09-13)
{ "klammertext", "Klammertext source, kept exactly as written", { "klammertext", "Klammertext source, kept exactly as written, for a "
"description a Machine renders later: unlike literal, the quoting "
"carets are kept, so a quoted klammer stays quoted when the text is "
"read again, and no named close is required",
R"((?:.|\n)*)", "str", R"((?:.|\n)*)", "str",
pyformat_string }, pyformat_string },
}; };
+1 -1
View File
@@ -62,7 +62,7 @@ std::map<std::string, std::pair<std::string, std::string>> diacritics {
{"h", {"0302", "circumflex (hat)"}}, {"h", {"0302", "circumflex (hat)"}},
{"~", {"0303", "tilde"}}, {"~", {"0303", "tilde"}},
{"-", {"0304", "macron"}}, {"-", {"0304", "macron"}},
{"\"", {"0308", "diaresis"}}, {"\"", {"0308", "dieresis"}},
// {"v", {"0305", "vinculum"}}, // {"v", {"0305", "vinculum"}},
{"b", {"0306", "breve"}}, {"b", {"0306", "breve"}},
{"d", {"0307", "dot above"}}, {"d", {"0307", "dot above"}},
+9
View File
@@ -36,3 +36,12 @@ public:
Machine m_machine; Machine m_machine;
Locator m_loc; Locator m_loc;
}; };
// The Python exception the last fetch saw (Eval_python::fetch_python_exception):
// its type name and its str(). The Error that fetch produces carries the
// whole traceback; a caller that wants the exception's OWN words for a
// headline -- Machine::run_phase_functions, reporting a phase's ValueError
// as the phase's message about the document -- reads these. Declared here
// so machine.cpp needs no Python header. (TODO 77, 2026-10-13)
std::string last_python_exception_type();
std::string last_python_exception_text();
+9
View File
@@ -6,6 +6,12 @@
std::regex Eval_python::statement_delimiter("\\s*;\\s*"); std::regex Eval_python::statement_delimiter("\\s*;\\s*");
PyObject* Eval_python::s_last_exception = nullptr; PyObject* Eval_python::s_last_exception = nullptr;
// See eval.h. Set by fetch_python_exception(), beside the object it keeps.
static std::string s_last_exception_type {};
static std::string s_last_exception_text {};
std::string last_python_exception_type() { return s_last_exception_type; }
std::string last_python_exception_text() { return s_last_exception_text; }
static bool s_python_output_to_log = false; static bool s_python_output_to_log = false;
void set_python_output_to_log(bool on) void set_python_output_to_log(bool on)
@@ -226,6 +232,9 @@ std::string Eval_python::fetch_python_exception()
detail = PyUnicode_AsUTF8(str); detail = PyUnicode_AsUTF8(str);
Py_DECREF(str); Py_DECREF(str);
} }
s_last_exception_text = detail;
s_last_exception_type =
ptype ? reinterpret_cast<PyTypeObject*>(ptype)->tp_name : "";
PyObject* tb_module = PyImport_ImportModule("traceback"); PyObject* tb_module = PyImport_ImportModule("traceback");
if (tb_module) { if (tb_module) {
PyObject* format = PyObject_GetAttrString(tb_module, "format_exception"); PyObject* format = PyObject_GetAttrString(tb_module, "format_exception");
+26 -1
View File
@@ -909,7 +909,9 @@ std::string Machine::run_phase_functions()
// result text. The Eval is constructed per phase so a chained // result text. The Eval is constructed per phase so a chained
// phase sees its predecessor's result in K_result. // phase sees its predecessor's result in K_result.
Eval E(*this, Locator()); Eval E(*this, Locator());
if (!f.empty() && f[0] != ':') { const std::string spec = f;
const bool python_phase = !f.empty() && f[0] != ':';
if (python_phase) {
// K reaches a phase only as a parameter: the state's // K reaches a phase only as a parameter: the state's
// "class K" exists in the EVAL's globals (python_code() // "class K" exists in the EVAL's globals (python_code()
// defines it), but a phase function's body resolves names in // defines it), but a phase function's body resolves names in
@@ -929,7 +931,30 @@ std::string Machine::run_phase_functions()
// Klammertext: take the raw result string. Re-reading it as // Klammertext: take the raw result string. Re-reading it as
// Klammertext (Eval::eval) would misparse target characters -- // Klammertext (Eval::eval) would misparse target characters --
// e.g. a "@" from a quoted ^@ in justified txt output. // e.g. a "@" from a quoted ^@ in justified txt output.
try {
m_result = E.eval_command(katoms.begin(), katoms.end() - 2); m_result = E.eval_command(katoms.begin(), katoms.end() - 2);
} catch (const Parsing_error& e) {
// A Python phase's exception is the phase's report about the
// document, not a parsing error at "phase, line 1": a phase
// raises ValueError to say what is wrong (phases.
// check_section_links), and that message is what the user
// needs headlined, located nowhere -- the phase ran over the
// whole target text, so no line is the place. Any other
// exception type is a fault in the phase itself and keeps
// its type name. The traceback the Parsing_error carried is
// the trace, at -v 2. (TODO 77, 2026-10-13)
if (!python_phase) throw;
(void)K::log(2, e.m_desc);
std::string what = last_python_exception_text();
const std::string type = last_python_exception_type();
if (what.empty()) throw;
if (type != "ValueError") what = type + ": " + what;
throw Target_error(
what + "\n\n(Reported by the " + m_state.value("K_target")
+ " target's phase " + spec
+ "; -v 2 shows the Python traceback.)",
Locator::none());
}
} }
} }
return m_result; return m_result;
+3
View File
@@ -39,6 +39,9 @@ std::string diacritics_examples([[maybe_unused]] Machine& machine)
if (sym == "~") { if (sym == "~") {
written = "^" + letter + "^~"; written = "^" + letter + "^~";
} }
if (sym == "`") {
written = "^" + letter + "^`";
}
std::string display = "^" + letter + sym; std::string display = "^" + letter + sym;
kt << display << " | @t ^" << written << " @ | " << name << " ||\n"; kt << display << " | @t ^" << written << " @ | " << name << " ||\n";
} }