MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
world.h
Go to the documentation of this file.
1#pragma once
2
3#include <memory>
4#include <string>
5#include <string_view>
6#include <type_traits>
7
8#include <absl/container/btree_map.h>
9#include <fe/arena.h>
10
11#include "mim/axm.h"
12#include "mim/rewrite.h"
13
14#include "mim/util/dbg.h"
15#include "mim/util/log.h"
16
17namespace mim {
18
19class Driver;
20struct Flags;
21
22/// The World represents the whole program and manages creation of MimIR nodes (Def%s).
23/// Def%s are hashed into an internal HashSet.
24/// The World's factory methods just calculate a hash and lookup the Def, if it is already present, or create a new one
25/// otherwise. This corresponds to value numbering.
26///
27/// You can create several worlds.
28/// All worlds are completely independent from each other.
29///
30/// Note that types are also just Def%s and will be hashed as well.
31class World {
32public:
33 /// @name State
34 ///@{
35 struct State {
36 State() = default;
37
38 /// [Plain Old Data](https://en.cppreference.com/w/cpp/named_req/PODType)
39 struct POD {
42 Loc loc;
43 Sym name;
44 mutable bool frozen = false;
45 } pod;
46
47#ifdef MIM_ENABLE_CHECKS
48 absl::flat_hash_set<uint32_t> breakpoints;
49 absl::flat_hash_set<uint32_t> watchpoints;
50#endif
51 friend void swap(State& s1, State& s2) noexcept {
52 using std::swap;
53 assert((!s1.pod.loc || !s2.pod.loc) && "Why is get_loc() still set?");
54 swap(s1.pod, s2.pod);
55#ifdef MIM_ENABLE_CHECKS
56 swap(s1.breakpoints, s2.breakpoints);
57 swap(s1.watchpoints, s2.watchpoints);
58#endif
59 }
60 };
61
62 /// @name Construction & Destruction
63 ///@{
64 World& operator=(World) = delete;
65
66 explicit World(Driver*);
67 World(Driver*, const State&);
68 World(World&& other) noexcept
69 : World(&other.driver(), other.state()) {
70 swap(*this, other);
71 }
72 ~World();
73
74 /// Inherits the State into the new World.
75 /// World::curr_gid will be offset to not collide with the original World.
76 std::unique_ptr<World> inherit() {
77 auto s = state();
78 s.pod.curr_gid += move_.defs.size();
79 return std::make_unique<World>(&driver(), s);
80 }
81 ///@}
82
83 /// @name Getters/Setters
84 ///@{
85 const State& state() const { return state_; }
86 const Driver& driver() const { return *driver_; }
87 Driver& driver() { return *driver_; }
88 Zonker& zonker() { return zonker_; }
89
90 Sym name() const { return state_.pod.name; }
91 void set(Sym name) { state_.pod.name = name; }
92 void set(std::string_view name) { state_.pod.name = sym(name); }
93
94 /// Manage global identifier - a unique number for each Def.
95 u32 curr_gid() const { return state_.pod.curr_gid; }
96 u32 next_gid() { return ++state_.pod.curr_gid; }
97
98 /// Manage run - used to track fixed-point iterations to compute Def::free_vars
99 u32 curr_run() const { return data_.curr_run; }
100 u32 next_run() { return ++data_.curr_run; }
101
102 /// Retrieve compile Flags.
103 Flags& flags();
104 ///@}
105
106 /// @name Loc
107 ///@{
108 struct ScopedLoc {
109 ScopedLoc(World& world, Loc old_loc)
110 : world_(world)
111 , old_loc_(old_loc) {}
112 ~ScopedLoc() { world_.set_loc(old_loc_); }
113
114 private:
115 World& world_;
116 Loc old_loc_;
117 };
118
119 Loc get_loc() const { return state_.pod.loc; }
120 void set_loc(Loc loc = {}) { state_.pod.loc = loc; }
121 ScopedLoc push(Loc loc) {
122 auto sl = ScopedLoc(*this, get_loc());
123 set_loc(loc);
124 return sl;
125 }
126 ///@}
127
128 /// @name Sym
129 ///@{
130 Sym sym(std::string_view);
131 Sym sym(const char*);
132 Sym sym(const std::string&);
133 /// Appends a @p suffix or an increasing number if the suffix already exists.
134 Sym append_suffix(Sym name, std::string suffix);
135 ///@}
136
137 /// @name Freeze
138 /// In frozen state the World does not create any nodes.
139 ///@{
140 bool is_frozen() const { return state_.pod.frozen; }
141
142 /// Yields old frozen state.
143 bool freeze(bool on = true) const {
144 bool old = state_.pod.frozen;
145 state_.pod.frozen = on;
146 return old;
147 }
148
149 /// Use to World::freeze and automatically unfreeze at the end of scope.
150 struct Freezer {
152 : world(world)
153 , old(world.freeze(true)) {}
154 ~Freezer() { world.freeze(old); }
155
156 const World& world;
157 bool old;
158 };
159 ///@}
160
161 /// @name Debugging Features
162 ///@{
163#ifdef MIM_ENABLE_CHECKS
164 const auto& breakpoints() { return state_.breakpoints; }
165 const auto& watchpoints() { return state_.watchpoints; }
166
167 const Def* gid2def(u32 gid); ///< Lookup Def by @p gid.
168 void breakpoint(u32 gid); ///< Trigger breakpoint in your debugger when creating a Def with this @p gid.
169 void watchpoint(u32 gid); ///< Trigger breakpoint in your debugger when Def::set%ting a Def with this @p gid.
170
171 World& verify(); ///< Verifies that all externals() and annexes() are Def::is_closed(), if `MIM_ENABLE_CHECKS`.
172#else
173 World& verify() { return *this; }
174#endif
175 ///@}
176
177 /// @name Annexes
178 ///@{
179 const auto& flags2annex() const { return move_.flags2annex; }
180 auto annexes() const { return move_.flags2annex | std::views::values; }
181
182 /// Lookup annex by Axm::id.
183 template<class Id>
184 const Def* annex(Id id) {
185 auto flags = static_cast<flags_t>(id);
186 if (auto i = move_.flags2annex.find(flags); i != move_.flags2annex.end()) return i->second;
187 error("Axm with ID '{x}' not found; demangled plugin name is '{}'", flags, Annex::demangle(driver(), flags));
188 }
189
190 /// Get Axm from a plugin.
191 /// Can be used to get an Axm without sub-tags.
192 /// E.g. use `w.annex<mem::M>();` to get the `%mem.M` Axm.
193 template<annex_without_subs id>
194 const Def* annex() {
195 return annex(Annex::base<id>());
196 }
197
198 const Def* register_annex(flags_t f, const Def*);
199 const Def* register_annex(plugin_t p, tag_t t, sub_t s, const Def* def) {
200 return register_annex(p | (flags_t(t) << 8_u64) | flags_t(s), def);
201 }
202 ///@}
203
204 /// @name Externals
205 ///@{
206 class Externals {
207 public:
208 ///@name Get syms/muts
209 ///@{
210 const auto& sym2mut() const { return sym2mut_; }
211 auto syms() const { return sym2mut_ | std::views::keys; }
212 auto muts() const { return sym2mut_ | std::views::values; }
213 /// Returns a copy of @p muts() in a Vector; this allows you modify the Externals while iterating.
214 /// @note The iteration will see all old externals, of course.
215 Vector<Def*> mutate() const { return {muts().begin(), muts().end()}; }
216 Def* operator[](Sym name) const { return mim::lookup(sym2mut_, name); } ///< Lookup by @p name.
217 ///@}
218
219 ///@name externalize/internalize
220 ///@{
221 void externalize(Def*);
222 void internalize(Def*);
223 ///@}
224
225 /// @name Iterators
226 ///@{
227 auto begin() const { return sym2mut_.cbegin(); }
228 auto end() const { return sym2mut_.cend(); }
229 ///@}
230
231 friend void swap(Externals& ex1, Externals& ex2) noexcept {
232 using std::swap;
233 swap(ex1.sym2mut_, ex2.sym2mut_);
234 }
235
236 private:
237 fe::SymMap<Def*> sym2mut_;
238 };
239
240 const Externals& externals() const { return move_.externals; }
241 Externals& externals() { return move_.externals; }
242 ///@}
243
244 /// @name Univ, Type, Var, Proxy, Hole
245 ///@{
246 const Univ* univ() { return data_.univ; }
247 const Def* uinc(const Def* op, level_t offset = 1);
248 template<int sort = UMax::Univ>
249 const Def* umax(Defs);
250 const Type* type(const Def* level);
251 const Type* type_infer_univ() { return type(mut_hole_univ()); }
252 template<level_t level = 0>
253 const Type* type() {
254 if constexpr (level == 0)
255 return data_.type_0;
256 else if constexpr (level == 1)
257 return data_.type_1;
258 else
259 return type(lit_univ(level));
260 }
261 const Def* var(Def* mut);
262 const Proxy* proxy(const Def* type, Defs ops, u32 index, u32 tag) { return unify<Proxy>(type, index, tag, ops); }
263
264 Hole* mut_hole(const Def* type) { return insert<Hole>(type); }
265 Hole* mut_hole_univ() { return mut_hole(univ()); }
267
268 /// Either a value `?:?:Type ?` or a type `?:Type ?:Type ?`.
270 auto t = type_infer_univ();
271 auto res = mut_hole(mut_hole(t));
272 assert(this == &res->world());
273 return res;
274 }
275 ///@}
276
277 /// @name Axm
278 ///@{
279 const Axm* axm(NormalizeFn n, u8 curry, u8 trip, const Def* type, plugin_t p, tag_t t, sub_t s) {
280 return unify<Axm>(n, curry, trip, type, p, t, s);
281 }
282 const Axm* axm(const Def* type, plugin_t p, tag_t t, sub_t s) { return axm(nullptr, 0, 0, type, p, t, s); }
283
284 /// Builds a fresh Axm with descending Axm::sub.
285 /// This is useful during testing to come up with some entity of a specific type.
286 /// It uses the plugin Axm::Global_Plugin and starts with `0` for Axm::sub and counts up from there.
287 /// The Axm::tag is set to `0` and the Axm::normalizer to `nullptr`.
288 const Axm* axm(NormalizeFn n, u8 curry, u8 trip, const Def* type) {
289 return axm(n, curry, trip, type, Annex::Global_Plugin, 0, state_.pod.curr_sub++);
290 }
291 const Axm* axm(const Def* type) { return axm(nullptr, 0, 0, type); } ///< See above.
292 ///@}
293
294 /// @name Pi
295 ///@{
296 // clang-format off
297 const Pi* pi(const Def* dom, const Def* codom, bool implicit = false) { return unify<Pi>(Pi::infer(dom, codom), dom, codom, implicit); }
298 const Pi* pi(Defs dom, const Def* codom, bool implicit = false) { return pi(sigma(dom), codom, implicit); }
299 const Pi* pi(const Def* dom, Defs codom, bool implicit = false) { return pi(dom, sigma(codom), implicit); }
300 const Pi* pi(Defs dom, Defs codom, bool implicit = false) { return pi(sigma(dom), sigma(codom), implicit); }
301 Pi* mut_pi(const Def* type, bool implicit = false) { return insert<Pi>(type, implicit); }
302 // clang-format on
303 ///@}
304
305 /// @name Cn
306 /// Pi with codom mim::Bot%tom
307 ///@{
308 // clang-format off
309 const Pi* cn( ) { return cn(sigma( ), false); }
310 const Pi* cn(const Def* dom, bool implicit = false) { return pi( dom , type_bot(), implicit); }
311 const Pi* cn(Defs dom, bool implicit = false) { return cn(sigma(dom), implicit); }
312 const Pi* fn(const Def* dom, const Def* codom, bool implicit = false) { return cn({ dom , cn(codom)}, implicit); }
313 const Pi* fn(Defs dom, const Def* codom, bool implicit = false) { return fn(sigma(dom), codom, implicit); }
314 const Pi* fn(const Def* dom, Defs codom, bool implicit = false) { return fn( dom , sigma(codom), implicit); }
315 const Pi* fn(Defs dom, Defs codom, bool implicit = false) { return fn(sigma(dom), sigma(codom), implicit); }
316 // clang-format on
317 ///@}
318
319 /// @name Lam
320 ///@{
322 if (auto b = std::get_if<bool>(&filter)) return lit_bool(*b);
323 return std::get<const Def*>(filter);
324 }
325 const Lam* lam(const Pi* pi, Lam::Filter f, const Def* body) { return unify<Lam>(pi, filter(f), body); }
326 Lam* mut_lam(const Pi* pi) { return insert<Lam>(pi); }
327 // clang-format off
328 const Lam* con(const Def* dom, Lam::Filter f, const Def* body) { return unify<Lam>(cn(dom ), filter(f), body); }
329 const Lam* con(Defs dom, Lam::Filter f, const Def* body) { return unify<Lam>(cn(dom ), filter(f), body); }
330 const Lam* lam(const Def* dom, const Def* codom, Lam::Filter f, const Def* body) { return unify<Lam>(pi(dom, codom), filter(f), body); }
331 const Lam* lam(Defs dom, const Def* codom, Lam::Filter f, const Def* body) { return unify<Lam>(pi(dom, codom), filter(f), body); }
332 const Lam* lam(const Def* dom, Defs codom, Lam::Filter f, const Def* body) { return unify<Lam>(pi(dom, codom), filter(f), body); }
333 const Lam* lam(Defs dom, Defs codom, Lam::Filter f, const Def* body) { return unify<Lam>(pi(dom, codom), filter(f), body); }
334 const Lam* fun(const Def* dom, const Def* codom, Lam::Filter f, const Def* body) { return unify<Lam>(fn(dom, codom), filter(f), body); }
335 const Lam* fun(Defs dom, const Def* codom, Lam::Filter f, const Def* body) { return unify<Lam>(fn(dom, codom), filter(f), body); }
336 const Lam* fun(const Def* dom, Defs codom, Lam::Filter f, const Def* body) { return unify<Lam>(fn(dom, codom), filter(f), body); }
337 const Lam* fun(Defs dom, Defs codom, Lam::Filter f, const Def* body) { return unify<Lam>(fn(dom, codom), filter(f), body); }
338 Lam* mut_con(const Def* dom ) { return insert<Lam>(cn(dom )); }
339 Lam* mut_con(Defs dom ) { return insert<Lam>(cn(dom )); }
340 Lam* mut_lam(const Def* dom, const Def* codom) { return insert<Lam>(pi(dom, codom)); }
341 Lam* mut_lam(Defs dom, const Def* codom) { return insert<Lam>(pi(dom, codom)); }
342 Lam* mut_lam(const Def* dom, Defs codom) { return insert<Lam>(pi(dom, codom)); }
343 Lam* mut_lam(Defs dom, Defs codom) { return insert<Lam>(pi(dom, codom)); }
344 Lam* mut_fun(const Def* dom, const Def* codom) { return insert<Lam>(fn(dom, codom)); }
345 Lam* mut_fun(Defs dom, const Def* codom) { return insert<Lam>(fn(dom, codom)); }
346 Lam* mut_fun(const Def* dom, Defs codom) { return insert<Lam>(fn(dom, codom)); }
347 Lam* mut_fun(Defs dom, Defs codom) { return insert<Lam>(fn(dom, codom)); }
348 // clang-format on
349 ///@}
350
351 /// @name Rewrite Rules
352 ///@{
353 const Reform* reform(const Def* meta_type) { return unify<Reform>(Reform::infer(meta_type), meta_type); }
354 Rule* mut_rule(const Reform* type) { return insert<Rule>(type); }
355 const Rule* rule(const Reform* type, const Def* lhs, const Def* rhs, const Def* guard) {
356 return mut_rule(type)->set(lhs, rhs, guard);
357 }
358 const Rule* rule(const Def* meta_type, const Def* lhs, const Def* rhs, const Def* guard) {
359 return rule(reform(meta_type), lhs, rhs, guard);
360 }
361 ///@}
362
363 /// @name App
364 ///@{
365 template<bool Normalize = true>
366 const Def* app(const Def* callee, const Def* arg);
367 template<bool Normalize = true>
368 const Def* app(const Def* callee, Defs args) {
369 return app<Normalize>(callee, tuple(args));
370 }
371 const Def* raw_app(const Axm* axm, u8 curry, u8 trip, const Def* type, const Def* callee, const Def* arg);
372 const Def* raw_app(const Def* type, const Def* callee, const Def* arg);
373 const Def* raw_app(const Def* type, const Def* callee, Defs args) { return raw_app(type, callee, tuple(args)); }
374 ///@}
375
376 /// @name Sigma
377 ///@{
378 Sigma* mut_sigma(const Def* type, size_t size) { return insert<Sigma>(type, size); }
379 /// A *mutable* Sigma of type @p level.
380 template<level_t level = 0>
381 Sigma* mut_sigma(size_t size) {
382 return mut_sigma(type<level>(), size);
383 }
384 const Def* sigma(Defs ops);
385 const Sigma* sigma() { return data_.sigma; } ///< The unit type within Type 0.
386 ///@}
387
388 /// @name Arr
389 ///@{
390 // clang-format off
391 const Def* unit(bool term) { return term ? (const Def*)tuple() : sigma(); }
392
393 Seq* mut_seq(bool term, const Def* type) { return term ? (Seq*)insert<Pack>(type) : insert<Arr>(type); }
394 const Def* seq(bool term, const Def* arity, const Def* body);
395 const Def* seq(bool term, Defs shape, const Def* body);
396 const Def* seq(bool term, u64 n, const Def* body) { return seq(term, lit_nat(n), body); }
397 const Def* seq(bool term, View<u64> shape, const Def* body) { return seq(term, DefVec(shape.size(), [&](size_t i) { return lit_nat(shape[i]); }), body); }
398 const Def* seq_unsafe(bool term, const Def* body) { return seq(term, top_nat(), body); }
399
400 template<level_t level = 0>
402 return mut_arr(type<level>());
403 }
404
405 Arr * mut_arr (const Def* type) { return mut_seq(false, type)->as<Arr >(); }
406 Pack* mut_pack(const Def* type) { return mut_seq(true , type)->as<Pack>(); }
407 const Def* arr (const Def* arity, const Def* body) { return seq(false, arity, body); }
408 const Def* pack(const Def* arity, const Def* body) { return seq(true , arity, body); }
409 const Def* arr (Defs shape, const Def* body) { return seq(false, shape, body); }
410 const Def* pack(Defs shape, const Def* body) { return seq(true , shape, body); }
411 const Def* arr (u64 n, const Def* body) { return seq(false, n, body); }
412 const Def* pack(u64 n, const Def* body) { return seq(true , n, body); }
413 const Def* arr (View<u64> shape, const Def* body) { return seq(false, shape, body); }
414 const Def* pack(View<u64> shape, const Def* body) { return seq(true , shape, body); }
415 const Def* arr_unsafe( const Def* body) { return seq_unsafe(false, body); }
416 const Def* pack_unsafe( const Def* body) { return seq_unsafe(true , body); }
417
418 const Def* prod(bool term, Defs ops) { return term ? tuple(ops) : sigma(ops); }
419 const Def* prod(bool term) { return term ? (const Def*)tuple() : (const Def*)sigma(); }
420 // clang-format on
421 ///@}
422
423 /// @name Tuple
424 ///@{
425 const Def* tuple(Defs ops);
426 /// Ascribes @p type to this tuple - needed for dependently typed and mutable Sigma%s.
427 const Def* tuple(const Def* type, Defs ops);
428 const Tuple* tuple() { return data_.tuple; } ///< the unit value of type `[]`
429 const Def* tuple(Sym sym); ///< Converts @p sym to a tuple of type '«n; I8»'.
430 ///@}
431
432 /// @name Extract
433 /// @see core::extract_unsafe
434 ///@{
435 const Def* extract(const Def* d, const Def* i);
436 const Def* extract(const Def* d, u64 a, u64 i) { return extract(d, lit_idx(a, i)); }
437 const Def* extract(const Def* d, u64 i) { return extract(d, Lit::as(d->arity()), i); }
438
439 /// Builds `(f, t)#cond`.
440 /// @note Expects @p cond as first, @p t as second, and @p f as third argument.
441 const Def* select(const Def* cond, const Def* t, const Def* f) { return extract(tuple({f, t}), cond); }
442 ///@}
443
444 /// @name Insert
445 /// @see core::insert_unsafe
446 ///@{
447 const Def* insert(const Def* d, const Def* i, const Def* val);
448 const Def* insert(const Def* d, u64 a, u64 i, const Def* val) { return insert(d, lit_idx(a, i), val); }
449 const Def* insert(const Def* d, u64 i, const Def* val) { return insert(d, Lit::as(d->arity()), i, val); }
450 ///@}
451
452 /// @name Lit
453 ///@{
454 const Lit* lit(const Def* type, u64 val);
455 const Lit* lit_univ(u64 level) { return lit(univ(), level); }
456 const Lit* lit_univ_0() { return data_.lit_univ_0; }
457 const Lit* lit_univ_1() { return data_.lit_univ_1; }
458 const Lit* lit_nat(nat_t a) { return lit(type_nat(), a); }
459 const Lit* lit_nat_0() { return data_.lit_nat_0; }
460 const Lit* lit_nat_1() { return data_.lit_nat_1; }
461 const Lit* lit_nat_max() { return data_.lit_nat_max; }
462 const Lit* lit_idx_1_0() { return data_.lit_idx_1_0; }
463 // clang-format off
464 const Lit* lit_i1() { return lit_nat(Idx::bitwidth2size( 1)); };
465 const Lit* lit_i8() { return lit_nat(Idx::bitwidth2size( 8)); };
466 const Lit* lit_i16() { return lit_nat(Idx::bitwidth2size(16)); };
467 const Lit* lit_i32() { return lit_nat(Idx::bitwidth2size(32)); };
468 const Lit* lit_i64() { return lit_nat(Idx::bitwidth2size(64)); };
469 /// Constructs a Lit of type Idx of size @p size.
470 /// @note `size = 0` means `2^64`.
471 const Lit* lit_idx(nat_t size, u64 val) { return lit(type_idx(size), val); }
472 const Lit* lit_idx_unsafe(u64 val) { return lit(type_idx(top(type_nat())), val); }
473
474 template<class I> const Lit* lit_idx(I val) {
475 static_assert(std::is_integral<I>());
476 return lit_idx(Idx::bitwidth2size(sizeof(I) * 8), val);
477 }
478
479 /// Constructs a Lit @p of type Idx of size 2^width.
480 /// `val = 64` will be automatically converted to size `0` - the encoding for 2^64.
481 const Lit* lit_int(nat_t width, u64 val) { return lit_idx(Idx::bitwidth2size(width), val); }
482 const Lit* lit_i1 (bool val) { return lit_int( 1, u64(val)); }
483 const Lit* lit_i2 (u8 val) { return lit_int( 2, u64(val)); }
484 const Lit* lit_i4 (u8 val) { return lit_int( 4, u64(val)); }
485 const Lit* lit_i8 (u8 val) { return lit_int( 8, u64(val)); }
486 const Lit* lit_i16(u16 val) { return lit_int(16, u64(val)); }
487 const Lit* lit_i32(u32 val) { return lit_int(32, u64(val)); }
488 const Lit* lit_i64(u64 val) { return lit_int(64, u64(val)); }
489 // clang-format on
490
491 /// Constructs a Lit of type Idx of size @p mod.
492 /// The value @p val will be adjusted modulo @p mod.
493 /// @note `mod == 0` is the special case for 2^64 and no modulo will be performed on @p val.
494 const Lit* lit_idx_mod(nat_t mod, u64 val) { return lit_idx(mod, mod == 0 ? val : (val % mod)); }
495
496 const Lit* lit_bool(bool val) { return data_.lit_bool[size_t(val)]; }
497 const Lit* lit_ff() { return data_.lit_bool[0]; }
498 const Lit* lit_tt() { return data_.lit_bool[1]; }
499 ///@}
500
501 /// @name Lattice
502 ///@{
503 template<bool Up>
504 const Def* ext(const Def* type);
505 const Def* bot(const Def* type) { return ext<false>(type); }
506 const Def* top(const Def* type) { return ext<true>(type); }
507 const Def* type_bot() { return data_.type_bot; }
508 const Def* type_top() { return data_.type_top; }
509 const Def* top_nat() { return data_.top_nat; }
510 template<bool Up>
511 const Def* bound(Defs ops);
512 const Def* join(Defs ops) { return bound<true>(ops); }
513 const Def* meet(Defs ops) { return bound<false>(ops); }
514 const Def* merge(const Def* type, Defs ops);
515 const Def* merge(Defs ops); ///< Infers the type using a Meet.
516 const Def* inj(const Def* type, const Def* value);
517 const Def* split(const Def* type, const Def* value);
518 const Def* match(Defs);
519 const Def* uniq(const Def* inhabitant);
520 ///@}
521
522 /// @name Globals
523 /// @deprecated Will be removed.
524 ///@{
525 Global* global(const Def* type, bool is_mutable = true) { return insert<Global>(type, is_mutable); }
526 ///@}
527
528 /// @name Types
529 ///@{
530 const Nat* type_nat() { return data_.type_nat; }
531 const Idx* type_idx() { return data_.type_idx; }
532 /// @note `size = 0` means `2^64`.
533 const Def* type_idx(const Def* size) { return app(type_idx(), size); }
534 /// @note `size = 0` means `2^64`.
535 const Def* type_idx(nat_t size) { return type_idx(lit_nat(size)); }
536
537 /// Constructs a type Idx of size 2^width.
538 /// `width = 64` will be automatically converted to size `0` - the encoding for 2^64.
539 const Def* type_int(nat_t width) { return type_idx(lit_nat(Idx::bitwidth2size(width))); }
540 // clang-format off
541 const Def* type_bool() { return data_.type_bool; }
542 const Def* type_i1() { return data_.type_bool; }
543 const Def* type_i2() { return type_int( 2); };
544 const Def* type_i4() { return type_int( 4); };
545 const Def* type_i8() { return type_int( 8); };
546 const Def* type_i16() { return type_int(16); };
547 const Def* type_i32() { return type_int(32); };
548 const Def* type_i64() { return type_int(64); };
549 // clang-format on
550 ///@}
551
552 /// @name Cope with implicit Arguments
553 ///@{
554
555 /// Places Hole%s as demanded by Pi::is_implicit() and then apps @p arg.
556 template<bool Normalize = true>
557 const Def* implicit_app(const Def* callee, const Def* arg);
558 template<bool Normalize = true>
559 const Def* implicit_app(const Def* callee, Defs args) {
560 return implicit_app<Normalize>(callee, tuple(args));
561 }
562 template<bool Normalize = true>
563 const Def* implicit_app(const Def* callee, nat_t arg) {
564 return implicit_app<Normalize>(callee, lit_nat(arg));
565 }
566 template<bool Normalize = true, class E>
567 const Def* implicit_app(const Def* callee, E arg)
568 requires std::is_enum_v<E> && std::is_same_v<std::underlying_type_t<E>, nat_t>
569 {
570 return implicit_app<Normalize>(callee, lit_nat((nat_t)arg));
571 }
572
573 /// Complete curried call of annexes obeying implicits.
574 // clang-format off
575 template<class Id, bool Normalize = true, class... Args> const Def* call(Id id, Args&&... args) { return call_<Normalize>(annex(id), std::forward<Args>(args)...); }
576 template<class Id, bool Normalize = true, class... Args> const Def* call( Args&&... args) { return call_<Normalize>(annex<Id>(), std::forward<Args>(args)...); }
577 // clang-format on
578 ///@}
579
580 /// @name Vars & Muts
581 /// Manges sets of Vars and Muts.
582 ///@{
583 [[nodiscard]] auto& vars() { return move_.vars; }
584 [[nodiscard]] auto& muts() { return move_.muts; }
585 [[nodiscard]] const auto& vars() const { return move_.vars; }
586 [[nodiscard]] const auto& muts() const { return move_.muts; }
587
588 /// Yields the new body of `[mut->var() -> arg]mut`.
589 /// The new body may have fewer elements as `mut->num_ops()` according to Def::reduction_offset.
590 /// E.g. a Pi has a Pi::reduction_offset of 1, and only Pi::dom will be reduced - *not* Pi::codom.
591 Defs reduce(const Var* var, const Def* arg);
592 ///@}
593
594 /// @name for_each
595 /// Visits all closed mutables in this World.
596 ///@{
597 void for_each(bool elide_empty, std::function<void(Def*)>);
598
599 template<class M>
600 void for_each(bool elide_empty, std::function<void(M*)> f) {
601 for_each(elide_empty, [f](Def* m) {
602 if (auto mut = m->template isa<M>()) f(mut);
603 });
604 }
605 ///@}
606
607 /// @name dump/log
608 ///@{
609 Log& log() const;
610 void dump(std::ostream& os); ///< Dump to @p os.
611 void dump(); ///< Dump to `std::cout`.
612 void debug_dump(); ///< Dump in Debug build if World::log::level is Log::Level::Debug.
613 void write(const char* file); ///< Write to a file named @p file.
614 void write(); ///< Same above but file name defaults to World::name.
615 ///@}
616
617 /// @name dot
618 /// GraphViz output.
619 ///@{
620
621 /// Dumps DOT to @p os.
622 /// @param os Output stream
623 /// @param annexes If `true`, include all annexes - even if unused.
624 /// @param types Follow type dependencies?
625 void dot(std::ostream& os, bool annexes = false, bool types = false) const;
626 /// Same as above but write to @p file or `std::cout` if @p file is `nullptr`.
627 void dot(const char* file = nullptr, bool annexes = false, bool types = false) const;
628 ///@}
629
630private:
631 /// @name call_
632 /// Helpers to unwind World::call with variadic templates.
633 ///@{
634 template<bool Normalize = true, class T, class... Args>
635 const Def* call_(const Def* callee, T arg, Args&&... args) {
636 return call_<Normalize>(implicit_app(callee, arg), std::forward<Args>(args)...);
637 }
638 template<bool Normalize = true, class T>
639 const Def* call_(const Def* callee, T arg) {
640 return implicit_app<Normalize>(callee, arg);
641 }
642 ///@}
643
644 /// @name Put into Sea of Nodes
645 ///@{
646 template<class T, class... Args>
647 const T* unify(Args&&... args) {
648 auto num_ops = T::Num_Ops;
649 if constexpr (T::Num_Ops == std::dynamic_extent) {
650 auto&& last = std::get<sizeof...(Args) - 1>(std::forward_as_tuple(std::forward<Args>(args)...));
651 num_ops = last.size();
652 }
653
654 auto state = move_.arena.defs.state();
655 auto def = allocate<T>(num_ops, std::forward<Args&&>(args)...);
656 assert(!def->isa_mut());
657
658 if (auto loc = get_loc()) def->set(loc);
659
660#ifdef MIM_ENABLE_CHECKS
661 if (flags().trace_gids) outln("{}: {} - {}", def->node_name(), def->gid(), def->flags());
662 if (flags().reeval_breakpoints && breakpoints().contains(def->gid())) fe::breakpoint();
663#endif
664
665 if (is_frozen()) {
666 auto i = move_.defs.find(def);
667 deallocate<T>(state, def);
668 if (i != move_.defs.end()) return static_cast<const T*>(*i);
669 return nullptr;
670 }
671
672 if (auto [i, ins] = move_.defs.emplace(def); !ins) {
673 deallocate<T>(state, def);
674 return static_cast<const T*>(*i);
675 }
676
677#ifdef MIM_ENABLE_CHECKS
678 if (!flags().reeval_breakpoints && breakpoints().contains(def->gid())) fe::breakpoint();
679#endif
680 return def;
681 }
682
683 template<class T>
684 void deallocate(fe::Arena::State state, const T* ptr) {
685 --state_.pod.curr_gid;
686 ptr->~T();
687 move_.arena.defs.deallocate(state);
688 }
689
690 template<class T, class... Args>
691 T* insert(Args&&... args) {
692 if (is_frozen()) return nullptr;
693
694 auto num_ops = T::Num_Ops;
695 if constexpr (T::Num_Ops == std::dynamic_extent)
696 num_ops = std::get<sizeof...(Args) - 1>(std::forward_as_tuple(std::forward<Args>(args)...));
697
698 auto def = allocate<T>(num_ops, std::forward<Args>(args)...);
699 if (auto loc = get_loc()) def->set(loc);
700
701#ifdef MIM_ENABLE_CHECKS
702 if (flags().trace_gids) outln("{}: {} - {}", def->node_name(), def->gid(), def->flags());
703 if (breakpoints().contains(def->gid())) fe::breakpoint();
704#endif
705 assert_emplace(move_.defs, def);
706 return def;
707 }
708
709#if (!defined(_MSC_VER) && defined(NDEBUG))
710 struct Lock {
711 Lock() { assert((guard_ = !guard_) && "you are not allowed to recursively invoke allocate"); }
712 ~Lock() { guard_ = !guard_; }
713 static bool guard_;
714 };
715#else
716 struct Lock {
717 ~Lock() {}
718 };
719#endif
720
721 template<class T, class... Args>
722 T* allocate(size_t num_ops, Args&&... args) {
723 static_assert(sizeof(Def) == sizeof(T),
724 "you are not allowed to introduce any additional data in subclasses of Def");
725 auto lock = Lock();
726 auto num_bytes = sizeof(Def) + sizeof(uintptr_t) * num_ops;
727 auto ptr = move_.arena.defs.allocate(num_bytes, alignof(T));
728 auto res = new (ptr) T(std::forward<Args>(args)...);
729 assert(res->num_ops() == num_ops);
730 return res;
731 }
732 ///@}
733
734 Driver* driver_;
735 Zonker zonker_;
736 State state_;
737
738 struct SeaHash {
739 size_t operator()(const Def* def) const { return def->hash(); }
740 };
741
742 struct SeaEq {
743 bool operator()(const Def* d1, const Def* d2) const { return d1->equal(d2); }
744 };
745
746 class Reduct {
747 public:
748 constexpr Reduct(size_t size) noexcept
749 : size_(size) {}
750
751 template<size_t N = std::dynamic_extent>
752 constexpr auto defs() const noexcept {
753 return View<const Def*, N>{defs_, size_};
754 }
755
756 private:
757 size_t size_;
758 const Def* defs_[];
759
760 friend class World;
761 };
762
763 struct Move {
764 struct {
765 fe::Arena defs, substs;
766 } arena;
767
769 absl::btree_map<flags_t, const Def*> flags2annex;
770 absl::flat_hash_set<const Def*, SeaHash, SeaEq> defs;
773 absl::flat_hash_map<std::pair<const Var*, const Def*>, const Reduct*> substs;
774
775 friend void swap(Move& m1, Move& m2) noexcept {
776 using std::swap;
777 // clang-format off
778 swap(m1.arena.defs, m2.arena.defs);
779 swap(m1.arena.substs, m2.arena.substs);
780 swap(m1.defs, m2.defs);
781 swap(m1.substs, m2.substs);
782 swap(m1.vars, m2.vars);
783 swap(m1.muts, m2.muts);
784 swap(m1.flags2annex, m2.flags2annex);
785 swap(m1.externals, m2.externals);
786 // clang-format on
787 }
788 } move_;
789
790 struct {
791 const Univ* univ;
792 const Type* type_0;
793 const Type* type_1;
794 const Bot* type_bot;
795 const Top* type_top;
796 const Def* type_bool;
797 const Top* top_nat;
798 const Sigma* sigma;
799 const Tuple* tuple;
800 const Nat* type_nat;
801 const Idx* type_idx;
802 const Def* table_id;
803 const Def* table_not;
804 const Lit* lit_univ_0;
805 const Lit* lit_univ_1;
806 const Lit* lit_nat_0;
807 const Lit* lit_nat_1;
808 const Lit* lit_nat_max;
809 const Lit* lit_idx_1_0;
810 std::array<const Lit*, 2> lit_bool;
811 u32 curr_run = 0;
812 } data_;
813
814 friend void swap(World& w1, World& w2) noexcept {
815 using std::swap;
816 // clang-format off
817 swap(w1.driver_, w2.driver_ );
818 swap(w1.zonker_, w2.zonker_ );
819 swap(w1.state_, w2.state_);
820 swap(w1.data_, w2.data_ );
821 swap(w1.move_, w2.move_ );
822 // clang-format on
823
824 swap(w1.data_.univ->world_, w2.data_.univ->world_);
825 assert(&w1.univ()->world() == &w1);
826 assert(&w2.univ()->world() == &w2);
827 }
828};
829
830} // namespace mim
A (possibly paramterized) Array.
Definition tuple.h:117
Definition axm.h:9
Base class for all Defs.
Definition def.h:251
Some "global" variables needed all over the place.
Definition driver.h:17
This node is a hole in the IR that is inferred by its context later on.
Definition check.h:14
A built-in constant of type Nat -> *.
Definition def.h:861
static constexpr nat_t bitwidth2size(nat_t n)
Definition def.h:892
A function.
Definition lam.h:110
std::variant< bool, const Def * > Filter
Definition lam.h:118
static T as(const Def *def)
Definition def.h:832
Facility to log what you are doing.
Definition log.h:17
A (possibly paramterized) Tuple.
Definition tuple.h:166
A dependent function type.
Definition lam.h:14
static const Def * infer(const Def *dom, const Def *codom)
Definition check.cpp:318
Type formation of a rewrite Rule.
Definition rule.h:9
static const Def * infer(const Def *meta_type)
Definition check.cpp:355
A rewrite rule.
Definition rule.h:38
Rule * set(const Def *lhs, const Def *rhs)
Definition rule.h:62
Base class for Arr and Pack.
Definition tuple.h:84
A dependent tuple type.
Definition tuple.h:20
Data constructor for a Sigma.
Definition tuple.h:68
A variable introduced by a binder (mutable).
Definition def.h:702
This is a thin wrapper for absl::InlinedVector<T, N, A> which is a drop-in replacement for std::vecto...
Definition vector.h:18
Vector< Def * > mutate() const
Returns a copy of muts() in a Vector; this allows you modify the Externals while iterating.
Definition world.h:215
void internalize(Def *)
Definition world.cpp:34
Def * operator[](Sym name) const
Lookup by name.
Definition world.h:216
friend void swap(Externals &ex1, Externals &ex2) noexcept
Definition world.h:231
auto end() const
Definition world.h:228
auto muts() const
Definition world.h:212
auto begin() const
Definition world.h:227
const auto & sym2mut() const
Definition world.h:210
void externalize(Def *)
Definition world.cpp:27
auto syms() const
Definition world.h:211
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:31
const Lit * lit_idx(nat_t size, u64 val)
Constructs a Lit of type Idx of size size.
Definition world.h:471
const Lit * lit_idx(I val)
Definition world.h:474
const Def * arr(Defs shape, const Def *body)
Definition world.h:409
const Def * insert(const Def *d, const Def *i, const Def *val)
Definition world.cpp:432
const Def * type_i16()
Definition world.h:546
const Pi * fn(Defs dom, const Def *codom, bool implicit=false)
Definition world.h:313
const Def * meet(Defs ops)
Definition world.h:513
std::unique_ptr< World > inherit()
Inherits the State into the new World.
Definition world.h:76
const auto & flags2annex() const
Definition world.h:179
const Lam * con(Defs dom, Lam::Filter f, const Def *body)
Definition world.h:329
const Def * uinc(const Def *op, level_t offset=1)
Definition world.cpp:118
const Pi * cn()
Definition world.h:309
const Lit * lit(const Def *type, u64 val)
Definition world.cpp:515
const Def * arr(u64 n, const Def *body)
Definition world.h:411
u32 next_run()
Definition world.h:100
friend void swap(World &w1, World &w2) noexcept
Definition world.h:814
const Def * implicit_app(const Def *callee, nat_t arg)
Definition world.h:563
const Def * extract(const Def *d, u64 a, u64 i)
Definition world.h:436
auto & muts()
Definition world.h:584
const Def * type_i4()
Definition world.h:544
const Lit * lit_i8()
Definition world.h:465
Hole * mut_hole_infer_entity()
Either a value ?:?:Type ? or a type ?:Type ?:Type ?.
Definition world.h:269
const Pi * cn(const Def *dom, bool implicit=false)
Definition world.h:310
const Def * type_int(nat_t width)
Constructs a type Idx of size 2^width.
Definition world.h:539
World & operator=(World)=delete
const Lit * lit_i16(u16 val)
Definition world.h:486
void watchpoint(u32 gid)
Trigger breakpoint in your debugger when Def::setting a Def with this gid.
Definition world.cpp:701
const Lit * lit_i1(bool val)
Definition world.h:482
const Def * arr(View< u64 > shape, const Def *body)
Definition world.h:413
const Lit * lit_i32()
Definition world.h:467
Driver & driver()
Definition world.h:87
Zonker & zonker()
Definition world.h:88
Lam * mut_fun(const Def *dom, Defs codom)
Definition world.h:346
const Type * type(const Def *level)
Definition world.cpp:108
const Driver & driver() const
Definition world.h:86
const Lam * lam(const Def *dom, const Def *codom, Lam::Filter f, const Def *body)
Definition world.h:330
Externals & externals()
Definition world.h:241
Lam * mut_lam(const Def *dom, Defs codom)
Definition world.h:342
const Lit * lit_tt()
Definition world.h:498
const Def * filter(Lam::Filter filter)
Definition world.h:321
World(Driver *)
Definition world.cpp:74
const auto & watchpoints()
Definition world.h:165
const Def * type_idx(nat_t size)
Definition world.h:535
const Def * pack(const Def *arity, const Def *body)
Definition world.h:408
const Def * unit(bool term)
Definition world.h:391
void set(std::string_view name)
Definition world.h:92
const Def * app(const Def *callee, const Def *arg)
Definition world.cpp:201
u32 curr_gid() const
Manage global identifier - a unique number for each Def.
Definition world.h:95
const Def * seq(bool term, View< u64 > shape, const Def *body)
Definition world.h:397
const Axm * axm(const Def *type)
See above.
Definition world.h:291
const Def * match(Defs)
Definition world.cpp:602
const Def * type_bot()
Definition world.h:507
const Pi * pi(const Def *dom, const Def *codom, bool implicit=false)
Definition world.h:297
const Def * pack(u64 n, const Def *body)
Definition world.h:412
const Def * seq(bool term, const Def *arity, const Def *body)
Definition world.cpp:481
const Def * insert(const Def *d, u64 a, u64 i, const Def *val)
Definition world.h:448
const auto & muts() const
Definition world.h:586
const Univ * univ()
Definition world.h:246
const Lam * lam(Defs dom, const Def *codom, Lam::Filter f, const Def *body)
Definition world.h:331
const Def * seq_unsafe(bool term, const Def *body)
Definition world.h:398
const Lam * fun(Defs dom, const Def *codom, Lam::Filter f, const Def *body)
Definition world.h:335
Rule * mut_rule(const Reform *type)
Definition world.h:354
const Def * type_i8()
Definition world.h:545
World & verify()
Verifies that all externals() and annexes() are Def::is_closed(), if MIM_ENABLE_CHECKS.
Definition world.cpp:709
const Def * bot(const Def *type)
Definition world.h:505
const Lit * lit_i64()
Definition world.h:468
Arr * mut_arr(const Def *type)
Definition world.h:405
const Rule * rule(const Def *meta_type, const Def *lhs, const Def *rhs, const Def *guard)
Definition world.h:358
const Lam * lam(const Def *dom, Defs codom, Lam::Filter f, const Def *body)
Definition world.h:332
const Lit * lit_idx_mod(nat_t mod, u64 val)
Constructs a Lit of type Idx of size mod.
Definition world.h:494
const Idx * type_idx()
Definition world.h:531
const Def * type_i1()
Definition world.h:542
Pi * mut_pi(const Def *type, bool implicit=false)
Definition world.h:301
const Lit * lit_univ_0()
Definition world.h:456
const Def * annex(Id id)
Lookup annex by Axm::id.
Definition world.h:184
void set_loc(Loc loc={})
Definition world.h:120
const Def * implicit_app(const Def *callee, E arg)
Definition world.h:567
Sym name() const
Definition world.h:90
const Pi * cn(Defs dom, bool implicit=false)
Definition world.h:311
void dump()
Dump to std::cout.
Definition dump.cpp:491
void for_each(bool elide_empty, std::function< void(Def *)>)
Definition world.cpp:679
const Lam * fun(const Def *dom, Defs codom, Lam::Filter f, const Def *body)
Definition world.h:336
const Lit * lit_univ_1()
Definition world.h:457
const Reform * reform(const Def *meta_type)
Definition world.h:353
void write()
Same above but file name defaults to World::name.
Definition dump.cpp:502
const Lam * lam(Defs dom, Defs codom, Lam::Filter f, const Def *body)
Definition world.h:333
const Def * register_annex(plugin_t p, tag_t t, sub_t s, const Def *def)
Definition world.h:199
Lam * mut_fun(Defs dom, const Def *codom)
Definition world.h:345
Lam * mut_fun(const Def *dom, const Def *codom)
Definition world.h:344
const Lit * lit_i1()
Definition world.h:464
const Axm * axm(NormalizeFn n, u8 curry, u8 trip, const Def *type)
Builds a fresh Axm with descending Axm::sub.
Definition world.h:288
const Nat * type_nat()
Definition world.h:530
const Pi * fn(const Def *dom, Defs codom, bool implicit=false)
Definition world.h:314
Hole * mut_hole(const Def *type)
Definition world.h:264
const Axm * axm(const Def *type, plugin_t p, tag_t t, sub_t s)
Definition world.h:282
const Lam * lam(const Pi *pi, Lam::Filter f, const Def *body)
Definition world.h:325
void for_each(bool elide_empty, std::function< void(M *)> f)
Definition world.h:600
const Lam * fun(Defs dom, Defs codom, Lam::Filter f, const Def *body)
Definition world.h:337
Lam * mut_lam(const Def *dom, const Def *codom)
Definition world.h:340
const Def * gid2def(u32 gid)
Lookup Def by gid.
Definition world.cpp:703
Flags & flags()
Retrieve compile Flags.
Definition world.cpp:87
const Def * implicit_app(const Def *callee, const Def *arg)
Places Holes as demanded by Pi::is_implicit() and then apps arg.
Definition world.cpp:194
ScopedLoc push(Loc loc)
Definition world.h:121
const Def * implicit_app(const Def *callee, Defs args)
Definition world.h:559
void debug_dump()
Dump in Debug build if World::log::level is Log::Level::Debug.
Definition dump.cpp:493
u32 next_gid()
Definition world.h:96
const Def * extract(const Def *d, u64 i)
Definition world.h:437
Seq * mut_seq(bool term, const Def *type)
Definition world.h:393
const Lam * fun(const Def *dom, const Def *codom, Lam::Filter f, const Def *body)
Definition world.h:334
const Def * inj(const Def *type, const Def *value)
Definition world.cpp:587
const Def * call(Args &&... args)
Definition world.h:576
const auto & breakpoints()
Definition world.h:164
const Type * type()
Definition world.h:253
const Axm * axm(NormalizeFn n, u8 curry, u8 trip, const Def *type, plugin_t p, tag_t t, sub_t s)
Definition world.h:279
const Def * pack(Defs shape, const Def *body)
Definition world.h:410
const Def * seq(bool term, u64 n, const Def *body)
Definition world.h:396
void set(Sym name)
Definition world.h:91
const Def * app(const Def *callee, Defs args)
Definition world.h:368
const Def * pack(View< u64 > shape, const Def *body)
Definition world.h:414
Lam * mut_fun(Defs dom, Defs codom)
Definition world.h:347
const Lit * lit_i2(u8 val)
Definition world.h:483
const Def * extract(const Def *d, const Def *i)
Definition world.cpp:351
Pack * mut_pack(const Def *type)
Definition world.h:406
bool is_frozen() const
Definition world.h:140
const Lit * lit_idx_unsafe(u64 val)
Definition world.h:472
Loc get_loc() const
Definition world.h:119
const Lit * lit_nat_0()
Definition world.h:459
const Def * arr(const Def *arity, const Def *body)
Definition world.h:407
Sym sym(std::string_view)
Definition world.cpp:90
const Lit * lit_i16()
Definition world.h:466
Global * global(const Def *type, bool is_mutable=true)
Definition world.h:525
Lam * mut_lam(Defs dom, const Def *codom)
Definition world.h:341
const Lit * lit_ff()
Definition world.h:497
const Lit * lit_nat_max()
Definition world.h:461
const Def * raw_app(const Def *type, const Def *callee, Defs args)
Definition world.h:373
const Pi * pi(Defs dom, const Def *codom, bool implicit=false)
Definition world.h:298
const Def * bound(Defs ops)
Definition world.cpp:546
const Def * join(Defs ops)
Definition world.h:512
const Def * ext(const Def *type)
Definition world.cpp:536
Sym append_suffix(Sym name, std::string suffix)
Appends a suffix or an increasing number if the suffix already exists.
Definition world.cpp:643
const Proxy * proxy(const Def *type, Defs ops, u32 index, u32 tag)
Definition world.h:262
const Lit * lit_i32(u32 val)
Definition world.h:487
const Lit * lit_i8(u8 val)
Definition world.h:485
Lam * mut_lam(Defs dom, Defs codom)
Definition world.h:343
const Def * type_top()
Definition world.h:508
const Lit * lit_idx_1_0()
Definition world.h:462
Sigma * mut_sigma(size_t size)
A mutable Sigma of type level.
Definition world.h:381
const Lit * lit_univ(u64 level)
Definition world.h:455
const Pi * pi(Defs dom, Defs codom, bool implicit=false)
Definition world.h:300
const Def * var(Def *mut)
Definition world.cpp:180
const Tuple * tuple()
the unit value of type []
Definition world.h:428
const Type * type_infer_univ()
Definition world.h:251
const Def * call(Id id, Args &&... args)
Complete curried call of annexes obeying implicits.
Definition world.h:575
const Def * type_bool()
Definition world.h:541
const Def * uniq(const Def *inhabitant)
Definition world.cpp:638
const Def * raw_app(const Axm *axm, u8 curry, u8 trip, const Def *type, const Def *callee, const Def *arg)
Definition world.cpp:279
const Def * prod(bool term, Defs ops)
Definition world.h:418
const Externals & externals() const
Definition world.h:240
const Def * prod(bool term)
Definition world.h:419
const Def * umax(Defs)
Definition world.cpp:138
const Lam * con(const Def *dom, Lam::Filter f, const Def *body)
Definition world.h:328
const Def * type_i2()
Definition world.h:543
const Def * arr_unsafe(const Def *body)
Definition world.h:415
const Def * merge(const Def *type, Defs ops)
Definition world.cpp:569
const Lit * lit_i64(u64 val)
Definition world.h:488
const Def * type_i64()
Definition world.h:548
const Sigma * sigma()
The unit type within Type 0.
Definition world.h:385
const Lit * lit_nat(nat_t a)
Definition world.h:458
const State & state() const
Definition world.h:85
Hole * mut_hole_type()
Definition world.h:266
const Def * pack_unsafe(const Def *body)
Definition world.h:416
const auto & vars() const
Definition world.h:585
const Def * register_annex(flags_t f, const Def *)
Definition world.cpp:93
const Def * top(const Def *type)
Definition world.h:506
const Def * type_idx(const Def *size)
Definition world.h:533
Lam * mut_con(const Def *dom)
Definition world.h:338
Arr * mut_arr()
Definition world.h:401
auto & vars()
Definition world.h:583
Defs reduce(const Var *var, const Def *arg)
Yields the new body of [mut->var() -> arg]mut.
Definition world.cpp:663
const Lit * lit_int(nat_t width, u64 val)
Constructs a Lit of type Idx of size 2^width.
Definition world.h:481
const Lit * lit_bool(bool val)
Definition world.h:496
void breakpoint(u32 gid)
Trigger breakpoint in your debugger when creating a Def with this gid.
Definition world.cpp:700
const Def * select(const Def *cond, const Def *t, const Def *f)
Builds (f, t)#cond.
Definition world.h:441
Sigma * mut_sigma(const Def *type, size_t size)
Definition world.h:378
Hole * mut_hole_univ()
Definition world.h:265
Lam * mut_con(Defs dom)
Definition world.h:339
const Def * split(const Def *type, const Def *value)
Definition world.cpp:595
const Def * top_nat()
Definition world.h:509
const Pi * fn(const Def *dom, const Def *codom, bool implicit=false)
Definition world.h:312
const Rule * rule(const Reform *type, const Def *lhs, const Def *rhs, const Def *guard)
Definition world.h:355
auto annexes() const
Definition world.h:180
u32 curr_run() const
Manage run - used to track fixed-point iterations to compute Def::free_vars.
Definition world.h:99
Log & log() const
Definition world.cpp:86
World(World &&other) noexcept
Definition world.h:68
const Lit * lit_nat_1()
Definition world.h:460
const Pi * pi(const Def *dom, Defs codom, bool implicit=false)
Definition world.h:299
bool freeze(bool on=true) const
Yields old frozen state.
Definition world.h:143
const Def * type_i32()
Definition world.h:547
const Lit * lit_i4(u8 val)
Definition world.h:484
void dot(std::ostream &os, bool annexes=false, bool types=false) const
Dumps DOT to os.
Definition dot.cpp:146
const Def * insert(const Def *d, u64 i, const Def *val)
Definition world.h:449
const Pi * fn(Defs dom, Defs codom, bool implicit=false)
Definition world.h:315
Lam * mut_lam(const Pi *pi)
Definition world.h:326
const Def * annex()
Get Axm from a plugin.
Definition world.h:194
#define M(S, D)
Definition ast.h:14
View< const Def * > Defs
Definition def.h:76
u64 nat_t
Definition types.h:44
Vector< const Def * > DefVec
Definition def.h:77
u8 sub_t
Definition types.h:49
auto assert_emplace(C &container, Args &&... args)
Invokes emplace on container, asserts that insertion actually happened, and returns the iterator.
Definition util.h:118
u64 flags_t
Definition types.h:46
auto lookup(const C &container, const K &key)
Yields pointer to element (or the element itself if it is already a pointer), if found and nullptr ot...
Definition util.h:100
Span< const T, N > View
Definition span.h:98
void error(Loc loc, const char *f, Args &&... args)
Definition dbg.h:125
u64 level_t
Definition types.h:43
TExt< true > Top
Definition lattice.h:172
std::ostream & outln(const char *fmt, Args &&... args)
Definition print.h:200
const Def *(*)(const Def *, const Def *, const Def *) NormalizeFn
Definition def.h:100
u64 plugin_t
Definition types.h:47
uint32_t u32
Definition types.h:35
TExt< false > Bot
Definition lattice.h:171
uint64_t u64
Definition types.h:35
u8 tag_t
Definition types.h:48
uint8_t u8
Definition types.h:35
@ Nat
Definition def.h:114
@ Univ
Definition def.h:114
@ Idx
Definition def.h:114
@ Sigma
Definition def.h:114
@ Type
Definition def.h:114
@ Tuple
Definition def.h:114
@ Lit
Definition def.h:114
uint16_t u16
Definition types.h:35
Compiler switches that must be saved and looked up in later phases of compilation.
Definition flags.h:11
static constexpr plugin_t Global_Plugin
Definition plugin.h:59
static Sym demangle(Driver &, plugin_t plugin)
Reverts an Axm::mangled string to a Sym.
Definition plugin.cpp:37
static consteval flags_t base()
Definition plugin.h:119
Freezer(const World &world)
Definition world.h:151
const World & world
Definition world.h:156
ScopedLoc(World &world, Loc old_loc)
Definition world.h:109
absl::flat_hash_set< uint32_t > watchpoints
Definition world.h:49
friend void swap(State &s1, State &s2) noexcept
Definition world.h:51
struct mim::World::State::POD pod
absl::flat_hash_set< uint32_t > breakpoints
Definition world.h:48
Plain Old Data
Definition world.h:39