@@ -14,15 +14,15 @@ use crate::value::{ListSeparator, Number, Numeric, Operator, Rgba};
14
14
use nom:: branch:: alt;
15
15
use nom:: bytes:: complete:: { tag, tag_no_case} ;
16
16
use nom:: character:: complete:: {
17
- alphanumeric1, char, multispace0, multispace1, one_of,
17
+ alphanumeric1, char, digit1 , multispace0, multispace1, one_of,
18
18
} ;
19
19
use nom:: combinator:: {
20
- cut, into, map, map_res, not, opt, peek, recognize, value, verify,
20
+ cut, into, map, map_res, not, opt, peek, recognize, success, value,
21
+ verify,
21
22
} ;
22
23
use nom:: error:: context;
23
24
use nom:: multi:: { fold_many0, fold_many1, many0, many_m_n, separated_list1} ;
24
25
use nom:: sequence:: { delimited, pair, preceded, terminated, tuple} ;
25
- use num_traits:: Zero ;
26
26
use std:: str:: from_utf8;
27
27
28
28
pub fn value_expression ( input : Span ) -> PResult < Value > {
@@ -326,11 +326,6 @@ pub fn bracket_list(input: Span) -> PResult<Value> {
326
326
) )
327
327
}
328
328
329
- fn sign_prefix ( input : Span ) -> PResult < Option < & [ u8 ] > > {
330
- opt ( alt ( ( tag ( "-" ) , tag ( "+" ) ) ) ) ( input)
331
- . map ( |( r, s) | ( r, s. map ( |s| s. fragment ( ) ) ) )
332
- }
333
-
334
329
pub fn numeric ( input : Span ) -> PResult < Numeric > {
335
330
map ( pair ( number, unit) , |( number, unit) | {
336
331
Numeric :: new ( number, unit)
@@ -340,46 +335,45 @@ pub fn numeric(input: Span) -> PResult<Numeric> {
340
335
pub fn number ( input : Span ) -> PResult < Number > {
341
336
map (
342
337
tuple ( (
343
- sign_prefix ,
338
+ sign_neg ,
344
339
alt ( (
345
340
map ( pair ( decimal_integer, decimal_decimals) , |( n, d) | n + d) ,
346
341
decimal_decimals,
347
342
decimal_integer,
348
343
) ) ,
349
344
opt ( preceded (
350
345
alt ( ( tag ( "e" ) , tag ( "E" ) ) ) ,
351
- tuple ( ( sign_prefix , decimal_i32) ) ,
346
+ tuple ( ( sign_neg , decimal_i32) ) ,
352
347
) ) ,
353
348
) ) ,
354
- |( sign, num, exp) | {
355
- let value = if sign == Some ( b"-" ) {
356
- // Only f64-based Number can represent negative zero.
357
- if num. is_zero ( ) {
358
- ( -0.0 ) . into ( )
359
- } else {
360
- -num
361
- }
362
- } else {
363
- num
364
- } ;
365
- if let Some ( ( e_sign, e_val) ) = exp {
366
- let e_val = if e_sign == Some ( b"-" ) { -e_val } else { e_val } ;
349
+ |( is_neg, num, exp) | {
350
+ let value = if is_neg { -num } else { num } ;
351
+ Number :: from ( if let Some ( ( e_neg, e_val) ) = exp {
352
+ let e_val = if e_neg { -e_val } else { e_val } ;
367
353
// Note: powi sounds right, but looses some precision.
368
- value * Number :: from ( 10f64 . powf ( e_val. into ( ) ) )
354
+ value * 10f64 . powf ( e_val. into ( ) )
369
355
} else {
370
356
value
371
- }
357
+ } )
372
358
} ,
373
359
) ( input)
374
360
}
375
361
376
- pub fn decimal_integer ( input : Span ) -> PResult < Number > {
377
- fold_many1 (
378
- // Note: We should use bytes directly, one_of returns a char.
379
- one_of ( "0123456789" ) ,
380
- || Number :: from ( 0 ) ,
381
- |r, d| ( r * 10 ) + Number :: from ( i64:: from ( d as u8 - b'0' ) ) ,
382
- ) ( input)
362
+ /// Parse true on `-` and false on `+` or no sign.
363
+ fn sign_neg ( input : Span ) -> PResult < bool > {
364
+ alt ( (
365
+ value ( true , char ( '-' ) ) ,
366
+ value ( false , char ( '+' ) ) ,
367
+ success ( false ) ,
368
+ ) ) ( input)
369
+ }
370
+
371
+ pub fn decimal_integer ( input : Span ) -> PResult < f64 > {
372
+ map ( digit1, |s : Span | {
373
+ s. fragment ( )
374
+ . iter ( )
375
+ . fold ( 0.0 , |r, d| ( r * 10. ) + f64:: from ( d - b'0' ) )
376
+ } ) ( input)
383
377
}
384
378
pub fn decimal_i32 ( input : Span ) -> PResult < i32 > {
385
379
fold_many1 (
@@ -390,23 +384,14 @@ pub fn decimal_i32(input: Span) -> PResult<i32> {
390
384
) ( input)
391
385
}
392
386
393
- pub fn decimal_decimals ( input : Span ) -> PResult < Number > {
394
- map (
395
- preceded (
396
- tag ( "." ) ,
397
- fold_many1 (
398
- one_of ( "0123456789" ) ,
399
- || ( Number :: from ( 0 ) , Number :: from ( 1 ) ) ,
400
- |( r, n) , d| {
401
- (
402
- ( r * 10 ) + Number :: from ( i64:: from ( d as u8 - b'0' ) ) ,
403
- n * 10 ,
404
- )
405
- } ,
406
- ) ,
407
- ) ,
408
- |( r, d) | r / d,
409
- ) ( input)
387
+ pub fn decimal_decimals ( input : Span ) -> PResult < f64 > {
388
+ map ( preceded ( char ( '.' ) , digit1) , |s : Span | {
389
+ let digits = s. fragment ( ) ;
390
+ digits
391
+ . iter ( )
392
+ . fold ( 0.0 , |r, d| ( r * 10. ) + f64:: from ( d - b'0' ) )
393
+ * ( 10f64 ) . powf ( -( digits. len ( ) as f64 ) )
394
+ } ) ( input)
410
395
}
411
396
412
397
pub fn variable_nomod ( input : Span ) -> PResult < Value > {
0 commit comments