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