Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

Fix invalid JS for ints with 0s as prefix (#5459)

author
Gavin Morrow
committer
Louis Pilfold
date (Mar 16, 2026, 11:30 AM UTC) commit bddb2d45 parent e7ec1ea2 change-id lrnmvtwx
+188 -10
+3
CHANGELOG.md
··· 421 421 updates if the constructor definition has a positional field defined after 422 422 labelled fields. 423 423 ([Hari Mohan](https://gituhub.com/seafoamteal)) 424 + 425 + - Fixed invalid JavaScript code generation when ints or floats had prefixed `0`s 426 + before and after an `_` (e.g. `000_001`).
+2 -7
compiler-core/src/javascript/expression.rs
··· 2464 2464 value 2465 2465 }; 2466 2466 2467 - let value = value.trim_start_matches('0'); 2467 + let value = value.trim_start_matches(['0', '_']); 2468 2468 if value.is_empty() { 2469 2469 out.push('0'); 2470 2470 } 2471 - 2472 - // If the number starts with a `0` then an underscore, the `0` will be stripped, 2473 - // leaving the number to look something like `_1_2_3`, which is not valid syntax. 2474 - // Therefore, we strip the `_` to avoid this case. 2475 - let value = value.trim_start_matches('_'); 2476 2471 2477 2472 out.push_str(value); 2478 2473 ··· 2489 2484 }; 2490 2485 let value = value.trim_start_matches(['+', '-'].as_ref()); 2491 2486 2492 - let value = value.trim_start_matches('0'); 2487 + let value = value.trim_start_matches(['0', '_']); 2493 2488 if value.starts_with(['.', 'e', 'E']) { 2494 2489 out.push('0'); 2495 2490 }
+68
compiler-core/src/javascript/tests/numbers.rs
··· 256 256 ); 257 257 } 258 258 259 + // https://github.com/gleam-lang/gleam/issues/5459 260 + #[test] 261 + fn many_preceeding_zeros_int() { 262 + assert_js!( 263 + r#" 264 + pub fn main() { 265 + 0000_000_00_9_179 266 + } 267 + "# 268 + ); 269 + } 270 + 259 271 // https://github.com/gleam-lang/gleam/issues/2412 260 272 #[test] 261 273 fn preceeding_zeros_float() { ··· 268 280 ); 269 281 } 270 282 283 + // https://github.com/gleam-lang/gleam/issues/5459 284 + #[test] 285 + fn many_preceeding_zeros_float() { 286 + assert_js!( 287 + r#" 288 + pub fn main() { 289 + 0000_000_00_9_179.1 290 + } 291 + "# 292 + ); 293 + } 294 + 271 295 // https://github.com/gleam-lang/gleam/issues/2412 272 296 #[test] 273 297 fn preceeding_zeros_int_const() { 274 298 assert_js!( 275 299 r#" 276 300 pub const x = 09_179 301 + "# 302 + ); 303 + } 304 + 305 + // https://github.com/gleam-lang/gleam/issues/5459 306 + #[test] 307 + fn many_preceeding_zeros_int_const() { 308 + assert_js!( 309 + r#" 310 + pub const x = 0000_000_00_9_179 277 311 "# 278 312 ); 279 313 } ··· 288 322 ); 289 323 } 290 324 325 + // https://github.com/gleam-lang/gleam/issues/5459 326 + #[test] 327 + fn many_preceeding_zeros_float_const() { 328 + assert_js!( 329 + r#" 330 + pub const x = 0000_000_00_9_179.1 331 + "# 332 + ); 333 + } 334 + 291 335 // https://github.com/gleam-lang/gleam/issues/2412 292 336 #[test] 293 337 fn preceeding_zeros_int_pattern() { ··· 300 344 ); 301 345 } 302 346 347 + // https://github.com/gleam-lang/gleam/issues/5459 348 + #[test] 349 + fn many_preceeding_zeros_int_pattern() { 350 + assert_js!( 351 + r#" 352 + pub fn main(x) { 353 + let assert 0000_000_00_9_179 = x 354 + } 355 + "# 356 + ); 357 + } 358 + 303 359 // https://github.com/gleam-lang/gleam/issues/2412 304 360 #[test] 305 361 fn preceeding_zeros_float_pattern() { ··· 307 363 r#" 308 364 pub fn main(x) { 309 365 let assert 09_179.1 = x 366 + } 367 + "# 368 + ); 369 + } 370 + 371 + // https://github.com/gleam-lang/gleam/issues/5459 372 + #[test] 373 + fn many_preceeding_zeros_float_pattern() { 374 + assert_js!( 375 + r#" 376 + pub fn main(x) { 377 + let assert 0000_000_00_9_179.1 = x 310 378 } 311 379 "# 312 380 );
+15
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_float.snap
··· 1 + --- 2 + source: compiler-core/src/javascript/tests/numbers.rs 3 + expression: "\npub fn main() {\n 0000_000_00_9_179.1\n}\n" 4 + --- 5 + ----- SOURCE CODE 6 + 7 + pub fn main() { 8 + 0000_000_00_9_179.1 9 + } 10 + 11 + 12 + ----- COMPILED JAVASCRIPT 13 + export function main() { 14 + return 9179.1; 15 + }
+11
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_float_const.snap
··· 1 + --- 2 + source: compiler-core/src/javascript/tests/numbers.rs 3 + expression: "\npub const x = 0000_000_00_9_179.1\n" 4 + --- 5 + ----- SOURCE CODE 6 + 7 + pub const x = 0000_000_00_9_179.1 8 + 9 + 10 + ----- COMPILED JAVASCRIPT 11 + export const x = 9_179.1;
+30
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_float_pattern.snap
··· 1 + --- 2 + source: compiler-core/src/javascript/tests/numbers.rs 3 + expression: "\npub fn main(x) {\n let assert 0000_000_00_9_179.1 = x\n}\n" 4 + --- 5 + ----- SOURCE CODE 6 + 7 + pub fn main(x) { 8 + let assert 0000_000_00_9_179.1 = x 9 + } 10 + 11 + 12 + ----- COMPILED JAVASCRIPT 13 + import { makeError } from "../gleam.mjs"; 14 + 15 + const FILEPATH = "src/module.gleam"; 16 + 17 + export function main(x) { 18 + if (!(x === 9179.1)) { 19 + throw makeError( 20 + "let_assert", 21 + FILEPATH, 22 + "my/mod", 23 + 3, 24 + "main", 25 + "Pattern match failed, no pattern matched the value.", 26 + { value: x, start: 20, end: 54, pattern_start: 31, pattern_end: 50 } 27 + ) 28 + } 29 + return x; 30 + }
+15
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_int.snap
··· 1 + --- 2 + source: compiler-core/src/javascript/tests/numbers.rs 3 + expression: "\npub fn main() {\n 0000_000_00_9_179\n}\n" 4 + --- 5 + ----- SOURCE CODE 6 + 7 + pub fn main() { 8 + 0000_000_00_9_179 9 + } 10 + 11 + 12 + ----- COMPILED JAVASCRIPT 13 + export function main() { 14 + return 9_179; 15 + }
+11
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_int_const.snap
··· 1 + --- 2 + source: compiler-core/src/javascript/tests/numbers.rs 3 + expression: "\npub const x = 0000_000_00_9_179\n" 4 + --- 5 + ----- SOURCE CODE 6 + 7 + pub const x = 0000_000_00_9_179 8 + 9 + 10 + ----- COMPILED JAVASCRIPT 11 + export const x = 9_179;
+30
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__many_preceeding_zeros_int_pattern.snap
··· 1 + --- 2 + source: compiler-core/src/javascript/tests/numbers.rs 3 + expression: "\npub fn main(x) {\n let assert 0000_000_00_9_179 = x\n}\n" 4 + --- 5 + ----- SOURCE CODE 6 + 7 + pub fn main(x) { 8 + let assert 0000_000_00_9_179 = x 9 + } 10 + 11 + 12 + ----- COMPILED JAVASCRIPT 13 + import { makeError } from "../gleam.mjs"; 14 + 15 + const FILEPATH = "src/module.gleam"; 16 + 17 + export function main(x) { 18 + if (!(x === 9179)) { 19 + throw makeError( 20 + "let_assert", 21 + FILEPATH, 22 + "my/mod", 23 + 3, 24 + "main", 25 + "Pattern match failed, no pattern matched the value.", 26 + { value: x, start: 20, end: 52, pattern_start: 31, pattern_end: 48 } 27 + ) 28 + } 29 + return x; 30 + }
+1 -1
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__zero_after_underscore_after_binary_prefix.snap
··· 11 11 12 12 ----- COMPILED JAVASCRIPT 13 13 export function main() { 14 - return 0b0_1_0_1; 14 + return 0b1_0_1; 15 15 }
+1 -1
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__zero_after_underscore_after_hex_prefix.snap
··· 11 11 12 12 ----- COMPILED JAVASCRIPT 13 13 export function main() { 14 - return 0x0_1_2_3; 14 + return 0x1_2_3; 15 15 }
+1 -1
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__numbers__zero_after_underscore_after_octal_prefix.snap
··· 11 11 12 12 ----- COMPILED JAVASCRIPT 13 13 export function main() { 14 - return 0o0_1_2_3; 14 + return 0o1_2_3; 15 15 }