8using namespace std::literals;
52 auto _ = e.world().push(
loc());
80 auto _ = e.world().push(
loc());
85 auto _ = e.world().push(
loc());
87 for (
size_t i = 0, n =
num_ptrns(); i != n; ++i)
99 auto _ = e.world().push(
loc());
100 return type() ?
type()->
emit(e) : e.world().mut_hole_type();
110 auto _ = e.world().push(
loc());
116 auto type = e.world().type_infer_univ();
117 sigma = e.world().mut_sigma(type, n);
119 auto var = sigma->
var();
120 auto& sym2idx = e.sigma2sym2idx[sigma];
122 for (
size_t i = 0; i != n; ++i) {
125 if (
auto id =
ptrn(i)->isa<IdPtrn>();
id && !
id->
dbg().is_anon()) sym2idx[
id->dbg().sym()] = i;
133 auto _ = e.world().push(
loc());
134 type = type ? type : e.world().type_infer_univ();
135 return e.world().mut_sigma(type,
num_ptrns());
143 auto _ = e.world().push(
loc());
148 auto _ = e.world().push(
loc());
153 auto _ = e.world().push(
loc());
162 if (
auto def =
decl()->def())
return def;
163 e.error().e(
loc(),
"`{}` is a module and not a value",
dbg().sym()).bail();
168 return e.world().type(l);
173 return e.world().reform(m);
179 case Tag::K_Univ:
return e.world().univ();
180 case Tag::K_Nat:
return e.world().type_nat();
181 case Tag::K_Idx:
return e.world().type_idx();
182 case Tag::K_Bool:
return e.world().type_bool();
183 case Tag::K_ff:
return e.world().lit_ff();
184 case Tag::K_tt:
return e.world().lit_tt();
185 case Tag::K_i1:
return e.world().lit_i1();
186 case Tag::K_i8:
return e.world().lit_i8();
187 case Tag::K_i16:
return e.world().lit_i16();
188 case Tag::K_i32:
return e.world().lit_i32();
189 case Tag::K_i64:
return e.world().lit_i64();
190 case Tag::K_I1:
return e.world().type_i1();
191 case Tag::K_I8:
return e.world().type_i8();
192 case Tag::K_I16:
return e.world().type_i16();
193 case Tag::K_I32:
return e.world().type_i32();
194 case Tag::K_I64:
return e.world().type_i64();
195 case Tag::T_star:
return e.world().type<0>();
196 case Tag::T_box:
return e.world().type<1>();
197 default: fe::unreachable();
205 auto math_f = e.world().annex(e.world().sym(
"math.F"));
206 if (
auto app = type->zonk()->isa<
App>(); math_f && app && app->
callee() == math_f) {
207 if (
auto [p, ex] = app->arg()->projs<2>([](
auto op) { return Lit::isa(op); }); p && ex) {
208 if (*p == 10 && *ex == 5)
return 16;
209 if (*p == 23 && *ex == 8)
return 32;
210 if (*p == 52 && *ex == 11)
return 64;
219 auto val = std::bit_cast<f64>(bits);
221#if defined(__STDCPP_FLOAT16_T__)
222 case 16:
return std::bit_cast<u16>(f16(val));
224 case 16: e.error().e(loc,
"16-bit floating-point literals are not supported on this platform").bail();
226 case 32:
return std::bit_cast<u32>(
f32(val));
237 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());
239 case Tag::L_u:
return t ? e.world().lit(t,
tok().lit_u()) : e.world().lit_nat(
tok().lit_u());
240 case Tag::L_i: {
auto [size, val] =
tok().
lit_i();
return e.world().lit_idx(size, val); }
241 case Tag::L_c:
return e.world().lit_i8(
tok().lit_c());
242 case Tag::L_str:
return e.world().tuple(
tok().sym());
243 case Tag::T_bot:
return t ? e.world().bot(t) : e.world().type_bot();
244 case Tag::T_top:
return t ? e.world().top(t) : e.world().type_top();
245 default: fe::unreachable();
252 for (
auto decl :
decls() | std::views::reverse)
255 for (
auto decl :
decls())
261 assert(
op().isa(Tag::T_arrow_r));
262 return pi_ = e.world().mut_pi(type,
false);
267 pi_->set_codom(
rhs()->
emit(e));
274 types.emplace_back(infix->rhs()->emit(e));
276 types.emplace_back(expr->
emit(e));
280const Def* InfixExpr::emit_index(
Emitter& e,
const Def* tup)
const {
283 if (
auto path =
rhs()->isa<PathExpr>(); path && path->path()->dbgs().size() == 1) {
284 auto dbg = path->dbg();
286 if (
auto i = e.sigma2sym2idx.find(mut); i != e.sigma2sym2idx.end()) {
287 auto sigma = i->first->as_mut<
Sigma>();
288 const auto& sym2idx = i->second;
289 if (
auto i = sym2idx.find(dbg.sym()); i != sym2idx.end())
return w.lit_idx(sigma->num_ops(), i->second);
292 if (!path->decl())
e.error().e(
dbg.loc(),
"cannot resolve field `{}` for extraction", dbg).bail();
300 switch (
op().tag()) {
304 return w.join(types);
306 case Tag::T_extract: {
308 return w.extract(tup, emit_index(e, tup));
310 case Tag::T_arrow_l: {
311 fe::Vector<const InfixExpr*> exs;
314 exs.emplace_back(ex);
321 .n(
"an update needs a component, as in `tuple#index {} value`",
Tok::tag2str(
op().tag()))
324 auto tup = base->emit(e);
326 for (
auto ex : exs | std::views::reverse) {
327 auto idx = ex->emit_index(e, tup);
328 tups.emplace_back(tup);
329 idxs.emplace_back(idx);
330 tup = w.extract(tup, idx);
334 for (
size_t i = tups.size(); i-- != 0;)
335 val = w.insert(tups[i], idxs[i], val);
345 switch (
op().tag()) {
346 case Tag::T_arrow_r:
return w.pi(l, r);
347 case Tag::T_at:
return w.app(l, r);
348 case Tag::K_inj:
return w.inj(r, l);
349 default:
return w.implicit_app(c, w.tuple({l, r}));
354 auto _ = e.world().push(
loc());
356 auto pi = e.world().pi(dom_t, e.world().mut_hole_type());
357 auto lam = e.world().mut_lam(pi);
366 res.emplace_back(
arm->
emit(e));
367 return e.world().match(res);
373 auto _ = e.world().push(
loc());
374 auto dom_t =
ptrn()->emit_type(e);
377 auto sigma = e.world().mut_sigma(2);
378 auto var = sigma->var();
379 sigma->set(0, dom_t);
380 ptrn()->emit_proj(e, var, 2, 0);
382 sigma->set(1, ret_t);
384 if (
auto imm = sigma->immutabilize())
391 ptrn()->emit_value(e,
pi_->var());
396 return dom()->decl_ = e.world().mut_pi(type, dom()->is_implicit());
403 auto cod = codom() ? codom()->emit(e) : e.world().type_bot();
404 auto pi = dom()->pi_->set_codom(cod);
405 if (
auto imm = pi->immutabilize())
return imm;
419 auto c =
callee()->emit(e);
420 auto a =
arg()->emit(e);
421 return e.world().implicit_app(c, a);
425 auto c =
callee()->emit(e);
427 auto con = e.world().mut_lam(cn);
428 auto pair = e.world().tuple({
arg()->emit(e), con});
429 auto app = e.world().app(c, pair);
430 ptrn()->emit_value(e, con->var());
436 .e(
callee()->
loc(),
"callee of a `ret` expression must be a returning continuation, but `{}` has type `{}`", c,
447 return e.world().tuple(
elems);
451 auto s =
arity()->emit_type(e);
452 if (
auto lit_s =
Lit::isa(s); lit_s && *lit_s == 0)
return e.world().unit(
is_pack());
454 if (
arity()->dbg().is_anon()) {
455 auto b =
body()->emit(e);
456 return e.world().seq(
is_pack(), s, b);
459 auto t = e.world().type_infer_univ();
460 auto a = e.world().mut_arr(t);
464 auto p = e.world().mut_pack(a);
466 arity()->emit_value(e, var);
467 auto b =
body()->emit(e);
469 auto arr_b = b->type();
470 if (
auto pvar = var->isa<
Var>())
472 arr_b =
VarRewriter(pvar, a->var()).rewrite(arr_b);
474 if (
auto imm = p->immutabilize())
return imm;
478 arity()->emit_value(e, var);
480 if (
auto imm = a->immutabilize())
return imm;
493 auto _ = e.world().push(
loc());
494 mim_type_ =
type()->emit(e);
495 auto&
id = annex_->id;
496 auto plugin = annex_->plugin_id();
500 if (curry_.lit_u() >
id.curry)
501 e.error().e(curry_.loc(),
"curry counter cannot be greater than {}",
id.curry).bail();
503 id.curry = curry_.lit_u();
507 if (trip_.lit_u() >
id.curry)
508 e.error().e(trip_.loc(),
"trip counter cannot be greater than curry counter {}", (
int)
id.curry).bail();
510 id.trip = trip_.lit_u();
513 auto norm = e.driver().normalizer(plugin,
id.tag, sub_);
514 auto name = annex_->qualified(e.driver(),
dbg().sym());
515 auto axm = e.world().axm(norm,
id.
curry,
id.
trip, mim_type_, plugin,
id.tag, sub_)->set(name);
517 e.world().annexes().attach(plugin,
id.tag, sub_, name, axm);
522 auto&
id = annex_->id;
523 auto plugin = annex_->plugin_id();
524 auto norm = e.driver().normalizer(plugin,
id.tag, sub_);
525 auto name = annex_->qualified(e.driver(),
dbg().sym());
528 e.world().annexes().attach(plugin,
id.tag, sub_, name, axm);
533 auto target =
path()->decl();
534 def_ = target->def();
535 auto name = annex_->qualified(e.driver(),
dbg().sym());
536 e.world().annexes().attach_alias(annex_->plugin_id(), annex_->id.tag, sub_, name);
540 for (
auto decl :
decls())
547 auto _ = e.world().push(
loc());
548 auto v =
value()->emit(e);
550 if (
auto id =
ptrn()->isa<IdPtrn>()) e.attach(id->annex_, id->sub_, id->dbg().sym(),
def_);
554 for (
auto curr =
this; curr; curr = curr->next())
556 for (
auto curr =
this; curr; curr = curr->next())
561 auto _ = e.world().push(
loc());
562 def_ =
body()->emit_decl(e, e.world().type_infer_univ());
567 auto _ = e.world().push(
loc());
570 e.attach(annex_, sub_,
dbg().sym(),
def_);
575 lam_ = e.world().mut_lam(
pi_);
576 auto _ = e.world().push(
loc());
577 auto var = lam_->var();
580 ptrn()->emit_proj(e, var, 2, 0);
581 ret()->emit_proj(e, var, 2, 1);
583 ptrn()->emit_value(e, var);
590 auto _ = e.world().push(
loc());
591 bool is_cps = !
ISA(tag_,
C_DS);
594 for (
size_t i = 0, n =
num_doms(); i != n; ++i) {
595 for (
auto dom :
doms() | std::views::drop(i))
598 auto cod =
codom() ?
codom()->emit(e) : is_cps ? e.world().type_bot() : e.world().mut_hole_type();
599 for (
auto dom :
doms() | std::views::drop(i) | std::views::reverse)
600 cod =
dom->pi_->set_codom(cod);
603 auto lam = cur->emit_value(e);
604 if (
auto filter = cur->filter()) {
605 auto _filter = e.world().push(filter->loc());
606 lam->set_filter(filter->emit(e));
608 lam->set_filter(i + 1 == n && is_cps ? e.world().lit_ff() : e.world().lit_tt());
614 dom(i - 1)->lam_->set_body(lam);
621 auto _ = e.world().push(
loc());
623 auto _body = e.world().push(
body()->
loc());
628 for (
size_t i = 0, n =
num_doms(); i != n; ++i) {
630 auto lam =
dom(i)->lam_;
631 auto pi = lam->type()->as_mut<
Pi>();
632 for (
auto dom :
doms() | std::views::drop(i)) {
633 if (
auto var = pi->has_var()) rw.add(
dom->lam_->var()->as<
Var>(), var);
634 auto cod = pi->codom();
635 if (!cod || !cod->isa_mut<
Pi>())
break;
636 pi = cod->as_mut<
Pi>();
639 if (
auto cod = pi->codom(); cod && cod->has_dep(
Dep::Hole)) pi->
set(pi->dom(), rw.rewrite(cod));
642 for (
auto dom :
doms() | std::views::reverse) {
643 if (
auto imm =
dom->pi_->immutabilize()) {
644 auto f =
dom->lam_->filter();
645 auto b =
dom->lam_->body();
646 dom->lam_->unset()->set_type(imm)->as<
Lam>()->set(f, b);
651 auto lam =
doms().front()->lam_;
652 if (!lam->is_closed())
655 "external function `{}` is not closed: its inferred type escapes into the scope of `{}`. This "
656 "usually means an unannotated parameter's type could only be inferred to depend on a variable bound "
657 "in an inner/sibling scope; add an explicit type annotation to the offending parameter.",
658 dbg().sym(), lam->free_vars().min()->binder()->sym())
662 e.attach(annex_, sub_,
dbg().sym(),
def_);
666 auto _ = e.world().push(
loc());
667 auto meta_t = e.world().reform(
var()->emit_type(e));
668 auto rule = e.world().mut_rule(meta_t)->set(
dbg());
669 var()->emit_value(e, rule->var());
670 auto l =
lhs()->emit(e);
671 auto r =
rhs()->emit(e);
672 auto g =
guard()->emit(e);
const Def * callee() const
static std::pair< u8, u8 > infer_curry_and_trip(const Def *type)
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.
Def * set(size_t i, const Def *)
Successively set from left to right.
T * as_mut() const
Asserts that this is a mutable, casts constness away and performs a static_cast to T.
T * isa_mut() const
If this is mutable, it will cast constness away and perform a dynamic_cast to T.
const Def * var(nat_t a, nat_t i) noexcept
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
const Def * immutabilize()
Some "global" variables needed all over the place.
static std::optional< T > isa(const Def *def)
A dependent function type.
static const Pi * has_ret_pi(const Def *d)
Yields the Pi::ret_pi() of d, if it is in fact a Pi.
Pi * set(const Def *dom, const Def *codom)
Sigma * set(size_t i, const Def *def)
VarRewriter(World &world)
A variable introduced by a binder (mutable).
const Def * attach(flags_t, Sym, const Def *)
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.
void emit(Emitter &) const override
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
const Path * path() const
const Def * emit_value(Emitter &, const Def *) const override
const Def * emit_type(Emitter &) const override
const Ptrn * ptrn() const
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
const Def * emit_(Emitter &) const override
const Expr * callee() const
const AxmDecl * owner() const
void emit(Emitter &) const override
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
void emit(Emitter &) const override
const Expr * type() const
const Def * mim_type() const
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
const Expr * expr() const
const Def * emit_(Emitter &) const override
virtual Dbg dbg() const
The name this Decl introduces; anonymous if it has none.
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...
absl::node_hash_map< Sigma *, fe::SymMap< size_t >, GIDHash< const Def * > > sigma2sym2idx
const Def * emit_(Emitter &) const override
const Def * emit_type(Emitter &) const override
const Def * emit_value(Emitter &, const Def *) const override
Base class of all expressions.
const Def * emit(Emitter &) const
const Def * emit_decl(Emitter &, const Def *type) const
virtual const Def * emit_decl_(Emitter &, const Def *) const
virtual const Def * emit_(Emitter &) const =0
void emit_body(Emitter &, const Def *decl) const
virtual void emit_body_(Emitter &, const Def *) const
auto implicit_imports() const
Imports the driver was told about via -p; they precede everything the file itself declares.
const Def * emit_type(Emitter &) const override
const Def * emit_value(Emitter &, const Def *) const override
const IdPtrn * id() const
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
const Def * emit_(Emitter &) const override
const Def * emit_type(Emitter &) const override
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
const Def * emit_value(Emitter &, const Def *) const override
const Expr * type() const
void emit_body_(Emitter &, const Def *decl) const override
static const InfixExpr * isa_op(Tok::Tag tag, const Expr *expr)
const Expr * callee() const
const Def * emit_(Emitter &) const override
const Def * emit_decl_(Emitter &, const Def *type) const override
Lam * emit_value(Emitter &) const
bool is_external() const
extern without a body is a forward declaration whose implementation lives in a native translation uni...
const Expr * codom() const
void emit_decl(Emitter &) const override
void emit_body(Emitter &) const override
const Dom * dom(size_t i) const
void emit_body_(Emitter &, const Def *decl) const override
const Def * emit_(Emitter &) const override
const LamDecl * lam() const
const Def * emit_decl_(Emitter &, const Def *type) const override
const Expr * value() const
const Ptrn * ptrn() const
void emit(Emitter &) const override
const Expr * type() const
const Def * emit_(Emitter &) const override
Lam * emit(Emitter &) const
const Expr * body() const
const Ptrn * ptrn() const
const Def * emit_(Emitter &) const override
const Expr * scrutinee() const
const Arm * arm(size_t i) const
void emit_decls(Emitter &) const
void emit(Emitter &) const override
const Def * emit_(Emitter &) const override
const Decl * decl() const
virtual void emit_type(Emitter &) const
const IdPtrn * ret() const
const Ptrn * ptrn() const
const Def * emit_(Emitter &) const override
const Def * emit_decl_(Emitter &, const Def *type) const override
void emit_body_(Emitter &, const Def *decl) const override
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...
virtual const Def * emit_type(Emitter &) const =0
void emit(Emitter &) const override
virtual void emit_body(Emitter &) const
virtual void emit_decl(Emitter &) const
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
const Expr * body() const
const Ptrn * ptrn() const
const Def * emit_(Emitter &) const override
const Expr * body() const
const Expr * callee() const
const Expr * guard() const
void emit(Emitter &) const override
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
const Def * emit_(Emitter &) const override
const Expr * body() const
const IdPtrn * arity() const
const Def * emit_(Emitter &) const override
const TuplePtrn * ptrn() const
const Def * emit_decl_(Emitter &, const Def *type) const override
void emit_body_(Emitter &, const Def *decl) const override
const Def * emit_(Emitter &) const override
std::pair< uint64_t, uint64_t > lit_i() const
static const char * tag2str(Tok::Tag)
const Expr * elem(size_t i) const
const Def * emit_(Emitter &) const override
const Ptrn * ptrn(size_t i) const
const Def * emit_type(Emitter &) const override
const Def * emit_decl(Emitter &, const Def *type) const
const Def * emit_value(Emitter &, const Def *) const override
const Def * emit_body(Emitter &, const Def *decl) const
const Def * emit_(Emitter &) const override
const Expr * level() const
const Expr * inhabitant() const
const Def * emit_(Emitter &) const override
void emit(Emitter &) const override
const File * file() const
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.
#define ISA(tag, family)
Turns such a family into a predicate - a case label is of no use outside of a switch.
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.
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.
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.
fe::Vector< const Def * > DefVec
Bookkeeping of an annex introduced by an AxmDecl.
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...
struct mim::ast::AnnexInfo::@177100250272201136376142224053244231100060214216 id
plugin_t plugin_id() const
The mangled plugin part of the flags.