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
6using namespace std::literals;
7
8namespace mim::ast {
9
10using Tag = Tok::Tag;
11
12class Emitter {
13public:
15 : ast_(ast) {}
16
17 AST& ast() const { return ast_; }
18 World& world() { return ast().world(); }
19 Driver& driver() { return world().driver(); }
20
21 /// @p name is the full syntactic name of *this* registration (`%plugin.tag` or `%plugin.tag.sub`).
22 /// We must take it from the declaration rather than from Def::sym, since hash-consing can make several
23 /// annexes share a single Def (e.g. `let %foo.bar = 23; let %foo.baz = 23;`).
24 void attach(AnnexInfo* annex, sub_t sub, Sym name, const Def* def) {
25 if (annex) world().annexes().attach(annex->plugin_id(), annex->id.tag, sub, name, def);
26 }
27
28 absl::node_hash_map<Sigma*, fe::SymMap<size_t>, GIDHash<const Def*>> sigma2sym2idx;
29
30private:
31 AST& ast_;
32};
33
34/*
35 * Module
36 */
37
38void Module::emit(AST& ast) const {
39 auto emitter = Emitter(ast);
40 emit(emitter);
41}
42
43void Module::emit(Emitter& e) const {
44 auto _ = e.world().push(loc());
45 for (const auto& import : implicit_imports())
46 import->emit(e);
47 for (const auto& import : imports())
48 import->emit(e);
49 for (const auto& decl : decls())
50 decl->emit(e);
51}
52
53void Import::emit(Emitter& e) const { module()->emit(e); }
54
55/*
56 * Ptrn::emit_value
57 */
58
59const Def* ErrorPtrn::emit_value(Emitter&, const Def* def) const { return def; }
60
61const Def* IdPtrn::emit_value(Emitter& e, const Def* def) const {
62 emit_type(e);
63 return def_ = def->set(dbg());
64}
65
66const Def* GrpPtrn::emit_value(Emitter&, const Def* def) const { return def_ = def->set(dbg()); }
67
68const Def* AliasPtrn::emit_value(Emitter& e, const Def* def) const {
69 return def_ = ptrn()->emit_value(e, def)->set(dbg());
70}
71
72const Def* TuplePtrn::emit_value(Emitter& e, const Def* def) const {
73 auto _ = e.world().push(loc());
74 emit_type(e);
75 for (size_t i = 0, n = num_ptrns(); i != n; ++i)
76 ptrn(i)->emit_value(e, def->proj(n, i));
77 return def_ = def;
78}
79
80/*
81 * Ptrn::emit_Type
82 */
83
84const Def* ErrorPtrn::emit_type(Emitter&) const { fe::unreachable(); }
85
86const Def* IdPtrn::emit_type(Emitter& e) const {
87 auto _ = e.world().push(loc());
88 return type() ? type()->emit(e) : e.world().mut_hole_type();
89}
90
91const Def* AliasPtrn::emit_type(Emitter& e) const { return ptrn()->emit_type(e); }
92
93const Def* GrpPtrn::emit_type(Emitter& e) const { return id()->emit_type(e); }
94
95const Def* TuplePtrn::emit_type(Emitter& e) const { return emit_body(e, {}); }
96
97const Def* TuplePtrn::emit_body(Emitter& e, const Def* decl) const {
98 auto _ = e.world().push(loc());
99 auto n = num_ptrns();
100 Sigma* sigma;
101 if (decl) {
102 sigma = decl->as_mut<Sigma>();
103 } else {
104 auto type = e.world().type_infer_univ();
105 sigma = e.world().mut_sigma(type, n);
106 }
107 auto var = sigma->var();
108 auto& sym2idx = e.sigma2sym2idx[sigma];
109
110 for (size_t i = 0; i != n; ++i) {
111 sigma->set(i, ptrn(i)->emit_type(e));
112 ptrn(i)->emit_value(e, var->proj(n, i));
113 if (auto id = ptrn(i)->isa<IdPtrn>()) sym2idx[id->dbg().sym()] = i;
114 }
115
116 if (auto imm = sigma->immutabilize()) return imm;
117 return sigma;
118}
119
120const Def* TuplePtrn::emit_decl(Emitter& e, const Def* type) const {
121 auto _ = e.world().push(loc());
122 type = type ? type : e.world().type_infer_univ();
123 return e.world().mut_sigma(type, num_ptrns());
124}
125
126/*
127 * Expr
128 */
129
130const Def* Expr::emit(Emitter& e) const {
131 auto _ = e.world().push(loc());
132 return emit_(e);
133}
134
135const Def* ErrorExpr::emit_(Emitter&) const { fe::unreachable(); }
136const Def* HoleExpr::emit_(Emitter& e) const { return e.world().mut_hole_type(); }
137
138const Def* IdExpr::emit_(Emitter&) const {
139 assert(decl());
140 return decl()->def();
141}
142
143const Def* TypeExpr::emit_(Emitter& e) const {
144 auto l = level()->emit(e);
145 return e.world().type(l);
146}
147
148const Def* RuleExpr::emit_(Emitter& e) const {
149 auto m = dom()->emit(e);
150 return e.world().reform(m);
151}
152
153const Def* PrimaryExpr ::emit_(Emitter& e) const {
154 // clang-format off
155 switch (tag()) {
156 case Tag::K_Univ: return e.world().univ();
157 case Tag::K_Nat: return e.world().type_nat();
158 case Tag::K_Idx: return e.world().type_idx();
159 case Tag::K_Bool: return e.world().type_bool();
160 case Tag::K_ff: return e.world().lit_ff();
161 case Tag::K_tt: return e.world().lit_tt();
162 case Tag::K_i1: return e.world().lit_i1();
163 case Tag::K_i8: return e.world().lit_i8();
164 case Tag::K_i16: return e.world().lit_i16();
165 case Tag::K_i32: return e.world().lit_i32();
166 case Tag::K_i64: return e.world().lit_i64();
167 case Tag::K_I1: return e.world().type_i1();
168 case Tag::K_I8: return e.world().type_i8();
169 case Tag::K_I16: return e.world().type_i16();
170 case Tag::K_I32: return e.world().type_i32();
171 case Tag::K_I64: return e.world().type_i64();
172 case Tag::T_star: return e.world().type<0>();
173 case Tag::T_box: return e.world().type<1>();
174 default: fe::unreachable();
175 }
176 // clang-format on
177}
178
179/// If @p type is a `%math.F` type of known precision/exponent, yields its bit width.
180/// Note that libmim must not depend on the generated math plugin header, so lookup the Axm at runtime instead.
181static std::optional<nat_t> isa_math_f(Emitter& e, const Def* type) {
182 auto math_f = e.world().annex(e.world().sym("%math.F"));
183 if (auto app = type->zonk()->isa<App>(); math_f && app && app->callee() == math_f) {
184 if (auto [p, ex] = app->arg()->projs<2>([](auto op) { return Lit::isa(op); }); p && ex) {
185 if (*p == 10 && *ex == 5) return 16;
186 if (*p == 23 && *ex == 8) return 32;
187 if (*p == 52 && *ex == 11) return 64;
188 }
189 }
190 return {};
191}
192
193/// A float Tok stores its value as mim::f64 bits; re-encode them for the width of the annotated type @p t.
194static u64 encode_f(Emitter& e, [[maybe_unused]] Loc loc, const Def* t, u64 bits) {
195 if (auto width = isa_math_f(e, t)) {
196 auto val = std::bit_cast<f64>(bits);
197 switch (*width) {
198#if defined(__STDCPP_FLOAT16_T__)
199 case 16: return std::bit_cast<u16>(f16(val));
200#else
201 case 16: error(loc, "16-bit floating-point literals are not supported on this platform");
202#endif
203 case 32: return std::bit_cast<u32>(f32(val));
204 default: break;
205 }
206 }
207 return bits;
208}
209
210const Def* LitExpr::emit_(Emitter& e) const {
211 auto t = type() ? type()->emit(e) : nullptr;
212 // clang-format off
213 switch (tag()) {
214 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());
215 case Tag::L_s:
216 case Tag::L_u: return t ? e.world().lit(t, tok().lit_u()) : e.world().lit_nat(tok().lit_u());
217 case Tag::L_i: return tok().lit_i();
218 case Tag::L_c: return e.world().lit_i8(tok().lit_c());
219 case Tag::L_str: return e.world().tuple(tok().sym());
220 case Tag::T_bot: return t ? e.world().bot(t) : e.world().type_bot();
221 case Tag::T_top: return t ? e.world().top(t) : e.world().type_top();
222 default: fe::unreachable();
223 }
224 // clang-format on
225}
226
227const Def* DeclExpr::emit_(Emitter& e) const {
228 if (is_where())
229 for (const auto& decl : decls() | std::views::reverse)
230 decl->emit(e);
231 else
232 for (const auto& decl : decls())
233 decl->emit(e);
234 return expr()->emit(e);
235}
236
237const Def* ArrowExpr::emit_decl(Emitter& e, const Def* type) const {
238 return decl_ = e.world().mut_pi(type, false)->set(loc());
239}
240
241void ArrowExpr::emit_body(Emitter& e, const Def*) const {
242 decl_->set_dom(dom()->emit(e));
243 decl_->set_codom(codom()->emit(e)); // TODO try to immutabilize
244}
245
246const Def* ArrowExpr::emit_(Emitter& e) const {
247 auto d = dom()->emit(e);
248 auto c = codom()->emit(e);
249 return e.world().pi(d, c);
250}
251
252const Def* UnionExpr::emit_(Emitter& e) const {
253 DefVec etypes;
254 for (auto& t : types())
255 etypes.emplace_back(t->emit(e));
256 return e.world().join(etypes);
257}
258
259const Def* InjExpr::emit_(Emitter& e) const {
260 auto v = value()->emit(e);
261 auto t = type()->emit(e);
262 return e.world().inj(t, v);
263}
264
266 auto _ = e.world().push(loc());
267 auto dom_t = ptrn()->emit_type(e);
268 auto pi = e.world().pi(dom_t, e.world().mut_hole_type());
269 auto lam = e.world().mut_lam(pi);
270 ptrn()->emit_value(e, lam->var());
271 return lam->set(true, body()->emit(e));
272}
273
274const Def* MatchExpr::emit_(Emitter& e) const {
275 DefVec res;
276 res.emplace_back(scrutinee()->emit(e));
277 for (const auto& arm : arms())
278 res.emplace_back(arm->emit(e));
279 return e.world().match(res);
280}
281
283 pi_ = decl_ ? decl_ : e.world().mut_pi(e.world().type_infer_univ(), is_implicit());
284 auto dom_t = ptrn()->emit_type(e);
285
286 if (ret()) {
287 auto sigma = e.world().mut_sigma(2)->set(loc());
288 auto var = sigma->var()->set(ret()->loc().anew_begin());
289 sigma->set(0, dom_t);
290 ptrn()->emit_value(e, var->proj(2, 0));
291 auto ret_t = e.world().cn(ret()->emit_type(e));
292 sigma->set(1, ret_t);
293
294 if (auto imm = sigma->immutabilize())
295 dom_t = imm;
296 else
297 dom_t = sigma;
298 pi_->set_dom(dom_t);
299 } else {
300 pi_->set_dom(dom_t);
301 ptrn()->emit_value(e, pi_->var());
302 }
303}
304
305const Def* PiExpr::emit_decl(Emitter& e, const Def* type) const {
306 return dom()->decl_ = e.world().mut_pi(type, dom()->is_implicit())->set(loc());
307}
308
309void PiExpr::emit_body(Emitter& e, const Def*) const { emit(e); }
310
311const Def* PiExpr::emit_(Emitter& e) const {
312 dom()->emit_type(e);
313 auto cod = codom() ? codom()->emit(e) : e.world().type_bot();
314 return dom()->pi_->set_codom(cod);
315}
316
317const Def* LamExpr::emit_decl(Emitter& e, const Def*) const { return lam()->emit_decl(e), lam()->def(); }
318void LamExpr::emit_body(Emitter& e, const Def*) const { lam()->emit_body(e); }
319
320const Def* LamExpr::emit_(Emitter& e) const {
321 auto res = emit_decl(e, {});
322 emit_body(e, {});
323 return res;
324}
325
326const Def* AppExpr::emit_(Emitter& e) const {
327 auto c = callee()->emit(e);
328 auto a = arg()->emit(e);
329 return is_explicit() ? e.world().app(c, a) : e.world().implicit_app(c, a);
330}
331
332const Def* RetExpr::emit_(Emitter& e) const {
333 auto c = callee()->emit(e);
334 if (auto cn = Pi::has_ret_pi(c->type())) {
335 auto con = e.world().mut_lam(cn);
336 auto pair = e.world().tuple({arg()->emit(e), con});
337 auto app = e.world().app(c, pair)->set(c->loc() + arg()->loc());
338 ptrn()->emit_value(e, con->var());
339 con->set(false, body()->emit(e));
340 return app;
341 }
342
343 error(c->loc(), "callee of a ret expression must type as a returning continuation but got '{}' of type '{}'", c,
344 c->type());
345}
346
347const Def* SigmaExpr::emit_decl(Emitter& e, const Def* type) const { return ptrn()->emit_decl(e, type); }
348void SigmaExpr::emit_body(Emitter& e, const Def* decl) const { ptrn()->emit_body(e, decl); }
349const Def* SigmaExpr::emit_(Emitter& e) const { return ptrn()->emit_type(e); }
350
351const Def* TupleExpr::emit_(Emitter& e) const {
352 DefVec elems(num_elems(), [&](size_t i) { return elem(i)->emit(e); });
353 return e.world().tuple(elems);
354}
355
356const Def* SeqExpr::emit_(Emitter& e) const {
357 auto s = arity()->emit_type(e);
358 if (auto lit_s = Lit::isa(s); lit_s && *lit_s == 0) return e.world().unit(is_pack());
359
360 if (arity()->dbg().is_anon()) { // immutable
361 auto b = body()->emit(e);
362 return e.world().seq(is_pack(), s, b);
363 }
364
365 auto t = e.world().type_infer_univ();
366 auto a = e.world().mut_arr(t);
367 a->set_arity(s);
368
369 if (is_pack()) {
370 auto p = e.world().mut_pack(a);
371 auto var = p->var();
372 arity()->emit_value(e, var);
373 auto b = body()->emit(e);
374 p->set(b);
375 auto arr_b = b->type();
376 if (auto pvar = var->isa<Var>())
377 // Use array var in array body instead of pack var
378 arr_b = VarRewriter(pvar, a->var()).rewrite(arr_b);
379 a->set_body(arr_b);
380 if (auto imm = p->immutabilize()) return imm;
381 return p;
382 } else {
383 auto var = a->var();
384 arity()->emit_value(e, var);
385 a->set_body(body()->emit(e));
386 if (auto imm = a->immutabilize()) return imm;
387 return a;
388 }
389}
390
392 auto tup = tuple()->emit(e);
393 if (auto dbg = std::get_if<Dbg>(&index())) {
394 if (auto sigma = tup->type()->isa_mut<Sigma>()) {
395 if (auto i = e.sigma2sym2idx.find(sigma); i != e.sigma2sym2idx.end()) {
396 auto sigma = i->first->as_mut<Sigma>();
397 const auto& sym2idx = i->second;
398 if (auto i = sym2idx.find(dbg->sym()); i != sym2idx.end())
399 return e.world().extract(tup, sigma->num_ops(), i->second);
400 }
401 }
402
403 if (decl()) return e.world().extract(tup, decl()->def());
404 error(dbg->loc(), "cannot resolve index '{}' for extraction", *dbg);
405 }
406
407 auto expr = std::get<Ptr<Expr>>(index()).get();
408 auto i = expr->emit(e);
409 return e.world().extract(tup, i);
410}
411
412const Def* InsertExpr::emit_(Emitter& e) const {
413 auto t = tuple()->emit(e);
414 auto i = index()->emit(e);
415 auto v = value()->emit(e);
416 return e.world().insert(t, i, v);
417}
418
419const Def* UniqExpr::emit_(Emitter& e) const { return e.world().uniq(inhabitant()->emit(e)); }
420
421/*
422 * Decl
423 */
424
425void AxmDecl::emit(Emitter& e) const {
426 if (!annex_) return; // Skip emit if binding failed
427 mim_type_ = type()->emit(e);
428 auto& id = annex_->id;
429 auto plugin = annex_->plugin_id();
430
431 std::tie(id.curry, id.trip) = Axm::infer_curry_and_trip(mim_type_);
432 if (curry_) {
433 if (curry_.lit_u() > id.curry)
434 error(curry_.loc(), "curry counter cannot be greater than {}", id.curry);
435 else
436 id.curry = curry_.lit_u();
437 }
438
439 if (trip_) {
440 if (trip_.lit_u() > id.curry)
441 error(trip_.loc(), "trip counter cannot be greater than curry counter '{}'", (int)id.curry);
442 else
443 id.trip = trip_.lit_u();
444 }
445
446 if (num_subs() == 0) {
447 auto norm = e.driver().normalizer(plugin, id.tag, 0);
448 auto axm = e.world().axm(norm, id.curry, id.trip, mim_type_, plugin, id.tag, 0)->set(dbg());
449 def_ = axm;
450 e.world().annexes().attach(plugin, id.tag, 0, dbg().sym(), axm);
451 } else {
452 for (sub_t i = 0, n = num_subs(); i != n; ++i) {
453 sub_t s = i + offset_;
454 auto norm = e.driver().normalizer(plugin, id.tag, s);
455 auto name = e.world().sym(dbg().sym().str() + "."s + sub(i).front()->dbg().sym().str());
456 auto axm = e.world().axm(norm, id.curry, id.trip, mim_type_, plugin, id.tag, s)->set(name);
457 e.world().annexes().attach(plugin, id.tag, s, name, axm);
458
459 for (const auto& alias : sub(i))
460 alias->def_ = axm;
461 }
462 }
463}
464
465void LetDecl::emit(Emitter& e) const {
466 auto v = value()->emit(e);
467 def_ = ptrn()->emit_value(e, v);
468 if (auto id = ptrn()->isa<IdPtrn>()) e.attach(annex_, sub_, id->dbg().sym(), def_);
469}
470
471void RecDecl::emit(Emitter& e) const {
472 for (auto curr = this; curr; curr = curr->next())
473 curr->emit_decl(e);
474 for (auto curr = this; curr; curr = curr->next())
475 curr->emit_body(e);
476}
477
479 auto t = type() ? type()->emit(e) : e.world().type_infer_univ();
480 def_ = body()->emit_decl(e, t);
481 def_->set(dbg());
482}
483
485 body()->emit_body(e, def_);
486 // TODO immutabilize?
487 e.attach(annex_, sub_, dbg().sym(), def_);
488}
489
491 lam_ = e.world().mut_lam(pi_);
492 auto var = lam_->var();
493
494 if (ret()) {
495 ptrn()->emit_value(e, var->proj(2, 0));
496 ret()->emit_value(e, var->proj(2, 1));
497 } else {
498 ptrn()->emit_value(e, var);
499 }
500
501 return lam_;
502}
503
505 auto _ = e.world().push(loc());
506 bool is_cps = tag_ == Tag::K_cn || tag_ == Tag::K_con || tag_ == Tag::K_fn || tag_ == Tag::K_fun;
507
508 // Iterate over all doms: Build a Lam for curr dom, by first building a curried Pi for the remaining doms.
509 for (size_t i = 0, n = num_doms(); i != n; ++i) {
510 for (const auto& dom : doms() | std::views::drop(i))
511 dom->emit_type(e);
512
513 auto cod = codom() ? codom()->emit(e) : is_cps ? e.world().type_bot() : e.world().mut_hole_type();
514 for (const auto& dom : doms() | std::views::drop(i) | std::views::reverse)
515 cod = dom->pi_->set_codom(cod);
516
517 auto cur = dom(i);
518 auto lam = cur->emit_value(e);
519 auto filter = cur->filter() ? cur->filter()->emit(e)
520 : i + 1 == n && is_cps ? e.world().lit_ff()
521 : e.world().lit_tt();
522 lam->set_filter(filter);
523
524 if (i == 0)
525 def_ = lam->set(dbg().sym());
526 else
527 dom(i - 1)->lam_->set_body(lam);
528 }
529}
530
532 auto b = body()->emit(e);
533 doms().back()->lam_->set_body(b);
534
535 // rewrite holes
536 for (size_t i = 0, n = num_doms(); i != n; ++i) {
537 auto rw = VarRewriter(e.world());
538 auto lam = dom(i)->lam_;
539 auto pi = lam->type()->as_mut<Pi>();
540 for (const auto& dom : doms() | std::views::drop(i)) {
541 if (auto var = pi->has_var()) rw.add(dom->lam_->var()->as<Var>(), var);
542 auto cod = pi->codom();
543 if (!cod || !cod->isa_mut<Pi>()) break;
544 pi = cod->as_mut<Pi>();
545 }
546
547 if (auto cod = pi->codom(); cod && cod->has_dep(Dep::Hole)) pi->set(pi->dom(), rw.rewrite(cod));
548 }
549
550 for (const auto& dom : doms() | std::views::reverse) {
551 if (auto imm = dom->pi_->immutabilize()) {
552 auto f = dom->lam_->filter();
553 auto b = dom->lam_->body();
554 dom->lam_->unset()->set_type(imm)->as<Lam>()->set(f, b);
555 }
556 }
557
558 if (is_external()) {
559 auto lam = doms().front()->lam_;
560 if (!lam->is_closed())
561 error(loc(),
562 "external function '{}' is not closed: its inferred type escapes into the scope of '{}'. This "
563 "usually means an unannotated parameter's type could only be inferred to depend on a variable bound "
564 "in an inner/sibling scope; add an explicit type annotation to the offending parameter.",
565 dbg().sym(), (*lam->free_vars().begin())->binder()->sym());
566 lam->externalize();
567 }
568 e.attach(annex_, sub_, dbg().sym(), def_);
569}
570
571void CDecl::emit(Emitter& e) const {
572 auto dom_t = dom()->emit_type(e);
573 if (tag() == Tag::K_cfun) {
574 auto ret_t = codom()->emit(e);
575 def_ = e.world().mut_fun(dom_t, ret_t)->set(dbg());
576 } else {
577 def_ = e.world().mut_con(dom_t)->set(dbg());
578 }
579}
580
581void RuleDecl::emit(Emitter& e) const {
582 auto _ = e.world().push(loc());
583 auto meta_t = e.world().reform(var()->emit_type(e));
584 auto rule = e.world().mut_rule(meta_t)->set(dbg());
585 var()->emit_value(e, rule->var());
586 auto l = lhs()->emit(e);
587 auto r = rhs()->emit(e);
588 auto g = guard()->emit(e);
589 rule->set(l, r, g);
590 def_ = rule;
591}
592
593} // namespace mim::ast
const Def * callee() const
Definition lam.h:276
static std::pair< u8, u8 > infer_curry_and_trip(const Def *type)
Definition axm.cpp:14
Base class for all Defs.
Definition def.h:261
Def * set(size_t i, const Def *)
Successively set from left to right.
Definition def.cpp:276
T * as_mut() const
Asserts that this is a mutable, casts constness away and performs a static_cast to T.
Definition def.h:536
const Def * var(nat_t a, nat_t i) noexcept
Definition def.h:441
Some "global" variables needed all over the place.
Definition driver.h:20
A function.
Definition lam.h:110
static std::optional< T > isa(const Def *def)
Definition def.h:878
A dependent function type.
Definition lam.h:14
static const Pi * has_ret_pi(const Def *d)
Yields the Pi::ret_pi() of d, if it is in fact a Pi.
Definition lam.h:59
Pi * set(const Def *dom, const Def *codom)
Definition lam.h:76
A dependent tuple type.
Definition tuple.h:22
const Def * immutabilize() final
Tries to make an immutable from a mutable.
Definition def.cpp:208
Sigma * set(size_t i, const Def *def)
Definition tuple.h:34
Extends Rewriter for variable substitution.
Definition rewrite.h:107
const Def * rewrite(const Def *) final
Definition rewrite.cpp:288
A variable introduced by a binder (mutable).
Definition def.h:756
const Def * attach(flags_t, Sym, const Def *)
Definition world.cpp:43
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:36
const Driver & driver() const
Definition world.h:93
Annexes & annexes()
Definition world.h:267
World & world()
Definition ast.h:67
const Def * emit_value(Emitter &, const Def *) const override
Definition emit.cpp:68
Dbg dbg() const
Definition ast.h:272
const Def * emit_type(Emitter &) const override
Definition emit.cpp:91
const Ptrn * ptrn() const
Definition ast.h:271
const Def * emit_(Emitter &) const override
Definition emit.cpp:326
bool is_explicit() const
Definition ast.h:666
const Expr * arg() const
Definition ast.h:668
const Expr * callee() const
Definition ast.h:667
void emit_body(Emitter &, const Def *decl) const override
Definition emit.cpp:241
const Def * emit_decl(Emitter &, const Def *type) const override
Definition emit.cpp:237
const Def * emit_(Emitter &) const override
Definition emit.cpp:246
void emit(Emitter &) const override
Definition emit.cpp:425
const Expr * type() const
Definition ast.h:904
Tok trip() const
Definition ast.h:907
size_t num_subs() const
Definition ast.h:902
Tok curry() const
Definition ast.h:906
Dbg dbg() const
Definition ast.h:900
const auto & sub(size_t i) const
Definition ast.h:903
Tok::Tag tag() const
Definition ast.h:1036
const Ptrn * dom() const
Definition ast.h:1037
void emit(Emitter &) const override
Definition emit.cpp:571
const Expr * codom() const
Definition ast.h:1038
Dbg dbg() const
Definition ast.h:1035
const Expr * expr() const
Definition ast.h:416
const Def * emit_(Emitter &) const override
Definition emit.cpp:227
const auto & decls() const
Definition ast.h:414
bool is_where() const
Definition ast.h:415
const Def * def_
Definition ast.h:169
const Def * def() const
Definition ast.h:166
void attach(AnnexInfo *annex, sub_t sub, Sym name, const Def *def)
name is the full syntactic name of this registration (plugin.tag or plugin.tag.sub).
Definition emit.cpp:24
AST & ast() const
Definition emit.cpp:17
World & world()
Definition emit.cpp:18
Emitter(AST &ast)
Definition emit.cpp:14
absl::node_hash_map< Sigma *, fe::SymMap< size_t >, GIDHash< const Def * > > sigma2sym2idx
Definition emit.cpp:28
Driver & driver()
Definition emit.cpp:19
const Def * emit_(Emitter &) const override
Definition emit.cpp:135
const Def * emit_type(Emitter &) const override
Definition emit.cpp:84
const Def * emit_value(Emitter &, const Def *) const override
Definition emit.cpp:59
const Def * emit(Emitter &) const
Definition emit.cpp:130
virtual void emit_body(Emitter &, const Def *) const
Definition ast.h:154
virtual const Def * emit_(Emitter &) const =0
virtual const Def * emit_decl(Emitter &, const Def *) const
Definition ast.h:153
const Decl * decl() const
Definition ast.h:789
const Def * emit_(Emitter &) const override
Definition emit.cpp:391
const auto & index() const
Definition ast.h:788
const Expr * tuple() const
Definition ast.h:787
const Def * emit_type(Emitter &) const override
Definition emit.cpp:93
const Def * emit_value(Emitter &, const Def *) const override
Definition emit.cpp:66
Dbg dbg() const
Definition ast.h:250
const IdPtrn * id() const
Definition ast.h:251
const Def * emit_(Emitter &) const override
Definition emit.cpp:136
const Def * emit_(Emitter &) const override
Definition emit.cpp:138
const Decl * decl() const
Definition ast.h:351
const Def * emit_type(Emitter &) const override
Definition emit.cpp:86
const Def * emit_value(Emitter &, const Def *) const override
Definition emit.cpp:61
Dbg dbg() const
Definition ast.h:220
const Expr * type() const
Definition ast.h:221
void emit(Emitter &) const
Definition emit.cpp:53
const Module * module() const
Definition ast.h:1097
const Def * emit_(Emitter &) const override
Definition emit.cpp:259
const Expr * type() const
Definition ast.h:496
const Expr * value() const
Definition ast.h:495
const Expr * index() const
Definition ast.h:812
const Expr * tuple() const
Definition ast.h:811
const Def * emit_(Emitter &) const override
Definition emit.cpp:412
const Expr * value() const
Definition ast.h:813
Lam * emit_value(Emitter &) const
Definition emit.cpp:490
bool is_external() const
Definition ast.h:1004
const Ptrs< Dom > & doms() const
Definition ast.h:1005
const Expr * codom() const
Definition ast.h:1008
void emit_decl(Emitter &) const override
Definition emit.cpp:504
size_t num_doms() const
Definition ast.h:1007
void emit_body(Emitter &) const override
Definition emit.cpp:531
const Dom * dom(size_t i) const
Definition ast.h:1006
void emit_body(Emitter &, const Def *decl) const override
Definition emit.cpp:318
const Def * emit_(Emitter &) const override
Definition emit.cpp:320
const LamDecl * lam() const
Definition ast.h:644
const Def * emit_decl(Emitter &, const Def *type) const override
Definition emit.cpp:317
const Expr * value() const
Definition ast.h:857
const Ptrn * ptrn() const
Definition ast.h:856
void emit(Emitter &) const override
Definition emit.cpp:465
Tok tok() const
Definition ast.h:391
const Expr * type() const
Definition ast.h:393
const Def * emit_(Emitter &) const override
Definition emit.cpp:210
Tok::Tag tag() const
Definition ast.h:392
Lam * emit(Emitter &) const
Definition emit.cpp:265
const Expr * body() const
Definition ast.h:521
const Ptrn * ptrn() const
Definition ast.h:520
const Def * emit_(Emitter &) const override
Definition emit.cpp:274
const Expr * scrutinee() const
Definition ast.h:537
const Arm * arm(size_t i) const
Definition ast.h:539
const auto & arms() const
Definition ast.h:538
const auto & decls() const
Definition ast.h:1125
void emit(AST &) const
Definition emit.cpp:38
const auto & implicit_imports() const
Definition ast.h:1123
const auto & imports() const
Definition ast.h:1124
Loc loc() const
Definition ast.h:134
virtual void emit_type(Emitter &) const
Definition emit.cpp:282
const IdPtrn * ret() const
Definition ast.h:593
bool is_implicit() const
Definition ast.h:591
const Ptrn * ptrn() const
Definition ast.h:592
const Def * emit_(Emitter &) const override
Definition emit.cpp:311
const Def * emit_decl(Emitter &, const Def *type) const override
Definition emit.cpp:305
void emit_body(Emitter &, const Def *decl) const override
Definition emit.cpp:309
Tok::Tag tag() const
Definition ast.h:372
virtual const Def * emit_value(Emitter &, const Def *) const =0
virtual const Def * emit_type(Emitter &) const =0
void emit(Emitter &) const override
Definition emit.cpp:471
Dbg dbg() const
Definition ast.h:934
virtual void emit_body(Emitter &) const
Definition emit.cpp:484
virtual void emit_decl(Emitter &) const
Definition emit.cpp:478
const Expr * body() const
Definition ast.h:936
const Expr * type() const
Definition ast.h:935
const Ptrn * ptrn() const
Definition ast.h:691
const Expr * arg() const
Definition ast.h:693
const Def * emit_(Emitter &) const override
Definition emit.cpp:332
const Expr * body() const
Definition ast.h:694
const Expr * callee() const
Definition ast.h:692
const Ptrn * var() const
Definition ast.h:1066
const Expr * guard() const
Definition ast.h:1069
const Expr * rhs() const
Definition ast.h:1068
const Expr * lhs() const
Definition ast.h:1067
Dbg dbg() const
Definition ast.h:1065
void emit(Emitter &) const override
Definition emit.cpp:581
const Expr * dom() const
Definition ast.h:454
const Def * emit_(Emitter &) const override
Definition emit.cpp:148
bool is_pack() const
Definition ast.h:760
const Expr * body() const
Definition ast.h:762
const IdPtrn * arity() const
Definition ast.h:761
const Def * emit_(Emitter &) const override
Definition emit.cpp:356
const TuplePtrn * ptrn() const
Definition ast.h:716
const Def * emit_(Emitter &) const override
Definition emit.cpp:349
void emit_body(Emitter &, const Def *decl) const override
Definition emit.cpp:348
const Def * emit_decl(Emitter &, const Def *type) const override
Definition emit.cpp:347
const Lit * lit_i() const
Definition tok.h:219
const Expr * elem(size_t i) const
Definition ast.h:739
const Def * emit_(Emitter &) const override
Definition emit.cpp:351
const auto & elems() const
Definition ast.h:738
size_t num_elems() const
Definition ast.h:740
const Ptrn * ptrn(size_t i) const
Definition ast.h:300
const Def * emit_type(Emitter &) const override
Definition emit.cpp:95
const Def * emit_decl(Emitter &, const Def *type) const
Definition emit.cpp:120
size_t num_ptrns() const
Definition ast.h:301
const Def * emit_value(Emitter &, const Def *) const override
Definition emit.cpp:72
const Def * emit_body(Emitter &, const Def *decl) const
Definition emit.cpp:97
const Def * emit_(Emitter &) const override
Definition emit.cpp:143
const Expr * level() const
Definition ast.h:436
const auto & types() const
Definition ast.h:474
const Def * emit_(Emitter &) const override
Definition emit.cpp:252
const Expr * inhabitant() const
Definition ast.h:833
const Def * emit_(Emitter &) const override
Definition emit.cpp:419
Definition ast.h:14
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:194
Tok::Tag Tag
Definition bind.cpp:7
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:181
Vector< const Def * > DefVec
Definition def.h:79
u8 sub_t
Definition types.h:42
@ Hole
Depends on a Hole.
Definition def.h:124
float f32
Definition types.h:34
constexpr decltype(auto) get(Span< T, N > span) noexcept
Definition span.h:119
void error(Loc loc, std::format_string< Args... > f, Args &&... args)
Definition dbg.h:114
uint64_t u64
Definition types.h:27
struct mim::ast::AnnexInfo::@177100250272201136376142224053244231100060214216 id
plugin_t plugin_id() const
The mangled plugin part of the flags.
Definition ast.h:34