Skip to main content

luaur_ast/methods/
parser_next_lexeme.rs

1use crate::functions::is_space::is_space;
2use crate::records::comment::Comment;
3use crate::records::lexeme::Type;
4use crate::records::parser::Parser;
5
6impl Parser {
7    pub fn next_lexeme(&mut self) {
8        let mut r#type = self.lexer.next_with(false, true).r#type;
9
10        while r#type == Type::BrokenComment
11            || r#type == Type::Comment
12            || r#type == Type::BlockComment
13        {
14            let lexeme = *self.lexer.current();
15
16            if self.options.capture_comments {
17                self.comment_locations.push(Comment {
18                    r#type: lexeme.r#type,
19                    location: lexeme.location,
20                });
21            }
22
23            // Subtlety: Broken comments are weird because we record them as comments AND pass them to the parser as a lexeme.
24            // The parser will turn this into a proper syntax error.
25            if lexeme.r#type == Type::BrokenComment {
26                return;
27            }
28
29            // Comments starting with ! are called "hot comments" and contain directives for type checking / linting / compiling
30            if lexeme.r#type == Type::Comment && lexeme.get_length() > 0 {
31                unsafe {
32                    let text_ptr = lexeme.data.data as *const u8;
33                    if *text_ptr == b'!' {
34                        let mut end = lexeme.get_length();
35                        while end > 0 && is_space(*text_ptr.add(end as usize - 1) as char) {
36                            end -= 1;
37                        }
38
39                        let content = core::str::from_utf8_unchecked(core::slice::from_raw_parts(
40                            text_ptr.add(1),
41                            (end - 1) as usize,
42                        ));
43
44                        self.hotcomments
45                            .push(crate::records::hot_comment::HotComment {
46                                header: self.hotcomment_header,
47                                location: lexeme.location,
48                                content: alloc::string::String::from(content),
49                            });
50                    }
51                }
52            }
53
54            r#type = self.lexer.next_with(false, false).r#type;
55        }
56    }
57}