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

Configure Feed

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

Fix scoping of blocks

+92 -26
+39 -23
compiler-core/src/javascript/expression.rs
··· 471 471 result 472 472 } 473 473 474 + fn wrap_block<CompileFn>(&mut self, compile: CompileFn) -> Output<'a> 475 + where 476 + CompileFn: Fn(&mut Self) -> Output<'a>, 477 + { 478 + let block_variable = self.next_local_var(&BLOCK_VARIABLE.into()); 479 + 480 + // Save initial state 481 + let scope_position = std::mem::replace( 482 + &mut self.scope_position, 483 + Position::Assign(block_variable.clone()), 484 + ); 485 + let function_position = std::mem::replace(&mut self.function_position, Position::NotTail); 486 + 487 + // Generate the expression 488 + let statement_doc = compile(self)?; 489 + self.statement_level 490 + .push(docvec!["let ", block_variable.clone(), ";"]); 491 + self.statement_level.push(statement_doc); 492 + 493 + // Reset 494 + self.scope_position = scope_position; 495 + self.function_position = function_position; 496 + 497 + Ok(self.wrap_return(block_variable.to_doc())) 498 + } 499 + 474 500 /// Use the `_block` variable if the expression is JS statement. 475 501 pub fn wrap_expression(&mut self, expression: &'a TypedExpr) -> Output<'a> { 476 502 match expression { ··· 478 504 | TypedExpr::Todo { .. } 479 505 | TypedExpr::Case { .. } 480 506 | TypedExpr::Pipeline { .. } 481 - | TypedExpr::RecordUpdate { .. } => { 482 - let block_variable = self.next_local_var(&BLOCK_VARIABLE.into()); 483 - let statement_doc = self.not_in_tail_position(|this| { 484 - this.scope_position = Position::Assign(block_variable.clone()); 485 - this.expression(expression) 486 - })?; 487 - self.statement_level 488 - .push(docvec!["let ", block_variable.clone(), ";"]); 489 - self.statement_level.push(statement_doc); 490 - Ok(self.wrap_return(block_variable.to_doc())) 491 - } 507 + | TypedExpr::RecordUpdate { .. } => self.wrap_block(|this| this.expression(expression)), 492 508 _ => self.expression(expression), 493 509 } 494 510 } ··· 604 620 } 605 621 } else { 606 622 match &self.scope_position { 607 - Position::Tail | Position::Assign(_) => return self.block_document(statements), 608 - Position::NotTail => {} 609 - } 623 + Position::Tail | Position::Assign(_) => self.block_document(statements), 624 + Position::NotTail => self.wrap_block(|this| { 625 + // Save previous scope 626 + let current_scope_vars = this.current_scope_vars.clone(); 610 627 611 - let block_variable = self.next_local_var(&BLOCK_VARIABLE.into()); 612 - let statements = self.not_in_tail_position(|this| { 613 - this.scope_position = Position::Assign(block_variable.clone()); 614 - this.block_document(statements) 615 - })?; 616 - self.statement_level 617 - .push(docvec!["let ", block_variable.clone(), ";"]); 618 - self.statement_level.push(statements); 619 - Ok(self.wrap_return(block_variable.to_doc())) 628 + let document = this.block_document(statements)?; 629 + 630 + // Restore previous state 631 + this.current_scope_vars = current_scope_vars; 632 + 633 + Ok(document) 634 + }), 635 + } 620 636 } 621 637 } 622 638
+18
compiler-core/src/javascript/tests/blocks.rs
··· 259 259 "# 260 260 ); 261 261 } 262 + 263 + #[test] 264 + fn shadowed_variable_in_nested_scope() { 265 + assert_js!( 266 + " 267 + pub fn main() { 268 + { 269 + let x = 1 270 + let _ = { 271 + let x = 2 272 + x 273 + } 274 + x 275 + } 276 + } 277 + " 278 + ) 279 + }
+1 -1
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__assignments__variable_renaming.snap
··· 51 51 _block = [a$3, b]; 52 52 } 53 53 let c = _block; 54 - wibble(a$3); 54 + wibble(a$2); 55 55 let x$1 = c; 56 56 return x$1; 57 57 }
+2 -2
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__blocks__nested_multiexpr_blocks_with_pipe.snap
··· 34 34 let _pipe = 3; 35 35 _block$1 = add1(_pipe); 36 36 } 37 - let _pipe$1 = _block$1; 38 - _block = add1(_pipe$1); 37 + let _pipe = _block$1; 38 + _block = add1(_pipe); 39 39 } 40 40 let x = _block; 41 41 return x;
+32
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__blocks__shadowed_variable_in_nested_scope.snap
··· 1 + --- 2 + source: compiler-core/src/javascript/tests/blocks.rs 3 + expression: "\npub fn main() {\n {\n let x = 1\n let _ = {\n let x = 2\n x\n }\n x\n }\n}\n" 4 + --- 5 + ----- SOURCE CODE 6 + 7 + pub fn main() { 8 + { 9 + let x = 1 10 + let _ = { 11 + let x = 2 12 + x 13 + } 14 + x 15 + } 16 + } 17 + 18 + 19 + ----- COMPILED JAVASCRIPT 20 + export function main() { 21 + { 22 + let x = 1; 23 + let _block; 24 + { 25 + let x$1 = 2; 26 + _block = x$1; 27 + } 28 + let $ = _block; 29 + 30 + return x; 31 + } 32 + }