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>
10const Def* normalize_init(const Def* type, const Def* callee, const Def* arg) {
11 auto& world = type->world();
12 return world.raw_app(type, callee, arg);
13}
14
15template<size>
16const Def* normalize_size(const Def*, const Def*, const Def* arg) {
17 if (auto init = Axm::isa<ord::init>(arg)) return init->decurry()->arg();
18 return nullptr;
19}
20
21const Def* normalize_get(const Def*, const Def*, const Def* arg) {
22 auto [map, k] = arg->projs<2>();
23
24 if (auto init = Axm::isa<ord::init>(map)) {
25 if (auto tuple = init->arg()->isa<Tuple>()) {
26 for (auto kv : tuple->ops())
27 if (kv->proj(2, 0) == k) return kv->proj(2, 1);
28 }
29 }
30
31 return nullptr;
32}
33
34template<contains id>
35const Def* normalize_contains(const Def*, const Def*, const Def* arg) {
36 auto& w = arg->world();
37 auto [c, k] = arg->projs<2>();
38
39 if (auto init = Axm::isa<ord::init>(c)) {
40 if (auto tuple = init->arg()->isa<Tuple>()) {
41 for (auto kv : tuple->ops()) {
42 auto key = id == contains::map ? kv->proj(2, 0) : kv;
43 if (key == k) return w.lit_tt();
44 }
45 return tuple->is_closed() ? w.lit_ff() : nullptr;
46 }
47
48 if (auto pack = init->arg()->isa_imm<Pack>()) w.WLOG("packs not yet implemented: {}", pack);
49 }
50
51 return nullptr;
52}
53
54template<insert id>
55const Def* normalize_insert(const Def* type, const Def*, const Def* arg) {
56 auto& w = type->world();
57 auto [ms, kv] = arg->projs<2>();
58
59 if (auto init = Axm::isa<ord::init>(ms)) {
60 auto [K, V, n, arg] = init->uncurry_args<4>();
61 if (auto tuple = arg->isa<Tuple>()) {
62 K = K ? K : V;
63 if (auto l = Lit::isa(n)) {
64 auto new_ops = DefVec();
65 bool updated = false;
66 for (size_t i = 0, e = *l; i != e; ++i) {
67 auto key = id == ord::insert::map ? kv->proj(2, 0) : kv;
68 auto cur = tuple->proj(e, i);
69 if (id == ord::insert::map) cur = cur->proj(2, 0);
70 if (key == cur) {
71 updated = true;
72 new_ops.emplace_back(kv);
73 } else {
74 new_ops.emplace_back(tuple->proj(e, i));
75 }
76 }
77
78 if (!updated) new_ops.emplace_back(kv);
79
80 // return w.call(id, lt, Defs(new_ops));
82 auto new_n = w.lit_nat(new_ops.size());
83 auto app = w.app(w.annex(insert), K);
84 if (id == ord::insert::map) app = w.app(app, V);
85
86 return w.app(w.app(app, new_n), new_ops);
87 }
88 }
89
90 if (auto pack = init->arg()->isa_imm<Pack>()) w.WLOG("packs not yet implemented: {}", pack);
91 }
92
93 return {};
94}
95
97
98} // namespace mim::plug::ord
static auto isa(const Def *def)
Definition axm.h:107
Base class for all Defs.
Definition def.h:251
World & world() const noexcept
Definition def.cpp:436
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:390
static std::optional< T > isa(const Def *def)
Definition def.h:810
A (possibly paramterized) Tuple.
Definition tuple.h:166
Data constructor for a Sigma.
Definition tuple.h:68
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:77
#define MIM_ord_NORMALIZER_IMPL
Definition autogen.h:119