@@ -44,6 +44,28 @@ mod lex {
44
44
input. split_at ( pos)
45
45
}
46
46
47
+ fn consume_number ( input : & str ) -> ( & str , & str ) {
48
+ let mut is_first_char = true ;
49
+ let mut right_after_exponent = false ;
50
+
51
+ let mut what = |c| {
52
+ if is_first_char {
53
+ is_first_char = false ;
54
+ c == '-' || c >= '0' && c <= '9' || c == '.'
55
+ } else if c == 'e' || c == 'E' {
56
+ right_after_exponent = true ;
57
+ true
58
+ } else if right_after_exponent {
59
+ right_after_exponent = false ;
60
+ c >= '0' && c <= '9' || c == '-'
61
+ } else {
62
+ c >= '0' && c <= '9' || c == '.'
63
+ }
64
+ } ;
65
+ let pos = input. find ( |c| !what ( c) ) . unwrap_or_else ( || input. len ( ) ) ;
66
+ input. split_at ( pos)
67
+ }
68
+
47
69
pub fn consume_token ( mut input : & str ) -> ( Token < ' _ > , & str ) {
48
70
input = input. trim_start ( ) ;
49
71
let mut chars = input. chars ( ) ;
@@ -60,7 +82,17 @@ mod lex {
60
82
( Token :: Separator ( cur) , input)
61
83
}
62
84
}
63
- ';' | ',' | '.' => ( Token :: Separator ( cur) , chars. as_str ( ) ) ,
85
+ ';' | ',' => ( Token :: Separator ( cur) , chars. as_str ( ) ) ,
86
+ '.' => {
87
+ let og_chars = chars. as_str ( ) ;
88
+ match chars. next ( ) {
89
+ Some ( '0' ..='9' ) => {
90
+ let ( number, rest) = consume_number ( input) ;
91
+ ( Token :: Number ( number) , rest)
92
+ }
93
+ _ => ( Token :: Separator ( cur) , og_chars) ,
94
+ }
95
+ }
64
96
'(' | ')' | '{' | '}' => ( Token :: Paren ( cur) , chars. as_str ( ) ) ,
65
97
'<' | '>' => {
66
98
input = chars. as_str ( ) ;
@@ -87,7 +119,7 @@ mod lex {
87
119
}
88
120
}
89
121
'0' ..='9' => {
90
- let ( number, rest) = consume_any ( input, |c| ( c >= '0' && c <= '9' || c == '.' ) ) ;
122
+ let ( number, rest) = consume_number ( input) ;
91
123
( Token :: Number ( number) , rest)
92
124
}
93
125
'a' ..='z' | 'A' ..='Z' | '_' => {
@@ -106,11 +138,14 @@ mod lex {
106
138
}
107
139
}
108
140
'-' => {
109
- input = chars. as_str ( ) ;
110
- if chars. next ( ) == Some ( '>' ) {
111
- ( Token :: Arrow , chars. as_str ( ) )
112
- } else {
113
- ( Token :: Operation ( cur) , input)
141
+ let og_chars = chars. as_str ( ) ;
142
+ match chars. next ( ) {
143
+ Some ( '>' ) => ( Token :: Arrow , chars. as_str ( ) ) ,
144
+ Some ( '0' ..='9' ) | Some ( '.' ) => {
145
+ let ( number, rest) = consume_number ( input) ;
146
+ ( Token :: Number ( number) , rest)
147
+ }
148
+ _ => ( Token :: Operation ( cur) , og_chars) ,
114
149
}
115
150
}
116
151
'+' | '*' | '/' | '%' | '^' => ( Token :: Operation ( cur) , chars. as_str ( ) ) ,
0 commit comments