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>"; }
54
55std::ostream& IdPtrn::stream(Tab& tab, std::ostream& os) const {
56 // clang-format off
57 if ( dbg() && type()) return print(os, "{}: {}", dbg(), S(tab, type()));
58 if ( dbg() && !type()) return print(os, "{}", dbg());
59 if (!dbg() && type()) return print(os, "{}", S(tab, type()));
60 // clang-format on
61 return os << "<invalid identifier pattern>";
62}
63
64std::ostream& GrpPtrn::stream(Tab&, std::ostream& os) const { return os << dbg(); }
65
66std::ostream& TuplePtrn::stream(Tab& tab, std::ostream& os) const {
67 print(os, "{}{, }{}", delim_l(), R(tab, ptrns()), delim_r());
68 if (dbg()) print(os, "::{}", dbg());
69 return os;
70}
71
72/*
73 * Expr
74 */
75
76std::ostream& IdExpr::stream(Tab&, std::ostream& os) const { return print(os, "{}", dbg()); }
77std::ostream& ErrorExpr::stream(Tab&, std::ostream& os) const { return os << "<error expression>"; }
78std::ostream& InferExpr::stream(Tab&, std::ostream& os) const { return os << "<infer>"; }
79std::ostream& PrimaryExpr::stream(Tab&, std::ostream& os) const { return print(os, "{}", tag()); }
80
81std::ostream& LitExpr::stream(Tab& tab, std::ostream& os) const {
82 switch (tag()) {
83 case Tag::L_i: return print(os, "{}", tok().lit_i());
84 case Tag::L_f: return os << std::bit_cast<double>(tok().lit_u());
85 case Tag::L_s:
86 case Tag::L_u:
87 os << tok().lit_u();
88 if (type()) print(os, ": {}", S(tab, type()));
89 break;
90 default: os << "TODO";
91 }
92 return os;
93}
94
95std::ostream& DeclExpr::stream(Tab& tab, std::ostream& os) const {
96 if (is_where()) {
97 tab.println(os, "{} .where", S(tab, expr()));
98 ++tab;
99 for (const auto& decl : decls()) tab.println(os, "{}", S(tab, decl.get()));
100 --tab;
101 return os;
102 } else {
103 for (const auto& decl : decls()) tab.println(os, "{}", S(tab, decl.get()));
104 return print(os, "{}", S(tab, expr()));
105 }
106}
107
108std::ostream& TypeExpr::stream(Tab& tab, std::ostream& os) const { return print(os, "(.Type {})", S(tab, level())); }
109
110std::ostream& ArrowExpr::stream(Tab& tab, std::ostream& os) const {
111 return print(os, "{} -> {}", S(tab, dom()), S(tab, codom()));
112}
113
114std::ostream& PiExpr::Dom::stream(Tab& tab, std::ostream& os) const {
115 print(os, "{}{}", is_implicit() ? "." : "", S(tab, ptrn()));
116 if (ret()) print(os, " -> {}", S(tab, ret()->type()));
117 return os;
118}
119
120std::ostream& PiExpr::stream(Tab& tab, std::ostream& os) const {
121 print(os, "{} {}", tag(), R(tab, doms()));
122 if (codom()) print(os, " -> {}", S(tab, codom()));
123 return os;
124}
125
126std::ostream& LamExpr::stream(Tab& tab, std::ostream& os) const { return print(os, "{};", S(tab, lam())); }
127
128std::ostream& AppExpr::stream(Tab& tab, std::ostream& os) const {
129 return print(os, "{} {} {}", S(tab, callee()), is_explicit() ? "@" : "", S(tab, arg()));
130}
131
132std::ostream& RetExpr::stream(Tab& tab, std::ostream& os) const {
133 println(os, ".ret {} = {} $ {};", S(tab, ptrn()), S(tab, callee()), S(tab, arg()));
134 return tab.print(os, "{}", S(tab, body()));
135}
136
137std::ostream& SigmaExpr::stream(Tab& tab, std::ostream& os) const { return ptrn()->stream(tab, os); }
138std::ostream& TupleExpr::stream(Tab& tab, std::ostream& os) const { return print(os, "({, })", R(tab, elems())); }
139
140template<bool arr> std::ostream& ArrOrPackExpr<arr>::stream(Tab& tab, std::ostream& os) const {
141 return print(os, "{}{}; {}{}", arr ? "«" : "‹", S(tab, shape()), S(tab, body()), arr ? "»" : "›");
142}
143
144template std::ostream& ArrOrPackExpr<true>::stream(Tab&, std::ostream&) const;
145template std::ostream& ArrOrPackExpr<false>::stream(Tab&, std::ostream&) const;
146
147std::ostream& ExtractExpr::stream(Tab& tab, std::ostream& os) const {
148 if (auto expr = std::get_if<Ptr<Expr>>(&index())) return print(os, "{}#{}", S(tab, tuple()), S(tab, expr->get()));
149 return print(os, "{}#{}", S(tab, tuple()), std::get<Dbg>(index()));
150}
151
152std::ostream& InsertExpr::stream(Tab& tab, std::ostream& os) const {
153 return print(os, ".ins({}, {}, {})", S(tab, tuple()), S(tab, index()), S(tab, value()));
154}
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, ".ax {}", 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
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:128
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:140
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:110
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:378
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:95
const auto & decls() const
Definition ast.h:376
bool is_where() const
Definition ast.h:377
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:77
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:53
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:147
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:64
Dbg dbg() const
Definition ast.h:312
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:76
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:55
const Expr * type() const
Definition ast.h:211
Tok::Tag tag() const
Definition ast.h:904
std::ostream & stream(Tab &, std::ostream &) const
Definition stream.cpp:41
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:78
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:152
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:126
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:179
Tok tok() const
Definition ast.h:353
const Expr * type() const
Definition ast.h:355
Tok::Tag tag() const
Definition ast.h:354
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:81
const auto & decls() const
Definition ast.h:933
const auto & imports() const
Definition ast.h:932
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:114
const IdPtrn * ret() const
Definition ast.h:448
bool is_implicit() const
Definition ast.h:446
const Ptrn * ptrn() const
Definition ast.h:447
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:120
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:79
Tok::Tag tag() const
Definition ast.h:334
Dbg dbg() const
Definition ast.h:178
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:183
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:132
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:137
uint64_t lit_u() const
Definition tok.h:177
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:138
Tok::Tag delim_r() const
Definition ast.h:256
const auto & ptrns() const
Definition ast.h:260
Tok::Tag delim_l() const
Definition ast.h:255
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:66
const Expr * level() const
Definition ast.h:398
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:108
Definition ast.h:13
fe::Arena::Ptr< const T > Ptr
Definition ast.h:20
std::deque< Ptr< T > > Ptrs
Definition ast.h:21
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