18 friend std::ostream&
operator<<(std::ostream& os,
const S& s) {
return s.node->stream(s.tab, os); }
21template<
class T>
struct R {
25 ,
f([&
tab](
std::ostream& os, const
Ptr<T>& ptr) { ptr->stream(
tab, os); }) {}
29 std::function<void(std::ostream&,
const Ptr<T>&)>
f;
34 stream(tab, std::cout) << std::endl;
44 for (
const auto&
import :
imports())
import->stream(tab, os);
45 for (
const auto& decl :
decls()) tab.
println(os,
"{}",
S(tab, decl.get()));
61 return os <<
"<invalid identifier pattern>";
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());
90 default: os <<
"TODO";
99 for (
const auto& decl :
decls()) tab.
println(os,
"{}",
S(tab, decl.get()));
103 for (
const auto& decl :
decls()) tab.
println(os,
"{}",
S(tab, decl.get()));
111 return print(os,
"{} -> {}",
S(tab, dom()),
S(tab, codom()));
121 print(os,
"{} {}", tag(),
R(tab, doms()));
122 if (codom())
print(os,
" -> {}",
S(tab, codom()));
129 return print(os,
"{} {} {}",
S(tab, callee()), is_explicit() ?
"@" :
"",
S(tab, arg()));
133 println(os,
"ret {} = {} $ {};",
S(tab, ptrn()),
S(tab, callee()),
S(tab, arg()));
134 return tab.
print(os,
"{}",
S(tab, body()));
141 return print(os,
"{}{}; {}{}", arr ?
"«" :
"‹",
S(tab, shape()),
S(tab, body()), arr ?
"»" :
"›");
148 if (
auto expr = std::get_if<
Ptr<Expr>>(&index()))
return print(os,
"{}#{}",
S(tab, tuple()),
S(tab, expr->get()));
153 return print(os,
"ins({}, {}, {})",
S(tab, tuple()),
S(tab, index()),
S(tab, value()));
163 print(os,
"axm {}", dbg());
164 if (num_subs() != 0) {
166 for (
auto sep =
"";
const auto& aliases : subs()) {
167 print(os,
"{}{ = }", sep,
R(tab, aliases));
172 print(os,
": {}",
S(tab, type()));
173 if (normalizer())
print(os,
", {}", normalizer());
174 if (curry())
print(os,
", {}", curry());
175 if (trip())
print(os,
", {}", trip());
180 return print(os,
"let {} = {};",
S(tab, ptrn()),
S(tab, value()));
184 print(os,
".rec {}", dbg());
185 if (!type()->isa<InferExpr>())
print(os,
": {}",
S(tab, type()));
186 return print(os,
" = {};",
S(tab, body()));
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()));
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()));
202 if (body()->isa<DeclExpr>()) {
203 os <<
" =" << std::endl;
204 (++tab).
print(os,
"{}",
S(tab, body()));
207 print(os,
" = {}",
S(tab, body()));
214 print(os,
"{} {} {}", dbg(), tag(),
S(tab, dom()),
S(tab, codom()));
215 if (tag() == Tag::K_cfun)
print(os,
": {}",
S(tab, codom()));
Keeps track of indentation level.
std::ostream & println(std::ostream &os, const char *s, Args &&... args)
Same as Tab::print but appends a std::endl to os.
std::ostream & print(std::ostream &os, const char *s, Args &&... args)
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
const Expr * expr() const
std::ostream & stream(Tab &, std::ostream &) const override
const auto & decls() const
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
const Expr * type() const
std::ostream & stream(Tab &, std::ostream &) const
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
const Expr * type() const
std::ostream & stream(Tab &, std::ostream &) const override
const auto & decls() const
const auto & imports() const
std::ostream & stream(Tab &, std::ostream &) const override
virtual std::ostream & stream(Tab &, std::ostream &) const =0
std::ostream & stream(Tab &, std::ostream &) const override
const IdPtrn * ret() const
const Ptrn * ptrn() const
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
std::ostream & stream(Tab &, std::ostream &) const override
const auto & ptrns() const
std::ostream & stream(Tab &, std::ostream &) const override
const Expr * level() const
std::ostream & stream(Tab &, std::ostream &) const override
fe::Arena::Ptr< const T > Ptr
std::deque< Ptr< T > > Ptrs
std::ostream & print(std::ostream &os, const char *s)
Base case.
std::ostream & println(std::ostream &os, const char *fmt, Args &&... args)
As above but end with std::endl.
constexpr decltype(auto) get(mim::Span< T, N > span)
std::function< void(std::ostream &, const Ptr< T > &)> f
R(Tab &tab, const Ptrs< T > &range)
S(Tab &tab, const Node *node)
friend std::ostream & operator<<(std::ostream &os, const S &s)