9class Axm :
public Def,
public Setters<Axm> {
46 static std::tuple<const Axm*, u8, u8>
get(
const Def* def);
50 static std::tuple<const Axm*, u8, u8>
next(
const Def* callee);
73 template<
class Id,
class D>
75 static_assert(
Annex::num<Id>() != size_t(-1),
"invalid number of sub tags");
86 const Axm*
axm()
const {
return axm_; }
88 operator const D*()
const {
return def_; }
89 explicit operator bool()
const {
return axm_ !=
nullptr; }
103 const Axm* axm_ =
nullptr;
104 const D* def_ =
nullptr;
111 template<
class Id, u8 Curry = 0,
bool DynCast = true>
112 static auto isa(
const Def* def) {
113 using D = std::conditional_t<Curry == 0, typename Axm::IsANode<Id>::type, Def>;
118 assert(cond &&
"assumed to be correct axm");
122 template<
class Id, u8 Curry = 0,
bool DynCast = true>
123 static auto isa(Id
id,
const Def* def) {
124 using D = std::conditional_t<Curry == 0, typename Axm::IsANode<Id>::type, Def>;
126 bool cond = axm &&
curry == Curry && axm->flags() == (
flags_t)
id;
129 assert(cond &&
"assumed to be correct axm");
141 template<
class Id,
u8 Curry = 0,
class... Args>
142 static auto expect(
const Def* def, std::format_string<Args...> fmt, Args&&... args) {
144 fe::throwf(
"expected {}, but got `{}`", std::format(fmt, std::forward<Args>(args)...), def);
178template<
class Id,
class D>
179struct std::formatter<
mim::Axm::IsA<Id, D>> : fe::ostream_formatter {};
auto id() const
Axm::flags cast to Id.
const D * operator->() const
IsA(const Axm *axm, const D *def)
static auto as(Id id, const Def *def)
static std::tuple< const Axm *, u8, u8 > next(const Def *callee)
Like Axm::get, but advances the counter as one more App is about to be built on top of callee.
static auto isa(const Def *def)
static auto isa(Id id, const Def *def)
static constexpr size_t Num_Ops
NormalizeFn normalizer() const
static std::pair< u8, u8 > infer_curry_and_trip(const Def *type)
static auto as(const Def *def)
static constexpr u8 Trip_End
static constexpr auto Node
static auto expect(const Def *def, std::format_string< Args... > fmt, Args &&... args)
Like Axm::as but - instead of merely asserting in Debug builds - throws a formatted mim::error when d...
static std::tuple< const Axm *, u8, u8 > get(const Def *def)
Yields currying counter of def.
Def * set(size_t i, const Def *)
Successively set from left to right.
constexpr flags_t flags() const noexcept
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
CRTP-based mixin to declare setters for Def::loc & Def::name using a covariant return type.
constexpr bool is_commutative(Id)
const Def *(*)(const Def *, const Def *, const Def *) NormalizeFn
constexpr bool is_associative(Id id)
static constexpr tag_t flags2tag(flags_t f)
Yields the tag part of the name as integer.
static constexpr sub_t flags2sub(flags_t f)
Yields the sub part of the name as integer.
static constexpr plugin_t flags2plugin(flags_t f)
static consteval size_t num()
static consteval flags_t base()
static constexpr flags_t flags2base(flags_t f)
Includes Axm::plugin() and Axm::tag() but not Axm::sub.