From 86009c70c8f182d0138e89cd3f52e59604a3ee5b Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Mon, 23 Nov 2020 22:51:21 +0800 Subject: [PATCH] Allow floating point numbers ending in a period. --- doc/src/language/numbers.md | 19 ++++++++++--------- src/token.rs | 23 ++++++++++++++++++++--- tests/float.rs | 1 + 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/doc/src/language/numbers.md b/doc/src/language/numbers.md index 388d3e77..33c3c930 100644 --- a/doc/src/language/numbers.md +++ b/doc/src/language/numbers.md @@ -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. 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 | -| ---------------- | ---------------- | -| `123_345`, `-42` | `i64` in decimal | -| `0o07_76` | `i64` in octal | -| `0xabcd_ef` | `i64` in hex | -| `0b0101_1001` | `i64` in binary | -| `123_456.789` | `f64` | +| Format | Type | +| --------------------- | ---------------- | +| `123_345`, `-42` | `INT` in decimal | +| `0o07_76` | `INT` in octal | +| `0xabcd_ef` | `INT` in hex | +| `0b0101_1001` | `INT` in binary | +| `123_456.789`, `-42.` | `FLOAT` | diff --git a/src/token.rs b/src/token.rs index aad19ef2..2433a35c 100644 --- a/src/token.rs +++ b/src/token.rs @@ -1056,14 +1056,31 @@ fn get_next_token_inner( '.' => { 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') { - '0'..='9' | '_' => { + // digits after period - accept the period + '0'..='9' => { result.push(next_char); 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); break; } diff --git a/tests/float.rs b/tests/float.rs index 1e973e29..7c5a4c2f 100644 --- a/tests/float.rs +++ b/tests/float.rs @@ -15,6 +15,7 @@ fn test_float() -> Result<(), Box> { engine.eval::("let x = 0.0; let y = 1.0; x > y")?, false ); + assert_eq!(engine.eval::("let x = 0.; let y = 1.; x > y")?, false); assert!((engine.eval::("let x = 9.9999; x")? - 9.9999 as FLOAT).abs() < EPSILON); Ok(())