52#define CODE(name, ...) name,
60#define CODE(name, assoc) \
61 case Prec::name: return Assoc::assoc;
87 m(K_Level, "Level" ) \
94 m(K_extern, "extern") \
103 m(K_import, "import") \
107 m(K_match, "match" ) \
109 m(K_mutual, "mutual") \
112 m(K_plugin, "plugin") \
122 m(K_where, "where" ) \
125#define CODE(t, str) + size_t(1)
130 m(EoF, "<end of file>" ) \
132 m(L_s, "<signed integer literal>") \
133 m(L_u, "<integer literal>" ) \
134 m(L_i, "<index literal>" ) \
135 m(L_f, "<floating-point literal>") \
136 m(L_c, "<char literal>" ) \
137 m(L_str, "<string literal>" ) \
139 m(M_id, "<identifier>" ) \
154 m(T_fat_arrow, "=>") \
175 m(T_semicolon, ";") \
189#define MIM_PREFIX(m) \
198#define MIM_INFIX_SUGAR(m) \
202 m(T_le, "<=", Rel ) \
204 m(T_ge, ">=", Rel ) \
205 m(T_shl, "<<", Shift) \
206 m(T_shr, ">>", Shift) \
207 m(T_add, "+", Add ) \
208 m(T_sub, "-", Add ) \
209 m(T_star, "*", Mul ) \
210 m(T_div, "/", Mul ) \
214#define MIM_INFIX_CORE(m) \
215 m(T_extract, "#", Extract) \
216 m(T_union, "∪", Union ) \
217 m(K_inj, "inj", Inj ) \
218 m(T_arrow_r, "→", Arrow ) \
219 m(T_arrow_l, "←", Ins ) \
222#define MIM_INFIX(m) MIM_INFIX_SUGAR(m) MIM_INFIX_CORE(m)
225#define MIM_SUBST(m) \
230#define CODE(str, t) + size_t(1)
240#define CODE(t, str) t,
248 if (
tag == Tag::Nil)
return false;
251#define CODE(str, t) case Tag::t:
255 default:
return false;
261#define CODE(t, str) case Tag::t:
265 default:
return false;
271#define CODE(t, str, prec) \
272 case Tag::t: return Prec::prec;
281#define CODE(t, str, prec) \
282 case Tag::t: return "`" str;
290 return Tag::D_angle_l <=
tag &&
tag <= Tag::D_quote_r && (
int(
tag) -
int(Tag::D_angle_l)) % 2 == 1;
311 , u_(std::bit_cast<uint64_t>(s)) {}
315 , u_(std::bit_cast<uint64_t>(d)) {}
317 Tok(Loc
loc, uint64_t size, uint64_t val)
333 Loc
loc()
const {
return loc_; }
334 explicit operator bool()
const {
return tag_ != Tag::Nil; }
336 std::pair<uint64_t, uint64_t>
lit_i()
const { assert(
isa(Tag::L_i));
return {idx_.size, idx_.val}; }
337 char8_t lit_c()
const { assert(
isa(Tag::L_c));
return c_; }
338 uint64_t
lit_u()
const { assert(
isa(Tag::L_u ) ||
isa(Tag::L_s ) ||
isa(Tag::L_f ));
return u_; }
341 std::string
str()
const;
363template<>
struct std::formatter<
mim::ast::Tok > : fe::ostream_formatter {};
364template<>
struct std::formatter<
mim::ast::Tok::Tag> : fe::ostream_formatter {};
static constexpr bool is_delim_r(Tag tag)
Tok(Loc loc, Tag tag, Sym sym)
Tok(Loc loc, uint64_t size, uint64_t val)
size and val of an Idx literal; World::lit_idx makes a Lit of it at emit time.
static constexpr std::string_view infix_sym(Tag tag)
Name the infix operator tag desugars to - including the leading ` ; empty for MIM_INFIX_CORE.
std::pair< uint64_t, uint64_t > lit_i() const
static constexpr std::optional< Prec > infix_prec(Tag tag)
Precedence of the infix operator tag; std::nullopt if tag isn't one.
static constexpr Tok::Tag delim_l2r(Tag tag)
static constexpr bool is_prefix(Tag tag)
Is tag a prefix operator?
friend std::ostream & operator<<(std::ostream &os, Tok::Tag tag)
static const char * tag2str(Tok::Tag)
static constexpr bool is_key(Tag tag)
Is tag something the keyword table yields? MIM_KEY occupies [1, Num_Keys]; MIM_SUBST adds a few more.
Assoc
Associativity of an infix expression.
constexpr bool is_rassoc(Prec p)
constexpr bool should_reduce(Prec curr, Prec op)
Should a Pratt parser reduce when the current binding power is curr and the infix operator has preced...
std::ostream & operator<<(std::ostream &os, Tok tok)
constexpr Assoc prec_assoc(Prec p)
Associativity of precedence level p.
Prec
Expression precedences used by the parser and the dumper; ordered low to high.
#define MIM_INFIX_SUGAR(m)
a str b is sugar for `str (a, b) ; what `str means is up to whatever the user binds it to.
#define MIM_PREFIX(m)
# is a prefix operator and an infix one; which one it is depends on the position it occurs in.