@@ -7,6 +7,7 @@ mod pattern;
77mod tests;
88
99use crate :: build:: { Target , module_erlang_name} ;
10+ use crate :: erlang:: pattern:: PatternPrinter ;
1011use crate :: strings:: { convert_string_escape_chars, to_snake_case} ;
1112use crate :: type_:: is_prelude_module;
1213use crate :: {
@@ -959,18 +960,18 @@ fn expr_segment<'a>(
959960 )
960961}
961962
962- fn bit_array_segment < ' a , Value : ' a , CreateDoc , SizeToDoc , UnitToDoc > (
963+ fn bit_array_segment < ' a , Value : ' a , CreateDoc , SizeToDoc , UnitToDoc , State > (
963964 mut create_document : CreateDoc ,
964965 options : & ' a [ BitArrayOption < Value > ] ,
965966 mut size_to_doc : SizeToDoc ,
966967 mut unit_to_doc : UnitToDoc ,
967968 value_is_a_string_literal : bool ,
968969 value_is_a_discard : bool ,
969- env : & mut Env < ' a > ,
970+ state : & mut State ,
970971) -> Document < ' a >
971972where
972- CreateDoc : FnMut ( & mut Env < ' a > ) -> Document < ' a > ,
973- SizeToDoc : FnMut ( & ' a Value , & mut Env < ' a > ) -> Option < Document < ' a > > ,
973+ CreateDoc : FnMut ( & mut State ) -> Document < ' a > ,
974+ SizeToDoc : FnMut ( & ' a Value , & mut State ) -> Option < Document < ' a > > ,
974975 UnitToDoc : FnMut ( & ' a u8 ) -> Option < Document < ' a > > ,
975976{
976977 let mut size: Option < Document < ' a > > = None ;
@@ -1007,12 +1008,12 @@ where
10071008 Opt :: Big { .. } => others. push ( "big" . to_doc ( ) ) ,
10081009 Opt :: Little { .. } => others. push ( "little" . to_doc ( ) ) ,
10091010 Opt :: Native { .. } => others. push ( "native" . to_doc ( ) ) ,
1010- Opt :: Size { value, .. } => size = size_to_doc ( value, env ) ,
1011+ Opt :: Size { value, .. } => size = size_to_doc ( value, state ) ,
10111012 Opt :: Unit { value, .. } => unit = unit_to_doc ( value) ,
10121013 }
10131014 }
10141015
1015- let mut document = create_document ( env ) ;
1016+ let mut document = create_document ( state ) ;
10161017
10171018 document = document. append ( size) ;
10181019 let others_is_empty = others. is_empty ( ) ;
@@ -1180,23 +1181,23 @@ fn binop_documents<'a>(left: Document<'a>, op: &'static str, right: Document<'a>
11801181fn let_assert < ' a > (
11811182 value : & ' a TypedExpr ,
11821183 pattern : & ' a TypedPattern ,
1183- env : & mut Env < ' a > ,
1184+ environment : & mut Env < ' a > ,
11841185 message : Option < & ' a TypedExpr > ,
11851186 position : Position ,
11861187 location : SrcSpan ,
11871188) -> Document < ' a > {
11881189 // If the pattern will never fail, like a tuple or a simple variable, we
11891190 // simply treat it as if it were a `let` assignment.
11901191 if pattern. always_matches ( ) {
1191- return let_ ( value, pattern, env ) ;
1192+ return let_ ( value, pattern, environment ) ;
11921193 }
11931194
11941195 let message = match message {
1195- Some ( message) => expr ( message, env ) ,
1196+ Some ( message) => expr ( message, environment ) ,
11961197 None => string ( "Pattern match failed, no pattern matched the value." ) ,
11971198 } ;
11981199
1199- let subject = maybe_block_expr ( value, env ) ;
1200+ let subject = maybe_block_expr ( value, environment ) ;
12001201
12011202 // The code we generated for a `let assert` assignment looks something like
12021203 // this. For this Gleam code:
@@ -1248,26 +1249,31 @@ fn let_assert<'a>(
12481249 } ;
12491250
12501251 let ( subject_assignment, subject) = if is_tail && !value. is_var ( ) {
1251- let variable = env . next_local_var_name ( ASSERT_SUBJECT_VARIABLE ) ;
1252+ let variable = environment . next_local_var_name ( ASSERT_SUBJECT_VARIABLE ) ;
12521253 let assignment = docvec ! [ variable. clone( ) , " = " , subject, "," , line( ) ] ;
12531254 ( assignment, variable)
12541255 } else {
12551256 ( nil ( ) , subject)
12561257 } ;
12571258
1258- let mut guards = vec ! [ ] ;
1259- let mut vars = vec ! [ ] ;
1260- let pattern_document = pattern:: to_doc ( pattern, & mut vars, env, & mut guards) ;
1261- let clause_guard = optional_clause_guard ( None , guards, env) ;
1259+ let mut pattern_printer = PatternPrinter :: new ( environment) ;
1260+ let pattern_document = pattern_printer. print ( pattern) ;
1261+ let PatternPrinter {
1262+ environment,
1263+ variables,
1264+ guards,
1265+ } = pattern_printer;
1266+
1267+ let clause_guard = optional_clause_guard ( None , guards, environment) ;
12621268
1263- let value_document = match vars . as_slice ( ) {
1269+ let value_document = match variables . as_slice ( ) {
12641270 _ if is_tail => subject. clone ( ) ,
12651271 [ ] => "nil" . to_doc ( ) ,
1266- [ variable] => env . local_var_name ( variable) ,
1272+ [ variable] => environment . local_var_name ( variable) ,
12671273 variables => {
12681274 let variables = variables
12691275 . iter ( )
1270- . map ( |variable| env . local_var_name ( variable) ) ;
1276+ . map ( |variable| environment . local_var_name ( variable) ) ;
12711277 docvec ! [
12721278 break_( "{" , "{" ) ,
12731279 join( variables, break_( "," , ", " ) ) . nest( INDENT ) ,
@@ -1277,14 +1283,14 @@ fn let_assert<'a>(
12771283 }
12781284 } ;
12791285
1280- let assignment = match vars . as_slice ( ) {
1286+ let assignment = match variables . as_slice ( ) {
12811287 _ if is_tail => nil ( ) ,
12821288 [ ] => nil ( ) ,
1283- [ variable] => env . next_local_var_name ( variable) . append ( " = " ) ,
1289+ [ variable] => environment . next_local_var_name ( variable) . append ( " = " ) ,
12841290 variables => {
12851291 let variables = variables
12861292 . iter ( )
1287- . map ( |variable| env . next_local_var_name ( variable) ) ;
1293+ . map ( |variable| environment . next_local_var_name ( variable) ) ;
12881294 docvec ! [
12891295 break_( "{" , "{" ) ,
12901296 join( variables, break_( "," , ", " ) ) . nest( INDENT ) ,
@@ -1301,7 +1307,7 @@ fn let_assert<'a>(
13011307 value_document,
13021308 ";" ,
13031309 line( ) ,
1304- env . next_local_var_name( ASSERT_FAIL_VARIABLE ) ,
1310+ environment . next_local_var_name( ASSERT_FAIL_VARIABLE ) ,
13051311 " ->" ,
13061312 docvec![
13071313 line( ) ,
@@ -1310,13 +1316,13 @@ fn let_assert<'a>(
13101316 & message,
13111317 location,
13121318 vec![
1313- ( "value" , env . local_var_name( ASSERT_FAIL_VARIABLE ) ) ,
1319+ ( "value" , environment . local_var_name( ASSERT_FAIL_VARIABLE ) ) ,
13141320 ( "start" , location. start. to_doc( ) ) ,
13151321 ( "'end'" , value. location( ) . end. to_doc( ) ) ,
13161322 ( "pattern_start" , pattern. location( ) . start. to_doc( ) ) ,
13171323 ( "pattern_end" , pattern. location( ) . end. to_doc( ) ) ,
13181324 ] ,
1319- env ,
1325+ environment ,
13201326 )
13211327 . nest( INDENT )
13221328 ]
@@ -1334,11 +1340,14 @@ fn let_assert<'a>(
13341340 ]
13351341}
13361342
1337- fn let_ < ' a > ( value : & ' a TypedExpr , pat : & ' a TypedPattern , env : & mut Env < ' a > ) -> Document < ' a > {
1338- let body = maybe_block_expr ( value, env) . group ( ) ;
1339- let mut guards = vec ! [ ] ;
1340-
1341- pattern:: to_doc ( pat, & mut vec ! [ ] , env, & mut guards)
1343+ fn let_ < ' a > (
1344+ value : & ' a TypedExpr ,
1345+ pattern : & ' a TypedPattern ,
1346+ environment : & mut Env < ' a > ,
1347+ ) -> Document < ' a > {
1348+ let body = maybe_block_expr ( value, environment) . group ( ) ;
1349+ PatternPrinter :: new ( environment)
1350+ . print ( pattern)
13421351 . append ( " = " )
13431352 . append ( body)
13441353}
@@ -1530,7 +1539,7 @@ fn record_constructor_function(tag: &EcoString, arity: usize) -> Document<'_> {
15301539 . append ( "} end" )
15311540}
15321541
1533- fn clause < ' a > ( clause : & ' a TypedClause , env : & mut Env < ' a > ) -> Document < ' a > {
1542+ fn clause < ' a > ( clause : & ' a TypedClause , environment : & mut Env < ' a > ) -> Document < ' a > {
15341543 let Clause {
15351544 guard,
15361545 pattern : pat,
@@ -1544,29 +1553,36 @@ fn clause<'a>(clause: &'a TypedClause, env: &mut Env<'a>) -> Document<'a> {
15441553 // rewriting because each pattern would define different (rewritten)
15451554 // variables names.
15461555 let mut then_doc = None ;
1547- let initial_erlang_vars = env . erl_function_scope_vars . clone ( ) ;
1556+ let initial_erlang_vars = environment . erl_function_scope_vars . clone ( ) ;
15481557 let mut end_erlang_vars = im:: HashMap :: new ( ) ;
15491558
15501559 let doc = join (
15511560 std:: iter:: once ( pat)
15521561 . chain ( alternative_patterns)
15531562 . map ( |patterns| {
1554- let mut additional_guards = vec ! [ ] ;
1555- env . erl_function_scope_vars = initial_erlang_vars . clone ( ) ;
1563+ environment . erl_function_scope_vars = initial_erlang_vars . clone ( ) ;
1564+ let mut pattern_printer = PatternPrinter :: new ( environment ) ;
15561565
15571566 let patterns_doc = if patterns. len ( ) == 1 {
1558- let p = patterns. first ( ) . expect ( "Single pattern clause printing" ) ;
1559- pattern :: to_doc ( p , & mut vec ! [ ] , env , & mut additional_guards )
1567+ let pattern = patterns. first ( ) . expect ( "Single pattern clause printing" ) ;
1568+ pattern_printer . print ( pattern )
15601569 } else {
15611570 tuple ( patterns. iter ( ) . map ( |pattern| {
1562- pattern:: to_doc ( pattern, & mut vec ! [ ] , env, & mut additional_guards)
1571+ pattern_printer. reset_variables ( ) ;
1572+ pattern_printer. print ( pattern)
15631573 } ) )
15641574 } ;
15651575
1566- let guard = optional_clause_guard ( guard. as_ref ( ) , additional_guards, env) ;
1576+ let PatternPrinter {
1577+ environment,
1578+ guards,
1579+ variables : _,
1580+ } = pattern_printer;
1581+
1582+ let guard = optional_clause_guard ( guard. as_ref ( ) , guards, environment) ;
15671583 if then_doc. is_none ( ) {
1568- then_doc = Some ( clause_consequence ( then, env ) ) ;
1569- end_erlang_vars = env . erl_function_scope_vars . clone ( ) ;
1584+ then_doc = Some ( clause_consequence ( then, environment ) ) ;
1585+ end_erlang_vars = environment . erl_function_scope_vars . clone ( ) ;
15701586 }
15711587
15721588 patterns_doc. append (
@@ -1578,7 +1594,7 @@ fn clause<'a>(clause: &'a TypedClause, env: &mut Env<'a>) -> Document<'a> {
15781594 ";" . to_doc ( ) . append ( lines ( 2 ) ) ,
15791595 ) ;
15801596
1581- env . erl_function_scope_vars = end_erlang_vars;
1597+ environment . erl_function_scope_vars = end_erlang_vars;
15821598 doc
15831599}
15841600
0 commit comments