1use super::errors::{ErrorKind, ParserError};
2use super::{core::Parser, core::Result, slice::Slice};
3
4impl<'s, S> Parser<S>
5where
6 S: Slice<'s>,
7{
8 pub(super) fn is_current_byte(&self, b: u8) -> bool {
9 get_current_byte!(self) == Some(&b)
10 }
11
12 pub(super) fn is_byte_at(&self, b: u8, pos: usize) -> bool {
13 get_byte!(self, pos) == Some(&b)
14 }
15
16 pub(super) fn skip_to_next_entry_start(&mut self) {
17 while let Some(b) = get_current_byte!(self) {
18 let new_line = self.ptr == 0 || get_byte!(self, self.ptr - 1) == Some(&b'\n');
19
20 if new_line && (b.is_ascii_alphabetic() || [b'-', b'#'].contains(b)) {
21 break;
22 }
23
24 self.ptr += 1;
25 }
26 }
27
28 pub(super) fn skip_eol(&mut self) -> bool {
29 match get_current_byte!(self) {
30 Some(b'\n') => {
31 self.ptr += 1;
32 true
33 }
34 Some(b'\r') if self.is_byte_at(b'\n', self.ptr + 1) => {
35 self.ptr += 2;
36 true
37 }
38 _ => false,
39 }
40 }
41
42 pub(super) fn skip_unicode_escape_sequence(&mut self, length: usize) -> Result<()> {
43 let start = self.ptr;
44 for _ in 0..length {
45 match get_current_byte!(self) {
46 Some(b) if b.is_ascii_hexdigit() => self.ptr += 1,
47 _ => break,
48 }
49 }
50 if self.ptr - start != length {
51 let end = if self.ptr >= self.length {
52 self.ptr
53 } else {
54 self.ptr + 1
55 };
56 let seq = self.source.slice(start..end).as_ref().to_owned();
57 return error!(ErrorKind::InvalidUnicodeEscapeSequence(seq), self.ptr);
58 }
59 Ok(())
60 }
61
62 pub(super) fn is_identifier_start(&self) -> bool {
63 matches!(get_current_byte!(self), Some(b) if b.is_ascii_alphabetic())
64 }
65
66 pub(super) fn take_byte_if(&mut self, b: u8) -> bool {
67 if self.is_current_byte(b) {
68 self.ptr += 1;
69 true
70 } else {
71 false
72 }
73 }
74
75 pub(super) fn skip_blank_block(&mut self) -> usize {
76 let mut count = 0;
77 loop {
78 let start = self.ptr;
79 self.skip_blank_inline();
80 if !self.skip_eol() {
81 self.ptr = start;
82 break;
83 }
84 count += 1;
85 }
86 count
87 }
88
89 pub(super) fn skip_blank(&mut self) {
90 loop {
91 match get_current_byte!(self) {
92 Some(b' ') | Some(b'\n') => self.ptr += 1,
93 Some(b'\r') if get_byte!(self, self.ptr + 1) == Some(&b'\n') => self.ptr += 2,
94 _ => break,
95 }
96 }
97 }
98
99 pub(super) fn skip_blank_inline(&mut self) -> usize {
100 let start = self.ptr;
101 while let Some(b' ') = get_current_byte!(self) {
102 self.ptr += 1;
103 }
104 self.ptr - start
105 }
106
107 pub(super) fn is_byte_pattern_continuation(b: u8) -> bool {
108 !matches!(b, b'.' | b'}' | b'[' | b'*')
109 }
110
111 pub(super) fn is_callee(name: &S) -> bool {
112 name.as_ref()
113 .as_bytes()
114 .iter()
115 .all(|c| c.is_ascii_uppercase() || c.is_ascii_digit() || *c == b'_' || *c == b'-')
116 }
117
118 pub(super) fn expect_byte(&mut self, b: u8) -> Result<()> {
119 if !self.is_current_byte(b) {
120 return error!(ErrorKind::ExpectedToken(b as char), self.ptr);
121 }
122 self.ptr += 1;
123 Ok(())
124 }
125
126 pub(super) fn is_number_start(&self) -> bool {
127 matches!(get_current_byte!(self), Some(b) if b.is_ascii_digit() || b == &b'-')
128 }
129
130 pub(super) fn is_eol(&self) -> bool {
131 match get_current_byte!(self) {
132 Some(b'\n') => true,
133 Some(b'\r') if self.is_byte_at(b'\n', self.ptr + 1) => true,
134 None => true,
135 _ => false,
136 }
137 }
138
139 pub(super) fn skip_digits(&mut self) -> Result<()> {
140 let start = self.ptr;
141 loop {
142 match get_current_byte!(self) {
143 Some(b) if b.is_ascii_digit() => self.ptr += 1,
144 _ => break,
145 }
146 }
147 if start == self.ptr {
148 error!(
149 ErrorKind::ExpectedCharRange {
150 range: "0-9".to_string()
151 },
152 self.ptr
153 )
154 } else {
155 Ok(())
156 }
157 }
158
159 pub(super) fn get_number_literal(&mut self) -> Result<S> {
160 let start = self.ptr;
161 self.take_byte_if(b'-');
162 self.skip_digits()?;
163 if self.take_byte_if(b'.') {
164 self.skip_digits()?;
165 }
166
167 Ok(self.source.slice(start..self.ptr))
168 }
169}
170