MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
stream.cpp
Go to the documentation of this file.
1#include <ostream>
2
3#include "mim/ast/ast.h"
4
5namespace mim::ast {
6
7using Tag = Tok::Tag;
8
9struct S {
10 S(fe::Tab& tab, const Node* node)
11 : tab(tab)
12 , node(node) {}
13
14 fe::Tab& tab;
15 const Node* node;
16
17 friend std::ostream& operator<<(std::ostream& os, const S& s) { return s.node->stream(s.tab, os), os; }
18};
19
20} // namespace mim::ast
21
22template<>
23struct std::formatter<mim::ast::S> : fe::ostream_formatter {};
24
25namespace mim::ast {
26
27template<class T>
28struct R {
29 R(fe::Tab& tab, const Ptrs<T>& range, std::string_view sep = ", ")
30 : tab(tab)
31 , range(range)
32 , sep(sep) {}
33
34 fe::Tab& tab;
35 const Ptrs<T>& range;
36 std::string_view sep;
37
38 friend std::ostream& operator<<(std::ostream& os, const R& r) {
39 for (std::string_view curr_sep{}; const auto& ptr : r.range) {
40 os << curr_sep;
41 ptr->stream(r.tab, os);
42 curr_sep = r.sep;
43 }
44 return os;
45 }
46};
47
48} // namespace mim::ast
49
50template<class T>
51struct std::formatter<mim::ast::R<T>> : fe::ostream_formatter {};
52
53namespace mim::ast {
54
55void Node::dump() const {
56 auto tab = fe::Tab::spaces();
57 stream(tab, std::cout);
58 std::cout << std::endl;
59}
60
61/*
62 * Module
63 */
64
65void Import::stream(fe::Tab& tab, std::ostream& os) const { std::println(os, "{}{} '{}';", tab, tag(), "TODO"); }
66
67void Module::stream(fe::Tab& tab, std::ostream& os) const {
68 for (const auto& import : imports())
69 import->stream(tab, os);
70 for (const auto& decl : decls())
71 std::println(os, "{}{}", tab, S(tab, decl.get()));
72}
73
74/*
75 * Ptrn
76 */
77
78void ErrorPtrn::stream(fe::Tab&, std::ostream& os) const { os << "<error pattern>"; }
79void AliasPtrn::stream(fe::Tab& tab, std::ostream& os) const { std::print(os, "{}: {}", S(tab, ptrn()), dbg()); }
80void GrpPtrn::stream(fe::Tab&, std::ostream& os) const { os << dbg(); }
81
82void IdPtrn::stream(fe::Tab& tab, std::ostream& os) const {
83 // clang-format off
84 if ( dbg() && type()) { std::print(os, "{}: {}", dbg(), S(tab, type())); return; }
85 if ( dbg() && !type()) { std::print(os, "{}", dbg()); return; }
86 if (!dbg() && type()) { std::print(os, "{}", S(tab, type())); return; }
87 // clang-format on
88 os << "<invalid identifier pattern>";
89}
90
91void TuplePtrn::stream(fe::Tab& tab, std::ostream& os) const {
92 std::print(os, "{}{}{}", delim_l(), R(tab, ptrns()), delim_r());
93}
94
95/*
96 * Expr
97 */
98
99void IdExpr::stream(fe::Tab&, std::ostream& os) const { std::print(os, "{}", dbg()); }
100void ErrorExpr::stream(fe::Tab&, std::ostream& os) const { os << "<error expression>"; }
101void HoleExpr::stream(fe::Tab&, std::ostream& os) const { os << "?"; }
102void PrimaryExpr::stream(fe::Tab&, std::ostream& os) const { std::print(os, "{}", tag()); }
103
104void LitExpr::stream(fe::Tab& tab, std::ostream& os) const {
105 switch (tag()) {
106 case Tag::L_i: std::print(os, "{}", tok().lit_i()); return;
107 case Tag::L_f: os << std::bit_cast<double>(tok().lit_u()); return;
108 case Tag::L_s:
109 case Tag::L_u:
110 os << tok().lit_u();
111 if (type()) std::print(os, ": {}", S(tab, type()));
112 return;
113 default: os << "TODO";
114 }
115}
116
117void DeclExpr::stream(fe::Tab& tab, std::ostream& os) const {
118 if (is_where()) {
119 std::println(os, "{}{} where", tab, S(tab, expr()));
120 ++tab;
121 for (const auto& decl : decls())
122 std::println(os, "{}{}", tab, S(tab, decl.get()));
123 --tab;
124 } else {
125 for (const auto& decl : decls())
126 std::println(os, "{}{}", tab, S(tab, decl.get()));
127 std::print(os, "{}", S(tab, expr()));
128 }
129}
130
131void TypeExpr::stream(fe::Tab& tab, std::ostream& os) const { std::print(os, "(Type {})", S(tab, level())); }
132void RuleExpr::stream(fe::Tab& tab, std::ostream& os) const { std::print(os, "(Rule {})", S(tab, dom())); }
133
134void ArrowExpr::stream(fe::Tab& tab, std::ostream& os) const {
135 std::print(os, "{} -> {}", S(tab, dom()), S(tab, codom()));
136}
137
138void UnionExpr::stream(fe::Tab& tab, std::ostream& os) const { std::print(os, "({})", R(tab, types(), "∪ ")); }
139
140void InjExpr::stream(fe::Tab& tab, std::ostream& os) const {
141 std::print(os, "{} inj {}", S(tab, value()), S(tab, type()));
142}
143
144void MatchExpr::Arm::stream(fe::Tab& tab, std::ostream& os) const {
145 std::print(os, "{} => {}", S(tab, ptrn()), S(tab, body()));
146}
147
148void MatchExpr::stream(fe::Tab& tab, std::ostream& os) const {
149 std::println(os, "{}match {} with", tab, S(tab, scrutinee()));
150 ++tab;
151 for (const auto& arm : arms())
152 std::println(os, "{}| {}", tab, S(tab, arm.get()));
153 --tab;
154 std::println(os, "{}}}", tab);
155}
156
157void PiExpr::Dom::stream(fe::Tab& tab, std::ostream& os) const {
158 std::print(os, "{}{}", is_implicit() ? "." : "", S(tab, ptrn()));
159 if (ret()) std::print(os, " -> {}", S(tab, ret()->type()));
160}
161
162void PiExpr::stream(fe::Tab& tab, std::ostream& os) const {
163 if (tag() != Tag::Nil) std::print(os, "{} ", tag());
164 std::print(os, "{}", S(tab, dom()));
165 if (codom()) std::print(os, " -> {}", S(tab, codom()));
166}
167
168void LamExpr::stream(fe::Tab& tab, std::ostream& os) const { std::print(os, "{};", S(tab, lam())); }
169
170void AppExpr::stream(fe::Tab& tab, std::ostream& os) const {
171 std::print(os, "{} {} {}", S(tab, callee()), is_explicit() ? "@" : "", S(tab, arg()));
172}
173
174void RetExpr::stream(fe::Tab& tab, std::ostream& os) const {
175 std::println(os, "ret {} = {} $ {};", S(tab, ptrn()), S(tab, callee()), S(tab, arg()));
176 std::print(os, "{}{}", tab, S(tab, body()));
177}
178
179void SigmaExpr::stream(fe::Tab& tab, std::ostream& os) const { ptrn()->stream(tab, os); }
180void TupleExpr::stream(fe::Tab& tab, std::ostream& os) const { std::print(os, "({})", R(tab, elems())); }
181
182void SeqExpr::stream(fe::Tab& tab, std::ostream& os) const {
183 std::print(os, "{}{}; {}{}", is_pack() ? "‹" : "«", S(tab, arity()), S(tab, body()), is_pack() ? "›" : "»");
184}
185
186void ExtractExpr::stream(fe::Tab& tab, std::ostream& os) const {
187 if (auto expr = std::get_if<Ptr<Expr>>(&index()))
188 std::print(os, "{}#{}", S(tab, tuple()), S(tab, expr->get()));
189 else
190 std::print(os, "{}#{}", S(tab, tuple()), std::get<Dbg>(index()));
191}
192
193void InsertExpr::stream(fe::Tab& tab, std::ostream& os) const {
194 std::print(os, "ins({}, {}, {})", S(tab, tuple()), S(tab, index()), S(tab, value()));
195}
196
197void UniqExpr::stream(fe::Tab& tab, std::ostream& os) const { std::print(os, "⦃{}⦄", S(tab, inhabitant())); }
198
199/*
200 * Decl
201 */
202
203void AxmDecl::Alias::stream(fe::Tab&, std::ostream& os) const { os << dbg(); }
204
205void AxmDecl::stream(fe::Tab& tab, std::ostream& os) const {
206 std::print(os, "axm {}", dbg());
207 if (num_subs() != 0) {
208 os << '(';
209 for (auto sep = ""; const auto& aliases : subs()) {
210 std::print(os, "{}{}", sep, R(tab, aliases, " = "));
211 sep = ", ";
212 }
213 os << ')';
214 }
215 std::print(os, ": {}", S(tab, type()));
216 if (normalizer()) std::print(os, ", {}", normalizer());
217 if (curry()) std::print(os, ", {}", curry());
218 if (trip()) std::print(os, ", {}", trip());
219 os << ";";
220}
221
222void LetDecl::stream(fe::Tab& tab, std::ostream& os) const {
223 std::print(os, "let {} = {};", S(tab, ptrn()), S(tab, value()));
224}
225
226void RecDecl::stream(fe::Tab& tab, std::ostream& os) const {
227 std::print(os, ".rec {}", dbg());
228 if (!type()->isa<HoleExpr>()) std::print(os, ": {}", S(tab, type()));
229 std::print(os, " = {};", S(tab, body()));
230}
231
232void LamDecl::Dom::stream(fe::Tab& tab, std::ostream& os) const {
233 std::print(os, "{}{}", is_implicit() ? "." : "", S(tab, ptrn()));
234 if (filter()) std::print(os, "@({})", S(tab, filter()));
235 if (ret()) std::print(os, ": {}", S(tab, ret()->type()));
236}
237
238void LamDecl::stream(fe::Tab& tab, std::ostream& os) const {
239 std::print(os, "{} {}", tag(), dbg());
240 if (!doms().front()->ptrn()->isa<TuplePtrn>()) os << ' ';
241 std::print(os, "{}", R(tab, doms()));
242 if (codom()) std::print(os, ": {}", S(tab, codom()));
243 if (body()) {
244 if (body()->isa<DeclExpr>()) {
245 os << " =" << std::endl;
246 ++tab;
247 std::print(os, "{}{}", tab, S(tab, body()));
248 --tab;
249 } else {
250 std::print(os, " = {}", S(tab, body()));
251 }
252 }
253 os << ';';
254}
255
256void CDecl::stream(fe::Tab& tab, std::ostream& os) const {
257 std::print(os, "{} {} {}", dbg(), tag(), S(tab, dom()), S(tab, codom()));
258 if (tag() == Tag::K_cfun) std::print(os, ": {}", S(tab, codom()));
259}
260
261void RuleDecl::stream(fe::Tab& tab, std::ostream& os) const {
262 std::print(os, "rule {} : {} => {} when {}", S(tab, var()), S(tab, lhs()), S(tab, rhs()), S(tab, guard()));
263}
264} // namespace mim::ast
Dbg dbg() const
Definition ast.h:272
const Ptrn * ptrn() const
Definition ast.h:271
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:79
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:170
bool is_explicit() const
Definition ast.h:666
const Expr * arg() const
Definition ast.h:668
const Expr * callee() const
Definition ast.h:667
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:134
Dbg dbg() const
Definition ast.h:879
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:203
const auto & subs() const
Definition ast.h:901
const Expr * type() const
Definition ast.h:904
Tok trip() const
Definition ast.h:907
size_t num_subs() const
Definition ast.h:902
Tok curry() const
Definition ast.h:906
Dbg normalizer() const
Definition ast.h:905
Dbg dbg() const
Definition ast.h:900
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:205
Tok::Tag tag() const
Definition ast.h:1036
const Ptrn * dom() const
Definition ast.h:1037
const Expr * codom() const
Definition ast.h:1038
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:256
Dbg dbg() const
Definition ast.h:1035
const Expr * expr() const
Definition ast.h:416
const auto & decls() const
Definition ast.h:414
bool is_where() const
Definition ast.h:415
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:117
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:100
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:78
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:186
const auto & index() const
Definition ast.h:788
const Expr * tuple() const
Definition ast.h:787
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:80
Dbg dbg() const
Definition ast.h:250
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:101
Dbg dbg() const
Definition ast.h:350
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:99
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:82
Dbg dbg() const
Definition ast.h:220
const Expr * type() const
Definition ast.h:221
Tok::Tag tag() const
Definition ast.h:1096
void stream(fe::Tab &, std::ostream &) const
Definition stream.cpp:65
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:140
const Expr * type() const
Definition ast.h:496
const Expr * value() const
Definition ast.h:495
const Expr * index() const
Definition ast.h:812
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:193
const Expr * tuple() const
Definition ast.h:811
const Expr * value() const
Definition ast.h:813
const Expr * filter() const
Definition ast.h:974
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:232
bool is_implicit() const
Definition ast.h:973
Tok::Tag tag() const
Definition ast.h:1003
const Ptrs< Dom > & doms() const
Definition ast.h:1005
const Expr * codom() const
Definition ast.h:1008
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:238
const LamDecl * lam() const
Definition ast.h:644
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:168
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:222
const Expr * value() const
Definition ast.h:857
const Ptrn * ptrn() const
Definition ast.h:856
Tok tok() const
Definition ast.h:391
const Expr * type() const
Definition ast.h:393
Tok::Tag tag() const
Definition ast.h:392
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:104
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:144
const Expr * body() const
Definition ast.h:521
const Ptrn * ptrn() const
Definition ast.h:520
const Expr * scrutinee() const
Definition ast.h:537
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:148
const Arm * arm(size_t i) const
Definition ast.h:539
const auto & arms() const
Definition ast.h:538
const auto & decls() const
Definition ast.h:1125
const auto & imports() const
Definition ast.h:1124
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:67
virtual void stream(fe::Tab &, std::ostream &) const =0
void dump() const
Definition stream.cpp:55
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:157
const IdPtrn * ret() const
Definition ast.h:593
bool is_implicit() const
Definition ast.h:591
const Ptrn * ptrn() const
Definition ast.h:592
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:162
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:102
Tok::Tag tag() const
Definition ast.h:372
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:226
Dbg dbg() const
Definition ast.h:934
const Expr * body() const
Definition ast.h:936
const Expr * type() const
Definition ast.h:935
const Ptrn * ptrn() const
Definition ast.h:691
const Expr * arg() const
Definition ast.h:693
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:174
const Expr * body() const
Definition ast.h:694
const Expr * callee() const
Definition ast.h:692
const Ptrn * var() const
Definition ast.h:1066
const Expr * guard() const
Definition ast.h:1069
const Expr * rhs() const
Definition ast.h:1068
const Expr * lhs() const
Definition ast.h:1067
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:261
const Expr * dom() const
Definition ast.h:454
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:132
bool is_pack() const
Definition ast.h:760
const Expr * body() const
Definition ast.h:762
const IdPtrn * arity() const
Definition ast.h:761
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:182
const TuplePtrn * ptrn() const
Definition ast.h:716
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:179
uint64_t lit_u() const
Definition tok.h:221
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:180
const auto & elems() const
Definition ast.h:738
Tok::Tag delim_r() const
Definition ast.h:294
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:91
const auto & ptrns() const
Definition ast.h:299
Tok::Tag delim_l() const
Definition ast.h:293
const Expr * level() const
Definition ast.h:436
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:131
const auto & types() const
Definition ast.h:474
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:138
const Expr * inhabitant() const
Definition ast.h:833
void stream(fe::Tab &, std::ostream &) const override
Definition stream.cpp:197
Definition ast.h:14
fe::Arena::Ptr< const T > Ptr
Definition ast.h:22
std::deque< Ptr< T > > Ptrs
Definition ast.h:24
Tok::Tag Tag
Definition bind.cpp:7
Definition ast.h:14
const Ptrs< T > & range
Definition stream.cpp:35
fe::Tab & tab
Definition stream.cpp:34
R(fe::Tab &tab, const Ptrs< T > &range, std::string_view sep=", ")
Definition stream.cpp:29
std::string_view sep
Definition stream.cpp:36
friend std::ostream & operator<<(std::ostream &os, const R &r)
Definition stream.cpp:38
fe::Tab & tab
Definition stream.cpp:14
friend std::ostream & operator<<(std::ostream &os, const S &s)
Definition stream.cpp:17
S(fe::Tab &tab, const Node *node)
Definition stream.cpp:10
const Node * node
Definition stream.cpp:15