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& HoleExpr::stream(Tab&, std::ostream& os) const { return os << "?"; }
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& UnionExpr::stream(Tab& tab, std::ostream& os) const { return print(os, "({∪ })", R(tab, types())); }
113
114std::ostream& InjExpr::stream(Tab& tab, std::ostream& os) const {
115 return print(os, "{} inj {}", S(tab, value()), S(tab, type()));
116}
117
118std::ostream& MatchExpr::Arm::stream(Tab& tab, std::ostream& os) const {
119 return print(os, "{} => {}", S(tab, ptrn()), S(tab, body()));
120}
121
122std::ostream& MatchExpr::stream(Tab& tab, std::ostream& os) const {
123 tab.println(os, "match {} {{", S(tab, scrutinee()));
124 ++tab;
125 for (const auto& arm : arms()) tab.println(os, "{},", S(tab, arm.get()));
126 --tab;
127 return tab.println(os, "}}");
128}
129
130std::ostream& PiExpr::Dom::stream(Tab& tab, std::ostream& os) const {
131 print(os, "{}{}", is_implicit() ? "." : "", S(tab, ptrn()));
132 if (ret()) print(os, " -> {}", S(tab, ret()->type()));
133 return os;
134}
135
136std::ostream& PiExpr::stream(Tab& tab, std::ostream& os) const {
137 print(os, "{} {}", tag(), S(tab, dom()));
138 if (codom()) print(os, " -> {}", S(tab, codom()));
139 return os;
140}
141
142std::ostream& LamExpr::stream(Tab& tab, std::ostream& os) const { return print(os, "{};", S(tab, lam())); }
143
144std::ostream& AppExpr::stream(Tab& tab, std::ostream& os) const {
145 return print(os, "{} {} {}", S(tab, callee()), is_explicit() ? "@" : "", S(tab, arg()));
146}
147
148std::ostream& RetExpr::stream(Tab& tab, std::ostream& os) const {
149 println(os, "ret {} = {} $ {};", S(tab, ptrn()), S(tab, callee()), S(tab, arg()));
150 return tab.print(os, "{}", S(tab, body()));
151}
152
153std::ostream& SigmaExpr::stream(Tab& tab, std::ostream& os) const { return ptrn()->stream(tab, os); }
154std::ostream& TupleExpr::stream(Tab& tab, std::ostream& os) const { return print(os, "({, })", R(tab, elems())); }
155
156std::ostream& SeqExpr::stream(Tab& tab, std::ostream& os) const {
157 return print(os, "{}{}; {}{}", is_arr() ? "«" : "‹", S(tab, shape()), S(tab, body()), is_arr() ? "»" : "›");
158}
159
160std::ostream& ExtractExpr::stream(Tab& tab, std::ostream& os) const {
161 if (auto expr = std::get_if<Ptr<Expr>>(&index())) return print(os, "{}#{}", S(tab, tuple()), S(tab, expr->get()));
162 return print(os, "{}#{}", S(tab, tuple()), std::get<Dbg>(index()));
163}
164
165std::ostream& InsertExpr::stream(Tab& tab, std::ostream& os) const {
166 return print(os, "ins({}, {}, {})", S(tab, tuple()), S(tab, index()), S(tab, value()));
167}
168
169std::ostream& UniqExpr::stream(Tab& tab, std::ostream& os) const { return print(os, "⦃{}⦄", S(tab, inhabitant())); }
170
171/*
172 * Decl
173 */
174
175std::ostream& AxmDecl::Alias::stream(Tab&, std::ostream& os) const { return os << dbg(); }
176
177std::ostream& AxmDecl::stream(Tab& tab, std::ostream& os) const {
178 print(os, "axm {}", dbg());
179 if (num_subs() != 0) {
180 os << '(';
181 for (auto sep = ""; const auto& aliases : subs()) {
182 print(os, "{}{ = }", sep, R(tab, aliases));
183 sep = ", ";
184 }
185 os << ')';
186 }
187 print(os, ": {}", S(tab, type()));
188 if (normalizer()) print(os, ", {}", normalizer());
189 if (curry()) print(os, ", {}", curry());
190 if (trip()) print(os, ", {}", trip());
191 return os << ";";
192}
193
194std::ostream& LetDecl::stream(Tab& tab, std::ostream& os) const {
195 return print(os, "let {} = {};", S(tab, ptrn()), S(tab, value()));
196}
197
198std::ostream& RecDecl::stream(Tab& tab, std::ostream& os) const {
199 print(os, ".rec {}", dbg());
200 if (!type()->isa<HoleExpr>()) print(os, ": {}", S(tab, type()));
201 return print(os, " = {};", S(tab, body()));
202}
203
204std::ostream& LamDecl::Dom::stream(Tab& tab, std::ostream& os) const {
205 print(os, "{}{}", is_implicit() ? "." : "", S(tab, ptrn()));
206 if (filter()) print(os, "@({})", S(tab, filter()));
207 if (ret()) print(os, ": {}", S(tab, ret()->type()));
208 return os;
209}
210
211std::ostream& LamDecl::stream(Tab& tab, std::ostream& os) const {
212 print(os, "{} {}", tag(), dbg());
213 if (!doms().front()->ptrn()->isa<TuplePtrn>()) os << ' ';
214 print(os, "{}", R(tab, doms()));
215 if (codom()) print(os, ": {}", S(tab, codom()));
216 if (body()) {
217 if (body()->isa<DeclExpr>()) {
218 os << " =" << std::endl;
219 (++tab).print(os, "{}", S(tab, body()));
220 --tab;
221 } else {
222 print(os, " = {}", S(tab, body()));
223 }
224 }
225 return os << ';';
226}
227
228std::ostream& CDecl::stream(Tab& tab, std::ostream& os) const {
229 print(os, "{} {} {}", dbg(), tag(), S(tab, dom()), S(tab, codom()));
230 if (tag() == Tag::K_cfun) print(os, ": {}", S(tab, codom()));
231 return os;
232}
233
234} // namespace mim::ast
Keeps track of indentation level.
Definition print.h:196
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:221
std::ostream & print(std::ostream &os, const char *s, Args &&... args)
Definition print.h:212
Dbg dbg() const
Definition ast.h:275
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:54
const Ptrn * ptrn() const
Definition ast.h:274
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:144
bool is_explicit() const
Definition ast.h:657
const Expr * arg() const
Definition ast.h:659
const Expr * callee() const
Definition ast.h:658
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:108
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:175
Dbg dbg() const
Definition ast.h:870
const auto & subs() const
Definition ast.h:892
const Expr * type() const
Definition ast.h:895
Tok trip() const
Definition ast.h:898
size_t num_subs() const
Definition ast.h:893
Tok curry() const
Definition ast.h:897
Dbg normalizer() const
Definition ast.h:896
Dbg dbg() const
Definition ast.h:891
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:177
Tok::Tag tag() const
Definition ast.h:1026
const Ptrn * dom() const
Definition ast.h:1027
const Expr * codom() const
Definition ast.h:1028
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:228
Dbg dbg() const
Definition ast.h:1025
const Expr * expr() const
Definition ast.h:419
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:93
const auto & decls() const
Definition ast.h:417
bool is_where() const
Definition ast.h:418
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:160
const auto & index() const
Definition ast.h:779
const Expr * tuple() const
Definition ast.h:778
Dbg dbg() const
Definition ast.h:253
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:55
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:76
Dbg dbg() const
Definition ast.h:353
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:223
const Expr * type() const
Definition ast.h:224
Tok::Tag tag() const
Definition ast.h:1054
std::ostream & stream(Tab &, std::ostream &) const
Definition stream.cpp:41
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:114
const Expr * type() const
Definition ast.h:481
const Expr * value() const
Definition ast.h:480
const Expr * index() const
Definition ast.h:803
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:165
const Expr * tuple() const
Definition ast.h:802
const Expr * value() const
Definition ast.h:804
const Expr * filter() const
Definition ast.h:964
bool is_implicit() const
Definition ast.h:963
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:204
Tok::Tag tag() const
Definition ast.h:993
const Ptrs< Dom > & doms() const
Definition ast.h:995
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:211
const Expr * codom() const
Definition ast.h:998
const LamDecl * lam() const
Definition ast.h:635
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:142
const Expr * value() const
Definition ast.h:848
const Ptrn * ptrn() const
Definition ast.h:847
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:194
Tok tok() const
Definition ast.h:394
const Expr * type() const
Definition ast.h:396
Tok::Tag tag() const
Definition ast.h:395
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:79
const Expr * body() const
Definition ast.h:506
const Ptrn * ptrn() const
Definition ast.h:505
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:118
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:122
const Expr * scrutinee() const
Definition ast.h:522
const Arm * arm(size_t i) const
Definition ast.h:524
const auto & arms() const
Definition ast.h:523
const auto & decls() const
Definition ast.h:1083
const auto & imports() const
Definition ast.h:1082
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:130
const IdPtrn * ret() const
Definition ast.h:578
bool is_implicit() const
Definition ast.h:576
const Ptrn * ptrn() const
Definition ast.h:577
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:136
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:77
Tok::Tag tag() const
Definition ast.h:375
Dbg dbg() const
Definition ast.h:924
const Expr * body() const
Definition ast.h:926
const Expr * type() const
Definition ast.h:925
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:198
const Ptrn * ptrn() const
Definition ast.h:682
const Expr * arg() const
Definition ast.h:684
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:148
const Expr * body() const
Definition ast.h:685
const Expr * callee() const
Definition ast.h:683
const Expr * body() const
Definition ast.h:753
bool is_arr() const
Definition ast.h:751
const IdPtrn * shape() const
Definition ast.h:752
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:156
const TuplePtrn * ptrn() const
Definition ast.h:707
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:153
uint64_t lit_u() const
Definition tok.h:166
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:154
const auto & elems() const
Definition ast.h:729
Tok::Tag delim_r() const
Definition ast.h:297
const auto & ptrns() const
Definition ast.h:302
Tok::Tag delim_l() const
Definition ast.h:296
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:66
const Expr * level() const
Definition ast.h:439
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:106
const auto & types() const
Definition ast.h:459
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:112
const Expr * inhabitant() const
Definition ast.h:824
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:169
Definition ast.h:14
fe::Arena::Ptr< const T > Ptr
Definition ast.h:21
std::deque< Ptr< T > > Ptrs
Definition ast.h:22
Tok::Tag Tag
Definition bind.cpp:7
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:151
Definition span.h:114
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