summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax/ext')
-rw-r--r--src/libsyntax/ext/tt/earley_parser.rs38
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs2
-rw-r--r--src/libsyntax/ext/tt/transcribe.rs2
3 files changed, 30 insertions, 12 deletions
diff --git a/src/libsyntax/ext/tt/earley_parser.rs b/src/libsyntax/ext/tt/earley_parser.rs
index 152b92a4b53..5015efa67df 100644
--- a/src/libsyntax/ext/tt/earley_parser.rs
+++ b/src/libsyntax/ext/tt/earley_parser.rs
@@ -41,6 +41,7 @@ type matcher_pos = ~{
     mut idx: uint,
     mut up: matcher_pos_up, // mutable for swapping only
     matches: ~[dvec<@arb_depth>],
+    match_lo: uint, match_hi: uint,
     sp_lo: uint,
 };
 
@@ -55,17 +56,25 @@ fn count_names(ms: &[matcher]) -> uint {
     vec::foldl(0u, ms, |ct, m| {
         ct + alt m.node {
           mtc_tok(_) { 0u }
-          mtc_rep(more_ms, _, _) { count_names(more_ms) }
+          mtc_rep(more_ms, _, _, _, _) { count_names(more_ms) }
           mtc_bb(_,_,_) { 1u }
         }})
 }
 
 #[warn(no_non_implicitly_copyable_typarams)]
-fn new_matcher_pos(ms: ~[matcher], sep: option<token>, lo: uint)
+fn initial_matcher_pos(ms: ~[matcher], sep: option<token>, lo: uint)
     -> matcher_pos {
+    let mut match_idx_hi = 0u;
+    for ms.each() |elt| {
+        alt elt.node {
+          mtc_tok(_) {}
+          mtc_rep(_,_,_,_,hi) { match_idx_hi = hi; } //it is monotonic...
+          mtc_bb(_,_,pos) { match_idx_hi = pos+1u; } //...so latest is highest
+        }
+    }
     ~{elts: ms, sep: sep, mut idx: 0u, mut up: matcher_pos_up(none),
       matches: copy vec::from_fn(count_names(ms), |_i| dvec::dvec()),
-      sp_lo: lo}
+      match_lo: 0u, match_hi: match_idx_hi, sp_lo: lo}
 }
 
 /* logically, an arb_depth should contain only one kind of nonterminal */
@@ -79,7 +88,7 @@ fn nameize(p_s: parse_sess, ms: ~[matcher], res: ~[@arb_depth])
              ret_val: hashmap<ident, @arb_depth>) {
         alt m {
           {node: mtc_tok(_), span: _} { }
-          {node: mtc_rep(more_ms, _, _), span: _} {
+          {node: mtc_rep(more_ms, _, _, _, _), span: _} {
             for more_ms.each() |next_m| { n_rec(p_s, next_m, res, ret_val) };
           }
           {node: mtc_bb(bind_name, _, idx), span: sp} {
@@ -104,7 +113,7 @@ enum parse_result {
 fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
     -> parse_result {
     let mut cur_eis = ~[];
-    vec::push(cur_eis, new_matcher_pos(ms, none, rdr.peek().sp.lo));
+    vec::push(cur_eis, initial_matcher_pos(ms, none, rdr.peek().sp.lo));
 
     loop {
         let mut bb_eis = ~[]; // black-box parsed by parser.rs
@@ -141,10 +150,10 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
                         // I bet this is a perf problem: we're preemptively
                         // doing a lot of array work that will get thrown away
                         // most of the time.
-                        for ei.matches.eachi() |idx, elt| {
-                            let sub = elt.get();
-                            // Some subtrees don't contain the name at all
-                            if sub.len() == 0u { again; }
+
+                        // Only touch the binders we have actually bound
+                        for uint::range(ei.match_lo, ei.match_hi) |idx| {
+                            let sub = ei.matches[idx].get();
                             new_pos.matches[idx]
                                 .push(@seq(sub, mk_sp(ei.sp_lo,sp.hi)));
                         }
@@ -176,10 +185,15 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
             } else {
                 alt copy ei.elts[idx].node {
                   /* need to descend into sequence */
-                  mtc_rep(matchers, sep, zero_ok) {
+                  mtc_rep(matchers, sep, zero_ok, match_idx_lo, match_idx_hi){
                     if zero_ok {
                         let new_ei = copy ei;
                         new_ei.idx += 1u;
+                        //we specifically matched zero repeats.
+                        for uint::range(match_idx_lo, match_idx_hi) |idx| {
+                            new_ei.matches[idx].push(@seq(~[], sp));
+                        }
+
                         vec::push(cur_eis, new_ei);
                     }
 
@@ -189,7 +203,9 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
                     vec::push(cur_eis, ~{
                         elts: matchers, sep: sep, mut idx: 0u,
                         mut up: matcher_pos_up(some(ei_t)),
-                        matches: matches, sp_lo: sp.lo
+                        matches: matches,
+                        match_lo: match_idx_lo, match_hi: match_idx_hi,
+                        sp_lo: sp.lo
                     });
                   }
                   mtc_bb(_,_,_) { vec::push(bb_eis, ei) }
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 7bed3107f53..a1bb879965f 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -21,7 +21,7 @@ fn add_new_extension(cx: ext_ctxt, sp: span, name: ident,
             ms(mtc_bb(@~"lhs",@~"mtcs", 0u)),
             ms(mtc_tok(FAT_ARROW)),
             ms(mtc_bb(@~"rhs",@~"tt", 1u)),
-        ], some(SEMI), false))];
+        ], some(SEMI), false, 0u, 2u))];
 
     let arg_reader = new_tt_reader(cx.parse_sess().span_diagnostic,
                                    cx.parse_sess().interner, none, arg);
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index a9bc124b605..b9d4adc2339 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -86,6 +86,8 @@ pure fn lookup_cur_ad_by_ad(r: tt_reader, start: @arb_depth) -> @arb_depth {
           seq(ads, _) { ads[idx] }
         }
     }
+    unchecked {io::println(#fmt["%? / %?", copy r.repeat_idx,
+                                copy r.repeat_len]);};
     vec::foldl(start, r.repeat_idx, red)
 }