MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
clos.cpp
Go to the documentation of this file.
2
3#include <mim/config.h>
4#include <mim/phase.h>
5
12
13using namespace mim;
14using namespace mim::plug;
15
26
28
29namespace mim::plug::clos {
30
31/*
32 * ClosLit
33 */
34
35const Def* ClosLit::env() const { return std::get<2>(clos_unpack(def_)); }
36
37const Def* ClosLit::fnc() const { return std::get<1>(clos_unpack(def_)); }
38
40 auto f = fnc();
41 if (auto a = Axm::isa<attr>(f)) f = a->arg();
42 return f->isa_mut<Lam>();
43}
44
45const Def* ClosLit::env_var() const {
46 auto lam = fnc_as_lam();
47 return lam->var(env_param(lam->type()->as<Pi>()));
48}
49
50ClosLit isa_clos_lit(const Def* def, bool fn_isa_lam) {
51 if (auto tpl = def->isa<Tuple>(); tpl && isa_clos_type(def->type())) {
52 auto fnc = std::get<1>(clos_unpack(tpl));
53 if (auto fa = Axm::isa<attr>(fnc)) fnc = fa->arg();
54 if (!fn_isa_lam || fnc->isa<Lam>()) return ClosLit(tpl);
55 }
56 return ClosLit(nullptr);
57}
58
59const Def* clos_pack(const Def* env, const Def* fn, const Def* ct) {
60 assert(env && fn);
61 assert(!ct || isa_clos_type(ct));
62 auto& w = env->world();
63 auto pi = fn->type()->as<Pi>();
64 auto ep = env_param(pi);
65 assert(env->type() == pi->dom(ep));
66 ct = ct ? ct : clos_type(w.cn(clos_remove_env(ep, pi->dom())));
67 return w.tuple(ct, {env->type(), fn, env})->as<Tuple>();
68}
69
70std::tuple<const Def*, const Def*, const Def*> clos_unpack(const Def* c) {
71 assert(c && isa_clos_type(c->type()));
72 auto [env_type, fn, env] = c->projs<3>();
73 return {env_type, fn, env};
74}
75
76const Def* clos_apply(const Def* closure, const Def* args) {
77 auto& w = closure->world();
78 auto [_, fn, env] = clos_unpack(closure);
79 auto pi = fn->type()->as<Pi>();
80 auto ep = env_param(pi);
81 return w.app(fn, DefVec(pi->num_doms(), [&](auto i) { return clos_insert_env(ep, i, env, args); }));
82}
83
84/*
85 * closure types
86 */
87
88const Sigma* isa_clos_type(const Def* def) {
89 auto& w = def->world();
90 auto sig = def->isa_mut<Sigma>();
91 if (!sig || sig->num_ops() < 3 || sig->op(0_u64) != w.type()) return nullptr;
92 auto var = sig->var(0_u64);
93 if (sig->op(2_u64) != var) return nullptr;
94 auto pi = sig->op(1_u64)->isa<Pi>();
95 if (!pi || !Pi::isa_cn(pi) || pi->num_ops() <= 1_u64) return nullptr;
96 return (pi->dom(env_param(pi)) == var) ? sig : nullptr;
97}
98
99Sigma* clos_type(const Pi* pi) {
100 auto& w = pi->world();
101 auto doms = pi->doms();
102 return ctype(w, doms, nullptr)->as_mut<Sigma>();
103}
104
105const Pi* clos_type_to_pi(const Def* ct, const Def* new_env_type) {
106 assert(isa_clos_type(ct));
107 auto& w = ct->world();
108 auto pi = ct->op(1_u64)->as<Pi>();
109 auto ep = env_param(pi);
110 auto new_dom = new_env_type ? clos_sub_env(ep, pi->dom(), new_env_type) : clos_remove_env(ep, pi->dom());
111 return w.cn(new_dom);
112}
113
114/*
115 * closure environments
116 */
117
118const Def* clos_insert_env(size_t ep, size_t i, const Def* env, std::function<const Def*(size_t)> f) {
119 return (i == ep) ? env : f(shift_env(ep, i));
120}
121
122const Def* clos_remove_env(size_t ep, size_t i, std::function<const Def*(size_t)> f) { return f(skip_env(ep, i)); }
123
124const Def* ctype(World& w, Defs doms, const Def* env_type) {
125 auto ep = env_param(doms);
126 if (!env_type) {
127 auto sigma = w.mut_sigma(w.type(), 3_u64)->set("Clos");
128 sigma->set(0_u64, w.type());
129 sigma->set(1_u64, ctype(w, doms, sigma->var(0_u64)));
130 sigma->set(2_u64, sigma->var(0_u64));
131 return sigma;
132 }
133 return w.cn(DefVec(doms.size() + 1,
134 [&](auto i) { return clos_insert_env(ep, i, env_type, [&](auto j) { return doms[j]; }); }));
135}
136
137} // namespace mim::plug::clos
void reg_phases(Flags2Phases &phases)
Definition affine.cpp:12
static auto isa(const Def *def)
Definition axm.h:107
Base class for all Defs.
Definition def.h:261
T * as_mut() const
Asserts that this is a mutable, casts constness away and performs a static_cast to T.
Definition def.h:536
World & world() const noexcept
Definition def.cpp:483
T * isa_mut() const
If this is mutable, it will cast constness away and perform a dynamic_cast to T.
Definition def.h:527
const Def * op(size_t i) const noexcept
Definition def.h:320
const Def * var(nat_t a, nat_t i) noexcept
Definition def.h:441
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Definition def.cpp:491
A function.
Definition lam.h:110
static void hook(Flags2Phases &phases)
Definition phase.h:70
A dependent function type.
Definition lam.h:14
static const Pi * isa_cn(const Def *d)
Is this a continuation - i.e. is the Pi::codom mim::Bottom?
Definition lam.h:47
const Def * dom() const
Definition lam.h:35
A dependent tuple type.
Definition tuple.h:22
Data constructor for a Sigma.
Definition tuple.h:70
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:36
const Def * fnc() const
Definition clos.cpp:37
Lam * fnc_as_lam() const
Definition clos.cpp:39
const Def * env_var() const
Definition clos.cpp:45
const Def * env() const
Definition clos.cpp:35
void reg_phases(Flags2Phases &phases)
Definition clos.cpp:16
#define MIM_EXPORT
Definition config.h:19
The clos Plugin
Definition clos.h:8
ClosLit isa_clos_lit(const Def *def, bool fn_isa_lam=true)
Tries to match a closure literal.
Definition clos.cpp:50
void register_normalizers(Normalizers &normalizers)
const Def * clos_sub_env(size_t ep, const Def *tup_or_sig, const Def *new_env)
Definition clos.h:135
const Def * clos_remove_env(size_t ep, size_t i, std::function< const Def *(size_t)> f)
Definition clos.cpp:122
Sigma * clos_type(const Pi *pi)
Creates a typed closure type from pi.
Definition clos.cpp:99
size_t shift_env(size_t ep, size_t i)
Adjust the index of an argument to account for the env param.
Definition clos.h:104
const Def * ctype(World &w, Defs doms, const Def *env_type=nullptr)
Builds a closure type from the domains doms of a Cn.
Definition clos.cpp:124
const Def * clos_insert_env(size_t ep, size_t i, const Def *env, std::function< const Def *(size_t)> f)
Definition clos.cpp:118
const Pi * clos_type_to_pi(const Def *ct, const Def *new_env_type=nullptr)
Convert a closure type to a Pi, where the environment type has been removed or replaced by new_env_ty...
Definition clos.cpp:105
std::tuple< const Def *, const Def *, const Def * > clos_unpack(const Def *c)
Deconstruct a closure into (env_type, function, env).
Definition clos.cpp:70
size_t skip_env(size_t ep, size_t i)
Same as shift_env, but skips the env param instead.
Definition clos.h:107
const Def * clos_pack(const Def *env, const Def *fn, const Def *ct=nullptr)
Pack a typed closure.
Definition clos.cpp:59
const Def * clos_apply(const Def *closure, const Def *args)
Apply a closure to arguments.
Definition clos.cpp:76
const Sigma * isa_clos_type(const Def *def)
Definition clos.cpp:88
size_t env_param(Defs doms)
Describes where the environment is placed in the argument list: right after a leading mem....
Definition clos.h:100
Definition ast.h:14
View< const Def * > Defs
Definition def.h:78
Vector< const Def * > DefVec
Definition def.h:79
absl::flat_hash_map< flags_t, std::function< std::unique_ptr< Phase >(World &)> > Flags2Phases
Maps an axiom of a Phase to a function that creates one.
Definition plugin.h:25
mim::Plugin mim_get_plugin()
#define MIM_VERSION
Definition plugin.h:54
Basic info and registration function pointer to be returned from a specific plugin.
Definition plugin.h:59