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)