aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/parsing/lexer/numbers.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/parsing/lexer/numbers.rs')
-rw-r--r--crates/ra_syntax/src/parsing/lexer/numbers.rs69
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 @@
1use crate::parsing::lexer::{
2 ptr::Ptr,
3 classes::*,
4};
5
6use crate::SyntaxKind::{self, *};
7
8pub(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
47fn 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
61fn 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}