1use std::fmt;
4
5use rustc_span::{Symbol, edition::Edition};
6
7use crate::{
8 ParseCtxt, ParseError, ParseResult,
9 lexer::{Token, TokenKind},
10 surface::BinOp,
11 symbols,
12};
13
14#[derive(Debug)]
16pub enum Expected {
17 Str(&'static str),
18 Sym(Symbol),
19}
20
21impl fmt::Display for Expected {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 match self {
24 Expected::Str(descr) => write!(f, "{descr}"),
25 Expected::Sym(sym) => write!(f, "{sym}"),
26 }
27 }
28}
29
30pub(crate) trait Peek: Copy {
32 fn matches(self, tok: TokenKind, edition: Edition) -> bool;
36}
37
38pub(crate) trait PeekExpected: Peek {
46 fn expected(self) -> Expected;
47}
48
49impl Peek for TokenKind {
51 fn matches(self, tok: TokenKind, _: Edition) -> bool {
52 self == tok
53 }
54}
55impl PeekExpected for TokenKind {
56 fn expected(self) -> Expected {
57 Expected::Str(TokenKind::descr(&self))
58 }
59}
60
61#[derive(Clone, Copy)]
63pub(crate) struct NonReserved;
64impl Peek for NonReserved {
65 fn matches(self, tok: TokenKind, edition: Edition) -> bool {
66 match tok {
67 TokenKind::Ident(sym) => !symbols::is_reserved(sym, edition),
68 _ => false,
69 }
70 }
71}
72impl PeekExpected for NonReserved {
73 fn expected(self) -> Expected {
74 Expected::Str("identifier")
75 }
76}
77
78#[derive(Clone, Copy)]
80pub(crate) struct AnyLit;
81impl Peek for AnyLit {
82 fn matches(self, tok: TokenKind, _: Edition) -> bool {
83 matches!(tok, TokenKind::Literal(_))
84 }
85}
86impl PeekExpected for AnyLit {
87 fn expected(self) -> Expected {
88 Expected::Str("literal")
89 }
90}
91
92#[derive(Clone, Copy)]
99pub(crate) struct RAngle;
100impl Peek for RAngle {
101 fn matches(self, tok: TokenKind, _: Edition) -> bool {
102 matches!(tok, TokenKind::GtFollowedByGt | TokenKind::Gt)
103 }
104}
105impl PeekExpected for RAngle {
106 fn expected(self) -> Expected {
107 Expected::Str(">")
108 }
109}
110
111#[derive(Clone, Copy)]
116pub(crate) struct LAngle;
117impl Peek for LAngle {
118 fn matches(self, tok: TokenKind, _: Edition) -> bool {
119 matches!(tok, TokenKind::LtFollowedByLt | TokenKind::Lt)
120 }
121}
122impl PeekExpected for LAngle {
123 fn expected(self) -> Expected {
124 Expected::Str("<")
125 }
126}
127
128impl Peek for Symbol {
130 fn matches(self, tok: TokenKind, _: Edition) -> bool {
131 matches!(tok, TokenKind::Ident(sym) if sym == self)
132 }
133}
134impl PeekExpected for Symbol {
135 fn expected(self) -> Expected {
136 Expected::Sym(self)
137 }
138}
139
140#[derive(Clone, Copy)]
142pub(crate) struct AnyOf<T, const N: usize>(pub [T; N]);
143impl<T: Peek, const N: usize> Peek for AnyOf<T, N> {
144 fn matches(self, tok: TokenKind, edition: Edition) -> bool {
145 self.0.into_iter().any(|t| t.matches(tok, edition))
146 }
147}
148
149impl<F: FnOnce(TokenKind) -> bool + Copy> Peek for F {
151 fn matches(self, tok: TokenKind, _: Edition) -> bool {
152 (self)(tok)
153 }
154}
155
156pub(crate) struct Lookahead1<'a, 'cx> {
164 expected: Vec<Expected>,
166 cx: &'a mut ParseCtxt<'cx>,
167}
168
169impl<'a, 'cx> Lookahead1<'a, 'cx> {
170 fn new(cx: &'a mut ParseCtxt<'cx>) -> Self {
171 Lookahead1 { expected: Vec::new(), cx }
172 }
173
174 pub(crate) fn peek<T: PeekExpected>(&mut self, t: T) -> bool {
178 self.expected.push(t.expected());
179 self.cx.peek(t)
180 }
181
182 pub(crate) fn advance_if<T: PeekExpected>(&mut self, t: T) -> bool {
186 self.expected.push(t.expected());
187 self.cx.advance_if(t)
188 }
189
190 pub(crate) fn into_error(self) -> ParseError {
193 self.cx.unexpected_token(self.expected)
194 }
195}
196
197impl<'cx> ParseCtxt<'cx> {
198 pub(crate) fn at(&mut self, n: usize) -> Token {
200 self.tokens.at(n)
201 }
202
203 pub(crate) fn peek<T: Peek>(&mut self, t: T) -> bool {
206 self.peek_at(0, t)
207 }
208
209 pub(crate) fn peek2<T1: Peek, T2: Peek>(&mut self, t1: T1, t2: T2) -> bool {
211 self.peek_at(0, t1) && self.peek_at(1, t2)
212 }
213
214 pub(crate) fn peek3<T1: Peek, T2: Peek, T3: Peek>(&mut self, t1: T1, t2: T2, t3: T3) -> bool {
216 self.peek_at(0, t1) && self.peek_at(1, t2) && self.peek_at(2, t3)
217 }
218
219 fn peek_at<T: Peek>(&mut self, n: usize, t: T) -> bool {
220 let tok = self.at(n);
221 t.matches(tok.kind, self.edition)
222 }
223
224 pub(crate) fn peek_binop(&mut self) -> Option<(BinOp, usize)> {
228 let op = match self.at(0).kind {
229 TokenKind::Iff => (BinOp::Iff, 1),
230 TokenKind::FatArrow => (BinOp::Imp, 1),
231 TokenKind::OrOr => (BinOp::Or, 1),
232 TokenKind::AndAnd => (BinOp::And, 1),
233 TokenKind::EqEq => (BinOp::Eq, 1),
234 TokenKind::Ne => (BinOp::Ne, 1),
235 TokenKind::Lt => (BinOp::Lt, 1),
236 TokenKind::Gt => (BinOp::Gt, 1),
237 TokenKind::Le => (BinOp::Le, 1),
238 TokenKind::Ge => (BinOp::Ge, 1),
239 TokenKind::Caret => (BinOp::BitOr, 1),
240 TokenKind::And => (BinOp::BitAnd, 1),
241 TokenKind::LtFollowedByLt => (BinOp::BitShl, 2),
242 TokenKind::GtFollowedByGt => (BinOp::BitShr, 2),
243 TokenKind::Plus => (BinOp::Add, 1),
244 TokenKind::Minus => (BinOp::Sub, 1),
245 TokenKind::Star => (BinOp::Mul, 1),
246 TokenKind::Slash => (BinOp::Div, 1),
247 TokenKind::Percent => (BinOp::Mod, 1),
248 _ => return None,
249 };
250 Some(op)
251 }
252
253 pub(crate) fn advance(&mut self) {
255 self.tokens.advance();
256 }
257
258 pub(crate) fn advance_by(&mut self, n: usize) {
260 self.tokens.advance_by(n);
261 }
262
263 pub(crate) fn advance_if<T: Peek>(&mut self, t: T) -> bool {
266 if self.peek(t) {
267 self.advance();
268 true
269 } else {
270 false
271 }
272 }
273
274 pub(crate) fn advance_if2<T1: Peek, T2: Peek>(&mut self, t1: T1, t2: T2) -> bool {
276 if self.peek2(t1, t2) {
277 self.advance_by(2);
278 true
279 } else {
280 false
281 }
282 }
283
284 pub(crate) fn expect<T: PeekExpected>(&mut self, t: T) -> ParseResult {
287 if self.advance_if(t) { Ok(()) } else { Err(self.unexpected_token(vec![t.expected()])) }
288 }
289
290 pub(crate) fn lookahead1(&mut self) -> Lookahead1<'_, 'cx> {
292 Lookahead1::new(self)
293 }
294}