diff options
Diffstat (limited to 'crates/libsyntax2/src/lexer/ptr.rs')
-rw-r--r-- | crates/libsyntax2/src/lexer/ptr.rs | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/crates/libsyntax2/src/lexer/ptr.rs b/crates/libsyntax2/src/lexer/ptr.rs index d1391fd5f..aa59e33cc 100644 --- a/crates/libsyntax2/src/lexer/ptr.rs +++ b/crates/libsyntax2/src/lexer/ptr.rs | |||
@@ -2,12 +2,14 @@ use TextUnit; | |||
2 | 2 | ||
3 | use std::str::Chars; | 3 | use std::str::Chars; |
4 | 4 | ||
5 | /// A simple view into the characters of a string. | ||
5 | pub(crate) struct Ptr<'s> { | 6 | pub(crate) struct Ptr<'s> { |
6 | text: &'s str, | 7 | text: &'s str, |
7 | len: TextUnit, | 8 | len: TextUnit, |
8 | } | 9 | } |
9 | 10 | ||
10 | impl<'s> Ptr<'s> { | 11 | impl<'s> Ptr<'s> { |
12 | /// Creates a new `Ptr` from a string. | ||
11 | pub fn new(text: &'s str) -> Ptr<'s> { | 13 | pub fn new(text: &'s str) -> Ptr<'s> { |
12 | Ptr { | 14 | Ptr { |
13 | text, | 15 | text, |
@@ -15,45 +17,55 @@ impl<'s> Ptr<'s> { | |||
15 | } | 17 | } |
16 | } | 18 | } |
17 | 19 | ||
20 | /// Gets the length of the remaining string. | ||
18 | pub fn into_len(self) -> TextUnit { | 21 | pub fn into_len(self) -> TextUnit { |
19 | self.len | 22 | self.len |
20 | } | 23 | } |
21 | 24 | ||
22 | pub fn next(&self) -> Option<char> { | 25 | /// Gets the current character, if one exists. |
26 | pub fn current(&self) -> Option<char> { | ||
23 | self.chars().next() | 27 | self.chars().next() |
24 | } | 28 | } |
25 | 29 | ||
26 | pub fn nnext(&self) -> Option<char> { | 30 | /// Gets the nth character from the current. |
27 | let mut chars = self.chars(); | 31 | /// For example, 0 will return the current token, 1 will return the next, etc. |
28 | chars.next()?; | 32 | pub fn nth(&self, n: u32) -> Option<char> { |
29 | chars.next() | 33 | let mut chars = self.chars().peekable(); |
34 | chars.by_ref().skip(n as usize).next() | ||
30 | } | 35 | } |
31 | 36 | ||
32 | pub fn next_is(&self, c: char) -> bool { | 37 | /// Checks whether the current character is `c`. |
33 | self.next() == Some(c) | 38 | pub fn at(&self, c: char) -> bool { |
39 | self.current() == Some(c) | ||
34 | } | 40 | } |
35 | 41 | ||
36 | pub fn nnext_is(&self, c: char) -> bool { | 42 | /// Checks whether the next characters match `s`. |
37 | self.nnext() == Some(c) | 43 | pub fn at_str(&self, s: &str) -> bool { |
44 | let chars = self.chars(); | ||
45 | chars.as_str().starts_with(s) | ||
38 | } | 46 | } |
39 | 47 | ||
40 | pub fn next_is_p<P: Fn(char) -> bool>(&self, p: P) -> bool { | 48 | /// Checks whether the current character satisfies the predicate `p`. |
41 | self.next().map(p) == Some(true) | 49 | pub fn at_p<P: Fn(char) -> bool>(&self, p: P) -> bool { |
50 | self.current().map(p) == Some(true) | ||
42 | } | 51 | } |
43 | 52 | ||
44 | pub fn nnext_is_p<P: Fn(char) -> bool>(&self, p: P) -> bool { | 53 | /// Checks whether the nth character satisfies the predicate `p`. |
45 | self.nnext().map(p) == Some(true) | 54 | pub fn nth_is_p<P: Fn(char) -> bool>(&self, n: u32, p: P) -> bool { |
55 | self.nth(n).map(p) == Some(true) | ||
46 | } | 56 | } |
47 | 57 | ||
58 | /// Moves to the next character. | ||
48 | pub fn bump(&mut self) -> Option<char> { | 59 | pub fn bump(&mut self) -> Option<char> { |
49 | let ch = self.chars().next()?; | 60 | let ch = self.chars().next()?; |
50 | self.len += TextUnit::of_char(ch); | 61 | self.len += TextUnit::of_char(ch); |
51 | Some(ch) | 62 | Some(ch) |
52 | } | 63 | } |
53 | 64 | ||
65 | /// Moves to the next character as long as `pred` is satisfied. | ||
54 | pub fn bump_while<F: Fn(char) -> bool>(&mut self, pred: F) { | 66 | pub fn bump_while<F: Fn(char) -> bool>(&mut self, pred: F) { |
55 | loop { | 67 | loop { |
56 | match self.next() { | 68 | match self.current() { |
57 | Some(c) if pred(c) => { | 69 | Some(c) if pred(c) => { |
58 | self.bump(); | 70 | self.bump(); |
59 | } | 71 | } |
@@ -62,11 +74,13 @@ impl<'s> Ptr<'s> { | |||
62 | } | 74 | } |
63 | } | 75 | } |
64 | 76 | ||
77 | /// Returns the text up to the current point. | ||
65 | pub fn current_token_text(&self) -> &str { | 78 | pub fn current_token_text(&self) -> &str { |
66 | let len: u32 = self.len.into(); | 79 | let len: u32 = self.len.into(); |
67 | &self.text[..len as usize] | 80 | &self.text[..len as usize] |
68 | } | 81 | } |
69 | 82 | ||
83 | /// Returns an iterator over the remaining characters. | ||
70 | fn chars(&self) -> Chars { | 84 | fn chars(&self) -> Chars { |
71 | let len: u32 = self.len.into(); | 85 | let len: u32 = self.len.into(); |
72 | self.text[len as usize..].chars() | 86 | self.text[len as usize..].chars() |