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

Configure Feed

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

better name for the erlang source builder

author
Giacomo Cavalieri
committer
Louis Pilfold
date (Jul 14, 2026, 12:57 PM +0100) commit 9b99d017 parent 2bc8e971 change-id pvylztok
+1361 -1343
+2 -2
Cargo.lock
··· 864 864 checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 865 865 866 866 [[package]] 867 - name = "erlang-abstract-format" 867 + name = "erlang-generation" 868 868 version = "1.0.0" 869 869 dependencies = [ 870 870 "ecow", ··· 1245 1245 "debug-ignore", 1246 1246 "dirs-next", 1247 1247 "ecow", 1248 - "erlang-abstract-format", 1248 + "erlang-generation", 1249 1249 "flate2", 1250 1250 "futures", 1251 1251 "gen-lsp-types",
+1 -2
Cargo.toml
··· 18 18 "pretty-arena", 19 19 "format", 20 20 "erlang-term-format", 21 - "erlang-abstract-format", 21 + "erlang-generation", 22 22 ] 23 23 24 24 # common dependencies ··· 88 88 unicode-segmentation = "1.13.2" 89 89 # Checksums 90 90 xxhash-rust = { version = "0", features = ["xxh3"] } 91 -
+1 -1
compiler-core/Cargo.toml
··· 60 60 futures.workspace = true 61 61 hexpm = { path = "../hexpm" } 62 62 pretty-arena = { path = "../pretty-arena" } 63 - erlang-abstract-format = { path = "../erlang-abstract-format" } 63 + erlang-generation = { path = "../erlang-generation" } 64 64 http.workspace = true 65 65 im.workspace = true 66 66 itertools.workspace = true
+777 -778
compiler-core/src/erlang.rs
··· 19 19 }; 20 20 use camino::Utf8Path; 21 21 use ecow::{EcoString, eco_format}; 22 - use erlang_abstract_format::{BitArraySegmentSpecifier, Eaf, ErlangModuleName, PrettyEaf}; 22 + use erlang_generation::{ 23 + BitArraySegmentSpecifier, ErlangBuilder, ErlangModuleName, ErlangSourceBuilder, 24 + }; 23 25 use itertools::Itertools; 24 26 use num_bigint::BigInt; 25 27 use num_traits::Signed; ··· 32 34 #[must_use] 33 35 struct RuntimeError { 34 36 /// This is the map that is going to be thrown by the `erlang:error` call. 35 - error_map: erlang_abstract_format::Map, 37 + error_map: erlang_generation::Map, 36 38 /// This is the call to `erlang:error` that will throw the error, with the 37 39 /// map as an argument. 38 - erlang_error_call: erlang_abstract_format::Call, 40 + erlang_error_call: erlang_generation::Call, 39 41 } 40 42 41 43 /// Represents all the different kind of runtime errors that Gleam can raise. ··· 211 213 } 212 214 } 213 215 214 - fn module_document<Output>(&mut self, eaf: &mut impl Eaf<Output>) { 216 + fn module_document<Output>(&mut self, builder: &mut impl ErlangBuilder<Output>) { 215 217 // We need to know which private functions are referenced in importable 216 218 // constants so that we can export them anyway in the generated Erlang. 217 219 // This is because otherwise when the constant is used in another module it ··· 221 223 222 224 // We add a `-compile` attribute at the top of each module to instruct 223 225 // the Erlang compiler. 224 - eaf.compile_attribute([ 226 + builder.compile_attribute([ 225 227 "no_auto_import", 226 228 "nowarn_ignored", 227 229 "nowarn_unused_vars", ··· 232 234 233 235 // We then need to add an `-export` attribute for all the module's 234 236 // public functions. 235 - eaf.export_attribute( 237 + builder.export_attribute( 236 238 (self.module.definitions.functions.iter()) 237 239 .filter_map(|function| function_export(function, &overridden_publicity)), 238 240 ); 239 241 // We do the same but with types. 240 - eaf.export_type_attribute(self.module.definitions.custom_types.iter().map(type_export)); 242 + builder.export_type_attribute(self.module.definitions.custom_types.iter().map(type_export)); 241 243 242 244 // We also add a `-module_doc` comment at the beginning of the module 243 245 // with its documentation. 244 - self.module_documentation(eaf); 246 + self.module_documentation(builder); 245 247 246 248 // Then we generate `-type` definitions for the module's types. 247 249 for custom_type in &self.module.definitions.custom_types { 248 - self.type_definition(eaf, custom_type); 250 + self.type_definition(builder, custom_type); 249 251 } 250 252 251 253 // And finally generate all the functions that the module defined. 252 254 for function in &self.module.definitions.functions { 253 - FunctionGenerator::new(function, self).module_function(eaf, function); 255 + FunctionGenerator::new(function, self).module_function(builder, function); 254 256 } 255 257 } 256 258 257 - fn module_documentation<Output>(&mut self, eaf: &mut impl Eaf<Output>) { 259 + fn module_documentation<Output>(&mut self, builder: &mut impl ErlangBuilder<Output>) { 258 260 if self.module.type_info.is_internal { 259 261 // The module is internal so we need to add a `-moduledoc(false).` 260 262 // attribute to make sure its documentation is hidden. 261 - let doc = eaf.start_moduledoc_attribute(); 262 - eaf.atom("false"); 263 - eaf.end_doc_attribute(doc); 263 + let doc = builder.start_moduledoc_attribute(); 264 + builder.atom("false"); 265 + builder.end_doc_attribute(doc); 264 266 } else if self.module.documentation.is_empty() { 265 267 // The module is not internal, but it has no docs. 266 268 // We don't have to do anything. 267 269 } else { 268 270 // The module has some documentation that we're going to include 269 271 // with a `-moduledoc` attribute. 270 - let doc = eaf.start_moduledoc_attribute(); 272 + let doc = builder.start_moduledoc_attribute(); 271 273 let documentation = &self.module.documentation.iter().join("\n"); 272 - eaf.string(documentation); 273 - eaf.end_doc_attribute(doc); 274 + builder.string(documentation); 275 + builder.end_doc_attribute(doc); 274 276 }; 275 277 } 276 278 277 - fn type_definition<Output>(&self, eaf: &mut impl Eaf<Output>, custom_type: &TypedCustomType) { 279 + fn type_definition<Output>( 280 + &self, 281 + builder: &mut impl ErlangBuilder<Output>, 282 + custom_type: &TypedCustomType, 283 + ) { 278 284 let TypedCustomType { 279 285 name, 280 286 constructors, ··· 287 293 let name = erl_safe_type_name(to_snake_case(name)); 288 294 289 295 // We start the type spec. 290 - eaf.type_spec( 296 + builder.type_spec( 291 297 *opaque, 292 298 &name, 293 299 typed_parameters ··· 307 313 // it corresponds to in Erlang. 308 314 // In that case all type variables are phantom type variables! 309 315 ([], _) if let Some((module, type_name, _)) = external_erlang => { 310 - let type_ = eaf.start_remote_named_type(ErlangModuleName::new(&module), type_name); 316 + let type_ = 317 + builder.start_remote_named_type(ErlangModuleName::new(&module), type_name); 311 318 for type_variable in phantom_type_variables { 312 - eaf.type_variable(&type_variable); 319 + builder.type_variable(&type_variable); 313 320 } 314 - eaf.end_named_type(type_); 321 + builder.end_named_type(type_); 315 322 } 316 323 // This is an external type with no external annotation and no 317 324 // phantom type variables. It is just `any()`. 318 325 ([], false) => { 319 - let any = eaf.start_named_type("any"); 320 - eaf.end_named_type(any); 326 + let any = builder.start_named_type("any"); 327 + builder.end_named_type(any); 321 328 } 322 329 // This is an external type with no external annotation and some 323 330 // phantom type variables, we need to add an alternative to use 324 331 // them: `any() | {gleam_phantom, A, B, ...}` 325 332 ([], true) => { 326 - let union = eaf.start_union_type(); 327 - let any = eaf.start_named_type("any"); 328 - eaf.end_named_type(any); 329 - self.phantom_type(eaf, phantom_type_variables); 330 - eaf.end_union_type(union); 333 + let union = builder.start_union_type(); 334 + let any = builder.start_named_type("any"); 335 + builder.end_named_type(any); 336 + self.phantom_type(builder, phantom_type_variables); 337 + builder.end_union_type(union); 331 338 } 332 339 // This is an external type with a single constructor, no need to 333 340 // make it a union. 334 - ([constructor], false) => self.constructor_type(eaf, constructor), 341 + ([constructor], false) => self.constructor_type(builder, constructor), 335 342 // This is an external type with multiple constructors, we have to 336 343 // turn it into a union! 337 344 (constructors, has_phantom_type_variables) => { 338 - let union = eaf.start_union_type(); 345 + let union = builder.start_union_type(); 339 346 for constructor in constructors { 340 - self.constructor_type(eaf, constructor); 347 + self.constructor_type(builder, constructor); 341 348 } 342 349 if has_phantom_type_variables { 343 - self.phantom_type(eaf, phantom_type_variables); 350 + self.phantom_type(builder, phantom_type_variables); 344 351 } 345 - eaf.end_union_type(union); 352 + builder.end_union_type(union); 346 353 } 347 354 } 348 355 } ··· 361 368 /// 362 369 fn constructor_type<Output>( 363 370 &self, 364 - eaf: &mut impl Eaf<Output>, 371 + builder: &mut impl ErlangBuilder<Output>, 365 372 constructor: &RecordConstructor<Arc<Type>>, 366 373 ) { 367 374 let constructor_atom = to_snake_case(&constructor.name); 368 375 if constructor.arguments.is_empty() { 369 376 // A constructor with no fields becomes a regular atom on the Erlang 370 377 // target. 371 - eaf.literal_atom_type(&constructor_atom); 378 + builder.literal_atom_type(&constructor_atom); 372 379 } else { 373 380 // Othwerwise, it is a tuple tagged with the atom with the 374 381 // constructor name. 375 382 let generator = TypeGenerator::new(&self.module.name); 376 - let tuple = eaf.start_tuple_type(); 377 - eaf.literal_atom_type(&constructor_atom); 383 + let tuple = builder.start_tuple_type(); 384 + builder.literal_atom_type(&constructor_atom); 378 385 for argument in &constructor.arguments { 379 - generator.type_(eaf, &argument.type_); 386 + generator.type_(builder, &argument.type_); 380 387 } 381 - eaf.end_tuple_type(tuple); 388 + builder.end_tuple_type(tuple); 382 389 } 383 390 } 384 391 ··· 406 413 /// 407 414 fn phantom_type<Output>( 408 415 &self, 409 - eaf: &mut impl Eaf<Output>, 416 + builder: &mut impl ErlangBuilder<Output>, 410 417 phantom_type_variables: Vec<EcoString>, 411 418 ) { 412 - let phantom_tuple = eaf.start_tuple_type(); 413 - eaf.literal_atom_type("gleam_phantom"); 419 + let phantom_tuple = builder.start_tuple_type(); 420 + builder.literal_atom_type("gleam_phantom"); 414 421 for phantom_type_variable in phantom_type_variables { 415 - eaf.type_variable(&phantom_type_variable); 422 + builder.type_variable(&phantom_type_variable); 416 423 } 417 - eaf.end_tuple_type(phantom_tuple); 424 + builder.end_tuple_type(phantom_tuple); 418 425 } 419 426 } 420 427 ··· 569 576 /// if there's no code to be generated at all! 570 577 /// For example if the function is unused, or if the function is a private 571 578 /// Erlang external (in which case, it would be inlined instead). 572 - fn module_function<Output>(&mut self, eaf: &mut impl Eaf<Output>, function: &'a TypedFunction) { 579 + fn module_function<Output>( 580 + &mut self, 581 + builder: &mut impl ErlangBuilder<Output>, 582 + function: &'a TypedFunction, 583 + ) { 573 584 // We don't generate any code for unused functions. 574 585 if self 575 586 .module_generator ··· 595 606 let function_name = EcoString::from(escape_erlang_existing_name(self.function_name)); 596 607 597 608 // Then we add the function's documentation and type annotation. 598 - eaf.file_attribute( 609 + builder.file_attribute( 599 610 &self.module_generator.module_source_path, 600 611 self.module_generator 601 612 .line_numbers 602 613 .line_number(function.location.start), 603 614 ); 604 - self.function_spec_attribute(eaf, &function_name, function); 605 - self.function_doc_attribute(eaf, function); 615 + self.function_spec_attribute(builder, &function_name, function); 616 + self.function_doc_attribute(builder, function); 606 617 607 618 // Finally we start generating code for the function itself, how we do 608 619 // it depends if the function is external or not. ··· 612 623 // its statements. 613 624 None => { 614 625 let arguments = self.function_arguments_names(&function.arguments, false); 615 - let open_function = eaf.start_function(&function_name, arity, arguments); 616 - self.statement_sequence(eaf, &function.body); 617 - eaf.end_function(open_function); 626 + let open_function = builder.start_function(&function_name, arity, arguments); 627 + self.statement_sequence(builder, &function.body); 628 + builder.end_function(open_function); 618 629 } 619 630 620 631 // An external function consists of just a remote call being ··· 623 634 let arguments = self 624 635 .function_arguments_names(&function.arguments, true) 625 636 .collect_vec(); 626 - let open_function = eaf.start_function(&function_name, arity, arguments.clone()); 627 - let call = 628 - eaf.start_remote_call(ErlangModuleName::new(&module), external_function_name); 637 + let open_function = 638 + builder.start_function(&function_name, arity, arguments.clone()); 639 + let call = builder 640 + .start_remote_call(ErlangModuleName::new(&module), external_function_name); 629 641 for argument in arguments { 630 - eaf.variable(&argument); 642 + builder.variable(&argument); 631 643 } 632 - eaf.end_call(call); 633 - eaf.end_function(open_function); 644 + builder.end_call(call); 645 + builder.end_function(open_function); 634 646 } 635 647 } 636 648 } ··· 639 651 /// 640 652 fn function_spec_attribute<Output>( 641 653 &mut self, 642 - eaf: &mut impl Eaf<Output>, 654 + builder: &mut impl ErlangBuilder<Output>, 643 655 function_name: &EcoString, 644 656 function: &'a Function<Arc<Type>, TypedExpr>, 645 657 ) { ··· 657 669 let generator = TypeGenerator::new(module_name).with_var_usages(var_usages); 658 670 659 671 // We can then start generating the function spec. 660 - let spec = eaf.start_function_spec(function_name, function.arguments.len()); 661 - let function_type = eaf.start_function_type(); 672 + let spec = builder.start_function_spec(function_name, function.arguments.len()); 673 + let function_type = builder.start_function_type(); 662 674 for argument in &function.arguments { 663 - generator.type_(eaf, &argument.type_) 675 + generator.type_(builder, &argument.type_) 664 676 } 665 - let function_type = eaf.end_function_type_arguments(function_type); 666 - generator.type_(eaf, &function.return_type); 667 - eaf.end_function_type(function_type); 668 - eaf.end_function_spec(spec); 677 + let function_type = builder.end_function_type_arguments(function_type); 678 + generator.type_(builder, &function.return_type); 679 + builder.end_function_type(function_type); 680 + builder.end_function_spec(spec); 669 681 } 670 682 671 - fn function_doc_attribute<Output>(&self, eaf: &mut impl Eaf<Output>, function: &TypedFunction) { 683 + fn function_doc_attribute<Output>( 684 + &self, 685 + builder: &mut impl ErlangBuilder<Output>, 686 + function: &TypedFunction, 687 + ) { 672 688 // If a function is marked as internal or comes from an internal module 673 689 // we want to hide its documentation in the Erlang shell! 674 690 // So the doc directive will look like this: `-doc(false).` ··· 676 692 self.module_generator.module.type_info.is_internal || function.publicity.is_internal(); 677 693 678 694 if is_internal { 679 - let attribute = eaf.start_doc_attribute(); 680 - eaf.atom("false"); 681 - eaf.end_doc_attribute(attribute); 695 + let attribute = builder.start_doc_attribute(); 696 + builder.atom("false"); 697 + builder.end_doc_attribute(attribute); 682 698 } else if let Some((_, documentation)) = &function.documentation 683 699 && !documentation.is_empty() 684 700 { 685 - let attribute = eaf.start_doc_attribute(); 686 - eaf.string(documentation); 687 - eaf.end_doc_attribute(attribute); 701 + let attribute = builder.start_doc_attribute(); 702 + builder.string(documentation); 703 + builder.end_doc_attribute(attribute); 688 704 } 689 705 } 690 706 ··· 742 758 743 759 fn statement_sequence<Output>( 744 760 &mut self, 745 - eaf: &mut impl Eaf<Output>, 761 + builder: &mut impl ErlangBuilder<Output>, 746 762 statements: &'a [TypedStatement], 747 763 ) { 748 764 // We go over each statement one by one and produce the code they need. 749 765 for i in 0..statements.len() { 750 766 match statements.get(i).expect("statement in range") { 751 - Statement::Expression(expression) => self.expr(eaf, expression), 752 - Statement::Use(use_) => self.expr(eaf, &use_.call), 753 - Statement::Assert(assert) => self.assert(eaf, assert), 767 + Statement::Expression(expression) => self.expr(builder, expression), 768 + Statement::Use(use_) => self.expr(builder, &use_.call), 769 + Statement::Assert(assert) => self.assert(builder, assert), 754 770 Statement::Assignment(assignment) => match &assignment.kind { 755 771 AssignmentKind::Let | AssignmentKind::Generated => { 756 - self.let_(eaf, &assignment.value, &assignment.pattern) 772 + self.let_(builder, &assignment.value, &assignment.pattern) 757 773 } 758 774 // Let asserts are slightly different from everything else: 759 775 // A let assert is compiled to a case expression where we ··· 783 799 message, location, .. 784 800 } => { 785 801 return self.let_assert( 786 - eaf, 802 + builder, 787 803 &assignment.value, 788 804 &assignment.pattern, 789 805 message.as_ref(), ··· 796 812 } 797 813 } 798 814 799 - fn expr<Output>(&mut self, eaf: &mut impl Eaf<Output>, expression: &'a TypedExpr) { 815 + fn expr<Output>( 816 + &mut self, 817 + builder: &mut impl ErlangBuilder<Output>, 818 + expression: &'a TypedExpr, 819 + ) { 800 820 match expression { 801 821 // 802 822 // Simple scalar values, and blocks. 803 823 // 804 - TypedExpr::Int { int_value, .. } => eaf.int(int_value.clone()), 805 - TypedExpr::Float { float_value, .. } => eaf.float(float_value.value()), 806 - TypedExpr::String { value, .. } => eaf.string(value), 824 + TypedExpr::Int { int_value, .. } => builder.int(int_value.clone()), 825 + TypedExpr::Float { float_value, .. } => builder.float(float_value.value()), 826 + TypedExpr::String { value, .. } => builder.string(value), 807 827 TypedExpr::Var { 808 828 name, constructor, .. 809 - } => self.var(eaf, name, constructor), 829 + } => self.var(builder, name, constructor), 810 830 TypedExpr::Block { statements, .. } => { 811 831 // If the block has a single expression we don't bother wrapping 812 832 // it in an additional `begin ... end` block. ··· 814 834 if statements.len() == 1 815 835 && let Statement::Expression(expression) = statements.first() 816 836 { 817 - self.maybe_block_expr(eaf, expression); 837 + self.maybe_block_expr(builder, expression); 818 838 } else { 819 - let block = eaf.start_block(); 820 - self.statement_sequence(eaf, statements); 821 - eaf.end_block(block) 839 + let block = builder.start_block(); 840 + self.statement_sequence(builder, statements); 841 + builder.end_block(block) 822 842 } 823 843 } 824 844 ··· 826 846 // Operators. 827 847 // 828 848 TypedExpr::NegateBool { value, .. } => { 829 - eaf.unary_operator("not"); 830 - self.maybe_block_expr(eaf, value) 849 + builder.unary_operator("not"); 850 + self.maybe_block_expr(builder, value) 831 851 } 832 852 TypedExpr::NegateInt { value, .. } => { 833 - eaf.unary_operator("-"); 834 - self.maybe_block_expr(eaf, value) 853 + builder.unary_operator("-"); 854 + self.maybe_block_expr(builder, value) 835 855 } 836 856 TypedExpr::BinOp { 837 857 operator, 838 858 left, 839 859 right, 840 860 .. 841 - } => self.bin_op(eaf, operator, left, right), 861 + } => self.bin_op(builder, operator, left, right), 842 862 843 863 // 844 864 // BitArrays, Lists, and Tuples. 845 865 // 846 866 TypedExpr::BitArray { segments, .. } => { 847 - let bit_array = eaf.start_bit_array(); 867 + let bit_array = builder.start_bit_array(); 848 868 for segment in segments { 849 - self.bit_array_expression_segment(eaf, segment); 869 + self.bit_array_expression_segment(builder, segment); 850 870 } 851 - eaf.end_bit_array(bit_array); 871 + builder.end_bit_array(bit_array); 852 872 } 853 873 TypedExpr::List { elements, tail, .. } => { 854 874 // We generate all the items of the list as cons cells. 855 875 for element in elements { 856 - eaf.cons_list(); 857 - self.maybe_block_expr(eaf, element); 876 + builder.cons_list(); 877 + self.maybe_block_expr(builder, element); 858 878 } 859 879 // Finally we close the list with the tail, or an empty list 860 880 // (so that we're sure we're building proper Erlang lists). 861 881 if let Some(tail) = tail { 862 - self.maybe_block_expr(eaf, tail); 882 + self.maybe_block_expr(builder, tail); 863 883 } else { 864 - eaf.empty_list(); 884 + builder.empty_list(); 865 885 } 866 886 } 867 887 TypedExpr::Tuple { elements, .. } => { 868 - let tuple = eaf.start_tuple(); 888 + let tuple = builder.start_tuple(); 869 889 for element in elements { 870 - self.maybe_block_expr(eaf, element); 890 + self.maybe_block_expr(builder, element); 871 891 } 872 - eaf.end_tuple(tuple) 892 + builder.end_tuple(tuple) 873 893 } 874 894 875 895 // 876 896 // Accessing data inside tuples, and records. 877 897 // They're all tuple accesses at the end of the day! 878 898 // 879 - TypedExpr::TupleIndex { tuple, index, .. } => self.tuple_index(eaf, tuple, *index), 899 + TypedExpr::TupleIndex { tuple, index, .. } => self.tuple_index(builder, tuple, *index), 880 900 TypedExpr::RecordAccess { record, index, .. } 881 901 | TypedExpr::PositionalAccess { record, index, .. } => { 882 - self.tuple_index(eaf, record, index + 1) 902 + self.tuple_index(builder, record, index + 1) 883 903 } 884 904 885 905 // ··· 888 908 TypedExpr::ModuleSelect { 889 909 constructor: ModuleValueConstructor::Record { name, arity: 0, .. }, 890 910 .. 891 - } => eaf.atom(&to_snake_case(name)), 911 + } => builder.atom(&to_snake_case(name)), 892 912 TypedExpr::RecordUpdate { 893 913 updated_record_assigned_name, 894 914 updated_record, ··· 899 919 // If the record value itself needs to be bound to a variable 900 920 // before the update, we define it. 901 921 if let Some(name) = updated_record_assigned_name.as_ref() { 902 - eaf.match_operator(); 903 - eaf.variable_pattern( 922 + builder.match_operator(); 923 + builder.variable_pattern( 904 924 &self.new_erlang_variable(name, updated_record.location()), 905 925 ); 906 - self.maybe_block_expr(eaf, updated_record); 926 + self.maybe_block_expr(builder, updated_record); 907 927 } 908 928 // Then a record update is simply a call! 909 - self.call(eaf, constructor, arguments) 929 + self.call(builder, constructor, arguments) 910 930 } 911 931 912 932 // ··· 917 937 } => { 918 938 let outer_scope = self.taken_names.clone(); 919 939 let argument_names = self.function_arguments_names(arguments, false); 920 - let function = eaf.start_anonymous_function(argument_names); 921 - self.statement_sequence(eaf, body); 922 - eaf.end_function(function); 940 + let function = builder.start_anonymous_function(argument_names); 941 + self.statement_sequence(builder, body); 942 + builder.end_function(function); 923 943 self.taken_names = outer_scope; 924 944 } 925 945 TypedExpr::ModuleSelect { 926 946 constructor: ModuleValueConstructor::Record { name, arity, .. }, 927 947 .. 928 - } => self.record_builder_anonymous_function(eaf, name, *arity as usize), 948 + } => self.record_builder_anonymous_function(builder, name, *arity as usize), 929 949 TypedExpr::ModuleSelect { 930 950 type_, 931 951 constructor: ··· 936 956 | ModuleValueConstructor::Fn { module, name, .. }, 937 957 .. 938 958 } => match type_::collapse_links(type_.clone()).as_ref() { 939 - Type::Fn { arguments, .. } => eaf.function_reference( 959 + Type::Fn { arguments, .. } => builder.function_reference( 940 960 Some(ErlangModuleName::new(&module)), 941 961 escape_erlang_existing_name(name), 942 962 arguments.len(), ··· 944 964 945 965 Type::Named { .. } | Type::Var { .. } | Type::Tuple { .. } => { 946 966 let name = escape_erlang_existing_name(name); 947 - let call = eaf.start_remote_call(ErlangModuleName::new(&module), name); 948 - eaf.end_call(call); 967 + let call = builder.start_remote_call(ErlangModuleName::new(&module), name); 968 + builder.end_call(call); 949 969 } 950 970 }, 951 971 952 972 // 953 973 // Calling functions. 954 974 // 955 - TypedExpr::Call { fun, arguments, .. } => self.call(eaf, fun, arguments), 975 + TypedExpr::Call { fun, arguments, .. } => self.call(builder, fun, arguments), 956 976 TypedExpr::Pipeline { 957 977 first_value, 958 978 assignments, 959 979 finally, 960 980 .. 961 - } => self.pipeline(eaf, first_value, assignments, finally), 981 + } => self.pipeline(builder, first_value, assignments, finally), 962 982 963 983 // 964 984 // Todo, panic, and echo. ··· 967 987 message, location, .. 968 988 } => { 969 989 let error = self.start_runtime_error( 970 - eaf, 990 + builder, 971 991 RuntimeErrorKind::Todo, 972 992 *location, 973 993 message.as_deref(), 974 994 ); 975 - self.end_runtime_error(eaf, error); 995 + self.end_runtime_error(builder, error); 976 996 } 977 997 TypedExpr::Panic { 978 998 location, message, .. 979 999 } => { 980 1000 let error = self.start_runtime_error( 981 - eaf, 1001 + builder, 982 1002 RuntimeErrorKind::Panic, 983 1003 *location, 984 1004 message.as_deref(), 985 1005 ); 986 - self.end_runtime_error(eaf, error); 1006 + self.end_runtime_error(builder, error); 987 1007 } 988 1008 TypedExpr::Echo { 989 1009 expression, ··· 991 1011 message, 992 1012 .. 993 1013 } => self.echo( 994 - eaf, 1014 + builder, 995 1015 *location, 996 1016 message.as_deref(), 997 1017 EchoPrintedValue::Expression { ··· 1007 1027 TypedExpr::ModuleSelect { 1008 1028 constructor: ModuleValueConstructor::Constant { literal, .. }, 1009 1029 .. 1010 - } => self.inlined_constant(eaf, literal), 1030 + } => self.inlined_constant(builder, literal), 1011 1031 1012 1032 // 1013 1033 // Control flow. 1014 1034 // 1015 1035 TypedExpr::Case { 1016 1036 subjects, clauses, .. 1017 - } => self.case(eaf, subjects, clauses), 1037 + } => self.case(builder, subjects, clauses), 1018 1038 1019 1039 // 1020 1040 // Something went wrong! ··· 1027 1047 1028 1048 fn echo<Output>( 1029 1049 &mut self, 1030 - eaf: &mut impl Eaf<Output>, 1050 + builder: &mut impl ErlangBuilder<Output>, 1031 1051 echo_location: SrcSpan, 1032 1052 message: Option<&'a TypedExpr>, 1033 1053 printed_value: EchoPrintedValue<'a>, 1034 1054 ) { 1035 1055 self.module_generator.echo_used = true; 1036 1056 1037 - let call = eaf.start_call(); 1038 - eaf.atom("echo"); 1057 + let call = builder.start_call(); 1058 + builder.atom("echo"); 1039 1059 1040 1060 // Echo has 4 arguments: the expression to print... 1041 1061 match printed_value { 1042 - EchoPrintedValue::PipeStep { name } => eaf.variable(&name), 1043 - EchoPrintedValue::Expression { value } => self.maybe_block_expr(eaf, value), 1062 + EchoPrintedValue::PipeStep { name } => builder.variable(&name), 1063 + EchoPrintedValue::Expression { value } => self.maybe_block_expr(builder, value), 1044 1064 } 1045 1065 // ...the message to print (or nil if there's no message)... 1046 1066 if let Some(message) = message { 1047 - self.maybe_block_expr(eaf, message); 1067 + self.maybe_block_expr(builder, message); 1048 1068 } else { 1049 - eaf.atom("nil") 1069 + builder.atom("nil") 1050 1070 } 1051 1071 1052 1072 // ...the filepath of this module... 1053 - eaf.string(&self.module_generator.module_source_path); 1073 + builder.string(&self.module_generator.module_source_path); 1054 1074 1055 1075 // ...and the line number of the expression. 1056 - eaf.int( 1076 + builder.int( 1057 1077 self.module_generator 1058 1078 .line_numbers 1059 1079 .line_number(echo_location.start) 1060 1080 .into(), 1061 1081 ); 1062 1082 1063 - eaf.end_call(call); 1083 + builder.end_call(call); 1064 1084 } 1065 1085 1066 1086 /// This starts a call to `erlang:error` with a map representing a Gleam 1067 1087 /// runtime error of the given kind. 1068 1088 /// Some fields are mandatory and always added, but if you need to add more 1069 - /// fields you can still do so by calling `eaf.map_field()`. 1089 + /// fields you can still do so by calling `builder.map_field()`. 1070 1090 /// 1071 1091 /// After you're done generating those additional fields remember you _must_ 1072 1092 /// call `end_runtime_error` before generating any other piece of code! 1073 1093 /// 1074 1094 fn start_runtime_error<Output>( 1075 1095 &mut self, 1076 - eaf: &mut impl Eaf<Output>, 1096 + builder: &mut impl ErlangBuilder<Output>, 1077 1097 error_kind: RuntimeErrorKind, 1078 1098 location: SrcSpan, 1079 1099 message: Option<&'a TypedExpr>, 1080 1100 ) -> RuntimeError { 1081 - let call = eaf.start_remote_call(ErlangModuleName::new("erlang"), "error"); 1082 - let map = eaf.start_map(); 1101 + let call = builder.start_remote_call(ErlangModuleName::new("erlang"), "error"); 1102 + let map = builder.start_map(); 1083 1103 1084 - eaf.map_field(); 1085 - eaf.atom("gleam_error"); 1086 - eaf.atom(match error_kind { 1104 + builder.map_field(); 1105 + builder.atom("gleam_error"); 1106 + builder.atom(match error_kind { 1087 1107 RuntimeErrorKind::Todo => "todo", 1088 1108 RuntimeErrorKind::Panic => "panic", 1089 1109 RuntimeErrorKind::Assert => "assert", 1090 1110 RuntimeErrorKind::LetAssert => "let_assert", 1091 1111 }); 1092 1112 1093 - eaf.map_field(); 1094 - eaf.atom("message"); 1113 + builder.map_field(); 1114 + builder.atom("message"); 1095 1115 if let Some(message) = message { 1096 - self.maybe_block_expr(eaf, message); 1116 + self.maybe_block_expr(builder, message); 1097 1117 } else { 1098 - eaf.string(error_kind.default_error_message()) 1118 + builder.string(error_kind.default_error_message()) 1099 1119 } 1100 1120 1101 - eaf.map_field(); 1102 - eaf.atom("file"); 1103 - eaf.string(&self.module_generator.module_source_path); 1121 + builder.map_field(); 1122 + builder.atom("file"); 1123 + builder.string(&self.module_generator.module_source_path); 1104 1124 1105 - eaf.map_field(); 1106 - eaf.atom("module"); 1107 - eaf.string(&self.module_generator.module.name); 1125 + builder.map_field(); 1126 + builder.atom("module"); 1127 + builder.string(&self.module_generator.module.name); 1108 1128 1109 - eaf.map_field(); 1110 - eaf.atom("function"); 1111 - eaf.string(self.function_name); 1129 + builder.map_field(); 1130 + builder.atom("function"); 1131 + builder.string(self.function_name); 1112 1132 1113 - eaf.map_field(); 1114 - eaf.atom("line"); 1115 - eaf.int( 1133 + builder.map_field(); 1134 + builder.atom("line"); 1135 + builder.int( 1116 1136 self.module_generator 1117 1137 .line_numbers 1118 1138 .line_number(location.start) ··· 1126 1146 } 1127 1147 1128 1148 /// This closes an open runtime error. 1129 - fn end_runtime_error<Output>(&self, eaf: &mut impl Eaf<Output>, runtime_error: RuntimeError) { 1130 - eaf.end_map(runtime_error.error_map); 1131 - eaf.end_call(runtime_error.erlang_error_call); 1149 + fn end_runtime_error<Output>( 1150 + &self, 1151 + builder: &mut impl ErlangBuilder<Output>, 1152 + runtime_error: RuntimeError, 1153 + ) { 1154 + builder.end_map(runtime_error.error_map); 1155 + builder.end_call(runtime_error.erlang_error_call); 1132 1156 } 1133 1157 1134 - fn maybe_block_expr<Output>(&mut self, eaf: &mut impl Eaf<Output>, expression: &'a TypedExpr) { 1158 + fn maybe_block_expr<Output>( 1159 + &mut self, 1160 + builder: &mut impl ErlangBuilder<Output>, 1161 + expression: &'a TypedExpr, 1162 + ) { 1135 1163 if needs_begin_end_wrapping(expression) { 1136 - let block = eaf.start_block(); 1137 - self.expr(eaf, expression); 1138 - eaf.end_block(block); 1164 + let block = builder.start_block(); 1165 + self.expr(builder, expression); 1166 + builder.end_block(block); 1139 1167 } else { 1140 - self.expr(eaf, expression); 1168 + self.expr(builder, expression); 1141 1169 } 1142 1170 } 1143 1171 1144 1172 fn let_<Output>( 1145 1173 &mut self, 1146 - eaf: &mut impl Eaf<Output>, 1174 + builder: &mut impl ErlangBuilder<Output>, 1147 1175 value: &'a TypedExpr, 1148 1176 pattern: &'a TypedPattern, 1149 1177 ) { 1150 - eaf.match_operator(); 1151 - PatternGenerator::new(self).pattern(eaf, pattern); 1152 - self.maybe_block_expr(eaf, value) 1178 + builder.match_operator(); 1179 + PatternGenerator::new(self).pattern(builder, pattern); 1180 + self.maybe_block_expr(builder, value) 1153 1181 } 1154 1182 1155 1183 fn let_assert<Output>( 1156 1184 &mut self, 1157 - eaf: &mut impl Eaf<Output>, 1185 + builder: &mut impl ErlangBuilder<Output>, 1158 1186 value: &'a TypedExpr, 1159 1187 pattern: &'a TypedPattern, 1160 1188 message: Option<&'a TypedExpr>, ··· 1164 1192 // If the pattern will never fail, like a tuple or a simple variable, we 1165 1193 // simply treat it as if it were a `let` assignment. 1166 1194 if pattern.always_matches() { 1167 - self.let_(eaf, value, pattern); 1168 - self.statement_sequence(eaf, following_statements); 1195 + self.let_(builder, value, pattern); 1196 + self.statement_sequence(builder, following_statements); 1169 1197 return; 1170 1198 } 1171 1199 1172 1200 // Otherwise we turn the let assert into a case expression with two 1173 1201 // branches: one for the asserted pattern, and one catch all to throw an 1174 1202 // exception in case the pattern doesn't match. 1175 - let case = eaf.start_case(); 1176 - self.maybe_block_expr(eaf, value); 1203 + let case = builder.start_case(); 1204 + self.maybe_block_expr(builder, value); 1177 1205 1178 1206 // This is the first branch for when the asserted pattern matches: it's 1179 1207 // going to run all the remaining statements in its body. 1180 1208 if !following_statements.is_empty() { 1181 1209 // If there's statements after this let assert we want to generate 1182 1210 // them. 1183 - let clause = eaf.start_case_clause(); 1211 + let clause = builder.start_case_clause(); 1184 1212 let mut generator = PatternGenerator::new(self); 1185 - generator.pattern(eaf, pattern); 1186 - let clause = eaf.end_clause_pattern(clause); 1187 - let clause = eaf.end_clause_guards(clause); 1213 + generator.pattern(builder, pattern); 1214 + let clause = builder.end_clause_pattern(clause); 1215 + let clause = builder.end_clause_guards(clause); 1188 1216 let variables_to_add_later = generator.variables_to_add_later; 1189 - self.pattern_assignments(eaf, variables_to_add_later); 1190 - self.statement_sequence(eaf, following_statements); 1191 - eaf.end_clause_body(clause); 1217 + self.pattern_assignments(builder, variables_to_add_later); 1218 + self.statement_sequence(builder, following_statements); 1219 + builder.end_clause_body(clause); 1192 1220 } else { 1193 1221 // If there's no statements following the let assert, that means 1194 1222 // that it's the last statement in the block and we need to return ··· 1203 1231 // _ -> erlang:error(...) 1204 1232 // end 1205 1233 // ``` 1206 - let clause = eaf.start_case_clause(); 1234 + let clause = builder.start_case_clause(); 1207 1235 let matched_value_name = self.new_throwaway_variable(); 1208 - eaf.match_pattern(); 1236 + builder.match_pattern(); 1209 1237 let mut generator = PatternGenerator::new(self); 1210 - generator.pattern(eaf, pattern); 1211 - eaf.variable_pattern(&matched_value_name); 1238 + generator.pattern(builder, pattern); 1239 + builder.variable_pattern(&matched_value_name); 1212 1240 1213 - let clause = eaf.end_clause_pattern(clause); 1214 - let clause = eaf.end_clause_guards(clause); 1215 - eaf.variable(&matched_value_name); 1216 - eaf.end_clause_body(clause); 1241 + let clause = builder.end_clause_pattern(clause); 1242 + let clause = builder.end_clause_guards(clause); 1243 + builder.variable(&matched_value_name); 1244 + builder.end_clause_body(clause); 1217 1245 } 1218 1246 1219 1247 // This is the catch all branch to throw an error otherwise. 1220 - let clause = eaf.start_case_clause(); 1248 + let clause = builder.start_case_clause(); 1221 1249 let value_name = self.new_throwaway_variable(); 1222 - eaf.variable_pattern(&value_name); 1223 - let clause = eaf.end_clause_pattern(clause); 1224 - let clause = eaf.end_clause_guards(clause); 1225 - let error = self.start_runtime_error(eaf, RuntimeErrorKind::LetAssert, location, message); 1250 + builder.variable_pattern(&value_name); 1251 + let clause = builder.end_clause_pattern(clause); 1252 + let clause = builder.end_clause_guards(clause); 1253 + let error = 1254 + self.start_runtime_error(builder, RuntimeErrorKind::LetAssert, location, message); 1226 1255 1227 1256 // We want to add some additional fields to the error map: 1228 - eaf.map_field(); 1229 - eaf.atom("value"); 1230 - eaf.variable(&value_name); 1257 + builder.map_field(); 1258 + builder.atom("value"); 1259 + builder.variable(&value_name); 1231 1260 1232 - eaf.map_field(); 1233 - eaf.atom("start"); 1234 - eaf.int(location.start.into()); 1261 + builder.map_field(); 1262 + builder.atom("start"); 1263 + builder.int(location.start.into()); 1235 1264 1236 - eaf.map_field(); 1237 - eaf.atom("end"); 1238 - eaf.int(value.location().end.into()); 1265 + builder.map_field(); 1266 + builder.atom("end"); 1267 + builder.int(value.location().end.into()); 1239 1268 1240 - eaf.map_field(); 1241 - eaf.atom("pattern_start"); 1242 - eaf.int(pattern.location().start.into()); 1269 + builder.map_field(); 1270 + builder.atom("pattern_start"); 1271 + builder.int(pattern.location().start.into()); 1243 1272 1244 - eaf.map_field(); 1245 - eaf.atom("pattern_end"); 1246 - eaf.int(pattern.location().end.into()); 1273 + builder.map_field(); 1274 + builder.atom("pattern_end"); 1275 + builder.int(pattern.location().end.into()); 1247 1276 1248 - self.end_runtime_error(eaf, error); 1249 - eaf.end_clause_body(clause); 1277 + self.end_runtime_error(builder, error); 1278 + builder.end_clause_body(clause); 1250 1279 1251 - eaf.end_case(case); 1280 + builder.end_case(case); 1252 1281 } 1253 1282 1254 1283 fn pipeline<Output>( 1255 1284 &mut self, 1256 - eaf: &mut impl Eaf<Output>, 1285 + builder: &mut impl ErlangBuilder<Output>, 1257 1286 first_value: &'a TypedPipelineAssignment, 1258 1287 assignments: &'a [(TypedPipelineAssignment, PipelineAssignmentKind)], 1259 1288 finally: &'a TypedExpr, ··· 1277 1306 // A pipeline step always ends up assigned to a variable. 1278 1307 // So we start by generating `_pipe = ...`, followed by the 1279 1308 // expression. 1280 - eaf.match_operator(); 1309 + builder.match_operator(); 1281 1310 let name = self.new_erlang_variable(&assignment.name, assignment.location); 1282 - eaf.variable_pattern(&name); 1311 + builder.variable_pattern(&name); 1283 1312 1284 1313 // In case of a pipe we need to manually pass the previous step to 1285 1314 // echo as an argument. ··· 1291 1320 } = assignment.value.as_ref() 1292 1321 { 1293 1322 self.echo( 1294 - eaf, 1323 + builder, 1295 1324 *location, 1296 1325 message.as_deref(), 1297 1326 EchoPrintedValue::PipeStep { ··· 1301 1330 }, 1302 1331 ) 1303 1332 } else { 1304 - self.maybe_block_expr(eaf, &assignment.value); 1333 + self.maybe_block_expr(builder, &assignment.value); 1305 1334 previous_step_variable_name = Some(name); 1306 1335 }; 1307 1336 } ··· 1317 1346 } = finally 1318 1347 { 1319 1348 self.echo( 1320 - eaf, 1349 + builder, 1321 1350 *location, 1322 1351 message.as_deref(), 1323 1352 EchoPrintedValue::PipeStep { ··· 1326 1355 }, 1327 1356 ) 1328 1357 } else { 1329 - self.expr(eaf, finally) 1358 + self.expr(builder, finally) 1330 1359 } 1331 1360 } 1332 1361 1333 - fn assert<Output>(&mut self, eaf: &mut impl Eaf<Output>, assert: &'a TypedAssert) { 1362 + fn assert<Output>( 1363 + &mut self, 1364 + builder: &mut impl ErlangBuilder<Output>, 1365 + assert: &'a TypedAssert, 1366 + ) { 1334 1367 let Assert { 1335 1368 value, 1336 1369 location, ··· 1352 1385 // Writing asserts on binops requires some extra care, check 1353 1386 // out their docs! 1354 1387 BinOp::And => { 1355 - return self.assert_and(eaf, left, right, message.as_ref(), *location); 1388 + return self.assert_and(builder, left, right, message.as_ref(), *location); 1356 1389 } 1357 1390 BinOp::Or => { 1358 - return self.assert_or(eaf, left, right, message.as_ref(), *location); 1391 + return self.assert_or(builder, left, right, message.as_ref(), *location); 1359 1392 } 1360 1393 1361 1394 BinOp::Eq => "=:=", ··· 1384 1417 // track of those names. 1385 1418 let left = if !left.is_var() { 1386 1419 let name = self.new_throwaway_variable(); 1387 - eaf.match_operator(); 1388 - eaf.variable_pattern(&name); 1389 - self.maybe_block_expr(eaf, left); 1420 + builder.match_operator(); 1421 + builder.variable_pattern(&name); 1422 + self.maybe_block_expr(builder, left); 1390 1423 AssertionExpression::from_throwaway_variable(name, left) 1391 1424 } else { 1392 1425 AssertionExpression::from_expression(left) ··· 1394 1427 1395 1428 let right = if !right.is_var() { 1396 1429 let name = self.new_throwaway_variable(); 1397 - eaf.match_operator(); 1398 - eaf.variable_pattern(&name); 1399 - self.maybe_block_expr(eaf, right); 1430 + builder.match_operator(); 1431 + builder.variable_pattern(&name); 1432 + self.maybe_block_expr(builder, right); 1400 1433 AssertionExpression::from_throwaway_variable(name, right) 1401 1434 } else { 1402 1435 AssertionExpression::from_expression(right) 1403 1436 }; 1404 1437 1405 - let case = eaf.start_case(); 1438 + let case = builder.start_case(); 1406 1439 1407 1440 // Then we need to apply the operator. If any of the two sides 1408 1441 // has been bound to a variable we can use that name directly! 1409 - eaf.binary_operator(erlang_operator); 1410 - self.runtime_value(eaf, &left); 1411 - self.runtime_value(eaf, &right); 1442 + builder.binary_operator(erlang_operator); 1443 + self.runtime_value(builder, &left); 1444 + self.runtime_value(builder, &right); 1412 1445 1413 1446 // If the operator evaluates to true the assertion succeeded. 1414 1447 // We can just return nil. 1415 - let clause = eaf.start_case_clause(); 1416 - eaf.atom_pattern("true"); 1417 - let clause = eaf.end_clause_pattern(clause); 1418 - let clause = eaf.end_clause_guards(clause); 1419 - eaf.atom("nil"); 1420 - eaf.end_clause_body(clause); 1448 + let clause = builder.start_case_clause(); 1449 + builder.atom_pattern("true"); 1450 + let clause = builder.end_clause_pattern(clause); 1451 + let clause = builder.end_clause_guards(clause); 1452 + builder.atom("nil"); 1453 + builder.end_clause_body(clause); 1421 1454 1422 1455 // Otherwise we want to throw a runtime error! 1423 - let clause = eaf.start_case_clause(); 1424 - eaf.atom_pattern("false"); 1425 - let clause = eaf.end_clause_pattern(clause); 1426 - let clause = eaf.end_clause_guards(clause); 1456 + let clause = builder.start_case_clause(); 1457 + builder.atom_pattern("false"); 1458 + let clause = builder.end_clause_pattern(clause); 1459 + let clause = builder.end_clause_guards(clause); 1427 1460 self.assert_binary_operator_error( 1428 - eaf, 1461 + builder, 1429 1462 *operator, 1430 1463 left, 1431 1464 right, 1432 1465 message.as_ref(), 1433 1466 *location, 1434 1467 ); 1435 - eaf.end_clause_body(clause); 1468 + builder.end_clause_body(clause); 1436 1469 1437 - eaf.end_case(case); 1470 + builder.end_case(case); 1438 1471 } 1439 1472 1440 1473 TypedExpr::Call { fun, arguments, .. } => { ··· 1447 1480 for argument in arguments { 1448 1481 let argument = if !argument.value.is_var() { 1449 1482 let name = self.new_throwaway_variable(); 1450 - eaf.match_operator(); 1451 - eaf.variable_pattern(&name); 1452 - self.maybe_block_expr(eaf, &argument.value); 1483 + builder.match_operator(); 1484 + builder.variable_pattern(&name); 1485 + self.maybe_block_expr(builder, &argument.value); 1453 1486 AssertionExpression::from_throwaway_variable(name, &argument.value) 1454 1487 } else { 1455 1488 AssertionExpression::from_expression(&argument.value) ··· 1457 1490 call_arguments.push(argument); 1458 1491 } 1459 1492 1460 - let case = eaf.start_case(); 1461 - self.call_in_assert(eaf, fun, &call_arguments); 1493 + let case = builder.start_case(); 1494 + self.call_in_assert(builder, fun, &call_arguments); 1462 1495 1463 1496 // If the operator evaluates to true the assertion succeeded. 1464 1497 // We can just return nil. 1465 - let clause = eaf.start_case_clause(); 1466 - eaf.atom_pattern("true"); 1467 - let clause = eaf.end_clause_pattern(clause); 1468 - let clause = eaf.end_clause_guards(clause); 1469 - eaf.atom("nil"); 1470 - eaf.end_clause_body(clause); 1498 + let clause = builder.start_case_clause(); 1499 + builder.atom_pattern("true"); 1500 + let clause = builder.end_clause_pattern(clause); 1501 + let clause = builder.end_clause_guards(clause); 1502 + builder.atom("nil"); 1503 + builder.end_clause_body(clause); 1471 1504 1472 1505 // Otherwise we want to throw a runtime error! 1473 - let clause = eaf.start_case_clause(); 1474 - eaf.atom_pattern("false"); 1475 - let clause = eaf.end_clause_pattern(clause); 1476 - let clause = eaf.end_clause_guards(clause); 1477 - self.assert_call_error(eaf, value, &call_arguments, message.as_ref(), *location); 1478 - eaf.end_clause_body(clause); 1506 + let clause = builder.start_case_clause(); 1507 + builder.atom_pattern("false"); 1508 + let clause = builder.end_clause_pattern(clause); 1509 + let clause = builder.end_clause_guards(clause); 1510 + self.assert_call_error( 1511 + builder, 1512 + value, 1513 + &call_arguments, 1514 + message.as_ref(), 1515 + *location, 1516 + ); 1517 + builder.end_clause_body(clause); 1479 1518 1480 - eaf.end_case(case); 1519 + builder.end_case(case); 1481 1520 } 1482 1521 1483 1522 TypedExpr::Int { .. } ··· 1502 1541 | TypedExpr::NegateBool { .. } 1503 1542 | TypedExpr::NegateInt { .. } 1504 1543 | TypedExpr::Invalid { .. } => { 1505 - let case = eaf.start_case(); 1506 - self.maybe_block_expr(eaf, value); 1544 + let case = builder.start_case(); 1545 + self.maybe_block_expr(builder, value); 1507 1546 1508 1547 // If the expression evaluates to true the assertion succeeded. 1509 1548 // We can just return nil. 1510 - let clause = eaf.start_case_clause(); 1511 - eaf.atom_pattern("true"); 1512 - let clause = eaf.end_clause_pattern(clause); 1513 - let clause = eaf.end_clause_guards(clause); 1514 - eaf.atom("nil"); 1515 - eaf.end_clause_body(clause); 1549 + let clause = builder.start_case_clause(); 1550 + builder.atom_pattern("true"); 1551 + let clause = builder.end_clause_pattern(clause); 1552 + let clause = builder.end_clause_guards(clause); 1553 + builder.atom("nil"); 1554 + builder.end_clause_body(clause); 1516 1555 1517 1556 // Otherwise we want to throw a runtime error! 1518 - let clause = eaf.start_case_clause(); 1519 - eaf.atom_pattern("false"); 1520 - let clause = eaf.end_clause_pattern(clause); 1521 - let clause = eaf.end_clause_guards(clause); 1557 + let clause = builder.start_case_clause(); 1558 + builder.atom_pattern("false"); 1559 + let clause = builder.end_clause_pattern(clause); 1560 + let clause = builder.end_clause_guards(clause); 1522 1561 self.assert_expression_error( 1523 - eaf, 1562 + builder, 1524 1563 AssertionExpression::from_expression(value).evaluated_to_bool(false), 1525 1564 message.as_ref(), 1526 1565 *location, 1527 1566 ); 1528 - eaf.end_clause_body(clause); 1567 + builder.end_clause_body(clause); 1529 1568 1530 - eaf.end_case(case); 1569 + builder.end_case(case); 1531 1570 } 1532 1571 } 1533 1572 } ··· 1560 1599 /// 1561 1600 fn assert_and<Output>( 1562 1601 &mut self, 1563 - eaf: &mut impl Eaf<Output>, 1602 + builder: &mut impl ErlangBuilder<Output>, 1564 1603 left: &'a TypedExpr, 1565 1604 right: &'a TypedExpr, 1566 1605 message: Option<&'a TypedExpr>, 1567 1606 location: SrcSpan, 1568 1607 ) { 1569 - let case = eaf.start_case(); 1570 - self.maybe_block_expr(eaf, left); 1608 + let case = builder.start_case(); 1609 + self.maybe_block_expr(builder, left); 1571 1610 1572 1611 // In case the first expression is true, we get to evaluate the second 1573 1612 // one as well, then we will be able to tell if the assertion failed or 1574 1613 // not! 1575 - let clause = eaf.start_case_clause(); 1576 - eaf.atom_pattern("true"); 1577 - let clause = eaf.end_clause_pattern(clause); 1578 - let clause = eaf.end_clause_guards(clause); 1614 + let clause = builder.start_case_clause(); 1615 + builder.atom_pattern("true"); 1616 + let clause = builder.end_clause_pattern(clause); 1617 + let clause = builder.end_clause_guards(clause); 1579 1618 { 1580 1619 // Now we have to match on the right hand side! 1581 - let case = eaf.start_case(); 1582 - self.maybe_block_expr(eaf, right); 1620 + let case = builder.start_case(); 1621 + self.maybe_block_expr(builder, right); 1583 1622 1584 1623 // If it's true the assertion succeded! We can return `nil`. 1585 - let clause = eaf.start_case_clause(); 1586 - eaf.atom_pattern("true"); 1587 - let clause = eaf.end_clause_pattern(clause); 1588 - let clause = eaf.end_clause_guards(clause); 1589 - eaf.atom("nil"); 1590 - eaf.end_clause_body(clause); 1624 + let clause = builder.start_case_clause(); 1625 + builder.atom_pattern("true"); 1626 + let clause = builder.end_clause_pattern(clause); 1627 + let clause = builder.end_clause_guards(clause); 1628 + builder.atom("nil"); 1629 + builder.end_clause_body(clause); 1591 1630 1592 1631 // If it's false the assertion failed! The left hand side was true 1593 1632 // but this one evaluated to false :( 1594 - let clause = eaf.start_case_clause(); 1595 - eaf.atom_pattern("false"); 1596 - let clause = eaf.end_clause_pattern(clause); 1597 - let clause = eaf.end_clause_guards(clause); 1633 + let clause = builder.start_case_clause(); 1634 + builder.atom_pattern("false"); 1635 + let clause = builder.end_clause_pattern(clause); 1636 + let clause = builder.end_clause_guards(clause); 1598 1637 self.assert_binary_operator_error( 1599 - eaf, 1638 + builder, 1600 1639 BinOp::And, 1601 1640 AssertionExpression::from_expression(left).evaluated_to_bool(true), 1602 1641 AssertionExpression::from_expression(right).evaluated_to_bool(false), 1603 1642 message, 1604 1643 location, 1605 1644 ); 1606 - eaf.end_clause_body(clause); 1607 - eaf.end_case(case); 1645 + builder.end_clause_body(clause); 1646 + builder.end_case(case); 1608 1647 } 1609 - eaf.end_clause_body(clause); 1648 + builder.end_clause_body(clause); 1610 1649 1611 1650 // In case the first expression is false, we want to fail fast. We are 1612 1651 // short circuiting without evaluating the right hand side! This side 1613 1652 // just build an error. 1614 - let clause = eaf.start_case_clause(); 1615 - eaf.atom_pattern("false"); 1616 - let clause = eaf.end_clause_pattern(clause); 1617 - let clause = eaf.end_clause_guards(clause); 1653 + let clause = builder.start_case_clause(); 1654 + builder.atom_pattern("false"); 1655 + let clause = builder.end_clause_pattern(clause); 1656 + let clause = builder.end_clause_guards(clause); 1618 1657 self.assert_binary_operator_error( 1619 - eaf, 1658 + builder, 1620 1659 BinOp::And, 1621 1660 AssertionExpression::from_expression(left).evaluated_to_bool(false), 1622 1661 AssertionExpression::from_expression(right).was_unevaluated(), 1623 1662 message, 1624 1663 location, 1625 1664 ); 1626 - eaf.end_clause_body(clause); 1665 + builder.end_clause_body(clause); 1627 1666 1628 - eaf.end_case(case); 1667 + builder.end_case(case); 1629 1668 } 1630 1669 1631 1670 /// Similar to `&&`, `||` is also short-circuiting in Gleam. However, if `||` ··· 1638 1677 /// need to store the values of them in variables beforehand. 1639 1678 fn assert_or<Output>( 1640 1679 &mut self, 1641 - eaf: &mut impl Eaf<Output>, 1680 + builder: &mut impl ErlangBuilder<Output>, 1642 1681 left: &'a TypedExpr, 1643 1682 right: &'a TypedExpr, 1644 1683 message: Option<&'a TypedExpr>, 1645 1684 location: SrcSpan, 1646 1685 ) { 1647 - let case = eaf.start_case(); 1648 - eaf.binary_operator("orelse"); 1649 - self.maybe_block_expr(eaf, left); 1650 - self.maybe_block_expr(eaf, right); 1686 + let case = builder.start_case(); 1687 + builder.binary_operator("orelse"); 1688 + self.maybe_block_expr(builder, left); 1689 + self.maybe_block_expr(builder, right); 1651 1690 1652 1691 // If the result is true, then the assertion succeeded, we can return 1653 1692 // nil. 1654 - let clause = eaf.start_case_clause(); 1655 - eaf.atom_pattern("true"); 1656 - let clause = eaf.end_clause_pattern(clause); 1657 - let clause = eaf.end_clause_guards(clause); 1658 - eaf.atom("nil"); 1659 - eaf.end_clause_body(clause); 1693 + let clause = builder.start_case_clause(); 1694 + builder.atom_pattern("true"); 1695 + let clause = builder.end_clause_pattern(clause); 1696 + let clause = builder.end_clause_guards(clause); 1697 + builder.atom("nil"); 1698 + builder.end_clause_body(clause); 1660 1699 1661 1700 // But if it fails we know that both sides of the assertion resulted in 1662 1701 // a false value. In that case we throw an error. 1663 1702 1664 - let clause = eaf.start_case_clause(); 1665 - eaf.atom_pattern("false"); 1666 - let clause = eaf.end_clause_pattern(clause); 1667 - let clause = eaf.end_clause_guards(clause); 1703 + let clause = builder.start_case_clause(); 1704 + builder.atom_pattern("false"); 1705 + let clause = builder.end_clause_pattern(clause); 1706 + let clause = builder.end_clause_guards(clause); 1668 1707 self.assert_binary_operator_error( 1669 - eaf, 1708 + builder, 1670 1709 BinOp::Or, 1671 1710 AssertionExpression::from_expression(left).evaluated_to_bool(false), 1672 1711 AssertionExpression::from_expression(right).evaluated_to_bool(false), 1673 1712 message, 1674 1713 location, 1675 1714 ); 1676 - eaf.end_clause_body(clause); 1715 + builder.end_clause_body(clause); 1677 1716 1678 - eaf.end_case(case); 1717 + builder.end_case(case); 1679 1718 } 1680 1719 1681 1720 /// This generates the code that throws a runtime error whan an `assert` 1682 1721 /// that is checking the result of a binary operator fails. 1683 1722 fn assert_binary_operator_error<Output>( 1684 1723 &mut self, 1685 - eaf: &mut impl Eaf<Output>, 1724 + builder: &mut impl ErlangBuilder<Output>, 1686 1725 operator: BinOp, 1687 1726 left: AssertionExpression<'a>, 1688 1727 right: AssertionExpression<'a>, 1689 1728 message: Option<&'a TypedExpr>, 1690 1729 location: SrcSpan, 1691 1730 ) { 1692 - let error = self.start_runtime_error(eaf, RuntimeErrorKind::Assert, location, message); 1731 + let error = self.start_runtime_error(builder, RuntimeErrorKind::Assert, location, message); 1693 1732 1694 - eaf.map_field(); 1695 - eaf.atom("kind"); 1696 - eaf.atom("binary_operator"); 1733 + builder.map_field(); 1734 + builder.atom("kind"); 1735 + builder.atom("binary_operator"); 1697 1736 1698 - eaf.map_field(); 1699 - eaf.atom("operator"); 1700 - eaf.atom(operator.name()); 1737 + builder.map_field(); 1738 + builder.atom("operator"); 1739 + builder.atom(operator.name()); 1701 1740 1702 - eaf.map_field(); 1703 - eaf.atom("left"); 1704 - self.assertion_expression_map(eaf, &left); 1741 + builder.map_field(); 1742 + builder.atom("left"); 1743 + self.assertion_expression_map(builder, &left); 1705 1744 1706 - eaf.map_field(); 1707 - eaf.atom("right"); 1708 - self.assertion_expression_map(eaf, &right); 1745 + builder.map_field(); 1746 + builder.atom("right"); 1747 + self.assertion_expression_map(builder, &right); 1709 1748 1710 - eaf.map_field(); 1711 - eaf.atom("start"); 1712 - eaf.int(location.start.into()); 1749 + builder.map_field(); 1750 + builder.atom("start"); 1751 + builder.int(location.start.into()); 1713 1752 1714 - eaf.map_field(); 1715 - eaf.atom("end"); 1716 - eaf.int(right.location.end.into()); 1753 + builder.map_field(); 1754 + builder.atom("end"); 1755 + builder.int(right.location.end.into()); 1717 1756 1718 - eaf.map_field(); 1719 - eaf.atom("expression_start"); 1720 - eaf.int(left.location.start.into()); 1757 + builder.map_field(); 1758 + builder.atom("expression_start"); 1759 + builder.int(left.location.start.into()); 1721 1760 1722 - self.end_runtime_error(eaf, error); 1761 + self.end_runtime_error(builder, error); 1723 1762 } 1724 1763 1725 1764 /// This generates the code that throws a runtime error whan an `assert` 1726 1765 /// that is checking the result of an arbitrary expression fails. 1727 1766 fn assert_expression_error<Output>( 1728 1767 &mut self, 1729 - eaf: &mut impl Eaf<Output>, 1768 + builder: &mut impl ErlangBuilder<Output>, 1730 1769 expression: AssertionExpression<'a>, 1731 1770 message: Option<&'a TypedExpr>, 1732 1771 location: SrcSpan, 1733 1772 ) { 1734 - let error = self.start_runtime_error(eaf, RuntimeErrorKind::Assert, location, message); 1773 + let error = self.start_runtime_error(builder, RuntimeErrorKind::Assert, location, message); 1735 1774 1736 - eaf.map_field(); 1737 - eaf.atom("kind"); 1738 - eaf.atom("expression"); 1775 + builder.map_field(); 1776 + builder.atom("kind"); 1777 + builder.atom("expression"); 1739 1778 1740 1779 // If assert fails on an expression's result then we know it must have 1741 1780 // evaluated to false! 1742 - eaf.map_field(); 1743 - eaf.atom("expression"); 1744 - self.assertion_expression_map(eaf, &expression); 1781 + builder.map_field(); 1782 + builder.atom("expression"); 1783 + self.assertion_expression_map(builder, &expression); 1745 1784 1746 - eaf.map_field(); 1747 - eaf.atom("start"); 1748 - eaf.int(location.start.into()); 1785 + builder.map_field(); 1786 + builder.atom("start"); 1787 + builder.int(location.start.into()); 1749 1788 1750 - eaf.map_field(); 1751 - eaf.atom("end"); 1752 - eaf.int(expression.location.end.into()); 1789 + builder.map_field(); 1790 + builder.atom("end"); 1791 + builder.int(expression.location.end.into()); 1753 1792 1754 - eaf.map_field(); 1755 - eaf.atom("expression_start"); 1756 - eaf.int(expression.location.start.into()); 1793 + builder.map_field(); 1794 + builder.atom("expression_start"); 1795 + builder.int(expression.location.start.into()); 1757 1796 1758 - self.end_runtime_error(eaf, error); 1797 + self.end_runtime_error(builder, error); 1759 1798 } 1760 1799 1761 1800 fn assert_call_error<Output>( 1762 1801 &mut self, 1763 - eaf: &mut impl Eaf<Output>, 1802 + builder: &mut impl ErlangBuilder<Output>, 1764 1803 call: &'a TypedExpr, 1765 1804 arguments: &[AssertionExpression<'a>], 1766 1805 message: Option<&'a TypedExpr>, 1767 1806 location: SrcSpan, 1768 1807 ) { 1769 - let error = self.start_runtime_error(eaf, RuntimeErrorKind::Assert, location, message); 1808 + let error = self.start_runtime_error(builder, RuntimeErrorKind::Assert, location, message); 1770 1809 1771 - eaf.map_field(); 1772 - eaf.atom("kind"); 1773 - eaf.atom("function_call"); 1810 + builder.map_field(); 1811 + builder.atom("kind"); 1812 + builder.atom("function_call"); 1774 1813 1775 - eaf.map_field(); 1776 - eaf.atom("arguments"); 1814 + builder.map_field(); 1815 + builder.atom("arguments"); 1777 1816 for argument in arguments { 1778 - eaf.cons_list(); 1779 - self.assertion_expression_map(eaf, argument); 1817 + builder.cons_list(); 1818 + self.assertion_expression_map(builder, argument); 1780 1819 } 1781 - eaf.empty_list(); 1820 + builder.empty_list(); 1782 1821 1783 - eaf.map_field(); 1784 - eaf.atom("start"); 1785 - eaf.int(location.start.into()); 1822 + builder.map_field(); 1823 + builder.atom("start"); 1824 + builder.int(location.start.into()); 1786 1825 1787 - eaf.map_field(); 1788 - eaf.atom("end"); 1789 - eaf.int(call.location().end.into()); 1826 + builder.map_field(); 1827 + builder.atom("end"); 1828 + builder.int(call.location().end.into()); 1790 1829 1791 - eaf.map_field(); 1792 - eaf.atom("expression_start"); 1793 - eaf.int(call.location().start.into()); 1830 + builder.map_field(); 1831 + builder.atom("expression_start"); 1832 + builder.int(call.location().start.into()); 1794 1833 1795 - self.end_runtime_error(eaf, error); 1834 + self.end_runtime_error(builder, error); 1796 1835 } 1797 1836 1798 1837 /// Given an expression being asserted on. This generates the code for an ··· 1800 1839 /// its location in the source code. 1801 1840 fn assertion_expression_map<Output>( 1802 1841 &mut self, 1803 - eaf: &mut impl Eaf<Output>, 1842 + builder: &mut impl ErlangBuilder<Output>, 1804 1843 expression: &AssertionExpression<'a>, 1805 1844 ) { 1806 1845 let AssertionExpression { ··· 1809 1848 location, 1810 1849 } = expression; 1811 1850 1812 - let map = eaf.start_map(); 1851 + let map = builder.start_map(); 1813 1852 1814 - eaf.map_field(); 1815 - eaf.atom("kind"); 1816 - eaf.atom(match kind { 1853 + builder.map_field(); 1854 + builder.atom("kind"); 1855 + builder.atom(match kind { 1817 1856 AssertedExpressionKind::Literal => "literal", 1818 1857 AssertedExpressionKind::Expression => "expression", 1819 1858 AssertedExpressionKind::Unevaluated => "unevaluated", 1820 1859 }); 1821 1860 1822 1861 if runtime_value.is_some() { 1823 - eaf.map_field(); 1824 - eaf.atom("value"); 1825 - self.runtime_value(eaf, expression); 1862 + builder.map_field(); 1863 + builder.atom("value"); 1864 + self.runtime_value(builder, expression); 1826 1865 } 1827 1866 1828 - eaf.map_field(); 1829 - eaf.atom("start"); 1830 - eaf.int(location.start.into()); 1867 + builder.map_field(); 1868 + builder.atom("start"); 1869 + builder.int(location.start.into()); 1831 1870 1832 - eaf.map_field(); 1833 - eaf.atom("end"); 1834 - eaf.int(location.end.into()); 1871 + builder.map_field(); 1872 + builder.atom("end"); 1873 + builder.int(location.end.into()); 1835 1874 1836 - eaf.end_map(map); 1875 + builder.end_map(map); 1837 1876 } 1838 1877 1839 1878 /// This takes a value that is in an assertion (and might have been bound ··· 1842 1881 /// 1843 1882 fn runtime_value<Output>( 1844 1883 &mut self, 1845 - eaf: &mut impl Eaf<Output>, 1884 + builder: &mut impl ErlangBuilder<Output>, 1846 1885 expression: &AssertionExpression<'a>, 1847 1886 ) { 1848 1887 match expression ··· 1850 1889 .as_ref() 1851 1890 .expect("trying to reference unevaluated assert value") 1852 1891 { 1853 - AssertedExpressionRuntimeValue::KnownBool(true) => eaf.atom("true"), 1854 - AssertedExpressionRuntimeValue::KnownBool(false) => eaf.atom("false"), 1855 - AssertedExpressionRuntimeValue::Variable(name) => eaf.variable(name), 1856 - AssertedExpressionRuntimeValue::Expression(expr) => self.maybe_block_expr(eaf, expr), 1892 + AssertedExpressionRuntimeValue::KnownBool(true) => builder.atom("true"), 1893 + AssertedExpressionRuntimeValue::KnownBool(false) => builder.atom("false"), 1894 + AssertedExpressionRuntimeValue::Variable(name) => builder.variable(name), 1895 + AssertedExpressionRuntimeValue::Expression(expr) => { 1896 + self.maybe_block_expr(builder, expr) 1897 + } 1857 1898 } 1858 1899 } 1859 1900 1860 1901 fn tuple_index<Output>( 1861 1902 &mut self, 1862 - eaf: &mut impl Eaf<Output>, 1903 + builder: &mut impl ErlangBuilder<Output>, 1863 1904 tuple: &'a TypedExpr, 1864 1905 index: u64, 1865 1906 ) { 1866 - let call = eaf.start_remote_call(ErlangModuleName::new("erlang"), "element"); 1867 - eaf.int((index + 1).into()); 1868 - self.maybe_block_expr(eaf, tuple); 1869 - eaf.end_call(call); 1907 + let call = builder.start_remote_call(ErlangModuleName::new("erlang"), "element"); 1908 + builder.int((index + 1).into()); 1909 + self.maybe_block_expr(builder, tuple); 1910 + builder.end_call(call); 1870 1911 } 1871 1912 1872 1913 fn var<Output>( 1873 1914 &mut self, 1874 - eaf: &mut impl Eaf<Output>, 1915 + builder: &mut impl ErlangBuilder<Output>, 1875 1916 name: &'a str, 1876 1917 constructor: &'a ValueConstructor, 1877 1918 ) { ··· 1897 1938 // } 1898 1939 // ``` 1899 1940 Type::Named { .. } | Type::Var { .. } | Type::Tuple { .. } => { 1900 - eaf.atom(&to_snake_case(record_name)) 1941 + builder.atom(&to_snake_case(record_name)) 1901 1942 } 1902 1943 Type::Fn { arguments, .. } => { 1903 - self.record_builder_anonymous_function(eaf, record_name, arguments.len()) 1944 + self.record_builder_anonymous_function(builder, record_name, arguments.len()) 1904 1945 } 1905 1946 }, 1906 1947 1907 1948 ValueConstructorVariant::LocalVariable { location, .. } => { 1908 - eaf.variable(&self.local_var_name(location)) 1949 + builder.variable(&self.local_var_name(location)) 1909 1950 } 1910 1951 1911 1952 ValueConstructorVariant::ModuleConstant { literal, .. } => { 1912 - self.inlined_constant(eaf, literal) 1953 + self.inlined_constant(builder, literal) 1913 1954 } 1914 1955 1915 1956 ValueConstructorVariant::ModuleFn { ··· 1919 1960 } => { 1920 1961 let name = escape_erlang_existing_name(name); 1921 1962 if *module == self.module_generator.module.name { 1922 - eaf.function_reference(None, name, *arity) 1963 + builder.function_reference(None, name, *arity) 1923 1964 } else { 1924 - eaf.function_reference(Some(ErlangModuleName::new(&module)), name, *arity) 1965 + builder.function_reference(Some(ErlangModuleName::new(&module)), name, *arity) 1925 1966 } 1926 1967 } 1927 1968 1928 1969 ValueConstructorVariant::ModuleFn { arity, module, .. } 1929 1970 if *module == self.module_generator.module.name => 1930 1971 { 1931 - eaf.function_reference(None, escape_erlang_existing_name(name), *arity) 1972 + builder.function_reference(None, escape_erlang_existing_name(name), *arity) 1932 1973 } 1933 1974 1934 1975 ValueConstructorVariant::ModuleFn { ··· 1936 1977 module, 1937 1978 name, 1938 1979 .. 1939 - } => eaf.function_reference( 1980 + } => builder.function_reference( 1940 1981 Some(ErlangModuleName::new(&module)), 1941 1982 escape_erlang_existing_name(name), 1942 1983 *arity, ··· 1946 1987 1947 1988 fn call<Output>( 1948 1989 &mut self, 1949 - eaf: &mut impl Eaf<Output>, 1990 + builder: &mut impl ErlangBuilder<Output>, 1950 1991 fun: &'a TypedExpr, 1951 1992 arguments: &'a [TypedCallArg], 1952 1993 ) { 1953 1994 match how_to_call(fun) { 1954 1995 // If we're building a record then we want to just output a 1955 1996 // tagged tuple, there's no function call at all! 1956 - FunctionCall::BuildRecord { name } => self.build_record(eaf, name, arguments), 1997 + FunctionCall::BuildRecord { name } => self.build_record(builder, name, arguments), 1957 1998 // If we're calling some module function like `io.println`, `main`, 1958 1999 // `list.map` then we can call the function using its name (and 1959 2000 // module name if it comes from a different module). 1960 2001 FunctionCall::Call { module, name } => { 1961 2002 let call = if module != self.module_generator.module.name { 1962 - eaf.start_remote_call( 2003 + builder.start_remote_call( 1963 2004 ErlangModuleName::new(&module), 1964 2005 escape_erlang_existing_name(name), 1965 2006 ) 1966 2007 } else { 1967 - let call = eaf.start_call(); 1968 - eaf.atom(escape_erlang_existing_name(name)); 2008 + let call = builder.start_call(); 2009 + builder.atom(escape_erlang_existing_name(name)); 1969 2010 call 1970 2011 }; 1971 2012 for argument in arguments { 1972 - self.maybe_block_expr(eaf, &argument.value); 2013 + self.maybe_block_expr(builder, &argument.value); 1973 2014 } 1974 - eaf.end_call(call) 2015 + builder.end_call(call) 1975 2016 } 1976 2017 // If we're calling anything else (like an anonymous function, or 1977 2018 // the result of another function call) we generate its code and 1978 2019 // call that result directly. 1979 2020 FunctionCall::DirectCall => { 1980 - let call = eaf.start_call(); 1981 - self.maybe_block_expr(eaf, fun); 2021 + let call = builder.start_call(); 2022 + self.maybe_block_expr(builder, fun); 1982 2023 for argument in arguments { 1983 - self.maybe_block_expr(eaf, &argument.value); 2024 + self.maybe_block_expr(builder, &argument.value); 1984 2025 } 1985 - eaf.end_call(call); 2026 + builder.end_call(call); 1986 2027 } 1987 2028 } 1988 2029 } ··· 1998 2039 /// 1999 2040 fn call_in_assert<Output>( 2000 2041 &mut self, 2001 - eaf: &mut impl Eaf<Output>, 2042 + builder: &mut impl ErlangBuilder<Output>, 2002 2043 fun: &'a TypedExpr, 2003 2044 arguments: &[AssertionExpression<'a>], 2004 2045 ) { ··· 2014 2055 // module name if it comes from a different module). 2015 2056 FunctionCall::Call { module, name } => { 2016 2057 let call = if module != self.module_generator.module.name { 2017 - eaf.start_remote_call( 2058 + builder.start_remote_call( 2018 2059 ErlangModuleName::new(&module), 2019 2060 escape_erlang_existing_name(name), 2020 2061 ) 2021 2062 } else { 2022 - let call = eaf.start_call(); 2023 - eaf.atom(escape_erlang_existing_name(name)); 2063 + let call = builder.start_call(); 2064 + builder.atom(escape_erlang_existing_name(name)); 2024 2065 call 2025 2066 }; 2026 2067 for argument in arguments { 2027 - self.runtime_value(eaf, argument); 2068 + self.runtime_value(builder, argument); 2028 2069 } 2029 - eaf.end_call(call) 2070 + builder.end_call(call) 2030 2071 } 2031 2072 2032 2073 // If we're calling anything else (like an anonymous function, or 2033 2074 // the result of another function call) we generate its code and 2034 2075 // call that result directly. 2035 2076 FunctionCall::DirectCall => { 2036 - let call = eaf.start_call(); 2037 - self.maybe_block_expr(eaf, fun); 2077 + let call = builder.start_call(); 2078 + self.maybe_block_expr(builder, fun); 2038 2079 for argument in arguments { 2039 - self.runtime_value(eaf, argument); 2080 + self.runtime_value(builder, argument); 2040 2081 } 2041 - eaf.end_call(call); 2082 + builder.end_call(call); 2042 2083 } 2043 2084 } 2044 2085 } ··· 2052 2093 /// record. This function will take care of turning it to snake case! 2053 2094 fn build_record<Output>( 2054 2095 &mut self, 2055 - eaf: &mut impl Eaf<Output>, 2096 + builder: &mut impl ErlangBuilder<Output>, 2056 2097 record_name: &str, 2057 2098 arguments: &'a [TypedCallArg], 2058 2099 ) { 2059 2100 if arguments.is_empty() { 2060 - eaf.atom(&to_snake_case(record_name)) 2101 + builder.atom(&to_snake_case(record_name)) 2061 2102 } else { 2062 - let tuple = eaf.start_tuple(); 2063 - eaf.atom(&to_snake_case(record_name)); 2103 + let tuple = builder.start_tuple(); 2104 + builder.atom(&to_snake_case(record_name)); 2064 2105 for argument in arguments { 2065 - self.maybe_block_expr(eaf, &argument.value); 2106 + self.maybe_block_expr(builder, &argument.value); 2066 2107 } 2067 - eaf.end_tuple(tuple) 2108 + builder.end_tuple(tuple) 2068 2109 } 2069 2110 } 2070 2111 2071 2112 fn case<Output>( 2072 2113 &mut self, 2073 - eaf: &mut impl Eaf<Output>, 2114 + builder: &mut impl ErlangBuilder<Output>, 2074 2115 subjects: &'a [TypedExpr], 2075 2116 clauses: &'a [TypedClause], 2076 2117 ) { 2077 - let case = eaf.start_case(); 2118 + let case = builder.start_case(); 2078 2119 2079 2120 // If there's more than a single subject we will need to wrap those in a 2080 2121 // tuple and start matching on tuple patterns. That's because Erlang 2081 2122 // doesn't support matching on multiple subjects like Gleam. 2082 2123 match subjects { 2083 - [subject] => self.maybe_block_expr(eaf, subject), 2124 + [subject] => self.maybe_block_expr(builder, subject), 2084 2125 subjects => { 2085 - let tuple = eaf.start_tuple(); 2126 + let tuple = builder.start_tuple(); 2086 2127 for subject in subjects { 2087 - self.maybe_block_expr(eaf, subject); 2128 + self.maybe_block_expr(builder, subject); 2088 2129 } 2089 - eaf.end_tuple(tuple); 2130 + builder.end_tuple(tuple); 2090 2131 } 2091 2132 } 2092 2133 2093 2134 for clause in clauses { 2094 2135 let taken_names_before_clause = self.taken_names.clone(); 2095 2136 2096 - self.clause_branch(eaf, &clause.pattern, clause); 2137 + self.clause_branch(builder, &clause.pattern, clause); 2097 2138 2098 2139 // Erlang doesn't support alternative patterns so we're gonna have 2099 2140 // to turn those into separate branches! ··· 2123 2164 // 2124 2165 for pattern in &clause.alternative_patterns { 2125 2166 self.taken_names = taken_names_before_clause.clone(); 2126 - self.clause_branch(eaf, pattern, clause); 2167 + self.clause_branch(builder, pattern, clause); 2127 2168 } 2128 2169 } 2129 2170 2130 - eaf.end_case(case); 2171 + builder.end_case(case); 2131 2172 } 2132 2173 2133 2174 /// Given a pattern and the branch it belongs to this generates an Erlang 2134 2175 /// case clause for that pattern. 2135 2176 fn clause_branch<Output>( 2136 2177 &mut self, 2137 - eaf: &mut impl Eaf<Output>, 2178 + builder: &mut impl ErlangBuilder<Output>, 2138 2179 patterns: &'a Vec<Pattern<Arc<Type>>>, 2139 2180 clause: &'a Clause<TypedExpr, Arc<Type>>, 2140 2181 ) { 2141 - let clause_pattern = eaf.start_case_clause(); 2182 + let clause_pattern = builder.start_case_clause(); 2142 2183 2143 2184 // We start by generating the case clause pattern. If we're matching on 2144 2185 // multiple subjects (and so patterns has more that a single item) those ··· 2146 2187 // That's how we match on multiple things on the Erlang target. 2147 2188 let mut pattern_generator = PatternGenerator::new(self); 2148 2189 match patterns.as_slice() { 2149 - [pattern] => pattern_generator.pattern(eaf, pattern), 2190 + [pattern] => pattern_generator.pattern(builder, pattern), 2150 2191 patterns => { 2151 - let tuple = eaf.start_tuple_pattern(); 2192 + let tuple = builder.start_tuple_pattern(); 2152 2193 for pattern in patterns { 2153 - pattern_generator.pattern(eaf, pattern); 2194 + pattern_generator.pattern(builder, pattern); 2154 2195 } 2155 - eaf.end_tuple_pattern(tuple); 2196 + builder.end_tuple_pattern(tuple); 2156 2197 } 2157 2198 }; 2158 2199 2159 2200 let variables_to_add_later = pattern_generator.variables_to_add_later; 2160 2201 2161 - let clause_guards = eaf.end_clause_pattern(clause_pattern); 2202 + let clause_guards = builder.end_clause_pattern(clause_pattern); 2162 2203 if let Some(guard) = clause.guard.as_ref() { 2163 - self.clause_guard(eaf, guard, &variables_to_add_later); 2204 + self.clause_guard(builder, guard, &variables_to_add_later); 2164 2205 } 2165 2206 2166 2207 // Finally we can generate the clause body. If the clause is 2167 2208 // followed by a single block then we want it to be a statements 2168 2209 // sequence (and not wrapped in a begin ... end block as we usually 2169 2210 // would when generating code for a block expression). 2170 - let clause_body = eaf.end_clause_guards(clause_guards); 2171 - self.pattern_assignments(eaf, variables_to_add_later); 2211 + let clause_body = builder.end_clause_guards(clause_guards); 2212 + self.pattern_assignments(builder, variables_to_add_later); 2172 2213 if let TypedExpr::Block { statements, .. } = &clause.then { 2173 - self.statement_sequence(eaf, statements); 2214 + self.statement_sequence(builder, statements); 2174 2215 } else { 2175 - self.expr(eaf, &clause.then); 2216 + self.expr(builder, &clause.then); 2176 2217 } 2177 - eaf.end_clause_body(clause_body); 2218 + builder.end_clause_body(clause_body); 2178 2219 } 2179 2220 2180 2221 /// Erlang doesn't have a special constant declaration syntax; so each Gleam ··· 2182 2223 /// 2183 2224 /// This function produces the code of a constant expression. 2184 2225 /// 2185 - fn inlined_constant<Output>(&mut self, eaf: &mut impl Eaf<Output>, literal: &'a TypedConstant) { 2226 + fn inlined_constant<Output>( 2227 + &mut self, 2228 + builder: &mut impl ErlangBuilder<Output>, 2229 + literal: &'a TypedConstant, 2230 + ) { 2186 2231 match literal { 2187 - Constant::Int { int_value, .. } => eaf.int(int_value.clone()), 2188 - Constant::Float { float_value, .. } => eaf.float(float_value.value()), 2189 - Constant::String { value, .. } => eaf.string(value), 2232 + Constant::Int { int_value, .. } => builder.int(int_value.clone()), 2233 + Constant::Float { float_value, .. } => builder.float(float_value.value()), 2234 + Constant::String { value, .. } => builder.string(value), 2190 2235 Constant::Var { 2191 2236 name, constructor, .. 2192 2237 } => self.var( 2193 - eaf, 2238 + builder, 2194 2239 name, 2195 2240 constructor 2196 2241 .as_ref() ··· 2198 2243 ), 2199 2244 2200 2245 Constant::Tuple { elements, .. } => { 2201 - let tuple = eaf.start_tuple(); 2246 + let tuple = builder.start_tuple(); 2202 2247 for element in elements { 2203 - self.inlined_constant(eaf, element) 2248 + self.inlined_constant(builder, element) 2204 2249 } 2205 - eaf.end_tuple(tuple); 2250 + builder.end_tuple(tuple); 2206 2251 } 2207 2252 2208 2253 Constant::List { elements, tail, .. } => { 2209 2254 for element in elements { 2210 - eaf.cons_list(); 2211 - self.inlined_constant(eaf, element) 2255 + builder.cons_list(); 2256 + self.inlined_constant(builder, element) 2212 2257 } 2213 2258 match tail { 2214 2259 // If there's no tail we simply add an empty list cell to 2215 2260 // end the cons list. 2216 - None => eaf.empty_list(), 2261 + None => builder.empty_list(), 2217 2262 Some(tail) => match tail.list_elements() { 2218 2263 // If there's a tail and we don't statically know the 2219 2264 // elements it's made of, we add it as a regular Erlang 2220 2265 // tail and it will be `[1, 2 | Tail]`. 2221 - None => self.inlined_constant(eaf, tail), 2266 + None => self.inlined_constant(builder, tail), 2222 2267 // But if we can tell it has some fixed amount of 2223 2268 // constant elements, then those are inlined too! 2224 2269 Some(list_elements) => { 2225 2270 for element in list_elements { 2226 - eaf.cons_list(); 2227 - self.inlined_constant(eaf, element); 2271 + builder.cons_list(); 2272 + self.inlined_constant(builder, element); 2228 2273 } 2229 - eaf.empty_list(); 2274 + builder.empty_list(); 2230 2275 } 2231 2276 }, 2232 2277 } 2233 2278 } 2234 2279 2235 2280 Constant::BitArray { segments, .. } => { 2236 - let bit_array = eaf.start_bit_array(); 2281 + let bit_array = builder.start_bit_array(); 2237 2282 for segment in segments { 2238 - self.bit_array_constant_segment(eaf, segment); 2283 + self.bit_array_constant_segment(builder, segment); 2239 2284 } 2240 - eaf.end_bit_array(bit_array); 2285 + builder.end_bit_array(bit_array); 2241 2286 } 2242 2287 2243 2288 Constant::Record { ··· 2251 2296 // This is a regular record call, we're building a record as 2252 2297 // usual as a tagged tuple. 2253 2298 Some(arguments) => { 2254 - let tuple = eaf.start_tuple(); 2255 - eaf.atom(&to_snake_case(&tag)); 2299 + let tuple = builder.start_tuple(); 2300 + builder.atom(&to_snake_case(&tag)); 2256 2301 for argument in arguments { 2257 - self.inlined_constant(eaf, &argument.value); 2302 + self.inlined_constant(builder, &argument.value); 2258 2303 } 2259 - eaf.end_tuple(tuple); 2304 + builder.end_tuple(tuple); 2260 2305 } 2261 2306 // Otherwise we are either referencing a record constructor 2262 2307 // function, or building a record that has no fields: ··· 2274 2319 // ``` 2275 2320 None => match type_::collapse_links(type_.clone()).deref() { 2276 2321 Type::Named { .. } | Type::Var { .. } | Type::Tuple { .. } => { 2277 - eaf.atom(&to_snake_case(&tag)) 2322 + builder.atom(&to_snake_case(&tag)) 2278 2323 } 2279 2324 Type::Fn { arguments, .. } => { 2280 - self.record_builder_anonymous_function(eaf, &tag, arguments.len()) 2325 + self.record_builder_anonymous_function(builder, &tag, arguments.len()) 2281 2326 } 2282 2327 }, 2283 2328 } 2284 2329 } 2285 2330 2286 2331 Constant::StringConcatenation { left, right, .. } => { 2287 - self.constant_string_concatenate(eaf, left, right) 2332 + self.constant_string_concatenate(builder, left, right) 2288 2333 } 2289 2334 2290 2335 Constant::RecordUpdate { .. } => { ··· 2299 2344 2300 2345 fn bit_array_constant_segment<Output>( 2301 2346 &mut self, 2302 - eaf: &mut impl Eaf<Output>, 2347 + builder: &mut impl ErlangBuilder<Output>, 2303 2348 segment: &'a TypedConstantBitArraySegment, 2304 2349 ) { 2305 - eaf.bit_array_segment(); 2306 - self.inlined_constant(eaf, &segment.value); 2350 + builder.bit_array_segment(); 2351 + self.inlined_constant(builder, &segment.value); 2307 2352 match segment.size() { 2308 2353 Some(TypedConstant::Int { int_value, .. }) if int_value.is_negative() => { 2309 - eaf.int(BigInt::ZERO) 2354 + builder.int(BigInt::ZERO) 2310 2355 } 2311 - Some(size) => self.inlined_constant(eaf, size), 2312 - None => eaf.atom("default"), 2356 + Some(size) => self.inlined_constant(builder, size), 2357 + None => builder.atom("default"), 2313 2358 }; 2314 - self.bit_array_segment_specifiers(eaf, segment); 2359 + self.bit_array_segment_specifiers(builder, segment); 2315 2360 } 2316 2361 2317 2362 fn bit_array_segment_specifiers<Output, Expr>( 2318 2363 &self, 2319 - eaf: &mut impl Eaf<Output>, 2364 + builder: &mut impl ErlangBuilder<Output>, 2320 2365 segment: &'a BitArraySegment<Expr, Arc<Type>>, 2321 2366 ) { 2322 2367 let options = segment.options.iter(); 2323 - eaf.bit_array_segment_specifiers(options.filter_map(|option| match option { 2368 + builder.bit_array_segment_specifiers(options.filter_map(|option| match option { 2324 2369 BitArrayOption::Utf8 { .. } | BitArrayOption::Utf8Codepoint { .. } => { 2325 2370 Some(BitArraySegmentSpecifier::Utf8) 2326 2371 } ··· 2346 2391 2347 2392 fn constant_string_concatenate<Output>( 2348 2393 &mut self, 2349 - eaf: &mut impl Eaf<Output>, 2394 + builder: &mut impl ErlangBuilder<Output>, 2350 2395 left: &'a TypedConstant, 2351 2396 right: &'a TypedConstant, 2352 2397 ) { ··· 2354 2399 items.push_back(left); 2355 2400 items.push_back(right); 2356 2401 2357 - let bit_array = eaf.start_bit_array(); 2402 + let bit_array = builder.start_bit_array(); 2358 2403 while let Some(segment) = items.pop_front() { 2359 2404 match segment { 2360 2405 // When concatenating constant strings we flatten out all ··· 2401 2446 | Constant::Todo { .. } => (), 2402 2447 } 2403 2448 2404 - eaf.bit_array_segment(); 2405 - self.inlined_constant(eaf, segment); 2406 - eaf.atom("default"); 2407 - eaf.bit_array_segment_specifiers([BitArraySegmentSpecifier::Utf8]); 2449 + builder.bit_array_segment(); 2450 + self.inlined_constant(builder, segment); 2451 + builder.atom("default"); 2452 + builder.bit_array_segment_specifiers([BitArraySegmentSpecifier::Utf8]); 2408 2453 } 2409 - eaf.end_bit_array(bit_array); 2454 + builder.end_bit_array(bit_array); 2410 2455 } 2411 2456 2412 2457 fn string_concatenate<Output>( 2413 2458 &mut self, 2414 - eaf: &mut impl Eaf<Output>, 2459 + builder: &mut impl ErlangBuilder<Output>, 2415 2460 left: &'a TypedExpr, 2416 2461 right: &'a TypedExpr, 2417 2462 ) { 2418 - let bit_array = eaf.start_bit_array(); 2419 - self.string_concatenate_argument(eaf, left); 2420 - self.string_concatenate_argument(eaf, right); 2421 - eaf.end_bit_array(bit_array); 2463 + let bit_array = builder.start_bit_array(); 2464 + self.string_concatenate_argument(builder, left); 2465 + self.string_concatenate_argument(builder, right); 2466 + builder.end_bit_array(bit_array); 2422 2467 } 2423 2468 2424 2469 fn string_concatenate_argument<Output>( 2425 2470 &mut self, 2426 - eaf: &mut impl Eaf<Output>, 2471 + builder: &mut impl ErlangBuilder<Output>, 2427 2472 value: &'a TypedExpr, 2428 2473 ) { 2429 2474 // String concatenation is basically building a bit array with two ··· 2432 2477 // the `/utf8` specifier instead! 2433 2478 // In both cases the size is alwaus automatic, so we generate the 2434 2479 // `default` atom. 2435 - eaf.bit_array_segment(); 2436 - self.maybe_block_expr(eaf, value); 2437 - eaf.atom("default"); 2438 - eaf.bit_array_segment_specifiers(if produces_literal_string(value) { 2480 + builder.bit_array_segment(); 2481 + self.maybe_block_expr(builder, value); 2482 + builder.atom("default"); 2483 + builder.bit_array_segment_specifiers(if produces_literal_string(value) { 2439 2484 [BitArraySegmentSpecifier::Utf8] 2440 2485 } else { 2441 2486 [BitArraySegmentSpecifier::Binary] ··· 2444 2489 2445 2490 fn bin_op<Output>( 2446 2491 &mut self, 2447 - eaf: &mut impl Eaf<Output>, 2492 + builder: &mut impl ErlangBuilder<Output>, 2448 2493 name: &'a BinOp, 2449 2494 left: &'a TypedExpr, 2450 2495 right: &'a TypedExpr, ··· 2464 2509 2465 2510 // Division needs some extra case, in Gleam dividing by 0 results 2466 2511 // in 0; while in Erlang that's an exception. 2467 - BinOp::DivFloat => return self.float_division(eaf, left, right), 2468 - BinOp::DivInt => return self.int_division(eaf, left, right, "div"), 2469 - BinOp::RemainderInt => return self.int_division(eaf, left, right, "rem"), 2512 + BinOp::DivFloat => return self.float_division(builder, left, right), 2513 + BinOp::DivInt => return self.int_division(builder, left, right, "div"), 2514 + BinOp::RemainderInt => return self.int_division(builder, left, right, "rem"), 2470 2515 2471 2516 // String concatenation is not a binop at all! It's just building a 2472 2517 // bit array. 2473 - BinOp::Concatenate => return self.string_concatenate(eaf, left, right), 2518 + BinOp::Concatenate => return self.string_concatenate(builder, left, right), 2474 2519 }; 2475 2520 2476 - eaf.binary_operator(operator); 2477 - self.maybe_block_expr(eaf, left); 2478 - self.maybe_block_expr(eaf, right); 2521 + builder.binary_operator(operator); 2522 + self.maybe_block_expr(builder, left); 2523 + self.maybe_block_expr(builder, right); 2479 2524 } 2480 2525 2481 2526 fn float_division<Output>( 2482 2527 &mut self, 2483 - eaf: &mut impl Eaf<Output>, 2528 + builder: &mut impl ErlangBuilder<Output>, 2484 2529 left: &'a TypedExpr, 2485 2530 right: &'a TypedExpr, 2486 2531 ) { 2487 2532 match how_to_divide(left, right) { 2488 - HowToDivide::ReplaceWithZero => eaf.float(0.0), 2533 + HowToDivide::ReplaceWithZero => builder.float(0.0), 2489 2534 HowToDivide::EvaluateLeftAndReturnZero => { 2490 2535 // We first evaluate the left hand side, and ignore its return 2491 2536 // value, and then we return zero directly! 2492 - self.maybe_block_expr(eaf, left); 2493 - eaf.float(0.0); 2537 + self.maybe_block_expr(builder, left); 2538 + builder.float(0.0); 2494 2539 } 2495 2540 HowToDivide::PlainErlangDivision => { 2496 - eaf.binary_operator("/"); 2497 - self.maybe_block_expr(eaf, left); 2498 - self.maybe_block_expr(eaf, right); 2541 + builder.binary_operator("/"); 2542 + self.maybe_block_expr(builder, left); 2543 + self.maybe_block_expr(builder, right); 2499 2544 } 2500 2545 HowToDivide::MatchOnRight { 2501 2546 is_left_hand_side_pure, ··· 2504 2549 // result in a variable to use later. 2505 2550 let left_name = if !is_left_hand_side_pure { 2506 2551 let left_name = self.new_throwaway_variable(); 2507 - eaf.match_operator(); 2508 - eaf.variable_pattern(&left_name); 2509 - self.maybe_block_expr(eaf, left); 2552 + builder.match_operator(); 2553 + builder.variable_pattern(&left_name); 2554 + self.maybe_block_expr(builder, left); 2510 2555 Some(left_name) 2511 2556 } else { 2512 2557 None 2513 2558 }; 2514 2559 2515 - let case = eaf.start_case(); 2516 - self.maybe_block_expr(eaf, right); 2560 + let case = builder.start_case(); 2561 + self.maybe_block_expr(builder, right); 2517 2562 2518 2563 // +0.0 -> +0.0 2519 - let clause = eaf.start_case_clause(); 2520 - eaf.float_pattern(0.0); 2521 - let guards = eaf.end_clause_pattern(clause); 2522 - let body = eaf.end_clause_guards(guards); 2523 - eaf.float(0.0); 2524 - eaf.end_clause_body(body); 2564 + let clause = builder.start_case_clause(); 2565 + builder.float_pattern(0.0); 2566 + let guards = builder.end_clause_pattern(clause); 2567 + let body = builder.end_clause_guards(guards); 2568 + builder.float(0.0); 2569 + builder.end_clause_body(body); 2525 2570 2526 2571 // -0.0 -> -0.0 2527 - let clause = eaf.start_case_clause(); 2528 - eaf.float_pattern(-0.0); 2529 - let guards = eaf.end_clause_pattern(clause); 2530 - let body = eaf.end_clause_guards(guards); 2531 - eaf.float(-0.0); 2532 - eaf.end_clause_body(body); 2572 + let clause = builder.start_case_clause(); 2573 + builder.float_pattern(-0.0); 2574 + let guards = builder.end_clause_pattern(clause); 2575 + let body = builder.end_clause_guards(guards); 2576 + builder.float(-0.0); 2577 + builder.end_clause_body(body); 2533 2578 2534 2579 // _value -> left / _value 2535 2580 let denominator = self.new_throwaway_variable(); 2536 - let clause = eaf.start_case_clause(); 2537 - eaf.variable_pattern(&denominator); 2538 - let guards = eaf.end_clause_pattern(clause); 2539 - let body = eaf.end_clause_guards(guards); 2540 - eaf.binary_operator("/"); 2581 + let clause = builder.start_case_clause(); 2582 + builder.variable_pattern(&denominator); 2583 + let guards = builder.end_clause_pattern(clause); 2584 + let body = builder.end_clause_guards(guards); 2585 + builder.binary_operator("/"); 2541 2586 // If we had bound the left hand side to a variabe we just 2542 2587 // reference it, otherwise we will generate the code for the 2543 2588 // numerator. 2544 2589 if let Some(left_name) = left_name { 2545 - eaf.variable(&left_name); 2590 + builder.variable(&left_name); 2546 2591 } else { 2547 - self.maybe_block_expr(eaf, left); 2592 + self.maybe_block_expr(builder, left); 2548 2593 } 2549 - eaf.variable(&denominator); 2550 - eaf.end_clause_body(body); 2594 + builder.variable(&denominator); 2595 + builder.end_clause_body(body); 2551 2596 2552 - eaf.end_case(case); 2597 + builder.end_case(case); 2553 2598 } 2554 2599 } 2555 - 2556 - //if right.is_non_zero_compile_time_number() { 2557 - // eaf.binary_operator("/"); 2558 - // self.maybe_block_expr(eaf, left); 2559 - // self.maybe_block_expr(eaf, right); 2560 - //} else if left.is_literal() && right.is_zero_compile_time_number() { 2561 - // eaf.float(0.0); 2562 - //} else { 2563 - // let left = { 2564 - // self.expr(eaf, left); 2565 - // nil() 2566 - // }; 2567 - // let right = { 2568 - // self.expr(eaf, right); 2569 - // nil() 2570 - // }; 2571 - // let denominator = self.new_throwaway_variable(); 2572 - // let clauses = docvec![ 2573 - // line(), 2574 - // "+0.0 -> +0.0;", 2575 - // line(), 2576 - // "-0.0 -> -0.0;", 2577 - // line(), 2578 - // denominator.clone(), 2579 - // " -> ", 2580 - // binop_documents(left, "/", denominator.to_doc()) 2581 - // ]; 2582 - // let _ = docvec!["case ", right, " of", clauses.nest(INDENT), line(), "end"]; 2583 - //} 2584 2600 } 2585 2601 2586 2602 fn int_division<Output>( 2587 2603 &mut self, 2588 - eaf: &mut impl Eaf<Output>, 2604 + builder: &mut impl ErlangBuilder<Output>, 2589 2605 left: &'a TypedExpr, 2590 2606 right: &'a TypedExpr, 2591 2607 op: &'static str, 2592 2608 ) { 2593 2609 match how_to_divide(left, right) { 2594 - HowToDivide::ReplaceWithZero => eaf.int(BigInt::ZERO), 2610 + HowToDivide::ReplaceWithZero => builder.int(BigInt::ZERO), 2595 2611 HowToDivide::EvaluateLeftAndReturnZero => { 2596 2612 // We first evaluate the left hand side, and ignore its return 2597 2613 // value, and then we return zero directly! 2598 - self.maybe_block_expr(eaf, left); 2599 - eaf.int(BigInt::ZERO); 2614 + self.maybe_block_expr(builder, left); 2615 + builder.int(BigInt::ZERO); 2600 2616 } 2601 2617 HowToDivide::PlainErlangDivision => { 2602 - eaf.binary_operator(op); 2603 - self.maybe_block_expr(eaf, left); 2604 - self.maybe_block_expr(eaf, right); 2618 + builder.binary_operator(op); 2619 + self.maybe_block_expr(builder, left); 2620 + self.maybe_block_expr(builder, right); 2605 2621 } 2606 2622 HowToDivide::MatchOnRight { 2607 2623 is_left_hand_side_pure, ··· 2622 2638 // 2623 2639 let left_name = if !is_left_hand_side_pure { 2624 2640 let left_name = self.new_throwaway_variable(); 2625 - eaf.match_operator(); 2626 - eaf.variable_pattern(&left_name); 2627 - self.maybe_block_expr(eaf, left); 2641 + builder.match_operator(); 2642 + builder.variable_pattern(&left_name); 2643 + self.maybe_block_expr(builder, left); 2628 2644 Some(left_name) 2629 2645 } else { 2630 2646 None 2631 2647 }; 2632 2648 2633 - let case = eaf.start_case(); 2634 - self.maybe_block_expr(eaf, right); 2649 + let case = builder.start_case(); 2650 + self.maybe_block_expr(builder, right); 2635 2651 2636 2652 // 0 -> 0 2637 - let clause = eaf.start_case_clause(); 2638 - eaf.int_pattern(BigInt::ZERO); 2639 - let guards = eaf.end_clause_pattern(clause); 2640 - let body = eaf.end_clause_guards(guards); 2641 - eaf.int(BigInt::ZERO); 2642 - eaf.end_clause_body(body); 2653 + let clause = builder.start_case_clause(); 2654 + builder.int_pattern(BigInt::ZERO); 2655 + let guards = builder.end_clause_pattern(clause); 2656 + let body = builder.end_clause_guards(guards); 2657 + builder.int(BigInt::ZERO); 2658 + builder.end_clause_body(body); 2643 2659 2644 2660 // _value -> left div _value 2645 2661 let denominator = self.new_throwaway_variable(); 2646 - let clause = eaf.start_case_clause(); 2647 - eaf.variable_pattern(&denominator); 2648 - let guards = eaf.end_clause_pattern(clause); 2649 - let body = eaf.end_clause_guards(guards); 2650 - eaf.binary_operator(op); 2662 + let clause = builder.start_case_clause(); 2663 + builder.variable_pattern(&denominator); 2664 + let guards = builder.end_clause_pattern(clause); 2665 + let body = builder.end_clause_guards(guards); 2666 + builder.binary_operator(op); 2651 2667 // If we had bound the left hand side to a variabe we just 2652 2668 // reference it, otherwise we will generate the code for the 2653 2669 // numerator. 2654 2670 if let Some(left_name) = left_name { 2655 - eaf.variable(&left_name); 2671 + builder.variable(&left_name); 2656 2672 } else { 2657 - self.maybe_block_expr(eaf, left); 2673 + self.maybe_block_expr(builder, left); 2658 2674 } 2659 - eaf.variable(&denominator); 2660 - eaf.end_clause_body(body); 2675 + builder.variable(&denominator); 2676 + builder.end_clause_body(body); 2661 2677 2662 - eaf.end_case(case); 2678 + builder.end_case(case); 2663 2679 } 2664 2680 } 2665 2681 } ··· 2673 2689 /// 2674 2690 fn bit_array_expression_segment<Output>( 2675 2691 &mut self, 2676 - eaf: &mut impl Eaf<Output>, 2692 + builder: &mut impl ErlangBuilder<Output>, 2677 2693 segment: &'a TypedExprBitArraySegment, 2678 2694 ) { 2679 2695 // Literal strings can have the `utf8`, `utf16`, or `utf32` options just ··· 2730 2746 ExpressionSegmentStringEncoding::Utf8 => { 2731 2747 // Gleam strings are utf8 encoded binaries, so we just need 2732 2748 // to add the binary option and we can call it a day. 2733 - eaf.bit_array_segment(); 2734 - self.maybe_block_expr(eaf, &segment.value); 2735 - eaf.atom("default"); 2736 - eaf.bit_array_segment_specifiers([BitArraySegmentSpecifier::Binary]); 2749 + builder.bit_array_segment(); 2750 + self.maybe_block_expr(builder, &segment.value); 2751 + builder.atom("default"); 2752 + builder.bit_array_segment_specifiers([BitArraySegmentSpecifier::Binary]); 2737 2753 return; 2738 2754 } 2739 2755 }; 2740 2756 2741 - eaf.bit_array_segment(); 2757 + builder.bit_array_segment(); 2742 2758 2743 2759 // For utf16 and utf32 we need an explicit conversion using erlang's 2744 2760 // `unicode:characters_to_binary`. The segment value will be ··· 2747 2763 // unicode:characters_to_binary(<segment_value>, utf8, {utf16, big}) 2748 2764 // ``` 2749 2765 let call = 2750 - eaf.start_remote_call(ErlangModuleName::new("unicode"), "characters_to_binary"); 2766 + builder.start_remote_call(ErlangModuleName::new("unicode"), "characters_to_binary"); 2751 2767 { 2752 - self.maybe_block_expr(eaf, &segment.value); 2753 - eaf.atom("utf8"); 2754 - let tuple = eaf.start_tuple(); 2755 - eaf.atom(&format!("utf{size}")); 2768 + self.maybe_block_expr(builder, &segment.value); 2769 + builder.atom("utf8"); 2770 + let tuple = builder.start_tuple(); 2771 + builder.atom(&format!("utf{size}")); 2756 2772 match endiannes { 2757 - Endianness::Big => eaf.atom("big"), 2758 - Endianness::Little => eaf.atom("little"), 2773 + Endianness::Big => builder.atom("big"), 2774 + Endianness::Little => builder.atom("little"), 2759 2775 } 2760 - eaf.end_tuple(tuple); 2776 + builder.end_tuple(tuple); 2761 2777 } 2762 - eaf.end_call(call); 2778 + builder.end_call(call); 2763 2779 2764 - eaf.atom("default"); 2765 - eaf.bit_array_segment_specifiers([BitArraySegmentSpecifier::Binary]); 2780 + builder.atom("default"); 2781 + builder.bit_array_segment_specifiers([BitArraySegmentSpecifier::Binary]); 2766 2782 } else { 2767 2783 // If the bit array segment doesn't need any special handling we use the 2768 2784 // regular printing functions to format its value and options. 2769 - eaf.bit_array_segment(); 2770 - self.maybe_block_expr(eaf, &segment.value); 2771 - self.bit_array_expression_segment_size(eaf, segment); 2772 - self.bit_array_segment_specifiers(eaf, segment); 2785 + builder.bit_array_segment(); 2786 + self.maybe_block_expr(builder, &segment.value); 2787 + self.bit_array_expression_segment_size(builder, segment); 2788 + self.bit_array_segment_specifiers(builder, segment); 2773 2789 } 2774 2790 } 2775 2791 ··· 2780 2796 /// size! 2781 2797 fn bit_array_expression_segment_size<Output>( 2782 2798 &mut self, 2783 - eaf: &mut impl Eaf<Output>, 2799 + builder: &mut impl ErlangBuilder<Output>, 2784 2800 segment: &'a TypedExprBitArraySegment, 2785 2801 ) { 2786 2802 let Some(size) = segment.size() else { 2787 - eaf.atom("default"); 2803 + builder.atom("default"); 2788 2804 return; 2789 2805 }; 2790 2806 ··· 2793 2809 // negative value must be turned to zero instead: 2794 2810 if let TypedExpr::Int { int_value, .. } = &size { 2795 2811 if int_value.is_negative() { 2796 - eaf.int(BigInt::ZERO) 2812 + builder.int(BigInt::ZERO) 2797 2813 } else { 2798 - eaf.int(int_value.clone()); 2814 + builder.int(int_value.clone()); 2799 2815 } 2800 2816 } else { 2801 - let call = eaf.start_remote_call(ErlangModuleName::new("erlang"), "max"); 2802 - eaf.int(BigInt::ZERO); 2803 - self.maybe_block_expr(eaf, size); 2804 - eaf.end_call(call); 2817 + let call = builder.start_remote_call(ErlangModuleName::new("erlang"), "max"); 2818 + builder.int(BigInt::ZERO); 2819 + self.maybe_block_expr(builder, size); 2820 + builder.end_call(call); 2805 2821 } 2806 2822 } 2807 2823 2808 2824 fn clause_guard<Output>( 2809 2825 &mut self, 2810 - eaf: &mut impl Eaf<Output>, 2826 + builder: &mut impl ErlangBuilder<Output>, 2811 2827 guard: &'a TypedClauseGuard, 2812 2828 assignments: &HashMap<EcoString, AliasedLiteral>, 2813 2829 ) { 2814 2830 match guard { 2815 2831 ClauseGuard::Invalid { .. } => unreachable!("invalid guard made it to code generation"), 2816 2832 2817 - ClauseGuard::ModuleSelect { literal, .. } => self.inlined_constant(eaf, literal), 2818 - ClauseGuard::Constant(constant) => self.inlined_constant(eaf, constant), 2833 + ClauseGuard::ModuleSelect { literal, .. } => self.inlined_constant(builder, literal), 2834 + ClauseGuard::Constant(constant) => self.inlined_constant(builder, constant), 2819 2835 2820 - ClauseGuard::Block { value, .. } => self.clause_guard(eaf, value, assignments), 2836 + ClauseGuard::Block { value, .. } => self.clause_guard(builder, value, assignments), 2821 2837 2822 2838 ClauseGuard::TupleIndex { tuple, index, .. } => { 2823 - self.clause_guard_tuple_index(eaf, tuple, *index) 2839 + self.clause_guard_tuple_index(builder, tuple, *index) 2824 2840 } 2825 2841 2826 2842 ClauseGuard::FieldAccess { 2827 2843 container, index, .. 2828 2844 } => self.clause_guard_tuple_index( 2829 - eaf, 2845 + builder, 2830 2846 container, 2831 2847 index.expect("Unable to find index") + 1, 2832 2848 ), 2833 2849 ClauseGuard::Not { expression, .. } => { 2834 - eaf.unary_operator("not"); 2835 - self.clause_guard(eaf, expression, assignments); 2850 + builder.unary_operator("not"); 2851 + self.clause_guard(builder, expression, assignments); 2836 2852 } 2837 2853 2838 2854 ClauseGuard::BinaryOperator { ··· 2857 2873 BinOp::DivInt => "div", 2858 2874 BinOp::RemainderInt => "rem", 2859 2875 BinOp::Concatenate => { 2860 - return self.clause_guard_string_concatenate(eaf, left, right, assignments); 2876 + return self.clause_guard_string_concatenate( 2877 + builder, 2878 + left, 2879 + right, 2880 + assignments, 2881 + ); 2861 2882 } 2862 2883 }; 2863 2884 2864 - eaf.binary_operator(operator); 2865 - self.clause_guard(eaf, left, assignments); 2866 - self.clause_guard(eaf, right, assignments); 2885 + builder.binary_operator(operator); 2886 + self.clause_guard(builder, left, assignments); 2887 + self.clause_guard(builder, right, assignments); 2867 2888 } 2868 2889 2869 2890 // Only local variables are supported and the typer ensures that all ··· 2878 2899 // generated code the variable is only defined later, so just 2879 2900 // referencing its name would result in an error. 2880 2901 match assignments.get(name) { 2881 - Some(AliasedLiteral::String { value, .. }) => eaf.string(value), 2882 - Some(AliasedLiteral::Int { value, .. }) => eaf.int(value.clone()), 2883 - Some(AliasedLiteral::Float { value, .. }) => eaf.float(value.value()), 2902 + Some(AliasedLiteral::String { value, .. }) => builder.string(value), 2903 + Some(AliasedLiteral::Int { value, .. }) => builder.int(value.clone()), 2904 + Some(AliasedLiteral::Float { value, .. }) => builder.float(value.value()), 2884 2905 None => { 2885 - eaf.variable(&self.local_var_name(definition_location)); 2906 + builder.variable(&self.local_var_name(definition_location)); 2886 2907 } 2887 2908 } 2888 2909 } ··· 2891 2912 2892 2913 fn clause_guard_tuple_index<Output>( 2893 2914 &mut self, 2894 - eaf: &mut impl Eaf<Output>, 2915 + builder: &mut impl ErlangBuilder<Output>, 2895 2916 tuple: &'a TypedClauseGuard, 2896 2917 index: u64, 2897 2918 ) { 2898 - let call = eaf.start_remote_call(ErlangModuleName::new("erlang"), "element"); 2899 - eaf.int((index + 1).into()); 2900 - self.clause_guard(eaf, tuple, &HashMap::new()); 2901 - eaf.end_call(call); 2919 + let call = builder.start_remote_call(ErlangModuleName::new("erlang"), "element"); 2920 + builder.int((index + 1).into()); 2921 + self.clause_guard(builder, tuple, &HashMap::new()); 2922 + builder.end_call(call); 2902 2923 } 2903 2924 2904 2925 fn clause_guard_string_concatenate<Output>( 2905 2926 &mut self, 2906 - eaf: &mut impl Eaf<Output>, 2927 + builder: &mut impl ErlangBuilder<Output>, 2907 2928 left: &'a TypedClauseGuard, 2908 2929 right: &'a TypedClauseGuard, 2909 2930 assignments: &HashMap<EcoString, AliasedLiteral>, 2910 2931 ) { 2911 - let bit_array = eaf.start_bit_array(); 2912 - self.clause_guard_string_concatenate_argument(eaf, left, assignments); 2913 - self.clause_guard_string_concatenate_argument(eaf, right, assignments); 2914 - eaf.end_bit_array(bit_array); 2932 + let bit_array = builder.start_bit_array(); 2933 + self.clause_guard_string_concatenate_argument(builder, left, assignments); 2934 + self.clause_guard_string_concatenate_argument(builder, right, assignments); 2935 + builder.end_bit_array(bit_array); 2915 2936 } 2916 2937 2917 2938 fn clause_guard_string_concatenate_argument<Output>( 2918 2939 &mut self, 2919 - eaf: &mut impl Eaf<Output>, 2940 + builder: &mut impl ErlangBuilder<Output>, 2920 2941 guard: &'a TypedClauseGuard, 2921 2942 assignments: &HashMap<EcoString, AliasedLiteral>, 2922 2943 ) { ··· 2926 2947 // the `/utf8` specifier instead! 2927 2948 // In both cases the size is alwaus automatic, so we generate the 2928 2949 // `default` atom. 2929 - eaf.bit_array_segment(); 2930 - self.clause_guard(eaf, guard, assignments); 2931 - eaf.atom("default"); 2932 - eaf.bit_array_segment_specifiers(if guard_produces_literal_string(guard) { 2950 + builder.bit_array_segment(); 2951 + self.clause_guard(builder, guard, assignments); 2952 + builder.atom("default"); 2953 + builder.bit_array_segment_specifiers(if guard_produces_literal_string(guard) { 2933 2954 [BitArraySegmentSpecifier::Utf8] 2934 2955 } else { 2935 2956 [BitArraySegmentSpecifier::Binary] ··· 2963 2984 /// 2964 2985 fn record_builder_anonymous_function<Output>( 2965 2986 &mut self, 2966 - eaf: &mut impl Eaf<Output>, 2987 + builder: &mut impl ErlangBuilder<Output>, 2967 2988 record_name: &str, 2968 2989 arguments: usize, 2969 2990 ) { 2970 2991 let arguments = (0..arguments) 2971 2992 .map(|_| self.new_throwaway_variable()) 2972 2993 .collect_vec(); 2973 - let function = eaf.start_anonymous_function(&arguments); 2994 + let function = builder.start_anonymous_function(&arguments); 2974 2995 2975 2996 if arguments.is_empty() { 2976 - eaf.atom(&to_snake_case(record_name)) 2997 + builder.atom(&to_snake_case(record_name)) 2977 2998 } else { 2978 - let tuple = eaf.start_tuple(); 2979 - eaf.atom(&to_snake_case(record_name)); 2999 + let tuple = builder.start_tuple(); 3000 + builder.atom(&to_snake_case(record_name)); 2980 3001 for argument in arguments { 2981 - eaf.variable(&argument); 3002 + builder.variable(&argument); 2982 3003 } 2983 - eaf.end_tuple(tuple) 3004 + builder.end_tuple(tuple) 2984 3005 } 2985 3006 2986 - eaf.end_function(function); 3007 + builder.end_function(function); 2987 3008 } 2988 3009 2989 3010 /// After generating a pattern we might have to generate additional variable ··· 2991 3012 /// This adds those variable to the current body. 2992 3013 fn pattern_assignments<Output>( 2993 3014 &mut self, 2994 - eaf: &mut impl Eaf<Output>, 3015 + builder: &mut impl ErlangBuilder<Output>, 2995 3016 variables_to_add_later: HashMap<EcoString, AliasedLiteral>, 2996 3017 ) { 2997 3018 let variables_to_add_later = variables_to_add_later ··· 2999 3020 .sorted_by(|(one, _), (other, _)| one.cmp(other)); 3000 3021 3001 3022 for (gleam_name, value) in variables_to_add_later { 3002 - eaf.match_operator(); 3023 + builder.match_operator(); 3003 3024 match value { 3004 3025 AliasedLiteral::String { location, value } => { 3005 - eaf.variable_pattern(&self.new_erlang_variable(&gleam_name, location)); 3006 - eaf.string(&value); 3026 + builder.variable_pattern(&self.new_erlang_variable(&gleam_name, location)); 3027 + builder.string(&value); 3007 3028 } 3008 3029 AliasedLiteral::Float { location, value } => { 3009 - eaf.variable_pattern(&self.new_erlang_variable(&gleam_name, location)); 3010 - eaf.float(value.value()); 3030 + builder.variable_pattern(&self.new_erlang_variable(&gleam_name, location)); 3031 + builder.float(value.value()); 3011 3032 } 3012 3033 AliasedLiteral::Int { location, value } => { 3013 - eaf.variable_pattern(&self.new_erlang_variable(&gleam_name, location)); 3014 - eaf.int(value.clone()); 3034 + builder.variable_pattern(&self.new_erlang_variable(&gleam_name, location)); 3035 + builder.int(value.clone()); 3015 3036 } 3016 3037 } 3017 3038 } ··· 3152 3173 } 3153 3174 }, 3154 3175 3155 - //TypedExpr::Fn { kind, body, .. } if kind.is_capture() => { 3156 - // if let Statement::Expression(TypedExpr::Call { 3157 - // fun, 3158 - // arguments: inner_arguments, 3159 - // .. 3160 - // }) = body.first() 3161 - // { 3162 - // let mut merged_arguments = Vec::with_capacity(inner_arguments.len()); 3163 - // for arg in inner_arguments { 3164 - // if let TypedExpr::Var { name, .. } = &arg.value 3165 - // && name == CAPTURE_VARIABLE 3166 - // { 3167 - // merged_arguments.push(arguments.swap_remove(0)) 3168 - // } else { 3169 - // merged_arguments.push(self.maybe_block_expr(eaf, &arg.value)) 3170 - // } 3171 - // } 3172 - // self.docs_arguments_call(eaf, fun, merged_arguments) 3173 - // } else { 3174 - // panic!("Erl printing: Capture was not a call") 3175 - // } 3176 - //} 3177 3176 TypedExpr::Fn { .. } 3178 3177 | TypedExpr::Call { .. } 3179 3178 | TypedExpr::Todo { .. } ··· 3264 3263 } 3265 3264 3266 3265 pub fn record_definition(record_name: &str, fields: &[(&str, Arc<Type>)]) -> String { 3267 - let mut eaf = PrettyEaf::new(None); 3266 + let mut builder = ErlangSourceBuilder::new(None); 3268 3267 3269 - let record = eaf.start_record_attribute(&to_snake_case(record_name)); 3268 + let record = builder.start_record_attribute(&to_snake_case(record_name)); 3270 3269 3271 3270 let type_printer = TypeGenerator::new("").var_as_any(); 3272 3271 for (field_name, field_type) in fields { 3273 - eaf.record_field(); 3274 - eaf.atom(field_name); 3275 - type_printer.type_(&mut eaf, field_type); 3272 + builder.record_field(); 3273 + builder.atom(field_name); 3274 + type_printer.type_(&mut builder, field_type); 3276 3275 } 3277 3276 3278 - eaf.end_record_attribute(record); 3279 - eaf.into_output() 3277 + builder.end_record_attribute(record); 3278 + builder.into_output() 3280 3279 } 3281 3280 3282 3281 pub fn module<'a>( ··· 3285 3284 root: &'a Utf8Path, 3286 3285 ) -> String { 3287 3286 let mut generator = Generator::new(module, line_numbers, root); 3288 - let mut eaf = PrettyEaf::new(Some(ErlangModuleName::new(&module.name))); 3289 - generator.module_document(&mut eaf); 3287 + let mut builder = ErlangSourceBuilder::new(Some(ErlangModuleName::new(&module.name))); 3288 + generator.module_document(&mut builder); 3290 3289 3291 - let mut output = eaf.into_output(); 3290 + let mut output = builder.into_output(); 3292 3291 if generator.echo_used { 3293 3292 output.push_str(std::include_str!("../templates/echo.erl")); 3294 3293 } ··· 3882 3881 self 3883 3882 } 3884 3883 3885 - pub fn type_<Output>(&self, eaf: &mut impl Eaf<Output>, type_: &Type) { 3884 + pub fn type_<Output>(&self, builder: &mut impl ErlangBuilder<Output>, type_: &Type) { 3886 3885 match type_ { 3887 - Type::Var { type_ } => self.type_variable(eaf, &type_.borrow()), 3886 + Type::Var { type_ } => self.type_variable(builder, &type_.borrow()), 3888 3887 Type::Named { 3889 3888 name, 3890 3889 module, 3891 3890 arguments, 3892 3891 .. 3893 - } if is_prelude_module(module) => self.prelude_type(eaf, name, arguments), 3892 + } if is_prelude_module(module) => self.prelude_type(builder, name, arguments), 3894 3893 Type::Named { 3895 3894 name, 3896 3895 module, 3897 3896 arguments, 3898 3897 .. 3899 - } => self.named_type(eaf, module.into(), name, arguments), 3898 + } => self.named_type(builder, module.into(), name, arguments), 3900 3899 Type::Fn { arguments, return_ } => { 3901 - let function_type = eaf.start_function_type(); 3900 + let function_type = builder.start_function_type(); 3902 3901 for argument in arguments { 3903 - self.type_(eaf, argument); 3902 + self.type_(builder, argument); 3904 3903 } 3905 - let function_type = eaf.end_function_type_arguments(function_type); 3906 - self.type_(eaf, return_); 3907 - eaf.end_function_type(function_type); 3904 + let function_type = builder.end_function_type_arguments(function_type); 3905 + self.type_(builder, return_); 3906 + builder.end_function_type(function_type); 3908 3907 } 3909 3908 Type::Tuple { elements } => { 3910 - let tuple = eaf.start_tuple_type(); 3909 + let tuple = builder.start_tuple_type(); 3911 3910 for element in elements { 3912 - self.type_(eaf, element) 3911 + self.type_(builder, element) 3913 3912 } 3914 - eaf.end_tuple_type(tuple); 3913 + builder.end_tuple_type(tuple); 3915 3914 } 3916 3915 } 3917 3916 } 3918 3917 3919 - fn type_variable<Output>(&self, eaf: &mut impl Eaf<Output>, type_: &TypeVar) { 3918 + fn type_variable<Output>(&self, builder: &mut impl ErlangBuilder<Output>, type_: &TypeVar) { 3920 3919 match type_ { 3921 - TypeVar::Link { type_ } => self.type_(eaf, type_), 3920 + TypeVar::Link { type_ } => self.type_(builder, type_), 3922 3921 TypeVar::Generic { id, .. } | TypeVar::Unbound { id, .. } => { 3923 3922 if self.var_as_any || self.type_variable_is_used_exactly_once(*id) { 3924 - let any = eaf.start_named_type("any"); 3925 - eaf.end_named_type(any); 3923 + let any = builder.start_named_type("any"); 3924 + builder.end_named_type(any); 3926 3925 } else { 3927 - eaf.type_variable(&id_to_type_var_str(*id)) 3926 + builder.type_variable(&id_to_type_var_str(*id)) 3928 3927 } 3929 3928 } 3930 3929 } ··· 3943 3942 3944 3943 fn prelude_type<Output>( 3945 3944 &self, 3946 - eaf: &mut impl Eaf<Output>, 3945 + builder: &mut impl ErlangBuilder<Output>, 3947 3946 name: &str, 3948 3947 arguments: &[Arc<Type>], 3949 3948 ) { 3950 3949 match name { 3951 - "Nil" => eaf.literal_atom_type("nil"), 3950 + "Nil" => builder.literal_atom_type("nil"), 3952 3951 "Int" | "UtfCodepoint" => { 3953 - let integer = eaf.start_named_type("integer"); 3954 - eaf.end_named_type(integer); 3952 + let integer = builder.start_named_type("integer"); 3953 + builder.end_named_type(integer); 3955 3954 } 3956 3955 "String" => { 3957 - let string = eaf.start_named_type("binary"); 3958 - eaf.end_named_type(string); 3956 + let string = builder.start_named_type("binary"); 3957 + builder.end_named_type(string); 3959 3958 } 3960 3959 "Bool" => { 3961 - let boolean = eaf.start_named_type("boolean"); 3962 - eaf.end_named_type(boolean); 3960 + let boolean = builder.start_named_type("boolean"); 3961 + builder.end_named_type(boolean); 3963 3962 } 3964 3963 "Float" => { 3965 - let float = eaf.start_named_type("float"); 3966 - eaf.end_named_type(float); 3964 + let float = builder.start_named_type("float"); 3965 + builder.end_named_type(float); 3967 3966 } 3968 3967 "BitArray" => { 3969 - let bitstring = eaf.start_named_type("bitstring"); 3970 - eaf.end_named_type(bitstring); 3968 + let bitstring = builder.start_named_type("bitstring"); 3969 + builder.end_named_type(bitstring); 3971 3970 } 3972 3971 "List" => { 3973 - let list = eaf.start_named_type("list"); 3972 + let list = builder.start_named_type("list"); 3974 3973 let list_item = arguments 3975 3974 .first() 3976 3975 .expect("prelude type list with no argument"); 3977 - self.type_(eaf, list_item); 3978 - eaf.end_named_type(list); 3976 + self.type_(builder, list_item); 3977 + builder.end_named_type(list); 3979 3978 } 3980 3979 "Result" => { 3981 3980 let [ok_type, error_type] = arguments else { 3982 3981 panic!("result type with no ok and err types") 3983 3982 }; 3984 3983 3985 - let result = eaf.start_union_type(); 3984 + let result = builder.start_union_type(); 3986 3985 3987 - let ok = eaf.start_tuple_type(); 3988 - eaf.literal_atom_type("ok"); 3989 - self.type_(eaf, ok_type); 3990 - eaf.end_tuple_type(ok); 3986 + let ok = builder.start_tuple_type(); 3987 + builder.literal_atom_type("ok"); 3988 + self.type_(builder, ok_type); 3989 + builder.end_tuple_type(ok); 3991 3990 3992 - let error = eaf.start_tuple_type(); 3993 - eaf.literal_atom_type("error"); 3994 - self.type_(eaf, error_type); 3995 - eaf.end_tuple_type(error); 3991 + let error = builder.start_tuple_type(); 3992 + builder.literal_atom_type("error"); 3993 + self.type_(builder, error_type); 3994 + builder.end_tuple_type(error); 3996 3995 3997 - eaf.end_union_type(result); 3996 + builder.end_union_type(result); 3998 3997 } 3999 3998 4000 3999 // Getting here should mean we either forgot a built-in type or there is a ··· 4005 4004 4006 4005 fn named_type<Output>( 4007 4006 &self, 4008 - eaf: &mut impl Eaf<Output>, 4007 + builder: &mut impl ErlangBuilder<Output>, 4009 4008 module: EcoString, 4010 4009 name: &str, 4011 4010 arguments: &[Arc<Type>], 4012 4011 ) { 4013 4012 let name = erl_safe_type_name(to_snake_case(name)); 4014 4013 let type_ = if self.current_module == module { 4015 - eaf.start_named_type(&name) 4014 + builder.start_named_type(&name) 4016 4015 } else { 4017 - eaf.start_remote_named_type(ErlangModuleName::new(&module), &name) 4016 + builder.start_remote_named_type(ErlangModuleName::new(&module), &name) 4018 4017 }; 4019 4018 4020 4019 for argument in arguments { 4021 - self.type_(eaf, argument) 4020 + self.type_(builder, argument) 4022 4021 } 4023 4022 4024 - eaf.end_named_type(type_); 4023 + builder.end_named_type(type_); 4025 4024 } 4026 4025 } 4027 4026
+84 -79
compiler-core/src/erlang/pattern.rs
··· 1 1 // SPDX-License-Identifier: Apache-2.0 2 2 // SPDX-FileCopyrightText: 2021 The Gleam contributors 3 3 4 - use erlang_abstract_format::BitArraySegmentSpecifier; 4 + use erlang_generation::BitArraySegmentSpecifier; 5 5 6 6 use crate::{analyse::Inferred, parse::LiteralFloatValue}; 7 7 ··· 129 129 130 130 pub(super) fn pattern<Output>( 131 131 &mut self, 132 - eaf: &mut impl Eaf<Output>, 132 + builder: &mut impl ErlangBuilder<Output>, 133 133 pattern: &'a TypedPattern, 134 134 ) { 135 135 match pattern { 136 - Pattern::Discard { .. } => eaf.discard_pattern(), 137 - Pattern::Float { float_value, .. } => eaf.float_pattern(float_value.value()), 138 - Pattern::Int { int_value, .. } => eaf.int_pattern(int_value.clone()), 139 - Pattern::String { value, .. } => eaf.string_pattern(value), 136 + Pattern::Discard { .. } => builder.discard_pattern(), 137 + Pattern::Float { float_value, .. } => builder.float_pattern(float_value.value()), 138 + Pattern::Int { int_value, .. } => builder.int_pattern(int_value.clone()), 139 + Pattern::String { value, .. } => builder.string_pattern(value), 140 140 Pattern::Variable { name, location, .. } => { 141 - eaf.variable_pattern(&self.generator.new_erlang_variable(name, *location)) 141 + builder.variable_pattern(&self.generator.new_erlang_variable(name, *location)) 142 142 } 143 143 144 144 Pattern::Assign { ··· 146 146 pattern, 147 147 location, 148 148 } => { 149 - eaf.match_pattern(); 150 - self.pattern(eaf, pattern); 151 - eaf.variable_pattern(&self.generator.new_erlang_variable(name, *location)); 149 + builder.match_pattern(); 150 + self.pattern(builder, pattern); 151 + builder.variable_pattern(&self.generator.new_erlang_variable(name, *location)); 152 152 } 153 153 154 154 Pattern::Tuple { elements, .. } => { 155 - let tuple = eaf.start_tuple_pattern(); 155 + let tuple = builder.start_tuple_pattern(); 156 156 for element in elements { 157 - self.pattern(eaf, element); 157 + self.pattern(builder, element); 158 158 } 159 - eaf.end_tuple_pattern(tuple); 159 + builder.end_tuple_pattern(tuple); 160 160 } 161 161 162 162 Pattern::List { elements, tail, .. } => { 163 163 for element in elements { 164 - eaf.cons_list_pattern(); 165 - self.pattern(eaf, element); 164 + builder.cons_list_pattern(); 165 + self.pattern(builder, element); 166 166 } 167 167 if let Some(tail) = tail { 168 - self.pattern(eaf, &tail.pattern); 168 + self.pattern(builder, &tail.pattern); 169 169 } else { 170 - eaf.empty_list_pattern(); 170 + builder.empty_list_pattern(); 171 171 } 172 172 } 173 173 ··· 181 181 }; 182 182 183 183 if arguments.is_empty() { 184 - eaf.atom_pattern(&to_snake_case(name)); 184 + builder.atom_pattern(&to_snake_case(name)); 185 185 } else { 186 - let tuple = eaf.start_tuple_pattern(); 187 - eaf.atom_pattern(&to_snake_case(name)); 186 + let tuple = builder.start_tuple_pattern(); 187 + builder.atom_pattern(&to_snake_case(name)); 188 188 for argument in arguments { 189 - self.pattern(eaf, &argument.value); 189 + self.pattern(builder, &argument.value); 190 190 } 191 - eaf.end_tuple_pattern(tuple); 191 + builder.end_tuple_pattern(tuple); 192 192 } 193 193 } 194 194 ··· 212 212 ); 213 213 } 214 214 215 - let bit_array = eaf.start_bit_array_pattern(); 215 + let bit_array = builder.start_bit_array_pattern(); 216 216 217 217 // We first generate a segment matching on the literal prefix. 218 - eaf.bit_array_segment(); 219 - eaf.string_pattern(left_side_string); 220 - eaf.atom("deafult"); 221 - eaf.bit_array_segment_specifiers([BitArraySegmentSpecifier::Utf8]); 218 + builder.bit_array_segment(); 219 + builder.string_pattern(left_side_string); 220 + builder.atom("deafult"); 221 + builder.bit_array_segment_specifiers([BitArraySegmentSpecifier::Utf8]); 222 222 223 223 // We then add a segment matching on the rest of the string. 224 - eaf.bit_array_segment(); 224 + builder.bit_array_segment(); 225 225 match right_side_assignment { 226 - AssignName::Variable(name) => eaf.variable_pattern( 226 + AssignName::Variable(name) => builder.variable_pattern( 227 227 &self.generator.new_erlang_variable(name, *right_location), 228 228 ), 229 - AssignName::Discard(_) => eaf.discard_pattern(), 229 + AssignName::Discard(_) => builder.discard_pattern(), 230 230 } 231 - eaf.atom("default"); 232 - eaf.bit_array_segment_specifiers([BitArraySegmentSpecifier::Binary]); 231 + builder.atom("default"); 232 + builder.bit_array_segment_specifiers([BitArraySegmentSpecifier::Binary]); 233 233 234 - eaf.end_bit_array_pattern(bit_array); 234 + builder.end_bit_array_pattern(bit_array); 235 235 } 236 236 237 237 Pattern::BitArray { segments, .. } => { 238 - let bit_array = eaf.start_bit_array_pattern(); 238 + let bit_array = builder.start_bit_array_pattern(); 239 239 for segment in segments { 240 - eaf.bit_array_segment(); 241 - self.bit_array_pattern_segment_value(eaf, segment); 242 - self.bit_array_pattern_segment_size(eaf, segment); 243 - self.generator.bit_array_segment_specifiers(eaf, segment); 240 + builder.bit_array_segment(); 241 + self.bit_array_pattern_segment_value(builder, segment); 242 + self.bit_array_pattern_segment_size(builder, segment); 243 + self.generator 244 + .bit_array_segment_specifiers(builder, segment); 244 245 } 245 - eaf.end_bit_array_pattern(bit_array); 246 + builder.end_bit_array_pattern(bit_array); 246 247 } 247 248 248 - Pattern::BitArraySize(size) => self.bit_array_size(eaf, size), 249 + Pattern::BitArraySize(size) => self.bit_array_size(builder, size), 249 250 250 251 Pattern::Invalid { .. } => { 251 252 panic!("invalid patterns should not reach code generation") ··· 253 254 } 254 255 } 255 256 256 - fn bit_array_size<Output>(&mut self, eaf: &mut impl Eaf<Output>, size: &'a TypedBitArraySize) { 257 + fn bit_array_size<Output>( 258 + &mut self, 259 + builder: &mut impl ErlangBuilder<Output>, 260 + size: &'a TypedBitArraySize, 261 + ) { 257 262 match size { 258 - BitArraySize::Int { int_value, .. } => eaf.int(int_value.clone()), 259 - BitArraySize::Block { inner, .. } => self.bit_array_size(eaf, inner), 263 + BitArraySize::Int { int_value, .. } => builder.int(int_value.clone()), 264 + BitArraySize::Block { inner, .. } => self.bit_array_size(builder, inner), 260 265 261 266 BitArraySize::Variable { 262 267 constructor, name, .. 263 268 } => match self.variables_to_add_later.get(name) { 264 - Some(AliasedLiteral::Int { value, .. }) => eaf.int(value.clone()), 269 + Some(AliasedLiteral::Int { value, .. }) => builder.int(value.clone()), 265 270 Some(_) => panic!("segment size that is not int made it through type checking"), 266 271 None => { 267 272 let constructor = constructor.as_ref().expect("variable with no constructor"); 268 273 match &constructor.variant { 269 274 ValueConstructorVariant::ModuleConstant { literal, .. } => { 270 - self.generator.inlined_constant(eaf, literal) 275 + self.generator.inlined_constant(builder, literal) 271 276 } 272 277 ValueConstructorVariant::LocalVariable { location, .. } => { 273 - eaf.variable(&self.generator.local_var_name(location)) 278 + builder.variable(&self.generator.local_var_name(location)) 274 279 } 275 280 ValueConstructorVariant::ModuleFn { .. } 276 281 | ValueConstructorVariant::Record { .. } => panic!("invalid segment"), ··· 289 294 IntOperator::Subtract => "-", 290 295 IntOperator::Multiply => "*", 291 296 IntOperator::Divide => { 292 - return self.bit_array_size_divide(eaf, left, right, "div"); 297 + return self.bit_array_size_divide(builder, left, right, "div"); 293 298 } 294 299 IntOperator::Remainder => { 295 - return self.bit_array_size_divide(eaf, left, right, "rem"); 300 + return self.bit_array_size_divide(builder, left, right, "rem"); 296 301 } 297 302 }; 298 - eaf.binary_operator(operator); 299 - self.bit_array_size(eaf, left); 300 - self.bit_array_size(eaf, right); 303 + builder.binary_operator(operator); 304 + self.bit_array_size(builder, left); 305 + self.bit_array_size(builder, right); 301 306 } 302 307 } 303 308 } 304 309 305 310 fn bit_array_pattern_segment_value<Output>( 306 311 &mut self, 307 - eaf: &mut impl Eaf<Output>, 312 + builder: &mut impl ErlangBuilder<Output>, 308 313 segment: &'a TypedPatternBitArraySegment, 309 314 ) { 310 315 let Pattern::Assign { ··· 315 320 else { 316 321 // If the pattern is not an assign, it needs no extra care, we can 317 322 // just produce the code for such pattern! 318 - self.pattern(eaf, &segment.value); 323 + self.pattern(builder, &segment.value); 319 324 return; 320 325 }; 321 326 ··· 349 354 // pattern, that makes things even simpler, we can just produce the 350 355 // code for a variable pattern with the wanted name and call it a day 351 356 Pattern::Discard { .. } => { 352 - eaf.variable_pattern(&self.generator.new_erlang_variable(name, *location)); 357 + builder.variable_pattern(&self.generator.new_erlang_variable(name, *location)); 353 358 return; 354 359 } 355 360 ··· 369 374 let _ = self 370 375 .variables_to_add_later 371 376 .insert(name.clone(), aliased_value); 372 - self.pattern(eaf, pattern); 377 + self.pattern(builder, pattern); 373 378 } 374 379 375 380 fn bit_array_pattern_segment_size<Output>( 376 381 &mut self, 377 - eaf: &mut impl Eaf<Output>, 382 + builder: &mut impl ErlangBuilder<Output>, 378 383 segment: &'a TypedPatternBitArraySegment, 379 384 ) { 380 385 let Some(size) = segment.size() else { 381 - eaf.atom("default"); 386 + builder.atom("default"); 382 387 return; 383 388 }; 384 389 let TypedPattern::BitArraySize(size) = size else { 385 390 panic!("invalid size in pattern size segment") 386 391 }; 387 - self.bit_array_size(eaf, size); 392 + self.bit_array_size(builder, size); 388 393 } 389 394 390 395 fn bit_array_size_divide<Output>( 391 396 &mut self, 392 - eaf: &mut impl Eaf<Output>, 397 + builder: &mut impl ErlangBuilder<Output>, 393 398 left: &'a TypedBitArraySize, 394 399 right: &'a TypedBitArraySize, 395 400 operator: &'static str, 396 401 ) { 397 402 if right.non_zero_compile_time_number() { 398 - eaf.binary_operator(operator); 399 - self.bit_array_size(eaf, left); 400 - self.bit_array_size(eaf, right); 403 + builder.binary_operator(operator); 404 + self.bit_array_size(builder, left); 405 + self.bit_array_size(builder, right); 401 406 } else { 402 - let case = eaf.start_case(); 403 - self.bit_array_size(eaf, right); 407 + let case = builder.start_case(); 408 + self.bit_array_size(builder, right); 404 409 405 - let clause = eaf.start_case_clause(); 406 - eaf.int_pattern(BigInt::ZERO); 407 - let clause = eaf.end_clause_pattern(clause); 408 - let clause = eaf.end_clause_guards(clause); 409 - eaf.int(BigInt::ZERO); 410 - eaf.end_clause_body(clause); 410 + let clause = builder.start_case_clause(); 411 + builder.int_pattern(BigInt::ZERO); 412 + let clause = builder.end_clause_pattern(clause); 413 + let clause = builder.end_clause_guards(clause); 414 + builder.int(BigInt::ZERO); 415 + builder.end_clause_body(clause); 411 416 412 - let clause = eaf.start_case_clause(); 417 + let clause = builder.start_case_clause(); 413 418 let denominator = self.generator.new_throwaway_variable(); 414 - eaf.variable_pattern(&denominator); 415 - let clause = eaf.end_clause_pattern(clause); 416 - let clause = eaf.end_clause_guards(clause); 417 - eaf.binary_operator(operator); 418 - self.bit_array_size(eaf, left); 419 - eaf.variable(&denominator); 420 - eaf.end_clause_body(clause); 421 - eaf.end_case(case); 419 + builder.variable_pattern(&denominator); 420 + let clause = builder.end_clause_pattern(clause); 421 + let clause = builder.end_clause_guards(clause); 422 + builder.binary_operator(operator); 423 + self.bit_array_size(builder, left); 424 + builder.variable(&denominator); 425 + builder.end_clause_body(clause); 426 + builder.end_case(case); 422 427 } 423 428 } 424 429 }
+1 -1
erlang-abstract-format/Cargo.toml erlang-generation/Cargo.toml
··· 2 2 # SPDX-FileCopyrightText: 2026 The Gleam contributors 3 3 4 4 [package] 5 - name = "erlang-abstract-format" 5 + name = "erlang-generation" 6 6 authors = ["Louis Pilfold <louis@lpil.uk>"] 7 7 version = "1.0.0" 8 8 edition = "2024"
+495 -480
erlang-abstract-format/src/lib.rs erlang-generation/src/lib.rs
··· 39 39 40 40 #[must_use] 41 41 /// Represents an open function that has yet to be closed. 42 - /// A function definition is started with `Eaf::start_function` and _must_ be 43 - /// closed using `Eaf::end_function`. 42 + /// A function definition is started with `ErlangBuilder::start_function` and 43 + /// _must_ be closed using `ErlangBuilder::end_function`. 44 44 pub struct Function { 45 45 clauses: erlang_term_format::List, 46 46 statements: erlang_term_format::List, ··· 187 187 Unit(u8), 188 188 } 189 189 190 - /// Defines the operations to describe the content of an Erlang module. 190 + /// A trait defining operations to describe the content of an Erlang module. 191 + /// 191 192 /// This might look strange in places, for example why is there a `start_tuple` 192 193 /// and `end_tuple` function, but lists are built using `cons_list` and not a 193 194 /// `start_list` and `end_list` function? ··· 200 201 /// it's gonna be handy: 201 202 /// https://www.erlang.org/doc/apps/erts/absform.html 202 203 /// 203 - pub trait Eaf<Output> { 204 - /// Creates a new `Eaf` data structure to generate Erlang code. 204 + pub trait ErlangBuilder<Output> { 205 + /// Creates a new `ErlangBuilder` data structure to generate Erlang code. 205 206 /// If a module name is provided this will also automatically take care of 206 207 /// generating the appropriate `-module` annotation at the very beginning. 207 208 /// ··· 210 211 /// 211 212 fn new(module_name: Option<ErlangModuleName>) -> Self; 212 213 213 - /// Consumes the given `Eaf` turning it into some other representation. 214 + /// Consumes the given `ErlangBuilder` turning it into some other 215 + /// representation. 214 216 /// For example that might be a binary representation, or a textual pretty 215 217 /// printed one. 216 218 /// ··· 221 223 /// For example: 222 224 /// 223 225 /// ```ignore 224 - /// eaf.export_attribute(vec![("wibble", 1), ("wobble", 2)]); 226 + /// builder.export_attribute(vec![("wibble", 1), ("wobble", 2)]); 225 227 /// ``` 226 228 /// 227 229 /// Corresponds to: ··· 240 242 /// For example: 241 243 /// 242 244 /// ```ignore 243 - /// eaf.export_attribute(vec![("wibble", 1), ("wobble", 2)]); 245 + /// builder.export_attribute(vec![("wibble", 1), ("wobble", 2)]); 244 246 /// ``` 245 247 /// 246 248 /// Corresponds to: ··· 262 264 /// For example: 263 265 /// 264 266 /// ```ignore 265 - /// let doc = eaf.start_doc_attribute(); 266 - /// eaf.atom("false"); 267 - /// eaf.close_doc_attribute(doc); 267 + /// let doc = builder.start_doc_attribute(); 268 + /// builder.atom("false"); 269 + /// builder.close_doc_attribute(doc); 268 270 /// ``` 269 271 /// 270 272 /// Corresponds to: ··· 283 285 /// For example: 284 286 /// 285 287 /// ```ignore 286 - /// let doc = eaf.start_moduledoc_attribute(); 287 - /// eaf.atom("false"); 288 - /// eaf.close_doc_attribute(doc); 288 + /// let doc = builder.start_moduledoc_attribute(); 289 + /// builder.atom("false"); 290 + /// builder.close_doc_attribute(doc); 289 291 /// ``` 290 292 /// 291 293 /// Corresponds to: ··· 308 310 /// For example: 309 311 /// 310 312 /// ```ignore 311 - /// eaf.compile_attribute(vec!["no_warn", "inline"]); 313 + /// builder.compile_attribute(vec!["no_warn", "inline"]); 312 314 /// ``` 313 315 /// 314 316 /// Corresponds to: ··· 323 325 /// For example: 324 326 /// 325 327 /// ```ignore 326 - /// eaf.file_attribute("wibble.gleam", 2.into()); 328 + /// builder.file_attribute("wibble.gleam", 2.into()); 327 329 /// ``` 328 330 /// 329 331 /// Correspods to: ··· 341 343 /// For example: 342 344 /// 343 345 /// ```ignore 344 - /// let record = eaf.start_record_attribute("wobble"); 345 - /// eaf.record_field(); 346 - /// eaf.atom("wibble"); 347 - /// eaf.literal_atom_type("ok"); 348 - /// eaf.close_record_attribute(record); 346 + /// let record = builder.start_record_attribute("wobble"); 347 + /// builder.record_field(); 348 + /// builder.atom("wibble"); 349 + /// builder.literal_atom_type("ok"); 350 + /// builder.close_record_attribute(record); 349 351 /// ``` 350 352 /// 351 353 /// Corresponds to: ··· 380 382 /// For example: 381 383 /// 382 384 /// ```ignore 383 - /// let spec = eaf.start_function_spec("wibble", 1) 384 - /// let function_type = eaf.start_function_type(); 385 - /// eaf.int_type(); 386 - /// let function_type eaf.end_function_type_arguments(function_type); 387 - /// eaf.variable_type("A"); 388 - /// eaf.end_function_type(function_type); 385 + /// let spec = builder.start_function_spec("wibble", 1) 386 + /// let function_type = builder.start_function_type(); 387 + /// builder.int_type(); 388 + /// let function_type builder.end_function_type_arguments(function_type); 389 + /// builder.variable_type("A"); 390 + /// builder.end_function_type(function_type); 389 391 /// ``` 390 392 /// 391 393 /// Corresponds to: ··· 408 410 /// For example: 409 411 /// 410 412 /// ```ignore 411 - /// let spec = eaf.start_type_spec(false, "wibble", ["A"]); 413 + /// let spec = builder.start_type_spec(false, "wibble", ["A"]); 412 414 /// 413 - /// let union = eaf.start_union_type(); 414 - /// eaf.literal_atom_type("nil"); 415 + /// let union = builder.start_union_type(); 416 + /// builder.literal_atom_type("nil"); 415 417 /// 416 - /// let list = eaf.start_named_type("list"); 417 - /// eaf.type_variable("A") 418 - /// eaf.close_named_type(); 418 + /// let list = builder.start_named_type("list"); 419 + /// builder.type_variable("A") 420 + /// builder.close_named_type(); 419 421 /// 420 - /// eaf.end_uniont_type(union); 422 + /// builder.end_uniont_type(union); 421 423 /// ``` 422 424 /// 423 425 /// Corresponds to: ··· 442 444 /// For example: 443 445 /// 444 446 /// ```ignore 445 - /// let function_type = eaf.start_function_type(); 446 - /// eaf.int_type(); 447 - /// eaf.variable_type("A"); 448 - /// let function_type eaf.end_function_type_arguments(function_type); 449 - /// eaf.variable_type("A"); 450 - /// eaf.end_function_type(function_type); 447 + /// let function_type = builder.start_function_type(); 448 + /// builder.int_type(); 449 + /// builder.variable_type("A"); 450 + /// let function_type builder.end_function_type_arguments(function_type); 451 + /// builder.variable_type("A"); 452 + /// builder.end_function_type(function_type); 451 453 /// ``` 452 454 /// 453 455 /// Corresponds to: ··· 481 483 /// For example: 482 484 /// 483 485 /// ```ignore 484 - /// let integer = eaf.start_named_type("integer"); 485 - /// eaf.end_named_type(integer); 486 + /// let integer = builder.start_named_type("integer"); 487 + /// builder.end_named_type(integer); 486 488 /// ``` 487 489 /// 488 490 /// Corresponds to: ··· 500 502 /// For example: 501 503 /// 502 504 /// ```ignore 503 - /// let type_ = eaf.start_remote_named_type("wibble", "wobble"); 504 - /// eaf.end_named_type(type_); 505 + /// let type_ = builder.start_remote_named_type("wibble", "wobble"); 506 + /// builder.end_named_type(type_); 505 507 /// ``` 506 508 /// 507 509 /// Corresponds to: ··· 523 525 /// For example: 524 526 /// 525 527 /// ```ignore 526 - /// let tuple = eaf.start_tuple_type(); 527 - /// eaf.literal_atom_type("nil"); 528 - /// eaf.literal_atom_type("ok"); 529 - /// eaf.end_tuple_type(tuple); 528 + /// let tuple = builder.start_tuple_type(); 529 + /// builder.literal_atom_type("nil"); 530 + /// builder.literal_atom_type("ok"); 531 + /// builder.end_tuple_type(tuple); 530 532 /// ``` 531 533 /// 532 534 /// Corresponds to the following Erlang type: ··· 549 551 /// For example: 550 552 /// 551 553 /// ```ignore 552 - /// let ok_or_error = eaf.start_union_type(); 553 - /// eaf.literal_atom_type("ok"); 554 - /// eaf.literal_atom_type("error"); 555 - /// eaf.end_union_type(ok_or_error); 554 + /// let ok_or_error = builder.start_union_type(); 555 + /// builder.literal_atom_type("ok"); 556 + /// builder.literal_atom_type("error"); 557 + /// builder.end_union_type(ok_or_error); 556 558 /// ``` 557 559 /// 558 560 /// Corresponds to: ··· 574 576 /// could do it like this: 575 577 /// 576 578 /// ```ignore 577 - /// let function = eaf.start_function_type(); 578 - /// eaf.type_variable("A"); 579 - /// let function = eaf.end_function_type_arguments(); 580 - /// eaf.type_variable("A"); 581 - /// eaf.end_function(function); 579 + /// let function = builder.start_function_type(); 580 + /// builder.type_variable("A"); 581 + /// let function = builder.end_function_type_arguments(); 582 + /// builder.type_variable("A"); 583 + /// builder.end_function(function); 582 584 /// ``` 583 585 /// 584 586 /// And it corresponds to: ··· 595 597 /// be defined like this: 596 598 /// 597 599 /// ```ignore 598 - /// let function = eaf.start_function_type(); 599 - /// let function = eaf.end_function_type_arguments(); 600 - /// eaf.literal_atom_type("nil"); 601 - /// eaf.end_function(function); 600 + /// let function = builder.start_function_type(); 601 + /// let function = builder.end_function_type_arguments(); 602 + /// builder.literal_atom_type("nil"); 603 + /// builder.end_function(function); 602 604 /// ``` 603 605 /// 604 606 /// And it corresponds to: ··· 617 619 /// For example: 618 620 /// 619 621 /// ```ignore 620 - /// let function = eaf.start_function("first_name", 0, vec![]); 621 - /// eaf.string("Giacomo"); 622 - /// eaf.end_function(function); 622 + /// let function = builder.start_function("first_name", 0, vec![]); 623 + /// builder.string("Giacomo"); 624 + /// builder.end_function(function); 623 625 /// ``` 624 626 /// 625 627 /// Corresponds to: ··· 642 644 /// For example: 643 645 /// 644 646 /// ```ignore 645 - /// let function = eaf.start_anonymous_function([]); 646 - /// eaf.string("Erlang rocks"); 647 - /// eaf.end_anonymous_function(function); 647 + /// let function = builder.start_anonymous_function([]); 648 + /// builder.string("Erlang rocks"); 649 + /// builder.end_anonymous_function(function); 648 650 /// ``` 649 651 /// 650 652 /// Corresponds to: ··· 670 672 /// For example: 671 673 /// 672 674 /// ```ignore 673 - /// let block = eaf.start_block(); 674 - /// eaf.string("Giacomo"); 675 - /// eaf.int(1); 676 - /// eaf.end_block(block); 675 + /// let block = builder.start_block(); 676 + /// builder.string("Giacomo"); 677 + /// builder.int(1); 678 + /// builder.end_block(block); 677 679 /// ``` 678 680 /// 679 681 /// Corresponds to: ··· 699 701 /// For example: 700 702 /// 701 703 /// ```ignore 702 - /// let call = eaf.start_remote_call("io", "format"); 703 - /// eaf.string("Giacomo"); 704 - /// eaf.end_call(call); 704 + /// let call = builder.start_remote_call("io", "format"); 705 + /// builder.string("Giacomo"); 706 + /// builder.end_call(call); 705 707 /// ``` 706 708 /// 707 709 /// Corresponds to: ··· 719 721 /// For example: 720 722 /// 721 723 /// ```ignore 722 - /// let call = eaf.start_call(); 723 - /// eaf.atom("wibble") 724 - /// eaf.string("Hello"); 725 - /// eaf.string("Giacomo"); 726 - /// eaf.end_call(call); 724 + /// let call = builder.start_call(); 725 + /// builder.atom("wibble") 726 + /// builder.string("Hello"); 727 + /// builder.string("Giacomo"); 728 + /// builder.end_call(call); 727 729 /// ``` 728 730 /// 729 731 /// Corresponds to: ··· 745 747 /// For example: 746 748 /// 747 749 /// ```ignore 748 - /// let tuple = eaf.start_tuple(); 749 - /// eaf.string("Hello"); 750 - /// eaf.int(1); 751 - /// eaf.end_tuple(tuple); 750 + /// let tuple = builder.start_tuple(); 751 + /// builder.string("Hello"); 752 + /// builder.int(1); 753 + /// builder.end_tuple(tuple); 752 754 /// ``` 753 755 /// 754 756 /// Corresponds to: ··· 771 773 /// For example: 772 774 /// 773 775 /// ```ignore 774 - /// let map = eaf.start_map(); 776 + /// let map = builder.start_map(); 775 777 /// 776 - /// eaf.map_field(); 777 - /// eaf.atom("gleam_error") 778 - /// eaf.atom("todo"); 778 + /// builder.map_field(); 779 + /// builder.atom("gleam_error") 780 + /// builder.atom("todo"); 779 781 /// 780 - /// eaf.map_field(); 781 - /// eaf.atom("line"); 782 - /// eaf.int(6.into()); 782 + /// builder.map_field(); 783 + /// builder.atom("line"); 784 + /// builder.int(6.into()); 783 785 /// ``` 784 786 /// 785 787 /// Corresponds to: ··· 810 812 /// For example: 811 813 /// 812 814 /// ```ignore 813 - /// let bit_array = eaf.start_bit_array(); 815 + /// let bit_array = builder.start_bit_array(); 814 816 /// 815 - /// eaf.bit_array_segment(); 816 - /// eaf.int(1); 817 - /// eaf.atom("default"); 818 - /// eaf.atom("default"); 817 + /// builder.bit_array_segment(); 818 + /// builder.int(1); 819 + /// builder.atom("default"); 820 + /// builder.atom("default"); 819 821 /// 820 - /// eaf.bit_array_segment(); 821 - /// eaf.string("hello"); 822 - /// eaf.atom("deafult"); 823 - /// eaf.atom("default"); 822 + /// builder.bit_array_segment(); 823 + /// builder.string("hello"); 824 + /// builder.atom("deafult"); 825 + /// builder.atom("default"); 824 826 /// 825 - /// eaf.end_bit_array(bit_array); 827 + /// builder.end_bit_array(bit_array); 826 828 /// ``` 827 829 /// 828 830 /// Corresponds to: ··· 879 881 /// For example: 880 882 /// 881 883 /// ```ignore 882 - /// eaf.cons_list(); 883 - /// eaf.variable("Hello"); 884 - /// eaf.cons_list(); 885 - /// eaf.string("Giacomo"); 886 - /// eaf.empty_list(); 884 + /// builder.cons_list(); 885 + /// builder.variable("Hello"); 886 + /// builder.cons_list(); 887 + /// builder.string("Giacomo"); 888 + /// builder.empty_list(); 887 889 /// ``` 888 890 /// 889 891 /// Corresponds to: ··· 911 913 /// For example: 912 914 /// 913 915 /// ```ignore 914 - /// let case = eaf.start_case(); 915 - /// eaf.variable("wibble"); 916 + /// let case = builder.start_case(); 917 + /// builder.variable("wibble"); 916 918 /// 917 - /// let clause = eaf.start_case_clause(); 918 - /// eaf.discard_pattern(); 919 - /// let clause = eaf.end_clause_pattern(); 920 - /// let clause = eaf.end_clause_guards(); 921 - /// eaf.int(1.into()); 922 - /// eaf.end_clause_body(); 919 + /// let clause = builder.start_case_clause(); 920 + /// builder.discard_pattern(); 921 + /// let clause = builder.end_clause_pattern(); 922 + /// let clause = builder.end_clause_guards(); 923 + /// builder.int(1.into()); 924 + /// builder.end_clause_body(); 923 925 /// 924 - /// eaf.end_case(case); 926 + /// builder.end_case(case); 925 927 /// ``` 926 928 /// 927 929 /// Corresponds to: ··· 978 980 /// For example: 979 981 /// 980 982 /// ```ignore 981 - /// eaf.unary_operator("-"); 982 - /// eaf.variable("X"); 983 + /// builder.unary_operator("-"); 984 + /// builder.variable("X"); 983 985 /// ``` 984 986 /// 985 987 /// Corresponds to: ··· 995 997 /// For example: 996 998 /// 997 999 /// ```ignore 998 - /// eaf.binary_operator("+"); 999 - /// eaf.variable("X"); 1000 - /// eaf.int(1); 1000 + /// builder.binary_operator("+"); 1001 + /// builder.variable("X"); 1002 + /// builder.int(1); 1001 1003 /// ``` 1002 1004 /// 1003 1005 /// Corresponds to: ··· 1012 1014 /// For example: 1013 1015 /// 1014 1016 /// ```ignore 1015 - /// eaf.function_reference(None, "wibble", 1); 1016 - /// eaf.function_reference(Some("io"), "format", 2); 1017 + /// builder.function_reference(None, "wibble", 1); 1018 + /// builder.function_reference(Some("io"), "format", 2); 1017 1019 /// ``` 1018 1020 /// 1019 1021 /// Correspond to: ··· 1033 1035 /// For example: 1034 1036 /// 1035 1037 /// ```ignore 1036 - /// eaf.match_operator(); 1037 - /// eaf.variable_pattern("X"); 1038 - /// eaf.int(1); 1038 + /// builder.match_operator(); 1039 + /// builder.variable_pattern("X"); 1040 + /// builder.int(1); 1039 1041 /// ``` 1040 1042 /// 1041 1043 /// Corresponds to: ··· 1054 1056 /// For example: 1055 1057 /// 1056 1058 /// ```ignore 1057 - /// eaf.match_pattern(); 1058 - /// eaf.int_pattern(1); 1059 - /// eaf.variable_pattern("X"); 1059 + /// builder.match_pattern(); 1060 + /// builder.int_pattern(1); 1061 + /// builder.variable_pattern("X"); 1060 1062 /// ``` 1061 1063 /// 1062 1064 /// Corresponds to: ··· 1144 1146 /// For example: 1145 1147 /// 1146 1148 /// ```ignore 1147 - /// let tuple = eaf.start_tuple_pattern(); 1148 - /// eaf.int_pattern(1); 1149 - /// eaf.discard_pattern(); 1150 - /// eaf.end_tuple(tuple); 1149 + /// let tuple = builder.start_tuple_pattern(); 1150 + /// builder.int_pattern(1); 1151 + /// builder.discard_pattern(); 1152 + /// builder.end_tuple(tuple); 1151 1153 /// ``` 1152 1154 /// 1153 1155 /// Corresponds to the following pattern: ··· 1168 1170 /// For example: 1169 1171 /// 1170 1172 /// ```ignore 1171 - /// let bit_array = eaf.start_bit_array_pattern(); 1173 + /// let bit_array = builder.start_bit_array_pattern(); 1172 1174 /// 1173 - /// eaf.bit_array_pattern_segment(); 1174 - /// eaf.int_pattern(1); 1175 - /// eaf.atom("default"); 1176 - /// eaf.atom("default"); 1175 + /// builder.bit_array_pattern_segment(); 1176 + /// builder.int_pattern(1); 1177 + /// builder.atom("default"); 1178 + /// builder.atom("default"); 1177 1179 /// 1178 - /// eaf.bit_array_pattern_segment(); 1179 - /// eaf.discard_pattern(); 1180 - /// eaf.atom("deafult"); 1181 - /// eaf.atom("default"); 1180 + /// builder.bit_array_pattern_segment(); 1181 + /// builder.discard_pattern(); 1182 + /// builder.atom("deafult"); 1183 + /// builder.atom("default"); 1182 1184 /// 1183 - /// eaf.end_bit_array_pattern(bit_array); 1185 + /// builder.end_bit_array_pattern(bit_array); 1184 1186 /// ``` 1185 1187 /// 1186 1188 /// Corresponds to the following pattern: ··· 1203 1205 /// For example: 1204 1206 /// 1205 1207 /// ```ignore 1206 - /// eaf.cons_list_pattern(); 1207 - /// eaf.discard_pattern(); 1208 - /// eaf.cons_list_pattern(); 1209 - /// eaf.string("Louis"); 1210 - /// eaf.empty_list_pattern(); 1208 + /// builder.cons_list_pattern(); 1209 + /// builder.discard_pattern(); 1210 + /// builder.cons_list_pattern(); 1211 + /// builder.string("Louis"); 1212 + /// builder.empty_list_pattern(); 1211 1213 /// ``` 1212 1214 /// 1213 1215 /// Corresponds to the following pattern: ··· 1233 1235 /// For example: 1234 1236 /// 1235 1237 /// ```ignore 1236 - /// eaf.string("ksiąskę"); 1238 + /// builder.string("ksiąskę"); 1237 1239 /// ``` 1238 1240 /// 1239 1241 /// Corresponds to: ··· 1252 1254 /// For example: 1253 1255 /// 1254 1256 /// ```ignore 1255 - /// eaf.int(BigInt::from(2)) 1257 + /// builder.int(BigInt::from(2)) 1256 1258 /// ``` 1257 1259 /// 1258 1260 /// Corresponds to: ··· 1268 1270 /// For example: 1269 1271 /// 1270 1272 /// ```ignore 1271 - /// eaf.float(1.2) 1273 + /// builder.float(1.2) 1272 1274 /// ``` 1273 1275 /// 1274 1276 /// Corresponds to: ··· 1284 1286 /// For example: 1285 1287 /// 1286 1288 /// ```ignore 1287 - /// eaf.atom("wibble") 1289 + /// builder.atom("wibble") 1288 1290 /// ``` 1289 1291 /// 1290 1292 /// Corresponds to: ··· 1296 1298 fn atom(&mut self, name: &str); 1297 1299 } 1298 1300 1299 - /// A structure that implements the EAF trait but rather than producing the 1300 - /// Erlang abstract format binary, it will produce a nice and readable Erlang 1301 - /// source string that can be used for testing. 1301 + /// A structure that implements the `ErlangBuilder` trait and produces a nice 1302 + /// and readable Erlang source string. 1302 1303 #[derive(Debug)] 1303 - pub struct PrettyEaf { 1304 + pub struct ErlangSourceBuilder { 1304 1305 code: String, 1305 1306 /// This keeps track of what we're generating 1306 - position: Vec<PrettyEafPosition>, 1307 + position: Vec<ErlangSourceBuilderPosition>, 1307 1308 /// The current indentation to use when generating stuff like case 1308 1309 /// expressions, block statements, etc. 1309 1310 indentation: usize, 1310 1311 } 1311 1312 1312 1313 /// This is used to keep track of the current position when generating pretty 1313 - /// printed code from an `Eaf`. 1314 + /// printed code from an `ErlangSourceBuilder`. 1314 1315 #[derive(Debug)] 1315 - pub enum PrettyEafPosition { 1316 + enum ErlangSourceBuilderPosition { 1316 1317 /// We're generating a top level documentation attribute like `-doc(false)`, 1317 1318 /// or `-moduledoc(~"wibble wobble")`. 1318 1319 DocAttribute, ··· 1406 1407 1407 1408 /// We're generating code for a unary operator. We're waiting for the 1408 1409 /// expression to apply the operator to. 1409 - UnaryOperator { 1410 - /// This is true if the operator is `-`. 1411 - is_number_negation: bool, 1412 - }, 1410 + UnaryOperator, 1413 1411 1414 1412 /// We're generating a tuple. 1415 1413 Tuple { ··· 1511 1509 } 1512 1510 1513 1511 #[derive(Debug, Eq, PartialEq)] 1514 - pub enum ListKind { 1512 + enum ListKind { 1515 1513 /// We're generating a list pattern. 1516 1514 Pattern, 1517 1515 /// We're generating a list expression. ··· 1519 1517 } 1520 1518 1521 1519 #[derive(Debug, Eq, PartialEq, Copy, Clone)] 1522 - pub enum BitArrayKind { 1520 + enum BitArrayKind { 1523 1521 /// We're generating a bit array pattern. 1524 1522 Pattern, 1525 1523 /// We're generating a bit array expression. ··· 1531 1529 /// after two expressions are generated. So we need to keep track of what we're 1532 1530 /// expecting to be generated next. 1533 1531 #[derive(Debug)] 1534 - pub enum MapFieldExpectedItem { 1532 + enum MapFieldExpectedItem { 1535 1533 Key, 1536 1534 Value, 1537 1535 } ··· 1541 1539 /// It is implicitly over after those two things are generated. 1542 1540 /// So we need to keep track of which we're expecting to be generated next. 1543 1541 #[derive(Debug)] 1544 - pub enum ExpectedRecordFieldItem { 1542 + enum ExpectedRecordFieldItem { 1545 1543 Name, 1546 1544 Type, 1547 1545 } ··· 1551 1549 /// finally we will be generating the statements making up the clause's body. 1552 1550 /// 1553 1551 #[derive(Debug)] 1554 - pub enum ExpectedCaseClauseItem { 1552 + enum ExpectedCaseClauseItem { 1555 1553 Pattern, 1556 1554 Guards { 1557 1555 /// This is true if no guard has been generated yet. ··· 1568 1566 /// expression. 1569 1567 /// 1570 1568 #[derive(Debug)] 1571 - pub enum ExpectedCaseItem { 1569 + enum ExpectedCaseItem { 1572 1570 /// We're waiting for the expression to be matched on to be generated. 1573 1571 Subject, 1574 1572 /// We've generated the expression to be matched on, and now are waiting for ··· 1587 1585 /// pretty print the output. 1588 1586 /// 1589 1587 #[derive(Debug)] 1590 - pub enum ExpectedBinaryOperatorSide { 1588 + enum ExpectedBinaryOperatorSide { 1591 1589 Left, 1592 1590 Right, 1593 1591 BinaryOperatorIsOver, ··· 1598 1596 /// This keeps track of which one we're expecting to be generated next. 1599 1597 /// 1600 1598 #[derive(Debug)] 1601 - pub enum BitArraySegmentExpectedItem { 1599 + enum BitArraySegmentExpectedItem { 1602 1600 Value { 1603 1601 /// This is telling us if the value of the segment has to be a pattern 1604 1602 /// or an expression. ··· 1613 1611 /// current module, or any expression), and its arguments. 1614 1612 /// 1615 1613 #[derive(Debug)] 1616 - pub enum ExpectedCallItem { 1614 + enum ExpectedCallItem { 1617 1615 /// We're waiting for the function to be called to be generated 1618 1616 FunctionToBeCalled, 1619 1617 /// The function to be called was generated, now we're waiting for its ··· 1625 1623 /// arguments of the function, and the return type. 1626 1624 /// 1627 1625 #[derive(Debug)] 1628 - pub enum ExpectedFunctionTypeItem { 1626 + enum ExpectedFunctionTypeItem { 1629 1627 Arguments { first: bool }, 1630 1628 ReturnType, 1631 1629 } ··· 1635 1633 /// see. 1636 1634 /// 1637 1635 #[derive(Debug)] 1638 - pub enum TypeSpecExpectedItem { 1636 + enum TypeSpecExpectedItem { 1639 1637 TypeDefinition, 1640 1638 TypeSpecIsOver, 1641 1639 } ··· 1643 1641 /// A match operator is made of two sides: `X = 1`. A pattern and an expression. 1644 1642 /// 1645 1643 #[derive(Debug)] 1646 - pub enum ExpectedMatchSide { 1644 + enum ExpectedMatchSide { 1647 1645 /// We're waiting for the pattern on the left hand side of an assignment to 1648 1646 /// be generated. 1649 1647 Pattern, ··· 1656 1654 /// A pattern and a variable pattern for the name. 1657 1655 /// 1658 1656 #[derive(Debug)] 1659 - pub enum ExpectedMatchPatternSide { 1657 + enum ExpectedMatchPatternSide { 1660 1658 /// We're waiting for the pattern on the left hand side of the match pattern 1661 1659 /// to be generated. 1662 1660 Left, ··· 1671 1669 /// the list is actually over. 1672 1670 /// 1673 1671 #[derive(Debug)] 1674 - pub enum ExpectedListItem { 1672 + enum ExpectedListItem { 1675 1673 First, 1676 1674 Rest, 1677 1675 ListIsOver, ··· 1715 1713 /// 1716 1714 /// ```ignore 1717 1715 /// // X = 1 1718 - /// eaf.match_operator() 1719 - /// eaf.variable_pattern("X") 1720 - /// eaf.int(1) 1716 + /// builder.match_operator() 1717 + /// builder.variable_pattern("X") 1718 + /// builder.int(1) 1721 1719 /// ``` 1722 1720 /// 1723 1721 /// Notice how here we don't have a `start_match_operator` and 1724 1722 /// `end_match_operator`. As you'll see in the implementation these will 1725 1723 /// require a bit of extra book-keeping in the `new_x` functions. 1726 1724 /// 1727 - impl Eaf<String> for PrettyEaf { 1725 + impl ErlangBuilder<String> for ErlangSourceBuilder { 1728 1726 fn new(module: Option<ErlangModuleName>) -> Self { 1729 1727 Self { 1730 1728 code: if let Some(module) = module { ··· 1802 1800 fn start_doc_attribute(&mut self) -> DocAttribute { 1803 1801 self.new_top_level_form(); 1804 1802 self.code.push_str("-doc("); 1805 - self.position.push(PrettyEafPosition::DocAttribute); 1803 + self.position 1804 + .push(ErlangSourceBuilderPosition::DocAttribute); 1806 1805 DocAttribute { 1807 - items: PrettyEaf::dummy_list(), 1806 + items: ErlangSourceBuilder::dummy_list(), 1808 1807 } 1809 1808 } 1810 1809 1811 1810 fn start_moduledoc_attribute(&mut self) -> DocAttribute { 1812 1811 self.new_top_level_form(); 1813 1812 self.code.push_str("-moduledoc("); 1814 - self.position.push(PrettyEafPosition::DocAttribute); 1813 + self.position 1814 + .push(ErlangSourceBuilderPosition::DocAttribute); 1815 1815 DocAttribute { 1816 - items: PrettyEaf::dummy_list(), 1816 + items: ErlangSourceBuilder::dummy_list(), 1817 1817 } 1818 1818 } 1819 1819 ··· 1856 1856 self.code.push_str(", {"); 1857 1857 self.indentation += INDENT; 1858 1858 self.position 1859 - .push(PrettyEafPosition::RecordAttribute { first: true }); 1859 + .push(ErlangSourceBuilderPosition::RecordAttribute { first: true }); 1860 1860 1861 1861 RecordAttribute { 1862 - fields: PrettyEaf::dummy_list(), 1862 + fields: ErlangSourceBuilder::dummy_list(), 1863 1863 } 1864 1864 } 1865 1865 ··· 1870 1870 1871 1871 fn record_field(&mut self) { 1872 1872 self.new_record_field(); 1873 - self.position.push(PrettyEafPosition::RecordField { 1874 - expected: ExpectedRecordFieldItem::Name, 1875 - }); 1873 + self.position 1874 + .push(ErlangSourceBuilderPosition::RecordField { 1875 + expected: ExpectedRecordFieldItem::Name, 1876 + }); 1876 1877 } 1877 1878 1878 1879 fn start_function_spec(&mut self, name: &str, _arity: usize) -> FunctionSpec { 1879 1880 self.new_top_level_form(); 1880 1881 self.code.push_str("\n-spec "); 1881 1882 self.code.push_str(&quote_atom_name(name)); 1882 - self.position.push(PrettyEafPosition::FunctionSpec); 1883 + self.position 1884 + .push(ErlangSourceBuilderPosition::FunctionSpec); 1883 1885 FunctionSpec { 1884 - representations: PrettyEaf::dummy_list(), 1886 + representations: ErlangSourceBuilder::dummy_list(), 1885 1887 } 1886 1888 } 1887 1889 ··· 1913 1915 self.code.push_str(type_variable.as_ref()) 1914 1916 } 1915 1917 self.code.push_str(") :: "); 1916 - self.position.push(PrettyEafPosition::TypeSpec { 1918 + self.position.push(ErlangSourceBuilderPosition::TypeSpec { 1917 1919 expected: TypeSpecExpectedItem::TypeDefinition, 1918 1920 }); 1919 1921 } ··· 1921 1923 fn start_function_type(&mut self) -> FunctionTypeArguments { 1922 1924 self.new_type(); 1923 1925 1924 - let needs_wrapping = if let Some(PrettyEafPosition::FunctionSpec) = self.position.last() { 1925 - self.code.push('('); 1926 - false 1927 - } else { 1928 - self.code.push_str("fun(("); 1929 - true 1930 - }; 1926 + let needs_wrapping = 1927 + if let Some(ErlangSourceBuilderPosition::FunctionSpec) = self.position.last() { 1928 + self.code.push('('); 1929 + false 1930 + } else { 1931 + self.code.push_str("fun(("); 1932 + true 1933 + }; 1931 1934 1932 - self.position.push(PrettyEafPosition::FunctionType { 1933 - expected: ExpectedFunctionTypeItem::Arguments { first: true }, 1934 - needs_wrapping, 1935 - }); 1935 + self.position 1936 + .push(ErlangSourceBuilderPosition::FunctionType { 1937 + expected: ExpectedFunctionTypeItem::Arguments { first: true }, 1938 + needs_wrapping, 1939 + }); 1936 1940 1937 1941 FunctionTypeArguments { 1938 - types: PrettyEaf::dummy_list(), 1939 - arguments: PrettyEaf::dummy_list(), 1942 + types: ErlangSourceBuilder::dummy_list(), 1943 + arguments: ErlangSourceBuilder::dummy_list(), 1940 1944 } 1941 1945 } 1942 1946 ··· 1959 1963 fn start_named_type(&mut self, name: &str) -> NamedType { 1960 1964 self.new_type(); 1961 1965 self.position 1962 - .push(PrettyEafPosition::NamedType { first: true }); 1966 + .push(ErlangSourceBuilderPosition::NamedType { first: true }); 1963 1967 self.code.push_str(&quote_atom_name(name)); 1964 1968 self.code.push('('); 1965 1969 1966 1970 NamedType { 1967 - types: PrettyEaf::dummy_list(), 1971 + types: ErlangSourceBuilder::dummy_list(), 1968 1972 } 1969 1973 } 1970 1974 1971 1975 fn start_remote_named_type(&mut self, module: ErlangModuleName, name: &str) -> NamedType { 1972 1976 self.new_type(); 1973 1977 self.position 1974 - .push(PrettyEafPosition::NamedType { first: true }); 1978 + .push(ErlangSourceBuilderPosition::NamedType { first: true }); 1975 1979 self.code.push_str(&quote_atom_name(&module.0)); 1976 1980 self.code.push(':'); 1977 1981 self.code.push_str(&quote_atom_name(name)); 1978 1982 self.code.push('('); 1979 1983 1980 1984 NamedType { 1981 - types: PrettyEaf::dummy_list(), 1985 + types: ErlangSourceBuilder::dummy_list(), 1982 1986 } 1983 1987 } 1984 1988 ··· 1990 1994 fn start_tuple_type(&mut self) -> TupleType { 1991 1995 self.new_type(); 1992 1996 self.position 1993 - .push(PrettyEafPosition::TupleType { first: true }); 1997 + .push(ErlangSourceBuilderPosition::TupleType { first: true }); 1994 1998 self.code.push('{'); 1995 1999 1996 2000 TupleType { 1997 - items: PrettyEaf::dummy_list(), 2001 + items: ErlangSourceBuilder::dummy_list(), 1998 2002 } 1999 2003 } 2000 2004 ··· 2006 2010 fn start_union_type(&mut self) -> UnionType { 2007 2011 self.new_type(); 2008 2012 self.position 2009 - .push(PrettyEafPosition::UnionType { first: true }); 2013 + .push(ErlangSourceBuilderPosition::UnionType { first: true }); 2010 2014 2011 2015 UnionType { 2012 - alternatives: PrettyEaf::dummy_list(), 2016 + alternatives: ErlangSourceBuilder::dummy_list(), 2013 2017 } 2014 2018 } 2015 2019 ··· 2051 2055 self.code.push_str(") ->"); 2052 2056 self.indentation += INDENT; 2053 2057 self.position 2054 - .push(PrettyEafPosition::FunctionStatement { first: true }); 2058 + .push(ErlangSourceBuilderPosition::FunctionStatement { first: true }); 2055 2059 2056 2060 Function { 2057 - clauses: PrettyEaf::dummy_list(), 2058 - statements: PrettyEaf::dummy_list(), 2061 + clauses: ErlangSourceBuilder::dummy_list(), 2062 + statements: ErlangSourceBuilder::dummy_list(), 2059 2063 } 2060 2064 } 2061 2065 ··· 2079 2083 self.code.push_str(") ->"); 2080 2084 self.indentation += INDENT; 2081 2085 self.position 2082 - .push(PrettyEafPosition::AnonymousFunctionStatement { first: true }); 2086 + .push(ErlangSourceBuilderPosition::AnonymousFunctionStatement { first: true }); 2083 2087 2084 2088 Function { 2085 - clauses: PrettyEaf::dummy_list(), 2086 - statements: PrettyEaf::dummy_list(), 2089 + clauses: ErlangSourceBuilder::dummy_list(), 2090 + statements: ErlangSourceBuilder::dummy_list(), 2087 2091 } 2088 2092 } 2089 2093 ··· 2097 2101 self.new_expression(); 2098 2102 self.code.push_str("begin"); 2099 2103 self.indentation += INDENT; 2100 - self.position.push(PrettyEafPosition::Block { first: true }); 2104 + self.position 2105 + .push(ErlangSourceBuilderPosition::Block { first: true }); 2101 2106 2102 2107 Block { 2103 - statements: PrettyEaf::dummy_list(), 2108 + statements: ErlangSourceBuilder::dummy_list(), 2104 2109 } 2105 2110 } 2106 2111 ··· 2116 2121 // it is going to need to be wrapped in parentheses to be valid in 2117 2122 // OTP 28: it is not ok to write `wibble()()`, but we have to write 2118 2123 // `(wibble())()`. 2119 - if let Some(PrettyEafPosition::FunctionCall { 2124 + if let Some(ErlangSourceBuilderPosition::FunctionCall { 2120 2125 expected: ExpectedCallItem::FunctionToBeCalled, 2121 2126 called_item_needs_wrapping, 2122 2127 }) = self.position.last_mut() ··· 2128 2133 self.code.push_str(&quote_atom_name(&module.0)); 2129 2134 self.code.push(':'); 2130 2135 self.code.push_str(&quote_atom_name(function)); 2131 - self.position.push(PrettyEafPosition::FunctionCall { 2132 - expected: ExpectedCallItem::Arguments { first: true }, 2133 - called_item_needs_wrapping: false, 2134 - }); 2136 + self.position 2137 + .push(ErlangSourceBuilderPosition::FunctionCall { 2138 + expected: ExpectedCallItem::Arguments { first: true }, 2139 + called_item_needs_wrapping: false, 2140 + }); 2135 2141 Call { 2136 - arguments: PrettyEaf::dummy_list(), 2142 + arguments: ErlangSourceBuilder::dummy_list(), 2137 2143 } 2138 2144 } 2139 2145 ··· 2144 2150 // it is going to need to be wrapped in parentheses to be valid in 2145 2151 // OTP 28: it is not ok to write `wibble()()`, but we have to write 2146 2152 // `(wibble())()`. 2147 - if let Some(PrettyEafPosition::FunctionCall { 2153 + if let Some(ErlangSourceBuilderPosition::FunctionCall { 2148 2154 expected: ExpectedCallItem::FunctionToBeCalled, 2149 2155 called_item_needs_wrapping, 2150 2156 }) = self.position.last_mut() ··· 2153 2159 }; 2154 2160 2155 2161 self.new_expression(); 2156 - self.position.push(PrettyEafPosition::FunctionCall { 2157 - expected: ExpectedCallItem::FunctionToBeCalled, 2158 - called_item_needs_wrapping: false, 2159 - }); 2162 + self.position 2163 + .push(ErlangSourceBuilderPosition::FunctionCall { 2164 + expected: ExpectedCallItem::FunctionToBeCalled, 2165 + called_item_needs_wrapping: false, 2166 + }); 2160 2167 Call { 2161 - arguments: PrettyEaf::dummy_list(), 2168 + arguments: ErlangSourceBuilder::dummy_list(), 2162 2169 } 2163 2170 } 2164 2171 ··· 2170 2177 fn start_tuple(&mut self) -> Tuple { 2171 2178 self.new_expression(); 2172 2179 self.code.push('{'); 2173 - self.position.push(PrettyEafPosition::Tuple { first: true }); 2180 + self.position 2181 + .push(ErlangSourceBuilderPosition::Tuple { first: true }); 2174 2182 2175 2183 Tuple { 2176 - items: PrettyEaf::dummy_list(), 2184 + items: ErlangSourceBuilder::dummy_list(), 2177 2185 } 2178 2186 } 2179 2187 ··· 2186 2194 self.new_expression(); 2187 2195 self.code.push_str("#{"); 2188 2196 self.indentation += INDENT; 2189 - self.position.push(PrettyEafPosition::Map { first: true }); 2197 + self.position 2198 + .push(ErlangSourceBuilderPosition::Map { first: true }); 2190 2199 Map { 2191 - items: PrettyEaf::dummy_list(), 2200 + items: ErlangSourceBuilder::dummy_list(), 2192 2201 } 2193 2202 } 2194 2203 ··· 2199 2208 2200 2209 fn map_field(&mut self) { 2201 2210 self.new_map_field(); 2202 - self.position.push(PrettyEafPosition::MapField { 2211 + self.position.push(ErlangSourceBuilderPosition::MapField { 2203 2212 expected: MapFieldExpectedItem::Key, 2204 2213 }); 2205 2214 } ··· 2208 2217 self.do_not_wrap_if_segment_value_or_size(); 2209 2218 self.new_expression(); 2210 2219 self.code.push_str("<<"); 2211 - self.position.push(PrettyEafPosition::BitArray { 2220 + self.position.push(ErlangSourceBuilderPosition::BitArray { 2212 2221 kind: BitArrayKind::Expression, 2213 2222 first: true, 2214 2223 }); 2215 2224 2216 2225 BitArray { 2217 - segments: PrettyEaf::dummy_list(), 2226 + segments: ErlangSourceBuilder::dummy_list(), 2218 2227 } 2219 2228 } 2220 2229 ··· 2225 2234 2226 2235 fn bit_array_segment(&mut self) { 2227 2236 let kind = self.new_bit_array_segment(); 2228 - self.position.push(PrettyEafPosition::BitArraySegment { 2229 - expected: BitArraySegmentExpectedItem::Value { kind }, 2230 - // We assume all values are going to have to be wrapped, better 2231 - // be safe than sorry! 2232 - // We will turn this off only for certain expressions we know 2233 - // are safe to not wrap, like bare integers and strings. 2234 - segment_value_needs_wrapping: true, 2235 - segment_size_needs_wrapping: true, 2236 - }) 2237 + self.position 2238 + .push(ErlangSourceBuilderPosition::BitArraySegment { 2239 + expected: BitArraySegmentExpectedItem::Value { kind }, 2240 + // We assume all values are going to have to be wrapped, better 2241 + // be safe than sorry! 2242 + // We will turn this off only for certain expressions we know 2243 + // are safe to not wrap, like bare integers and strings. 2244 + segment_value_needs_wrapping: true, 2245 + segment_size_needs_wrapping: true, 2246 + }) 2237 2247 } 2238 2248 2239 2249 fn bit_array_segment_specifiers( ··· 2241 2251 specifiers: impl IntoIterator<Item = BitArraySegmentSpecifier>, 2242 2252 ) { 2243 2253 self.pop_leftover_items(); 2244 - let Some(PrettyEafPosition::BitArraySegment { 2254 + let Some(ErlangSourceBuilderPosition::BitArraySegment { 2245 2255 expected: BitArraySegmentExpectedItem::Specifiers, 2246 2256 segment_value_needs_wrapping, 2247 2257 segment_size_needs_wrapping, ··· 2308 2318 fn start_case(&mut self) -> Case { 2309 2319 self.new_expression(); 2310 2320 self.code.push_str("case "); 2311 - self.position.push(PrettyEafPosition::Case { 2321 + self.position.push(ErlangSourceBuilderPosition::Case { 2312 2322 expected: ExpectedCaseItem::Subject, 2313 2323 }); 2314 2324 2315 2325 Case { 2316 - branches: PrettyEaf::dummy_list(), 2326 + branches: ErlangSourceBuilder::dummy_list(), 2317 2327 } 2318 2328 } 2319 2329 ··· 2324 2334 2325 2335 fn start_case_clause(&mut self) -> ClausePattern { 2326 2336 self.new_case_clause(); 2327 - self.position.push(PrettyEafPosition::CaseClause { 2337 + self.position.push(ErlangSourceBuilderPosition::CaseClause { 2328 2338 expected: ExpectedCaseClauseItem::Pattern, 2329 2339 }); 2330 2340 ClausePattern { 2331 - pattern: PrettyEaf::dummy_list(), 2332 - guards: PrettyEaf::dummy_list(), 2333 - body: PrettyEaf::dummy_list(), 2341 + pattern: ErlangSourceBuilder::dummy_list(), 2342 + guards: ErlangSourceBuilder::dummy_list(), 2343 + body: ErlangSourceBuilder::dummy_list(), 2334 2344 } 2335 2345 } 2336 2346 2337 2347 fn end_clause_pattern(&mut self, clause_pattern: ClausePattern) -> ClauseGuards { 2338 2348 self.close_currently_open_item(); 2339 - self.position.push(PrettyEafPosition::CaseClause { 2349 + self.position.push(ErlangSourceBuilderPosition::CaseClause { 2340 2350 expected: ExpectedCaseClauseItem::Guards { first: true }, 2341 2351 }); 2342 2352 clause_pattern.pattern.consume(); ··· 2349 2359 fn end_clause_guards(&mut self, clause_guards: ClauseGuards) -> ClauseBody { 2350 2360 self.close_currently_open_item(); 2351 2361 self.indentation += INDENT; 2352 - self.position.push(PrettyEafPosition::CaseClause { 2362 + self.position.push(ErlangSourceBuilderPosition::CaseClause { 2353 2363 expected: ExpectedCaseClauseItem::Body { first: true }, 2354 2364 }); 2355 2365 ··· 2374 2384 self.new_expression(); 2375 2385 self.code.push_str(operator); 2376 2386 self.code.push(' '); 2377 - self.position.push(PrettyEafPosition::UnaryOperator { 2378 - is_number_negation: operator == "-", 2379 - }) 2387 + self.position 2388 + .push(ErlangSourceBuilderPosition::UnaryOperator) 2380 2389 } 2381 2390 2382 2391 fn binary_operator(&mut self, operator: &'static str) { ··· 2387 2396 // side), then we want to wrap it in parentheses to avoid precedence 2388 2397 // confusion! 2389 2398 let needs_wrapping = match self.position.last() { 2390 - Some(PrettyEafPosition::BinaryOperator { .. }) => { 2399 + Some(ErlangSourceBuilderPosition::BinaryOperator { .. }) => { 2391 2400 self.code.push('('); 2392 2401 true 2393 2402 } 2394 2403 Some(_) | None => false, 2395 2404 }; 2396 2405 2397 - self.position.push(PrettyEafPosition::BinaryOperator { 2398 - expected: ExpectedBinaryOperatorSide::Left, 2399 - needs_wrapping, 2400 - operator, 2401 - }) 2406 + self.position 2407 + .push(ErlangSourceBuilderPosition::BinaryOperator { 2408 + expected: ExpectedBinaryOperatorSide::Left, 2409 + needs_wrapping, 2410 + operator, 2411 + }) 2402 2412 } 2403 2413 2404 2414 fn function_reference(&mut self, module: Option<ErlangModuleName>, name: &str, arity: usize) { ··· 2415 2425 2416 2426 fn match_operator(&mut self) { 2417 2427 self.new_expression(); 2418 - self.position.push(PrettyEafPosition::MatchOperator { 2419 - expected: ExpectedMatchSide::Pattern, 2420 - }); 2428 + self.position 2429 + .push(ErlangSourceBuilderPosition::MatchOperator { 2430 + expected: ExpectedMatchSide::Pattern, 2431 + }); 2421 2432 } 2422 2433 2423 2434 fn match_pattern(&mut self) { 2424 2435 self.new_pattern(); 2425 - self.position.push(PrettyEafPosition::MatchPattern { 2426 - expected: ExpectedMatchPatternSide::Left, 2427 - }) 2436 + self.position 2437 + .push(ErlangSourceBuilderPosition::MatchPattern { 2438 + expected: ExpectedMatchPatternSide::Left, 2439 + }) 2428 2440 } 2429 2441 2430 2442 fn variable_pattern(&mut self, name: &str) { ··· 2467 2479 self.new_pattern(); 2468 2480 self.code.push('{'); 2469 2481 self.position 2470 - .push(PrettyEafPosition::TuplePattern { first: true }); 2482 + .push(ErlangSourceBuilderPosition::TuplePattern { first: true }); 2471 2483 TuplePattern { 2472 - items: PrettyEaf::dummy_list(), 2484 + items: ErlangSourceBuilder::dummy_list(), 2473 2485 } 2474 2486 } 2475 2487 ··· 2481 2493 fn start_bit_array_pattern(&mut self) -> BitArrayPattern { 2482 2494 self.new_pattern(); 2483 2495 self.code.push_str("<<"); 2484 - self.position.push(PrettyEafPosition::BitArray { 2496 + self.position.push(ErlangSourceBuilderPosition::BitArray { 2485 2497 kind: BitArrayKind::Pattern, 2486 2498 first: true, 2487 2499 }); 2488 2500 2489 2501 BitArrayPattern { 2490 - segments: PrettyEaf::dummy_list(), 2502 + segments: ErlangSourceBuilder::dummy_list(), 2491 2503 } 2492 2504 } 2493 2505 ··· 2529 2541 // That's how we can tell in the Erlang Abstract Format that the size 2530 2542 // should be the default value, but it's not actually spelled out in 2531 2543 // textual Erlang code. 2532 - if let Some(PrettyEafPosition::BitArraySegment { 2544 + if let Some(ErlangSourceBuilderPosition::BitArraySegment { 2533 2545 expected: expected @ BitArraySegmentExpectedItem::Size, 2534 2546 segment_value_needs_wrapping, 2535 2547 segment_size_needs_wrapping, ··· 2568 2580 2569 2581 const INDENT: usize = 4; 2570 2582 2571 - impl PrettyEaf { 2583 + impl ErlangSourceBuilder { 2572 2584 fn dummy_list() -> erlang_term_format::List { 2573 2585 erlang_term_format::List::new(0) 2574 2586 } ··· 2605 2617 }; 2606 2618 2607 2619 match position { 2608 - PrettyEafPosition::DocAttribute => (), 2620 + ErlangSourceBuilderPosition::DocAttribute => (), 2609 2621 2610 - PrettyEafPosition::RecordField { 2622 + ErlangSourceBuilderPosition::RecordField { 2611 2623 expected: expected @ ExpectedRecordFieldItem::Name, 2612 2624 } => *expected = ExpectedRecordFieldItem::Type, 2613 2625 2614 - PrettyEafPosition::Case { 2626 + ErlangSourceBuilderPosition::Case { 2615 2627 expected: expected @ ExpectedCaseItem::Subject, 2616 2628 } => *expected = ExpectedCaseItem::Branches { first: true }, 2617 2629 2618 - PrettyEafPosition::FunctionCall { 2630 + ErlangSourceBuilderPosition::FunctionCall { 2619 2631 expected: expected @ ExpectedCallItem::FunctionToBeCalled, 2620 2632 called_item_needs_wrapping, 2621 2633 } => { ··· 2625 2637 *expected = ExpectedCallItem::Arguments { first: true } 2626 2638 } 2627 2639 2628 - PrettyEafPosition::FunctionCall { 2640 + ErlangSourceBuilderPosition::FunctionCall { 2629 2641 expected: ExpectedCallItem::Arguments { first }, 2630 2642 called_item_needs_wrapping, 2631 2643 } => { ··· 2640 2652 } 2641 2653 *first = false; 2642 2654 } 2643 - PrettyEafPosition::Tuple { first } => { 2655 + ErlangSourceBuilderPosition::Tuple { first } => { 2644 2656 if !*first { 2645 2657 self.code.push_str(", "); 2646 2658 } ··· 2649 2661 2650 2662 // We're expecting the list's head. We don't have to add 2651 2663 // anything! 2652 - PrettyEafPosition::List { 2664 + ErlangSourceBuilderPosition::List { 2653 2665 expected: expected @ ExpectedListItem::First, 2654 2666 kind: ListKind::Expression, 2655 2667 } => *expected = ExpectedListItem::Rest, 2656 2668 2657 - PrettyEafPosition::List { 2669 + ErlangSourceBuilderPosition::List { 2658 2670 expected: expected @ ExpectedListItem::Rest, 2659 2671 kind: ListKind::Expression, 2660 2672 } => { ··· 2662 2674 self.code.push_str(" | ") 2663 2675 } 2664 2676 2665 - PrettyEafPosition::BinaryOperator { 2677 + ErlangSourceBuilderPosition::BinaryOperator { 2666 2678 expected: expected @ ExpectedBinaryOperatorSide::Left, 2667 2679 .. 2668 2680 } => *expected = ExpectedBinaryOperatorSide::Right, 2669 2681 2670 - PrettyEafPosition::BinaryOperator { 2682 + ErlangSourceBuilderPosition::BinaryOperator { 2671 2683 expected: expected @ ExpectedBinaryOperatorSide::Right, 2672 2684 operator, 2673 2685 .. ··· 2678 2690 self.code.push(' '); 2679 2691 } 2680 2692 2681 - PrettyEafPosition::FunctionStatement { first } 2682 - | PrettyEafPosition::AnonymousFunctionStatement { first } 2683 - | PrettyEafPosition::Block { first } 2684 - | PrettyEafPosition::CaseClause { 2693 + ErlangSourceBuilderPosition::FunctionStatement { first } 2694 + | ErlangSourceBuilderPosition::AnonymousFunctionStatement { first } 2695 + | ErlangSourceBuilderPosition::Block { first } 2696 + | ErlangSourceBuilderPosition::CaseClause { 2685 2697 expected: ExpectedCaseClauseItem::Body { first }, 2686 2698 } => { 2687 2699 if !*first { ··· 2692 2704 self.push_indentation(); 2693 2705 } 2694 2706 2695 - PrettyEafPosition::BitArraySegment { 2707 + ErlangSourceBuilderPosition::BitArraySegment { 2696 2708 expected: 2697 2709 expected @ BitArraySegmentExpectedItem::Value { 2698 2710 kind: BitArrayKind::Expression, ··· 2706 2718 *expected = BitArraySegmentExpectedItem::Size 2707 2719 } 2708 2720 2709 - PrettyEafPosition::BitArraySegment { 2721 + ErlangSourceBuilderPosition::BitArraySegment { 2710 2722 expected: expected @ BitArraySegmentExpectedItem::Size, 2711 2723 segment_value_needs_wrapping, 2712 2724 segment_size_needs_wrapping, ··· 2725 2737 } 2726 2738 } 2727 2739 2728 - PrettyEafPosition::CaseClause { 2740 + ErlangSourceBuilderPosition::CaseClause { 2729 2741 expected: 2730 2742 ExpectedCaseClauseItem::Guards { 2731 2743 first: first @ true, ··· 2735 2747 self.code.push_str(" when "); 2736 2748 } 2737 2749 2738 - PrettyEafPosition::MapField { expected } => match expected { 2750 + ErlangSourceBuilderPosition::MapField { expected } => match expected { 2739 2751 MapFieldExpectedItem::Key => *expected = MapFieldExpectedItem::Value, 2740 2752 // We've generated a key and now the value is being generated. 2741 2753 // So we need to add the `=>` separating key and value and we ··· 2749 2761 // We were expecting an expression and someone is about to generate 2750 2762 // it, we can pop this off the stack and need to add the ` = ` 2751 2763 // separating the previous pattern from this new expression. 2752 - PrettyEafPosition::MatchOperator { 2764 + ErlangSourceBuilderPosition::MatchOperator { 2753 2765 expected: ExpectedMatchSide::Expression, 2754 2766 } => { 2755 2767 self.code.push_str(" = "); ··· 2757 2769 } 2758 2770 // We were expecting an expression and someone generated it, we can 2759 2771 // now pop this off the stack. 2760 - PrettyEafPosition::UnaryOperator { .. } => { 2772 + ErlangSourceBuilderPosition::UnaryOperator { .. } => { 2761 2773 self.position.pop(); 2762 2774 } 2763 2775 2764 2776 // Expressions are not allowed in any of these positions. 2765 - PrettyEafPosition::Case { 2777 + ErlangSourceBuilderPosition::Case { 2766 2778 expected: ExpectedCaseItem::Branches { .. }, 2767 2779 } 2768 - | PrettyEafPosition::List { 2780 + | ErlangSourceBuilderPosition::List { 2769 2781 expected: ExpectedListItem::ListIsOver, 2770 2782 kind: ListKind::Expression, 2771 2783 } 2772 - | PrettyEafPosition::BitArray { .. } 2773 - | PrettyEafPosition::MatchOperator { 2784 + | ErlangSourceBuilderPosition::BitArray { .. } 2785 + | ErlangSourceBuilderPosition::MatchOperator { 2774 2786 expected: ExpectedMatchSide::Pattern, 2775 2787 } 2776 - | PrettyEafPosition::CaseClause { 2788 + | ErlangSourceBuilderPosition::CaseClause { 2777 2789 expected: ExpectedCaseClauseItem::Pattern, 2778 2790 } 2779 - | PrettyEafPosition::TuplePattern { .. } 2780 - | PrettyEafPosition::MatchPattern { .. } 2781 - | PrettyEafPosition::FunctionSpec 2782 - | PrettyEafPosition::TypeSpec { .. } 2783 - | PrettyEafPosition::NamedType { .. } 2784 - | PrettyEafPosition::FunctionType { .. } 2785 - | PrettyEafPosition::UnionType { .. } 2786 - | PrettyEafPosition::RecordField { 2791 + | ErlangSourceBuilderPosition::TuplePattern { .. } 2792 + | ErlangSourceBuilderPosition::MatchPattern { .. } 2793 + | ErlangSourceBuilderPosition::FunctionSpec 2794 + | ErlangSourceBuilderPosition::TypeSpec { .. } 2795 + | ErlangSourceBuilderPosition::NamedType { .. } 2796 + | ErlangSourceBuilderPosition::FunctionType { .. } 2797 + | ErlangSourceBuilderPosition::UnionType { .. } 2798 + | ErlangSourceBuilderPosition::RecordField { 2787 2799 expected: ExpectedRecordFieldItem::Type, 2788 2800 } 2789 - | PrettyEafPosition::TupleType { .. } 2790 - | PrettyEafPosition::Map { .. } 2791 - | PrettyEafPosition::RecordAttribute { .. } 2792 - | PrettyEafPosition::CaseClause { 2801 + | ErlangSourceBuilderPosition::TupleType { .. } 2802 + | ErlangSourceBuilderPosition::Map { .. } 2803 + | ErlangSourceBuilderPosition::RecordAttribute { .. } 2804 + | ErlangSourceBuilderPosition::CaseClause { 2793 2805 expected: ExpectedCaseClauseItem::Guards { first: false }, 2794 2806 } 2795 - | PrettyEafPosition::BitArraySegment { 2807 + | ErlangSourceBuilderPosition::BitArraySegment { 2796 2808 expected: BitArraySegmentExpectedItem::Specifiers, 2797 2809 .. 2798 2810 } 2799 - | PrettyEafPosition::BitArraySegment { 2811 + | ErlangSourceBuilderPosition::BitArraySegment { 2800 2812 expected: 2801 2813 BitArraySegmentExpectedItem::Value { 2802 2814 kind: BitArrayKind::Pattern, 2803 2815 }, 2804 2816 .. 2805 2817 } 2806 - | PrettyEafPosition::BinaryOperator { 2818 + | ErlangSourceBuilderPosition::BinaryOperator { 2807 2819 expected: ExpectedBinaryOperatorSide::BinaryOperatorIsOver, 2808 2820 .. 2809 2821 } 2810 - | PrettyEafPosition::List { 2822 + | ErlangSourceBuilderPosition::List { 2811 2823 kind: ListKind::Pattern, 2812 2824 .. 2813 2825 } => invalid_code_for_position!(self, "expression"), ··· 2829 2841 }; 2830 2842 2831 2843 match position { 2832 - PrettyEafPosition::FunctionSpec => {} 2833 - PrettyEafPosition::FunctionType { 2844 + ErlangSourceBuilderPosition::FunctionSpec => {} 2845 + ErlangSourceBuilderPosition::FunctionType { 2834 2846 expected: ExpectedFunctionTypeItem::ReturnType, 2835 2847 needs_wrapping: _, 2836 2848 } => {} 2837 2849 2838 - PrettyEafPosition::TypeSpec { 2850 + ErlangSourceBuilderPosition::TypeSpec { 2839 2851 expected: expected @ TypeSpecExpectedItem::TypeDefinition, 2840 2852 } => { 2841 2853 *expected = TypeSpecExpectedItem::TypeSpecIsOver; 2842 2854 } 2843 2855 2844 - PrettyEafPosition::FunctionType { 2856 + ErlangSourceBuilderPosition::FunctionType { 2845 2857 expected: ExpectedFunctionTypeItem::Arguments { first }, 2846 2858 needs_wrapping: _, 2847 2859 } 2848 - | PrettyEafPosition::TupleType { first } 2849 - | PrettyEafPosition::NamedType { first } => { 2860 + | ErlangSourceBuilderPosition::TupleType { first } 2861 + | ErlangSourceBuilderPosition::NamedType { first } => { 2850 2862 if !*first { 2851 2863 self.code.push_str(", ") 2852 2864 } 2853 2865 *first = false 2854 2866 } 2855 2867 2856 - PrettyEafPosition::UnionType { first } => { 2868 + ErlangSourceBuilderPosition::UnionType { first } => { 2857 2869 if !*first { 2858 2870 self.code.push_str(" | ") 2859 2871 } 2860 2872 *first = false 2861 2873 } 2862 2874 2863 - PrettyEafPosition::RecordField { 2875 + ErlangSourceBuilderPosition::RecordField { 2864 2876 expected: ExpectedRecordFieldItem::Type, 2865 2877 } => { 2866 2878 self.code.push_str(" :: "); 2867 2879 self.position.pop(); 2868 2880 } 2869 2881 2870 - PrettyEafPosition::FunctionCall { .. } 2871 - | PrettyEafPosition::Block { .. } 2872 - | PrettyEafPosition::Tuple { .. } 2873 - | PrettyEafPosition::BitArray { .. } 2874 - | PrettyEafPosition::BitArraySegment { .. } 2875 - | PrettyEafPosition::List { .. } 2876 - | PrettyEafPosition::FunctionStatement { .. } 2877 - | PrettyEafPosition::AnonymousFunctionStatement { .. } 2878 - | PrettyEafPosition::DocAttribute 2879 - | PrettyEafPosition::UnaryOperator { .. } 2880 - | PrettyEafPosition::Case { .. } 2881 - | PrettyEafPosition::BinaryOperator { .. } 2882 - | PrettyEafPosition::CaseClause { .. } 2883 - | PrettyEafPosition::Map { .. } 2884 - | PrettyEafPosition::MapField { .. } 2885 - | PrettyEafPosition::RecordField { 2882 + ErlangSourceBuilderPosition::FunctionCall { .. } 2883 + | ErlangSourceBuilderPosition::Block { .. } 2884 + | ErlangSourceBuilderPosition::Tuple { .. } 2885 + | ErlangSourceBuilderPosition::BitArray { .. } 2886 + | ErlangSourceBuilderPosition::BitArraySegment { .. } 2887 + | ErlangSourceBuilderPosition::List { .. } 2888 + | ErlangSourceBuilderPosition::FunctionStatement { .. } 2889 + | ErlangSourceBuilderPosition::AnonymousFunctionStatement { .. } 2890 + | ErlangSourceBuilderPosition::DocAttribute 2891 + | ErlangSourceBuilderPosition::UnaryOperator { .. } 2892 + | ErlangSourceBuilderPosition::Case { .. } 2893 + | ErlangSourceBuilderPosition::BinaryOperator { .. } 2894 + | ErlangSourceBuilderPosition::CaseClause { .. } 2895 + | ErlangSourceBuilderPosition::Map { .. } 2896 + | ErlangSourceBuilderPosition::MapField { .. } 2897 + | ErlangSourceBuilderPosition::RecordField { 2886 2898 expected: ExpectedRecordFieldItem::Name, 2887 2899 } 2888 - | PrettyEafPosition::MatchOperator { 2900 + | ErlangSourceBuilderPosition::MatchOperator { 2889 2901 expected: ExpectedMatchSide::Expression, 2890 2902 } 2891 - | PrettyEafPosition::RecordAttribute { .. } 2892 - | PrettyEafPosition::TypeSpec { 2903 + | ErlangSourceBuilderPosition::RecordAttribute { .. } 2904 + | ErlangSourceBuilderPosition::TypeSpec { 2893 2905 expected: TypeSpecExpectedItem::TypeSpecIsOver, 2894 2906 } 2895 - | PrettyEafPosition::MatchOperator { 2907 + | ErlangSourceBuilderPosition::MatchOperator { 2896 2908 expected: ExpectedMatchSide::Pattern, 2897 2909 } 2898 - | PrettyEafPosition::MatchPattern { .. } 2899 - | PrettyEafPosition::TuplePattern { .. } => { 2910 + | ErlangSourceBuilderPosition::MatchPattern { .. } 2911 + | ErlangSourceBuilderPosition::TuplePattern { .. } => { 2900 2912 invalid_code_for_position!(self, "type") 2901 2913 } 2902 2914 } ··· 2919 2931 match position { 2920 2932 // We're expecting the list's head. We don't have to add 2921 2933 // anything! 2922 - PrettyEafPosition::List { 2934 + ErlangSourceBuilderPosition::List { 2923 2935 kind: ListKind::Pattern, 2924 2936 expected: expected @ ExpectedListItem::First, 2925 2937 } => *expected = ExpectedListItem::Rest, 2926 2938 2927 - PrettyEafPosition::List { 2939 + ErlangSourceBuilderPosition::List { 2928 2940 kind: ListKind::Pattern, 2929 2941 expected: expected @ ExpectedListItem::Rest, 2930 2942 } => { ··· 2932 2944 self.code.push_str(" | ") 2933 2945 } 2934 2946 2935 - PrettyEafPosition::BitArraySegment { 2947 + ErlangSourceBuilderPosition::BitArraySegment { 2936 2948 segment_value_needs_wrapping, 2937 2949 segment_size_needs_wrapping: _, 2938 2950 expected: ··· 2948 2960 2949 2961 // We were waiting for the pattern to be generated, now we're done 2950 2962 // and can start generating an expression for the right-hand side. 2951 - PrettyEafPosition::MatchOperator { 2963 + ErlangSourceBuilderPosition::MatchOperator { 2952 2964 expected: expected @ ExpectedMatchSide::Pattern, 2953 2965 } => { 2954 2966 *expected = ExpectedMatchSide::Expression; ··· 2958 2970 // We don't change this ourselves since the pattern has to be closed 2959 2971 // explicitly calling `end_clause_pattern`. 2960 2972 // We don't have to do anything here! 2961 - PrettyEafPosition::CaseClause { 2973 + ErlangSourceBuilderPosition::CaseClause { 2962 2974 expected: ExpectedCaseClauseItem::Pattern, 2963 2975 } => (), 2964 - PrettyEafPosition::TuplePattern { first } => { 2976 + ErlangSourceBuilderPosition::TuplePattern { first } => { 2965 2977 if *first { 2966 2978 *first = false; 2967 2979 } else { 2968 2980 self.code.push_str(", ") 2969 2981 } 2970 2982 } 2971 - PrettyEafPosition::MatchPattern { expected } => match expected { 2983 + ErlangSourceBuilderPosition::MatchPattern { expected } => match expected { 2972 2984 ExpectedMatchPatternSide::Left => *expected = ExpectedMatchPatternSide::Right, 2973 2985 // The right hand side is about to be generated so we have to 2974 2986 // push the ` = ` to separate it from the left hand side, and we ··· 2980 2992 } 2981 2993 }, 2982 2994 2983 - PrettyEafPosition::FunctionCall { .. } 2984 - | PrettyEafPosition::Block { .. } 2985 - | PrettyEafPosition::FunctionStatement { .. } 2986 - | PrettyEafPosition::AnonymousFunctionStatement { .. } 2987 - | PrettyEafPosition::List { 2995 + ErlangSourceBuilderPosition::FunctionCall { .. } 2996 + | ErlangSourceBuilderPosition::Block { .. } 2997 + | ErlangSourceBuilderPosition::FunctionStatement { .. } 2998 + | ErlangSourceBuilderPosition::AnonymousFunctionStatement { .. } 2999 + | ErlangSourceBuilderPosition::List { 2988 3000 kind: ListKind::Expression, 2989 3001 .. 2990 3002 } 2991 - | PrettyEafPosition::BitArray { .. } 2992 - | PrettyEafPosition::BitArraySegment { 3003 + | ErlangSourceBuilderPosition::BitArray { .. } 3004 + | ErlangSourceBuilderPosition::BitArraySegment { 2993 3005 expected: 2994 3006 BitArraySegmentExpectedItem::Size 2995 3007 | BitArraySegmentExpectedItem::Specifiers ··· 2998 3010 }, 2999 3011 .. 3000 3012 } 3001 - | PrettyEafPosition::UnaryOperator { .. } 3002 - | PrettyEafPosition::BinaryOperator { .. } 3003 - | PrettyEafPosition::Case { .. } 3004 - | PrettyEafPosition::Map { .. } 3005 - | PrettyEafPosition::MapField { .. } 3006 - | PrettyEafPosition::MatchOperator { 3013 + | ErlangSourceBuilderPosition::UnaryOperator { .. } 3014 + | ErlangSourceBuilderPosition::BinaryOperator { .. } 3015 + | ErlangSourceBuilderPosition::Case { .. } 3016 + | ErlangSourceBuilderPosition::Map { .. } 3017 + | ErlangSourceBuilderPosition::MapField { .. } 3018 + | ErlangSourceBuilderPosition::MatchOperator { 3007 3019 expected: ExpectedMatchSide::Expression, 3008 3020 } 3009 - | PrettyEafPosition::Tuple { .. } 3010 - | PrettyEafPosition::FunctionType { .. } 3011 - | PrettyEafPosition::FunctionSpec 3012 - | PrettyEafPosition::TypeSpec { .. } 3013 - | PrettyEafPosition::NamedType { .. } 3014 - | PrettyEafPosition::UnionType { .. } 3015 - | PrettyEafPosition::TupleType { .. } 3016 - | PrettyEafPosition::RecordField { .. } 3017 - | PrettyEafPosition::DocAttribute 3018 - | PrettyEafPosition::RecordAttribute { .. } 3019 - | PrettyEafPosition::List { 3021 + | ErlangSourceBuilderPosition::Tuple { .. } 3022 + | ErlangSourceBuilderPosition::FunctionType { .. } 3023 + | ErlangSourceBuilderPosition::FunctionSpec 3024 + | ErlangSourceBuilderPosition::TypeSpec { .. } 3025 + | ErlangSourceBuilderPosition::NamedType { .. } 3026 + | ErlangSourceBuilderPosition::UnionType { .. } 3027 + | ErlangSourceBuilderPosition::TupleType { .. } 3028 + | ErlangSourceBuilderPosition::RecordField { .. } 3029 + | ErlangSourceBuilderPosition::DocAttribute 3030 + | ErlangSourceBuilderPosition::RecordAttribute { .. } 3031 + | ErlangSourceBuilderPosition::List { 3020 3032 kind: ListKind::Pattern, 3021 3033 expected: ExpectedListItem::ListIsOver, 3022 3034 } 3023 - | PrettyEafPosition::CaseClause { 3035 + | ErlangSourceBuilderPosition::CaseClause { 3024 3036 expected: ExpectedCaseClauseItem::Guards { .. }, 3025 3037 } 3026 - | PrettyEafPosition::CaseClause { 3038 + | ErlangSourceBuilderPosition::CaseClause { 3027 3039 expected: ExpectedCaseClauseItem::Body { .. }, 3028 3040 } => { 3029 3041 invalid_code_for_position!(self, "pattern"); ··· 3041 3053 // When we're done generating statements for a function we need to 3042 3054 // add one final `.` to the last statement. Then we also want to 3043 3055 // add an empty line to make our code breath a bit better. 3044 - PrettyEafPosition::FunctionStatement { .. } => { 3056 + ErlangSourceBuilderPosition::FunctionStatement { .. } => { 3045 3057 self.indentation -= INDENT; 3046 3058 self.code.push_str(".\n") 3047 3059 } 3048 3060 // When we're done generating statements for an anonymous function 3049 3061 // we need to add the closing `end` after the last statement on a 3050 3062 // new line. 3051 - PrettyEafPosition::AnonymousFunctionStatement { .. } => { 3063 + ErlangSourceBuilderPosition::AnonymousFunctionStatement { .. } => { 3052 3064 self.indentation -= INDENT; 3053 3065 self.code.push('\n'); 3054 3066 self.push_indentation(); ··· 3056 3068 } 3057 3069 // When we're done generating statements for a block we need to add 3058 3070 // the closing `end`, and reduce the nesting level. 3059 - PrettyEafPosition::Block { .. } => { 3071 + ErlangSourceBuilderPosition::Block { .. } => { 3060 3072 self.indentation -= INDENT; 3061 3073 self.code.push('\n'); 3062 3074 self.push_indentation(); ··· 3065 3077 // When we're done generating code for a function spec we want to 3066 3078 // add a `.` and go to a new line so we can start generating the 3067 3079 // function itself. 3068 - PrettyEafPosition::FunctionSpec => self.code.push_str(".\n"), 3080 + ErlangSourceBuilderPosition::FunctionSpec => self.code.push_str(".\n"), 3069 3081 // When we're done generating the arguments of a function we need 3070 3082 // to add the closed parentheses for the function call! 3071 - PrettyEafPosition::FunctionCall { 3083 + ErlangSourceBuilderPosition::FunctionCall { 3072 3084 expected: ExpectedCallItem::Arguments { first }, 3073 3085 called_item_needs_wrapping, 3074 3086 } => { ··· 3089 3101 3090 3102 // When we're done generating the items of a tuple we need 3091 3103 // to add the closed curly brace to actually close the tuple. 3092 - PrettyEafPosition::TupleType { .. } 3093 - | PrettyEafPosition::Tuple { .. } 3094 - | PrettyEafPosition::TuplePattern { .. } => self.code.push('}'), 3104 + ErlangSourceBuilderPosition::TupleType { .. } 3105 + | ErlangSourceBuilderPosition::Tuple { .. } 3106 + | ErlangSourceBuilderPosition::TuplePattern { .. } => self.code.push('}'), 3095 3107 // When we're done generating a bit array we can add its closing 3096 3108 // element. 3097 - PrettyEafPosition::BitArray { .. } => self.code.push_str(">>"), 3109 + ErlangSourceBuilderPosition::BitArray { .. } => self.code.push_str(">>"), 3098 3110 3099 3111 // When the function type arguments are over we add what we need for 3100 3112 // the return type. 3101 - PrettyEafPosition::FunctionType { 3113 + ErlangSourceBuilderPosition::FunctionType { 3102 3114 expected: ExpectedFunctionTypeItem::Arguments { .. }, 3103 3115 needs_wrapping, 3104 3116 } => { 3105 3117 // After popping the argument, we now need to wait for the 3106 3118 // return type! 3107 - self.position.push(PrettyEafPosition::FunctionType { 3108 - expected: ExpectedFunctionTypeItem::ReturnType, 3109 - needs_wrapping, 3110 - }); 3119 + self.position 3120 + .push(ErlangSourceBuilderPosition::FunctionType { 3121 + expected: ExpectedFunctionTypeItem::ReturnType, 3122 + needs_wrapping, 3123 + }); 3111 3124 self.code.push_str(") -> ") 3112 3125 } 3113 3126 // When a named type is over we need to add the closing parentheses. 3114 - PrettyEafPosition::NamedType { .. } => self.code.push(')'), 3127 + ErlangSourceBuilderPosition::NamedType { .. } => self.code.push(')'), 3115 3128 // If we close a function type we need to check what the current 3116 3129 // state is. If we were generating this for a type spec we're done. 3117 3130 // But if we were generating this as a type inside another we need to ··· 3128 3141 // % ^ We're adding this bit here! 3129 3142 // wobble() -> fun wibble/0. 3130 3143 // ``` 3131 - PrettyEafPosition::FunctionType { 3144 + ErlangSourceBuilderPosition::FunctionType { 3132 3145 expected: ExpectedFunctionTypeItem::ReturnType, 3133 3146 needs_wrapping, 3134 3147 } => { ··· 3137 3150 } 3138 3151 } 3139 3152 // There's nothing left to do when a union type ends. 3140 - PrettyEafPosition::UnionType { .. } => (), 3153 + ErlangSourceBuilderPosition::UnionType { .. } => (), 3141 3154 // When a doc attribute is closed we need to add the closed 3142 3155 // parentheses and a newline. 3143 - PrettyEafPosition::DocAttribute => self.code.push_str(").\n"), 3156 + ErlangSourceBuilderPosition::DocAttribute => self.code.push_str(").\n"), 3144 3157 // When a case expression is over, we need to add the closing `end`. 3145 - PrettyEafPosition::Case { 3158 + ErlangSourceBuilderPosition::Case { 3146 3159 expected: ExpectedCaseItem::Branches { .. }, 3147 3160 } => { 3148 3161 self.indentation -= INDENT; ··· 3151 3164 self.code.push_str("end"); 3152 3165 } 3153 3166 3154 - PrettyEafPosition::CaseClause { expected } => match expected { 3167 + ErlangSourceBuilderPosition::CaseClause { expected } => match expected { 3155 3168 ExpectedCaseClauseItem::Pattern => (), 3156 3169 // When the guards of a case clause are over we need to add the 3157 3170 // arrow before the body is generated. ··· 3162 3175 }, 3163 3176 // We're done with a map, we can add the closed parentheses and 3164 3177 // reduce nesting. 3165 - PrettyEafPosition::Map { .. } => { 3178 + ErlangSourceBuilderPosition::Map { .. } => { 3166 3179 self.indentation -= INDENT; 3167 3180 self.code.push('\n'); 3168 3181 self.push_indentation(); 3169 3182 self.code.push('}'); 3170 3183 } 3171 - PrettyEafPosition::RecordAttribute { .. } => { 3184 + ErlangSourceBuilderPosition::RecordAttribute { .. } => { 3172 3185 self.indentation -= INDENT; 3173 3186 self.code.push('\n'); 3174 3187 self.push_indentation(); 3175 3188 self.code.push_str("})."); 3176 3189 } 3177 3190 3178 - PrettyEafPosition::MapField { .. } 3179 - | PrettyEafPosition::RecordField { .. } 3180 - | PrettyEafPosition::MatchPattern { .. } 3181 - | PrettyEafPosition::UnaryOperator { .. } 3182 - | PrettyEafPosition::List { .. } 3183 - | PrettyEafPosition::BinaryOperator { .. } 3184 - | PrettyEafPosition::MatchOperator { .. } 3185 - | PrettyEafPosition::TypeSpec { .. } 3186 - | PrettyEafPosition::BitArraySegment { .. } 3187 - | PrettyEafPosition::Case { 3191 + ErlangSourceBuilderPosition::MapField { .. } 3192 + | ErlangSourceBuilderPosition::RecordField { .. } 3193 + | ErlangSourceBuilderPosition::MatchPattern { .. } 3194 + | ErlangSourceBuilderPosition::UnaryOperator { .. } 3195 + | ErlangSourceBuilderPosition::List { .. } 3196 + | ErlangSourceBuilderPosition::BinaryOperator { .. } 3197 + | ErlangSourceBuilderPosition::MatchOperator { .. } 3198 + | ErlangSourceBuilderPosition::TypeSpec { .. } 3199 + | ErlangSourceBuilderPosition::BitArraySegment { .. } 3200 + | ErlangSourceBuilderPosition::Case { 3188 3201 expected: ExpectedCaseItem::Subject, 3189 3202 } 3190 - | PrettyEafPosition::FunctionCall { 3203 + | ErlangSourceBuilderPosition::FunctionCall { 3191 3204 // If we try and close a function for which no called item was 3192 3205 // generated, then that's an error! 3193 3206 expected: ExpectedCallItem::FunctionToBeCalled, ··· 3231 3244 .expect("escaping string in the top level scope"); 3232 3245 3233 3246 match position { 3234 - PrettyEafPosition::FunctionSpec 3235 - | PrettyEafPosition::TypeSpec { .. } 3236 - | PrettyEafPosition::FunctionType { .. } 3237 - | PrettyEafPosition::NamedType { .. } 3238 - | PrettyEafPosition::UnionType { .. } 3239 - | PrettyEafPosition::RecordAttribute { .. } 3240 - | PrettyEafPosition::TupleType { .. } => { 3247 + ErlangSourceBuilderPosition::FunctionSpec 3248 + | ErlangSourceBuilderPosition::TypeSpec { .. } 3249 + | ErlangSourceBuilderPosition::FunctionType { .. } 3250 + | ErlangSourceBuilderPosition::NamedType { .. } 3251 + | ErlangSourceBuilderPosition::UnionType { .. } 3252 + | ErlangSourceBuilderPosition::RecordAttribute { .. } 3253 + | ErlangSourceBuilderPosition::TupleType { .. } => { 3241 3254 invalid_code_for_position!(self, "escaping string") 3242 3255 } 3243 3256 3244 - PrettyEafPosition::FunctionCall { .. } 3245 - | PrettyEafPosition::FunctionStatement { .. } 3246 - | PrettyEafPosition::AnonymousFunctionStatement { .. } 3247 - | PrettyEafPosition::List { .. } 3248 - | PrettyEafPosition::UnaryOperator { .. } 3249 - | PrettyEafPosition::Tuple { .. } 3250 - | PrettyEafPosition::TuplePattern { .. } 3251 - | PrettyEafPosition::BitArray { .. } 3252 - | PrettyEafPosition::BitArraySegment { .. } 3253 - | PrettyEafPosition::Block { .. } 3254 - | PrettyEafPosition::BinaryOperator { .. } 3255 - | PrettyEafPosition::Case { .. } 3256 - | PrettyEafPosition::CaseClause { .. } 3257 - | PrettyEafPosition::Map { .. } 3258 - | PrettyEafPosition::MapField { .. } 3259 - | PrettyEafPosition::MatchPattern { .. } 3260 - | PrettyEafPosition::RecordField { .. } 3261 - | PrettyEafPosition::MatchOperator { .. } => { 3257 + ErlangSourceBuilderPosition::FunctionCall { .. } 3258 + | ErlangSourceBuilderPosition::FunctionStatement { .. } 3259 + | ErlangSourceBuilderPosition::AnonymousFunctionStatement { .. } 3260 + | ErlangSourceBuilderPosition::List { .. } 3261 + | ErlangSourceBuilderPosition::UnaryOperator { .. } 3262 + | ErlangSourceBuilderPosition::Tuple { .. } 3263 + | ErlangSourceBuilderPosition::TuplePattern { .. } 3264 + | ErlangSourceBuilderPosition::BitArray { .. } 3265 + | ErlangSourceBuilderPosition::BitArraySegment { .. } 3266 + | ErlangSourceBuilderPosition::Block { .. } 3267 + | ErlangSourceBuilderPosition::BinaryOperator { .. } 3268 + | ErlangSourceBuilderPosition::Case { .. } 3269 + | ErlangSourceBuilderPosition::CaseClause { .. } 3270 + | ErlangSourceBuilderPosition::Map { .. } 3271 + | ErlangSourceBuilderPosition::MapField { .. } 3272 + | ErlangSourceBuilderPosition::MatchPattern { .. } 3273 + | ErlangSourceBuilderPosition::RecordField { .. } 3274 + | ErlangSourceBuilderPosition::MatchOperator { .. } => { 3262 3275 // When pretty printing we want the resulting code to be regular 3263 3276 // executable Erlang code. 3264 3277 // If we're tasked with escaping the content of a literal string ··· 3283 3296 .into() 3284 3297 } 3285 3298 3286 - PrettyEafPosition::DocAttribute => { 3299 + ErlangSourceBuilderPosition::DocAttribute => { 3287 3300 // Escaping strings generated inside doc attributes is a little 3288 3301 // different: since their content doesn't come from a Gleam 3289 3302 // literal string but freeform text, their content might contain ··· 3296 3309 #[must_use] 3297 3310 fn new_bit_array_segment(&mut self) -> BitArrayKind { 3298 3311 self.pop_leftover_items(); 3299 - let Some(PrettyEafPosition::BitArray { first, kind }) = self.position.last_mut() else { 3312 + let Some(ErlangSourceBuilderPosition::BitArray { first, kind }) = self.position.last_mut() 3313 + else { 3300 3314 invalid_code_for_position!(self, "bit array segment") 3301 3315 }; 3302 3316 ··· 3311 3325 3312 3326 fn new_case_clause(&mut self) { 3313 3327 self.pop_leftover_items(); 3314 - let Some(PrettyEafPosition::Case { 3328 + let Some(ErlangSourceBuilderPosition::Case { 3315 3329 expected: ExpectedCaseItem::Branches { first }, 3316 3330 }) = self.position.last_mut() 3317 3331 else { ··· 3330 3344 3331 3345 fn new_map_field(&mut self) { 3332 3346 self.pop_leftover_items(); 3333 - let Some(PrettyEafPosition::Map { first }) = self.position.last_mut() else { 3347 + let Some(ErlangSourceBuilderPosition::Map { first }) = self.position.last_mut() else { 3334 3348 invalid_code_for_position!(self, "map field"); 3335 3349 }; 3336 3350 ··· 3363 3377 // If we're about to generate a bit array segment value, or a size, 3364 3378 // then we can skip the wrapping, otherwise this is not needed at all! 3365 3379 match self.position.last_mut() { 3366 - Some(PrettyEafPosition::BitArraySegment { 3380 + Some(ErlangSourceBuilderPosition::BitArraySegment { 3367 3381 segment_value_needs_wrapping, 3368 3382 expected: BitArraySegmentExpectedItem::Value { .. }, 3369 3383 .. 3370 3384 }) => *segment_value_needs_wrapping = false, 3371 - Some(PrettyEafPosition::BitArraySegment { 3385 + Some(ErlangSourceBuilderPosition::BitArraySegment { 3372 3386 segment_size_needs_wrapping, 3373 3387 expected: BitArraySegmentExpectedItem::Size, 3374 3388 .. ··· 3385 3399 // output slightly different code: rather than a bit array we want to 3386 3400 // output a regular string with no modifiers which are going to be added 3387 3401 // later as the segment is created 3388 - if let Some(PrettyEafPosition::BitArraySegment { 3402 + if let Some(ErlangSourceBuilderPosition::BitArraySegment { 3389 3403 // the call to `new_expression` at the beginning is going to advance 3390 3404 // the state to expect the `::Size`, that means the code we are 3391 3405 // outputting now was expected to be the the `::Value` of the bit ··· 3414 3428 // If we were expecting the rest of a list and we generate a new 3415 3429 // cons cell we can keep adding commas to separate items: we want 3416 3430 // to show `[1, 2, 3]` rather than `[1 | [2 | [3 | []]]]` 3417 - Some(PrettyEafPosition::List { 3431 + Some(ErlangSourceBuilderPosition::List { 3418 3432 kind, 3419 3433 expected: expected @ ExpectedListItem::Rest, 3420 3434 }) if *kind == list_kind => { ··· 3429 3443 ListKind::Expression => self.new_expression(), 3430 3444 } 3431 3445 self.code.push('['); 3432 - self.position.push(PrettyEafPosition::List { 3446 + self.position.push(ErlangSourceBuilderPosition::List { 3433 3447 kind: list_kind, 3434 3448 expected: ExpectedListItem::First, 3435 3449 }); ··· 3443 3457 // If we were building a cons list and were expecting the end of the 3444 3458 // list then we have to special case this: we don't want to render 3445 3459 // it as: `[1, 2 | []]`, but as `[1, 2]`. 3446 - Some(PrettyEafPosition::List { 3460 + Some(ErlangSourceBuilderPosition::List { 3447 3461 kind, 3448 3462 expected: ExpectedListItem::Rest, 3449 3463 }) if *kind == list_kind => { ··· 3475 3489 }; 3476 3490 3477 3491 match position { 3478 - PrettyEafPosition::TypeSpec { 3492 + ErlangSourceBuilderPosition::TypeSpec { 3479 3493 expected: TypeSpecExpectedItem::TypeSpecIsOver, 3480 3494 } => { 3481 3495 self.code.push_str(".\n"); ··· 3488 3502 // are built as a list of cons cells, so we can't really 3489 3503 // tell when a list is over until we get to the next 3490 3504 // expression. 3491 - PrettyEafPosition::List { 3505 + ErlangSourceBuilderPosition::List { 3492 3506 expected: ExpectedListItem::ListIsOver, 3493 3507 .. 3494 3508 } => { ··· 3505 3519 // the current item and notice there's a closed operator left). 3506 3520 // Also, just like lists, we might still need to add some 3507 3521 // parentheses _after_ the operator is over. 3508 - PrettyEafPosition::BinaryOperator { 3522 + ErlangSourceBuilderPosition::BinaryOperator { 3509 3523 expected: ExpectedBinaryOperatorSide::BinaryOperatorIsOver, 3510 3524 needs_wrapping, 3511 3525 .. ··· 3523 3537 3524 3538 // All of these items are not leftovers. They are either still open, 3525 3539 // require manual closing, or things that don't need closing at all! 3526 - PrettyEafPosition::NamedType { .. } 3527 - | PrettyEafPosition::UnionType { .. } 3528 - | PrettyEafPosition::TupleType { .. } 3529 - | PrettyEafPosition::FunctionStatement { .. } 3530 - | PrettyEafPosition::AnonymousFunctionStatement { .. } 3531 - | PrettyEafPosition::DocAttribute 3532 - | PrettyEafPosition::FunctionSpec 3533 - | PrettyEafPosition::Tuple { .. } 3534 - | PrettyEafPosition::TuplePattern { .. } 3535 - | PrettyEafPosition::BitArray { .. } 3536 - | PrettyEafPosition::Map { .. } 3537 - | PrettyEafPosition::Block { .. } 3538 - | PrettyEafPosition::UnaryOperator { .. } 3539 - | PrettyEafPosition::FunctionType { 3540 + ErlangSourceBuilderPosition::NamedType { .. } 3541 + | ErlangSourceBuilderPosition::UnionType { .. } 3542 + | ErlangSourceBuilderPosition::TupleType { .. } 3543 + | ErlangSourceBuilderPosition::FunctionStatement { .. } 3544 + | ErlangSourceBuilderPosition::AnonymousFunctionStatement { .. } 3545 + | ErlangSourceBuilderPosition::DocAttribute 3546 + | ErlangSourceBuilderPosition::FunctionSpec 3547 + | ErlangSourceBuilderPosition::Tuple { .. } 3548 + | ErlangSourceBuilderPosition::TuplePattern { .. } 3549 + | ErlangSourceBuilderPosition::BitArray { .. } 3550 + | ErlangSourceBuilderPosition::Map { .. } 3551 + | ErlangSourceBuilderPosition::Block { .. } 3552 + | ErlangSourceBuilderPosition::UnaryOperator { .. } 3553 + | ErlangSourceBuilderPosition::FunctionType { 3540 3554 expected: 3541 3555 ExpectedFunctionTypeItem::Arguments { .. } | ExpectedFunctionTypeItem::ReturnType, 3542 3556 .. 3543 3557 } 3544 - | PrettyEafPosition::TypeSpec { 3558 + | ErlangSourceBuilderPosition::TypeSpec { 3545 3559 expected: TypeSpecExpectedItem::TypeDefinition, 3546 3560 } 3547 - | PrettyEafPosition::MapField { 3561 + | ErlangSourceBuilderPosition::MapField { 3548 3562 expected: MapFieldExpectedItem::Key | MapFieldExpectedItem::Value, 3549 3563 } 3550 - | PrettyEafPosition::List { 3564 + | ErlangSourceBuilderPosition::List { 3551 3565 expected: ExpectedListItem::First | ExpectedListItem::Rest, 3552 3566 .. 3553 3567 } 3554 - | PrettyEafPosition::BitArraySegment { 3568 + | ErlangSourceBuilderPosition::BitArraySegment { 3555 3569 expected: 3556 3570 BitArraySegmentExpectedItem::Size 3557 3571 | BitArraySegmentExpectedItem::Specifiers 3558 3572 | BitArraySegmentExpectedItem::Value { .. }, 3559 3573 .. 3560 3574 } 3561 - | PrettyEafPosition::FunctionCall { 3575 + | ErlangSourceBuilderPosition::FunctionCall { 3562 3576 expected: ExpectedCallItem::Arguments { .. } | ExpectedCallItem::FunctionToBeCalled, 3563 3577 .. 3564 3578 } 3565 - | PrettyEafPosition::MatchPattern { 3579 + | ErlangSourceBuilderPosition::MatchPattern { 3566 3580 expected: ExpectedMatchPatternSide::Left | ExpectedMatchPatternSide::Right, 3567 3581 } 3568 - | PrettyEafPosition::Case { 3582 + | ErlangSourceBuilderPosition::Case { 3569 3583 expected: ExpectedCaseItem::Subject | ExpectedCaseItem::Branches { .. }, 3570 3584 } 3571 - | PrettyEafPosition::CaseClause { 3585 + | ErlangSourceBuilderPosition::CaseClause { 3572 3586 expected: 3573 3587 ExpectedCaseClauseItem::Pattern 3574 3588 | ExpectedCaseClauseItem::Guards { .. } 3575 3589 | ExpectedCaseClauseItem::Body { .. }, 3576 3590 } 3577 - | PrettyEafPosition::BinaryOperator { 3591 + | ErlangSourceBuilderPosition::BinaryOperator { 3578 3592 expected: ExpectedBinaryOperatorSide::Left | ExpectedBinaryOperatorSide::Right, 3579 3593 .. 3580 3594 } 3581 - | PrettyEafPosition::RecordAttribute { .. } 3582 - | PrettyEafPosition::MatchOperator { 3595 + | ErlangSourceBuilderPosition::RecordAttribute { .. } 3596 + | ErlangSourceBuilderPosition::MatchOperator { 3583 3597 expected: ExpectedMatchSide::Expression | ExpectedMatchSide::Pattern, 3584 3598 } 3585 - | PrettyEafPosition::RecordField { .. } => (), 3599 + | ErlangSourceBuilderPosition::RecordField { .. } => (), 3586 3600 } 3587 3601 } 3588 3602 3589 3603 fn new_record_field(&mut self) { 3590 3604 self.pop_leftover_items(); 3591 - let Some(PrettyEafPosition::RecordAttribute { first }) = self.position.last_mut() else { 3605 + let Some(ErlangSourceBuilderPosition::RecordAttribute { first }) = self.position.last_mut() 3606 + else { 3592 3607 panic!("tried generating record field outside of record attribute"); 3593 3608 }; 3594 3609