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
+66
-6
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
|
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
@@ -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
@@ -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"}},
|
||||||
|
|||||||
@@ -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();
|
||||||
@@ -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");
|
||||||
|
|||||||
+27
-2
@@ -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.
|
||||||
m_result = E.eval_command(katoms.begin(), katoms.end() - 2);
|
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;
|
return m_result;
|
||||||
|
|||||||
@@ -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";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user