|
|
@ -157,6 +157,16 @@ impl<R> Tokenizer<R> for NumberLiteral { |
|
|
|
|
|
|
|
|
|
|
|
// HexIntegerLiteral
|
|
|
|
// HexIntegerLiteral
|
|
|
|
kind = NumericKind::Integer(16); |
|
|
|
kind = NumericKind::Integer(16); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Checks if the next char after '0x' is a digit of that base. if not return an error.
|
|
|
|
|
|
|
|
if let Some(digit) = cursor.peek()? { |
|
|
|
|
|
|
|
if !digit.is_digit(16) { |
|
|
|
|
|
|
|
return Err(Error::syntax( |
|
|
|
|
|
|
|
"expected hexadecimal digit after number base prefix", |
|
|
|
|
|
|
|
cursor.pos(), |
|
|
|
|
|
|
|
)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
'o' | 'O' => { |
|
|
|
'o' | 'O' => { |
|
|
|
// Remove the initial '0' from buffer.
|
|
|
|
// Remove the initial '0' from buffer.
|
|
|
@ -165,6 +175,16 @@ impl<R> Tokenizer<R> for NumberLiteral { |
|
|
|
|
|
|
|
|
|
|
|
// OctalIntegerLiteral
|
|
|
|
// OctalIntegerLiteral
|
|
|
|
kind = NumericKind::Integer(8); |
|
|
|
kind = NumericKind::Integer(8); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Checks if the next char after '0o' is a digit of that base. if not return an error.
|
|
|
|
|
|
|
|
if let Some(digit) = cursor.peek()? { |
|
|
|
|
|
|
|
if !digit.is_digit(8) { |
|
|
|
|
|
|
|
return Err(Error::syntax( |
|
|
|
|
|
|
|
"expected hexadecimal digit after number base prefix", |
|
|
|
|
|
|
|
cursor.pos(), |
|
|
|
|
|
|
|
)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
'b' | 'B' => { |
|
|
|
'b' | 'B' => { |
|
|
|
// Remove the initial '0' from buffer.
|
|
|
|
// Remove the initial '0' from buffer.
|
|
|
@ -173,6 +193,16 @@ impl<R> Tokenizer<R> for NumberLiteral { |
|
|
|
|
|
|
|
|
|
|
|
// BinaryIntegerLiteral
|
|
|
|
// BinaryIntegerLiteral
|
|
|
|
kind = NumericKind::Integer(2); |
|
|
|
kind = NumericKind::Integer(2); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Checks if the next char after '0b' is a digit of that base. if not return an error.
|
|
|
|
|
|
|
|
if let Some(digit) = cursor.peek()? { |
|
|
|
|
|
|
|
if !digit.is_digit(2) { |
|
|
|
|
|
|
|
return Err(Error::syntax( |
|
|
|
|
|
|
|
"expected hexadecimal digit after number base prefix", |
|
|
|
|
|
|
|
cursor.pos(), |
|
|
|
|
|
|
|
)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
'n' => { |
|
|
|
'n' => { |
|
|
|
cursor.next_char()?.expect("n character vanished"); |
|
|
|
cursor.next_char()?.expect("n character vanished"); |
|
|
@ -294,7 +324,7 @@ impl<R> Tokenizer<R> for NumberLiteral { |
|
|
|
let val = f64::from_str(&buf).expect("Failed to parse float after checks"); |
|
|
|
let val = f64::from_str(&buf).expect("Failed to parse float after checks"); |
|
|
|
let int_val = val as i32; |
|
|
|
let int_val = val as i32; |
|
|
|
|
|
|
|
|
|
|
|
// The truncated float should be identically to the non-truncated float for the conversion to be loss-less,
|
|
|
|
// The truncated float should be identically to the non-truncated float for the conversion to be loss-less,
|
|
|
|
// any other different and the number must be stored as a rational.
|
|
|
|
// any other different and the number must be stored as a rational.
|
|
|
|
#[allow(clippy::float_cmp)] |
|
|
|
#[allow(clippy::float_cmp)] |
|
|
|
if (int_val as f64) == val { |
|
|
|
if (int_val as f64) == val { |
|
|
|