lib_ruby_parser/lexer/
parse_atmark.rs

1use crate::lexer::*;
2use crate::source::buffer::*;
3use crate::DiagnosticMessage;
4use crate::{lex_states::*, LexState};
5
6impl Lexer {
7    pub(crate) fn parse_atmark(&mut self, last_state: LexState) -> i32 {
8        let ptr = self.buffer.pcur;
9        let mut result: i32 = Self::tIVAR;
10        let mut c = self.nextc();
11
12        self.buffer.ptok = ptr - 1; // from '@'
13        self.newtok();
14        self.tokadd(b'@');
15        if c == b'@' {
16            result = Self::tCVAR;
17            self.tokadd(b'@');
18            c = self.nextc()
19        }
20        self.lex_state.set(if last_state.is_some(EXPR_FNAME) {
21            EXPR_ENDFN
22        } else {
23            EXPR_END
24        });
25        if c.is_eof() || !self.is_identchar() {
26            self.buffer.pushback(c);
27            if result == Self::tIVAR {
28                self.compile_error(DiagnosticMessage::IvarWithoutId {}, self.current_loc());
29            } else {
30                self.compile_error(DiagnosticMessage::CvarWithoutId {}, self.current_loc());
31            }
32            self.lex_state.set(EXPR_END);
33            return result;
34        } else if c.is_digit() {
35            // The following line comes from MRI, but it seems to be a bug
36            // self.buffer.pushback(&c);
37            if result == Self::tIVAR {
38                self.compile_error(
39                    DiagnosticMessage::InvalidIvarName {
40                        c: c.expect("c is a digit"),
41                    },
42                    self.current_loc(),
43                );
44            } else {
45                self.compile_error(
46                    DiagnosticMessage::InvalidCvarName {
47                        c: c.expect("c is a digit"),
48                    },
49                    self.current_loc(),
50                );
51            }
52            self.lex_state.set(EXPR_END);
53            return result;
54        }
55
56        if self.tokadd_ident(c) {
57            return Self::END_OF_INPUT;
58        }
59        self.tokenize_ident();
60        result
61    }
62}