@@ -6,40 +6,33 @@ use crate::analyse::Inferred;
66
77use super :: * ;
88
9- pub ( super ) struct PatternAssignment < ' a > {
10- pub variable : & ' a EcoString ,
11- pub value : Document < ' a > ,
12- }
13-
149pub ( super ) fn pattern < ' a > (
1510 p : & ' a TypedPattern ,
1611 env : & mut Env < ' a > ,
1712 guards : & mut Vec < Document < ' a > > ,
18- assignments : & mut Vec < PatternAssignment < ' a > > ,
1913) -> Document < ' a > {
2014 let mut vars = vec ! [ ] ;
21- to_doc ( p, & mut vars, env, guards, assignments )
15+ to_doc ( p, & mut vars, env, guards)
2216}
2317
2418fn print < ' a > (
2519 p : & ' a TypedPattern ,
2620 vars : & mut Vec < & ' a str > ,
2721 env : & mut Env < ' a > ,
2822 guards : & mut Vec < Document < ' a > > ,
29- assignments : & mut Vec < PatternAssignment < ' a > > ,
3023) -> Document < ' a > {
3124 match p {
3225 Pattern :: Assign {
3326 name, pattern : p, ..
3427 } => {
3528 vars. push ( name) ;
36- print ( p, vars, env, guards, assignments )
29+ print ( p, vars, env, guards)
3730 . append ( " = " )
3831 . append ( env. next_local_var_name ( name) )
3932 }
4033
4134 Pattern :: List { elements, tail, .. } => {
42- pattern_list ( elements, tail. as_deref ( ) , vars, env, guards, assignments )
35+ pattern_list ( elements, tail. as_deref ( ) , vars, env, guards)
4336 }
4437
4538 Pattern :: Discard { .. } => "_" . to_doc ( ) ,
@@ -74,7 +67,7 @@ fn print<'a>(
7467 arguments : args,
7568 constructor : Inferred :: Known ( PatternConstructor { name, .. } ) ,
7669 ..
77- } => tag_tuple_pattern ( name, args, vars, env, guards, assignments ) ,
70+ } => tag_tuple_pattern ( name, args, vars, env, guards) ,
7871
7972 Pattern :: Constructor {
8073 constructor : Inferred :: Unknown ,
@@ -83,16 +76,14 @@ fn print<'a>(
8376 panic ! ( "Erlang generation performed with uninferred pattern constructor" )
8477 }
8578
86- Pattern :: Tuple { elements, .. } => tuple (
87- elements
88- . iter ( )
89- . map ( |p| print ( p, vars, env, guards, assignments) ) ,
90- ) ,
79+ Pattern :: Tuple { elements, .. } => {
80+ tuple ( elements. iter ( ) . map ( |p| print ( p, vars, env, guards) ) )
81+ }
9182
9283 Pattern :: BitArray { segments, .. } => bit_array (
9384 segments
9485 . iter ( )
95- . map ( |s| pattern_segment ( s , vars, env, guards, assignments ) ) ,
86+ . map ( |s| pattern_segment ( & s . value , & s . options , vars, env, guards) ) ,
9687 ) ,
9788
9889 Pattern :: StringPrefix {
@@ -156,9 +147,8 @@ pub(super) fn to_doc<'a>(
156147 vars : & mut Vec < & ' a str > ,
157148 env : & mut Env < ' a > ,
158149 guards : & mut Vec < Document < ' a > > ,
159- assignments : & mut Vec < PatternAssignment < ' a > > ,
160150) -> Document < ' a > {
161- print ( p, vars, env, guards, assignments )
151+ print ( p, vars, env, guards)
162152}
163153
164154fn tag_tuple_pattern < ' a > (
@@ -167,62 +157,39 @@ fn tag_tuple_pattern<'a>(
167157 vars : & mut Vec < & ' a str > ,
168158 env : & mut Env < ' a > ,
169159 guards : & mut Vec < Document < ' a > > ,
170- assignments : & mut Vec < PatternAssignment < ' a > > ,
171160) -> Document < ' a > {
172161 if args. is_empty ( ) {
173162 atom_string ( to_snake_case ( name) )
174163 } else {
175164 tuple (
176- [ atom_string ( to_snake_case ( name) ) ] . into_iter ( ) . chain (
177- args. iter ( )
178- . map ( |p| print ( & p. value , vars, env, guards, assignments) ) ,
179- ) ,
165+ [ atom_string ( to_snake_case ( name) ) ]
166+ . into_iter ( )
167+ . chain ( args. iter ( ) . map ( |p| print ( & p. value , vars, env, guards) ) ) ,
180168 )
181169 }
182170}
183171
184172fn pattern_segment < ' a > (
185- segment : & ' a TypedPatternBitArraySegment ,
173+ value : & ' a TypedPattern ,
174+ options : & ' a [ BitArrayOption < TypedPattern > ] ,
186175 vars : & mut Vec < & ' a str > ,
187176 env : & mut Env < ' a > ,
188177 guards : & mut Vec < Document < ' a > > ,
189- assignments : & mut Vec < PatternAssignment < ' a > > ,
190178) -> Document < ' a > {
191- let value = segment. value . as_ref ( ) ;
192-
193- let pattern_is_a_string_literal = match value {
194- Pattern :: String { .. } => true ,
195- Pattern :: Assign { pattern, .. } => pattern. is_string ( ) ,
196- Pattern :: Int { .. }
197- | Pattern :: Float { .. }
198- | Pattern :: Variable { .. }
199- | Pattern :: VarUsage { .. }
200- | Pattern :: Discard { .. }
201- | Pattern :: List { .. }
202- | Pattern :: Constructor { .. }
203- | Pattern :: Tuple { .. }
204- | Pattern :: BitArray { .. }
205- | Pattern :: StringPrefix { .. }
206- | Pattern :: Invalid { .. } => false ,
207- } ;
179+ let pattern_is_a_string_literal = matches ! ( value, Pattern :: String { .. } ) ;
208180 let pattern_is_a_discard = matches ! ( value, Pattern :: Discard { .. } ) ;
209181
210182 let vars = RefCell :: new ( vars) ;
211183 let guards = RefCell :: new ( guards) ;
212- let assignments = RefCell :: new ( assignments) ;
213184
214185 let create_document = |env : & mut Env < ' a > | match value {
215186 Pattern :: String { value, .. } => value. to_doc ( ) . surround ( "\" " , "\" " ) ,
216187 Pattern :: Discard { .. }
217188 | Pattern :: Variable { .. }
218189 | Pattern :: Int { .. }
219- | Pattern :: Float { .. } => print (
220- value,
221- & mut vars. borrow_mut ( ) ,
222- env,
223- & mut guards. borrow_mut ( ) ,
224- & mut assignments. borrow_mut ( ) ,
225- ) ,
190+ | Pattern :: Float { .. } => {
191+ print ( value, & mut vars. borrow_mut ( ) , env, & mut guards. borrow_mut ( ) )
192+ }
226193
227194 Pattern :: Assign { name, pattern, .. } => {
228195 vars. borrow_mut ( ) . push ( name) ;
@@ -244,24 +211,16 @@ fn pattern_segment<'a>(
244211 variable_name
245212 }
246213
247- // If we are assigning to a string which is UTF-16 or UTF-32, we cannot simply use
248- // variable patterns and guards like we do with other segments. Gleam strings are
249- // UTF-8 so we must anyway bind the correct value to the variable. We generate code
250- // that looks like this:
251- //
252- // ```erlang
253- // case X of
254- // <<"Hello"/utf16>> ->
255- // Message = <<"Hello"/utf8>>,
256- // <clause body>
257- // end.
258- // ```
214+ // Here we do the same as for floats and ints, but we must calculate the size of
215+ // the string first, so we can correctly match the bit array segment then compare
216+ // it afterwards.
259217 Pattern :: String { value, .. } => {
260- assignments. borrow_mut ( ) . push ( PatternAssignment {
261- variable : name,
262- value : string ( value) ,
263- } ) ;
264- value. to_doc ( ) . surround ( "\" " , "\" " )
218+ guards. borrow_mut ( ) . push ( docvec ! [
219+ variable_name. clone( ) ,
220+ " =:= " ,
221+ string( value)
222+ ] ) ;
223+ docvec ! [ variable_name, ":" , string_length_utf8_bytes( value) ]
265224 }
266225
267226 // Doing a pattern such as `<<_ as a>>` is the same as just `<<a>>`, so we treat it
@@ -283,15 +242,14 @@ fn pattern_segment<'a>(
283242 & mut vars. borrow_mut ( ) ,
284243 env,
285244 & mut guards. borrow_mut ( ) ,
286- & mut assignments. borrow_mut ( ) ,
287245 ) ) )
288246 } ;
289247
290248 let unit = |value : & ' a u8 | Some ( eco_format ! ( "unit:{value}" ) . to_doc ( ) ) ;
291249
292250 bit_array_segment (
293251 create_document,
294- & segment . options ,
252+ options,
295253 size,
296254 unit,
297255 pattern_is_a_string_literal,
@@ -306,14 +264,13 @@ fn pattern_list<'a>(
306264 vars : & mut Vec < & ' a str > ,
307265 env : & mut Env < ' a > ,
308266 guards : & mut Vec < Document < ' a > > ,
309- assignments : & mut Vec < PatternAssignment < ' a > > ,
310267) -> Document < ' a > {
311268 let elements = join (
312269 elements
313270 . iter ( )
314- . map ( |element| print ( element, vars, env, guards, assignments ) ) ,
271+ . map ( |element| print ( element, vars, env, guards) ) ,
315272 break_ ( "," , ", " ) ,
316273 ) ;
317- let tail = tail. map ( |tail| print ( tail, vars, env, guards, assignments ) ) ;
274+ let tail = tail. map ( |tail| print ( tail, vars, env, guards) ) ;
318275 list ( elements, tail)
319276}
0 commit comments