MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
emit.cpp
Go to the documentation of this file.
1#include "mim/def.h"
2#include "mim/rewrite.h"
3
4#include "mim/ast/ast.h"
5
6#include "family.h"
7
8using namespace std::literals;
9
10namespace mim::ast {
11
12using Tag = Tok::Tag;
13
14class Emitter {
15public:
17 : ast_(ast) {}
18
19 AST& ast() const { return ast_; }
20 World& world() { return ast().world(); }
21 Driver& driver() { return world().driver(); }
22 fe::Error& error() { return driver().error(); }
23
24 /// @p name is *this* registration's own (unqualified) Dbg::sym; AnnexInfo::qualified turns it into the
25 /// full `plugin.tag[.sub]` name. We must take it from the declaration rather than from Def::sym, since
26 /// hash-consing can make several annexes share a single Def (e.g. `mod foo anx let bar = 23; anx let baz = 23;
27 /// end`).
28 void attach(AnnexInfo* annex, sub_t sub, Sym name, const Def* def) {
29 if (annex)
30 world().annexes().attach(annex->plugin_id(), annex->id.tag, sub, annex->qualified(driver(), name), def);
31 }
32
33 void attach_alias(AnnexInfo* annex, sub_t sub, Sym name) {
34 world().annexes().attach_alias(annex->plugin_id(), annex->id.tag, sub, annex->qualified(driver(), name));
35 }
36
37 /// @name Names
38 /// Field and constructor names live on the Def, so same-shaped types share one table.
39 ///@{
40 void add_names(const Def* def, const fe::SymMap<size_t>& sym2idx) {
41 auto& names = def2sym2idx_[def];
42 for (auto [sym, i] : sym2idx)
43 if (auto [j, ins] = names.emplace(sym, i); !ins && j->second != i) j->second = Ambiguous;
44 }
45
46 /// Copies the names of @p nom's declaration onto the corresponding parts of @p nom - an instance of it.
47 void adopt_names(const Nom* nom) {
48 auto decl = nom_decl(nom).decl;
49 if (decl == nom || !adopted_.emplace(nom).second) return;
50 auto visited = DefSet();
51 adopt_names(decl->op(), nom->op(), visited);
52 }
53
54 /// A declared @p variant prints under its name; an anonymous one spells out its cases, named as source does.
55 /// Streams lazily so that it still renders under the PlainNames guard Error::msg formats within.
56 auto variant_str(const Def* variant) {
57 auto names = std::vector<std::string>();
58 for (auto i : std::views::iota(size_t(0), variant->num_ops())) {
59 auto syms = ctor_syms(variant, i);
60 names.emplace_back(syms.empty() ? std::format("_{}", i) : syms.front());
61 }
62 return fe::StreamFn{[variant, names = std::move(names)](std::ostream& os) -> std::ostream& {
63 if (auto sym = variant->sym(); sym && sym != '_') return std::print(os, "{}", variant), os;
64 if (names.empty()) return os << "(|)";
65 os << '(';
66 for (auto sep = ""; auto i : std::views::iota(size_t(0), names.size())) {
67 std::print(os, "{}| {}", sep, names[i]);
68 if (auto op = variant->op(i); op != variant->world().sigma()) std::print(os, ": {}", op);
69 sep = " ";
70 }
71 return os << ')';
72 }};
73 }
74
75 std::optional<size_t> find_name(const Def* def, Dbg dbg) {
76 if (auto i = def2sym2idx_.find(def); i != def2sym2idx_.end()) {
77 if (auto j = i->second.find(dbg.sym()); j != i->second.end()) {
78 if (j->second == Ambiguous) {
79 if (def->isa<Variant>())
80 error()
81 .e(dbg.loc(), "constructor `{}` is ambiguous in variant `{}`", dbg, variant_str(def))
82 .n("variants of the same shape name it at different positions")
83 .n("select the case by index instead, as in `T#0`")
84 .bail();
85 error()
86 .e(dbg.loc(), "field `{}` is ambiguous in `{}`", dbg, def)
87 .n("sigmas of the same shape name it at different positions")
88 .n("select the field by index instead, as in `t#0_2`")
89 .bail();
90 }
91 return j->second;
92 }
93 }
94
95 return {};
96 }
97
98 void add_ctors(const Def* variant, const VariantExpr* expr) {
99 auto sym2idx = fe::SymMap<size_t>();
100 for (size_t i = 0, n = expr->num_ctors(); i != n; ++i) {
101 auto dbg = expr->ctor(i)->dbg();
102 if (!sym2idx.emplace(dbg.sym(), i).second) error().e(dbg.loc(), "constructor `{}` declared twice", dbg);
103 }
104 add_names(variant, sym2idx);
105 }
106
107 size_t ctor(const Def* variant, Dbg dbg) {
108 if (auto i = find_name(variant, dbg)) return *i;
109 error().e(dbg.loc(), "variant `{}` has no constructor `{}`", variant_str(variant), dbg).bail();
110 }
111
112 /// Every name case @p i goes by, sorted for a deterministic diagnostic; its index if it has none.
113 std::string ctor_names(const Def* variant, size_t i) {
114 auto names = ctor_syms(variant, i);
115 if (names.empty()) return std::format("`{}`", i);
116 for (auto& name : names)
117 name = std::format("`{}`", name);
118 return std::format("{}", fe::Join(names, " / "));
119 }
120 ///@}
121
122 /// @name Nominal scope
123 /// Only the `mod` declaring a private `nom` - or one nested in it - may access its representation.
124 ///@{
125 void push_mod(const ModDecl* mod) { mods_.emplace_back(mod); }
126 void pop_mod() { mods_.pop_back(); }
127 fe::Vector<const ModDecl*> reset_mods() { return std::exchange(mods_, {}); }
128 void restore_mods(fe::Vector<const ModDecl*> mods) { mods_ = std::move(mods); }
129
130 struct NomInfo {
131 const Nom* decl;
133 };
134
135 void add_nom(const Nom* nom, const NomDecl* decl) {
136 key2nom_[nom->key()] = {nom, decl->rep_vis() == Vis::Priv ? mods_.back() : nullptr};
137 }
138
139 /// The declared `nom` that @p nom instantiates and, if its representation is private, the `mod` owning it.
140 NomInfo nom_decl(const Nom* nom) const {
141 auto i = key2nom_.find(nom->key());
142 return i != key2nom_.end() ? i->second : NomInfo{nom, nullptr};
143 }
144
145 bool within(const ModDecl* mod) const { return std::ranges::find(mods_, mod) != mods_.end(); }
146 ///@}
147
148private:
149 static constexpr size_t Ambiguous = size_t(-1);
150
151 /// Walks @p decl and @p inst in lockstep; a `Sigma` may have normalized to an `Arr` in @p inst.
152 void adopt_names(const Def* decl, const Def* inst, DefSet& visited) {
153 if (decl == inst || decl->isa<Nom>() || inst->isa<Nom>() || !visited.emplace(decl).second) return;
154 if (auto i = def2sym2idx_.find(decl); i != def2sym2idx_.end()) {
155 auto sym2idx = i->second; // add_names may rehash def2sym2idx_
156 add_names(inst, sym2idx);
157 }
158 if (decl->node() == inst->node() && decl->num_ops() == inst->num_ops()) {
159 for (size_t k = 0, n = decl->num_ops(); k != n; ++k)
160 adopt_names(decl->op(k), inst->op(k), visited);
161 } else if (auto sigma = decl->isa<Sigma>()) {
162 if (auto n = sigma->num_ops(); Lit::isa(inst->arity()) == n)
163 for (size_t k = 0; k != n; ++k)
164 adopt_names(sigma->op(k), inst->proj(n, k), visited);
165 }
166 }
167
168 std::vector<std::string> ctor_syms(const Def* variant, size_t i) {
169 auto names = std::vector<std::string>();
170 if (auto j = def2sym2idx_.find(variant); j != def2sym2idx_.end())
171 for (const auto& [sym, k] : j->second)
172 if (k == i) names.emplace_back(sym.str());
173 std::ranges::sort(names);
174 return names;
175 }
176
177 AST& ast_;
178 DefMap<fe::SymMap<size_t>> def2sym2idx_;
179 fe::Vector<const ModDecl*> mods_;
180 ankerl::unordered_dense::map<flags_t, NomInfo> key2nom_;
181 DefSet adopted_;
182};
183
184/*
185 * File
186 */
187
188void File::emit(AST& ast) const {
189 auto emitter = Emitter(ast);
190 emit(emitter);
191}
192
193void File::emit(Emitter& e) const {
194 if (emitted_) return;
195 emitted_ = true;
196
197 // An imported file is emitted from within its importer's mods, but it is not nested in them.
198 auto mods = e.reset_mods();
199 e.push_mod(this);
200 auto _ = e.world().push(loc());
201 for (auto import : implicit_imports())
202 import->emit(e);
203 emit_decls(e);
204 e.restore_mods(std::move(mods));
205}
206
207void UseDecl::emit(Emitter& e) const {
208 if (file()) file()->emit(e);
209}
210
211/*
212 * Ptrn::emit_value
213 */
214
215/// A wildcard binds nothing, so the Def it would name need not exist - and a dump would then have to name it.
216static bool is_wildcard(const Ptrn* ptrn) {
217 if (auto id = ptrn->isa<IdPtrn>()) return id->dbg().is_anon();
218 if (auto tuple = ptrn->isa<TuplePtrn>())
219 return std::ranges::all_of(tuple->ptrns(), [](auto p) { return is_wildcard(p.get()); });
220 return false;
221}
222
223const Def* ErrorPtrn::emit_value(Emitter&, const Def* def) const { return def; }
224
225static const Def* assign(Emitter& e, const Ptrn* ptrn, const Def* type, const Def* def) {
226 if (auto res = Check::coerce(type, def)) return res->set(ptrn->dbg());
227
228 e.error()
229 .e(ptrn->loc(), "value bound to `{}` is not assignable to its annotated type", ptrn->dbg().sym())
230 .n("expected `{}`, got `{}`", type, type_of(def))
231 .bail();
232}
233
234const Def* IdPtrn::emit_value(Emitter& e, const Def* def) const {
235 return def_ = type() ? assign(e, this, emit_type(e), def) : def->set(dbg());
236}
237
238const Def* IdDecl::emit(const Def* def) const { return def_ = def->set(dbg()); }
239
240const Def* GrpPtrn::emit_value(Emitter& e, const Def* def) const { return def_ = assign(e, this, emit_type(e), def); }
241
242const Def* AliasPtrn::emit_value(Emitter& e, const Def* def) const {
243 return def_ = ptrn()->emit_value(e, def)->set(dbg());
244}
245
246const Def* Ptrn::emit_proj(Emitter& e, const Def* def, size_t n, size_t i) const {
247 auto _ = e.world().push(loc());
248 if (is_wildcard(this)) return emit_type(e), nullptr;
249 return emit_value(e, def->proj(n, i));
250}
251
252/// Binds @p ptrn to the Var of @p mut - which a wildcard does not create.
253static void emit_var(Emitter& e, const Ptrn* ptrn, Def* mut) {
254 if (is_wildcard(ptrn))
255 ptrn->emit_type(e);
256 else
257 ptrn->emit_value(e, mut->var());
258}
259
260const Def* TuplePtrn::emit_value(Emitter& e, const Def* def) const {
261 auto _ = e.world().push(loc());
262 emit_type(e);
263 auto n = num_ptrns();
264 // An unset Hole type has arity 1 until inference resolves it, so only a known arity may be rejected.
265 if (auto t = def->type()->zonk(); n != 1 && !Hole::isa_unset(t))
266 if (auto a = Lit::isa(t->arity()); a && *a != n)
267 e.error().e(loc(), "pattern has {} components, but a value of type `{}` has {}", n, t, *a).bail();
268 for (size_t i = 0; i != n; ++i)
269 ptrn(i)->emit_proj(e, def, n, i);
270 return def_ = def;
271}
272
273/*
274 * Ptrn::emit_Type
275 */
276
277const Def* ErrorPtrn::emit_type(Emitter&) const { std::unreachable(); }
278
279const Def* IdPtrn::emit_type(Emitter& e) const {
280 auto _ = e.world().push(loc());
281 return emitted_type_ = type() ? type()->emit(e) : e.world().mut_hole_type();
282}
283
284const Def* AliasPtrn::emit_type(Emitter& e) const { return ptrn()->emit_type(e); }
285
286// The leading IdPtrn has just emitted the group's type.
287const Def* GrpPtrn::emit_type(Emitter&) const { return id()->emitted_type_; }
288
289const Def* TuplePtrn::emit_type(Emitter& e) const { return emit_body(e, {}); }
290
291const Def* TuplePtrn::emit_body(Emitter& e, const Def* decl) const {
292 auto _ = e.world().push(loc());
293 auto n = num_ptrns();
294 Sigma* sigma;
295 if (decl)
296 sigma = decl->as_mut<Sigma>();
297 else
298 sigma = e.world().mut_sigma(e.world().type_pending(), n);
299 auto var = sigma->var();
300 auto sym2idx = fe::SymMap<size_t>();
301
302 for (size_t i = 0; i != n; ++i) {
303 sigma->set(i, ptrn(i)->emit_type(e));
304 ptrn(i)->emit_proj(e, var, n, i);
305 if (auto sym = field(i)) sym2idx[sym] = i;
306 }
307
308 e.add_names(sigma, sym2idx);
309 auto imm = sigma->immutabilize();
310 // A 1-Sigma collapses to its field's type, which must not inherit the name.
311 if (imm && n > 1) e.add_names(imm, sym2idx);
312 return imm ? imm : sigma;
313}
314
315const Def* TuplePtrn::emit_decl(Emitter& e, const Def* type) const {
316 auto _ = e.world().push(loc());
317 type = type ? type : e.world().type_infer_level();
318 return e.world().mut_sigma(type, num_ptrns());
319}
320
321/*
322 * Expr
323 */
324
325const Def* Expr::emit(Emitter& e) const {
326 auto _ = e.world().push(loc());
327 return emit_(e);
328}
329
330const Def* Expr::emit_decl(Emitter& e, const Def* type) const {
331 auto _ = e.world().push(loc());
332 return emit_decl_(e, type);
333}
334
335void Expr::emit_body(Emitter& e, const Def* decl) const {
336 auto _ = e.world().push(loc());
337 emit_body_(e, decl);
338}
339
340const Def* ErrorExpr::emit_(Emitter&) const { std::unreachable(); }
341const Def* HoleExpr::emit_(Emitter& e) const { return e.world().mut_hole_type(); }
342
343const Def* PathExpr::emit_(Emitter& e) const {
344 assert(decl());
345 if (auto def = decl()->def()) return def;
346 if (auto nom = decl()->isa<NomDecl>()) {
347 if (auto def = nom->emit_ahead(e)) return def;
348 e.error()
349 .e(loc(), "nominal type `{}` refers to itself", dbg().sym())
350 .n("a `nom` can only refer to itself through a sigma, a variant, or a function type")
351 .bail();
352 }
353 e.error().e(loc(), "`{}` is a module and not a value", dbg().sym()).bail();
354}
355
356const Def* TypeExpr::emit_(Emitter& e) const {
357 auto l = level()->emit(e);
358 return e.world().type(l);
359}
360
361const Def* RuleExpr::emit_(Emitter& e) const {
362 auto m = dom()->emit(e);
363 return e.world().reform(m);
364}
365
367 // clang-format off
368 switch (tag()) {
369 case Tag::K_Level: return e.world().type_level();
370 case Tag::K_Nat: return e.world().type_nat();
371 case Tag::K_Idx: return e.world().type_idx();
372 case Tag::K_Bool: return e.world().type_bool();
373 case Tag::K_ff: return e.world().lit_ff();
374 case Tag::K_tt: return e.world().lit_tt();
375 case Tag::K_i1: return e.world().lit_i1();
376 case Tag::K_i8: return e.world().lit_i8();
377 case Tag::K_i16: return e.world().lit_i16();
378 case Tag::K_i32: return e.world().lit_i32();
379 case Tag::K_i64: return e.world().lit_i64();
380 case Tag::K_I1: return e.world().type_i1();
381 case Tag::K_I8: return e.world().type_i8();
382 case Tag::K_I16: return e.world().type_i16();
383 case Tag::K_I32: return e.world().type_i32();
384 case Tag::K_I64: return e.world().type_i64();
385 case Tag::T_star: return e.world().type<0>();
386 case Tag::T_box: return e.world().type<1>();
387 default: std::unreachable();
388 }
389 // clang-format on
390}
391
392/// If @p type is a `math.F` type of known precision/exponent, yields its bit width.
393/// Note that libmim must not depend on the generated math plugin header, so lookup the Axm at runtime instead.
394static std::optional<nat_t> isa_math_f(Emitter& e, const Def* type) {
395 auto math_f = e.world().annex(e.world().sym("math.F"));
396 if (auto app = type->zonk()->isa<App>(); math_f && app && app->callee() == math_f) {
397 if (auto [p, ex] = app->arg()->projs<2>([](auto op) { return Lit::isa(op); }); p && ex) {
398 if (*p == 10 && *ex == 5) return 16;
399 if (*p == 23 && *ex == 8) return 32;
400 if (*p == 52 && *ex == 11) return 64;
401 }
402 }
403 return {};
404}
405
406/// A float Tok stores its value as mim::f64 bits; re-encode them for the width of the annotated type @p t.
407static u64 encode_f(Emitter& e, [[maybe_unused]] Loc loc, const Def* t, u64 bits) {
408 if (auto width = isa_math_f(e, t)) {
409 auto val = std::bit_cast<f64>(bits);
410 switch (*width) {
411#if defined(__STDCPP_FLOAT16_T__)
412 case 16: return std::bit_cast<u16>(f16(val));
413#else
414 case 16: e.error().e(loc, "16-bit floating-point literals are not supported on this platform").bail();
415#endif
416 case 32: return std::bit_cast<u32>(f32(val));
417 default: break;
418 }
419 }
420 return bits;
421}
422
423const Def* LitExpr::emit_(Emitter& e) const {
424 auto t = type() ? type()->emit(e) : nullptr;
425 // clang-format off
426 switch (tag()) {
427 case Tag::L_f: return t ? e.world().lit(t, encode_f(e, loc(), t, tok().lit_u())) : e.world().lit_nat(tok().lit_u());
428 case Tag::L_s:
429 if (auto size = t ? Idx::isa_lit(t) : std::nullopt; size && *size != 0) {
430 auto mag = -tok().lit_u();
431 return e.world().lit(t, (*size - mag % *size) % *size);
432 }
433 [[fallthrough]];
434 case Tag::L_u: return t ? e.world().lit(t, tok().lit_u()) : e.world().lit_nat(tok().lit_u());
435 case Tag::L_i: { auto [size, val] = tok().lit_i(); return e.world().lit_idx(size, val); }
436 case Tag::L_c: return e.world().lit_i8(tok().lit_c());
437 case Tag::L_str: return e.world().tuple(tok().sym());
438 case Tag::T_bot: return t ? e.world().bot(t) : e.world().type_bot();
439 case Tag::T_top: return t ? e.world().top(t) : e.world().type_top();
440 default: std::unreachable();
441 }
442 // clang-format on
443}
444
445const Def* DeclExpr::emit_(Emitter& e) const {
446 if (is_where())
447 for (auto decl : decls() | std::views::reverse)
448 decl->emit(e);
449 else
450 for (auto decl : decls())
451 decl->emit(e);
452 return expr()->emit(e);
453}
454
455const Def* InfixExpr::emit_decl_(Emitter& e, const Def* type) const {
456 assert(op().isa(Tag::T_arrow_r));
457 return pi_ = e.world().mut_pi(type, false);
458}
459
460void InfixExpr::emit_body_(Emitter& e, const Def*) const {
461 pi_->set_dom(lhs()->emit(e));
462 pi_->set_codom(rhs()->emit(e)); // TODO try to immutabilize
463}
464
465/// `a ∪ b ∪ c` is one n-ary Join, so flatten the left spine the left-associative parse built.
466static void emit_union(Emitter& e, const Expr* expr, DefVec& types) {
467 if (auto infix = InfixExpr::isa_op(Tag::T_union, expr)) {
468 emit_union(e, infix->lhs(), types);
469 types.emplace_back(infix->rhs()->emit(e));
470 } else {
471 types.emplace_back(expr->emit(e));
472 }
473}
474
475const Def* InfixExpr::emit_index(Emitter& e, const Def* tup) const {
476 auto& w = e.world();
477 // A simple path names a field of tup's Sigma before anything the binder resolved it to.
478 if (auto path = rhs()->isa<PathExpr>(); path && path->path()->dbgs().size() == 1) {
479 auto dbg = path->dbg();
480 if (auto i = e.find_name(tup->type(), dbg)) {
481 if (auto decl = path->decl())
482 e.error()
483 .w(dbg.loc(), "`{}` names both field {} of `{}` and a declaration in scope; using the field", dbg,
484 *i, tup->type())
485 .n(decl->loc(), "declaration here")
486 .n("parenthesize it, as in `#({})`, to extract by the declaration instead", dbg);
487 return w.lit(w.type_idx(tup->type()->arity()), *i);
488 }
489 if (!path->decl()) e.error().e(dbg.loc(), "cannot resolve field `{}` for extraction", dbg).bail();
490 }
491 return rhs()->emit(e);
492}
493
494/// A private `nom`'s representation is confined to the `mod` that declared it; the type itself is not.
495static void check_nom_scope(Emitter& e, Loc loc, const Nom* nom) {
496 auto [decl, owner] = e.nom_decl(nom);
497 if (!owner || e.within(owner)) return;
498 auto where = owner->isa<File>() ? fe::format_cite("file `{}`", owner->loc().src->path().filename().string())
499 : fe::format_cite("module `{}`", owner->dbg());
500 e.error()
501 .e(loc, "the representation of private nominal type `{}` is only accessible within {}", nom, where)
502 .n(decl->loc(), "declared here")
503 .bail();
504}
505
506/// Checks and prepares access to @p nom's representation.
507static void open_nom(Emitter& e, Loc loc, const Nom* nom) {
508 check_nom_scope(e, loc, nom);
509 e.adopt_names(nom);
510}
511
512/// Unwraps @p tup if it is a value of a `nom` and @p ex names one of its fields; `nullptr` otherwise.
513static const Def* unwrap_field(Emitter& e, const InfixExpr* ex, const Def* tup) {
514 auto nom = tup->isa_type<Nom>();
515 auto path = ex->rhs()->isa<PathExpr>();
516 if (!nom || !path || path->path()->dbgs().size() != 1) return nullptr;
517 e.adopt_names(nom);
518 if (!e.find_name(nom->op(), path->dbg())) return nullptr;
519 open_nom(e, ex->loc(), nom);
520 return e.world().struc(tup);
521}
522
523const Def* PrefixExpr::emit_(Emitter& e) const {
524 auto def = rhs()->emit(e);
525 switch (op().tag()) {
526 case Tag::T_extract:
527 if (auto nom = def->isa_type<Nom>()) {
528 open_nom(e, loc(), nom);
529 return e.world().struc(def);
530 }
531 if (!def->zonk()->isa_type<Single>()) {
532 auto& err = e.error().e(
533 loc(), "operand of prefix `#` is of type `{}` but must be of nominal or singleton type",
534 type_of(def));
535 if (def->zonk()->isa<Nom>()) err.n("`{}` is a nominal type itself; `#` unwraps a value of it", def);
536 err.bail();
537 }
538 return e.world().unwrap(def);
539 default: std::unreachable();
540 }
541}
542
543/// `T#C` or `T#i` selects case `C` or `i` of the Variant `T`: a constructor function - or its value for a `[]` payload.
544/// If @p nom is given, `T` is its body and the constructor yields @p nom.
545static const Def* emit_ctor(Emitter& e, const Variant* variant, const Expr* index, const Nom* nom = nullptr) {
546 auto& w = e.world();
547 auto i = std::optional<nat_t>();
548
549 if (auto path = index->isa<PathExpr>(); path && path->path()->dbgs().size() == 1) {
550 i = e.find_name(variant, path->dbg());
551 if (!i && !path->decl())
552 e.error()
553 .e(path->dbg().loc(), "variant `{}` has no constructor `{}`", e.variant_str(variant), path->dbg())
554 .bail();
555 }
556 if (!i) i = Lit::isa(index->emit(e));
557 if (!i) e.error().e(index->loc(), "a case of a variant must be selected by name or by literal index").bail();
558 if (*i >= variant->num_ops())
559 e.error()
560 .e(index->loc(), "variant `{}` has {} cases but case {} was requested", e.variant_str(variant),
561 variant->num_ops(), *i)
562 .bail();
563
564 auto type = nom ? static_cast<const Def*>(nom) : variant;
565 auto payload = variant->op(*i);
566 if (payload == w.sigma()) return w.inj(type, *i, w.tuple());
567 auto ctor = w.mut_lam(w.pi(payload, type));
568 return ctor->set(true, w.inj(type, *i, ctor->var()));
569}
570
571const Def* InfixExpr::emit_(Emitter& e) const {
572 auto& w = e.world();
573
574 switch (op().tag()) {
575 case Tag::T_union: {
576 DefVec types;
577 emit_union(e, this, types);
578 return w.join(types);
579 }
580 case Tag::T_extract: {
581 auto tup = w.implicit_holes(lhs()->emit(e));
582 if (auto variant = tup->isa<Variant>()) return emit_ctor(e, variant, rhs());
583 if (auto nom = tup->isa<Nom>()) {
584 if (auto variant = nom->op()->isa<Variant>()) {
585 open_nom(e, loc(), nom);
586 return emit_ctor(e, variant, rhs(), nom);
587 }
588 }
589 if (auto value = unwrap_field(e, this, tup)) tup = value;
590 return w.extract(tup, emit_index(e, tup));
591 }
592 case Tag::T_arrow_l: {
593 fe::Vector<const InfixExpr*> exs;
594 auto base = lhs();
595 while (auto ex = InfixExpr::isa_op(Tag::T_extract, base)) {
596 exs.emplace_back(ex);
597 base = ex->lhs();
598 }
599
600 if (exs.empty())
601 e.error()
602 .e(lhs()->loc(), "expected `#` on the left-hand side of `{}`", Tok::tag2str(op().tag()))
603 .n("an update needs a component, as in `tuple#index {} value`", Tok::tag2str(op().tag()))
604 .bail();
605
606 auto tup = base->emit(e);
607 DefVec tups, idxs;
608 fe::Vector<const Nom*> noms;
609 for (auto ex : exs | std::views::reverse) {
610 auto value = unwrap_field(e, ex, tup);
611 noms.emplace_back(value ? tup->isa_type<Nom>() : nullptr);
612 if (value) tup = value;
613 auto idx = ex->emit_index(e, tup);
614 tups.emplace_back(tup);
615 idxs.emplace_back(idx);
616 tup = w.extract(tup, idx);
617 }
618
619 auto val = rhs()->emit(e);
620 for (size_t i = tups.size(); i-- != 0;) {
621 val = w.insert(tups[i], idxs[i], val);
622 if (noms[i]) val = w.name(noms[i], val);
623 }
624 return val;
625 }
626 default: break;
627 }
628
629 auto c = callee() ? callee()->emit(e) : nullptr;
630 auto l = lhs()->emit(e);
631 auto r = rhs()->emit(e);
632
633 switch (op().tag()) {
634 case Tag::T_arrow_r: return w.pi(l, r);
635 case Tag::T_at: return w.app(l, r);
636 case Tag::K_inj:
637 r = w.implicit_holes(r);
638 if (auto nom = r->isa<Nom>()) check_nom_scope(e, loc(), nom);
639 return w.inj(r, l);
640 default: return w.implicit_app(c, w.tuple({l, r})); // MIM_INFIX_SUGAR
641 }
642}
643
644Lam* MatchExpr::Arm::emit(Emitter& e, const Def* dom) const {
645 auto _ = e.world().push(loc());
646 if (ptrn()) {
647 auto dom_t = ptrn()->emit_type(e);
648 if (dom && !Check::alpha(dom_t, dom))
649 e.error()
650 .e(ptrn()->loc(), "pattern of type `{}` does not match the constructor's payload `{}`", dom_t, dom)
651 .bail();
652 if (!dom) dom = dom_t;
653 }
654 auto lam = e.world().mut_lam(e.world().pi(dom, e.world().mut_hole_type()));
655 if (ptrn()) ptrn()->emit_value(e, lam->var());
656 return lam->set(true, body()->emit(e));
657}
658
659const Def* MatchExpr::emit_variant(Emitter& e, const Def* scrutinee, const Variant* variant) const {
660 auto sel = DefVec(variant->num_ops());
661 for (auto arm : arms()) {
662 auto i = size_t();
663 if (auto index = arm->index()) {
664 if (*index >= variant->num_ops())
665 e.error()
666 .e(arm->loc(), "variant `{}` has {} cases but case {} was requested", e.variant_str(variant),
667 variant->num_ops(), *index)
668 .bail();
669 i = *index;
670 } else if (auto ctor = arm->ctor()) {
671 i = e.ctor(variant, ctor);
672 } else if (auto id = arm->ptrn()->isa<IdPtrn>(); id && !id->type()) {
673 i = e.ctor(variant, id->dbg());
674 } else {
675 e.error()
676 .e(arm->ptrn()->loc(), "an arm of a match on variant `{}` must name a constructor",
677 e.variant_str(variant))
678 .bail();
679 }
680 if (sel[i]) {
681 e.error().w(arm->loc(), "this arm is unreachable: constructor {} is already handled",
682 e.ctor_names(variant, i));
683 continue;
684 }
685 sel[i] = arm->emit(e, variant->op(i));
686 }
687
688 auto missing = std::vector<std::string>();
689 for (size_t i = 0, n = sel.size(); i != n; ++i)
690 if (!sel[i]) missing.emplace_back(e.ctor_names(variant, i));
691 if (!missing.empty()) e.error().e(loc(), "match expression has no arm for {}", fe::Join(missing, ", ")).bail();
692
693 auto ops = DefVec{scrutinee};
694 ops.append_range(sel);
695 return e.world().match(ops);
696}
697
698const Def* MatchExpr::emit_(Emitter& e) const {
699 DefVec ops;
700 ops.emplace_back(scrutinee()->emit(e));
701 if (auto variant = ops.front()->isa_type<Variant>()) return emit_variant(e, ops.front(), variant);
702 if (auto nom = ops.front()->isa_type<Nom>())
703 if (auto variant = nom->op()->isa<Variant>();
704 variant && std::ranges::any_of(arms(), [](const auto& arm) { return arm->index() || arm->ctor(); })) {
705 open_nom(e, loc(), nom);
706 return emit_variant(e, e.world().struc(ops.front()), variant);
707 }
708
709 for (auto arm : arms()) {
710 if (arm->index() || arm->ctor())
711 e.error()
712 .e(arm->loc(), "a constructor pattern needs a variant scrutinee")
713 .n("but the scrutinee has type `{}`", type_of(ops.front()))
714 .bail();
715 ops.emplace_back(arm->emit(e));
716 }
717 auto res = e.world().match(ops);
718
719 // Only a *source* arm is unreachable by mistake; substitution legitimately kills arms of a polymorphic match.
720 auto cases = Match::cases(ops.front());
721 for (size_t i = 0, n = num_arms(); i != n; ++i)
722 if (std::ranges::none_of(cases, [&](const Def* c) { return Match::accepts(ops[i + 1], c); }))
723 e.error().w(arm(i)->loc(), "this arm is unreachable: no case of `{}` matches `{}`", type_of(ops.front()),
724 ops[i + 1]->isa_type<Pi>()->dom());
725
726 return res;
727}
728
730 // Created before the push: the Pi belongs to the whole function type, not just to this Dom.
731 pi_ = decl_ ? decl_ : e.world().mut_pi(e.world().type_pending(), is_implicit());
732 auto _ = e.world().push(loc());
733 auto dom_t = ptrn()->emit_type(e);
734
735 if (ret_type()) {
736 auto sigma = e.world().mut_sigma(2);
737 auto var = sigma->var();
738 sigma->set(0, dom_t);
739 ptrn()->emit_proj(e, var, 2, 0);
740 auto ret_t = e.world().cn(ret_type()->emit(e));
741 sigma->set(1, ret_t);
742
743 auto imm = sigma->immutabilize();
744 pi_->set_dom(imm ? imm : sigma);
745 } else {
746 pi_->set_dom(dom_t);
747 emit_var(e, ptrn(), pi_);
748 }
749}
750
751const Def* PiExpr::emit_decl_(Emitter& e, const Def* type) const {
752 return dom()->decl_ = e.world().mut_pi(type, dom()->is_implicit());
753}
754
755void PiExpr::emit_body_(Emitter& e, const Def*) const { emit(e); }
756
757const Def* PiExpr::emit_(Emitter& e) const {
758 dom()->emit_type(e);
759 auto cod = codom() ? codom()->emit(e) : e.world().type_bot();
760 auto pi = dom()->pi_->set_codom(cod);
761 if (auto imm = pi->immutabilize()) return imm;
762 return pi;
763}
764
765const Def* LamExpr::emit_decl_(Emitter& e, const Def*) const { return lam()->emit_decl(e), lam()->def(); }
766void LamExpr::emit_body_(Emitter& e, const Def*) const { lam()->emit_body(e); }
767
768const Def* LamExpr::emit_(Emitter& e) const {
769 auto res = emit_decl(e, {});
770 emit_body(e, {});
771 return res;
772}
773
774const Def* AppExpr::emit_(Emitter& e) const {
775 auto c = callee()->emit(e);
776 auto a = arg()->emit(e);
777 return e.world().implicit_app(c, a);
778}
779
780const Def* RetExpr::emit_(Emitter& e) const {
781 auto& w = e.world();
782 auto c = callee()->emit(e);
783 if (auto pi = c->type()->isa<Pi>())
784 if (auto cn = pi->ret_pi()) {
785 auto a = arg()->emit(e);
786 // A dependent domain's ret type refers to the other arguments, so instantiate it with them.
787 if (auto sigma = pi->dom()->isa_mut<Sigma>()) {
788 auto n = sigma->num_ops();
789 auto args = DefVec(n, [&](size_t i) {
790 return i + 1 == n ? w.bot(sigma->op(i)) : n == 2 ? a : a->proj(n - 1, i);
791 });
792 if (auto inst = sigma->reduce(w.tuple(args)).back()->isa<Pi>()) cn = inst;
793 }
794 auto con = w.mut_lam(cn);
795 auto pair = w.tuple({a, con});
796 auto app = w.app(c, pair);
797 ptrn()->emit_value(e, con->var());
798 con->set(false, body()->emit(e));
799 return app;
800 }
801
802 e.error()
803 .e(callee()->loc(), "callee of a `ret` expression must be a returning continuation, but `{}` has type `{}`", c,
804 c->type())
805 .bail();
806}
807
808const Def* SigmaExpr::emit_decl_(Emitter& e, const Def* type) const { return ptrn()->emit_decl(e, type); }
809void SigmaExpr::emit_body_(Emitter& e, const Def* decl) const { ptrn()->emit_body(e, decl); }
810const Def* SigmaExpr::emit_(Emitter& e) const { return ptrn()->emit_type(e); }
811
812DefVec VariantExpr::emit_payloads(Emitter& e) const {
813 return DefVec(num_ctors(), [&](size_t i) -> const Def* {
814 auto type = ctor(i)->type();
815 return type ? type->emit(e) : e.world().sigma();
816 });
817}
818
820 auto variant = e.world().variant(emit_payloads(e));
821 e.add_ctors(variant, this);
822 return variant;
823}
824
825const Def* VariantExpr::emit_decl_(Emitter& e, const Def* type) const {
826 return e.world().mut_variant(type, num_ctors());
827}
828
829void VariantExpr::emit_body_(Emitter& e, const Def* decl) const {
830 auto variant = decl->as_mut<Variant>();
831 variant->set(emit_payloads(e));
832 e.add_ctors(variant, this);
833}
834
835const Def* TupleExpr::emit_(Emitter& e) const {
836 DefVec elems(num_elems(), [&](size_t i) { return elem(i)->emit(e); });
837 return e.world().tuple(elems);
838}
839
840const Def* SeqExpr::emit_(Emitter& e) const {
841 auto s = shape()->emit(e);
842 if (auto lit_s = Lit::isa(s); lit_s && *lit_s == 0) return e.world().prod(is_pack());
843
844 if (index()->dbg().is_anon()) { // immutable
845 auto b = body()->emit(e);
846 return e.world().seq(is_pack(), s, b);
847 }
848
849 auto a = e.world().mut_arr(e.world().type_pending());
850 a->set_shape(s);
851
852 if (is_pack()) {
853 auto p = e.world().mut_pack(a);
854 p->set_shape(s);
855 auto var = p->var();
856 index()->emit(var);
857 auto b = body()->emit(e);
858 p->set_body(b);
859 auto arr_b = b->type();
860 if (auto pvar = var->isa<Var>())
861 // Use array var in array body instead of pack var
862 arr_b = VarRewriter(pvar, a->var()).rewrite(arr_b);
863 a->set_body(arr_b);
864 return e.world().fuse(p);
865 } else {
866 auto var = a->var();
867 index()->emit(var);
868 a->set_body(body()->emit(e));
869 return e.world().fuse(a);
870 }
871}
872
873const Def* SingleExpr::emit_(Emitter& e) const {
874 auto def = body()->emit(e);
875 return is_wrap() ? e.world().wrap(def) : e.world().single(def);
876}
877
878/*
879 * Decl
880 */
881
882void AxmDecl::emit(Emitter& e) const {
883 auto _ = e.world().push(loc());
884 auto type = type_->emit(e);
885 auto [n_curry, n_trip] = Axm::infer_curry_and_trip(type);
886 // An Axm cannot be replaced by the inhabitant, which all other values of a singleton type collapse to.
887 if (e.world().inhabitant(type))
888 e.error().e(type_->loc(), "axiom of singleton type `{}` carries no information", type).bail();
889 if (curry_) {
890 if (curry_.lit_u() > n_curry)
891 e.error().e(curry_.loc(), "curry counter cannot be greater than {}", n_curry).bail();
892 else
893 n_curry = curry_.lit_u();
894 }
895
896 if (trip_) {
897 if (trip_.lit_u() > n_curry)
898 e.error().e(trip_.loc(), "trip counter cannot be greater than curry counter {}", (int)n_curry).bail();
899 else
900 n_trip = trip_.lit_u();
901 }
902
903 for (auto name : names()) {
904 auto annex = name->annex_;
905 if (!annex) continue; // binding failed
906 auto plugin = annex->plugin_id();
907 auto tag = annex->id.tag;
908 auto sub = name->sub_;
909 auto norm = e.driver().normalizer(plugin, tag, sub);
910 auto sym = annex->qualified(e.driver(), name->dbg().sym());
911 auto axm = e.world().axm(norm, n_curry, n_trip, type, plugin, tag, sub)->set(sym);
912 name->def_ = axm;
913 e.world().annexes().attach(plugin, tag, sub, sym, axm);
914 for (auto alias : name->aliases())
915 e.attach_alias(annex, sub, alias.sym());
916 }
917}
918
919void AliasDecl::emit(Emitter& e) const {
920 if (!annex_) return; // skip emit if binding failed
921 auto target = path()->decl();
922 def_ = target->def();
923 if (foreign_)
924 e.world().annexes().attach_alias(annex_->plugin_id(), annex_->id.tag, sub_, foreign_);
925 else
926 e.attach_alias(annex_, sub_, dbg().sym());
927}
928
930 for (auto decl : decls()) {
931 decl->emit(e);
932 e.world().solve_levels();
933 }
934}
935
936void ModDecl::emit(Emitter& e) const {
937 e.push_mod(this);
938 emit_decls(e);
939 e.pop_mod();
940}
941
942void LetDecl::emit(Emitter& e) const {
943 auto _ = e.world().push(loc());
944 auto v = value()->emit(e);
945 def_ = ptrn()->emit_value(e, v);
946 if (auto id = ptrn()->isa<IdPtrn>()) e.attach(id->annex_, id->sub_, id->dbg().sym(), def_);
947}
948
949void RecDecl::emit(Emitter& e) const {
950 emit_decl(e);
951 emit_body(e);
952}
953
954void MutualDecl::emit(Emitter& e) const {
955 for (auto decl : decls())
956 decl->emit_decl(e);
957 for (auto decl : decls())
958 decl->emit_body(e);
959}
960
962 auto _ = e.world().push(loc());
963 def_ = body()->emit_decl(e, e.world().type_infer_level());
964 def_->set(dbg().sym());
965}
966
968 auto _ = e.world().push(loc());
969 body()->emit_body(e, def_);
970 // TODO immutabilize?
971 e.attach(annex_, sub_, dbg().sym(), def_);
972}
973
975 if (!has_mut_body()) return;
976 auto _ = e.world().push(loc());
977 emit_nom(e, body()->emit_decl(e, e.world().type_infer_level()));
978}
979
981 auto _ = e.world().push(loc());
982 if (has_mut_body()) {
983 body()->emit_body(e, def_->as<Nom>()->op());
984 } else {
985 if (def_) return; // see emit_ahead
986 emitting_ = true;
987 emit_nom(e, body()->emit(e));
988 }
989 e.attach(annex_, sub_, dbg().sym(), def_);
990}
991
993 if (!has_mut_body() && !emitting_) emit_body(e);
994 return def_;
995}
996
997void NomDecl::emit_sugar(Emitter& e, Lam* lam) const {
998 // `I dom` then resolves to this very instance as an application of a Lam to its own Var.
999 emit_decl(e);
1000 lam->set_body(emit_ahead(e));
1001 emit_body(e);
1002}
1003
1004void NomDecl::emit_nom(Emitter& e, const Def* body) const {
1005 // World::dump finds a file's annexes by their qualified sym.
1006 auto sym = annex_ ? annex_->qualified(e.driver(), dbg().sym()) : dbg().sym();
1007 auto nom = e.world().nom(e.world().next_gid(), body);
1008 nom->set(sym);
1009 e.add_nom(nom, this);
1010 def_ = nom;
1011}
1012
1014 // Created before the push: the Lam belongs to the whole declaration, not just to this Dom.
1015 lam_ = e.world().mut_lam(pi_);
1016 auto _ = e.world().push(loc());
1017
1018 if (ret()) {
1019 auto var = lam_->var();
1020 ptrn()->emit_proj(e, var, 2, 0);
1021 ret()->emit(var->proj(2, 1));
1022 } else {
1023 emit_var(e, ptrn(), lam_);
1024 }
1025
1026 return lam_;
1027}
1028
1030 auto _ = e.world().push(loc());
1031 bool is_cps = !ISA(tag_, C_DS);
1032
1033 // Iterate over all doms: Build a Lam for curr dom, by first building a curried Pi for the remaining doms.
1034 for (size_t i = 0, n = num_doms(); i != n; ++i) {
1035 for (auto dom : doms() | std::views::drop(i))
1036 dom->emit_type(e);
1037
1038 auto cod = codom() ? codom()->emit(e) : is_cps ? e.world().type_bot() : e.world().mut_hole_type();
1039 for (auto dom : doms() | std::views::drop(i) | std::views::reverse)
1040 cod = dom->pi_->set_codom(cod);
1041
1042 auto cur = dom(i);
1043 auto lam = cur->emit_value(e);
1044 if (auto filter = cur->filter()) {
1045 auto _filter = e.world().push(filter->loc());
1046 lam->set_filter(filter->emit(e));
1047 } else {
1048 lam->set_filter(i + 1 == n && is_cps ? e.world().lit_ff() : e.world().lit_tt());
1049 }
1050
1051 if (i == 0)
1052 def_ = lam->set(dbg().sym());
1053 else
1054 dom(i - 1)->lam_->set_body(lam);
1055 }
1056}
1057
1059 if (!body()) return; // extern forward declaration: the implementation lives in a native translation unit
1060
1061 auto _ = e.world().push(loc());
1062 {
1063 auto _body = e.world().push(body()->loc());
1064 auto lam = doms().back()->lam_;
1065 if (auto nom = nom_sugar())
1066 nom->emit_sugar(e, lam);
1067 else
1068 lam->set_body(body()->emit(e));
1069 }
1070
1071 // rewrite holes
1072 for (size_t i = 0, n = num_doms(); i != n; ++i) {
1073 auto rw = VarRewriter(e.world());
1074 auto lam = dom(i)->lam_;
1075 auto pi = lam->type()->as_mut<Pi>();
1076 for (auto dom : doms() | std::views::drop(i)) {
1077 // A Lam's Var that was never created cannot occur in the codomain.
1078 if (auto var = pi->has_var())
1079 if (auto lam_var = dom->lam_->has_var()) rw.add(lam_var, var);
1080 auto cod = pi->codom();
1081 if (!cod || !cod->isa_mut<Pi>()) break;
1082 pi = cod->as_mut<Pi>();
1083 }
1084
1085 if (auto cod = pi->codom(); cod && cod->has_hole()) pi->set(pi->dom(), rw.rewrite(cod));
1086 }
1087
1088 for (auto dom : doms() | std::views::reverse) {
1089 if (auto imm = dom->pi_->immutabilize()) {
1090 auto f = dom->lam_->filter();
1091 auto b = dom->lam_->body();
1092 dom->lam_->unset()->set_type(imm)->as<Lam>()->set(f, b);
1093 }
1094 }
1095
1096 if (is_extern()) {
1097 auto lam = doms().front()->lam_;
1098 if (!lam->is_closed())
1099 e.error()
1100 .e(loc(),
1101 "external function `{}` is not closed: its inferred type escapes into the scope of `{}`. This "
1102 "usually means an unannotated parameter's type could only be inferred to depend on a variable bound "
1103 "in an inner/sibling scope; add an explicit type annotation to the offending parameter.",
1104 dbg().sym(), lam->free_vars().min()->binder()->sym())
1105 .bail();
1106 if (auto prev = e.world().externals()[dbg().sym()])
1107 e.error()
1108 .e(loc(), "external function `{}` is already defined", dbg().sym())
1109 .n(prev->loc(), "previous definition here")
1110 .bail();
1111 lam->externalize();
1112 }
1113 e.attach(annex_, sub_, dbg().sym(), def_);
1114}
1115
1116void RuleDecl::emit(Emitter& e) const {
1117 auto _ = e.world().push(loc());
1118 auto meta_t = e.world().reform(var()->emit_type(e));
1119 auto rule = e.world().mut_rule(meta_t)->set(dbg());
1120 var()->emit_value(e, rule->var());
1121 auto l = lhs()->emit(e);
1122 auto r = rhs()->emit(e);
1123 auto g = guard()->emit(e);
1124 rule->set(l, r, g);
1125 def_ = rule;
1126}
1127
1128} // namespace mim::ast
const Def * callee() const
Definition lam.h:237
static std::pair< u8, u8 > infer_curry_and_trip(const Def *type)
Definition axm.cpp:14
static const Def * coerce(const Def *type, const Def *value)
Can value be assigned to sth of type?
Definition check.h:105
static bool alpha(const Def *d1, const Def *d2)
Definition check.h:93
Base class for all Defs.
Definition def.h:289
const Def * proj(nat_t a, nat_t i) const
Similar to World::extract while assuming an arity of a, but also works on Sigmas and Arrays.
Definition def.cpp:647
constexpr Node node() const noexcept
Definition def.h:315
Def * set(size_t i, const Def *)
Successively set from left to right.
Definition def.cpp:188
T * as_mut() const
Asserts that this is a mutable, casts constness away and performs a static_cast to T.
Definition def.h:597
const Def * zonk() const
If Holes have been filled, reconstruct the program without them.
Definition check.cpp:20
World & world() const noexcept
Definition def.h:1105
const Def * op(size_t i) const noexcept
Definition def.h:377
const Def * var(nat_t a, nat_t i) noexcept
Definition def.h:492
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Definition def.h:1119
Loc loc() const
Definition def.h:632
Sym sym() const
Definition def.h:633
const Def * immutabilize()
Definition def.cpp:567
const Def * arity() const
Number of elements available to Extract / Insert (may be dynamic).
Definition def.cpp:612
constexpr auto reduce(const Def *arg) const
Definition def.h:681
Dbg dbg() const
Looks up Def::dbg_ in Driver::dbg.
Definition def.cpp:448
const T * isa_type() const
Is Def::unfold_type a T? Yields nullptr for Level, which has no type at all.
Definition def.h:363
constexpr size_t num_ops() const noexcept
Definition def.h:378
Some "global" variables needed all over the place.
Definition driver.h:64
static Hole * isa_unset(const Def *def)
Definition check.h:53
static std::optional< nat_t > isa_lit(const Def *def)
Definition def.cpp:677
A function.
Definition lam.h:91
Lam * set_body(const Def *body)
Set body second.
Definition lam.h:158
static std::optional< T > isa(const Def *def)
Definition def.h:976
static bool accepts(const Def *arm, const Def *c, bool infer=false)
Does arm handle c?
Definition union.cpp:18
static DefVec cases(const Def *scrutinee)
Definition union.cpp:10
Nominal newtype formation.
Definition nom.h:11
flags_t key() const
What tells this Nom apart from one over the same Nom::op.
Definition nom.h:24
const Def * op() const
The wrapped type.
Definition nom.h:21
A dependent function type.
Definition lam.h:14
const Def * dom() const
Definition lam.h:38
Pi * set(const Def *dom, const Def *codom)
Definition lam.h:65
A dependent tuple type.
Definition tuple.h:39
Sigma * set(size_t i, const Def *def)
Definition tuple.h:51
Singleton type formation.
Definition single.h:10
VarRewriter(World &world)
Definition rewrite.h:146
A variable introduced by a binder (mutable).
Definition def.h:857
A sum type whose cases are positional: unlike a Join, they are neither sorted nor deduplicated.
Definition union.h:86
Variant * set(size_t i, const Def *def)
Definition union.h:98
void attach_alias(flags_t, Sym)
Registers a further Sym for an already attach()ed annex, sharing its flags_t;.
Definition world.cpp:149
const Def * attach(flags_t, Sym, const Def *)
Definition world.cpp:137
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:43
Driver & driver()
Definition world.h:107
const Def * sigma(Defs ops)
Definition world.cpp:506
Annexes & annexes()
Definition world.h:289
Owns the arena all AST nodes live in as well as the AnnexInfos of all plugins.
Definition ast.h:107
World & world() const
Definition ast.h:116
void emit(Emitter &) const override
Definition emit.cpp:919
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
Definition ast.h:1271
const Path * path() const
Definition ast.h:1272
const Def * emit_value(Emitter &, const Def *) const override
Definition emit.cpp:242
const Def * emit_type(Emitter &) const override
Definition emit.cpp:284
const Ptrn * ptrn() const
Definition ast.h:409
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
Definition ast.h:410
const Def * emit_(Emitter &) const override
Definition emit.cpp:774
const Expr * arg() const
Definition ast.h:864
const Expr * callee() const
Definition ast.h:863
void emit(Emitter &) const override
Definition emit.cpp:882
auto names() const
Definition ast.h:1113
const Expr * type() const
Definition ast.h:1116
const Expr * expr() const
Definition ast.h:577
auto decls() const
Definition ast.h:575
const Def * emit_(Emitter &) const override
Definition emit.cpp:445
bool is_where() const
Definition ast.h:576
virtual Dbg dbg() const
The name this Decl introduces; anonymous if it has none.
Definition ast.h:259
const Def * def_
Definition ast.h:272
const Def * def() const
Definition ast.h:256
bool within(const ModDecl *mod) const
Definition emit.cpp:145
void add_ctors(const Def *variant, const VariantExpr *expr)
Definition emit.cpp:98
fe::Vector< const ModDecl * > reset_mods()
Definition emit.cpp:127
fe::Error & error()
Definition emit.cpp:22
void attach(AnnexInfo *annex, sub_t sub, Sym name, const Def *def)
name is this registration's own (unqualified) Dbg::sym; AnnexInfo::qualified turns it into the full p...
Definition emit.cpp:28
AST & ast() const
Definition emit.cpp:19
World & world()
Definition emit.cpp:20
Emitter(AST &ast)
Definition emit.cpp:16
std::optional< size_t > find_name(const Def *def, Dbg dbg)
Definition emit.cpp:75
void push_mod(const ModDecl *mod)
Definition emit.cpp:125
void adopt_names(const Nom *nom)
Copies the names of nom's declaration onto the corresponding parts of nom - an instance of it.
Definition emit.cpp:47
const ModDecl * owner
Definition emit.cpp:132
void add_nom(const Nom *nom, const NomDecl *decl)
Definition emit.cpp:135
void add_names(const Def *def, const fe::SymMap< size_t > &sym2idx)
Definition emit.cpp:40
void restore_mods(fe::Vector< const ModDecl * > mods)
Definition emit.cpp:128
NomInfo nom_decl(const Nom *nom) const
The declared nom that nom instantiates and, if its representation is private, the mod owning it.
Definition emit.cpp:140
size_t ctor(const Def *variant, Dbg dbg)
Definition emit.cpp:107
std::string ctor_names(const Def *variant, size_t i)
Every name case i goes by, sorted for a deterministic diagnostic; its index if it has none.
Definition emit.cpp:113
Driver & driver()
Definition emit.cpp:21
void attach_alias(AnnexInfo *annex, sub_t sub, Sym name)
Definition emit.cpp:33
auto variant_str(const Def *variant)
A declared variant prints under its name; an anonymous one spells out its cases, named as source does...
Definition emit.cpp:56
const Def * emit_(Emitter &) const override
Definition emit.cpp:340
const Def * emit_type(Emitter &) const override
Definition emit.cpp:277
const Def * emit_value(Emitter &, const Def *) const override
Definition emit.cpp:223
Base class of all expressions.
Definition ast.h:227
const Def * emit(Emitter &) const
Definition emit.cpp:325
const Def * emit_decl(Emitter &, const Def *type) const
Definition emit.cpp:330
virtual const Def * emit_decl_(Emitter &, const Def *) const
Definition ast.h:245
virtual const Def * emit_(Emitter &) const =0
void emit_body(Emitter &, const Def *decl) const
Definition emit.cpp:335
virtual void emit_body_(Emitter &, const Def *) const
Definition ast.h:246
The AST of one source file: an anonymous ModDecl that a UseDecl binds under a name of its own.
Definition ast.h:1355
auto implicit_imports() const
Imports the driver was told about via -p; they precede everything the file itself declares.
Definition ast.h:1361
void emit(AST &) const
Definition emit.cpp:188
const Def * emit_type(Emitter &) const override
Definition emit.cpp:287
const Def * emit_value(Emitter &, const Def *) const override
Definition emit.cpp:240
const IdPtrn * id() const
Definition ast.h:389
const Def * emit_(Emitter &) const override
Definition emit.cpp:341
const Def * emit(const Def *) const
Definition emit.cpp:238
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
Definition ast.h:282
dbg: type
Definition ast.h:348
const Def * emit_type(Emitter &) const override
Definition emit.cpp:279
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
Definition ast.h:355
const Def * emit_value(Emitter &, const Def *) const override
Definition emit.cpp:234
const Expr * type() const
Definition ast.h:356
lhs op rhs; InfixExpr::op picks the meaning - see MIM_INFIX.
Definition ast.h:649
void emit_body_(Emitter &, const Def *decl) const override
Definition emit.cpp:460
static const InfixExpr * isa_op(Tok::Tag tag, const Expr *expr)
Definition ast.h:665
const Expr * callee() const
Definition ast.h:662
const Expr * rhs() const
Definition ast.h:661
const Def * emit_(Emitter &) const override
Definition emit.cpp:571
const Def * emit_decl_(Emitter &, const Def *type) const override
Definition emit.cpp:455
const Expr * lhs() const
Definition ast.h:659
Tok op() const
Definition ast.h:660
Lam * emit_value(Emitter &) const
Definition emit.cpp:1013
const IdDecl * ret() const
Definition ast.h:1206
auto doms() const
Definition ast.h:1229
const Expr * codom() const
Definition ast.h:1232
void emit_decl(Emitter &) const override
Definition emit.cpp:1029
size_t num_doms() const
Definition ast.h:1231
void emit_body(Emitter &) const override
Definition emit.cpp:1058
const NomDecl * nom_sugar() const
The nom of lam I dom+ = nom I = e; I if nom I dom+ = e desugared to this; within e,...
Definition ast.h:1234
const Dom * dom(size_t i) const
Definition ast.h:1230
void emit_body_(Emitter &, const Def *decl) const override
Definition emit.cpp:766
const Def * emit_(Emitter &) const override
Definition emit.cpp:768
const LamDecl * lam() const
Definition ast.h:842
const Def * emit_decl_(Emitter &, const Def *type) const override
Definition emit.cpp:765
const Expr * value() const
Definition ast.h:1060
const Ptrn * ptrn() const
Definition ast.h:1059
void emit(Emitter &) const override
Definition emit.cpp:942
Tok tok() const
Definition ast.h:551
const Expr * type() const
Definition ast.h:553
const Def * emit_(Emitter &) const override
Definition emit.cpp:423
Tok::Tag tag() const
Definition ast.h:552
const Expr * body() const
Definition ast.h:702
Dbg ctor() const
The constructor in Cons (h, t); a bare Nil is an unannotated IdPtrn instead.
Definition ast.h:706
Lam * emit(Emitter &, const Def *dom=nullptr) const
dom is the case's payload type if the scrutinee is a Variant; otherwise ptrn() determines the domain.
Definition emit.cpp:644
const Ptrn * ptrn() const
Definition ast.h:701
std::optional< nat_t > index() const
The case this arm selects by literal index, as in 1 (h, t).
Definition ast.h:704
auto arms() const
Definition ast.h:727
const Def * emit_(Emitter &) const override
Definition emit.cpp:698
const Expr * scrutinee() const
Definition ast.h:726
const Arm * arm(size_t i) const
Definition ast.h:728
size_t num_arms() const
Definition ast.h:729
mod dbg decls end; also the base of the anonymous File.
Definition ast.h:1321
void emit_decls(Emitter &) const
Definition emit.cpp:929
void emit(Emitter &) const override
Definition emit.cpp:936
auto decls() const
Definition ast.h:1331
auto decls() const
Definition ast.h:1256
void emit(Emitter &) const override
Definition emit.cpp:954
Loc loc() const
Definition ast.h:217
nom dbg = body; - a nominal newtype.
Definition ast.h:1170
void emit_sugar(Emitter &, Lam *lam) const
Sets lam's body to this LamDecl::nom_sugar before emitting the latter's body.
Definition emit.cpp:997
const Def * emit_ahead(Emitter &) const
Emits a nom without a mutable body as soon as a sibling refers to it; nullptr on a cycle.
Definition emit.cpp:992
void emit_body(Emitter &) const override
Definition emit.cpp:980
Vis rep_vis() const
The visibility of this nom's representation: that of the enclosing top-level declaration.
Definition ast.h:1176
void emit_decl(Emitter &) const override
Definition emit.cpp:974
const Def * emit_(Emitter &) const override
Definition emit.cpp:343
const Path * path() const
Definition ast.h:510
Dbg dbg() const
Definition ast.h:511
const Decl * decl() const
Definition ast.h:512
auto dbgs() const
Definition ast.h:491
virtual void emit_type(Emitter &) const
Definition emit.cpp:729
const Expr * ret_type() const
Definition ast.h:796
bool is_implicit() const
Definition ast.h:794
const Ptrn * ptrn() const
Definition ast.h:795
const Def * emit_(Emitter &) const override
Definition emit.cpp:757
const Def * emit_decl_(Emitter &, const Def *type) const override
Definition emit.cpp:751
void emit_body_(Emitter &, const Def *decl) const override
Definition emit.cpp:755
Tok op() const
Definition ast.h:635
const Expr * rhs() const
Definition ast.h:636
const Def * emit_(Emitter &) const override
Definition emit.cpp:523
const Def * emit_(Emitter &) const override
Definition emit.cpp:366
Tok::Tag tag() const
Definition ast.h:532
Base class of all patterns.
Definition ast.h:317
virtual const Def * emit_value(Emitter &, const Def *) const =0
const Def * emit_proj(Emitter &, const Def *def, size_t n, size_t i) const
Ptrn::emit_value on def's i-th of n projections - with this Ptrn's Loc, so the projection is blamed o...
Definition emit.cpp:246
virtual const Def * emit_type(Emitter &) const =0
void emit(Emitter &) const override
Definition emit.cpp:949
virtual void emit_body(Emitter &) const
Definition emit.cpp:967
bool has_mut_body() const
Only such a body is emitted as a mutable, so only it may refer to the declaration itself.
Definition bind.cpp:524
virtual void emit_decl(Emitter &) const
Definition emit.cpp:961
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
Definition ast.h:1142
const Expr * body() const
Definition ast.h:1143
AnnexInfo * annex_
Definition ast.h:1161
const Ptrn * ptrn() const
Definition ast.h:886
const Expr * arg() const
Definition ast.h:888
const Def * emit_(Emitter &) const override
Definition emit.cpp:780
const Expr * body() const
Definition ast.h:889
const Expr * callee() const
Definition ast.h:887
const Ptrn * var() const
Definition ast.h:1300
const Expr * guard() const
Definition ast.h:1303
const Expr * rhs() const
Definition ast.h:1302
const Expr * lhs() const
Definition ast.h:1301
void emit(Emitter &) const override
Definition emit.cpp:1116
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
Definition ast.h:1299
const Expr * dom() const
Definition ast.h:614
const Def * emit_(Emitter &) const override
Definition emit.cpp:361
bool is_pack() const
Definition ast.h:953
const Expr * body() const
Definition ast.h:956
const IdDecl * index() const
Definition ast.h:954
const Def * emit_(Emitter &) const override
Definition emit.cpp:840
const Expr * shape() const
Definition ast.h:955
const TuplePtrn * ptrn() const
Definition ast.h:911
const Def * emit_decl_(Emitter &, const Def *type) const override
Definition emit.cpp:808
void emit_body_(Emitter &, const Def *decl) const override
Definition emit.cpp:809
const Def * emit_(Emitter &) const override
Definition emit.cpp:810
bool is_wrap() const
Definition ast.h:978
const Def * emit_(Emitter &) const override
Definition emit.cpp:873
const Expr * body() const
Definition ast.h:979
std::pair< uint64_t, uint64_t > lit_i() const
Definition tok.h:336
uint64_t lit_u() const
Definition tok.h:338
static const char * tag2str(Tok::Tag)
Definition tok.cpp:10
auto elems() const
Definition ast.h:932
const Expr * elem(size_t i) const
Definition ast.h:933
const Def * emit_(Emitter &) const override
Definition emit.cpp:835
size_t num_elems() const
Definition ast.h:934
(ptrn_0, ..., ptrn_n-1), [ptrn_0, ..., ptrn_n-1], or {ptrn_0, ..., ptrn_n-1}
Definition ast.h:424
const Ptrn * ptrn(size_t i) const
Definition ast.h:438
const Def * emit_type(Emitter &) const override
Definition emit.cpp:289
const Def * emit_decl(Emitter &, const Def *type) const
Definition emit.cpp:315
size_t num_ptrns() const
Definition ast.h:440
Sym field(size_t i) const
The field name of ptrn(i), or the empty Sym if it binds none.
Definition ast.cpp:263
const Def * emit_value(Emitter &, const Def *) const override
Definition emit.cpp:260
const Def * emit_body(Emitter &, const Def *decl) const
Definition emit.cpp:291
const Def * emit_(Emitter &) const override
Definition emit.cpp:356
const Expr * level() const
Definition ast.h:596
void emit(Emitter &) const override
Definition emit.cpp:207
const File * file() const
Definition ast.h:1027
const Mods & mods() const
Definition ast.h:303
bool is_extern() const override
Whether this decl crosses the Mim/native boundary (extern); body presence picks which side supplies i...
Definition ast.h:301
| ctor_0: type_0 | ... | ctor_n-1: type_n-1; a constructor without a type carries [].
Definition ast.h:742
void emit_body_(Emitter &, const Def *decl) const override
Definition emit.cpp:829
const Ctor * ctor(size_t i) const
Definition ast.h:768
const Def * emit_decl_(Emitter &, const Def *type) const override
Definition emit.cpp:825
const Def * emit_(Emitter &) const override
Definition emit.cpp:819
size_t num_ctors() const
Definition ast.h:769
Families of Tok::Tag as reusable case labels; include this in *.cpp files only.
#define C_DS
Direct-style binders; all other binders are CPS.
Definition family.h:86
#define ISA(tag, family)
Turns such a family into a predicate - a case label is of no use outside of a switch.
Definition family.h:138
Definition ast.h:16
static bool is_wildcard(const Ptrn *ptrn)
A wildcard binds nothing, so the Def it would name need not exist - and a dump would then have to nam...
Definition emit.cpp:216
static const Def * unwrap_field(Emitter &e, const InfixExpr *ex, const Def *tup)
Unwraps tup if it is a value of a nom and ex names one of its fields; nullptr otherwise.
Definition emit.cpp:513
static const Def * assign(Emitter &e, const Ptrn *ptrn, const Def *type, const Def *def)
Definition emit.cpp:225
static u64 encode_f(Emitter &e, Loc loc, const Def *t, u64 bits)
A float Tok stores its value as mim::f64 bits; re-encode them for the width of the annotated type t.
Definition emit.cpp:407
static void emit_var(Emitter &e, const Ptrn *ptrn, Def *mut)
Binds ptrn to the Var of mut - which a wildcard does not create.
Definition emit.cpp:253
static void check_nom_scope(Emitter &e, Loc loc, const Nom *nom)
A private nom's representation is confined to the mod that declared it; the type itself is not.
Definition emit.cpp:495
static const Def * emit_ctor(Emitter &e, const Variant *variant, const Expr *index, const Nom *nom=nullptr)
T#C or T#i selects case C or i of the Variant T: a constructor function - or its value for a [] paylo...
Definition emit.cpp:545
static void open_nom(Emitter &e, Loc loc, const Nom *nom)
Checks and prepares access to nom's representation.
Definition emit.cpp:507
static void emit_union(Emitter &e, const Expr *expr, DefVec &types)
a ∪ b ∪ c is one n-ary Join, so flatten the left spine the left-associative parse built.
Definition emit.cpp:466
Tok::Tag Tag
Definition bind.cpp:11
static std::optional< nat_t > isa_math_f(Emitter &e, const Def *type)
If type is a math.F type of known precision/exponent, yields its bit width.
Definition emit.cpp:394
u8 sub_t
Definition types.h:42
float f32
Definition types.h:34
GIDMap< const Def *, To > DefMap
Definition def.h:93
fe::Vector< const Def * > DefVec
Definition def.h:98
GIDSet< const Def * > DefSet
Definition def.h:94
uint64_t u64
Definition types.h:27
auto type_of(const Def *def)
Def::unfold_type of def for a diagnostic - Level is the one Def that has no type at all.
Definition def.h:1144
Bookkeeping of an annex introduced by an AxmDecl.
Definition ast.h:72
Sym qualified(Driver &driver, Sym own) const
Fully-qualified plugin.tag[.sub] name for own (this decl's own Dbg::sym), registered for by-name look...
Definition ast.h:84
struct mim::ast::AnnexInfo::@177100250272201136376142224053244231100060214216 id
plugin_t plugin_id() const
The mangled plugin part of the flags.
Definition ast.h:79