Allow [a, b, ..., c]
transcription patterns in MBE.
This commit is contained in:
parent
d2f9b15052
commit
87b56b5565
@ -92,19 +92,21 @@ type match_result = option::t[arb_depth[matchable]];
|
|||||||
type selector = fn(&matchable) -> match_result ;
|
type selector = fn(&matchable) -> match_result ;
|
||||||
|
|
||||||
fn elts_to_ell(cx: &ext_ctxt, elts: &[@expr])
|
fn elts_to_ell(cx: &ext_ctxt, elts: &[@expr])
|
||||||
-> {fixed: [@expr], rep: option::t[@expr]} {
|
-> {pre: [@expr], rep: option::t[@expr], post: [@expr]} {
|
||||||
let idx: uint = 0u;
|
let idx: uint = 0u;
|
||||||
|
let res = none;
|
||||||
for elt: @expr in elts {
|
for elt: @expr in elts {
|
||||||
alt elt.node {
|
alt elt.node {
|
||||||
expr_mac(m) {
|
expr_mac(m) {
|
||||||
alt m.node {
|
alt m.node {
|
||||||
ast::mac_ellipsis. {
|
ast::mac_ellipsis. {
|
||||||
let last = ivec::len(elts) - 1u;
|
if res != none {
|
||||||
if idx != last {
|
cx.span_fatal(m.span, "only one ellipsis allowed");
|
||||||
cx.span_fatal(m.span, "ellipses must occur last");
|
|
||||||
}
|
}
|
||||||
ret {fixed: ivec::slice(elts, 0u, last - 1u),
|
res = some({pre: ivec::slice(elts, 0u, idx - 1u),
|
||||||
rep: some(elts.(last - 1u))};
|
rep: some(elts.(idx - 1u)),
|
||||||
|
post: ivec::slice(elts, idx + 1u,
|
||||||
|
ivec::len(elts))});
|
||||||
}
|
}
|
||||||
_ { }
|
_ { }
|
||||||
}
|
}
|
||||||
@ -113,7 +115,10 @@ fn elts_to_ell(cx: &ext_ctxt, elts: &[@expr])
|
|||||||
}
|
}
|
||||||
idx += 1u;
|
idx += 1u;
|
||||||
}
|
}
|
||||||
ret {fixed: elts, rep: none};
|
ret alt res {
|
||||||
|
some(val) { val }
|
||||||
|
none. { {pre: elts, rep: none, post: ~[]} }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn option_flatten_map[T, U](f: &fn(&T) -> option::t[U] , v: &[T]) ->
|
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],
|
|||||||
recur: fn(&@expr) -> @expr , exprs: [@expr])
|
recur: fn(&@expr) -> @expr , exprs: [@expr])
|
||||||
-> [@expr] {
|
-> [@expr] {
|
||||||
alt elts_to_ell(cx, exprs) {
|
alt elts_to_ell(cx, exprs) {
|
||||||
{fixed: fixed, rep: repeat_me_maybe} {
|
{pre: pre, rep: repeat_me_maybe, post: post} {
|
||||||
let res = ivec::map(recur, fixed);
|
let res = ivec::map(recur, pre);
|
||||||
alt repeat_me_maybe {
|
alt repeat_me_maybe {
|
||||||
none. {}
|
none. {}
|
||||||
some(repeat_me) {
|
some(repeat_me) {
|
||||||
@ -324,6 +329,7 @@ fn transcribe_exprs(cx: &ext_ctxt, b: &bindings, idx_path: @mutable [uint],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
res += ivec::map(recur, post);
|
||||||
ret res;
|
ret res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -440,14 +446,25 @@ fn p_t_s_rec(cx: &ext_ctxt, m: &matchable, s: &selector, b: &binders) {
|
|||||||
expr_path(p_pth) { p_t_s_r_path(cx, p_pth, s, b); }
|
expr_path(p_pth) { p_t_s_r_path(cx, p_pth, s, b); }
|
||||||
expr_vec(p_elts, _, _) {
|
expr_vec(p_elts, _, _) {
|
||||||
alt elts_to_ell(cx, p_elts) {
|
alt elts_to_ell(cx, p_elts) {
|
||||||
{fixed: fixed, rep: some(repeat_me)} {
|
{pre: pre, rep: some(repeat_me), post: post} {
|
||||||
if(ivec::len(fixed) > 0u) {
|
p_t_s_r_length(cx, ivec::len(pre) + ivec::len(post),
|
||||||
p_t_s_r_actual_vector(cx, fixed, true, s, b);
|
true, s, b);
|
||||||
|
if(ivec::len(pre) > 0u) {
|
||||||
|
p_t_s_r_actual_vector(cx, pre, true, s, b);
|
||||||
|
}
|
||||||
|
p_t_s_r_ellipses(cx, repeat_me, ivec::len(pre), s, b);
|
||||||
|
|
||||||
|
if(ivec::len(post) > 0u) {
|
||||||
|
cx.span_unimpl(e.span,
|
||||||
|
"matching after `...` not yet supported");
|
||||||
}
|
}
|
||||||
p_t_s_r_ellipses(cx, repeat_me, ivec::len(fixed), s, b);
|
|
||||||
}
|
}
|
||||||
{fixed: fixed, rep: none.} {
|
{pre: pre, rep: none., post: post} {
|
||||||
p_t_s_r_actual_vector(cx, fixed, false, s, b);
|
if post != ~[] {
|
||||||
|
cx.bug("elts_to_ell provided an invalid result");
|
||||||
|
}
|
||||||
|
p_t_s_r_length(cx, ivec::len(pre), false, s, b);
|
||||||
|
p_t_s_r_actual_vector(cx, pre, false, s, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -606,17 +623,17 @@ fn p_t_s_r_ellipses(cx: &ext_ctxt, repeat_me: @expr, offset: uint,
|
|||||||
compose_sels(s, bind select(cx, repeat_me, offset, _)), b);
|
compose_sels(s, bind select(cx, repeat_me, offset, _)), b);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn p_t_s_r_actual_vector(cx: &ext_ctxt, elts: [@expr], repeat_after: bool,
|
|
||||||
s: &selector, b: &binders) {
|
fn p_t_s_r_length(cx: &ext_ctxt, len: uint, at_least: bool, s: selector,
|
||||||
fn len_select(cx: &ext_ctxt, m: &matchable, repeat_after: bool, len: uint)
|
b: &binders) {
|
||||||
|
fn len_select(cx: &ext_ctxt, m: &matchable, at_least: bool, len: uint)
|
||||||
-> match_result {
|
-> match_result {
|
||||||
ret alt m {
|
ret alt m {
|
||||||
match_expr(e) {
|
match_expr(e) {
|
||||||
alt e.node {
|
alt e.node {
|
||||||
expr_vec(arg_elts, _, _) {
|
expr_vec(arg_elts, _, _) {
|
||||||
let actual_len = ivec::len(arg_elts);
|
let actual_len = ivec::len(arg_elts);
|
||||||
if (repeat_after && actual_len >= len)
|
if (at_least && actual_len >= len) || actual_len == len {
|
||||||
|| actual_len == len {
|
|
||||||
some(leaf(match_exact))
|
some(leaf(match_exact))
|
||||||
} else { none }
|
} else { none }
|
||||||
}
|
}
|
||||||
@ -627,10 +644,11 @@ fn p_t_s_r_actual_vector(cx: &ext_ctxt, elts: [@expr], repeat_after: bool,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.literal_ast_matchers +=
|
b.literal_ast_matchers +=
|
||||||
~[compose_sels(s, bind len_select(cx, _, repeat_after,
|
~[compose_sels(s, bind len_select(cx, _, at_least, len))];
|
||||||
ivec::len(elts)))];
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn p_t_s_r_actual_vector(cx: &ext_ctxt, elts: [@expr], repeat_after: bool,
|
||||||
|
s: &selector, b: &binders) {
|
||||||
let idx: uint = 0u;
|
let idx: uint = 0u;
|
||||||
while idx < ivec::len(elts) {
|
while idx < ivec::len(elts) {
|
||||||
fn select(cx: &ext_ctxt, m: &matchable, idx: uint) -> match_result {
|
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,
|
|||||||
alt mac.node {
|
alt mac.node {
|
||||||
mac_invoc(pth, invoc_arg, body) {
|
mac_invoc(pth, invoc_arg, body) {
|
||||||
alt path_to_ident(pth) {
|
alt path_to_ident(pth) {
|
||||||
some(id) {
|
some(id) {
|
||||||
alt macro_name {
|
alt macro_name {
|
||||||
none. { macro_name = some(id); }
|
none. { macro_name = some(id); }
|
||||||
some(other_id) {
|
some(other_id) {
|
||||||
|
@ -43,4 +43,9 @@ fn main() {
|
|||||||
|
|
||||||
assert (#transcr_mixed[10, 5, 4, 3, 2, 1] == 210);
|
assert (#transcr_mixed[10, 5, 4, 3, 2, 1] == 210);
|
||||||
|
|
||||||
|
#macro[[#surround[pre, [xs, ...], post],
|
||||||
|
[pre, xs, ..., post]]];
|
||||||
|
|
||||||
|
assert (#surround[1, [2,3,4], 5] == [1,2,3,4,5]);
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user