5using namespace std::literals;
10struct AST::Files : absl::node_hash_map<const fe::Src*, Ptr<File>> {};
14 , files_(std::make_unique<
Files>()) {}
23std::pair<Ptr<File>&,
bool>
AST::file(
const fe::Src* src) {
24 auto [i, fresh] = files_->try_emplace(src);
25 return {i->second, fresh};
29 auto tab = fe::Tab::spaces();
30 std::println(h,
"{}#pragma once\n", tab);
31 std::println(h,
"{}#include <mim/axm.h>", tab);
32 std::println(h,
"#include <mim/plugin.h>\n", tab);
33 std::println(h,
"{}/// @namespace mim::plug::{} @ref {}", tab, plugin, plugin);
34 std::println(h,
"{}namespace mim {{", tab);
35 std::println(h,
"{}namespace plug::{} {{\n", tab, plugin);
38 std::vector<std::ostringstream> normalizers, outer_namespace;
40 std::println(h,
"{}static constexpr plugin_t Plugin_Id = 0x{:x};\n", tab, plugin_id);
43 std::deque<std::pair<Sym, AnnexInfo>> infos(unordered.begin(), unordered.end());
44 std::ranges::sort(infos, [&](
const auto& p1,
const auto& p2) {
return p1.second.id.tag < p2.second.id.tag; });
47 for (
const auto& [key, annex] : infos) {
48 const auto&
sym = annex.sym;
49 if (
sym.plugin != plugin)
continue;
51 std::println(h,
"{}/// @name %%{}.{}\n///@{{", tab, plugin,
sym.tag);
52 std::println(h,
"{}enum class {} : flags_t {{", tab,
sym.tag);
56 auto& os = outer_namespace.emplace_back();
57 std::print(os,
"template<> constexpr flags_t Annex::Base<plug::{}::{}> = 0x{:x};\n", plugin,
sym.tag, ax_id);
59 if (
auto& subs = annex.subs; !subs.empty()) {
60 for (
const auto& aliases : subs) {
62 for (
const auto alias : aliases)
63 std::println(h,
"{}{} = 0x{:x},", tab, alias,
id);
65 if (
auto norm = annex.normalizer) {
66 auto sub = aliases.front();
67 auto& os = normalizers.emplace_back();
68 std::print(os,
"normalizers[flags_t({}::{})] = &{}<{}::{}>;",
sym.tag, sub, norm,
sym.tag, sub);
72 if (
auto norm = annex.normalizer)
73 std::print(normalizers.emplace_back(),
"normalizers[flags_t(Annex::Base<{}>)] = &{};",
sym.tag, norm);
76 std::println(h,
"{}}};\n", tab);
78 std::println(outer_namespace.emplace_back(),
"template<> constexpr size_t Annex::Num<plug::{}::{}> = {};", plugin,
sym.tag, annex.subs.size());
80 if (
auto norm = annex.normalizer) {
81 if (
auto& subs = annex.subs; !subs.empty()) {
82 std::println(h,
"{}template<{}>\nconst Def* {}(const Def*, const Def*, const Def*);\n", tab,
sym.tag,
85 std::println(h,
"{}const Def* {}(const Def*, const Def*, const Def*);", tab, norm);
88 std::println(h,
"{}///@}}\n", tab);
92 if (!normalizers.empty()) {
93 std::println(h,
"{}void register_normalizers(Normalizers& normalizers);\n", tab);
94 std::println(h,
"{}#define MIM_{}_NORMALIZER_IMPL \\", tab, plugin);
96 std::println(h,
"{}void register_normalizers(Normalizers& normalizers) {{\\", tab);
98 for (
const auto& normalizer : normalizers)
99 std::println(h,
"{}{} \\", tab, normalizer.str());
101 std::println(h,
"{}}}", tab);
105 std::println(h,
"{}}} // namespace plug::{}\n", tab, plugin);
107 std::println(h,
"{}#ifndef DOXYGEN // don't include in Doxygen documentation\n", tab);
108 for (
const auto& line : outer_namespace)
109 std::print(h,
"{}{}", tab, line.str());
110 std::println(h,
"{}", tab);
113 for (
const auto& [tag, ax] : infos) {
115 if ((ax.pi && *ax.pi) ||
sym.plugin != plugin)
continue;
116 std::println(h,
"{}template<> struct Axm::IsANode<plug::{}::{}> {{ using type = Axm; }};", tab,
sym.plugin,
120 std::println(h,
"{}\n#endif", tab);
121 std::println(h,
"{}}} // namespace mim\n", tab);
123 std::println(h,
"{}#ifndef DOXYGEN // don't include in Doxygen documentation\n", tab);
124 for (
const auto& [key, annex] : infos) {
125 if (!annex.subs.empty()) {
126 auto sym = annex.sym;
127 std::println(h,
"{}template<> struct fe::is_bit_enum<mim::plug::{}::{}> : std::true_type {{}};", tab,
132 std::println(h,
"{}\n#endif", tab);
139 std::print(h,
"from enum import IntEnum\n\n");
140 std::println(h,
"class {}(IntEnum):", plugin);
142 std::println(h,
"{}ID = 0x{:x}", tab, plugin_id);
143 std::vector<mim::ast::AnnexInfo> annexes_with_subs;
146 std::deque<std::pair<Sym, AnnexInfo>> infos(unordered.begin(), unordered.end());
147 std::ranges::sort(infos, [&](
const auto& p1,
const auto& p2) {
return p1.second.id.tag < p2.second.id.tag; });
148 for (
const auto& [key, annex] : infos) {
149 const auto&
sym = annex.sym;
150 if (
sym.plugin != plugin)
continue;
154 if (
auto& subs = annex.subs; subs.empty())
155 std::println(h,
"{}{} = 0x{:x}", tab,
sym.tag, ax_id);
157 annexes_with_subs.push_back(annex);
161 if (!annexes_with_subs.empty()) {
162 for (
const auto& annex : annexes_with_subs) {
164 std::println(h,
"class _{}_{}(IntEnum):", plugin, annex.sym.tag);
167 for (
const auto& aliases : annex.subs) {
169 for (
const auto alias : aliases)
170 std::println(h,
"{}{} = 0x{:x}", tab, alias,
id);
174 std::println(h,
"\n{}.{} = _{}_{}\n", plugin, annex.sym.tag, plugin, annex.sym.tag);
192 if (
auto idp = ptrn->isa<
IdPtrn>(); idp && !idp->
dbg() && idp->type()) {
193 if (
auto pe = idp->type()->isa<
PathExpr>())
205 ast.error().report();
213 if (!plugins.empty()) {
214 auto imports = parser.import_plugins(plugins, tag);
216 for (
auto import : imports)
217 decls.emplace_back(
import);
220 auto file =
ast.ptr<
File>(Loc(),
ast.scope(),
ast.copy(decls));
The World represents the whole program and manages creation of MimIR nodes (Defs).
Owns the arena all AST nodes live in as well as the AnnexInfos of all plugins.
friend void swap(AST &a1, AST &a2) noexcept
void bootstrap_py(Sym plugin, std::ostream &h)
const auto & plugin2annexes(Sym plugin)
void bootstrap(Sym plugin, std::ostream &h)
std::pair< Ptr< File > &, bool > file(const fe::Src *src)
The AST of one source file: an anonymous ModDecl that a UseDecl binds under a name of its own.
void compile(AST &) const
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
const LamDecl * lam() const
LamExpr(Ptr< LamDecl > lam)
static Ptr< Expr > to_expr(AST &, Ptr< Ptrn >)
Wraps a TuplePtrn as Expr.
(ptrn_0, ..., ptrn_n-1), [ptrn_0, ..., ptrn_n-1], or {ptrn_0, ..., ptrn_n-1}
AST load_plugins(World &, fe::View< std::string >)
fe::Arena::Ref< const T > Ptr
Nodes live in the AST's Arena and are never destroyed, so this merely points at one.
fe::Vector< Ptr< T > > Ptrs
static std::optional< plugin_t > mangle(std::string_view plugin)
Mangles s into a dense 48-bit representation.