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