MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
clos.h
Go to the documentation of this file.
1#pragma once
2
3#include "mim/world.h"
4
6
7namespace mim::plug::clos {
8
9/// @name Closures
10///@{
11
12/// Wrapper around a Def that can be used to match closures (see isa_clos_lit).
13class ClosLit {
14public:
15 /// @name Getters
16 ///@{
17 const Sigma* type() {
18 assert(def_);
19 return def_->type()->isa<Sigma>();
20 }
21
22 const Def* env();
23 const Def* env_type() { return env()->type(); }
24
25 const Def* fnc();
26 const Pi* fnc_type() { return fnc()->type()->isa<Pi>(); }
27 Lam* fnc_as_lam();
28
29 const Def* env_var();
30 const Def* ret_var() { return fnc_as_lam()->ret_var(); }
31 ///@}
32
33 explicit operator bool() const { return def_ != nullptr; }
34 operator const Tuple*() { return def_; }
35
36 const Tuple* operator->() {
37 assert(def_);
38 return def_;
39 }
40
41 /// @name Properties
42 ///@{
45 attr get() { return attr_; } ///< Clos annotation. These should appear in front of the code-part.
46 ///@}
47
48private:
49 ClosLit(const Tuple* def, attr a = attr::bottom)
50 : def_(def)
51 , attr_(a) {}
52
53 const Tuple* def_;
54 const attr attr_;
55
56 friend ClosLit isa_clos_lit(const Def*, bool);
57};
58
59/// Tries to match a closure literal.
60ClosLit isa_clos_lit(const Def* def, bool fn_isa_lam = true);
61
62/// Pack a typed closure. This assumes that @p fn expects the environment as its Clos_Env_Param%th argument.
63const Def* clos_pack(const Def* env, const Def* fn, const Def* ct = nullptr);
64
65/// Deconstruct a closure into `(env_type, function, env)`.
66/// **Important**: use this or ClosLit to destruct closures, since typechecking dependent pairs is currently
67/// broken.
68std::tuple<const Def*, const Def*, const Def*> clos_unpack(const Def* c);
69
70/// Apply a closure to arguments.
71const Def* clos_apply(const Def* closure, const Def* args);
72inline const Def* apply_closure(const Def* closure, Defs args) {
73 auto& w = closure->world();
74 return clos_apply(closure, w.tuple(args));
75}
76
77// TODO: rename this
78/// Checks is def is the variable of a mut of type N.
79template<class N> std::tuple<const Extract*, N*> ca_isa_var(const Def* def) {
80 if (auto proj = def->isa<Extract>()) {
81 if (auto var = proj->tuple()->isa<Var>(); var && var->mut()->isa<N>())
82 return std::tuple(proj, var->mut()->as<N>());
83 }
84 return {nullptr, nullptr};
85}
86///@}
87
88/// @name Closure Types
89///@{
90/// Returns @p def if @p def is a closure and @c nullptr otherwise
91const Sigma* isa_clos_type(const Def* def);
92
93/// Creates a typed closure type from @p pi.
94Sigma* clos_type(const Pi* pi);
95
96/// Convert a closure type to a Pi, where the environment type has been removed or replaced by @p new_env_type
97/// (if @p new_env_type != @c nullptr)
98const Pi* clos_type_to_pi(const Def* ct, const Def* new_env_type = nullptr);
99
100///@}
101
102/// @name Closure Environment
103///@{
104/// `tup_or_sig` should generally be a Tuple, Sigma or Var.
105
106/// Describes where the environment is placed in the argument list.
107static constexpr size_t Clos_Env_Param = 1_u64;
108
109// Adjust the index of an argument to account for the env param
110inline size_t shift_env(size_t i) { return (i < Clos_Env_Param) ? i : i - 1_u64; }
111
112// Same but skip the env param
113inline size_t skip_env(size_t i) { return (i < Clos_Env_Param) ? i : i + 1_u64; }
114
115// TODO what does this do exactly?
116const Def* ctype(World& w, Defs doms, const Def* env_type = nullptr);
117
118const Def* clos_insert_env(size_t i, const Def* env, std::function<const Def*(size_t)> f);
119inline const Def* clos_insert_env(size_t i, const Def* env, const Def* a) {
120 return clos_insert_env(i, env, [&](auto i) { return a->proj(i); });
121}
122
123inline const Def* clos_insert_env(const Def* env, const Def* tup_or_sig) {
124 auto& w = tup_or_sig->world();
125 auto new_ops = DefVec(tup_or_sig->num_projs() + 1, [&](auto i) { return clos_insert_env(i, env, tup_or_sig); });
126 return (tup_or_sig->isa<Sigma>()) ? w.sigma(new_ops) : w.tuple(new_ops);
127}
128
129const Def* clos_remove_env(size_t i, std::function<const Def*(size_t)> f);
130inline const Def* clos_remove_env(size_t i, const Def* def) {
131 return clos_remove_env(i, [&](auto i) { return def->proj(i); });
132}
133inline const Def* clos_remove_env(const Def* tup_or_sig) {
134 auto& w = tup_or_sig->world();
135 auto new_ops = DefVec(tup_or_sig->num_projs() - 1, [&](auto i) { return clos_remove_env(i, tup_or_sig); });
136 return (tup_or_sig->isa<Sigma>()) ? w.sigma(new_ops) : w.tuple(new_ops);
137}
138
139inline const Def* clos_sub_env(const Def* tup_or_sig, const Def* new_env) {
140 return tup_or_sig->refine(Clos_Env_Param, new_env);
141}
142///@}
143
144} // namespace mim::plug::clos
Base class for all Defs.
Definition def.h:198
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:528
World & world() const noexcept
Definition def.cpp:413
const Def * refine(size_t i, const Def *new_op) const
Definition def.cpp:251
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Definition def.h:242
nat_t num_projs() const
Yields Def::as_lit_arity(), if it is in fact a Lit, or 1 otherwise.
Definition def.h:335
Extracts from a Sigma or Array-typed Extract::tuple the element at position Extract::index.
Definition tuple.h:155
A function.
Definition lam.h:105
const Def * ret_var()
Yields the Lam::var of the Lam::ret_pi.
Definition lam.h:151
A dependent function type.
Definition lam.h:11
static const Pi * isa_basicblock(const Def *d)
Is this a continuation (Pi::isa_cn) that is not Pi::isa_returning?
Definition lam.h:48
static const Pi * isa_returning(const Def *d)
Is this a continuation (Pi::isa_cn) which has a Pi::ret_pi?
Definition lam.h:46
A dependent tuple type.
Definition tuple.h:9
Data constructor for a Sigma.
Definition tuple.h:50
Def * mut() const
Definition def.h:627
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:33
Wrapper around a Def that can be used to match closures (see isa_clos_lit).
Definition clos.h:13
const Def * env_type()
Definition clos.h:23
const Sigma * type()
Definition clos.h:17
const Def * fnc()
Definition clos.cpp:52
const Pi * fnc_type()
Definition clos.h:26
const Def * env_var()
Definition clos.cpp:63
const Def * ret_var()
Definition clos.h:30
const Def * env()
Definition clos.cpp:47
const Tuple * operator->()
Definition clos.h:36
friend ClosLit isa_clos_lit(const Def *, bool)
Tries to match a closure literal.
Definition clos.cpp:65
attr get()
Clos annotation. These should appear in front of the code-part.
Definition clos.h:45
The clos Plugin
Definition clos.h:7
ClosLit isa_clos_lit(const Def *def, bool fn_isa_lam=true)
Tries to match a closure literal.
Definition clos.cpp:65
std::tuple< const Extract *, N * > ca_isa_var(const Def *def)
Checks is def is the variable of a mut of type N.
Definition clos.h:79
Sigma * clos_type(const Pi *pi)
Creates a typed closure type from pi.
Definition clos.cpp:122
size_t shift_env(size_t i)
Definition clos.h:110
const Def * clos_remove_env(size_t i, std::function< const Def *(size_t)> f)
Definition clos.cpp:144
const Def * clos_insert_env(size_t i, const Def *env, std::function< const Def *(size_t)> f)
Definition clos.cpp:140
const Def * ctype(World &w, Defs doms, const Def *env_type=nullptr)
Definition clos.cpp:146
static constexpr size_t Clos_Env_Param
Describes where the environment is placed in the argument list.
Definition clos.h:107
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:128
const Def * apply_closure(const Def *closure, Defs args)
Definition clos.h:72
std::tuple< const Def *, const Def *, const Def * > clos_unpack(const Def *c)
Deconstruct a closure into (env_type, function, env).
Definition clos.cpp:89
const Def * clos_sub_env(const Def *tup_or_sig, const Def *new_env)
Definition clos.h:139
size_t skip_env(size_t i)
Definition clos.h:113
const Def * clos_pack(const Def *env, const Def *fn, const Def *ct=nullptr)
Pack a typed closure. This assumes that fn expects the environment as its Clos_Env_Paramth argument.
Definition clos.cpp:79
const Def * clos_apply(const Def *closure, const Def *args)
Apply a closure to arguments.
Definition clos.cpp:101
const Sigma * isa_clos_type(const Def *def)
Definition clos.cpp:112
View< const Def * > Defs
Definition def.h:49
Vector< const Def * > DefVec
Definition def.h:50