MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
normalizers.cpp
Go to the documentation of this file.
1#include "mim/world.h"
2
3#include "mim/plug/ord/ord.h"
4
5#include "fe/assert.h"
6
7namespace mim::plug::ord {
8
9template<init id> const Def* normalize_init(const Def* type, const Def* callee, const Def* arg) {
10 auto& world = type->world();
11 return world.raw_app(type, callee, arg);
12}
13
14template<size> const Def* normalize_size(const Def*, const Def*, const Def* arg) {
15 if (auto init = Axm::isa<ord::init>(arg)) return init->decurry()->arg();
16 return nullptr;
17}
18
19const Def* normalize_get(const Def*, const Def*, const Def* arg) {
20 auto [map, k] = arg->projs<2>();
21
22 if (auto init = Axm::isa<ord::init>(map)) {
23 if (auto tuple = init->arg()->isa<Tuple>()) {
24 for (auto kv : tuple->ops())
25 if (kv->proj(2, 0) == k) return kv->proj(2, 1);
26 }
27 }
28
29 return nullptr;
30}
31
32template<contains id> const Def* normalize_contains(const Def*, const Def*, const Def* arg) {
33 auto& w = arg->world();
34 auto [c, k] = arg->projs<2>();
35
36 if (auto init = Axm::isa<ord::init>(c)) {
37 if (auto tuple = init->arg()->isa<Tuple>()) {
38 for (auto kv : tuple->ops()) {
39 auto key = id == contains::map ? kv->proj(2, 0) : kv;
40 if (key == k) return w.lit_tt();
41 }
42 return tuple->is_closed() ? w.lit_ff() : nullptr;
43 }
44
45 if (auto pack = init->arg()->isa_imm<Pack>()) w.WLOG("packs not yet implemented: {}", pack);
46 }
47
48 return nullptr;
49}
50
51template<insert id> const Def* normalize_insert(const Def* type, const Def*, const Def* arg) {
52 auto& w = type->world();
53 auto [ms, kv] = arg->projs<2>();
54
55 if (auto init = Axm::isa<ord::init>(ms)) {
56 if (auto tuple = init->arg()->isa<Tuple>()) {
57 auto n = init->decurry()->arg();
58 auto V = init->decurry()->decurry()->arg();
59 auto K = id == ord::insert::map ? init->decurry()->decurry()->decurry()->arg() : V;
60 if (auto l = Lit::isa(n)) {
61 auto new_ops = DefVec();
62 bool updated = false;
63 for (size_t i = 0, e = *l; i != e; ++i) {
64 auto key = id == ord::insert::map ? kv->proj(2, 0) : kv;
65 auto cur = tuple->proj(e, i);
66 if (id == ord::insert::map) cur = cur->proj(2, 0);
67 if (key == cur) {
68 updated = true;
69 new_ops.emplace_back(kv);
70 } else {
71 new_ops.emplace_back(tuple->proj(e, i));
72 }
73 }
74
75 if (!updated) new_ops.emplace_back(kv);
76
77 // return w.call(id, lt, Defs(new_ops));
79 auto new_n = w.lit_nat(new_ops.size());
80 auto app = w.app(w.annex(insert), K);
81 if (id == ord::insert::map) app = w.app(app, V);
82
83 return w.app(w.app(app, new_n), new_ops);
84 }
85 }
86
87 if (auto pack = init->arg()->isa_imm<Pack>()) w.WLOG("packs not yet implemented: {}", pack);
88 }
89
90 return {};
91}
92
94
95} // namespace mim::plug::ord
static auto isa(const Def *def)
Definition axm.h:104
Base class for all Defs.
Definition def.h:203
World & world() const noexcept
Definition def.cpp:376
auto projs(F f) const
Splits this Def via Def::projections into an Array (if A == std::dynamic_extent) or std::array (other...
Definition def.h:350
static std::optional< T > isa(const Def *def)
Definition def.h:733
A (possibly paramterized) Tuple.
Definition tuple.h:150
Data constructor for a Sigma.
Definition tuple.h:62
The ord Plugin
const Def * normalize_insert(const Def *type, const Def *, const Def *arg)
const Def * normalize_size(const Def *, const Def *, const Def *arg)
const Def * normalize_contains(const Def *, const Def *, const Def *arg)
const Def * normalize_get(const Def *, const Def *, const Def *arg)
const Def * normalize_init(const Def *type, const Def *callee, const Def *arg)
The tuple Plugin
Vector< const Def * > DefVec
Definition def.h:50
#define MIM_ord_NORMALIZER_IMPL
Definition autogen.h:119