3using namespace std::literals;
14 std::ostream&
stream(
Tab&, std::ostream& os)
const override {
return os <<
"<dummy>"; }
19 using Scope = fe::SymMap<std::pair<Loc, const Decl*>>;
32 void push() { scopes_.emplace_back(); }
35 assert(!scopes_.empty());
40 if (dbg.is_anon())
return nullptr;
42 for (
auto& scope : scopes_ | std::ranges::views::reverse)
43 if (
auto i = scope.find(dbg.sym()); i != scope.end())
return i->second.second;
46 ast().
error(dbg.loc(),
"'{}' not found", dbg.sym());
52 void bind(
Dbg dbg,
const Decl* decl,
bool rebind =
false,
bool quiet =
false) {
53 if (dbg.is_anon())
return;
56 top()[dbg.sym()] = std::pair(dbg.loc(), decl);
57 }
else if (
auto [i, ins] =
top().emplace(dbg.sym(), std::pair(dbg.loc(), decl)); !ins) {
58 auto [prev_loc, prev_decl] = i->second;
59 if (!quiet && !prev_decl->isa<
DummyDecl>()) {
60 ast().
error(dbg.loc(),
"redeclaration of '{}'", dbg);
61 ast().
note(prev_loc,
"previous declaration here");
69 std::deque<Scope> scopes_;
70 absl::flat_hash_map<plugin_t, tag_t> plugin2tag_;
84 for (
const auto&
import :
imports())
import->bind(s);
85 for (
const auto& decl :
decls()) decl->bind(s);
99 s.bind(
dbg(),
this, rebind, quiet);
104 s.bind(
dbg(),
this, rebind, quiet);
108 for (
const auto&
ptrn :
ptrns())
ptrn->bind(s, rebind, quiet);
116void IdExpr ::bind(
Scopes& s)
const { decl_ = s.find(
dbg()); }
126 if (
tag() == Tag::L_str ||
tag() == Tag::L_c ||
tag() == Tag::L_i)
127 s.ast().error(
type()->
loc(),
"a {} shall not have a type annotation",
tag());
129 if (
tag() == Tag::L_f) s.ast().error(
loc(),
"type annotation mandatory for floating point literal");
135 for (
const auto& decl :
decls() | std::ranges::views::reverse) decl->bind(s);
137 for (
const auto& decl :
decls()) decl->bind(s);
155 if (tag() == Tag::K_Cn) s.ast().error(codom()->
loc(),
"a continuation shall not have a codomain");
174 ptrn()->bind(s,
true,
false);
180 ptrn()->bind(s,
false,
false);
190 shape()->bind(s,
false,
false);
203 auto dbg = std::get<Dbg>(
index());
204 decl_ = s.find(dbg,
true);
221 auto sym = s.ast().sym(axiom->
dbg().
sym().str() +
"."s +
dbg().sym().str());
228 annex_ = s.ast().name2annex(
dbg(),
nullptr);
232 else if (annex_->normalizer.sym() !=
normalizer().sym()) {
234 s.ast().error(l,
"normalizer mismatch for axiom '{}'",
dbg());
235 if (
auto norm = annex_->normalizer)
236 s.ast().note(norm.loc(),
"previous normalizer '{}'", norm);
238 s.ast().note(l,
"initially no normalizer specified");
244 if (
auto old = s.find(
dbg(),
true)) {
245 if (
auto old_ax = old->isa<
AxiomDecl>()) {
246 if (old_ax->num_subs() == 0) {
247 s.ast().error(
dbg().
loc(),
"redeclared sub-less axiom '{}' with subs",
dbg());
248 s.ast().note(old_ax->dbg().loc(),
"previous location here");
252 for (
const auto& aliases :
subs())
253 for (
const auto& alias : aliases) alias->bind(s,
this);
261 ptrn()->bind(s,
true,
false);
263 if (
auto id =
ptrn()->isa<IdPtrn>()) annex_ = s.ast().name2annex(id->dbg(), &sub_);
267 for (
auto curr =
this; curr; curr = curr->next()) curr->bind_decl(s);
268 for (
auto curr =
this; curr; curr = curr->next()) curr->bind_body(s);
269 annex_ = s.ast().name2annex(
dbg(), &sub_);
273 if (
auto t =
type()) t->bind(s);
274 if (!
type()->isa<HoleExpr>() &&
body()->isa<LamExpr>())
275 s.ast().warn(
type()->
loc(),
"type of recursive declaration ignored for function expression");
277 if (!
body()->isa<LamExpr>() && !
body()->isa<PiExpr>() && !
body()->isa<ArrowExpr>() && !
body()->isa<SigmaExpr>())
278 s.ast().error(
body()->
loc(),
"unsupported expression for a recursive declaration");
292 for (
size_t i = 0, e =
num_doms(); i != e; ++i)
dom(i)->bind(s);
294 if (
auto filter =
doms().back()->filter()) {
296 if (pe->tag() == Tag::K_tt && (
tag() == Tag::K_lam ||
tag() == Tag::T_lm))
297 s.ast().warn(filter->loc(),
298 "'tt'-filter superfluous as the last curried function group of a '{}' receives a "
299 "'tt'-filter by default",
301 if (pe->tag() == Tag::K_ff && (
tag() != Tag::K_lam &&
tag() != Tag::T_lm))
302 s.ast().warn(filter->loc(),
303 "'ff'-filter superfluous as the last curried function group of a '{}' receives a "
304 "'ff'-filter by default",
310 if (
tag() == Tag::K_con ||
tag() == Tag::K_cn)
311 s.ast().error(
codom()->
loc(),
"a continuation shall not have a codomain");
317 annex_ = s.ast().name2annex(
dbg(), &sub_);
322 for (
const auto&
dom :
doms())
dom->bind(s,
true);
329 dom()->bind(s,
false,
false);
Some "global" variables needed all over the place.
Keeps track of indentation level.
Error & note(Loc loc, const char *fmt, Args &&... args) const
const Ptrn * ptrn() const
void bind(Scopes &, bool rebind, bool quiet) const override
void bind(Scopes &) const override
const Expr * callee() const
const Expr * body() const
const IdPtrn * shape() const
void bind(Scopes &) const override
void bind(Scopes &) const override
void bind(Scopes &, const AxiomDecl *) const
const auto & subs() const
AxiomDecl(Loc loc, Dbg dbg, std::deque< Ptrs< Alias > > &&subs, Ptr< Expr > &&type, Dbg normalizer, Tok curry, Tok trip)
void bind(Scopes &) const override
const Expr * type() const
const Expr * codom() const
void bind(Scopes &) const override
const Expr * expr() const
const auto & decls() const
void bind(Scopes &) const override
std::ostream & stream(Tab &, std::ostream &os) const override
void bind(Scopes &, bool rebind, bool quiet) const override
virtual void bind(Scopes &) const =0
void bind(Scopes &, bool rebind, bool quiet) const override
void bind(Scopes &, bool rebind, bool quiet) const override
const Expr * type() const
void bind(Scopes &) const
const Module * module() const
const Expr * index() const
void bind(Scopes &) const override
const Expr * tuple() const
const Expr * value() const
const Expr * filter() const
void bind(Scopes &scopes, bool quiet=false) const override
void bind_body(Scopes &) const override
const Ptrs< Dom > & doms() const
const Expr * codom() const
void bind_decl(Scopes &) const override
const Dom * dom(size_t i) const
void bind(Scopes &) const override
const LamDecl * lam() const
void bind(Scopes &) const override
const Expr * value() const
const Ptrn * ptrn() const
const Expr * type() const
void bind(Scopes &) const override
const auto & decls() const
const auto & implicit_imports() const
const auto & imports() const
virtual void bind(Scopes &scopes, bool quiet=false) const
const IdPtrn * ret() const
const Ptrn * ptrn() const
void bind(Scopes &) const override
void bind(Scopes &) const override
virtual void bind(Scopes &, bool rebind, bool quiet) const =0
virtual void bind_body(Scopes &) const
virtual void bind_decl(Scopes &) const
const Expr * body() const
const Expr * type() const
void bind(Scopes &) const override
const Ptrn * ptrn() const
void bind(Scopes &) const override
const Expr * body() const
const Expr * callee() const
const Decl * dummy() const
const Decl * find(Dbg dbg, bool quiet=false)
void bind(Dbg dbg, const Decl *decl, bool rebind=false, bool quiet=false)
fe::SymMap< std::pair< Loc, const Decl * > > Scope
const TuplePtrn * ptrn() const
void bind(Scopes &) const override
const Expr * elem(size_t i) const
void bind(Scopes &) const override
const auto & elems() const
void bind(Scopes &, bool rebind, bool quiet) const override
const Ptrn * ptrn(size_t i) const
const auto & ptrns() const
const Expr * level() const
const Expr * inhabitant() const
void bind(Scopes &) const override
fe::Arena::Ptr< const T > Ptr