From 5a7aca0a9a91e380e69d0177688a1d1c935509d7 Mon Sep 17 00:00:00 2001 From: Andrew Lamb <andrew@nerdnetworks.org> Date: Tue, 26 Nov 2024 11:39:58 -0500 Subject: [PATCH] Add more peek --- src/parser/mod.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 94dac54d7..35dfe1f4e 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -3278,6 +3278,12 @@ impl<'a> Parser<'a> { self.peek_nth_token(0) } + /// Return the first non-whitespace token that has not yet been processed + /// (or None if reached end-of-file) + pub fn peek_token_ref(&self) -> &TokenWithLocation { + self.peek_nth_token_ref(0) + } + /// Returns the `N` next non-whitespace tokens that have not yet been /// processed. /// @@ -3305,6 +3311,11 @@ impl<'a> Parser<'a> { .map(|with_loc| with_loc.token) } + pub fn peek_tokens_ref<const N: usize>(&self) -> [&Token; N] { + self.peek_tokens_with_location_ref() + .map(|with_loc| &with_loc.token) + } + /// Returns the `N` next non-whitespace tokens with locations that have not /// yet been processed. /// @@ -3328,6 +3339,26 @@ impl<'a> Parser<'a> { }) } + pub fn peek_tokens_with_location_ref<const N: usize>(&self) -> [&TokenWithLocation; N] { + let mut index = self.index; + core::array::from_fn(|_| loop { + let token = self.tokens.get(index); + index += 1; + if let Some(TokenWithLocation { + token: Token::Whitespace(_), + span: _, + }) = token + { + continue; + } + if let Some(tok) = token { + return tok; + } else { + return eof_token(); + }; + }) + } + /// Return nth non-whitespace token that has not yet been processed pub fn peek_nth_token(&self, n: usize) -> TokenWithLocation { self.peek_nth_token_ref(n).clone() @@ -3458,6 +3489,13 @@ impl<'a> Parser<'a> { } } + pub fn parse_keyword_token_ref(&mut self, expected: Keyword) -> Option<&TokenWithLocation> { + match &self.peek_token_ref().token { + Token::Word(w) if expected == w.keyword => Some(self.next_token_ref()), + _ => None, + } + } + #[must_use] pub fn peek_keyword(&mut self, expected: Keyword) -> bool { matches!(self.peek_token().token, Token::Word(w) if expected == w.keyword)