@@ -92,19 +92,21 @@ type match_result = option::t[arb_depth[matchable]];
92
92
type selector = fn ( & matchable ) -> match_result ;
93
93
94
94
fn elts_to_ell ( cx : & ext_ctxt , elts : & [ @expr] )
95
- -> { fixed : [ @expr] , rep : option:: t [ @expr] } {
95
+ -> { pre : [ @expr] , rep : option:: t [ @expr ] , post : [ @expr] } {
96
96
let idx : uint = 0 u ;
97
+ let res = none;
97
98
for elt: @expr in elts {
98
99
alt elt. node {
99
100
expr_mac ( m) {
100
101
alt m. node {
101
102
ast:: mac_ellipsis. {
102
- let last = ivec:: len ( elts) - 1 u;
103
- if idx != last {
104
- cx. span_fatal ( m. span , "ellipses must occur last" ) ;
103
+ if res != none {
104
+ cx. span_fatal ( m. span , "only one ellipsis allowed" ) ;
105
105
}
106
- ret { fixed : ivec:: slice ( elts, 0 u, last - 1 u) ,
107
- rep : some ( elts. ( last - 1 u) ) } ;
106
+ res = some ( { pre: ivec:: slice ( elts, 0 u, idx - 1 u) ,
107
+ rep: some ( elts. ( idx - 1 u) ) ,
108
+ post: ivec:: slice ( elts, idx + 1 u,
109
+ ivec:: len ( elts) ) } ) ;
108
110
}
109
111
_ { }
110
112
}
@@ -113,7 +115,10 @@ fn elts_to_ell(cx: &ext_ctxt, elts: &[@expr])
113
115
}
114
116
idx += 1 u;
115
117
}
116
- ret { fixed : elts, rep : none} ;
118
+ ret alt res {
119
+ some( val) { val }
120
+ none. { { pre: elts , rep: none, post: ~[ ] } }
121
+ }
117
122
}
118
123
119
124
fn option_flatten_map[ T , U ] ( f: & fn ( & T ) -> option:: t[ U ] , v: & [ T ] ) ->
@@ -275,8 +280,8 @@ fn transcribe_exprs(cx: &ext_ctxt, b: &bindings, idx_path: @mutable [uint],
275
280
recur : fn ( & @expr) -> @expr , exprs : [ @expr] )
276
281
-> [ @expr] {
277
282
alt elts_to_ell ( cx , exprs ) {
278
- { fixed : fixed , rep : repeat_me_maybe } {
279
- let res = ivec:: map ( recur , fixed ) ;
283
+ { pre : pre , rep : repeat_me_maybe , post : post } {
284
+ let res = ivec:: map ( recur , pre ) ;
280
285
alt repeat_me_maybe {
281
286
none. { }
282
287
some ( repeat_me) {
@@ -324,6 +329,7 @@ fn transcribe_exprs(cx: &ext_ctxt, b: &bindings, idx_path: @mutable [uint],
324
329
}
325
330
}
326
331
}
332
+ res += ivec:: map ( recur, post) ;
327
333
ret res;
328
334
}
329
335
}
@@ -440,14 +446,25 @@ fn p_t_s_rec(cx: &ext_ctxt, m: &matchable, s: &selector, b: &binders) {
440
446
expr_path ( p_pth) { p_t_s_r_path ( cx, p_pth, s, b) ; }
441
447
expr_vec ( p_elts, _, _) {
442
448
alt elts_to_ell ( cx, p_elts) {
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) ;
449
+ { pre: pre, rep: some ( repeat_me) , post: post} {
450
+ p_t_s_r_length ( cx, ivec:: len ( pre) + ivec:: len ( post) ,
451
+ true , s, b) ;
452
+ if ( ivec:: len ( pre) > 0 u) {
453
+ p_t_s_r_actual_vector ( cx, pre, true , s, b) ;
454
+ }
455
+ p_t_s_r_ellipses ( cx, repeat_me, ivec:: len ( pre) , s, b) ;
456
+
457
+ if ( ivec:: len ( post) > 0 u) {
458
+ cx. span_unimpl ( e. span ,
459
+ "matching after `...` not yet supported" ) ;
446
460
}
447
- p_t_s_r_ellipses( cx, repeat_me, ivec:: len( fixed) , s, b) ;
448
461
}
449
- { fixed: fixed, rep: none. } {
450
- p_t_s_r_actual_vector ( cx, fixed, false , s, b) ;
462
+ { pre: pre, rep: none. , post: post } {
463
+ if post != ~[ ] {
464
+ cx. bug ( "elts_to_ell provided an invalid result" ) ;
465
+ }
466
+ p_t_s_r_length ( cx, ivec:: len ( pre) , false , s, b) ;
467
+ p_t_s_r_actual_vector ( cx, pre, false , s, b) ;
451
468
}
452
469
}
453
470
}
@@ -606,17 +623,17 @@ fn p_t_s_r_ellipses(cx: &ext_ctxt, repeat_me: @expr, offset: uint,
606
623
compose_sels ( s, bind select ( cx, repeat_me, offset, _) ) , b) ;
607
624
}
608
625
609
- fn p_t_s_r_actual_vector ( cx : & ext_ctxt , elts : [ @expr] , repeat_after : bool ,
610
- s : & selector , b : & binders ) {
611
- fn len_select ( cx : & ext_ctxt , m : & matchable , repeat_after : bool , len : uint )
626
+
627
+ fn p_t_s_r_length ( cx : & ext_ctxt , len : uint , at_least : bool , s : selector ,
628
+ b : & binders ) {
629
+ fn len_select ( cx : & ext_ctxt , m : & matchable , at_least : bool , len : uint )
612
630
-> match_result {
613
631
ret alt m {
614
632
match_expr( e) {
615
633
alt e. node {
616
634
expr_vec ( arg_elts, _, _) {
617
635
let actual_len = ivec:: len ( arg_elts) ;
618
- if ( repeat_after && actual_len >= len)
619
- || actual_len == len {
636
+ if ( at_least && actual_len >= len) || actual_len == len {
620
637
some ( leaf ( match_exact) )
621
638
} else { none }
622
639
}
@@ -627,10 +644,11 @@ fn p_t_s_r_actual_vector(cx: &ext_ctxt, elts: [@expr], repeat_after: bool,
627
644
}
628
645
}
629
646
b. literal_ast_matchers +=
630
- ~[ compose_sels ( s, bind len_select ( cx, _, repeat_after,
631
- ivec:: len ( elts) ) ) ] ;
632
-
647
+ ~[ compose_sels ( s, bind len_select ( cx, _, at_least, len) ) ] ;
648
+ }
633
649
650
+ fn p_t_s_r_actual_vector ( cx : & ext_ctxt , elts : [ @expr] , repeat_after : bool ,
651
+ s : & selector , b : & binders ) {
634
652
let idx: uint = 0 u;
635
653
while idx < ivec:: len ( elts) {
636
654
fn select ( cx : & ext_ctxt , m : & matchable , idx : uint ) -> match_result {
@@ -678,7 +696,7 @@ fn add_new_extension(cx: &ext_ctxt, sp: span, arg: @expr,
678
696
alt mac. node {
679
697
mac_invoc ( pth, invoc_arg, body) {
680
698
alt path_to_ident ( pth) {
681
- some ( id) {
699
+ some ( id) {
682
700
alt macro_name {
683
701
none. { macro_name = some ( id) ; }
684
702
some ( other_id) {
0 commit comments