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, "{}{}", 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(), R(tab, doms()));
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
154/*
155 * Decl
156 */
157
158std::ostream& AxiomDecl::Alias::stream(Tab&, std::ostream& os) const { return os << dbg(); }
159
160std::ostream& AxiomDecl::stream(Tab& tab, std::ostream& os) const {
161 print(os, "axm {}", dbg());
162 if (num_subs() != 0) {
163 os << '(';
164 for (auto sep = ""; const auto& aliases : subs()) {
165 print(os, "{}{ = }", sep, R(tab, aliases));
166 sep = ", ";
167 }
168 os << ')';
169 }
170 print(os, ": {}", S(tab, type()));
171 if (normalizer()) print(os, ", {}", normalizer());
172 if (curry()) print(os, ", {}", curry());
173 if (trip()) print(os, ", {}", trip());
174 return os << ";";
175}
176
177std::ostream& LetDecl::stream(Tab& tab, std::ostream& os) const {
178 return print(os, "let {} = {};", S(tab, ptrn()), S(tab, value()));
179}
180
181std::ostream& RecDecl::stream(Tab& tab, std::ostream& os) const {
182 print(os, ".rec {}", dbg());
183 if (!type()->isa<InferExpr>()) print(os, ": {}", S(tab, type()));
184 return print(os, " = {};", S(tab, body()));
185}
186
187std::ostream& LamDecl::Dom::stream(Tab& tab, std::ostream& os) const {
188 print(os, "{}{}", implicit() ? "." : "", S(tab, ptrn()));
189 if (filter()) print(os, "@({})", S(tab, filter()));
190 if (ret()) print(os, ": {}", S(tab, ret()->type()));
191 return os;
192}
193
194std::ostream& LamDecl::stream(Tab& tab, std::ostream& os) const {
195 print(os, "{} {}", tag(), dbg());
196 if (!doms().front()->ptrn()->isa<TuplePtrn>()) os << ' ';
197 print(os, "{}", R(tab, doms()));
198 if (codom()) print(os, ": {}", S(tab, codom()));
199 if (body()) {
200 if (body()->isa<DeclExpr>()) {
201 os << " =" << std::endl;
202 (++tab).print(os, "{}", S(tab, body()));
203 --tab;
204 } else {
205 print(os, " = {}", S(tab, body()));
206 }
207 }
208 return os << ';';
209}
210
211std::ostream& CDecl::stream(Tab& tab, std::ostream& os) const {
212 print(os, "{} {} {}", dbg(), tag(), S(tab, dom()), S(tab, codom()));
213 if (tag() == Tag::K_cfun) print(os, ": {}", S(tab, codom()));
214 return os;
215}
216
217} // 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:158
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:160
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:211
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:945
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:187
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:194
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:124
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:177
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:974
const auto & imports() const
Definition ast.h:973
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
bool implicit() const
Definition ast.h:487
const IdPtrn * ret() const
Definition ast.h:489
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:181
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:159
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
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