diff options
Diffstat (limited to 'crates/ra_syntax/src/parsing/lexer/numbers.rs')
-rw-r--r-- | crates/ra_syntax/src/parsing/lexer/numbers.rs | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/crates/ra_syntax/src/parsing/lexer/numbers.rs b/crates/ra_syntax/src/parsing/lexer/numbers.rs new file mode 100644 index 000000000..7f6abe1d5 --- /dev/null +++ b/crates/ra_syntax/src/parsing/lexer/numbers.rs | |||
@@ -0,0 +1,69 @@ | |||
1 | use crate::parsing::lexer::{ | ||
2 | ptr::Ptr, | ||
3 | classes::*, | ||
4 | }; | ||
5 | |||
6 | use crate::SyntaxKind::{self, *}; | ||
7 | |||
8 | pub(crate) fn scan_number(c: char, ptr: &mut Ptr) -> SyntaxKind { | ||
9 | if c == '0' { | ||
10 | match ptr.current().unwrap_or('\0') { | ||
11 | 'b' | 'o' => { | ||
12 | ptr.bump(); | ||
13 | scan_digits(ptr, false); | ||
14 | } | ||
15 | 'x' => { | ||
16 | ptr.bump(); | ||
17 | scan_digits(ptr, true); | ||
18 | } | ||
19 | '0'...'9' | '_' | '.' | 'e' | 'E' => { | ||
20 | scan_digits(ptr, true); | ||
21 | } | ||
22 | _ => return INT_NUMBER, | ||
23 | } | ||
24 | } else { | ||
25 | scan_digits(ptr, false); | ||
26 | } | ||
27 | |||
28 | // might be a float, but don't be greedy if this is actually an | ||
29 | // integer literal followed by field/method access or a range pattern | ||
30 | // (`0..2` and `12.foo()`) | ||
31 | if ptr.at('.') && !(ptr.at_str("..") || ptr.nth_is_p(1, is_ident_start)) { | ||
32 | // might have stuff after the ., and if it does, it needs to start | ||
33 | // with a number | ||
34 | ptr.bump(); | ||
35 | scan_digits(ptr, false); | ||
36 | scan_float_exponent(ptr); | ||
37 | return FLOAT_NUMBER; | ||
38 | } | ||
39 | // it might be a float if it has an exponent | ||
40 | if ptr.at('e') || ptr.at('E') { | ||
41 | scan_float_exponent(ptr); | ||
42 | return FLOAT_NUMBER; | ||
43 | } | ||
44 | INT_NUMBER | ||
45 | } | ||
46 | |||
47 | fn scan_digits(ptr: &mut Ptr, allow_hex: bool) { | ||
48 | while let Some(c) = ptr.current() { | ||
49 | match c { | ||
50 | '_' | '0'...'9' => { | ||
51 | ptr.bump(); | ||
52 | } | ||
53 | 'a'...'f' | 'A'...'F' if allow_hex => { | ||
54 | ptr.bump(); | ||
55 | } | ||
56 | _ => return, | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | |||
61 | fn scan_float_exponent(ptr: &mut Ptr) { | ||
62 | if ptr.at('e') || ptr.at('E') { | ||
63 | ptr.bump(); | ||
64 | if ptr.at('-') || ptr.at('+') { | ||
65 | ptr.bump(); | ||
66 | } | ||
67 | scan_digits(ptr, false); | ||
68 | } | ||
69 | } | ||