@@ -93,19 +93,20 @@ fn match_error(cx: &ext_ctxt, m: &matchable, expected: &str) -> ! {
93
93
type match_result = option:: t [ arb_depth[ matchable] ] ;
94
94
type selector = fn ( & matchable ) -> match_result ;
95
95
96
- fn elts_to_ell ( cx : & ext_ctxt , elts : & ( @expr) [ ] ) -> option:: t [ @expr] {
96
+ fn elts_to_ell ( cx : & ext_ctxt , elts : & ( @expr) [ ] )
97
+ -> { fixed : ( @expr) [ ] , rep: option:: t[ @expr] } {
97
98
let idx: uint = 0 u;
98
99
for elt: @expr in elts {
99
100
alt elt. node {
100
101
expr_mac ( m) {
101
102
alt m. node {
102
103
ast:: mac_ellipsis. {
103
- if idx != 1 u || ivec:: len ( elts) != 2 u {
104
- cx. span_fatal ( m. span ,
105
- "Ellpisis may only appear" +
106
- " after exactly 1 item." ) ;
104
+ let last = ivec:: len ( elts) - 1 u;
105
+ if idx != last {
106
+ cx. span_fatal ( m. span , "ellipses must occur last" ) ;
107
107
}
108
- ret some( elts. ( 0 ) ) ;
108
+ ret { fixed : ivec:: slice ( elts, 0 u, last - 1 u) ,
109
+ rep : some ( elts. ( last - 1 u) ) } ;
109
110
}
110
111
_ { }
111
112
}
@@ -114,7 +115,7 @@ fn elts_to_ell(cx: &ext_ctxt, elts: &(@expr)[]) -> option::t[@expr] {
114
115
}
115
116
idx += 1 u;
116
117
}
117
- ret none;
118
+ ret { fixed : elts , rep : none} ;
118
119
}
119
120
120
121
fn option_flatten_map[ T , U ] ( f: & fn ( & T ) -> option:: t[ U ] , v: & vec[ T ] ) ->
@@ -271,57 +272,60 @@ iter free_vars(b: &bindings, e: @expr) -> ident {
271
272
272
273
/* handle sequences (anywhere in the AST) of exprs, either real or ...ed */
273
274
fn transcribe_exprs ( cx : & ext_ctxt , b : & bindings , idx_path : @mutable vec[ uint ] ,
274
- recur : fn ( & @expr) -> @expr , exprs : ( @expr) [ ] ) ->
275
- ( @expr) [ ] {
275
+ recur : fn ( & @expr) -> @expr , exprs : ( @expr) [ ] )
276
+ -> ( @expr) [ ] {
276
277
alt elts_to_ell ( cx, exprs) {
277
- some ( repeat_me) {
278
- let repeat: option:: t [ { rep_count: uint, name: ident} ] = none;
279
- /* we need to walk over all the free vars in lockstep, except for
280
- the leaves, which are just duplicated */
281
- for each fv: ident in free_vars ( b, repeat_me) {
282
- let cur_pos = follow ( b. get ( fv) , idx_path) ;
283
- alt cur_pos {
284
- leaf( _) { }
285
- seq ( ms, _) {
286
- alt repeat {
287
- none. {
288
- repeat = some ( { rep_count: vec:: len ( ms) , name: fv} ) ;
289
- }
290
- some ( { rep_count: old_len, name: old_name} ) {
291
- let len = vec:: len ( ms) ;
292
- if old_len != len {
293
- cx. span_fatal ( repeat_me. span ,
294
- #fmt ( "'%s' occurs %u times, but " , fv,
295
- len) +
296
- #fmt ( "'%s' occurs %u times" ,
297
- old_name, old_len) ) ;
278
+ { fixed: fixed, rep: repeat_me_maybe} {
279
+ let res = ivec:: map ( recur, fixed) ;
280
+ alt repeat_me_maybe {
281
+ none. { }
282
+ some( repeat_me) {
283
+ let repeat: option:: t [ { rep_count: uint, name: ident} ] = none;
284
+ /* we need to walk over all the free vars in lockstep, except for
285
+ the leaves, which are just duplicated */
286
+ for each fv: ident in free_vars ( b, repeat_me) {
287
+ let cur_pos = follow ( b. get ( fv) , idx_path) ;
288
+ alt cur_pos {
289
+ leaf( _) { }
290
+ seq ( ms, _) {
291
+ alt repeat {
292
+ none. {
293
+ repeat = some ( { rep_count: vec:: len ( ms) , name: fv} ) ;
294
+ }
295
+ some ( { rep_count: old_len, name: old_name} ) {
296
+ let len = vec:: len ( ms) ;
297
+ if old_len != len {
298
+ let msg = #fmt ( "'%s' occurs %u times, but " , fv,
299
+ len) + #fmt ( "'%s' occurs %u times" ,
300
+ old_name, old_len) ;
301
+ cx. span_fatal ( repeat_me. span , msg) ;
302
+ }
303
+ }
298
304
}
299
305
}
300
306
}
301
- }
302
307
}
303
- }
304
- let res = ~[ ] ;
305
- alt repeat {
306
- none. {
307
- cx. span_fatal ( repeat_me. span ,
308
- "'...' surrounds an expression without any" +
308
+ alt repeat {
309
+ none. {
310
+ cx. span_fatal ( repeat_me. span ,
311
+ "'...' surrounds an expression without any" +
309
312
" repeating syntax variables" ) ;
310
- }
311
- some ( { rep_count: rc, _} ) {
312
- /* Whew, we now know how how many times to repeat */
313
- let idx: uint = 0 u;
314
- while idx < rc {
315
- vec:: push ( * idx_path, idx) ;
316
- res += ~[ recur ( repeat_me) ] ; // whew!
317
- vec:: pop ( * idx_path) ;
318
- idx += 1 u;
313
+ }
314
+ some ( { rep_count: rc, _} ) {
315
+ /* Whew, we now know how how many times to repeat */
316
+ let idx: uint = 0 u;
317
+ while idx < rc {
318
+ vec:: push ( * idx_path, idx) ;
319
+ res += ~[ recur ( repeat_me) ] ; // whew!
320
+ vec:: pop ( * idx_path) ;
321
+ idx += 1 u;
322
+ }
323
+ }
319
324
}
320
325
}
321
326
}
322
327
ret res;
323
328
}
324
- none. { ret ivec:: map ( recur, exprs) ; }
325
329
}
326
330
}
327
331
@@ -436,8 +440,15 @@ fn p_t_s_rec(cx: &ext_ctxt, m: &matchable, s: &selector, b: &binders) {
436
440
expr_path ( p_pth) { p_t_s_r_path ( cx, p_pth, s, b) ; }
437
441
expr_vec ( p_elts, _, _) {
438
442
alt elts_to_ell ( cx, p_elts) {
439
- some ( repeat_me) { p_t_s_r_ellipses ( cx, repeat_me, s, b) ; }
440
- none. { p_t_s_r_actual_vector ( cx, p_elts, s, b) ; }
443
+ { fixed: fixed, rep: some ( repeat_me) } {
444
+ if ( ivec:: len ( fixed) > 0 u) {
445
+ p_t_s_r_actual_vector ( cx, fixed, true , s, b) ;
446
+ }
447
+ p_t_s_r_ellipses ( cx, repeat_me, ivec:: len ( fixed) , s, b) ;
448
+ }
449
+ { fixed: fixed, rep: none. } {
450
+ p_t_s_r_actual_vector ( cx, fixed, false , s, b) ;
451
+ }
441
452
}
442
453
}
443
454
@@ -575,20 +586,23 @@ fn ivec_to_vec[T](v: &T[]) -> vec[T] {
575
586
ret rs;
576
587
}
577
588
578
- fn p_t_s_r_ellipses ( cx : & ext_ctxt , repeat_me: @expr, s : & selector ,
579
- b : & binders ) {
580
- fn select ( cx : & ext_ctxt , repeat_me: @expr, m : & matchable ) ->
589
+ fn p_t_s_r_ellipses ( cx : & ext_ctxt , repeat_me: @expr, offset : uint ,
590
+ s : & selector , b : & binders ) {
591
+ fn select ( cx : & ext_ctxt , repeat_me: @expr, offset : uint , m : & matchable ) ->
581
592
match_result {
582
593
ret alt m {
583
594
match_expr( e) {
584
595
alt e. node {
585
596
expr_vec ( arg_elts, _, _) {
586
- let elts =
587
- ivec:: map ( leaf, ivec:: map ( match_expr, arg_elts) ) ;
588
-
597
+ let elts = [ ] ;
598
+ let idx = offset;
599
+ while idx < ivec:: len ( arg_elts) {
600
+ elts += [ leaf ( match_expr ( arg_elts. ( idx) ) ) ] ;
601
+ idx += 1 u;
602
+ }
589
603
// using repeat_me.span is a little wacky, but the
590
604
// error we want to report is one in the macro def
591
- some ( seq ( ivec_to_vec ( elts) , repeat_me. span ) )
605
+ some ( seq ( elts, repeat_me. span ) )
592
606
}
593
607
_ { none }
594
608
}
@@ -597,17 +611,20 @@ fn p_t_s_r_ellipses(cx: &ext_ctxt, repeat_me: @expr, s: &selector,
597
611
}
598
612
}
599
613
p_t_s_rec ( cx, match_expr ( repeat_me) ,
600
- compose_sels ( s, bind select ( cx, repeat_me, _) ) , b) ;
614
+ compose_sels ( s, bind select ( cx, repeat_me, offset , _) ) , b) ;
601
615
}
602
616
603
- fn p_t_s_r_actual_vector ( cx : & ext_ctxt , elts : ( @expr) [ ] , s : & selector ,
604
- b : & binders ) {
605
- fn len_select ( cx : & ext_ctxt , m : & matchable , len : uint ) -> match_result {
617
+ fn p_t_s_r_actual_vector ( cx : & ext_ctxt , elts : ( @expr) [ ] , repeat_after : bool ,
618
+ s : & selector , b : & binders ) {
619
+ fn len_select ( cx : & ext_ctxt , m : & matchable , repeat_after : bool , len : uint )
620
+ -> match_result {
606
621
ret alt m {
607
622
match_expr( e) {
608
623
alt e. node {
609
624
expr_vec ( arg_elts, _, _) {
610
- if ivec:: len ( arg_elts) == len {
625
+ let actual_len = ivec:: len ( arg_elts) ;
626
+ if ( repeat_after && actual_len >= len)
627
+ || actual_len == len {
611
628
some ( leaf ( match_exact) )
612
629
} else { none }
613
630
}
@@ -618,7 +635,8 @@ fn p_t_s_r_actual_vector(cx: &ext_ctxt, elts: (@expr)[], s: &selector,
618
635
}
619
636
}
620
637
b. literal_ast_matchers +=
621
- ~[ compose_sels ( s, bind len_select ( cx, _, ivec:: len ( elts) ) ) ] ;
638
+ ~[ compose_sels ( s, bind len_select ( cx, _, repeat_after,
639
+ ivec:: len ( elts) ) ) ] ;
622
640
623
641
624
642
let idx: uint = 0 u;
0 commit comments