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

Configure Feed

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

gleam / compiler-core / src / ast_folder.rs
42 kB 1411 lines
1use ecow::EcoString; 2use num_bigint::BigInt; 3use vec1::Vec1; 4 5use crate::{ 6 analyse::Inferred, 7 ast::{ 8 AssignName, Assignment, BinOp, CallArg, Constant, Definition, FunctionLiteralKind, Pattern, 9 RecordBeingUpdated, SrcSpan, Statement, TargetedDefinition, TodoKind, TypeAst, 10 TypeAstConstructor, TypeAstFn, TypeAstHole, TypeAstTuple, TypeAstVar, UntypedArg, 11 UntypedAssignment, UntypedClause, UntypedConstant, UntypedConstantBitArraySegment, 12 UntypedCustomType, UntypedDefinition, UntypedExpr, UntypedExprBitArraySegment, 13 UntypedFunction, UntypedImport, UntypedModule, UntypedModuleConstant, UntypedPattern, 14 UntypedPatternBitArraySegment, UntypedRecordUpdateArg, UntypedStatement, UntypedTypeAlias, 15 UntypedUse, UntypedUseAssignment, Use, UseAssignment, 16 }, 17 build::Target, 18 type_::error::VariableOrigin, 19}; 20 21#[allow(dead_code)] 22pub trait UntypedModuleFolder: TypeAstFolder + UntypedExprFolder { 23 /// You probably don't want to override this method. 24 fn fold_module(&mut self, mut m: UntypedModule) -> UntypedModule { 25 m.definitions = m 26 .definitions 27 .into_iter() 28 .map(|d| { 29 let TargetedDefinition { definition, target } = d; 30 match definition { 31 Definition::Function(f) => { 32 let f = self.fold_function_definition(f, target); 33 let definition = self.walk_function_definition(f); 34 TargetedDefinition { definition, target } 35 } 36 37 Definition::TypeAlias(a) => { 38 let a = self.fold_type_alias(a, target); 39 let definition = self.walk_type_alias(a); 40 TargetedDefinition { definition, target } 41 } 42 43 Definition::CustomType(t) => { 44 let t = self.fold_custom_type(t, target); 45 let definition = self.walk_custom_type(t); 46 TargetedDefinition { definition, target } 47 } 48 49 Definition::Import(i) => { 50 let i = self.fold_import(i, target); 51 let definition = self.walk_import(i); 52 TargetedDefinition { definition, target } 53 } 54 55 Definition::ModuleConstant(c) => { 56 let c = self.fold_module_constant(c, target); 57 let definition = self.walk_module_constant(c); 58 TargetedDefinition { definition, target } 59 } 60 } 61 }) 62 .collect(); 63 m 64 } 65 66 /// You probably don't want to override this method. 67 fn walk_function_definition(&mut self, mut f: UntypedFunction) -> UntypedDefinition { 68 f.body = f.body.mapped(|s| self.fold_statement(s)); 69 f.return_annotation = f.return_annotation.map(|t| self.fold_type(t)); 70 f.arguments = f 71 .arguments 72 .into_iter() 73 .map(|mut a| { 74 a.annotation = a.annotation.map(|t| self.fold_type(t)); 75 a 76 }) 77 .collect(); 78 Definition::Function(f) 79 } 80 81 /// You probably don't want to override this method. 82 fn walk_type_alias(&mut self, mut f: UntypedTypeAlias) -> UntypedDefinition { 83 f.type_ast = self.fold_type(f.type_ast); 84 Definition::TypeAlias(f) 85 } 86 87 /// You probably don't want to override this method. 88 fn walk_custom_type(&mut self, mut c: UntypedCustomType) -> UntypedDefinition { 89 c.constructors = c 90 .constructors 91 .into_iter() 92 .map(|mut c| { 93 c.arguments = c 94 .arguments 95 .into_iter() 96 .map(|mut a| { 97 a.ast = self.fold_type(a.ast); 98 a 99 }) 100 .collect(); 101 c 102 }) 103 .collect(); 104 105 Definition::CustomType(c) 106 } 107 108 /// You probably don't want to override this method. 109 fn walk_import(&mut self, i: UntypedImport) -> UntypedDefinition { 110 Definition::Import(i) 111 } 112 113 /// You probably don't want to override this method. 114 fn walk_module_constant(&mut self, mut c: UntypedModuleConstant) -> UntypedDefinition { 115 c.annotation = c.annotation.map(|t| self.fold_type(t)); 116 c.value = Box::new(self.fold_constant(*c.value)); 117 Definition::ModuleConstant(c) 118 } 119 120 fn fold_function_definition( 121 &mut self, 122 f: UntypedFunction, 123 _target: Option<Target>, 124 ) -> UntypedFunction { 125 f 126 } 127 128 fn fold_type_alias( 129 &mut self, 130 f: UntypedTypeAlias, 131 _target: Option<Target>, 132 ) -> UntypedTypeAlias { 133 f 134 } 135 136 fn fold_custom_type( 137 &mut self, 138 c: UntypedCustomType, 139 _target: Option<Target>, 140 ) -> UntypedCustomType { 141 c 142 } 143 144 fn fold_import(&mut self, i: UntypedImport, _target: Option<Target>) -> UntypedImport { 145 i 146 } 147 148 fn fold_module_constant( 149 &mut self, 150 c: UntypedModuleConstant, 151 _target: Option<Target>, 152 ) -> UntypedModuleConstant { 153 c 154 } 155} 156 157#[allow(dead_code)] 158pub trait TypeAstFolder { 159 /// Visit a node and potentially replace it with another node using the 160 /// `fold_*` methods. Afterwards, the `walk` method is called on the new 161 /// node to continue traversing. 162 /// 163 /// You probably don't want to override this method. 164 fn fold_type(&mut self, t: TypeAst) -> TypeAst { 165 let t = self.update_type(t); 166 self.walk_type(t) 167 } 168 169 /// You probably don't want to override this method. 170 fn update_type(&mut self, t: TypeAst) -> TypeAst { 171 match t { 172 TypeAst::Constructor(c) => self.fold_type_constructor(c), 173 TypeAst::Fn(f) => self.fold_type_fn(f), 174 TypeAst::Var(v) => self.fold_type_var(v), 175 TypeAst::Tuple(t) => self.fold_type_tuple(t), 176 TypeAst::Hole(h) => self.fold_type_hole(h), 177 } 178 } 179 180 /// You probably don't want to override this method. 181 fn walk_type(&mut self, t: TypeAst) -> TypeAst { 182 match t { 183 TypeAst::Constructor(mut c) => { 184 c.arguments = self.fold_all_types(c.arguments); 185 TypeAst::Constructor(c) 186 } 187 188 TypeAst::Fn(mut f) => { 189 f.arguments = self.fold_all_types(f.arguments); 190 f.return_ = Box::new(self.fold_type(*f.return_)); 191 TypeAst::Fn(f) 192 } 193 194 TypeAst::Tuple(mut t) => { 195 t.elems = self.fold_all_types(t.elems); 196 TypeAst::Tuple(t) 197 } 198 199 TypeAst::Var(_) | TypeAst::Hole(_) => t, 200 } 201 } 202 203 /// You probably don't want to override this method. 204 fn fold_all_types(&mut self, ts: Vec<TypeAst>) -> Vec<TypeAst> { 205 ts.into_iter().map(|t| self.fold_type(t)).collect() 206 } 207 208 fn fold_type_constructor(&mut self, constructor: TypeAstConstructor) -> TypeAst { 209 TypeAst::Constructor(constructor) 210 } 211 212 fn fold_type_fn(&mut self, function: TypeAstFn) -> TypeAst { 213 TypeAst::Fn(function) 214 } 215 216 fn fold_type_tuple(&mut self, tuple: TypeAstTuple) -> TypeAst { 217 TypeAst::Tuple(tuple) 218 } 219 220 fn fold_type_var(&mut self, var: TypeAstVar) -> TypeAst { 221 TypeAst::Var(var) 222 } 223 224 fn fold_type_hole(&mut self, hole: TypeAstHole) -> TypeAst { 225 TypeAst::Hole(hole) 226 } 227} 228 229#[allow(dead_code)] 230pub trait UntypedExprFolder: TypeAstFolder + UntypedConstantFolder + PatternFolder { 231 /// Visit a node and potentially replace it with another node using the 232 /// `fold_*` methods. Afterwards, the `walk` method is called on the new 233 /// node to continue traversing. 234 /// 235 /// You probably don't want to override this method. 236 fn fold_expr(&mut self, t: UntypedExpr) -> UntypedExpr { 237 let t = self.update_expr(t); 238 self.walk_expr(t) 239 } 240 241 /// You probably don't want to override this method. 242 fn update_expr(&mut self, e: UntypedExpr) -> UntypedExpr { 243 match e { 244 UntypedExpr::Var { location, name } => self.fold_var(location, name), 245 UntypedExpr::Int { 246 location, 247 value, 248 int_value, 249 } => self.fold_int(location, value, int_value), 250 UntypedExpr::Float { location, value } => self.fold_float(location, value), 251 UntypedExpr::String { location, value } => self.fold_string(location, value), 252 253 UntypedExpr::Block { 254 location, 255 statements, 256 } => self.fold_block(location, statements), 257 258 UntypedExpr::Fn { 259 location, 260 end_of_head_byte_index, 261 kind, 262 arguments, 263 body, 264 return_annotation, 265 } => self.fold_fn( 266 location, 267 end_of_head_byte_index, 268 kind, 269 arguments, 270 body, 271 return_annotation, 272 ), 273 274 UntypedExpr::List { 275 location, 276 elements, 277 tail, 278 } => self.fold_list(location, elements, tail), 279 280 UntypedExpr::Call { 281 location, 282 fun, 283 arguments, 284 } => self.fold_call(location, fun, arguments), 285 286 UntypedExpr::BinOp { 287 location, 288 name, 289 left, 290 right, 291 } => self.fold_bin_op(location, name, left, right), 292 293 UntypedExpr::PipeLine { expressions } => self.fold_pipe_line(expressions), 294 295 UntypedExpr::Case { 296 location, 297 subjects, 298 clauses, 299 } => self.fold_case(location, subjects, clauses), 300 301 UntypedExpr::FieldAccess { 302 location, 303 label_location, 304 label, 305 container, 306 } => self.fold_field_access(location, label_location, label, container), 307 308 UntypedExpr::Tuple { location, elems } => self.fold_tuple(location, elems), 309 310 UntypedExpr::TupleIndex { 311 location, 312 index, 313 tuple, 314 } => self.fold_tuple_index(location, index, tuple), 315 316 UntypedExpr::Todo { 317 kind, 318 location, 319 message, 320 } => self.fold_todo(kind, location, message), 321 322 UntypedExpr::Panic { location, message } => self.fold_panic(location, message), 323 324 UntypedExpr::BitArray { location, segments } => self.fold_bit_array(location, segments), 325 326 UntypedExpr::RecordUpdate { 327 location, 328 constructor, 329 record, 330 arguments, 331 } => self.fold_record_update(location, constructor, record, arguments), 332 333 UntypedExpr::NegateBool { location, value } => self.fold_negate_bool(location, value), 334 335 UntypedExpr::NegateInt { location, value } => self.fold_negate_int(location, value), 336 337 UntypedExpr::Placeholder { location } => self.fold_placeholder(location), 338 } 339 } 340 341 /// You probably don't want to override this method. 342 fn walk_expr(&mut self, e: UntypedExpr) -> UntypedExpr { 343 match e { 344 UntypedExpr::Int { .. } 345 | UntypedExpr::Var { .. } 346 | UntypedExpr::Float { .. } 347 | UntypedExpr::String { .. } 348 | UntypedExpr::NegateInt { .. } 349 | UntypedExpr::NegateBool { .. } 350 | UntypedExpr::Placeholder { .. } => e, 351 352 UntypedExpr::Todo { 353 kind, 354 location, 355 message, 356 } => UntypedExpr::Todo { 357 kind, 358 location, 359 message: message.map(|msg_expr| Box::new(self.fold_expr(*msg_expr))), 360 }, 361 362 UntypedExpr::Panic { location, message } => UntypedExpr::Panic { 363 location, 364 message: message.map(|msg_expr| Box::new(self.fold_expr(*msg_expr))), 365 }, 366 367 UntypedExpr::Block { 368 location, 369 statements, 370 } => { 371 let statements = statements.mapped(|s| self.fold_statement(s)); 372 UntypedExpr::Block { 373 location, 374 statements, 375 } 376 } 377 378 UntypedExpr::Fn { 379 location, 380 kind, 381 end_of_head_byte_index, 382 arguments, 383 body, 384 return_annotation, 385 } => { 386 let arguments = arguments.into_iter().map(|a| self.fold_arg(a)).collect(); 387 let return_annotation = return_annotation.map(|t| self.fold_type(t)); 388 let body = body.mapped(|s| self.fold_statement(s)); 389 UntypedExpr::Fn { 390 location, 391 end_of_head_byte_index, 392 kind, 393 arguments, 394 body, 395 return_annotation, 396 } 397 } 398 399 UntypedExpr::List { 400 location, 401 elements, 402 tail, 403 } => { 404 let elements = elements.into_iter().map(|e| self.fold_expr(e)).collect(); 405 let tail = tail.map(|e| Box::new(self.fold_expr(*e))); 406 UntypedExpr::List { 407 location, 408 elements, 409 tail, 410 } 411 } 412 413 UntypedExpr::Call { 414 location, 415 fun, 416 arguments, 417 } => { 418 let fun = Box::new(self.fold_expr(*fun)); 419 let arguments = arguments 420 .into_iter() 421 .map(|mut a| { 422 a.value = self.fold_expr(a.value); 423 a 424 }) 425 .collect(); 426 UntypedExpr::Call { 427 location, 428 fun, 429 arguments, 430 } 431 } 432 433 UntypedExpr::BinOp { 434 location, 435 name, 436 left, 437 right, 438 } => { 439 let left = Box::new(self.fold_expr(*left)); 440 let right = Box::new(self.fold_expr(*right)); 441 UntypedExpr::BinOp { 442 location, 443 name, 444 left, 445 right, 446 } 447 } 448 449 UntypedExpr::PipeLine { expressions } => { 450 let expressions = expressions.mapped(|e| self.fold_expr(e)); 451 UntypedExpr::PipeLine { expressions } 452 } 453 454 UntypedExpr::Case { 455 location, 456 subjects, 457 clauses, 458 } => { 459 let subjects = subjects.into_iter().map(|e| self.fold_expr(e)).collect(); 460 let clauses = clauses.map(|clauses| { 461 clauses 462 .into_iter() 463 .map(|mut c| { 464 c.pattern = c 465 .pattern 466 .into_iter() 467 .map(|p| self.fold_pattern(p)) 468 .collect(); 469 c.alternative_patterns = c 470 .alternative_patterns 471 .into_iter() 472 .map(|p| p.into_iter().map(|p| self.fold_pattern(p)).collect()) 473 .collect(); 474 c.then = self.fold_expr(c.then); 475 c 476 }) 477 .collect() 478 }); 479 UntypedExpr::Case { 480 location, 481 subjects, 482 clauses, 483 } 484 } 485 486 UntypedExpr::FieldAccess { 487 location, 488 label_location, 489 label, 490 container, 491 } => { 492 let container = Box::new(self.fold_expr(*container)); 493 UntypedExpr::FieldAccess { 494 location, 495 label_location, 496 label, 497 container, 498 } 499 } 500 501 UntypedExpr::Tuple { location, elems } => { 502 let elems = elems.into_iter().map(|e| self.fold_expr(e)).collect(); 503 UntypedExpr::Tuple { location, elems } 504 } 505 506 UntypedExpr::TupleIndex { 507 location, 508 index, 509 tuple, 510 } => { 511 let tuple = Box::new(self.fold_expr(*tuple)); 512 UntypedExpr::TupleIndex { 513 location, 514 index, 515 tuple, 516 } 517 } 518 519 UntypedExpr::BitArray { location, segments } => { 520 let segments = segments 521 .into_iter() 522 .map(|mut s| { 523 s.value = Box::new(self.fold_expr(*s.value)); 524 s 525 }) 526 .collect(); 527 UntypedExpr::BitArray { location, segments } 528 } 529 530 UntypedExpr::RecordUpdate { 531 location, 532 constructor, 533 record, 534 arguments, 535 } => { 536 let constructor = Box::new(self.fold_expr(*constructor)); 537 let arguments = arguments 538 .into_iter() 539 .map(|mut a| { 540 a.value = self.fold_expr(a.value); 541 a 542 }) 543 .collect(); 544 UntypedExpr::RecordUpdate { 545 location, 546 constructor, 547 record, 548 arguments, 549 } 550 } 551 } 552 } 553 554 /// You probably don't want to override this method. 555 fn fold_arg(&mut self, arg: UntypedArg) -> UntypedArg { 556 let UntypedArg { 557 location, 558 names, 559 annotation, 560 type_, 561 } = arg; 562 let annotation = annotation.map(|t| self.fold_type(t)); 563 UntypedArg { 564 location, 565 names, 566 annotation, 567 type_, 568 } 569 } 570 571 /// You probably don't want to override this method. 572 fn fold_statement(&mut self, s: UntypedStatement) -> UntypedStatement { 573 let s = self.update_statement(s); 574 self.walk_statement(s) 575 } 576 577 /// You probably don't want to override this method. 578 fn update_statement(&mut self, s: UntypedStatement) -> UntypedStatement { 579 match s { 580 Statement::Expression(e) => Statement::Expression(e), 581 Statement::Assignment(a) => Statement::Assignment(self.fold_assignment(a)), 582 Statement::Use(u) => Statement::Use(self.fold_use(u)), 583 } 584 } 585 586 /// You probably don't want to override this method. 587 fn walk_statement(&mut self, s: UntypedStatement) -> UntypedStatement { 588 match s { 589 Statement::Expression(e) => Statement::Expression(self.fold_expr(e)), 590 591 Statement::Assignment(Assignment { 592 location, 593 value, 594 pattern, 595 kind, 596 annotation, 597 }) => { 598 let pattern = self.fold_pattern(pattern); 599 let annotation = annotation.map(|t| self.fold_type(t)); 600 let value = Box::new(self.fold_expr(*value)); 601 Statement::Assignment(Assignment { 602 location, 603 value, 604 pattern, 605 kind, 606 annotation, 607 }) 608 } 609 610 Statement::Use(Use { 611 location, 612 right_hand_side_location, 613 assignments_location, 614 call, 615 assignments, 616 }) => { 617 let assignments = assignments 618 .into_iter() 619 .map(|a| { 620 let mut use_ = self.fold_use_assignment(a); 621 use_.pattern = self.fold_pattern(use_.pattern); 622 use_ 623 }) 624 .collect(); 625 let call = Box::new(self.fold_expr(*call)); 626 Statement::Use(Use { 627 location, 628 right_hand_side_location, 629 assignments_location, 630 call, 631 assignments, 632 }) 633 } 634 } 635 } 636 637 /// You probably don't want to override this method. 638 fn fold_use_assignment(&mut self, use_: UntypedUseAssignment) -> UntypedUseAssignment { 639 let UseAssignment { 640 location, 641 pattern, 642 annotation, 643 } = use_; 644 let annotation = annotation.map(|t| self.fold_type(t)); 645 UseAssignment { 646 location, 647 pattern, 648 annotation, 649 } 650 } 651 652 fn fold_int(&mut self, location: SrcSpan, value: EcoString, int_value: BigInt) -> UntypedExpr { 653 UntypedExpr::Int { 654 location, 655 value, 656 int_value, 657 } 658 } 659 660 fn fold_float(&mut self, location: SrcSpan, value: EcoString) -> UntypedExpr { 661 UntypedExpr::Float { location, value } 662 } 663 664 fn fold_string(&mut self, location: SrcSpan, value: EcoString) -> UntypedExpr { 665 UntypedExpr::String { location, value } 666 } 667 668 fn fold_block(&mut self, location: SrcSpan, statements: Vec1<UntypedStatement>) -> UntypedExpr { 669 UntypedExpr::Block { 670 location, 671 statements, 672 } 673 } 674 675 fn fold_var(&mut self, location: SrcSpan, name: EcoString) -> UntypedExpr { 676 UntypedExpr::Var { location, name } 677 } 678 679 fn fold_fn( 680 &mut self, 681 location: SrcSpan, 682 end_of_head_byte_index: u32, 683 kind: FunctionLiteralKind, 684 arguments: Vec<UntypedArg>, 685 body: Vec1<UntypedStatement>, 686 return_annotation: Option<TypeAst>, 687 ) -> UntypedExpr { 688 UntypedExpr::Fn { 689 location, 690 end_of_head_byte_index, 691 kind, 692 arguments, 693 body, 694 return_annotation, 695 } 696 } 697 698 fn fold_list( 699 &mut self, 700 location: SrcSpan, 701 elements: Vec<UntypedExpr>, 702 tail: Option<Box<UntypedExpr>>, 703 ) -> UntypedExpr { 704 UntypedExpr::List { 705 location, 706 elements, 707 tail, 708 } 709 } 710 711 fn fold_call( 712 &mut self, 713 location: SrcSpan, 714 fun: Box<UntypedExpr>, 715 arguments: Vec<CallArg<UntypedExpr>>, 716 ) -> UntypedExpr { 717 UntypedExpr::Call { 718 location, 719 fun, 720 arguments, 721 } 722 } 723 724 fn fold_bin_op( 725 &mut self, 726 location: SrcSpan, 727 name: BinOp, 728 left: Box<UntypedExpr>, 729 right: Box<UntypedExpr>, 730 ) -> UntypedExpr { 731 UntypedExpr::BinOp { 732 location, 733 name, 734 left, 735 right, 736 } 737 } 738 739 fn fold_pipe_line(&mut self, expressions: Vec1<UntypedExpr>) -> UntypedExpr { 740 UntypedExpr::PipeLine { expressions } 741 } 742 743 fn fold_case( 744 &mut self, 745 location: SrcSpan, 746 subjects: Vec<UntypedExpr>, 747 clauses: Option<Vec<UntypedClause>>, 748 ) -> UntypedExpr { 749 UntypedExpr::Case { 750 location, 751 subjects, 752 clauses, 753 } 754 } 755 756 fn fold_field_access( 757 &mut self, 758 location: SrcSpan, 759 label_location: SrcSpan, 760 label: EcoString, 761 container: Box<UntypedExpr>, 762 ) -> UntypedExpr { 763 UntypedExpr::FieldAccess { 764 location, 765 label_location, 766 label, 767 container, 768 } 769 } 770 771 fn fold_tuple(&mut self, location: SrcSpan, elems: Vec<UntypedExpr>) -> UntypedExpr { 772 UntypedExpr::Tuple { location, elems } 773 } 774 775 fn fold_tuple_index( 776 &mut self, 777 location: SrcSpan, 778 index: u64, 779 tuple: Box<UntypedExpr>, 780 ) -> UntypedExpr { 781 UntypedExpr::TupleIndex { 782 location, 783 index, 784 tuple, 785 } 786 } 787 788 fn fold_todo( 789 &mut self, 790 kind: TodoKind, 791 location: SrcSpan, 792 message: Option<Box<UntypedExpr>>, 793 ) -> UntypedExpr { 794 UntypedExpr::Todo { 795 kind, 796 location, 797 message, 798 } 799 } 800 801 fn fold_panic(&mut self, location: SrcSpan, message: Option<Box<UntypedExpr>>) -> UntypedExpr { 802 UntypedExpr::Panic { location, message } 803 } 804 805 fn fold_bit_array( 806 &mut self, 807 location: SrcSpan, 808 segments: Vec<UntypedExprBitArraySegment>, 809 ) -> UntypedExpr { 810 UntypedExpr::BitArray { location, segments } 811 } 812 813 fn fold_record_update( 814 &mut self, 815 location: SrcSpan, 816 constructor: Box<UntypedExpr>, 817 record: RecordBeingUpdated, 818 arguments: Vec<UntypedRecordUpdateArg>, 819 ) -> UntypedExpr { 820 UntypedExpr::RecordUpdate { 821 location, 822 constructor, 823 record, 824 arguments, 825 } 826 } 827 828 fn fold_negate_bool(&mut self, location: SrcSpan, value: Box<UntypedExpr>) -> UntypedExpr { 829 UntypedExpr::NegateBool { location, value } 830 } 831 832 fn fold_negate_int(&mut self, location: SrcSpan, value: Box<UntypedExpr>) -> UntypedExpr { 833 UntypedExpr::NegateInt { location, value } 834 } 835 836 fn fold_placeholder(&mut self, location: SrcSpan) -> UntypedExpr { 837 UntypedExpr::Placeholder { location } 838 } 839 840 fn fold_assignment(&mut self, assignment: UntypedAssignment) -> UntypedAssignment { 841 assignment 842 } 843 844 fn fold_use(&mut self, use_: UntypedUse) -> UntypedUse { 845 use_ 846 } 847} 848 849#[allow(dead_code)] 850pub trait UntypedConstantFolder { 851 /// You probably don't want to override this method. 852 fn fold_constant(&mut self, m: UntypedConstant) -> UntypedConstant { 853 let m = self.update_constant(m); 854 self.walk_constant(m) 855 } 856 857 /// You probably don't want to override this method. 858 fn update_constant(&mut self, m: UntypedConstant) -> UntypedConstant { 859 match m { 860 Constant::Int { 861 location, 862 value, 863 int_value, 864 } => self.fold_constant_int(location, value, int_value), 865 866 Constant::Float { location, value } => self.fold_constant_float(location, value), 867 868 Constant::String { location, value } => self.fold_constant_string(location, value), 869 870 Constant::Tuple { location, elements } => self.fold_constant_tuple(location, elements), 871 872 Constant::List { 873 location, 874 elements, 875 type_: (), 876 } => self.fold_constant_list(location, elements), 877 878 Constant::Record { 879 location, 880 module, 881 name, 882 args, 883 tag: (), 884 type_: (), 885 field_map: _, 886 } => self.fold_constant_record(location, module, name, args), 887 888 Constant::BitArray { location, segments } => { 889 self.fold_constant_bit_array(location, segments) 890 } 891 892 Constant::Var { 893 location, 894 module, 895 name, 896 constructor: _, 897 type_: (), 898 } => self.fold_constant_var(location, module, name), 899 900 Constant::StringConcatenation { 901 location, 902 left, 903 right, 904 } => self.fold_constant_string_concatenation(location, left, right), 905 906 Constant::Invalid { 907 location, 908 type_: (), 909 } => self.fold_constant_invalid(location), 910 } 911 } 912 913 fn fold_constant_int( 914 &mut self, 915 location: SrcSpan, 916 value: EcoString, 917 int_value: BigInt, 918 ) -> UntypedConstant { 919 Constant::Int { 920 location, 921 value, 922 int_value, 923 } 924 } 925 926 fn fold_constant_float(&mut self, location: SrcSpan, value: EcoString) -> UntypedConstant { 927 Constant::Float { location, value } 928 } 929 930 fn fold_constant_string(&mut self, location: SrcSpan, value: EcoString) -> UntypedConstant { 931 Constant::String { location, value } 932 } 933 934 fn fold_constant_tuple( 935 &mut self, 936 location: SrcSpan, 937 elements: Vec<UntypedConstant>, 938 ) -> UntypedConstant { 939 Constant::Tuple { location, elements } 940 } 941 942 fn fold_constant_list( 943 &mut self, 944 location: SrcSpan, 945 elements: Vec<UntypedConstant>, 946 ) -> UntypedConstant { 947 Constant::List { 948 location, 949 elements, 950 type_: (), 951 } 952 } 953 954 fn fold_constant_record( 955 &mut self, 956 location: SrcSpan, 957 module: Option<(EcoString, SrcSpan)>, 958 name: EcoString, 959 args: Vec<CallArg<UntypedConstant>>, 960 ) -> UntypedConstant { 961 Constant::Record { 962 location, 963 module, 964 name, 965 args, 966 tag: (), 967 type_: (), 968 field_map: None, 969 } 970 } 971 972 fn fold_constant_bit_array( 973 &mut self, 974 location: SrcSpan, 975 segments: Vec<UntypedConstantBitArraySegment>, 976 ) -> UntypedConstant { 977 Constant::BitArray { location, segments } 978 } 979 980 fn fold_constant_var( 981 &mut self, 982 location: SrcSpan, 983 module: Option<(EcoString, SrcSpan)>, 984 name: EcoString, 985 ) -> UntypedConstant { 986 Constant::Var { 987 location, 988 module, 989 name, 990 constructor: None, 991 type_: (), 992 } 993 } 994 995 fn fold_constant_string_concatenation( 996 &mut self, 997 location: SrcSpan, 998 left: Box<UntypedConstant>, 999 right: Box<UntypedConstant>, 1000 ) -> UntypedConstant { 1001 Constant::StringConcatenation { 1002 location, 1003 left, 1004 right, 1005 } 1006 } 1007 1008 fn fold_constant_invalid(&mut self, location: SrcSpan) -> UntypedConstant { 1009 Constant::Invalid { 1010 location, 1011 type_: (), 1012 } 1013 } 1014 1015 /// You probably don't want to override this method. 1016 fn walk_constant(&mut self, m: UntypedConstant) -> UntypedConstant { 1017 match m { 1018 Constant::Var { .. } 1019 | Constant::Int { .. } 1020 | Constant::Float { .. } 1021 | Constant::String { .. } 1022 | Constant::Tuple { .. } 1023 | Constant::Invalid { .. } => m, 1024 1025 Constant::List { 1026 location, 1027 elements, 1028 type_, 1029 } => { 1030 let elements = elements 1031 .into_iter() 1032 .map(|e| self.fold_constant(e)) 1033 .collect(); 1034 Constant::List { 1035 location, 1036 elements, 1037 type_, 1038 } 1039 } 1040 1041 Constant::Record { 1042 location, 1043 module, 1044 name, 1045 args, 1046 tag, 1047 type_, 1048 field_map, 1049 } => { 1050 let args = args 1051 .into_iter() 1052 .map(|mut a| { 1053 a.value = self.fold_constant(a.value); 1054 a 1055 }) 1056 .collect(); 1057 Constant::Record { 1058 location, 1059 module, 1060 name, 1061 args, 1062 tag, 1063 type_, 1064 field_map, 1065 } 1066 } 1067 1068 Constant::BitArray { location, segments } => { 1069 let segments = segments 1070 .into_iter() 1071 .map(|mut s| { 1072 s.value = Box::new(self.fold_constant(*s.value)); 1073 s 1074 }) 1075 .collect(); 1076 Constant::BitArray { location, segments } 1077 } 1078 1079 Constant::StringConcatenation { 1080 location, 1081 left, 1082 right, 1083 } => { 1084 let left = Box::new(self.fold_constant(*left)); 1085 let right = Box::new(self.fold_constant(*right)); 1086 Constant::StringConcatenation { 1087 location, 1088 left, 1089 right, 1090 } 1091 } 1092 } 1093 } 1094} 1095 1096#[allow(dead_code)] 1097pub trait PatternFolder { 1098 /// You probably don't want to override this method. 1099 fn fold_pattern(&mut self, m: UntypedPattern) -> UntypedPattern { 1100 let m = self.update_pattern(m); 1101 self.walk_pattern(m) 1102 } 1103 1104 /// You probably don't want to override this method. 1105 fn update_pattern(&mut self, m: UntypedPattern) -> UntypedPattern { 1106 match m { 1107 Pattern::Int { 1108 location, 1109 value, 1110 int_value, 1111 } => self.fold_pattern_int(location, value, int_value), 1112 1113 Pattern::Float { location, value } => self.fold_pattern_float(location, value), 1114 1115 Pattern::String { location, value } => self.fold_pattern_string(location, value), 1116 1117 Pattern::Variable { 1118 location, 1119 name, 1120 type_: (), 1121 origin, 1122 } => self.fold_pattern_var(location, name, origin), 1123 1124 Pattern::VarUsage { 1125 location, 1126 name, 1127 constructor: _, 1128 type_: (), 1129 } => self.fold_pattern_var_usage(location, name), 1130 1131 Pattern::Assign { 1132 name, 1133 location, 1134 pattern, 1135 } => self.fold_pattern_assign(name, location, pattern), 1136 1137 Pattern::Discard { 1138 name, 1139 location, 1140 type_: (), 1141 } => self.fold_pattern_discard(name, location), 1142 1143 Pattern::List { 1144 location, 1145 elements, 1146 tail, 1147 type_: (), 1148 } => self.fold_pattern_list(location, elements, tail), 1149 1150 Pattern::Constructor { 1151 location, 1152 name, 1153 arguments, 1154 module, 1155 spread, 1156 constructor: _, 1157 type_: (), 1158 } => self.fold_pattern_constructor(location, name, arguments, module, spread), 1159 1160 Pattern::Tuple { location, elems } => self.fold_pattern_tuple(location, elems), 1161 1162 Pattern::BitArray { location, segments } => { 1163 self.fold_pattern_bit_array(location, segments) 1164 } 1165 1166 Pattern::StringPrefix { 1167 location, 1168 left_location, 1169 left_side_assignment, 1170 right_location, 1171 left_side_string, 1172 right_side_assignment, 1173 } => self.fold_pattern_string_prefix( 1174 location, 1175 left_location, 1176 left_side_assignment, 1177 right_location, 1178 left_side_string, 1179 right_side_assignment, 1180 ), 1181 1182 Pattern::Invalid { location, .. } => self.fold_pattern_invalid(location), 1183 } 1184 } 1185 1186 fn fold_pattern_int( 1187 &mut self, 1188 location: SrcSpan, 1189 value: EcoString, 1190 int_value: BigInt, 1191 ) -> UntypedPattern { 1192 Pattern::Int { 1193 location, 1194 value, 1195 int_value, 1196 } 1197 } 1198 1199 fn fold_pattern_float(&mut self, location: SrcSpan, value: EcoString) -> UntypedPattern { 1200 Pattern::Float { location, value } 1201 } 1202 1203 fn fold_pattern_string(&mut self, location: SrcSpan, value: EcoString) -> UntypedPattern { 1204 Pattern::String { location, value } 1205 } 1206 1207 fn fold_pattern_var( 1208 &mut self, 1209 location: SrcSpan, 1210 name: EcoString, 1211 origin: VariableOrigin, 1212 ) -> UntypedPattern { 1213 Pattern::Variable { 1214 location, 1215 name, 1216 type_: (), 1217 origin, 1218 } 1219 } 1220 1221 fn fold_pattern_var_usage(&mut self, location: SrcSpan, name: EcoString) -> UntypedPattern { 1222 Pattern::VarUsage { 1223 location, 1224 name, 1225 constructor: None, 1226 type_: (), 1227 } 1228 } 1229 1230 fn fold_pattern_assign( 1231 &mut self, 1232 name: EcoString, 1233 location: SrcSpan, 1234 pattern: Box<UntypedPattern>, 1235 ) -> UntypedPattern { 1236 Pattern::Assign { 1237 name, 1238 location, 1239 pattern, 1240 } 1241 } 1242 1243 fn fold_pattern_discard(&mut self, name: EcoString, location: SrcSpan) -> UntypedPattern { 1244 Pattern::Discard { 1245 name, 1246 location, 1247 type_: (), 1248 } 1249 } 1250 1251 fn fold_pattern_list( 1252 &mut self, 1253 location: SrcSpan, 1254 elements: Vec<UntypedPattern>, 1255 tail: Option<Box<UntypedPattern>>, 1256 ) -> UntypedPattern { 1257 Pattern::List { 1258 location, 1259 elements, 1260 tail, 1261 type_: (), 1262 } 1263 } 1264 1265 fn fold_pattern_constructor( 1266 &mut self, 1267 location: SrcSpan, 1268 name: EcoString, 1269 arguments: Vec<CallArg<UntypedPattern>>, 1270 module: Option<(EcoString, SrcSpan)>, 1271 spread: Option<SrcSpan>, 1272 ) -> UntypedPattern { 1273 Pattern::Constructor { 1274 location, 1275 name, 1276 arguments, 1277 module, 1278 constructor: Inferred::Unknown, 1279 spread, 1280 type_: (), 1281 } 1282 } 1283 1284 fn fold_pattern_tuple( 1285 &mut self, 1286 location: SrcSpan, 1287 elems: Vec<UntypedPattern>, 1288 ) -> UntypedPattern { 1289 Pattern::Tuple { location, elems } 1290 } 1291 1292 fn fold_pattern_bit_array( 1293 &mut self, 1294 location: SrcSpan, 1295 segments: Vec<UntypedPatternBitArraySegment>, 1296 ) -> UntypedPattern { 1297 Pattern::BitArray { location, segments } 1298 } 1299 1300 fn fold_pattern_string_prefix( 1301 &mut self, 1302 location: SrcSpan, 1303 left_location: SrcSpan, 1304 left_side_assignment: Option<(EcoString, SrcSpan)>, 1305 right_location: SrcSpan, 1306 left_side_string: EcoString, 1307 right_side_assignment: AssignName, 1308 ) -> UntypedPattern { 1309 Pattern::StringPrefix { 1310 location, 1311 left_location, 1312 left_side_assignment, 1313 right_location, 1314 left_side_string, 1315 right_side_assignment, 1316 } 1317 } 1318 1319 fn fold_pattern_invalid(&mut self, location: SrcSpan) -> UntypedPattern { 1320 Pattern::Invalid { 1321 location, 1322 type_: (), 1323 } 1324 } 1325 1326 /// You probably don't want to override this method. 1327 fn walk_pattern(&mut self, m: UntypedPattern) -> UntypedPattern { 1328 match m { 1329 Pattern::Int { .. } 1330 | Pattern::Variable { .. } 1331 | Pattern::Float { .. } 1332 | Pattern::String { .. } 1333 | Pattern::Discard { .. } 1334 | Pattern::VarUsage { .. } 1335 | Pattern::StringPrefix { .. } 1336 | Pattern::Invalid { .. } => m, 1337 1338 Pattern::Assign { 1339 name, 1340 location, 1341 pattern, 1342 } => { 1343 let pattern = Box::new(self.fold_pattern(*pattern)); 1344 Pattern::Assign { 1345 name, 1346 location, 1347 pattern, 1348 } 1349 } 1350 1351 Pattern::List { 1352 location, 1353 elements, 1354 tail, 1355 type_, 1356 } => { 1357 let elements = elements.into_iter().map(|p| self.fold_pattern(p)).collect(); 1358 let tail = tail.map(|p| Box::new(self.fold_pattern(*p))); 1359 Pattern::List { 1360 location, 1361 elements, 1362 tail, 1363 type_, 1364 } 1365 } 1366 1367 Pattern::Constructor { 1368 location, 1369 name, 1370 arguments, 1371 module, 1372 constructor, 1373 spread, 1374 type_, 1375 } => { 1376 let arguments = arguments 1377 .into_iter() 1378 .map(|mut a| { 1379 a.value = self.fold_pattern(a.value); 1380 a 1381 }) 1382 .collect(); 1383 Pattern::Constructor { 1384 location, 1385 name, 1386 arguments, 1387 module, 1388 constructor, 1389 spread, 1390 type_, 1391 } 1392 } 1393 1394 Pattern::Tuple { location, elems } => { 1395 let elems = elems.into_iter().map(|p| self.fold_pattern(p)).collect(); 1396 Pattern::Tuple { location, elems } 1397 } 1398 1399 Pattern::BitArray { location, segments } => { 1400 let segments = segments 1401 .into_iter() 1402 .map(|mut s| { 1403 s.value = Box::new(self.fold_pattern(*s.value)); 1404 s 1405 }) 1406 .collect(); 1407 Pattern::BitArray { location, segments } 1408 } 1409 } 1410 } 1411}