MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
check.h
Go to the documentation of this file.
1#pragma once
2
3#include "mim/def.h"
4
5namespace mim {
6
7/// This node is a hole in the IR that is inferred by its context later on.
8/// It is modelled as a *mut*able Def.
9/// If inference was successful, it's Infer::op will be set to the inferred Def.
10class Infer : public Def, public Setters<Infer> {
11private:
12 Infer(const Def* type)
13 : Def(Node, type, 1, 0) {}
14
15public:
16 using Setters<Infer>::set;
17
18 /// @name op
19 ///@{
20 const Def* op() const { return Def::op(0); }
21 Infer* set(const Def* op) { return Def::set(0, op)->as<Infer>(); }
22 Infer* reset(const Def* op) { return Def::reset(0, op)->as<Infer>(); }
23 Infer* unset() { return Def::unset()->as<Infer>(); }
24 ///@}
25
26 /// [Union-Find](https://en.wikipedia.org/wiki/Disjoint-set_data_structure) to unify Infer nodes.
27 /// Def::flags is used to keep track of rank for
28 /// [Union by rank](https://en.wikipedia.org/wiki/Disjoint-set_data_structure#Union_by_rank).
29 static const Def* find(const Def*);
30
31 Infer* stub(Ref type) { return stub_(world(), type)->set(dbg()); }
32 /// If unset, explode to Tuple.
33 /// @returns the new Tuple, or `this` if unsuccessful.
34 Ref tuplefy();
35
36 static constexpr auto Node = Node::Infer;
37
38private:
39 flags_t rank() const { return flags(); }
40 flags_t& rank() { return flags_; }
41
42 Ref rebuild_(World&, Ref, Defs) const override;
43 Infer* stub_(World&, Ref) override;
44
45 friend class World;
46 friend class Checker;
47};
48
49class Checker {
50public:
52 : world_(world) {}
53
54 World& world() { return world_; }
55
56 enum Mode {
57 /// In Mode::Check, type inference is happening and Infer%s will be resolved, if possible.
58 /// Also, two *free* but *different* Var%s **are** considered α-equivalent.
60 /// In Mode::Test, no type inference is happening and Infer%s will not be touched.
61 /// Also, Two *free* but *different* Var%s are **not** considered α-equivalent.
63 };
64
65 template<Mode mode> static bool alpha(Ref d1, Ref d2) { return Checker(d1->world()).alpha_<mode>(d1, d2); }
66
67 /// Can @p value be assigned to sth of @p type?
68 /// @note This is different from `equiv(type, value->type())` since @p type may be dependent.
69 [[nodiscard]] static Ref assignable(Ref type, Ref value) { return Checker(type->world()).assignable_(type, value); }
70
71 /// Yields `defs.front()`, if all @p defs are Check::alpha-equivalent (`Mode::Test`) and `nullptr` otherwise.
72 static Ref is_uniform(Defs defs);
73
74private:
75#ifdef MIM_ENABLE_CHECKS
76 template<Mode> bool fail();
77 Ref fail();
78#else
79 template<Mode> bool fail() { return false; }
80 Ref fail() { return {}; }
81#endif
82
83 template<Mode> bool alpha_(Ref d1, Ref d2);
84 template<Mode> bool alpha_internal(Ref, Ref);
85 [[nodiscard]] Ref assignable_(Ref type, Ref value);
86
87 World& world_;
88 MutMap<const Def*> binders_;
89};
90
91} // namespace mim
Checker(World &world)
Definition check.h:51
World & world()
Definition check.h:54
@ Test
In Mode::Test, no type inference is happening and Infers will not be touched.
Definition check.h:62
@ Check
In Mode::Check, type inference is happening and Infers will be resolved, if possible.
Definition check.h:59
static Ref is_uniform(Defs defs)
Yields defs.front(), if all defs are Check::alpha-equivalent (Mode::Test) and nullptr otherwise.
Definition check.cpp:226
static bool alpha(Ref d1, Ref d2)
Definition check.h:65
static Ref assignable(Ref type, Ref value)
Can value be assigned to sth of type?
Definition check.h:69
Base class for all Defs.
Definition def.h:226
Ref type() const
Definition def.h:251
Def * set(size_t i, Ref)
Successively set from left to right.
Definition def.cpp:256
World & world() const
Definition def.cpp:411
Ref op(size_t i) const
Definition def.h:272
Def * reset(size_t i, Ref def)
Successively reset from left to right.
Definition def.h:294
flags_t flags() const
Definition def.h:241
flags_t flags_
Definition def.h:593
Def * unset()
Unsets all Def::ops; works even, if not set at all or partially.
Definition def.cpp:281
Dbg dbg() const
Definition def.h:464
This node is a hole in the IR that is inferred by its context later on.
Definition check.h:10
Ref tuplefy()
If unset, explode to Tuple.
Definition check.cpp:47
Infer * stub_(World &, Ref) override
Definition def.cpp:132
Infer * stub(Ref type)
Definition check.h:31
static const Def * find(const Def *)
Union-Find to unify Infer nodes.
Definition check.cpp:31
static constexpr auto Node
Definition check.h:36
friend class World
Definition check.h:45
const Def * op() const
Definition check.h:20
Infer * reset(const Def *op)
Definition check.h:22
Infer * unset()
Definition check.h:23
Infer * set(const Def *op)
Definition check.h:21
Ref rebuild_(World &, Ref, Defs) const override
Definition def.cpp:91
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:189
This is a thin wrapper for std::span<T, N> with the following additional features:
Definition span.h:28
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:33
@ Infer
Definition def.h:40
Definition cfg.h:11
View< const Def * > Defs
Definition def.h:61
u64 flags_t
Definition types.h:45
GIDMap< Def *, To > MutMap
Definition def.h:68