oak_core/lexer/
scan_comment.rs1use super::LexerState;
2use crate::{Language, source::Source};
3
4pub struct CommentConfig {
6 pub line_marker: &'static str,
8 pub block_start: &'static str,
10 pub block_end: &'static str,
12 pub nested_blocks: bool,
14}
15
16impl CommentConfig {
17 pub fn scan<S: Source + ?Sized, L: Language>(&self, state: &mut LexerState<S, L>, line_kind: L::TokenType, block_kind: L::TokenType) -> bool {
19 let start = state.get_position();
20
21 if !self.line_marker.is_empty() && state.starts_with(self.line_marker) {
23 state.advance(self.line_marker.len());
24 state.take_while_byte(|b| b != b'\n');
25 state.add_token(line_kind, start, state.get_position());
26 return true;
27 }
28
29 if !self.block_start.is_empty() && state.starts_with(self.block_start) {
31 state.advance(self.block_start.len());
32 let mut depth = 1;
33 while depth > 0 && state.not_at_end() {
34 if self.nested_blocks && !self.block_start.is_empty() && state.starts_with(self.block_start) {
35 depth += 1;
36 state.advance(self.block_start.len());
37 }
38 else if !self.block_end.is_empty() && state.starts_with(self.block_end) {
39 depth -= 1;
40 state.advance(self.block_end.len());
41 }
42 else if let Some(ch) = state.current() {
43 state.advance(ch.len_utf8());
44 }
45 }
46 state.add_token(block_kind, start, state.get_position());
47 return true;
48 }
49
50 false
51 }
52}
53
54#[inline]
56pub fn starts_with_line_comment(bytes: &[u8]) -> bool {
57 bytes.starts_with(b"//")
58}
59
60#[inline]
62pub fn starts_with_block_comment(bytes: &[u8]) -> bool {
63 bytes.starts_with(b"/*")
64}