diff --git a/CHANGELOG.md b/CHANGELOG.md index cf0959d63e5..b10b3f8dc7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -413,3 +413,6 @@ updates if the constructor definition has a positional field defined after labelled fields. ([Hari Mohan](https://gituhub.com/seafoamteal)) + +- Fixed invalid JavaScript code generation when ints or floats had prefixed `0`s + before and after an `_` (e.g. `000_001`). diff --git a/compiler-core/src/javascript/expression.rs b/compiler-core/src/javascript/expression.rs index 78d13d1f567..8bf56bd64a4 100644 --- a/compiler-core/src/javascript/expression.rs +++ b/compiler-core/src/javascript/expression.rs @@ -2464,16 +2464,11 @@ pub fn eco_string_int<'a>(value: EcoString) -> Document<'a> { value }; - let value = value.trim_start_matches('0'); + let value = value.trim_start_matches(['0', '_']); if value.is_empty() { out.push('0'); } - // If the number starts with a `0` then an underscore, the `0` will be stripped, - // leaving the number to look something like `_1_2_3`, which is not valid syntax. - // Therefore, we strip the `_` to avoid this case. - let value = value.trim_start_matches('_'); - out.push_str(value); out.to_doc() @@ -2489,7 +2484,7 @@ pub fn float(value: &str) -> Document<'_> { }; let value = value.trim_start_matches(['+', '-'].as_ref()); - let value = value.trim_start_matches('0'); + let value = value.trim_start_matches(['0', '_']); if value.starts_with(['.', 'e', 'E']) { out.push('0'); } diff --git a/compiler-core/src/javascript/tests/numbers.rs b/compiler-core/src/javascript/tests/numbers.rs index 75aed82f81a..7b468fdc326 100644 --- a/compiler-core/src/javascript/tests/numbers.rs +++ b/compiler-core/src/javascript/tests/numbers.rs @@ -256,6 +256,18 @@ pub fn main() { ); } +// https://github.com/gleam-lang/gleam/issues/5459 +#[test] +fn many_preceeding_zeros_int() { + assert_js!( + r#" +pub fn main() { + 0000_000_00_9_179 +} +"# + ); +} + // https://github.com/gleam-lang/gleam/issues/2412 #[test] fn preceeding_zeros_float() { @@ -268,6 +280,18 @@ pub fn main() { ); } +// https://github.com/gleam-lang/gleam/issues/5459 +#[test] +fn many_preceeding_zeros_float() { + assert_js!( + r#" +pub fn main() { + 0000_000_00_9_179.1 +} +"# + ); +} + // https://github.com/gleam-lang/gleam/issues/2412 #[test] fn preceeding_zeros_int_const() { @@ -278,6 +302,16 @@ pub const x = 09_179 ); } +// https://github.com/gleam-lang/gleam/issues/5459 +#[test] +fn many_preceeding_zeros_int_const() { + assert_js!( + r#" +pub const x = 0000_000_00_9_179 +"# + ); +} + // https://github.com/gleam-lang/gleam/issues/2412 #[test] fn preceeding_zeros_float_const() { @@ -288,6 +322,16 @@ pub const x = 09_179.1 ); } +// https://github.com/gleam-lang/gleam/issues/5459 +#[test] +fn many_preceeding_zeros_float_const() { + assert_js!( + r#" +pub const x = 0000_000_00_9_179.1 +"# + ); +} + // https://github.com/gleam-lang/gleam/issues/2412 #[test] fn preceeding_zeros_int_pattern() { @@ -300,6 +344,18 @@ pub fn main(x) { ); } +// https://github.com/gleam-lang/gleam/issues/5459 +#[test] +fn many_preceeding_zeros_int_pattern() { + assert_js!( + r#" +pub fn main(x) { + let assert 0000_000_00_9_179 = x +} +"# + ); +} + // https://github.com/gleam-lang/gleam/issues/2412 #[test] fn preceeding_zeros_float_pattern() { @@ -312,6 +368,18 @@ pub fn main(x) { ); } +// https://github.com/gleam-lang/gleam/issues/5459 +#[test] +fn many_preceeding_zeros_float_pattern() { + assert_js!( + r#" +pub fn main(x) { + let assert 0000_000_00_9_179.1 = x +} +"# + ); +} + // https://github.com/gleam-lang/gleam/issues/4459 #[test] fn underscore_after_hexadecimal_prefix() { diff --git a/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_float.snap b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_float.snap new file mode 100644 index 00000000000..81c9aecfb65 --- /dev/null +++ b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_float.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/javascript/tests/numbers.rs +expression: "\npub fn main() {\n 0000_000_00_9_179.1\n}\n" +--- +----- SOURCE CODE + +pub fn main() { + 0000_000_00_9_179.1 +} + + +----- COMPILED JAVASCRIPT +export function main() { + return 9179.1; +} diff --git a/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_float_const.snap b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_float_const.snap new file mode 100644 index 00000000000..c7bd24f7011 --- /dev/null +++ b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_float_const.snap @@ -0,0 +1,11 @@ +--- +source: compiler-core/src/javascript/tests/numbers.rs +expression: "\npub const x = 0000_000_00_9_179.1\n" +--- +----- SOURCE CODE + +pub const x = 0000_000_00_9_179.1 + + +----- COMPILED JAVASCRIPT +export const x = 9_179.1; diff --git a/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_float_pattern.snap b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_float_pattern.snap new file mode 100644 index 00000000000..f214c94e3c5 --- /dev/null +++ b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_float_pattern.snap @@ -0,0 +1,30 @@ +--- +source: compiler-core/src/javascript/tests/numbers.rs +expression: "\npub fn main(x) {\n let assert 0000_000_00_9_179.1 = x\n}\n" +--- +----- SOURCE CODE + +pub fn main(x) { + let assert 0000_000_00_9_179.1 = x +} + + +----- COMPILED JAVASCRIPT +import { makeError } from "../gleam.mjs"; + +const FILEPATH = "src/module.gleam"; + +export function main(x) { + if (!(x === 9179.1)) { + throw makeError( + "let_assert", + FILEPATH, + "my/mod", + 3, + "main", + "Pattern match failed, no pattern matched the value.", + { value: x, start: 20, end: 54, pattern_start: 31, pattern_end: 50 } + ) + } + return x; +} diff --git a/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_int.snap b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_int.snap new file mode 100644 index 00000000000..0ebb532ad1c --- /dev/null +++ b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_int.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/javascript/tests/numbers.rs +expression: "\npub fn main() {\n 0000_000_00_9_179\n}\n" +--- +----- SOURCE CODE + +pub fn main() { + 0000_000_00_9_179 +} + + +----- COMPILED JAVASCRIPT +export function main() { + return 9_179; +} diff --git a/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_int_const.snap b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_int_const.snap new file mode 100644 index 00000000000..665fcb9c6b1 --- /dev/null +++ b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_int_const.snap @@ -0,0 +1,11 @@ +--- +source: compiler-core/src/javascript/tests/numbers.rs +expression: "\npub const x = 0000_000_00_9_179\n" +--- +----- SOURCE CODE + +pub const x = 0000_000_00_9_179 + + +----- COMPILED JAVASCRIPT +export const x = 9_179; diff --git a/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_int_pattern.snap b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_int_pattern.snap new file mode 100644 index 00000000000..403e8ae2c75 --- /dev/null +++ b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_int_pattern.snap @@ -0,0 +1,30 @@ +--- +source: compiler-core/src/javascript/tests/numbers.rs +expression: "\npub fn main(x) {\n let assert 0000_000_00_9_179 = x\n}\n" +--- +----- SOURCE CODE + +pub fn main(x) { + let assert 0000_000_00_9_179 = x +} + + +----- COMPILED JAVASCRIPT +import { makeError } from "../gleam.mjs"; + +const FILEPATH = "src/module.gleam"; + +export function main(x) { + if (!(x === 9179)) { + throw makeError( + "let_assert", + FILEPATH, + "my/mod", + 3, + "main", + "Pattern match failed, no pattern matched the value.", + { value: x, start: 20, end: 52, pattern_start: 31, pattern_end: 48 } + ) + } + return x; +} diff --git a/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__zero_after_underscore_after_binary_prefix.snap b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__zero_after_underscore_after_binary_prefix.snap index 50c7eaec8b7..0f864c36147 100644 --- a/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__zero_after_underscore_after_binary_prefix.snap +++ b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__zero_after_underscore_after_binary_prefix.snap @@ -11,5 +11,5 @@ pub fn main() { ----- COMPILED JAVASCRIPT export function main() { - return 0b0_1_0_1; + return 0b1_0_1; } diff --git a/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__zero_after_underscore_after_hex_prefix.snap b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__zero_after_underscore_after_hex_prefix.snap index 1bf69a0b4f2..5476cfd1b69 100644 --- a/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__zero_after_underscore_after_hex_prefix.snap +++ b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__zero_after_underscore_after_hex_prefix.snap @@ -11,5 +11,5 @@ pub fn main() { ----- COMPILED JAVASCRIPT export function main() { - return 0x0_1_2_3; + return 0x1_2_3; } diff --git a/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__zero_after_underscore_after_octal_prefix.snap b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__zero_after_underscore_after_octal_prefix.snap index 6e809444b84..5c7cce87125 100644 --- a/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__zero_after_underscore_after_octal_prefix.snap +++ b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__zero_after_underscore_after_octal_prefix.snap @@ -11,5 +11,5 @@ pub fn main() { ----- COMPILED JAVASCRIPT export function main() { - return 0o0_1_2_3; + return 0o1_2_3; }