13 tab.
print(h,
"#pragma once\n\n");
14 tab.
print(h,
"#include <thorin/axiom.h>\n"
15 "#include <thorin/plugin.h>\n\n");
17 tab.
print(h,
"/// @namespace thorin::plug::{} @ref {} \n", plugin, plugin);
18 tab.
print(h,
"namespace thorin {{\n");
19 tab.
print(h,
"namespace plug::{} {{\n\n", plugin);
22 std::vector<std::ostringstream> normalizers, outer_namespace;
24 tab.
print(h << std::hex,
"static constexpr plugin_t Plugin_Id = 0x{};\n\n", plugin_id);
27 std::deque<std::pair<Sym, Annex>> infos(unordered.begin(), unordered.end());
28 std::ranges::sort(infos, [&](
const auto& p1,
const auto& p2) {
return p1.second.tag_id < p2.second.tag_id; });
31 for (
const auto& [key, ax] : infos) {
32 if (ax.plugin != plugin)
continue;
34 tab.
print(h,
"/// @name %%{}.{}\n///@{{\n", plugin, ax.tag);
35 tab.
print(h,
"#ifdef DOXYGEN // see https://github.com/doxygen/doxygen/issues/9668\n");
36 tab.
print(h,
"enum {} : flags_t {{\n", ax.tag);
37 tab.
print(h,
"#else\n");
38 tab.
print(h,
"enum class {} : flags_t {{\n", ax.tag);
39 tab.
print(h,
"#endif\n");
41 flags_t ax_id = plugin_id | (ax.tag_id << 8u);
43 auto& os = outer_namespace.emplace_back();
44 print(os << std::hex,
"template<> constexpr flags_t Annex::Base<plug::{}::{}> = 0x{};\n", plugin, ax.tag, ax_id);
46 if (
auto& subs = ax.subs; !subs.empty()) {
47 for (
const auto& aliases : subs) {
48 const auto& sub = aliases.front();
49 tab.
print(h,
"{} = 0x{},\n", sub, ax_id++);
50 for (
size_t i = 1; i < aliases.size(); ++i) tab.
print(h,
"{} = {},\n", aliases[i], sub);
53 print(normalizers.emplace_back(),
"normalizers[flags_t({}::{})] = &{}<{}::{}>;", ax.tag, sub,
54 ax.normalizer, ax.tag, sub);
58 print(normalizers.emplace_back(),
"normalizers[flags_t(Annex::Base<{}>)] = &{};", ax.tag, ax.normalizer);
61 tab.
print(h,
"}};\n\n");
63 if (!ax.subs.empty()) tab.
print(h,
"THORIN_ENUM_OPERATORS({})\n", ax.tag);
64 print(outer_namespace.emplace_back(),
"template<> constexpr size_t Annex::Num<plug::{}::{}> = {};\n", plugin, ax.tag, ax.subs.size());
67 if (
auto& subs = ax.subs; !subs.empty()) {
68 tab.
print(h,
"template<{}>\nRef {}(Ref, Ref, Ref);\n\n", ax.tag, ax.normalizer);
70 tab.
print(h,
"Ref {}(Ref, Ref, Ref);\n", ax.normalizer);
73 tab.
print(h,
"///@}}\n\n");
77 if (!normalizers.empty()) {
78 tab.
print(h,
"void register_normalizers(Normalizers& normalizers);\n\n");
79 tab.
print(h,
"#define THORIN_{}_NORMALIZER_IMPL \\\n", plugin);
81 tab.
print(h,
"void register_normalizers(Normalizers& normalizers) {{\\\n");
83 for (
const auto& normalizer : normalizers) tab.
print(h,
"{} \\\n", normalizer.str());
89 tab.
print(h,
"}} // namespace plug::{}\n\n", plugin);
91 tab.
print(h,
"#ifndef DOXYGEN // don't include in Doxygen documentation\n");
92 for (
const auto& line : outer_namespace) tab.
print(h,
"{}", line.str());
96 for (
const auto& [tag, ax] : infos) {
97 if (ax.pi || ax.plugin != plugin)
continue;
98 tab.
print(h,
"template<> struct Axiom::Match<plug::{}::{}> {{ using type = Axiom; }};\n", ax.plugin, ax.tag);
101 tab.
print(h,
"#endif\n");
102 tab.
print(h,
"}} // namespace thorin\n");