18 friend std::ostream&
operator<<(std::ostream& os,
const S& s) {
return s.node->stream(s.tab, os), os; }
25struct std::formatter<
mim::ast::S> : fe::ostream_formatter {};
41 friend std::ostream&
operator<<(std::ostream& os,
const R& r) {
42 for (std::string_view curr_sep{};
const auto& ptr : r.range) {
44 ptr->stream(r.tab, os);
55struct std::formatter<
mim::ast::R<T>> : fe::ostream_formatter {};
62 for (
auto decl : decls)
63 std::println(os,
"{}{}", tab,
S(tab, decl.get()));
67 auto tab = fe::Tab::spaces();
69 std::cout << std::endl;
88 if (
dbg() &&
type()) { std::print(os,
"{}: {}",
dbg(),
S(tab,
type()));
return; }
89 if (
dbg() && !
type()) { std::print(os,
"{}",
dbg());
return; }
90 if (!
dbg() &&
type()) { std::print(os,
"{}",
S(tab,
type()));
return; }
92 os <<
"<invalid identifier pattern>";
103void Path::stream(fe::Tab&, std::ostream& os)
const { std::print(os,
"{}", fe::Join(
dbgs(),
".")); }
114 std::print(os,
"{}_{}", val, size);
117 case Tag::L_f: os << std::bit_cast<double>(
tok().lit_u());
return;
121 if (
type()) std::print(os,
": {}",
S(tab,
type()));
123 default: os <<
"TODO";
129 std::println(os,
"{}{} where", tab,
S(tab,
expr()));
135 std::print(os,
"{}",
S(tab,
expr()));
147 std::print(os,
"{} => {}",
S(tab,
ptrn()),
S(tab,
body()));
151 std::println(os,
"{}match {} with", tab,
S(tab,
scrutinee()));
154 std::println(os,
"{}| {}", tab,
S(tab,
arm.get()));
156 std::println(os,
"{}}}", tab);
161 if (
ret()) std::print(os,
" -> {}",
S(tab,
ret()->type()));
165 if (tag() != Tag::Nil) std::print(os,
"{} ", tag());
166 std::print(os,
"{}",
S(tab, dom()));
167 if (codom()) std::print(os,
" -> {}",
S(tab, codom()));
173 std::print(os,
"({} {})",
S(tab,
callee()),
S(tab,
arg()));
177 std::println(os,
"ret {} = {} $ {};",
S(tab,
ptrn()),
S(tab,
callee()),
S(tab,
arg()));
178 std::print(os,
"{}{}", tab,
S(tab,
body()));
205 if (mods.
is_extern) std::print(os,
"extern ");
206 if (mods.
is_anx) std::print(os,
"anx ");
214struct std::formatter<
mim::ast::Mods> : fe::ostream_formatter {};
221 std::print(os,
"axm {}: {}",
dbg(),
S(tab,
type()));
224 if (
trip()) std::print(os,
", {}",
trip());
230 std::print(os,
"axm {}: {}",
dbg(),
S(tab,
owner()->
type()));
237 std::print(os,
"anx {} = {};",
dbg(),
S(tab,
path()));
241 std::println(os,
"{}mod {} {{",
mods(),
dbg());
245 std::print(os,
"{}}}", tab);
252 std::print(os,
"{}{} {}",
mods(),
tag(),
S(tab,
path()));
253 if (
alias()) std::print(os,
" as {}",
alias());
259 std::print(os,
"{}let {} = {};",
mods(),
S(tab,
ptrn()),
S(tab,
value()));
263 std::print(os,
"{}{}",
mods(), isa<LamDecl>() ?
"" :
"rec ");
265 for (
auto curr =
next(); curr; curr = curr->next()) {
267 std::print(os,
"{}and ", tab);
268 curr->stream_(tab, os);
278 if (
ret()) std::print(os,
": {}",
S(tab,
ret()->
type()));
282 std::print(os,
"{} {}",
tag(),
dbg());
283 if (!
doms().front()->ptrn()->isa<TuplePtrn>()) os <<
' ';
284 std::print(os,
"{}",
R(tab,
doms()));
285 if (
codom()) std::print(os,
": {}",
S(tab,
codom()));
287 if (
body()->isa<DeclExpr>()) {
288 os <<
" =" << std::endl;
290 std::print(os,
"{}{}", tab,
S(tab,
body()));
293 std::print(os,
" = {}",
S(tab,
body()));
299 std::print(os,
"rule {} : {} => {} when {}",
S(tab,
var()),
S(tab,
lhs()),
S(tab,
rhs()),
S(tab,
guard()));
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
void stream(fe::Tab &, std::ostream &) const override
const Path * path() const
const Ptrn * ptrn() const
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
void stream(fe::Tab &, std::ostream &) const override
void stream(fe::Tab &, std::ostream &) const override
const Expr * callee() const
const AxmDecl * owner() const
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
void stream(fe::Tab &, std::ostream &) const override
const Expr * type() const
void stream(fe::Tab &, std::ostream &) const override
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
const Expr * expr() const
void stream(fe::Tab &, std::ostream &) const override
void stream(fe::Tab &, std::ostream &) const override
void stream(fe::Tab &, std::ostream &) const override
void stream(fe::Tab &, std::ostream &) const override
void stream(fe::Tab &, std::ostream &) const override
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
void stream(fe::Tab &, std::ostream &) const override
void stream(fe::Tab &, std::ostream &) const override
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
const Expr * type() const
void stream(fe::Tab &, std::ostream &) const override
const Expr * filter() const
void stream(fe::Tab &, std::ostream &) const override
const Expr * codom() const
void stream_(fe::Tab &, std::ostream &) const override
Streams this declaration alone - without the leading rec/and and without the trailing ;.
const LamDecl * lam() const
void stream(fe::Tab &, std::ostream &) const override
void stream(fe::Tab &, std::ostream &) const override
const Expr * value() const
const Ptrn * ptrn() const
static std::string escape(std::string_view str)
Inverse of Lexer::lex_char: renders str as the body of a Mim string literal.
const Expr * type() const
void stream(fe::Tab &, std::ostream &) const override
void stream(fe::Tab &, std::ostream &) const override
const Expr * body() const
const Ptrn * ptrn() const
const Expr * scrutinee() const
void stream(fe::Tab &, std::ostream &) const override
const Arm * arm(size_t i) const
void stream(fe::Tab &, std::ostream &) const override
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
Base class of all AST nodes.
virtual void stream(fe::Tab &, std::ostream &) const =0
const Path * path() const
void stream(fe::Tab &, std::ostream &) const override
void stream(fe::Tab &, std::ostream &) const override
void stream(fe::Tab &, std::ostream &) const override
const IdPtrn * ret() const
const Ptrn * ptrn() const
void stream(fe::Tab &, std::ostream &) const override
void stream(fe::Tab &, std::ostream &) const override
void stream(fe::Tab &, std::ostream &) const override
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
virtual void stream_(fe::Tab &, std::ostream &) const
Streams this declaration alone - without the leading rec/and and without the trailing ;.
const Expr * body() const
const RecDecl * next() const
const Ptrn * ptrn() const
void stream(fe::Tab &, std::ostream &) const override
const Expr * body() const
const Expr * callee() const
const Expr * guard() const
void stream(fe::Tab &, std::ostream &) const override
void stream(fe::Tab &, std::ostream &) const override
const Expr * body() const
const IdPtrn * arity() const
void stream(fe::Tab &, std::ostream &) const override
const TuplePtrn * ptrn() const
void stream(fe::Tab &, std::ostream &) const override
std::pair< uint64_t, uint64_t > lit_i() const
static const char * tag2str(Tok::Tag)
void stream(fe::Tab &, std::ostream &) const override
void stream(fe::Tab &, std::ostream &) const override
const Expr * level() const
void stream(fe::Tab &, std::ostream &) const override
const Expr * inhabitant() const
void stream(fe::Tab &, std::ostream &) const override
bool is_splice() const
as *: splice the module's public members, bind no name.
Dbg alias() const
Empty, unless the source spelled as I.
void stream(fe::Tab &, std::ostream &) const override
Sym file_path() const
Spelling of an import "..."; empty otherwise.
bool is_file_path() const
Tok::Tag tag() const
import, plugin, or use.
const Path * path() const
Module path of a use; module name of an import/plugin.
const Mods & mods() const
Vis vis() const override
A ValDecl's own Vis; Pub for anything else (Ptrn, Import, ...), which the priv/pub system ignores.
static std::string_view vis2str(Vis vis)
Vis
Visibility tier of a ValDecl.
fe::Arena::Ref< const T > Ptr
Nodes live in the AST's Arena and are never destroyed, so this merely points at one.
static void stream_decls(fe::Tab &tab, std::ostream &os, fe::View< Ptr< T > > decls)
std::ostream & operator<<(std::ostream &os, Tok tok)
Raw, unvalidated combination of priv/pub/extern/anx modifiers written before a declaration.
Vis default_vis() const
extern/anx nudge the default visibility to Pub unless priv is given explicitly.
friend std::ostream & operator<<(std::ostream &os, const R &r)
fe::View< Ptr< T > > range
R(fe::Tab &tab, fe::View< Ptr< T > > range, std::string_view sep=", ")
friend std::ostream & operator<<(std::ostream &os, const S &s)
S(fe::Tab &tab, const Node *node)