MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
normalizers.cpp
Go to the documentation of this file.
1#include <fe/assert.h>
2
3#include <mim/world.h>
4
6
7#include "mim/plug/ord/ord.h"
8
9namespace mim::plug::ord {
10
11template<init id>
12const Def* normalize_init(const Def* type, const Def* callee, const Def* arg) {
13 auto& world = type->world();
14 return world.raw_app(type, callee, arg);
15}
16
17template<size>
18const Def* normalize_size(const Def*, const Def*, const Def* arg) {
19 if (auto init = Axm::isa<ord::init>(arg)) return init->decurry()->arg();
20 return nullptr;
21}
22
23const Def* normalize_get(const Def*, const Def* callee, const Def* arg) {
24 auto& w = arg->world();
25 auto [map, k] = arg->projs<2>();
26 auto V = callee->as<App>()->arg();
27
28 if (auto init = Axm::isa<ord::init>(map)) {
29 if (auto tuple = init->arg()->isa<Tuple>()) {
30 for (auto kv : tuple->ops()) {
31 if (kv->proj(2, 0) == k) {
32 auto val = kv->proj(2, 1);
33 auto opt_V = w.call<option::Opt>(V);
34 return w.inj(opt_V, val);
35 }
36 }
37 if (tuple->is_closed()) {
38 auto opt_V = w.call<option::Opt>(V);
39 return w.inj(opt_V, w.tuple(Defs{}));
40 };
41 }
42 }
43
44 return nullptr;
45}
46
47template<contains id>
48const Def* normalize_contains(const Def*, const Def*, const Def* arg) {
49 auto& w = arg->world();
50 auto [c, k] = arg->projs<2>();
51
52 if (auto init = Axm::isa<ord::init>(c)) {
53 if (auto tuple = init->arg()->isa<Tuple>()) {
54 for (auto kv : tuple->ops()) {
55 auto key = id == contains::map ? kv->proj(2, 0) : kv;
56 if (key == k) return w.lit_tt();
57 }
58 return tuple->is_closed() ? w.lit_ff() : nullptr;
59 }
60
61 if (auto pack = init->arg()->isa_imm<Pack>()) w.log().w("Pack not yet implemented: {}", pack);
62 }
63
64 return nullptr;
65}
66
67template<insertion id>
68const Def* normalize_insert(const Def* type, const Def*, const Def* arg) {
69 auto& w = type->world();
70 auto [ms, kv] = arg->projs<2>();
71
72 if (auto init = Axm::isa<ord::init>(ms)) {
73 auto [K, V, n, arg] = init->uncurry_args<4>();
74 if (auto tuple = arg->isa<Tuple>()) {
75 K = K ? K : V;
76 if (auto l = Lit::isa(n)) {
77 auto new_ops = DefVec();
78 bool updated = false;
79 for (size_t i = 0, e = *l; i != e; ++i) {
80 auto key = id == ord::insertion::map ? kv->proj(2, 0) : kv;
81 auto cur = tuple->proj(e, i);
82 if (id == ord::insertion::map) cur = cur->proj(2, 0);
83 if (key == cur) {
84 updated = true;
85 new_ops.emplace_back(kv);
86 } else {
87 new_ops.emplace_back(tuple->proj(e, i));
88 }
89 }
90
91 if (!updated) new_ops.emplace_back(kv);
92
93 // return w.call(id, lt, Defs(new_ops));
95 auto new_n = w.lit_nat(new_ops.size());
96 auto app = w.app(w.annex(insert), K);
97 if (id == ord::insertion::map) app = w.app(app, V);
98
99 return w.app(w.app(app, new_n), new_ops);
100 }
101 }
102
103 if (auto pack = init->arg()->isa_imm<Pack>()) w.log().w("Pack not yet implemented: {}", pack);
104 }
105
106 return {};
107}
108
110
111} // namespace mim::plug::ord
static auto isa(const Def *def)
Definition axm.h:112
Base class for all Defs.
Definition def.h:273
World & world() const noexcept
Definition def.h:1097
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:440
static std::optional< T > isa(const Def *def)
Definition def.h:937
A (possibly paramterized) Tuple.
Definition tuple.h:137
Data constructor for a Sigma.
Definition tuple.h:61
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_get(const Def *, const Def *callee, const Def *arg)
const Def * normalize_contains(const Def *, const Def *, const Def *arg)
const Def * normalize_init(const Def *type, const Def *callee, const Def *arg)
The tuple Plugin
fe::View< const Def * > Defs
Definition def.h:91
fe::Vector< const Def * > DefVec
Definition def.h:93
#define MIM_ord_NORMALIZER_IMPL
Definition autogen.h:119