lib_ruby_parser/
lex_state.rs1use crate::maybe_byte::MaybeByte;
2
3#[derive(Clone, Copy, PartialEq, Eq)]
5#[repr(C)]
6pub struct LexState {
7 pub(crate) value: i32,
8}
9
10impl LexState {
11 pub(crate) fn is(&self, value: i32) -> bool {
12 self.value == value
13 }
14
15 pub(crate) fn is_some(&self, states: i32) -> bool {
16 (self.value & states) != 0
17 }
18
19 pub(crate) fn is_all(&self, states: i32) -> bool {
20 (self.value & states) == states
21 }
22
23 pub fn set(&mut self, value: i32) {
25 self.value = value
26 }
27
28 pub(crate) fn get(&self) -> i32 {
29 self.value
30 }
31
32 pub(crate) fn is_after_operator(&self) -> bool {
33 self.is_some(EXPR_FNAME | EXPR_DOT)
34 }
35 pub(crate) fn is_end(&self) -> bool {
36 self.is_some(EXPR_END_ANY)
37 }
38 pub(crate) fn is_arg(&self) -> bool {
39 self.is_some(EXPR_ARG_ANY)
40 }
41 pub(crate) fn is_label_possible(&self, cmd_state: bool) -> bool {
42 (self.is_some(EXPR_LABEL | EXPR_ENDFN) && !cmd_state) || self.is_arg()
43 }
44 pub(crate) fn is_spacearg(&self, c: MaybeByte, space_seen: bool) -> bool {
45 self.is_arg() && space_seen && !c.is_space()
46 }
47 pub(crate) fn is_beg(&self) -> bool {
48 self.is_some(EXPR_BEG_ANY) || self.is_all(EXPR_ARG | EXPR_LABELED)
49 }
50}
51
52impl Default for LexState {
53 fn default() -> Self {
54 Self { value: EXPR_BEG }
55 }
56}
57
58pub mod lex_states {
60 pub const EXPR_BEG: i32 = 1 << 0;
62
63 pub const EXPR_END: i32 = 1 << 1;
65
66 pub const EXPR_ENDARG: i32 = 1 << 2;
68
69 pub const EXPR_ENDFN: i32 = 1 << 3;
71
72 pub const EXPR_ARG: i32 = 1 << 4;
74
75 pub const EXPR_CMDARG: i32 = 1 << 5;
77
78 pub const EXPR_MID: i32 = 1 << 6;
80
81 pub const EXPR_FNAME: i32 = 1 << 7;
83
84 pub const EXPR_DOT: i32 = 1 << 8;
86
87 pub const EXPR_CLASS: i32 = 1 << 9;
89
90 pub const EXPR_LABEL: i32 = 1 << 10;
92
93 pub const EXPR_LABELED: i32 = 1 << 11;
95
96 pub const EXPR_FITEM: i32 = 1 << 12;
98
99 pub const EXPR_VALUE: i32 = EXPR_BEG;
101
102 pub const EXPR_BEG_ANY: i32 = EXPR_BEG | EXPR_MID | EXPR_CLASS;
104
105 pub const EXPR_ARG_ANY: i32 = EXPR_ARG | EXPR_CMDARG;
107
108 pub const EXPR_END_ANY: i32 = EXPR_END | EXPR_ENDARG | EXPR_ENDFN;
110
111 pub const EXPR_NONE: i32 = 0;
113}
114use lex_states::*;
115
116impl std::fmt::Debug for LexState {
117 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118 let mut states: Vec<&'static str> = vec![];
119
120 if self.is_some(EXPR_BEG) {
121 states.push("EXPR_BEG")
122 }
123 if self.is_some(EXPR_END) {
124 states.push("EXPR_END")
125 }
126 if self.is_some(EXPR_ENDARG) {
127 states.push("EXPR_ENDARG")
128 }
129 if self.is_some(EXPR_ENDFN) {
130 states.push("EXPR_ENDFN")
131 }
132 if self.is_some(EXPR_ARG) {
133 states.push("EXPR_ARG")
134 }
135 if self.is_some(EXPR_CMDARG) {
136 states.push("EXPR_CMDARG")
137 }
138 if self.is_some(EXPR_MID) {
139 states.push("EXPR_MID")
140 }
141 if self.is_some(EXPR_FNAME) {
142 states.push("EXPR_FNAME")
143 }
144 if self.is_some(EXPR_DOT) {
145 states.push("EXPR_DOT")
146 }
147 if self.is_some(EXPR_CLASS) {
148 states.push("EXPR_CLASS")
149 }
150 if self.is_some(EXPR_LABEL) {
151 states.push("EXPR_LABEL")
152 }
153 if self.is_some(EXPR_FITEM) {
154 states.push("EXPR_FITEM")
155 }
156 if self.is_some(EXPR_NONE) {
157 states.push("EXPR_NONE")
158 }
159
160 if self.is_some(EXPR_VALUE) {
161 states.push("Also(EXPR_VALUE)")
162 }
163 if self.is_some(EXPR_BEG_ANY) {
164 states.push("Also(EXPR_BEG_ANY)")
165 }
166 if self.is_some(EXPR_END_ANY) {
167 states.push("Also(EXPR_END_ANY)")
168 }
169 if self.is_some(EXPR_END_ANY) {
170 states.push("Also(EXPR_END_ANY)")
171 }
172
173 f.write_str(&states.join("|"))
174 }
175}
176
177#[test]
178fn test_fmt() {
179 let mut lex_state = LexState::default();
180 lex_state.set(EXPR_BEG | EXPR_VALUE);
181 assert_eq!(
182 format!("{:?}", lex_state),
183 "EXPR_BEG|Also(EXPR_VALUE)|Also(EXPR_BEG_ANY)"
184 );
185}