9static constexpr const auto always_false = [](
auto&&... ) {
return false; };
11template <StringLiteral msg,
typename RetT =
void>
13 [](
auto&&... ) -> RetT {
throw std::runtime_error{
static_cast<const char*
>(msg.value)}; };
15template <auto pm,
typename R =
void>
16static constexpr const auto fwd = [](
auto&&... args) -> R {
return std::invoke(pm, args...); };
18static constexpr const auto fwd<pm, void> = [](
auto&&... args) ->
decltype(
auto) {
return std::invoke(pm, args...); };
21 auto def_clone = def.visit([
this](
auto* ast) ->
Def {
22 auto* cloned = ast->clone();
23 member->body.emplace_back(cloned);
27 auto self_ty_clone = self_ty;
28 if (self_ty.has_value())
29 self_ty_clone = self_ty->apply_generic_substitution(subs);
31 auto fn_ptr = std::make_unique<Fn>(def_clone, member, self_ty_clone, subs);
32 auto new_emplace = instantiations.emplace(subs, move(fn_ptr));
33 return *new_emplace.first->second;
37 auto existing_instantiation = instantiations.find(subs);
38 if (existing_instantiation == instantiations.end())
39 return {
false, create_instantiation(subs)};
41 return {
true, *existing_instantiation->second};
45 auto* decl_clone = st_ast.clone();
46 member->
body.emplace_back(decl_clone);
51 auto st_ptr = std::make_unique<Struct>(*decl_clone, member, self_ty, subs);
52 auto new_emplace = instantiations.emplace(subs, move(st_ptr));
53 return *new_emplace.first->second;
57 auto existing_instantiation = instantiations.find(subs);
58 if (existing_instantiation == instantiations.end())
59 return {
false, create_instantiation(subs)};
61 return {
true, *existing_instantiation->second};
66 [](
auto*
ast) {
return ast->decl_name(); });
78auto Fn::ret() const -> optional<ty::Type> {
80 [](
auto*
ast) -> optional<ty::Type> {
81 if (
auto&
ret =
ast->ret;
ret.has_value())
88 return def.
visit([](
auto* decl) {
return decl->args.size(); });
91auto Fn::arg_types() const -> vector<ty::Type> {
return visit_map_args(fwd<&ast::TypeName::ensure_ty, ty::Type>); }
92auto Fn::arg_names() const -> vector<
string> {
return visit_map_args(fwd<&ast::TypeName::name, string>); }
94 return def.
visit([](
auto*
ast) ->
const auto& {
return ast->args; });
97 return visit_map_args([](
auto& arg) {
return FnArg(arg.ensure_ty(), arg.name, arg); });
120 [&name](
auto* ast) {
return ast->annotations.contains(name); });
125 always_throw<
"Cannot make non-function declaration external">);
129 return def.
visit([](
ast::FnDecl* fn_decl) ->
auto& {
return get<ast::Compound>(fn_decl->
body); },
130 [](
ast::CtorDecl* ct_decl) ->
auto& {
return ct_decl->body; },
virtual void visit(Visitor &visitor) const =0
Recursively visit this ast node and all its constituents.
Statements make up most things in source code.
static constexpr const auto fwd< pm, void >
static constexpr const auto always_throw
static constexpr const auto always_false
static constexpr const auto fwd
auto name() const noexcept -> string
A function declaration in the compiler.
optional< ty::Type > self_ty
If this function is in the body of a struct, this points to its type. Used for the self type.
auto arg_names() const -> vector< string >
auto fn_body() -> ast::FnDecl::Body &
auto create_instantiation(Substitutions &subs) noexcept -> Fn &
auto primitive() const -> bool
auto compound_body() -> ast::Compound &
auto local() const -> bool
Def def
The ast node that defines this declaration.
auto extern_decl() const -> bool
auto arg_types() const -> vector< ty::Type >
auto extern_linkage() const -> bool
auto varargs() const -> bool
auto abstract() const -> bool
auto args() const -> vector< FnArg >
auto arg_count() const -> size_t
auto ast() const -> const ast::Stmt &
void make_extern_linkage(bool value=true)
auto has_annotation(const string &name) const -> bool
auto arg_nodes() const -> const vector< ast::TypeName > &
auto ret() const -> optional< ty::Type >
auto name() const noexcept -> string
auto get_or_create_instantiation(Substitutions &subs) noexcept -> std::pair< bool, Fn & >
A struct declaration in the compiler.
auto name() const noexcept -> string
auto body() const noexcept -> const auto &
auto get_or_create_instantiation(Substitutions &subs) noexcept -> std::pair< bool, Struct & >
auto create_instantiation(Substitutions &subs) noexcept -> Struct &
A statement consisting of multiple other statements, i.e. the body of a function.
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
A declaration of a custom constructor (def :new).
A declaration of a function (def).
auto extern_linkage() const -> bool
Body body
If this function declaration refers to a primitive, this field is a string representing the name of t...
void make_extern_linkage(bool value=true)
auto extern_decl() const -> bool
auto primitive() const -> bool
auto abstract() const -> bool
A local definition of an anonymous function.
auto visit(Us... us) -> decltype(auto)