1use crate::tokens::{Token, TokenType, TokenValue};
2use crate::types::{FloatType, IntType, Number, Source};
3use crate::{debuggable, error, success};
4use std::str;
5
6struct Context<'a> {
8 buffer: &'a str,
9 current: usize,
10 line: usize,
11 col: usize,
12 old_pos: usize,
13 old_line: usize,
14 old_col: usize,
15 offset: usize,
16 comment_offset: usize,
17}
18
19impl<'a> Context<'a> {
20 pub fn new(buffer: &'a str) -> Self {
21 Context::<'a> {
22 buffer,
23 current: 0,
24 line: 1,
25 col: 1,
26 old_pos: 0,
27 old_line: 0,
28 old_col: 0,
29 offset: 0,
30 comment_offset: 0,
31 }
32 }
33
34 pub fn save(&mut self) {
35 self.old_pos = self.current;
36 self.old_col = self.col;
37 self.old_line = self.line;
38 }
39
40 pub fn get_saved_source(&self) -> Source {
41 Source {
42 pos: self.old_pos,
43 length: self.current - self.old_pos,
44 line: self.old_line,
45 col: self.old_col,
46 }
47 }
48
49 pub fn next(&mut self) {
50 self.skip(1);
51 }
52
53 pub fn skip(&mut self, n: usize) {
54 self.current += n;
55 self.col += n;
56 }
57
58 pub fn write_into(&mut self, n: usize, output: &mut Vec<u8>) {
60 if let Some(slice) = self.buffer.as_bytes().get(self.current..(self.current + n)) {
61 output.extend_from_slice(slice);
62 self.skip(n);
63 }
64 }
65
66 pub fn inc_line(&mut self) {
67 self.col = 1;
68 self.line += 1;
69 }
70
71 pub fn get(&self) -> Option<u8> {
72 self.get_ahead(0)
73 }
74
75 pub fn get_next(&self) -> Option<u8> {
76 self.get_ahead(1)
77 }
78
79 pub fn get_ahead(&self, index: usize) -> Option<u8> {
80 self.buffer.as_bytes().get(self.current + index).copied()
81 }
82}
83
84pub struct LexerConfig {
85 pub use_origin_string: bool,
87 pub reserve_comments: bool,
89}
90
91impl LexerConfig {
92 pub fn default() -> Self {
93 LexerConfig {
94 use_origin_string: false,
95 reserve_comments: false,
96 }
97 }
98}
99
100pub struct Lexer {
101 debug: bool,
102 config: LexerConfig,
103 tokens: Vec<Token>,
104}
105
106#[derive(Debug)]
107pub struct LexError(String);
108
109type LexResult = Result<Option<(TokenType, TokenValue)>, LexError>;
110
111macro_rules! lex_error {
112 ($self:ident, $ctx:ident, $msg:expr) => {
113 error!(
114 $self,
115 LexError,
116 format!("[lex error] {} at line [{}:{}].", $msg, $ctx.line, $ctx.col)
117 )
118 };
119}
120
121impl<'a> Lexer {
122 pub fn new() -> Self {
123 Lexer {
124 debug: false,
125 tokens: Vec::<Token>::new(),
126 config: LexerConfig::default(),
127 }
128 }
129
130 pub fn set_config(&mut self, config: LexerConfig) {
131 self.config = config;
132 }
133
134 pub fn run(&mut self, input: &'a str) -> Result<&Vec<Token>, LexError> {
135 self.reset();
136 let mut ctx = Context::new(input);
137 loop {
138 ctx.save();
139 if let Some(c) = ctx.get() {
140 if let Some((token_type, token_value)) = match c {
141 _ if Lexer::is_line_break(c) => self.read_line_break(&mut ctx)?,
142 _ if Lexer::is_space(c) => self.read_space(&mut ctx)?,
143 _ if Lexer::is_digit(c) => self.read_number(&mut ctx)?,
144 b'-' if self.check_next(&ctx, '-') => self.read_comment(&mut ctx)?,
145 b'=' => self.read_eq_assign(&mut ctx)?,
146 b'<' => self.read_le_shl_lt(&mut ctx)?,
147 b'>' => self.read_ge_shr_gt(&mut ctx)?,
148 b'/' if self.check_next(&ctx, '/') => self.read_idiv(&mut ctx)?,
149 b'~' => self.read_ne_xor(&mut ctx)?,
150 b':' => self.read_colon(&mut ctx)?,
151 b'.' => self.read_attr_concat_dots_numbers(&mut ctx)?,
152 b'"' | b'\'' => self.read_short_string(&mut ctx)?,
153 b'[' if self.check_next2(&ctx, '[', '=') => self.read_long_string(&mut ctx)?,
154 _ => self.read_other_tokens(&mut ctx)?,
155 } {
156 self.add_token(&mut ctx, token_type, token_value);
157 }
158 } else {
159 self.add_token(&mut ctx, TokenType::Eos, TokenValue::None);
161 return Ok(&self.tokens);
162 }
163 }
164 }
165
166 pub fn tokens(&self) -> &Vec<Token> {
167 &self.tokens
168 }
169
170 fn read_line_break(&self, ctx: &mut Context) -> LexResult {
171 let old = ctx.get();
172 ctx.next();
173
174 if old != ctx.get() && self.check_current_if(ctx, |c| Lexer::is_line_break(c)) {
176 ctx.next();
177 }
178
179 ctx.inc_line();
180 Ok(None)
181 }
182
183 fn read_space(&self, ctx: &mut Context) -> LexResult {
184 ctx.next();
185 Ok(None)
186 }
187
188 fn read_comment(&mut self, ctx: &mut Context) -> LexResult {
189 ctx.skip(2);
190 let sep_count = self.try_read_long_string_boundary(ctx, b'[');
191 if sep_count >= 0 {
192 let comment = self.read_long_string_impl(ctx, sep_count as usize, "comment")?;
193 if self.config.reserve_comments {
194 success!((TokenType::MComment, TokenValue::Str(comment)))
195 } else {
196 Ok(None)
197 }
198 } else {
199 self.read_short_comment(ctx)
200 }
201 }
202
203 fn read_short_comment(&mut self, ctx: &mut Context) -> LexResult {
204 let mut bytes: Vec<u8> = Vec::new();
205 while let Some(c) = ctx.get() {
206 if Lexer::is_line_break(c) {
207 break;
208 }
209 ctx.write_into(1, &mut bytes);
210 }
211 if let Ok(comment) = str::from_utf8(&bytes) {
212 if self.config.reserve_comments {
213 success!((TokenType::SComment, TokenValue::Str(comment.to_string())))
214 } else {
215 Ok(None)
216 }
217 } else {
218 lex_error!(self, ctx, "invalid single line comment")
219 }
220 }
221
222 fn read_token2(
224 &mut self,
225 ctx: &mut Context,
226 c: char,
227 t1: TokenType,
228 t2: TokenType,
229 ) -> LexResult {
230 ctx.next();
231 if self.check_current(ctx, c) {
232 ctx.next();
233 return success!((t1, TokenValue::None));
234 }
235 success!((t2, TokenValue::None))
236 }
237
238 fn read_token3(
240 &mut self,
241 ctx: &mut Context,
242 c1: char,
243 c2: char,
244 t1: TokenType,
245 t2: TokenType,
246 t3: TokenType,
247 ) -> LexResult {
248 ctx.next();
249 if self.check_current(ctx, c1) {
250 ctx.next();
251 success!((t1, TokenValue::None))
252 } else if self.check_current(ctx, c2) {
253 ctx.next();
254 success!((t2, TokenValue::None))
255 } else {
256 success!((t3, TokenValue::None))
257 }
258 }
259
260 fn read_eq_assign(&mut self, ctx: &mut Context) -> LexResult {
261 self.read_token2(ctx, '=', TokenType::Eq, TokenType::Assign)
262 }
263
264 fn read_le_shl_lt(&mut self, ctx: &mut Context) -> LexResult {
265 self.read_token3(ctx, '=', '<', TokenType::Le, TokenType::Shl, TokenType::Lt)
266 }
267
268 fn read_ge_shr_gt(&mut self, ctx: &mut Context) -> LexResult {
269 self.read_token3(ctx, '=', '>', TokenType::Ge, TokenType::Shr, TokenType::Gt)
270 }
271
272 fn read_idiv(&mut self, ctx: &mut Context) -> LexResult {
273 ctx.skip(2);
274 success!((TokenType::IDiv, TokenValue::None))
275 }
276
277 fn read_ne_xor(&mut self, ctx: &mut Context) -> LexResult {
278 self.read_token2(ctx, '=', TokenType::Ne, TokenType::BXor)
279 }
280
281 fn read_colon(&mut self, ctx: &mut Context) -> LexResult {
282 self.read_token2(ctx, ':', TokenType::DbColon, TokenType::Colon)
283 }
284
285 fn read_attr_concat_dots_numbers(&mut self, ctx: &mut Context) -> LexResult {
286 if self.check_next(ctx, '.') {
287 ctx.next();
288 if self.check_next(ctx, '.') {
289 ctx.skip(2);
290 return success!((TokenType::Dots, TokenValue::None));
291 } else {
292 ctx.next();
293 return success!((TokenType::Concat, TokenValue::None));
294 }
295 }
296 if let Some(c) = ctx.get_next() {
297 if Lexer::is_digit(c) {
298 return self.read_number(ctx);
299 }
300 }
301 ctx.next();
302 success!((TokenType::Attr, TokenValue::None))
303 }
304
305 fn read_number(&mut self, ctx: &mut Context) -> LexResult {
306 let mut expo = ('E', 'e');
307 let mut num_str: Vec<u8> = Vec::new();
308 let mut hex = false;
309 if self.check_current(ctx, '0') && self.check_next2(ctx, 'x', 'X') {
310 expo = ('P', 'p');
311 ctx.write_into(2, &mut num_str);
312 hex = true;
313 }
314 let is_digit = |c| {
315 (hex && Lexer::is_hex_digit(c)) || (!hex && Lexer::is_digit(c)) || (c as char) == '.'
316 };
317 loop {
318 if self.check_current_if(ctx, is_digit) {
319 ctx.write_into(1, &mut num_str)
320 } else if self.check_current2(ctx, expo.0, expo.1) {
321 ctx.write_into(1, &mut num_str);
322 if self.check_current2(ctx, '-', '+') {
323 ctx.write_into(1, &mut num_str)
324 }
325 } else {
326 break;
327 }
328 }
329 if let Ok(string) = str::from_utf8(&num_str) {
330 let num = Lexer::str_to_num(string);
331 match num {
332 Number::Int(n) => success!((TokenType::Int, TokenValue::Int(n))),
333 Number::Float(n) => success!((TokenType::Flt, TokenValue::Float(n))),
334 _ => lex_error!(self, ctx, "malformed number"),
335 }
336 } else {
337 unreachable!();
338 }
339 }
340
341 fn try_read_hexa(&mut self, ctx: &mut Context) -> Option<u8> {
342 ctx.get().filter(|c| Lexer::is_hex_digit(*c)).map(|c| {
343 ctx.next();
344 Lexer::to_hex_digit(c)
345 })
346 }
347
348 fn try_read_hex_esc(&mut self, ctx: &mut Context) -> Result<u8, LexError> {
349 if let Some(p1) = self.try_read_hexa(ctx) {
350 if let Some(p2) = self.try_read_hexa(ctx) {
351 return Ok((p1 << 4) + p2);
352 }
353 }
354 lex_error!(self, ctx, "hexadecimal digit expected")
355 }
356
357 fn try_read_utf8_esc(
358 &mut self,
359 ctx: &mut Context,
360 bytes: &mut Vec<u8>,
361 ) -> Result<(), LexError> {
362 if let Some(c) = ctx.get() {
363 if c != b'{' {
364 return lex_error!(self, ctx, "missing '{'");
365 }
366 ctx.next();
367 if let Some(c) = self.try_read_hexa(ctx) {
368 let mut r = c as u32;
369 while let Some(c) = self.try_read_hexa(ctx) {
370 r = (r << 4) + (c as u32);
371 if r > 0x10FFFF {
372 return lex_error!(self, ctx, "UTF-8 value too large");
373 }
374 }
375 if self.check_current(ctx, '}') {
376 if let Some(c) = std::char::from_u32(r) {
377 let mut string = String::new();
378 string.push(c);
379 bytes.append(&mut string.into_bytes());
380 ctx.next();
381 } else {
382 return lex_error!(self, ctx, "invalid utf8 codepoint");
383 }
384 } else {
385 return lex_error!(self, ctx, "missing '}'");
386 }
387 } else {
388 return lex_error!(self, ctx, "hexadecimal digit expected");
389 }
390 }
391 Ok(())
392 }
393
394 fn try_read_dec_esc(
395 &mut self,
396 ctx: &mut Context,
397 bytes: &mut Vec<u8>,
398 first_place: u8,
399 ) -> Result<(), LexError> {
400 let mut r: u32 = Lexer::to_digit(first_place) as u32;
401 let mut i = 0;
402 while let Some(c) = ctx.get() {
403 i += 1;
404 if i > 2 || !Lexer::is_digit(c) {
405 break;
407 }
408 r = r * 10 + Lexer::to_digit(c) as u32;
409 ctx.next();
410 }
411 if r > 0xFF {
412 lex_error!(self, ctx, "decimal escape too large")
413 } else {
414 bytes.push(r as u8);
415 Ok(())
416 }
417 }
418
419 fn try_read_esc(&mut self, ctx: &mut Context, bytes: &mut Vec<u8>) -> Result<(), LexError> {
420 ctx.next();
421 if let Some(next) = ctx.get() {
422 ctx.next();
423 match next {
424 b'n' => bytes.push(b'\n'),
425 b'r' => bytes.push(b'\r'),
426 b't' => bytes.push(b'\t'),
427 b'a' => bytes.push(b'\x07'),
428 b'b' => bytes.push(b'\x08'),
429 b'v' => bytes.push(b'\x0B'),
430 b'f' => bytes.push(b'\x0C'),
431 b'x' => {
432 let v = self.try_read_hex_esc(ctx)?;
433 bytes.push(v);
434 }
435 b'u' => self.try_read_utf8_esc(ctx, bytes)?,
436 b'\r' | b'\n' => {
437 bytes.push(b'\n');
438 ctx.inc_line();
439 }
440 b'\\' | b'"' | b'\'' => bytes.push(next),
441 b'z' => {
442 while let Some(c) = ctx.get() {
444 match c {
445 _ if Lexer::is_space(c) => ctx.next(),
446 _ if Lexer::is_line_break(c) => {
447 ctx.next();
448 ctx.inc_line();
449 }
450 _ => break,
451 }
452 }
453 }
454 _ if Lexer::is_digit(next) => self.try_read_dec_esc(ctx, bytes, next)?,
455 _ => {
456 return lex_error!(self, ctx, "invalid escape sequence");
457 }
458 }
459 }
460 Ok(())
461 }
462
463 fn read_short_string(&mut self, ctx: &mut Context) -> LexResult {
464 let mut bytes: Vec<u8> = Vec::new();
465 let start = ctx.get();
466 if self.config.use_origin_string {
467 bytes.push(start.unwrap());
468 }
469 ctx.next();
470 let unfinished_error: &'static str = "unfinished string";
471 while ctx.get() != start {
472 match ctx.get() {
473 Some(b'\\') if self.config.use_origin_string => ctx.write_into(2, &mut bytes),
474 Some(b'\\') => self.try_read_esc(ctx, &mut bytes)?,
475 Some(c) => {
476 if Lexer::is_line_break(c) {
477 return lex_error!(self, ctx, unfinished_error);
478 } else {
479 bytes.push(c);
480 ctx.next();
481 }
482 }
483 None => return lex_error!(self, ctx, unfinished_error),
484 }
485 }
486 if self.config.use_origin_string {
487 bytes.push(ctx.get().unwrap());
488 }
489 if let Ok(string) = String::from_utf8(bytes) {
490 ctx.next();
491 success!((TokenType::String, TokenValue::Str(string)))
492 } else {
493 lex_error!(self, ctx, "invalid utf8 string")
494 }
495 }
496
497 fn try_read_long_string_boundary(&self, ctx: &mut Context, sep: u8) -> i8 {
499 if self.check_current(ctx, sep as char) {
500 let mut sep_count = 0;
501 loop {
502 if let Some(c) = ctx.get_ahead(sep_count + 1) {
503 match c {
504 b'=' => sep_count += 1,
505 _ if c == sep => {
506 ctx.skip(sep_count + 2);
507 return sep_count as i8;
508 }
509 _ => break,
510 };
511 }
512 }
513 }
514 -1
515 }
516
517 fn read_long_string_impl(
519 &mut self,
520 ctx: &mut Context,
521 sep_count: usize,
522 sem: &str,
523 ) -> Result<String, LexError> {
524 let line = ctx.line;
525 let mut start = 0;
526
527 if self.config.use_origin_string {
528 start = ctx.current - 2 - sep_count;
529 }
530
531 if self.check_current_if(ctx, |c| Lexer::is_line_break(c)) {
533 self.read_line_break(ctx)?;
534 }
535
536 if !self.config.use_origin_string {
537 start = ctx.current;
538 }
539
540 while let Some(c) = ctx.get() {
541 match c {
542 b']' => {
543 if self.try_read_long_string_boundary(ctx, b']') == sep_count as i8 {
544 let length;
545 if self.config.use_origin_string {
546 length = ctx.current - start;
547 } else {
548 length = ctx.current - 2 - sep_count - start;
549 }
550 if let Some(slice) = ctx.buffer.get(start..(start + length)) {
551 return Ok(slice.to_string());
552 }
553 } else {
554 ctx.next();
555 }
556 }
557 _ if Lexer::is_line_break(c) => {
558 self.read_line_break(ctx)?;
559 }
560 _ => ctx.next(),
561 }
562 }
563 lex_error!(
564 self,
565 ctx,
566 &format!("unfinished long {} (starting at line {})", sem, line)
567 )
568 }
569
570 fn read_long_string(&mut self, ctx: &mut Context) -> LexResult {
571 let sep_count = self.try_read_long_string_boundary(ctx, b'[');
572 if sep_count >= 0 {
573 let string = self.read_long_string_impl(ctx, sep_count as usize, "string")?;
574 return success!((TokenType::String, TokenValue::Str(string)));
575 }
576 unreachable!()
577 }
578
579 fn read_other_tokens(&mut self, ctx: &mut Context) -> LexResult {
580 if let Some(c) = ctx.get() {
581 let token_type = match c {
582 b'+' => Some(TokenType::Add),
583 b'-' => Some(TokenType::Minus),
584 b'*' => Some(TokenType::Mul),
585 b'/' => Some(TokenType::Div),
586 b'%' => Some(TokenType::Mod),
587 b'^' => Some(TokenType::Pow),
588 b'#' => Some(TokenType::Len),
589 b'&' => Some(TokenType::BAnd),
590 b'|' => Some(TokenType::BOr),
591 b'(' => Some(TokenType::Lp),
592 b')' => Some(TokenType::Rp),
593 b'[' => Some(TokenType::Ls),
594 b']' => Some(TokenType::Rs),
595 b'{' => Some(TokenType::Lb),
596 b'}' => Some(TokenType::Rb),
597 b';' => Some(TokenType::Semi),
598 b',' => Some(TokenType::Comma),
599 _ => None,
600 };
601
602 if let Some(t) = token_type {
603 ctx.next();
604 return success!((t, TokenValue::None));
605 } else if self.check_current_if(ctx, |c| Lexer::is_valid_name_start(c)) {
606 let mut word: Vec<u8> = Vec::new();
607 ctx.write_into(1, &mut word);
608 while self.check_current_if(ctx, |c| Lexer::is_valid_name(c)) {
609 ctx.write_into(1, &mut word);
610 }
611 if let Ok(s) = str::from_utf8(&word) {
612 if let Some(t) = TokenType::from_keyword(s) {
613 return success!((t, TokenValue::None));
614 } else {
615 return success!((TokenType::Name, TokenValue::Str(s.to_string())));
616 }
617 }
618 } else {
619 return lex_error!(self, ctx, &format!("unknown token near {}", c as char));
620 }
621 }
622 unreachable!()
623 }
624
625 fn reset(&mut self) {
626 self.tokens.clear();
627 }
628
629 fn is_line_break(c: u8) -> bool {
630 match c {
631 b'\r' | b'\n' => true,
632 _ => false,
633 }
634 }
635
636 fn is_space(c: u8) -> bool {
637 match c {
638 b' ' | b'\t' | b'\x0B' | b'\x0C' => true,
639 _ => false,
640 }
641 }
642
643 fn is_digit(c: u8) -> bool {
644 match c {
645 b'0' | b'1' | b'2' | b'3' | b'4' | b'5' | b'6' | b'7' | b'8' | b'9' => true,
646 _ => false,
647 }
648 }
649
650 fn is_hex_digit(c: u8) -> bool {
651 match c {
652 b'a' | b'b' | b'c' | b'd' | b'e' | b'f' | b'A' | b'B' | b'C' | b'D' | b'E' | b'F' => {
653 true
654 }
655 _ if Lexer::is_digit(c) => true,
656 _ => false,
657 }
658 }
659
660 fn is_alpha(c: u8) -> bool {
661 (c as char).is_ascii_alphabetic()
662 }
663
664 fn is_valid_name_start(c: u8) -> bool {
665 Lexer::is_alpha(c) || Lexer::is_digit(c) || c == b'_'
666 }
667
668 fn is_valid_name(c: u8) -> bool {
669 Lexer::is_valid_name_start(c) || Lexer::is_alpha(c)
670 }
671
672 fn to_digit(c: u8) -> u8 {
673 c - b'0'
674 }
675
676 fn to_hex_digit(c: u8) -> u8 {
677 if c >= b'0' && c <= b'9' {
678 return c - b'0';
679 } else {
680 return ((c as char).to_ascii_lowercase() as u8) - b'a' + 10;
681 }
682 }
683
684 fn skip_spaces(bytes: &[u8], i: usize) -> usize {
685 let mut index = i;
686 while index < bytes.len() && bytes[index] == b' ' {
687 index += 1;
688 }
689 index
690 }
691
692 fn starts_with_0x(bytes: &[u8], i: usize) -> bool {
693 bytes.len() > i + 2
694 && bytes[i + 0] == b'0'
695 && (bytes[i + 1] == b'x' || bytes[i + 1] == b'X')
696 }
697
698 fn get_sign(bytes: &[u8], i: usize) -> (IntType, usize) {
700 let (mut sign, mut index) = (1, i);
701 if index < bytes.len() {
702 if bytes[index] == b'-' {
703 index += 1;
704 sign = -1;
705 } else if bytes[i] == b'+' {
706 index += 1;
707 }
708 }
709 (sign, index)
710 }
711
712 pub fn str_to_int(s: &str) -> Option<IntType> {
713 let bytes = s.as_bytes();
714 let len = bytes.len();
715 let mut r: IntType = 0;
716 let mut i = 0;
717 let mut empty = true;
718 i = Lexer::skip_spaces(bytes, i);
719 let (sign, mut i) = Lexer::get_sign(bytes, i);
720 if Lexer::starts_with_0x(bytes, i) {
721 i += 2;
722 while i < len && Lexer::is_hex_digit(bytes[i]) {
723 r = (r << 4) + (Lexer::to_hex_digit(bytes[i]) as IntType);
724 i += 1;
725 empty = false;
726 }
727 } else {
728 while i < len && Lexer::is_digit(bytes[i]) {
729 r = r * 10 + (Lexer::to_digit(bytes[i]) as IntType);
730 i += 1;
731 empty = false;
732 }
733 }
734 i = Lexer::skip_spaces(bytes, i);
735 if empty || i != len {
736 None
737 } else {
738 Some((r as IntType) * sign)
739 }
740 }
741
742 pub fn str_to_float(s: &str) -> Option<FloatType> {
743 let bytes = s.as_bytes();
744 let mut i = 0;
745 i = Lexer::skip_spaces(bytes, i);
746 if Lexer::starts_with_0x(bytes, i) {
747 Lexer::str_to_hex_float(&bytes[2..])
748 } else {
749 match s.parse::<FloatType>() {
750 Ok(f) => Some(f),
751 Err(_e) => None,
752 }
753 }
754 }
755
756 pub fn str_to_hex_float(bytes: &[u8]) -> Option<FloatType> {
757 let (sign, mut i) = Lexer::get_sign(bytes, 0);
758 let mut has_dot = false;
759 let mut e: IntType = 0;
760 let mut r = 0.0;
761 let mut empty = true;
762 while i < bytes.len() {
763 match bytes[i] {
764 b'.' => {
765 if has_dot {
766 return None;
768 } else {
769 has_dot = true;
770 }
771 }
772 _ if Lexer::is_hex_digit(bytes[i]) => {
773 r = r * 16.0 + Lexer::to_hex_digit(bytes[i]) as FloatType;
774 if has_dot {
775 e -= 1;
776 }
777 empty = false;
778 }
779 _ => break,
780 }
781 i += 1;
782 }
783 e *= 4;
784 if i < bytes.len() && (bytes[i] == b'p' || bytes[i] == b'P') {
785 i += 1;
786 let (esign, mut index) = Lexer::get_sign(bytes, i);
787 let mut exp_value = 0;
788 let mut exp_empty = true;
789 while index < bytes.len() {
790 if Lexer::is_digit(bytes[index]) {
791 exp_empty = false;
792 exp_value = exp_value * 10 + Lexer::to_digit(bytes[index]) as IntType;
793 } else {
794 break;
795 }
796 index += 1;
797 }
798 if exp_empty {
799 return None;
800 }
801 e += exp_value * esign;
802 i = index;
803 }
804 r = r * (2 as FloatType).powf(e as FloatType);
805 Lexer::skip_spaces(bytes, i);
806 if empty || i != bytes.len() {
807 None
808 } else {
809 Some(r * (sign as FloatType))
810 }
811 }
812
813 fn str_to_num(s: &str) -> Number {
814 if let Some(i) = Lexer::str_to_int(s) {
815 Number::Int(i)
816 } else if let Some(f) = Lexer::str_to_float(s) {
817 Number::Float(f)
818 } else {
819 Number::None
820 }
821 }
822
823 fn check(&self, src: Option<u8>, target: char) -> bool {
824 match src {
825 Some(c) => c as char == target,
826 None => false,
827 }
828 }
829
830 fn check_if(&self, src: Option<u8>, f: impl Fn(u8) -> bool) -> bool {
831 match src {
832 Some(c) => f(c),
833 None => false,
834 }
835 }
836
837 fn check_current(&self, ctx: &Context, c: char) -> bool {
838 self.check(ctx.get(), c)
839 }
840
841 fn check_current2(&self, ctx: &Context, c1: char, c2: char) -> bool {
842 self.check(ctx.get(), c1) || self.check(ctx.get(), c2)
843 }
844
845 fn check_current_if(&self, ctx: &Context, f: impl Fn(u8) -> bool) -> bool {
846 self.check_if(ctx.get(), f)
847 }
848
849 fn check_next(&self, ctx: &Context, c: char) -> bool {
850 self.check(ctx.get_next(), c)
851 }
852
853 fn check_next2(&self, ctx: &Context, c1: char, c2: char) -> bool {
854 self.check(ctx.get_next(), c1) || self.check(ctx.get_next(), c2)
855 }
856
857 fn add_token(&mut self, ctx: &mut Context, t: TokenType, value: TokenValue) {
858 let source = ctx.get_saved_source();
859 self.tokens.push(Token {
860 t,
861 value,
862 source,
863 offset: ctx.offset,
864 comment_offset: ctx.comment_offset,
865 });
866 ctx.offset += 1;
867 if t != TokenType::SComment && t != TokenType::MComment {
868 ctx.comment_offset = ctx.offset;
869 }
870 }
871
872 debuggable!();
873}