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()));
63 return os <<
"<invalid identifier pattern>";
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());
88 default: os <<
"TODO";
97 for (
const auto& decl :
decls()) tab.
println(os,
"{}",
S(tab, decl.get()));
101 for (
const auto& decl :
decls()) tab.
println(os,
"{}",
S(tab, decl.get()));
109 return print(os,
"{} -> {}",
S(tab, dom()),
S(tab, codom()));
119 print(os,
"{} {}", tag(),
R(tab, doms()));
120 if (codom())
print(os,
" -> {}",
S(tab, codom()));
127 return print(os,
"{} {} {}",
S(tab, callee()), is_explicit() ?
"@" :
"",
S(tab, arg()));
131 println(os,
"ret {} = {} $ {};",
S(tab, ptrn()),
S(tab, callee()),
S(tab, arg()));
132 return tab.
print(os,
"{}",
S(tab, body()));
139 return print(os,
"{}{}; {}{}", arr ?
"«" :
"‹",
S(tab, shape()),
S(tab, body()), arr ?
"»" :
"›");
146 if (
auto expr = std::get_if<
Ptr<Expr>>(&index()))
return print(os,
"{}#{}",
S(tab, tuple()),
S(tab, expr->get()));
151 return print(os,
"ins({}, {}, {})",
S(tab, tuple()),
S(tab, index()),
S(tab, value()));
161 print(os,
"axm {}", dbg());
162 if (num_subs() != 0) {
164 for (
auto sep =
"";
const auto& aliases : subs()) {
165 print(os,
"{}{ = }", sep,
R(tab, aliases));
170 print(os,
": {}",
S(tab, type()));
171 if (normalizer())
print(os,
", {}", normalizer());
172 if (curry())
print(os,
", {}", curry());
173 if (trip())
print(os,
", {}", trip());
178 return print(os,
"let {} = {};",
S(tab, ptrn()),
S(tab, value()));
182 print(os,
".rec {}", dbg());
183 if (!type()->isa<InferExpr>())
print(os,
": {}",
S(tab, type()));
184 return print(os,
" = {};",
S(tab, body()));
188 print(os,
"{}{}", implicit() ?
"." :
"",
S(tab, ptrn()));
189 if (filter())
print(os,
"@({})",
S(tab, filter()));
190 if (ret())
print(os,
": {}",
S(tab, ret()->type()));
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()));
200 if (body()->isa<DeclExpr>()) {
201 os <<
" =" << std::endl;
202 (++tab).
print(os,
"{}",
S(tab, body()));
205 print(os,
" = {}",
S(tab, body()));
212 print(os,
"{} {} {}", dbg(), tag(),
S(tab, dom()),
S(tab, codom()));
213 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
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 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)