Allow floating point numbers ending in a period.

This commit is contained in:
Stephen Chung 2020-11-23 22:51:21 +08:00
parent 36aa827e15
commit 86009c70c8
3 changed files with 31 additions and 12 deletions

View File

@ -8,14 +8,15 @@ Integer numbers follow C-style format with support for decimal, binary ('`0b`'),
The default system integer type (also aliased to `INT`) is `i64`. It can be turned into `i32` via the [`only_i32`] feature. The default system integer type (also aliased to `INT`) is `i64`. It can be turned into `i32` via the [`only_i32`] feature.
Floating-point numbers are also supported if not disabled with [`no_float`]. The default system floating-point type is `i64` Floating-point numbers are also supported if not disabled with [`no_float`]. The default system floating-point type is `i64`
(also aliased to `FLOAT`). (also aliased to `FLOAT`). It can be turned into `f32` via the [`f32_float`] feature.
'`_`' separators can be added freely and are ignored within a number. '`_`' separators can be added freely and are ignored within a number - except at the very beginning or right after
a decimal point ('`.`').
| Format | Type | | Format | Type |
| ---------------- | ---------------- | | --------------------- | ---------------- |
| `123_345`, `-42` | `i64` in decimal | | `123_345`, `-42` | `INT` in decimal |
| `0o07_76` | `i64` in octal | | `0o07_76` | `INT` in octal |
| `0xabcd_ef` | `i64` in hex | | `0xabcd_ef` | `INT` in hex |
| `0b0101_1001` | `i64` in binary | | `0b0101_1001` | `INT` in binary |
| `123_456.789` | `f64` | | `123_456.789`, `-42.` | `FLOAT` |

View File

@ -1056,14 +1056,31 @@ fn get_next_token_inner(
'.' => { '.' => {
stream.get_next().unwrap(); stream.get_next().unwrap();
// Check if followed by digits (or _) // Check if followed by digits or something that cannot start a property name
match stream.peek_next().unwrap_or('\0') { match stream.peek_next().unwrap_or('\0') {
'0'..='9' | '_' => { // digits after period - accept the period
'0'..='9' => {
result.push(next_char); result.push(next_char);
pos.advance() pos.advance()
} }
_ => { // _ - cannot follow a decimal point
'_' => {
stream.unread(next_char);
break;
}
// .. - reserved symbol, not a floating-point number
'.' => {
stream.unread(next_char);
break;
}
// symbol after period - probably a float
ch @ _ if !is_id_first_alphabetic(ch) => {
result.push(next_char);
pos.advance();
result.push('0');
}
// Not a floating-point number // Not a floating-point number
_ => {
stream.unread(next_char); stream.unread(next_char);
break; break;
} }

View File

@ -15,6 +15,7 @@ fn test_float() -> Result<(), Box<EvalAltResult>> {
engine.eval::<bool>("let x = 0.0; let y = 1.0; x > y")?, engine.eval::<bool>("let x = 0.0; let y = 1.0; x > y")?,
false false
); );
assert_eq!(engine.eval::<bool>("let x = 0.; let y = 1.; x > y")?, false);
assert!((engine.eval::<FLOAT>("let x = 9.9999; x")? - 9.9999 as FLOAT).abs() < EPSILON); assert!((engine.eval::<FLOAT>("let x = 9.9999; x")? - 9.9999 as FLOAT).abs() < EPSILON);
Ok(()) Ok(())