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>
22struct R {
23 R(Tab& tab, const Ptrs<T>& range)
24 : tab(tab)
25 , range(range)
26 , f([&tab](std::ostream& os, const Ptr<T>& ptr) { ptr->stream(tab, os); }) {}
27
29 const Ptrs<T>& range;
30 std::function<void(std::ostream&, const Ptr<T>&)> f;
31};
32
33void Node::dump() const {
34 Tab tab;
35 stream(tab, std::cout) << std::endl;
36}
37
38/*
39 * Module
40 */
41
42std::ostream& Import::stream(Tab& tab, std::ostream& os) const { return tab.println(os, "{} '{}';", tag(), "TODO"); }
43
44std::ostream& Module::stream(Tab& tab, std::ostream& os) const {
45 for (const auto& import : imports())
46 import->stream(tab, os);
47 for (const auto& decl : decls())
48 tab.println(os, "{}", S(tab, decl.get()));
49 return os;
50}
51
52/*
53 * Ptrn
54 */
55
56std::ostream& ErrorPtrn::stream(Tab&, std::ostream& os) const { return os << "<error pattern>"; }
57std::ostream& AliasPtrn::stream(Tab& tab, std::ostream& os) const { return print(os, "{}: {}", S(tab, ptrn()), dbg()); }
58std::ostream& GrpPtrn::stream(Tab&, std::ostream& os) const { return os << dbg(); }
59
60std::ostream& IdPtrn::stream(Tab& tab, std::ostream& os) const {
61 // clang-format off
62 if ( dbg() && type()) return print(os, "{}: {}", dbg(), S(tab, type()));
63 if ( dbg() && !type()) return print(os, "{}", dbg());
64 if (!dbg() && type()) return print(os, "{}", S(tab, type()));
65 // clang-format on
66 return os << "<invalid identifier pattern>";
67}
68
69std::ostream& TuplePtrn::stream(Tab& tab, std::ostream& os) const {
70 return print(os, "{}{, }{}", delim_l(), R(tab, ptrns()), delim_r());
71}
72
73/*
74 * Expr
75 */
76
77std::ostream& IdExpr::stream(Tab&, std::ostream& os) const { return print(os, "{}", dbg()); }
78std::ostream& ErrorExpr::stream(Tab&, std::ostream& os) const { return os << "<error expression>"; }
79std::ostream& HoleExpr::stream(Tab&, std::ostream& os) const { return os << "?"; }
80std::ostream& PrimaryExpr::stream(Tab&, std::ostream& os) const { return print(os, "{}", tag()); }
81
82std::ostream& LitExpr::stream(Tab& tab, std::ostream& os) const {
83 switch (tag()) {
84 case Tag::L_i: return print(os, "{}", tok().lit_i());
85 case Tag::L_f: return os << std::bit_cast<double>(tok().lit_u());
86 case Tag::L_s:
87 case Tag::L_u:
88 os << tok().lit_u();
89 if (type()) print(os, ": {}", S(tab, type()));
90 break;
91 default: os << "TODO";
92 }
93 return os;
94}
95
96std::ostream& DeclExpr::stream(Tab& tab, std::ostream& os) const {
97 if (is_where()) {
98 tab.println(os, "{} where", S(tab, expr()));
99 ++tab;
100 for (const auto& decl : decls())
101 tab.println(os, "{}", S(tab, decl.get()));
102 --tab;
103 return os;
104 } else {
105 for (const auto& decl : decls())
106 tab.println(os, "{}", S(tab, decl.get()));
107 return print(os, "{}", S(tab, expr()));
108 }
109}
110
111std::ostream& TypeExpr::stream(Tab& tab, std::ostream& os) const { return print(os, "(Type {})", S(tab, level())); }
112std::ostream& RuleExpr::stream(Tab& tab, std::ostream& os) const { return print(os, "(Rule {})", S(tab, meta_type())); }
113
114std::ostream& ArrowExpr::stream(Tab& tab, std::ostream& os) const {
115 return print(os, "{} -> {}", S(tab, dom()), S(tab, codom()));
116}
117
118std::ostream& UnionExpr::stream(Tab& tab, std::ostream& os) const { return print(os, "({∪ })", R(tab, types())); }
119
120std::ostream& InjExpr::stream(Tab& tab, std::ostream& os) const {
121 return print(os, "{} inj {}", S(tab, value()), S(tab, type()));
122}
123
124std::ostream& MatchExpr::Arm::stream(Tab& tab, std::ostream& os) const {
125 return print(os, "{} => {}", S(tab, ptrn()), S(tab, body()));
126}
127
128std::ostream& MatchExpr::stream(Tab& tab, std::ostream& os) const {
129 tab.println(os, "match {} with", S(tab, scrutinee()));
130 ++tab;
131 for (const auto& arm : arms())
132 tab.println(os, "| {}", S(tab, arm.get()));
133 --tab;
134 return tab.println(os, "}}");
135}
136
137std::ostream& PiExpr::Dom::stream(Tab& tab, std::ostream& os) const {
138 print(os, "{}{}", is_implicit() ? "." : "", S(tab, ptrn()));
139 if (ret()) print(os, " -> {}", S(tab, ret()->type()));
140 return os;
141}
142
143std::ostream& PiExpr::stream(Tab& tab, std::ostream& os) const {
144 if (tag() != Tag::Nil) print(os, "{} ", tag());
145 print(os, "{}", S(tab, dom()));
146 if (codom()) print(os, " -> {}", S(tab, codom()));
147 return os;
148}
149
150std::ostream& LamExpr::stream(Tab& tab, std::ostream& os) const { return print(os, "{};", S(tab, lam())); }
151
152std::ostream& AppExpr::stream(Tab& tab, std::ostream& os) const {
153 return print(os, "{} {} {}", S(tab, callee()), is_explicit() ? "@" : "", S(tab, arg()));
154}
155
156std::ostream& RetExpr::stream(Tab& tab, std::ostream& os) const {
157 println(os, "ret {} = {} $ {};", S(tab, ptrn()), S(tab, callee()), S(tab, arg()));
158 return tab.print(os, "{}", S(tab, body()));
159}
160
161std::ostream& SigmaExpr::stream(Tab& tab, std::ostream& os) const { return ptrn()->stream(tab, os); }
162std::ostream& TupleExpr::stream(Tab& tab, std::ostream& os) const { return print(os, "({, })", R(tab, elems())); }
163
164std::ostream& SeqExpr::stream(Tab& tab, std::ostream& os) const {
165 return print(os, "{}{}; {}{}", is_arr() ? "«" : "‹", S(tab, arity()), S(tab, body()), is_arr() ? "»" : "›");
166}
167
168std::ostream& ExtractExpr::stream(Tab& tab, std::ostream& os) const {
169 if (auto expr = std::get_if<Ptr<Expr>>(&index())) return print(os, "{}#{}", S(tab, tuple()), S(tab, expr->get()));
170 return print(os, "{}#{}", S(tab, tuple()), std::get<Dbg>(index()));
171}
172
173std::ostream& InsertExpr::stream(Tab& tab, std::ostream& os) const {
174 return print(os, "ins({}, {}, {})", S(tab, tuple()), S(tab, index()), S(tab, value()));
175}
176
177std::ostream& UniqExpr::stream(Tab& tab, std::ostream& os) const { return print(os, "⦃{}⦄", S(tab, inhabitant())); }
178
179/*
180 * Decl
181 */
182
183std::ostream& AxmDecl::Alias::stream(Tab&, std::ostream& os) const { return os << dbg(); }
184
185std::ostream& AxmDecl::stream(Tab& tab, std::ostream& os) const {
186 print(os, "axm {}", dbg());
187 if (num_subs() != 0) {
188 os << '(';
189 for (auto sep = ""; const auto& aliases : subs()) {
190 print(os, "{}{ = }", sep, R(tab, aliases));
191 sep = ", ";
192 }
193 os << ')';
194 }
195 print(os, ": {}", S(tab, type()));
196 if (normalizer()) print(os, ", {}", normalizer());
197 if (curry()) print(os, ", {}", curry());
198 if (trip()) print(os, ", {}", trip());
199 return os << ";";
200}
201
202std::ostream& LetDecl::stream(Tab& tab, std::ostream& os) const {
203 return print(os, "let {} = {};", S(tab, ptrn()), S(tab, value()));
204}
205
206std::ostream& RecDecl::stream(Tab& tab, std::ostream& os) const {
207 print(os, ".rec {}", dbg());
208 if (!type()->isa<HoleExpr>()) print(os, ": {}", S(tab, type()));
209 return print(os, " = {};", S(tab, body()));
210}
211
212std::ostream& LamDecl::Dom::stream(Tab& tab, std::ostream& os) const {
213 print(os, "{}{}", is_implicit() ? "." : "", S(tab, ptrn()));
214 if (filter()) print(os, "@({})", S(tab, filter()));
215 if (ret()) print(os, ": {}", S(tab, ret()->type()));
216 return os;
217}
218
219std::ostream& LamDecl::stream(Tab& tab, std::ostream& os) const {
220 print(os, "{} {}", tag(), dbg());
221 if (!doms().front()->ptrn()->isa<TuplePtrn>()) os << ' ';
222 print(os, "{}", R(tab, doms()));
223 if (codom()) print(os, ": {}", S(tab, codom()));
224 if (body()) {
225 if (body()->isa<DeclExpr>()) {
226 os << " =" << std::endl;
227 (++tab).print(os, "{}", S(tab, body()));
228 --tab;
229 } else {
230 print(os, " = {}", S(tab, body()));
231 }
232 }
233 return os << ';';
234}
235
236std::ostream& CDecl::stream(Tab& tab, std::ostream& os) const {
237 print(os, "{} {} {}", dbg(), tag(), S(tab, dom()), S(tab, codom()));
238 if (tag() == Tag::K_cfun) print(os, ": {}", S(tab, codom()));
239 return os;
240}
241
242std::ostream& RuleDecl::stream(Tab& tab, std::ostream& os) const {
243 return print(os, "rule {} : {} => {} when {}", S(tab, var()), S(tab, lhs()), S(tab, rhs()), S(tab, guard()));
244}
245} // namespace mim::ast
Keeps track of indentation level.
Definition print.h:221
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:250
std::ostream & print(std::ostream &os, const char *s, Args &&... args)
Definition print.h:238
Dbg dbg() const
Definition ast.h:260
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:57
const Ptrn * ptrn() const
Definition ast.h:259
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:152
bool is_explicit() const
Definition ast.h:654
const Expr * arg() const
Definition ast.h:656
const Expr * callee() const
Definition ast.h:655
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:114
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:183
Dbg dbg() const
Definition ast.h:867
const auto & subs() const
Definition ast.h:889
const Expr * type() const
Definition ast.h:892
Tok trip() const
Definition ast.h:895
size_t num_subs() const
Definition ast.h:890
Tok curry() const
Definition ast.h:894
Dbg normalizer() const
Definition ast.h:893
Dbg dbg() const
Definition ast.h:888
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:185
Tok::Tag tag() const
Definition ast.h:1024
const Ptrn * dom() const
Definition ast.h:1025
const Expr * codom() const
Definition ast.h:1026
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:236
Dbg dbg() const
Definition ast.h:1023
const Expr * expr() const
Definition ast.h:404
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:96
const auto & decls() const
Definition ast.h:402
bool is_where() const
Definition ast.h:403
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:78
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:56
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:168
const auto & index() const
Definition ast.h:776
const Expr * tuple() const
Definition ast.h:775
Dbg dbg() const
Definition ast.h:238
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:58
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:79
Dbg dbg() const
Definition ast.h:338
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:77
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:60
Dbg dbg() const
Definition ast.h:208
const Expr * type() const
Definition ast.h:209
Tok::Tag tag() const
Definition ast.h:1088
std::ostream & stream(Tab &, std::ostream &) const
Definition stream.cpp:42
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:120
const Expr * type() const
Definition ast.h:484
const Expr * value() const
Definition ast.h:483
const Expr * index() const
Definition ast.h:800
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:173
const Expr * tuple() const
Definition ast.h:799
const Expr * value() const
Definition ast.h:801
const Expr * filter() const
Definition ast.h:962
bool is_implicit() const
Definition ast.h:961
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:212
Tok::Tag tag() const
Definition ast.h:991
const Ptrs< Dom > & doms() const
Definition ast.h:993
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:219
const Expr * codom() const
Definition ast.h:996
const LamDecl * lam() const
Definition ast.h:632
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:150
const Expr * value() const
Definition ast.h:845
const Ptrn * ptrn() const
Definition ast.h:844
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:202
Tok tok() const
Definition ast.h:379
const Expr * type() const
Definition ast.h:381
Tok::Tag tag() const
Definition ast.h:380
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:82
const Expr * body() const
Definition ast.h:509
const Ptrn * ptrn() const
Definition ast.h:508
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:124
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:128
const Expr * scrutinee() const
Definition ast.h:525
const Arm * arm(size_t i) const
Definition ast.h:527
const auto & arms() const
Definition ast.h:526
const auto & decls() const
Definition ast.h:1117
const auto & imports() const
Definition ast.h:1116
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:44
virtual std::ostream & stream(Tab &, std::ostream &) const =0
void dump() const
Definition stream.cpp:33
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:137
const IdPtrn * ret() const
Definition ast.h:581
bool is_implicit() const
Definition ast.h:579
const Ptrn * ptrn() const
Definition ast.h:580
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:143
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:80
Tok::Tag tag() const
Definition ast.h:360
Dbg dbg() const
Definition ast.h:922
const Expr * body() const
Definition ast.h:924
const Expr * type() const
Definition ast.h:923
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:206
const Ptrn * ptrn() const
Definition ast.h:679
const Expr * arg() const
Definition ast.h:681
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:156
const Expr * body() const
Definition ast.h:682
const Expr * callee() const
Definition ast.h:680
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:242
const Ptrn * var() const
Definition ast.h:1055
const Expr * guard() const
Definition ast.h:1058
const Expr * rhs() const
Definition ast.h:1057
const Expr * lhs() const
Definition ast.h:1056
const Expr * meta_type() const
Definition ast.h:442
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:112
const Expr * body() const
Definition ast.h:750
const IdPtrn * arity() const
Definition ast.h:749
bool is_arr() const
Definition ast.h:748
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:164
const TuplePtrn * ptrn() const
Definition ast.h:704
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:161
uint64_t lit_u() const
Definition tok.h:219
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:162
Tok::Tag delim_r() const
Definition ast.h:282
const auto & ptrns() const
Definition ast.h:287
Tok::Tag delim_l() const
Definition ast.h:281
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:69
const Expr * level() const
Definition ast.h:424
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:111
const auto & types() const
Definition ast.h:462
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:118
const Expr * inhabitant() const
Definition ast.h:821
std::ostream & stream(Tab &, std::ostream &) const override
Definition stream.cpp:177
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
std::ostream & print(std::ostream &os, const char *s)
Base case.
Definition print.cpp:5
auto elems(std::ostream &os, const auto &range)
Wrap all elements in range through os << T(elem).
Definition print.h:97
std::ostream & println(std::ostream &os, const char *fmt, Args &&... args)
As above but end with std::endl.
Definition print.h:172
Definition span.h:122
const Ptrs< T > & range
Definition stream.cpp:29
std::function< void(std::ostream &, const Ptr< T > &)> f
Definition stream.cpp:30
R(Tab &tab, const Ptrs< T > &range)
Definition stream.cpp:23
Tab & tab
Definition stream.cpp:28
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