MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
normalizers.cpp
Go to the documentation of this file.
1#include <fe/term.h>
2
3#include <mim/tuple.h>
4#include <mim/world.h>
5
7
8using namespace std::string_literals;
9
11
12static_assert(sizeof(void*) <= sizeof(u64), "pointer doesn't fit into Lit");
13
14namespace {
15
16// The trick is that we simply "box" the pointer of @p def inside a Lit of type `refly.Code`.
17const Def* do_reify(const Def* def) {
18 auto& world = def->world();
19 return world.lit(world.call<Code>(def->type()), reinterpret_cast<u64>(def));
20}
21
22void debug_print(const Def* lvl, const Def* def) {
23 auto& world = def->world();
24 auto level = fe::Log::Level::Debug;
25 if (auto l = Lit::isa(lvl)) {
26 level = std::to_underlying(fe::Log::Level::Error) <= int(*l)
27 && int(*l) <= std::to_underlying(fe::Log::Level::Debug)
28 ? static_cast<fe::Log::Level>(*l)
29 : fe::Log::Level::Debug;
30 }
31 world.log().log(level, "{}debug_print: {}{}", fe::term::FG::Yellow, def, fe::term::FG::Reset);
32 world.log().log(level, def->loc(), "def : {}", def);
33 world.log().log(level, def->loc(), "id : {}", def->unique_name());
34 world.log().log(level, def->type()->loc(), "type: {}", def->type());
35 world.log().log(level, def->loc(), "node: {}", def->node_name());
36 world.log().log(level, def->loc(), "ops : {}", def->num_ops());
37 world.log().log(level, def->loc(), "proj: {}", def->num_projs());
38 world.log().log(level, def->loc(), "eops: {}", def->num_deps());
39}
40
41} // namespace
42
43template<dbg id>
44const Def* normalize_dbg(const Def*, const Def*, const Def* arg) {
45 auto [lvl, x] = arg->projs<2>();
46 debug_print(lvl, x);
47 return id == dbg::perm ? nullptr : x;
48}
49
50const Def* normalize_reify(const Def*, const Def*, const Def* arg) { return do_reify(arg); }
51
52const Def* normalize_reflect(const Def*, const Def*, const Def* arg) {
53 if (auto l = Lit::isa(arg)) return reinterpret_cast<const Def*>(*l);
54 return {};
55}
56
57const Def* normalize_type(const Def*, const Def*, const Def* arg) { return arg->type(); }
58const Def* normalize_gid(const Def*, const Def*, const Def* arg) { return arg->world().lit_nat(arg->gid()); }
59
60template<struc id>
61const Def* normalize_struc(const Def*, const Def*, const Def* arg) {
62 auto [a, b] = arg->projs<2>();
63 auto res = a == b;
64 if (res ^ (id == struc::e)) arg->blame("'{}' and '{}' {}structural-equivalent", a, b, !res ? "not " : "").bail();
65 return a;
66}
67
68template<alpha id>
69const Def* normalize_alpha(const Def*, const Def*, const Def* arg) {
70 auto [a, b] = arg->projs<2>();
71 auto res = Check::test_alpha(a, b);
72 if (res ^ (id == alpha::e)) arg->blame("'{}' and '{}' {}alpha-equivalent", a, b, !res ? "not " : "").bail();
73 return a;
74}
75
76const Def* normalize_check_bot(const Def*, const Def* c, const Def* arg) {
77 if (!arg->isa<Bot>()) c->blame("'{}' is not bottom", arg).bail();
78 return arg;
79}
80
81const Def* normalize_check(const Def* type, const Def*, const Def* arg) {
82 auto& w = type->world();
83 auto [cond, val, msg] = arg->projs<3>();
84
85 if (cond == w.lit_tt()) return val;
86 if (cond == w.lit_ff()) {
87 auto s = tuple2str(msg);
88 if (s.empty()) s = "unknown error"s;
89 w.log().e("{}", s);
90 }
91
92 return nullptr;
93}
94
96
97} // namespace mim::plug::refly
static bool test_alpha(const Def *d1, const Def *d2)
Definition check.h:101
Base class for all Defs.
Definition def.h:289
size_t num_deps() const noexcept
Definition def.h:420
World & world() const noexcept
Definition def.h:1105
std::string_view node_name() const
Definition def.cpp:477
auto projs(Projector auto f) const
Splits this Def via Def::projections into an Array (if A == std::dynamic_extent) or std::array (other...
Definition def.h:457
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Definition def.h:1119
fe::Error & blame(fe::cite_string< Args... > s, Args &&... args) const
Reports an error that blames this; chain Error::n for Notes and Error::bail to throw.
Definition def.h:333
Loc loc() const
Definition def.h:632
nat_t num_projs() const
Yields Def::arity(), if it is a Lit, or 1 otherwise.
Definition def.h:1140
constexpr u32 gid() const noexcept
Global id - unique number for this Def.
Definition def.h:312
std::string unique_name() const
name + "_" + Def::gid
Definition def.cpp:634
constexpr size_t num_ops() const noexcept
Definition def.h:378
static std::optional< T > isa(const Def *def)
Definition def.h:976
const Lit * lit(const Def *type, u64 val)
Definition world.cpp:919
const fe::Log & log() const
Log via log().e("...", args) etc.; owned by the Driver.
Definition world.cpp:224
const Lit * lit_nat(nat_t a)
Definition world.h:563
The refly Plugin
const Def * normalize_reify(const Def *, const Def *, const Def *arg)
const Def * normalize_dbg(const Def *, const Def *, const Def *arg)
const Def * normalize_check(const Def *type, const Def *, const Def *arg)
const Def * normalize_check_bot(const Def *, const Def *c, const Def *arg)
const Def * normalize_gid(const Def *, const Def *, const Def *arg)
const Def * normalize_alpha(const Def *, const Def *, const Def *arg)
const Def * normalize_type(const Def *, const Def *, const Def *arg)
const Def * normalize_struc(const Def *, const Def *, const Def *arg)
const Def * normalize_reflect(const Def *, const Def *, const Def *arg)
std::string tuple2str(const Def *)
Definition tuple.cpp:115
TExt< false > Bot
Definition union.h:39
uint64_t u64
Definition types.h:27
#define MIM_refly_NORMALIZER_IMPL
Definition autogen.h:147