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:
1 parent
f4dcdf3ffd
commit
35ca469e4d
7 files changed
+65
-5
No files matched your search
@@ -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
|
||||
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
|
||||
|
||||
|
||||
+16
-2
@@ -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)))",
|
||||
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",
|
||||
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:
|
||||
// "^@date" stays "^@date", so it re-reads as the text "@date" rather
|
||||
// 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",
|
||||
pyformat_string },
|
||||
};
|
||||
+1
-1
@@ -62,7 +62,7 @@ std::map<std::string, std::pair<std::string, std::string>> diacritics {
|
||||
{"h", {"0302", "circumflex (hat)"}},
|
||||
{"~", {"0303", "tilde"}},
|
||||
{"-", {"0304", "macron"}},
|
||||
{"\"", {"0308", "diaresis"}},
|
||||
{"\"", {"0308", "dieresis"}},
|
||||
// {"v", {"0305", "vinculum"}},
|
||||
{"b", {"0306", "breve"}},
|
||||
{"d", {"0307", "dot above"}},
|
||||
|
||||
@@ -36,3 +36,12 @@ public:
|
||||
Machine m_machine;
|
||||
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();
|
||||
@@ -6,6 +6,12 @@
|
||||
std::regex Eval_python::statement_delimiter("\\s*;\\s*");
|
||||
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;
|
||||
|
||||
void set_python_output_to_log(bool on)
|
||||
@@ -226,6 +232,9 @@ std::string Eval_python::fetch_python_exception()
|
||||
detail = PyUnicode_AsUTF8(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");
|
||||
if (tb_module) {
|
||||
PyObject* format = PyObject_GetAttrString(tb_module, "format_exception");
|
||||
|
||||
+26
-1
@@ -909,7 +909,9 @@ std::string Machine::run_phase_functions()
|
||||
// result text. The Eval is constructed per phase so a chained
|
||||
// phase sees its predecessor's result in K_result.
|
||||
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
|
||||
// "class K" exists in the EVAL's globals (python_code()
|
||||
// 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 (Eval::eval) would misparse target characters --
|
||||
// e.g. a "@" from a quoted ^@ in justified txt output.
|
||||
try {
|
||||
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;
|
||||
|
||||
@@ -39,6 +39,9 @@ std::string diacritics_examples([[maybe_unused]] Machine& machine)
|
||||
if (sym == "~") {
|
||||
written = "^" + letter + "^~";
|
||||
}
|
||||
if (sym == "`") {
|
||||
written = "^" + letter + "^`";
|
||||
}
|
||||
std::string display = "^" + letter + sym;
|
||||
kt << display << " | @t ^" << written << " @ | " << name << " ||\n";
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user