MimIR 0.1
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#include "mim/util/print.h"
5
6namespace mim::ast {
7
8using Tag = Tok::Tag;
9
10struct S {
11 S(Tab& tab, const Node* node)
12 : tab(tab)
13 , node(node) {}
14
16 const Node* node;
17
18 friend std::ostream& operator<<(std::ostream& os, const S& s) { return s.node->stream(s.tab, os); }
19};
20
21template<class T> struct R {
22 R(Tab& tab, const Ptrs<T>& range)
23 : tab(tab)
24 , range(range)
25 , f([&tab](std::ostream& os, const Ptr<T>& ptr) { ptr->stream(tab, os); }) {}
26
28 const Ptrs<T>& range;
29 std::function<void(std::ostream&, const Ptr<T>&)> f;
30};
31
32void Node::dump() const {
33 Tab tab;
34 stream(tab, std::cout) << std::endl;
35}
36
37/*
38 * Module
39 */
40
41std::ostream& Import::stream(Tab& tab, std::ostream& os) const { return tab.println(os, "{} '{}';", tag(), "TODO"); }
42
43std::ostream& Module::stream(Tab& tab, std::ostream& os) const {
44 for (const auto& import : imports()) import->stream(tab, os);
45 for (const auto& decl : decls()) tab.println(os, "{}", S(tab, decl.get()));
46 return os;
47}
48
49/*
50 * Ptrn
51 */
52
53std::ostream& ErrorPtrn::stream(Tab&, std::ostream& os) const { return os << "<error pattern>"; }
54std::ostream& AliasPtrn::stream(Tab& tab, std::ostream& os) const { return print(os, "{}: {}", S(tab, ptrn()), dbg()); }
55std::ostream& GrpPtrn::stream(Tab&, std::ostream& os) const { return os << dbg(); }
56
57std::ostream& IdPtrn::stream(Tab& tab, std::ostream& os) const {
58 // clang-format off
59 if ( dbg() && type()) return print(os, "{}: {}", dbg(), S(tab, type()));
60 if ( dbg() && !type()) return print(os, "{}", dbg());
61 if (!dbg() && type()) return print(os, "{}", S(tab, type()));
62 // clang-format on
63 return os << "<invalid identifier pattern>";
64}
65
66std::ostream& TuplePtrn::stream(Tab& tab, std::ostream& os) const {
67 return print(os, "{}{, }{}", delim_l(), R(tab, ptrns()), delim_r());
68}
69
70/*
71 * Expr
72 */
73
74std::ostream& IdExpr::stream(Tab&, std::ostream& os) const { return print(os, "{}", dbg()); }
75std::ostream& ErrorExpr::stream(Tab&, std::ostream& os) const { return os << "<error expression>"; }
76std::ostream& InferExpr::stream(Tab&, std::ostream& os) const { return os << "<infer>"; }
77std::ostream& PrimaryExpr::stream(Tab&, std::ostream& os) const { return print(os, "{}", tag()); }
78
79std::ostream& LitExpr::stream(Tab& tab, std::ostream& os) const {
80 switch (tag()) {
81 case Tag::L_i: return print(os, "{}", tok().lit_i());
82 case Tag::L_f: return os << std::bit_cast<double>(tok().lit_u());
83 case Tag::L_s:
84 case Tag::L_u:
85 os << tok().lit_u();
86 if (type()) print(os, ": {}", S(tab, type()));
87 break;
88 default: os << "TODO";
89 }
90 return os;
91}
92
93std::ostream& DeclExpr::stream(Tab& tab, std::ostream& os) const {
94 if (is_where()) {
95 tab.println(os, "{} where", S(tab, expr()));
96 ++tab;
97 for (const auto& decl : decls()) tab.println(os, "{}", S(tab, decl.get()));
98 --tab;
99 return os;
100 } else {
101 for (const auto& decl : decls()) tab.println(os, "{}", S(tab, decl.get()));
102 return print(os, "{}", S(tab, expr()));
103 }
104}
105
106std::ostream& TypeExpr::stream(Tab& tab, std::ostream& os) const { return print(os, "(Type {})", S(tab, level())); }
107
108std::ostream& ArrowExpr::stream(Tab& tab, std::ostream& os) const {
109 return print(os, "{} -> {}", S(tab, dom()), S(tab, codom()));
110}
111
112std::ostream& PiExpr::Dom::stream(Tab& tab, std::ostream& os) const {
113 print(os, "{}{}", is_implicit() ? "." : "", S(tab, ptrn()));
114 if (ret()) print(os, " -> {}", S(tab, ret()->type()));
115 return os;
116}
117
118std::ostream& PiExpr::stream(Tab& tab, std::ostream& os) const {
119 print(os, "{} {}", tag(), S(tab, dom()));
120 if (codom()) print(os, " -> {}", S(tab, codom()));
121 return os;
122}
123
124std::ostream& LamExpr::stream(Tab& tab, std::ostream& os) const { return print(os, "{};", S(tab, lam())); }
125
126std::ostream& AppExpr::stream(Tab& tab, std::ostream& os) const {
127 return print(os, "{} {} {}", S(tab, callee()), is_explicit() ? "@" : "", S(tab, arg()));
128}
129
130std::ostream& RetExpr::stream(Tab& tab, std::ostream& os) const {
131 println(os, "ret {} = {} $ {};", S(tab, ptrn()), S(tab, callee()), S(tab, arg()));
132 return tab.print(os, "{}", S(tab, body()));
133}
134
135std::ostream& SigmaExpr::stream(Tab& tab, std::ostream& os) const { return ptrn()->stream(tab, os); }
136std::ostream& TupleExpr::stream(Tab& tab, std::ostream& os) const { return print(os, "({, })", R(tab, elems())); }
137
138template<bool arr> std::ostream& ArrOrPackExpr<arr>::stream(Tab& tab, std::ostream& os) const {
139 return print(os, "{}{}; {}{}", arr ? "«" : "‹", S(tab, shape()), S(tab, body()), arr ? "»" : "›");
140}
141
142template std::ostream& ArrOrPackExpr<true>::stream(Tab&, std::ostream&) const;
143template std::ostream& ArrOrPackExpr<false>::stream(Tab&, std::ostream&) const;
144
145std::ostream& ExtractExpr::stream(Tab& tab, std::ostream& os) const {
146 if (auto expr = std::get_if<Ptr<Expr>>(&index())) return print(os, "{}#{}", S(tab, tuple()), S(tab, expr->get()));
147 return print(os, "{}#{}", S(tab, tuple()), std::get<Dbg>(index()));
148}
149
150std::ostream& InsertExpr::stream(Tab& tab, std::ostream& os) const {
151 return print(os, "ins({}, {}, {})", S(tab, tuple()), S(tab, index()), S(tab, value()));
152}
153
154std::ostream& UniqExpr::stream(Tab& tab, std::ostream& os) const { return print(os, "⦃{}⦄", S(tab, inhabitant())); }
155
156/*
157 * Decl
158 */
159
160std::ostream& AxiomDecl::Alias::stream(Tab&, std::ostream& os) const { return os << dbg(); }
161
162std::ostream& AxiomDecl::stream(Tab& tab, std::ostream& os) const {
163 print(os, "axm {}", dbg());
164 if (num_subs() != 0) {
165 os << '(';
166 for (auto sep = ""; const auto& aliases : subs()) {
167 print(os, "{}{ = }", sep, R(tab, aliases));
168 sep = ", ";
169 }
170 os << ')';
171 }
172 print(os, ": {}", S(tab, type()));
173 if (normalizer()) print(os, ", {}", normalizer());
174 if (curry()) print(os, ", {}", curry());
175 if (trip()) print(os, ", {}", trip());
176 return os << ";";
177}
178
179std::ostream& LetDecl::stream(Tab& tab, std::ostream& os) const {
180 return print(os, "let {} = {};", S(tab, ptrn()), S(tab, value()));
181}
182
183std::ostream& RecDecl::stream(Tab& tab, std::ostream& os) const {
184 print(os, ".rec {}", dbg());
185 if (!type()->isa<InferExpr>()) print(os, ": {}", S(tab, type()));
186 return print(os, " = {};", S(tab, body()));
187}
188
189std::ostream& LamDecl::Dom::stream(Tab& tab, std::ostream& os) const {
190 print(os, "{}{}", is_implicit() ? "." : "", S(tab, ptrn()));
191 if (filter()) print(os, "@({})", S(tab, filter()));
192 if (ret()) print(os, ": {}", S(tab, ret()->type()));
193 return os;
194}
195
196std::ostream& LamDecl::stream(Tab& tab, std::ostream& os) const {
197 print(os, "{} {}", tag(), dbg());
198 if (!doms().front()->ptrn()->isa<TuplePtrn>()) os << ' ';
199 print(os, "{}", R(tab, doms()));
200 if (codom()) print(os, ": {}", S(tab, codom()));
201 if (body()) {
202 if (body()->isa<DeclExpr>()) {
203 os << " =" << std::endl;
204 (++tab).print(os, "{}", S(tab, body()));
205 --tab;
206 } else {
207 print(os, " = {}", S(tab, body()));
208 }
209 }
210 return os << ';';
211}
212
213std::ostream& CDecl::stream(Tab& tab, std::ostream& os) const {
214 print(os, "{} {} {}", dbg(), tag(), S(tab, dom()), S(tab, codom()));
215 if (tag() == Tag::K_cfun) print(os, ": {}", S(tab, codom()));
216 return os;
217}
218
219} // namespace mim::ast
Keeps track of indentation level.
Definition print.h:195
std::ostream & println(std::ostream &os, const char *s, Args &&... args)
Same as Tab::print but appends a std::endl to os.
Definition print.h:220
std::ostream & print(std::ostream &os, const char *s, Args &&... args)
Definition print.h:211
Dbg dbg() const
Definition ast.h:273
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:54
const Ptrn * ptrn() const
Definition ast.h:272
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:126
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:138
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:108
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:160
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:162
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:213
const Expr * expr() const
Definition ast.h:417
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:93
const auto & decls() const
Definition ast.h:415
bool is_where() const
Definition ast.h:416
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:75
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:53
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:145
Dbg dbg() const
Definition ast.h:251
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:55
Dbg dbg() const
Definition ast.h:351
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:74
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:57
Dbg dbg() const
Definition ast.h:221
const Expr * type() const
Definition ast.h:222
Tok::Tag tag() const
Definition ast.h:959
std::ostream & stream(Tab &, std::ostream &) const
Definition stream.cpp:41
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:76
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:150
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:189
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:196
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:124
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:179
Tok tok() const
Definition ast.h:392
const Expr * type() const
Definition ast.h:394
Tok::Tag tag() const
Definition ast.h:393
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:79
const auto & decls() const
Definition ast.h:988
const auto & imports() const
Definition ast.h:987
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:43
virtual std::ostream & stream(Tab &, std::ostream &) const =0
void dump() const
Definition stream.cpp:32
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:112
const IdPtrn * ret() const
Definition ast.h:489
bool is_implicit() const
Definition ast.h:487
const Ptrn * ptrn() const
Definition ast.h:488
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:118
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:77
Tok::Tag tag() const
Definition ast.h:373
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:183
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:130
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:135
uint64_t lit_u() const
Definition tok.h:161
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:136
Tok::Tag delim_r() const
Definition ast.h:295
const auto & ptrns() const
Definition ast.h:300
Tok::Tag delim_l() const
Definition ast.h:294
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:66
const Expr * level() const
Definition ast.h:437
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:106
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:154
Definition ast.h:14
fe::Arena::Ptr< const T > Ptr
Definition ast.h:21
std::deque< Ptr< T > > Ptrs
Definition ast.h:22
std::ostream & print(std::ostream &os, const char *s)
Base case.
Definition print.cpp:5
std::ostream & println(std::ostream &os, const char *fmt, Args &&... args)
As above but end with std::endl.
Definition print.h:150
Definition span.h:104
constexpr decltype(auto) get(mim::Span< T, N > span)
Definition span.h:113
const Ptrs< T > & range
Definition stream.cpp:28
std::function< void(std::ostream &, const Ptr< T > &)> f
Definition stream.cpp:29
R(Tab &tab, const Ptrs< T > &range)
Definition stream.cpp:22
Tab & tab
Definition stream.cpp:27
S(Tab &tab, const Node *node)
Definition stream.cpp:11
friend std::ostream & operator<<(std::ostream &os, const S &s)
Definition stream.cpp:18
const Node * node
Definition stream.cpp:16
Tab & tab
Definition stream.cpp:15