27using Ptr = fe::Arena::Ref<const T>;
34using Ptrs = fe::Vector<Ptr<T>>;
35using Dbgs = fe::Vector<Dbg>;
57 std::optional<Vis>
vis = {};
74 :
sym{sym_plugin, sym_tag}
85 auto base =
sym.plugin.str() +
"." +
sym.tag.str();
86 return driver.sym(own ==
sym.tag ?
base :
base +
"." + own.str());
97 fe::Vector<fe::Vector<Sym>>
subs;
102 std::optional<bool>
pi;
125 Sym
sym(
const std::string& s) {
return driver().sym(s); }
131 template<
class T,
class... Args>
132 auto ptr(Args&&... args) {
133 return arena_.ref<
const T>(std::forward<Args>(args)...);
137 template<
class R,
class T = std::ranges::range_value_t<R>>
139 auto span = arena_.copy(range);
140 return fe::View<T>(span.data(), span.size());
151 std::pair<Ptr<File>&,
bool>
file(
const fe::Src* src);
175 void bootstrap(Sym plugin, std::ostream& h);
182 swap(a1.world_, a2.world_ );
183 swap(a1.arena_, a2.arena_ );
184 swap(a1.files_, a2.files_ );
185 swap(a1.scopes_, a2.scopes_);
186 swap(a1.plugin2sym2annex_, a2.plugin2sym2annex_);
187 swap(a1.plugin2foreign_aliases_, a2.plugin2foreign_aliases_);
195 World* world_ =
nullptr;
197 std::unique_ptr<Files> files_;
198 std::deque<Scope> scopes_;
201 std::unordered_map<fe::Sym, std::unordered_map<fe::Sym, AnnexInfo>> plugin2sym2annex_;
202 std::unordered_map<fe::Sym, std::vector<ForeignAlias>> plugin2foreign_aliases_;
206class Node :
public fe::RuntimeCast<Node> {
211 assert((!
loc.begin == !
loc.end &&
loc.begin <=
loc.end) &&
"malformed Loc");
212 assert((!
loc || !
loc.src || (
loc.src->contains(
loc.begin) &&
loc.src->contains(
loc.end)))
213 &&
"Loc outside its Src");
217 Loc
loc()
const {
return loc_; }
219 virtual void stream(fe::Tab&, std::ostream&)
const = 0;
259 virtual Dbg
dbg()
const {
return Dbg(
loc(), Sym()); }
263 virtual std::pair<AnnexInfo*, sub_t>
annex_sub()
const {
return {
nullptr, 0}; }
269 virtual bool is_anx()
const {
return false; }
282 Dbg
dbg()
const override {
return dbg_; }
286 void stream(fe::Tab&, std::ostream&)
const override;
300 Vis vis()
const override {
return mods_.resolved_vis(); }
301 bool is_extern()
const override {
return mods_.is_extern; }
302 bool is_anx()
const override {
return mods_.is_anx; }
324 virtual void bind(
Scopes&,
bool rebind,
bool quiet)
const = 0;
341 void bind(
Scopes&,
bool rebind,
bool quiet)
const override;
344 void stream(fe::Tab&, std::ostream&)
const override;
355 Dbg
dbg()
const override {
return dbg_; }
357 std::pair<AnnexInfo*, sub_t>
annex_sub()
const override {
return {annex_, sub_}; }
359 Vis vis()
const override {
return vis_; }
360 bool is_anx()
const override {
return anx_; }
362 void bind(
Scopes&,
bool rebind,
bool quiet)
const override;
365 void stream(fe::Tab&, std::ostream&)
const override;
370 mutable const Def* emitted_type_ =
nullptr;
372 mutable sub_t sub_ = 0;
374 mutable bool anx_ =
false;
388 Dbg
dbg()
const override {
return dbg_; }
391 void bind(
Scopes&,
bool rebind,
bool quiet)
const override;
394 void stream(fe::Tab&, std::ostream&)
const override;
410 Dbg
dbg()
const override {
return dbg_; }
413 void bind(
Scopes&,
bool rebind,
bool quiet)
const override;
416 void stream(fe::Tab&, std::ostream&)
const override;
435 bool is_implicit()
const override {
return delim_l_ == Tok::Tag::D_brace_l; }
437 auto ptrns()
const {
return vla<0>(); }
439 Sym
field(
size_t i)
const;
442 void bind(
Scopes&,
bool rebind,
bool quiet)
const override;
447 void stream(fe::Tab&, std::ostream&)
const override;
464 void stream(fe::Tab&, std::ostream&)
const override;
477 void stream(fe::Tab&, std::ostream&)
const override;
491 auto dbgs()
const {
return vla<0>(); }
497 void stream(fe::Tab&, std::ostream&)
const override;
500 mutable const Decl* decl_ =
nullptr;
511 Dbg
dbg()
const {
return path_->back(); }
515 void stream(fe::Tab&, std::ostream&)
const override;
535 void stream(fe::Tab&, std::ostream&)
const override;
556 void stream(fe::Tab&, std::ostream&)
const override;
575 auto decls()
const {
return vla<0>(); }
580 void stream(fe::Tab&, std::ostream&)
const override;
599 void stream(fe::Tab&, std::ostream&)
const override;
614 const Expr*
dom()
const {
return dom_.get(); }
617 void stream(fe::Tab&, std::ostream&)
const override;
636 const Expr*
rhs()
const {
return rhs_.get(); }
639 void stream(fe::Tab&, std::ostream&)
const override;
659 const Expr*
lhs()
const {
return lhs_.get(); }
661 const Expr*
rhs()
const {
return rhs_.get(); }
667 return infix && infix->op().isa(tag) ? infix :
nullptr;
671 void stream(fe::Tab&, std::ostream&)
const override;
685 mutable Pi* pi_ =
nullptr;
704 std::optional<nat_t>
index()
const {
return index_; }
706 Dbg
ctor()
const {
return ctor_; }
711 void stream(fe::Tab&, std::ostream&)
const override;
714 std::optional<nat_t> index_;
727 auto arms()
const {
return vla<0>(); }
732 void stream(fe::Tab&, std::ostream&)
const override;
752 Dbg
dbg()
const {
return dbg_; }
755 void stream(fe::Tab&, std::ostream&)
const override;
767 auto ctors()
const {
return vla<0>(); }
772 void stream(fe::Tab&, std::ostream&)
const override;
798 virtual void bind(
Scopes&,
bool quiet =
false)
const;
800 void stream(fe::Tab&, std::ostream&)
const override;
820 Tok::Tag tag()
const {
return tag_; }
821 const Dom* dom()
const {
return dom_.get(); }
822 const Expr* codom()
const {
return codom_.get(); }
824 void bind(Scopes&)
const override;
825 void stream(fe::Tab&, std::ostream&)
const override;
828 const Def*
emit_(Emitter&)
const override;
829 const Def*
emit_decl_(Emitter&,
const Def* type)
const override;
830 void emit_body_(Emitter&,
const Def* decl)
const override;
845 void stream(fe::Tab&, std::ostream&)
const override;
864 const Expr*
arg()
const {
return arg_.get(); }
867 void stream(fe::Tab&, std::ostream&)
const override;
888 const Expr*
arg()
const {
return arg_.get(); }
892 void stream(fe::Tab&, std::ostream&)
const override;
914 void stream(fe::Tab&, std::ostream&)
const override;
932 auto elems()
const {
return vla<0>(); }
937 void stream(fe::Tab&, std::ostream&)
const override;
959 void stream(fe::Tab&, std::ostream&)
const override;
982 void stream(fe::Tab&, std::ostream&)
const override;
1008 , splice_(!
alias) {}
1019 , splice_(splice) {}
1031 Dbg
dbg()
const override {
return is_splice() ? Dbg() : alias_ ? alias_ : path_->back(); }
1036 void stream(fe::Tab&, std::ostream&)
const override;
1046 const File* file_ =
nullptr;
1048 mutable const Scope* scope_ =
nullptr;
1064 void stream(fe::Tab&, std::ostream&)
const override;
1086 bool is_anx()
const override {
return true; }
1087 std::pair<AnnexInfo*, sub_t>
annex_sub()
const override {
return {annex_, sub_}; }
1089 void stream(fe::Tab&, std::ostream&)
const override;
1093 mutable sub_t sub_ = 0;
1111 Dbg
dbg()
const override {
return mod_; }
1123 void stream(fe::Tab&, std::ostream&)
const override;
1142 Dbg
dbg()
const override {
return dbg_; }
1155 void stream(fe::Tab&, std::ostream&)
const override;
1157 virtual void stream_(fe::Tab&, std::ostream&)
const;
1185 void stream_(fe::Tab&, std::ostream&)
const override;
1190 mutable bool emitting_ =
false;
1208 void bind(
Scopes&,
bool quiet =
false)
const override;
1210 void stream(fe::Tab&, std::ostream&)
const override;
1229 auto doms()
const {
return vla<0>(); }
1240 void stream_(fe::Tab&, std::ostream&)
const override;
1260 void stream(fe::Tab&, std::ostream&)
const override;
1271 Dbg
dbg()
const override {
return dbg_; }
1276 void stream(fe::Tab&, std::ostream&)
const override;
1277 std::pair<AnnexInfo*, sub_t>
annex_sub()
const override {
return {annex_, sub_}; }
1283 mutable sub_t sub_ = 0;
1284 mutable Sym foreign_;
1299 Dbg
dbg()
const override {
return dbg_; }
1307 void stream(fe::Tab&, std::ostream&)
const override;
1330 Dbg
dbg()
const override {
return dbg_; }
1336 void stream(fe::Tab&, std::ostream&)
const override;
1345 fe::View<Ptr<ValDecl>> decls_;
1370 void stream(fe::Tab&, std::ostream&)
const override;
1373 mutable fe::View<Ptr<UseDecl>> implicit_imports_;
1375 mutable bool bound_ =
false, emitted_ =
false;
1380 return load_plugins(w, fe::View<std::string>({std::string(plugin)}));
Some "global" variables needed all over the place.
A dependent function type.
A sum type whose cases are positional: unlike a Join, they are neither sorted nor deduplicated.
The World represents the whole program and manages creation of MimIR nodes (Defs).
Owns the arena all AST nodes live in as well as the AnnexInfos of all plugins.
Scope & scope()
A fresh Scope for a ModDecl; owned here, as an AST node never runs a destructor.
friend void swap(AST &a1, AST &a2) noexcept
fe::View< T > copy(const R &range)
An Arena-allocated copy of range - for the few lists that do not sit behind a node.
AnnexInfo * name2annex(Scopes &s, Dbg dbg, sub_t *sub_id, const Expr *type=nullptr)
auto ptr(Args &&... args)
The VLA ranges of a fe::VLA node come last, in the order its VLA_Types declares them.
void bootstrap_py(Sym plugin, std::ostream &h)
Sym sym(std::string_view s)
const auto & plugin2annexes(Sym plugin)
void add_foreign_alias(Sym plugin, ForeignAlias alias)
void bootstrap(Sym plugin, std::ostream &h)
const auto & plugin2foreign_aliases(Sym plugin)
Sym sym_return()
"return".
Sym sym_error()
"_error_".
std::pair< Ptr< File > &, bool > file(const fe::Src *src)
Sym sym(const std::string &s)
An anx alias in one plugin for an annex of another, e.g. anx M = core.M; in mem.
void emit(Emitter &) const override
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
std::pair< AnnexInfo *, sub_t > annex_sub() const override
The (AnnexInfo, sub) slot this decl registered itself under as an annex; {nullptr,...
void stream(fe::Tab &, std::ostream &) const override
void bind(Scopes &) const override
const Path * path() const
AliasDecl(Loc loc, Vis vis, Dbg dbg, Ptr< Path > path)
const Def * emit_value(Emitter &, const Def *) const override
const Def * emit_type(Emitter &) const override
const Ptrn * ptrn() const
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
AliasPtrn(Loc loc, Ptr< Ptrn > ptrn, Dbg dbg)
bool is_implicit() const override
void bind(Scopes &, bool rebind, bool quiet) const override
void stream(fe::Tab &, std::ostream &) const override
void bind(Scopes &) const override
AppExpr(Loc loc, Ptr< Expr > callee, Ptr< Expr > arg)
const Def * emit_(Emitter &) const override
void stream(fe::Tab &, std::ostream &) const override
const Expr * callee() const
bool is_anx() const override
Whether this decl is registered as a compiler-exposed annex (anx).
std::tuple< Dbg > VLA_Types
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
std::pair< AnnexInfo *, sub_t > annex_sub() const override
The (AnnexInfo, sub) slot this decl registered itself under as an annex; {nullptr,...
void emit(Emitter &) const override
const Expr * type() const
bool is_family() const
Whether the names are spelled as a parenthesized list, even if it is just one.
AxmDecl(Loc l, Vis v, Dbg mod, Scope *members, bool is_family, Ptr< Expr > type, Dbg normalizer, Tok curry, Tok trip)
const Scope * scope() const override
Non-nullptr if this Decl is a module whose members a Path may walk into.
std::tuple< Ptr< Name > > VLA_Types
void bind(Scopes &) const override
void stream(fe::Tab &, std::ostream &) const override
axm is always anx, so only priv is ever printed.
Dbg dbg() const override
The mod. prefix, if any.
const Expr * expr() const
DeclExpr(Loc loc, Ptr< Expr > expr, bool is_where)
const Def * emit_(Emitter &) const override
std::tuple< Ptr< ValDecl > > VLA_Types
void bind(Scopes &) const override
void stream(fe::Tab &, std::ostream &) const override
Base class of all declarations; caches the emitted Decl::def.
virtual bool is_anx() const
Whether this decl is registered as a compiler-exposed annex (anx).
virtual std::pair< AnnexInfo *, sub_t > annex_sub() const
The (AnnexInfo, sub) slot this decl registered itself under as an annex; {nullptr,...
virtual Vis vis() const
A ValDecl's own Vis; Pub for anything else (Ptrn, Import, ...), which the priv/pub system ignores.
virtual bool is_extern() const
Whether this decl crosses the Mim/native boundary (extern); body presence picks which side supplies i...
virtual const Scope * scope() const
Non-nullptr if this Decl is a module whose members a Path may walk into.
virtual Dbg dbg() const
The name this Decl introduces; anonymous if it has none.
void stream(fe::Tab &, std::ostream &) const override
void bind(Scopes &) const override
const Def * emit_(Emitter &) const override
const Def * emit_type(Emitter &) const override
const Def * emit_value(Emitter &, const Def *) const override
void bind(Scopes &, bool rebind, bool quiet) const override
void stream(fe::Tab &, std::ostream &) const override
Base class of all expressions.
const Def * emit(Emitter &) const
const Def * emit_decl(Emitter &, const Def *type) const
virtual const Def * emit_decl_(Emitter &, const Def *) const
virtual void bind(Scopes &) const =0
virtual const Def * emit_(Emitter &) const =0
void emit_body(Emitter &, const Def *decl) const
virtual void emit_body_(Emitter &, const Def *) const
The AST of one source file: an anonymous ModDecl that a UseDecl binds under a name of its own.
void add_implicit_imports(fe::View< Ptr< UseDecl > > imports) const
void compile(AST &) const
auto implicit_imports() const
Imports the driver was told about via -p; they precede everything the file itself declares.
void stream(fe::Tab &, std::ostream &) const override
File(Loc loc, Scope &members, fe::View< Ptr< ValDecl > > decls)
const Def * emit_type(Emitter &) const override
GrpPtrn(Dbg dbg, const IdPtrn *id)
void bind(Scopes &, bool rebind, bool quiet) const override
const Def * emit_value(Emitter &, const Def *) const override
void stream(fe::Tab &, std::ostream &) const override
const IdPtrn * id() const
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
void bind(Scopes &) const override
void stream(fe::Tab &, std::ostream &) const override
const Def * emit_(Emitter &) const override
dbg bound to a Def whose type the binding construct dictates; hence, it carries no annotation.
const Def * emit(const Def *) const
void stream(fe::Tab &, std::ostream &) const override
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
void bind(Scopes &, bool quiet=false) const
Vis vis() const override
Mirrors the enclosing LetDecl::vis/is_anx, since a let's Ptrn - not the LetDecl - is what a Path reso...
void stream(fe::Tab &, std::ostream &) const override
const Def * emit_type(Emitter &) const override
void bind(Scopes &, bool rebind, bool quiet) const override
IdPtrn(Loc loc, Dbg dbg, Ptr< Expr > type)
std::pair< AnnexInfo *, sub_t > annex_sub() const override
The (AnnexInfo, sub) slot this decl registered itself under as an annex; {nullptr,...
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
const Def * emit_value(Emitter &, const Def *) const override
const Expr * type() const
bool is_anx() const override
Whether this decl is registered as a compiler-exposed annex (anx).
void emit_body_(Emitter &, const Def *decl) const override
void bind(Scopes &) const override
static const InfixExpr * isa_op(Tok::Tag tag, const Expr *expr)
const Expr * callee() const
const Def * emit_(Emitter &) const override
const Def * emit_decl_(Emitter &, const Def *type) const override
void stream(fe::Tab &, std::ostream &) const override
InfixExpr(Loc loc, Ptr< Expr > lhs, Tok op, Ptr< Expr > rhs, Ptr< Expr > callee)
callee is the `op a MIM_INFIX_SUGAR operator desugars to and nullptr for MIM_INFIX_CORE.
One dom of a LamDecl: ptrn@(filter) with an optional : ret type.
Lam * emit_value(Emitter &) const
const Expr * filter() const
Dom(Loc loc, Ptr< Ptrn > ptrn, Ptr< Expr > filter, Ptr< Expr > ret_type, Ptr< IdDecl > ret)
const IdDecl * ret() const
tag dbg dom_0 ... dom_n-1: codom = body; with LamDecl::tag lam/con/fun or anonymous λ/cn/fn.
void bind_body(Scopes &) const override
const Expr * codom() const
std::tuple< Ptr< Dom > > VLA_Types
LamDecl(Loc loc, Mods mods, Tok::Tag tag, Dbg dbg, Ptr< Expr > codom, Ptr< Expr > body, const NomDecl *nom_sugar)
void emit_decl(Emitter &) const override
void emit_body(Emitter &) const override
void bind_decl(Scopes &) const override
const NomDecl * nom_sugar() const
The nom of lam I dom+ = nom I = e; I if nom I dom+ = e desugared to this; within e,...
const Dom * dom(size_t i) const
void stream_(fe::Tab &, std::ostream &) const override
Streams this declaration without modifiers and without the trailing ;.
void bind(Scopes &) const override
void emit_body_(Emitter &, const Def *decl) const override
const Def * emit_(Emitter &) const override
const LamDecl * lam() const
const Def * emit_decl_(Emitter &, const Def *type) const override
void stream(fe::Tab &, std::ostream &) const override
LamExpr(Ptr< LamDecl > lam)
void bind(Scopes &) const override
void stream(fe::Tab &, std::ostream &) const override
LetDecl(Loc loc, Mods mods, Ptr< Ptrn > ptrn, Ptr< Expr > value)
const Expr * value() const
const Ptrn * ptrn() const
void emit(Emitter &) const override
const Expr * type() const
const Def * emit_(Emitter &) const override
LitExpr(Loc loc, Tok tok, Ptr< Expr > type)
void bind(Scopes &) const override
void stream(fe::Tab &, std::ostream &) const override
ptrn => body, ctor ptrn => body, or index [ptrn] => body of a MatchExpr.
const Expr * body() const
Dbg ctor() const
The constructor in Cons (h, t); a bare Nil is an unannotated IdPtrn instead.
const Ptrn * ptrn() const
Arm(Loc loc, std::optional< nat_t > index, Dbg ctor, Ptr< Ptrn > ptrn, Ptr< Expr > body)
std::optional< nat_t > index() const
The case this arm selects by literal index, as in 1 (h, t).
void bind(Scopes &) const override
const Def * emit_(Emitter &) const override
std::tuple< Ptr< Arm > > VLA_Types
const Expr * scrutinee() const
void stream(fe::Tab &, std::ostream &) const override
const Arm * arm(size_t i) const
MatchExpr(Loc loc, Ptr< Expr > scrutinee)
void bind_decls(Scopes &) const
void bind(Scopes &) const override
void emit_decls(Emitter &) const
void emit(Emitter &) const override
ModDecl(Loc loc, Vis vis, Dbg dbg, Scope &members, fe::View< Ptr< ValDecl > > decls)
void stream(fe::Tab &, std::ostream &) const override
const Scope * scope() const override
Non-nullptr if this Decl is a module whose members a Path may walk into.
Dbg dbg() const override
The name this Decl introduces; anonymous if it has none.
std::tuple< Ptr< RecDecl > > VLA_Types
void stream(fe::Tab &, std::ostream &) const override
void bind(Scopes &) const override
void emit(Emitter &) const override
virtual void stream(fe::Tab &, std::ostream &) const =0
nom dbg = body; - a nominal newtype.
void emit_sugar(Emitter &, Lam *lam) const
Sets lam's body to this LamDecl::nom_sugar before emitting the latter's body.
const Def * emit_ahead(Emitter &) const
Emits a nom without a mutable body as soon as a sibling refers to it; nullptr on a cycle.
void bind_body(Scopes &) const override
void emit_body(Emitter &) const override
Vis rep_vis() const
The visibility of this nom's representation: that of the enclosing top-level declaration.
NomDecl(Loc loc, Mods mods, Dbg dbg, Ptr< Expr > body)
void emit_decl(Emitter &) const override
void stream_(fe::Tab &, std::ostream &) const override
Streams this declaration without modifiers and without the trailing ;.
const Def * emit_(Emitter &) const override
const Path * path() const
void bind(Scopes &) const override
PathExpr(Ptr< Path > path)
void stream(fe::Tab &, std::ostream &) const override
const Decl * decl() const
void bind(Scopes &, bool quiet=false) const
std::tuple< Dbg > VLA_Types
void stream(fe::Tab &, std::ostream &) const override
const Decl * decl() const
One dom of a PiExpr: ptrn with an optional -> ret type.
virtual void emit_type(Emitter &) const
const Expr * ret_type() const
Dom(Loc loc, Ptr< Ptrn > ptrn, Ptr< Expr > ret_type)
const Ptrn * ptrn() const
const Def * emit_(Emitter &) const override
void stream(fe::Tab &, std::ostream &) const override
void bind(Scopes &) const override
const Def * emit_decl_(Emitter &, const Def *type) const override
PiExpr(Loc loc, Tok::Tag tag, Ptr< Dom > dom, Ptr< Expr > codom)
void emit_body_(Emitter &, const Def *decl) const override
PrefixExpr(Loc loc, Tok op, Ptr< Expr > rhs)
const Def * emit_(Emitter &) const override
void bind(Scopes &) const override
void stream(fe::Tab &, std::ostream &) const override
void stream(fe::Tab &, std::ostream &) const override
const Def * emit_(Emitter &) const override
void bind(Scopes &) const override
PrimaryExpr(Loc loc, Tok::Tag tag)
Base class of all patterns.
static Ptr< Expr > to_expr(AST &, Ptr< Ptrn >)
virtual void bind(Scopes &, bool rebind, bool quiet) const =0
virtual const Def * emit_value(Emitter &, const Def *) const =0
const Def * emit_proj(Emitter &, const Def *def, size_t n, size_t i) const
Ptrn::emit_value on def's i-th of n projections - with this Ptrn's Loc, so the projection is blamed o...
virtual const Def * emit_type(Emitter &) const =0
virtual bool is_implicit() const
void emit(Emitter &) const override
void stream(fe::Tab &, std::ostream &) const override
virtual void emit_body(Emitter &) const
virtual void bind_body(Scopes &) const
bool has_mut_body() const
Only such a body is emitted as a mutable, so only it may refer to the declaration itself.
virtual void emit_decl(Emitter &) const
virtual void bind_decl(Scopes &) const
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 without modifiers and without the trailing ;.
RecDecl(Loc loc, Mods mods, Dbg dbg, Ptr< Expr > body)
const Expr * body() const
void bind(Scopes &) const override
std::pair< AnnexInfo *, sub_t > annex_sub() const override
The (AnnexInfo, sub) slot this decl registered itself under as an annex; {nullptr,...
const Ptrn * ptrn() const
void bind(Scopes &) const override
void stream(fe::Tab &, std::ostream &) const override
const Def * emit_(Emitter &) const override
RetExpr(Loc loc, Ptr< Ptrn > ptrn, Ptr< Expr > callee, Ptr< Expr > arg, Ptr< Expr > body)
const Expr * body() const
const Expr * callee() const
void bind(Scopes &) const override
const Expr * guard() const
RuleDecl(Loc loc, Mods mods, Dbg dbg, Ptr< Ptrn > var, Ptr< Expr > lhs, Ptr< Expr > rhs, Ptr< Expr > guard, bool is_norm)
void emit(Emitter &) 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 bind(Scopes &) const override
RuleExpr(Loc loc, Ptr< Expr > dom)
const Def * emit_(Emitter &) const override
void stream(fe::Tab &, std::ostream &) const override
const Expr * body() const
const IdDecl * index() const
SeqExpr(Loc loc, bool is_pack, Ptr< IdDecl > index, Ptr< Expr > shape, Ptr< Expr > body)
void bind(Scopes &) const override
void stream(fe::Tab &, std::ostream &) const override
const Def * emit_(Emitter &) const override
const Expr * shape() const
const TuplePtrn * ptrn() const
const Def * emit_decl_(Emitter &, const Def *type) const override
void emit_body_(Emitter &, const Def *decl) const override
const Def * emit_(Emitter &) const override
void bind(Scopes &) const override
void stream(fe::Tab &, std::ostream &) const override
SigmaExpr(Ptr< TuplePtrn > ptrn)
void bind(Scopes &) const override
void stream(fe::Tab &, std::ostream &) const override
SingleExpr(Loc loc, bool is_wrap, Ptr< Expr > body)
const Def * emit_(Emitter &) const override
const Expr * body() const
static constexpr Tok::Tag delim_l2r(Tag tag)
const Expr * elem(size_t i) const
void bind(Scopes &) const override
const Def * emit_(Emitter &) const override
void stream(fe::Tab &, std::ostream &) const override
std::tuple< Ptr< Expr > > VLA_Types
(ptrn_0, ..., ptrn_n-1), [ptrn_0, ..., ptrn_n-1], or {ptrn_0, ..., ptrn_n-1}
bool is_implicit() const override
void bind(Scopes &, bool rebind, bool quiet) const override
const Ptrn * ptrn(size_t i) const
std::tuple< Ptr< Ptrn > > VLA_Types
const Def * emit_type(Emitter &) const override
const Def * emit_decl(Emitter &, const Def *type) const
void stream(fe::Tab &, std::ostream &) const override
TuplePtrn(Loc loc, Tok::Tag delim_l)
Sym field(size_t i) const
The field name of ptrn(i), or the empty Sym if it binds none.
const Def * emit_value(Emitter &, const Def *) const override
const Def * emit_body(Emitter &, const Def *decl) const
const Def * emit_(Emitter &) const override
const Expr * level() const
void stream(fe::Tab &, std::ostream &) const override
TypeExpr(Loc loc, Ptr< Expr > level)
void bind(Scopes &) const override
Dbg dbg() const override
The name this decl introduces; anonymous if it splices instead.
UseDecl(Loc loc, Mods mods, Ptr< Path > path, Dbg alias)
use path [as alias|*];; no alias means as *.
const Scope * scope() const override
Non-nullptr if this Decl is a module whose members a Path may walk into.
void emit(Emitter &) 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.
void bind(Scopes &) const override
bool is_file_path() const
UseDecl(Loc loc, Mods mods, Tok::Tag tag, Ptr< Path > path, Sym file_path, Dbg alias, bool splice, const File *file)
import/plugin; name is the module name, derived from file_path if there is one.
const File * file() const
Tok::Tag tag() const
import, plugin, or use.
const Path * path() const
Module path of a use; module name of an import/plugin.
virtual void bind(Scopes &) const =0
ValDecl(Loc loc, Mods mods={})
const Mods & mods() const
bool is_extern() const override
Whether this decl crosses the Mim/native boundary (extern); body presence picks which side supplies i...
Vis vis() const override
A ValDecl's own Vis; Pub for anything else (Ptrn, Import, ...), which the priv/pub system ignores.
virtual void emit(Emitter &) const =0
bool is_anx() const override
Whether this decl is registered as a compiler-exposed annex (anx).
dbg: type of a VariantExpr.
const Expr * type() const
nullptr if omitted.
Ctor(Loc loc, Dbg dbg, Ptr< Expr > type)
void stream(fe::Tab &, std::ostream &) const override
void emit_body_(Emitter &, const Def *decl) const override
const Ctor * ctor(size_t i) const
void bind(Scopes &) const override
const Def * emit_decl_(Emitter &, const Def *type) const override
const Def * emit_(Emitter &) const override
std::tuple< Ptr< Ctor > > VLA_Types
fe::SymMap< Bind > Scope
Maps a name to the Binding introducing it.
Vis
Visibility tier of a ValDecl.
AST load_plugins(World &, fe::View< std::string >)
fe::Arena::Ref< const T > Ptr
Nodes live in the AST's Arena and are never destroyed, so this merely points at one.
AST load_plugin(World &w, std::string_view plugin)
fe::Vector< Ptr< T > > Ptrs
One name in a Scope: the Decl it introduces and the Vis of this binding.
fe::Vector< const Def * > DefVec
static constexpr flags_t flags(plugin_t p, tag_t t, sub_t s=0)
Assembles the full flags from its plugin, tag, and sub fields.
static std::optional< plugin_t > mangle(std::string_view plugin)
Mangles s into a dense 48-bit representation.
Bookkeeping of an annex introduced by an AxmDecl.
Sym qualified(Driver &driver, Sym own) const
Fully-qualified plugin.tag[.sub] name for own (this decl's own Dbg::sym), registered for by-name look...
struct mim::ast::AnnexInfo::@112046103026102051147230017206327014033073201371 sym
struct mim::ast::AnnexInfo::@177100250272201136376142224053244231100060214216 id
fe::Vector< Sym > names
The constructor or field names its variant or sigma declares, by index; an unnamed field is the empty...
plugin_t plugin_id() const
The mangled plugin part of the flags.
AnnexInfo(Sym sym_plugin, Sym sym_tag, tag_t id_tag)
flags_t base() const
The base flags (plugin + tag, no sub).
bool fields
Are AnnexInfo::names the fields of a sigma rather than the constructors of a variant?
fe::Vector< fe::Vector< Sym > > subs
List of subs which is a list of aliases.
Raw, unvalidated combination of priv/pub/extern/anx modifiers written before a declaration.
Mods inherit(const Mods &group) const
group's modifiers as defaults, so an explicit priv/pub here overrides the group's.
Vis default_vis() const
extern/anx nudge the default visibility to Pub unless priv is given explicitly.