MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
tuple.h
Go to the documentation of this file.
1#pragma once
2
3#include "mim/def.h"
4
5namespace mim {
6
7/// A [dependent tuple type](https://en.wikipedia.org/wiki/Dependent_type#%CE%A3_type).
8/// @see Tuple, Arr, Pack
9class Sigma : public Def, public Setters<Sigma> {
10private:
11 Sigma(const Def* type, Defs ops)
12 : Def(Node, type, ops, 0) {} ///< Constructor for an *immutable* Sigma.
13 Sigma(const Def* type, size_t size)
14 : Def(Node, type, size, 0) {} ///< Constructor for a *mutable* Sigma.
15
16public:
17 /// @name Setters
18 /// @see @ref set_ops "Setting Ops"
19 ///@{
20 using Setters<Sigma>::set;
21 Sigma* set(size_t i, const Def* def) { return Def::set(i, def)->as<Sigma>(); }
22 Sigma* set(Defs ops) { return Def::set(ops)->as<Sigma>(); }
23 Sigma* unset() { return Def::unset()->as<Sigma>(); }
24 ///@}
25
26 /// @name Rebuild
27 ///@{
28 const Def* immutabilize() override;
29 Sigma* stub(const Def* type) { return stub_(world(), type)->set(dbg()); }
30 ///@}
31
32 /// @name Type Checking
33 ///@{
34 const Def* check(size_t, const Def*) override;
35 const Def* check() override;
36 static const Def* infer(World&, Defs);
37 ///@}
38
39 static constexpr auto Node = mim::Node::Sigma;
40
41private:
42 const Def* rebuild_(World&, const Def*, Defs) const override;
43 Sigma* stub_(World&, const Def*) override;
44
45 friend class World;
46};
47
48/// Data constructor for a Sigma.
49/// @see Sigma, Arr, Pack
50class Tuple : public Def, public Setters<Tuple> {
51public:
52 using Setters<Tuple>::set;
53 static const Def* infer(World&, Defs);
54 static constexpr auto Node = mim::Node::Tuple;
55
56private:
57 Tuple(const Def* type, Defs args)
58 : Def(Node, type, args, 0) {}
59
60 const Def* rebuild_(World&, const Def*, Defs) const override;
61
62 friend class World;
63};
64
65/// A (possibly paramterized) Arr%ay.
66/// Arr%ays are usually homogenous but they can be *inhomogenous* as well: `«i: N; T#i»`
67/// @see Sigma, Tuple, Pack
68class Arr : public Def, public Setters<Arr> {
69private:
70 Arr(const Def* type, const Def* shape, const Def* body)
71 : Def(Node, type, {shape, body}, 0) {} ///< Constructor for an *immutable* Arr.
72 Arr(const Def* type)
73 : Def(Node, type, 2, 0) {} ///< Constructor for a *mut*able Arr.
74
75public:
76 /// @name ops
77 ///@{
78 const Def* shape() const { return op(0); }
79 const Def* body() const { return op(1); }
80 ///@}
81
82 /// @name Setters
83 /// @see @ref set_ops "Setting Ops"
84 ///@{
85 using Setters<Arr>::set;
86 Arr* set_shape(const Def* shape) { return Def::set(0, shape)->as<Arr>(); }
87 Arr* set_body(const Def* body) { return Def::set(1, body)->as<Arr>(); }
88 Arr* unset() { return Def::unset()->as<Arr>(); }
89 ///@}
90
91 /// @name Rebuild
92 ///@{
93 const Def* reduce(const Def* arg) const { return Def::reduce(1, arg); }
94 Arr* stub(const Def* type) { return stub_(world(), type)->set(dbg()); }
95 const Def* immutabilize() override;
96 ///@}
97
98 /// @name Type Checking
99 ///@{
100 const Def* check(size_t, const Def*) override;
101 const Def* check() override;
102 ///@}
103
104 static constexpr auto Node = mim::Node::Arr;
105
106private:
107 const Def* rebuild_(World&, const Def*, Defs) const override;
108 Arr* stub_(World&, const Def*) override;
109
110 friend class World;
111};
112
113/// A (possibly paramterized) Tuple.
114/// @see Sigma, Tuple, Arr
115class Pack : public Def, public Setters<Pack> {
116private:
117 Pack(const Def* type, const Def* body)
118 : Def(Node, type, {body}, 0) {} ///< Constructor for an *immutable* Pack.
119 Pack(const Def* type)
120 : Def(Node, type, 1, 0) {} ///< Constructor for a *mut*ablel Pack.
121
122public:
123 /// @name ops
124 ///@{
125 const Def* body() const { return op(0); }
126 const Def* shape() const;
127 ///@}
128
129 /// @name Setters
130 /// @see @ref set_ops "Setting Ops"
131 ///@{
132 using Setters<Pack>::set;
133 Pack* set(const Def* body) { return Def::set(0, body)->as<Pack>(); }
134 Pack* reset(const Def* body) { return unset()->set(body); }
135 Pack* unset() { return Def::unset()->as<Pack>(); }
136 ///@}
137
138 /// @name Rebuild
139 ///@{
140 const Def* reduce(const Def* arg) const { return Def::reduce(0, arg); }
141 Pack* stub(const Def* type) { return stub_(world(), type)->set(dbg()); }
142 const Def* immutabilize() override;
143 ///@}
144
145 static constexpr auto Node = mim::Node::Pack;
146
147private:
148 const Def* rebuild_(World&, const Def*, Defs) const override;
149 Pack* stub_(World&, const Def*) override;
150
151 friend class World;
152};
153
154/// Extracts from a Sigma or Arr%ay-typed Extract::tuple the element at position Extract::index.
155class Extract : public Def, public Setters<Extract> {
156private:
157 Extract(const Def* type, const Def* tuple, const Def* index)
158 : Def(Node, type, {tuple, index}, 0) {}
159
160public:
161 using Setters<Extract>::set;
162
163 /// @name ops
164 ///@{
165 const Def* tuple() const { return op(0); }
166 const Def* index() const { return op(1); }
167 ///@}
168
169 static constexpr auto Node = mim::Node::Extract;
170
171private:
172 const Def* rebuild_(World&, const Def*, Defs) const override;
173
174 friend class World;
175};
176
177/// Creates a new Tuple / Pack by inserting Insert::value at position Insert::index into Insert::tuple.
178/// @attention This is a *functional* Insert.
179/// The Insert::tuple itself remains untouched.
180/// The Insert itself is a *new* Tuple / Pack which contains the inserted Insert::value.
181class Insert : public Def, public Setters<Insert> {
182private:
183 Insert(const Def* tuple, const Def* index, const Def* value)
184 : Def(Node, tuple->type(), {tuple, index, value}, 0) {}
185
186public:
187 using Setters<Insert>::set;
188
189 /// @name ops
190 ///@{
191 const Def* tuple() const { return op(0); }
192 const Def* index() const { return op(1); }
193 const Def* value() const { return op(2); }
194 ///@}
195
196 static constexpr auto Node = mim::Node::Insert;
197
198private:
199 const Def* rebuild_(World&, const Def*, Defs) const override;
200
201 friend class World;
202};
203
204/// @name Helpers to work with Tulpes/Sigmas/Arrays/Packs
205///@{
206bool is_unit(const Def*);
207std::string tuple2str(const Def*);
208
209/// Flattens a sigma/array/pack/tuple.
210const Def* flatten(const Def* def);
211/// Same as unflatten, but uses the operands of a flattened Pack / Tuple directly.
212size_t flatten(DefVec& ops, const Def* def, bool flatten_sigmas = true);
213
214/// Applies the reverse transformation on a Pack / Tuple, given the original type.
215const Def* unflatten(const Def* def, const Def* type);
216/// Same as unflatten, but uses the operands of a flattened Pack / Tuple directly.
217const Def* unflatten(Defs ops, const Def* type, bool flatten_muts = true);
218
220DefVec merge(const Def* def, Defs defs);
221const Def* merge_sigma(const Def* def, Defs defs);
222const Def* merge_tuple(const Def* def, Defs defs);
223
224const Def* tuple_of_types(const Def* t);
225///@}
226
227} // namespace mim
A (possibly paramterized) Array.
Definition tuple.h:68
const Def * immutabilize() override
Tries to make an immutable from a mutable.
Definition def.cpp:203
const Def * body() const
Definition tuple.h:79
static constexpr auto Node
Definition tuple.h:104
Arr * unset()
Definition tuple.h:88
const Def * rebuild_(World &, const Def *, Defs) const override
Definition def.cpp:117
Arr * set_body(const Def *body)
Definition tuple.h:87
Arr * set_shape(const Def *shape)
Definition tuple.h:86
friend class World
Definition tuple.h:110
const Def * shape() const
Definition tuple.h:78
const Def * check() override
Definition check.cpp:254
Arr * stub_(World &, const Def *) override
Definition def.cpp:149
const Def * reduce(const Def *arg) const
Definition tuple.h:93
Arr * stub(const Def *type)
Definition tuple.h:94
Base class for all Defs.
Definition def.h:198
Def * set(size_t i, const Def *)
Successively set from left to right.
Definition def.cpp:266
World & world() const noexcept
Definition def.cpp:413
constexpr auto ops() const noexcept
Definition def.h:261
const Def * op(size_t i) const noexcept
Definition def.h:264
DefVec reduce(const Def *arg) const
Rewrites Def::ops by substituting this mutable's Var with arg.
Definition def.cpp:227
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Definition def.h:242
Def * unset()
Unsets all Def::ops; works even, if not set at all or partially.
Definition def.cpp:282
Dbg dbg() const
Definition def.h:449
const Def * rebuild_(World &, const Def *, Defs) const override
Definition def.cpp:118
const Def * tuple() const
Definition tuple.h:165
friend class World
Definition tuple.h:174
static constexpr auto Node
Definition tuple.h:169
const Def * index() const
Definition tuple.h:166
const Def * rebuild_(World &, const Def *, Defs) const override
Definition def.cpp:119
static constexpr auto Node
Definition tuple.h:196
const Def * tuple() const
Definition tuple.h:191
friend class World
Definition tuple.h:201
const Def * index() const
Definition tuple.h:192
const Def * value() const
Definition tuple.h:193
A (possibly paramterized) Tuple.
Definition tuple.h:115
const Def * body() const
Definition tuple.h:125
Pack * reset(const Def *body)
Definition tuple.h:134
const Def * rebuild_(World &, const Def *, Defs) const override
Definition def.cpp:122
Pack * unset()
Definition tuple.h:135
const Def * shape() const
Definition tuple.cpp:40
friend class World
Definition tuple.h:151
const Def * reduce(const Def *arg) const
Definition tuple.h:140
const Def * immutabilize() override
Tries to make an immutable from a mutable.
Definition def.cpp:213
static constexpr auto Node
Definition tuple.h:145
Pack * set(const Def *body)
Definition tuple.h:133
Pack * stub_(World &, const Def *) override
Definition def.cpp:153
Pack * stub(const Def *type)
Definition tuple.h:141
CRTP-based Mixin to declare setters for Def::loc & Def::name using a covariant return type.
Definition def.h:143
Sigma * unset()
Definition tuple.h:23
const Def * immutabilize() override
Tries to make an immutable from a mutable.
Definition def.cpp:198
Sigma * stub(const Def *type)
Definition tuple.h:29
Sigma * set(Defs ops)
Definition tuple.h:22
friend class World
Definition tuple.h:45
const Def * rebuild_(World &, const Def *, Defs) const override
Definition def.cpp:126
Sigma * stub_(World &, const Def *) override
Definition def.cpp:155
static const Def * infer(World &, Defs)
Definition check.cpp:267
const Def * check() override
Definition check.cpp:275
static constexpr auto Node
Definition tuple.h:39
Sigma * set(size_t i, const Def *def)
Definition tuple.h:21
friend class World
Definition tuple.h:62
static const Def * infer(World &, Defs)
Definition check.cpp:261
const Def * rebuild_(World &, const Def *, Defs) const override
Definition def.cpp:130
static constexpr auto Node
Definition tuple.h:54
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:33
Definition ast.h:14
View< const Def * > Defs
Definition def.h:49
const Def * flatten(const Def *def)
Flattens a sigma/array/pack/tuple.
Definition tuple.cpp:66
Vector< const Def * > DefVec
Definition def.h:50
bool is_unit(const Def *)
Definition tuple.cpp:46
const Def * merge_sigma(const Def *def, Defs defs)
Definition tuple.cpp:93
std::string tuple2str(const Def *)
Definition tuple.cpp:48
DefVec merge(Defs, Defs)
Definition tuple.cpp:86
const Def * unflatten(const Def *def, const Def *type)
Applies the reverse transformation on a Pack / Tuple, given the original type.
Definition tuple.cpp:80
const Def * tuple_of_types(const Def *t)
Definition tuple.cpp:109
const Def * merge_tuple(const Def *def, Defs defs)
Definition tuple.cpp:98
@ Arr
Definition def.h:85
@ Pack
Definition def.h:85
@ Sigma
Definition def.h:85
@ Extract
Definition def.h:85
@ Insert
Definition def.h:85
@ Tuple
Definition def.h:85