51#define CODE(name, ...) name,
59#define CODE(name, assoc) \
60 case Prec::name: return Assoc::assoc;
95 m(K_extern, "extern") \
104 m(K_import, "import") \
108 m(K_match, "match" ) \
111 m(K_plugin, "plugin") \
121 m(K_where, "where" ) \
124#define CODE(t, str) + size_t(1)
129 m(EoF, "<end of file>" ) \
131 m(L_s, "<signed integer literal>") \
132 m(L_u, "<integer literal>" ) \
133 m(L_i, "<index literal>" ) \
134 m(L_f, "<floating-point literal>") \
135 m(L_c, "<char literal>" ) \
136 m(L_str, "<string literal>" ) \
138 m(M_id, "<identifier>" ) \
155 m(T_fat_arrow, "=>") \
176 m(T_semicolon, ";") \
189#define MIM_INFIX_SUGAR(m) \
193 m(T_le, "<=", Rel ) \
195 m(T_ge, ">=", Rel ) \
196 m(T_shl, "<<", Shift) \
197 m(T_shr, ">>", Shift) \
198 m(T_add, "+", Add ) \
199 m(T_sub, "-", Add ) \
200 m(T_star, "*", Mul ) \
201 m(T_div, "/", Mul ) \
205#define MIM_INFIX_CORE(m) \
206 m(T_extract, "#", Extract) \
207 m(T_union, "∪", Union ) \
208 m(K_inj, "inj", Inj ) \
209 m(T_arrow_r, "→", Arrow ) \
210 m(T_arrow_l, "←", Ins ) \
213#define MIM_INFIX(m) MIM_INFIX_SUGAR(m) MIM_INFIX_CORE(m)
216#define MIM_SUBST(m) \
221#define CODE(str, t) + size_t(1)
231#define CODE(t, str) t,
239 if (
tag == Tag::Nil)
return false;
242#define CODE(str, t) case Tag::t:
246 default:
return false;
252#define CODE(t, str, prec) \
253 case Tag::t: return Prec::prec;
262#define CODE(t, str, prec) \
263 case Tag::t: return "`" str;
271 return Tag::D_angle_l <=
tag &&
tag <= Tag::D_quote_r && (
int(
tag) -
int(Tag::D_angle_l)) % 2 == 1;
292 , u_(std::bit_cast<uint64_t>(s)) {}
296 , u_(std::bit_cast<uint64_t>(d)) {}
298 Tok(Loc
loc, uint64_t size, uint64_t val)
314 Loc
loc()
const {
return loc_; }
315 explicit operator bool()
const {
return tag_ != Tag::Nil; }
317 std::pair<uint64_t, uint64_t>
lit_i()
const { assert(
isa(Tag::L_i));
return {idx_.size, idx_.val}; }
318 char8_t lit_c()
const { assert(
isa(Tag::L_c));
return c_; }
319 uint64_t
lit_u()
const { assert(
isa(Tag::L_u ) ||
isa(Tag::L_s ) ||
isa(Tag::L_f ));
return u_; }
322 std::string
str()
const;
344template<>
struct std::formatter<
mim::ast::Tok > : fe::ostream_formatter {};
345template<>
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)
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.
constexpr bool is_lassoc(Prec p)
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.