Skip to content

Commit

Permalink
Add support for floats with scientific notation
Browse files Browse the repository at this point in the history
  • Loading branch information
Dave Parfitt committed Dec 21, 2022
1 parent 6f8fd93 commit 471703c
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 3 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

- Scientific notation support for floats.
- Fixed a bug where comments in list prepending expressions could be formatted
incorrectly.
- Fixed a bug where comments in record update expressions could be formatted
Expand All @@ -26,8 +27,8 @@
- Updated following runtime versions set via `gleam new`: `Erlang/OTP`
to `25.2`, and `Elixir` to `1.14.2`.
- The formatter now inserts underscores into larger `Int`s and the larger
integer parts of `Float`s.
- Added support for top level TypeScript file inclusion in builds.
integer parts of `Float`s.
- The build tool will now favour using rebar3 over Mix for packages that support
both. This fixes an issue where some packages could not be compiled without
Elixir installed even though it is not strictly required.
Expand Down
25 changes: 25 additions & 0 deletions compiler-core/src/erlang/tests/numbers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,28 @@ pub fn main() {
"#
);
}

#[test]
fn numbers_with_scientific_notation() {
assert_erl!(
r#"
const i = 100.001e523
const j = -100.001e-523
const k = 100.001e1_230
const l = -100.001e-1_230
const m = 100.001e123_456_789
const n = -100.001e-123_456_789
pub fn main() {
i
j
k
l
m
n
}
"#
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
source: compiler-core/src/erlang/tests/numbers.rs
expression: "\nconst i = 100.001e523\nconst j = -100.001e-523\n\nconst k = 100.001e1_230\nconst l = -100.001e-1_230\n\nconst m = 100.001e123_456_789\nconst n = -100.001e-123_456_789\n\npub fn main() {\n i\n j\n k\n l\n m\n n\n}\n"
---
-module(the_app).
-compile(no_auto_import).

-export([main/0]).

-spec main() -> float().
main() ->
100.001e523,
-100.001e-523,
100.001e1230,
-100.001e-1230,
100.001e123456789,
-100.001e-123456789.

37 changes: 37 additions & 0 deletions compiler-core/src/format/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1241,6 +1241,43 @@ fn expr_float() {
-1_234_567.0
-12_345_678.0
}
"#
);

assert_format_rewrite!(
r#"fn main() {
1.0e1
1.0e-1
-1.0e1
-1.0e-1
1.0e10
1.0e-10
-1.0e10
-11.0e-10
1.0e100
1.0e-100
-1.0e100
-11.0e-100
1.0000e100
1.0000e100_100
}
"#,
r#"fn main() {
1.0e1
1.0e-1
-1.0e1
-1.0e-1
1.0e10
1.0e-10
-1.0e10
-11.0e-10
1.0e100
1.0e-100
-1.0e100
-11.0e-100
1.0000e100
1.0000e100_100
}
"#
);
}
Expand Down
8 changes: 8 additions & 0 deletions compiler-core/src/javascript/tests/numbers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ fn go() {
0b00001111
0o17
0xF
0.01e-1
0.01e-0
-10.01e-1
-10.01e-0
100.001e523
-100.001e-523
100.001e123_456_789
-100.001e-123_456_789
1_000
}
"#,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
source: compiler-core/src/javascript/tests/numbers.rs
assertion_line: 5
expression: "\nfn go() {\n 1\n 2\n -3\n 4001\n 0b00001111\n 0o17\n 0xF\n 1_000\n}\n"
expression: "\nfn go() {\n 1\n 2\n -3\n 4001\n 0b00001111\n 0o17\n 0xF\n 0.01e-1\n 0.01e-0\n -10.01e-1\n -10.01e-0\n 100.001e523\n -100.001e-523\n 100.001e123_456_789\n -100.001e-123_456_789\n 1_000\n}\n"
---
function go() {
1;
Expand All @@ -11,6 +10,14 @@ function go() {
0b00001111;
0o17;
0xF;
0.01e-1;
0.01e-0;
-10.01e-1;
-10.01e-0;
100.001e523;
-100.001e-523;
100.001e123_456_789;
-100.001e-123_456_789;
return 1_000;
}

12 changes: 12 additions & 0 deletions compiler-core/src/parse/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,18 @@ where
if self.chr0 == Some('.') {
value.push(self.next_char().expect("lex_normal_number float"));
value.push_str(&self.radix_run(10));

// If scientific:
if self.chr0 == Some('e') {
value.push(self.next_char().expect("lex_normal_number scientific"));
if self.chr0 == Some('-') {
value.push(
self.next_char()
.expect("lex_normal_number scientific negative"),
);
}
value.push_str(&self.radix_run(10));
}
let end_pos = self.get_pos();
(start_pos, Token::Float { value }, end_pos)
} else {
Expand Down
4 changes: 4 additions & 0 deletions compiler-core/src/type_/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,10 @@ fn simple_exprs() {
assert_infer!("0xF", "Int");
assert_infer!("0o11", "Int");
assert_infer!("0b1010", "Int");

// scientific notation
assert_infer!("6.02e23", "Float");
assert_infer!("6.02e-23", "Float");
}

#[test]
Expand Down
39 changes: 39 additions & 0 deletions test/language/src/main.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,45 @@ fn float_tests() -> List(Test) {
equality_test("Precedence 1", 8.0, 2.0 +. 2.0 *. 3.0),
equality_test("Precedence 2", 10.0, 2.0 *. { 2.0 +. 3.0 }),
equality_test("Precedence 3", 12.0, { 2.0 +. 2.0 } *. 3.0),


// scientific notation
basic_addition(0.0e0, 0.0, 0.0),
basic_addition(0.0, 0.0e0, 0.0),
basic_addition(0.0e-0, 0.0, 0.0),
basic_addition(0.0, 0.0e-0, 0.0),
basic_addition(1.0e3, 1.0, 1001.0),
basic_addition(5.0, 1.0e3, 1005.0),
basic_addition(1.0e5, -3.0e5, -200000.0),
basic_addition(1.0e50, -1.0e50, 0.0),
basic_addition(1.0e-3, 1.0, 1.001),
basic_addition(5.0, 1.0e-3, 5.001),
basic_addition(10.0e-2, -3.0e-2, 0.07),

basic_subtraction(0.0e0, 0.0, 0.0),
basic_subtraction(0.0, 0.0e0, 0.0),
basic_subtraction(0.0e-0, 0.0, 0.0),
basic_subtraction(0.0, 0.0e-0, 0.0),
basic_subtraction(1.0e3, 1.0, 999.0),
basic_subtraction(5.0, 1.0e3, -995.0),
basic_subtraction(1.0e5, 1.0e5, 0.0),
basic_subtraction(1.0e-3, 1.0, -0.999),
basic_subtraction(5.0, 1.0e-3, 4.999),
basic_subtraction(10.0e-2, -3.0e-2, 0.13),

basic_multiplication(0.0e0, 0.0, 0.0),
basic_multiplication(0.0, 0.0e0, 0.0),
basic_multiplication(0.0e-0, 0.0, 0.0),
basic_multiplication(0.0, 0.0e-0, 0.0),
basic_multiplication(2.0e1, 2.0e1, 400.0),
basic_multiplication(1.0e-5, 1.0e5, 1.0),
basic_multiplication(2.0e5, 2.0e-5, 4.0),
basic_multiplication(2.0e5, 4.0e-4, 80.0),
basic_multiplication(2.0e-5, 2.0e5, 4.0),
basic_multiplication(2.0e5, 4.0e-5, 8.0),
basic_multiplication(-2.0e-5, 2.0e5, -4.0),
basic_multiplication(-2.0e5, -4.0e-5, 8.0),

]
}

Expand Down

0 comments on commit 471703c

Please sign in to comment.