Add elipses, reorganize the macro components into their own AST node.
This commit is contained in:
parent
425732311a
commit
48dbee6b47
14 changed files with 206 additions and 103 deletions
|
@ -6378,7 +6378,7 @@ fn trans_expr_out(&@block_ctxt cx, &@ast::expr e, out_method output) ->
|
|||
case (ast::expr_rec(?args, ?base)) {
|
||||
ret trans_rec(cx, args, base, e.id);
|
||||
}
|
||||
case (ast::expr_ext(_, _, _)) {
|
||||
case (ast::expr_mac(_)) {
|
||||
ret cx.fcx.lcx.ccx.sess.bug("unexpanded macro");
|
||||
}
|
||||
case (ast::expr_fail(?expr)) {
|
||||
|
|
|
@ -570,7 +570,7 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) {
|
|||
case (expr_break) { clear_pp(expr_pp(fcx.ccx, e)); }
|
||||
case (expr_cont) { clear_pp(expr_pp(fcx.ccx, e)); }
|
||||
case (expr_port(_)) { clear_pp(expr_pp(fcx.ccx, e)); }
|
||||
case (expr_ext(_, _, _)) {
|
||||
case (expr_mac(_)) {
|
||||
fcx.ccx.tcx.sess.bug("unexpanded macro");
|
||||
}
|
||||
case (expr_anon_obj(?anon_obj, _)) {
|
||||
|
|
|
@ -367,7 +367,7 @@ fn find_pre_post_state_expr(&fn_ctxt fcx, &prestate pres, @expr e) -> bool {
|
|||
case (expr_chan(?ex)) {
|
||||
ret find_pre_post_state_sub(fcx, pres, ex, e.id, none);
|
||||
}
|
||||
case (expr_ext(_, _, _)) {
|
||||
case (expr_mac(_)) {
|
||||
fcx.ccx.tcx.sess.bug("unexpanded macro");
|
||||
}
|
||||
case (expr_put(?maybe_e)) {
|
||||
|
|
|
@ -1780,7 +1780,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
|
|||
}
|
||||
write::ty_only_fixup(fcx, id, tpt._1);
|
||||
}
|
||||
case (ast::expr_ext(_,_,_)) {
|
||||
case (ast::expr_mac(_)) {
|
||||
fcx.ccx.tcx.sess.bug("unexpanded macro");
|
||||
}
|
||||
case (ast::expr_fail(?expr_opt)) {
|
||||
|
|
|
@ -305,7 +305,6 @@ tag expr_ {
|
|||
expr_field(@expr, ident);
|
||||
expr_index(@expr, @expr);
|
||||
expr_path(path);
|
||||
expr_ext(path, (@expr)[], option::t[str]);
|
||||
expr_fail(option::t[@expr]);
|
||||
expr_break;
|
||||
expr_cont;
|
||||
|
@ -323,7 +322,18 @@ tag expr_ {
|
|||
to expr_if_check. */
|
||||
expr_if_check(@expr, block, option::t[@expr]);
|
||||
expr_port(option::t[@ty]);
|
||||
expr_chan(@expr);
|
||||
expr_anon_obj(anon_obj, ty_param[]);
|
||||
expr_mac(mac);
|
||||
}
|
||||
|
||||
type mac = spanned[mac_];
|
||||
|
||||
tag mac_ {
|
||||
mac_invoc(path, (@expr)[], option::t[str]);
|
||||
mac_embed_type(@ty);
|
||||
mac_embed_block(block);
|
||||
mac_elipsis;
|
||||
}
|
||||
|
||||
type lit = spanned[lit_];
|
||||
|
@ -433,6 +443,7 @@ tag ty_ {
|
|||
ty_path(path, node_id);
|
||||
ty_type;
|
||||
ty_constr(@ty, (@constr)[]);
|
||||
ty_mac(mac);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@ import codemap::emit_error;
|
|||
import driver::session;
|
||||
import syntax::ast::crate;
|
||||
import syntax::ast::expr_;
|
||||
import syntax::ast::expr_ext;
|
||||
import syntax::ast::expr_mac;
|
||||
import syntax::ast::mac_invoc;
|
||||
import syntax::fold::*;
|
||||
|
||||
import std::option::none;
|
||||
|
@ -16,27 +17,39 @@ fn expand_expr(&hashmap[str, base::syntax_extension] exts,
|
|||
&session::session sess, &expr_ e, ast_fold fld,
|
||||
&fn(&ast::expr_, ast_fold) -> expr_ orig) -> expr_ {
|
||||
ret alt(e) {
|
||||
case (expr_ext(?pth, ?args, ?body)) {
|
||||
assert(ivec::len(pth.node.idents) > 0u);
|
||||
auto extname = pth.node.idents.(0);
|
||||
auto ext_cx = base::mk_ctxt(sess);
|
||||
alt (exts.find(extname)) {
|
||||
case (none) {
|
||||
emit_error(some(pth.span), "unknown syntax expander: '"
|
||||
+ extname + "'", sess.get_codemap());
|
||||
case (expr_mac(?mac)) {
|
||||
alt(mac.node) {
|
||||
case (mac_invoc(?pth, ?args, ?body)) {
|
||||
assert(ivec::len(pth.node.idents) > 0u);
|
||||
auto extname = pth.node.idents.(0);
|
||||
auto ext_cx = base::mk_ctxt(sess);
|
||||
alt (exts.find(extname)) {
|
||||
case (none) {
|
||||
emit_error(some(pth.span),
|
||||
"unknown syntax expander: '"
|
||||
+ extname + "'", sess.get_codemap());
|
||||
fail
|
||||
}
|
||||
case (some(base::normal(?ext))) {
|
||||
//keep going, outside-in
|
||||
fld.fold_expr(ext(ext_cx, pth.span,
|
||||
args, body)).node
|
||||
}
|
||||
case (some(base::macro_defining(?ext))) {
|
||||
auto named_extension
|
||||
= ext(ext_cx, pth.span, args, body);
|
||||
exts.insert(named_extension._0,
|
||||
named_extension._1);
|
||||
ast::expr_tup(~[])
|
||||
}
|
||||
}
|
||||
}
|
||||
case (_) {
|
||||
emit_error(some(mac.span), "naked syntactic bit",
|
||||
sess.get_codemap());
|
||||
fail
|
||||
}
|
||||
case (some(base::normal(?ext))) {
|
||||
//keep going, outside-in
|
||||
fld.fold_expr(ext(ext_cx, pth.span, args, body)).node
|
||||
}
|
||||
case (some(base::macro_defining(?ext))) {
|
||||
auto named_extension = ext(ext_cx, pth.span, args, body);
|
||||
exts.insert(named_extension._0, named_extension._1);
|
||||
ast::expr_tup([])
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
case (_) { orig(e, fld) }
|
||||
};
|
||||
|
|
|
@ -22,11 +22,12 @@ import ast::path;
|
|||
import ast::path_;
|
||||
import ast::expr_path;
|
||||
import ast::expr_vec;
|
||||
import ast::expr_ext;
|
||||
import ast::expr_mac;
|
||||
import ast::mac_invoc;
|
||||
|
||||
export add_new_extension;
|
||||
|
||||
fn lookup(&vec[invk_binding] ibs, ident i) -> option::t[invk_binding] {
|
||||
fn lookup(&(invk_binding)[] ibs, ident i) -> option::t[invk_binding] {
|
||||
for (invk_binding ib in ibs) {
|
||||
alt (ib) {
|
||||
case (ident_binding(?p_id, _)) { if (i == p_id) { ret some(ib); }}
|
||||
|
@ -96,7 +97,7 @@ fn subst_expr(&ext_ctxt cx, &(invk_binding)[] ibs, &ast::expr_ e,
|
|||
}
|
||||
}
|
||||
|
||||
type pat_ext = rec(vec[@ast::expr] invk, @ast::expr body);
|
||||
type pat_ext = rec((@ast::expr)[] invk, @ast::expr body);
|
||||
|
||||
// maybe box?
|
||||
tag invk_binding {
|
||||
|
@ -113,6 +114,24 @@ fn path_to_ident(&path pth) -> option::t[ident] {
|
|||
ret none;
|
||||
}
|
||||
|
||||
fn process_clause(&ext_ctxt cx, &mutable vec[pat_ext] pes,
|
||||
&mutable option::t[str] macro_name, &path pth,
|
||||
&(@ast::expr)[] invoc_args, @ast::expr body) {
|
||||
let str clause_name = alt(path_to_ident(pth)) {
|
||||
case (some(?id)) { id }
|
||||
case (none) {
|
||||
cx.span_fatal(pth.span, "macro name must not be a path")
|
||||
}
|
||||
};
|
||||
if (macro_name == none) {
|
||||
macro_name = some(clause_name);
|
||||
} else if (macro_name != some(clause_name)) {
|
||||
cx.span_fatal(pth.span, "#macro can only introduce one name");
|
||||
}
|
||||
pes += [rec(invk=invoc_args, body=body)];
|
||||
}
|
||||
|
||||
|
||||
fn add_new_extension(&ext_ctxt cx, span sp, &(@ast::expr)[] args,
|
||||
option::t[str] body) -> tup(str, syntax_extension) {
|
||||
let option::t[str] macro_name = none;
|
||||
|
@ -121,28 +140,19 @@ fn add_new_extension(&ext_ctxt cx, span sp, &(@ast::expr)[] args,
|
|||
alt(arg.node) {
|
||||
case(expr_vec(?elts, ?mut, ?seq_kind)) {
|
||||
|
||||
if (len(elts) != 2u) {
|
||||
if (ivec::len(elts) != 2u) {
|
||||
cx.span_fatal((*arg).span,
|
||||
"extension clause must consist of [" +
|
||||
"macro invocation, expansion body]");
|
||||
}
|
||||
alt(elts.(0u).node) {
|
||||
case(expr_ext(?pth, ?invk_args, ?body)) {
|
||||
let str clause_name = alt(path_to_ident(pth)) {
|
||||
case (some(?id)) { id }
|
||||
case (none) {
|
||||
cx.span_fatal
|
||||
(elts.(0u).span,
|
||||
"macro name must not be a path")
|
||||
case(expr_mac(?mac)) {
|
||||
alt (mac.node) {
|
||||
case (mac_invoc(?pth, ?invoc_args, ?body)) {
|
||||
process_clause(cx, pat_exts, macro_name,
|
||||
pth, invoc_args, elts.(1u));
|
||||
}
|
||||
};
|
||||
if (macro_name == none) {
|
||||
macro_name = some(clause_name);
|
||||
} else if (macro_name != some(clause_name)) {
|
||||
cx.span_fatal(elts.(0u).span, "macros must have"
|
||||
+ " only one name");
|
||||
}
|
||||
pat_exts += [rec(invk=invk_args, body=elts.(1u))];
|
||||
}
|
||||
case(_) {
|
||||
cx.span_fatal(elts.(0u).span, "extension clause must"
|
||||
|
@ -169,25 +179,25 @@ fn add_new_extension(&ext_ctxt cx, span sp, &(@ast::expr)[] args,
|
|||
normal(ext));
|
||||
|
||||
|
||||
fn generic_extension(&ext_ctxt cx, span sp, &vec[@ast::expr] args,
|
||||
fn generic_extension(&ext_ctxt cx, span sp, &(@ast::expr)[] args,
|
||||
option::t[str] body, @vec[pat_ext] clauses)
|
||||
-> @ast::expr {
|
||||
|
||||
/* returns a list of bindings, or none if the match fails. */
|
||||
fn match_invk(@ast::expr pattern, @ast::expr argument)
|
||||
-> option::t[vec[invk_binding]] {
|
||||
-> option::t[(invk_binding)[]] {
|
||||
auto pat = pattern.node;
|
||||
auto arg = argument.node;
|
||||
ret alt (pat) {
|
||||
case (expr_vec(?p_elts, _, _)) {
|
||||
alt (arg) {
|
||||
case (expr_vec(?a_elts, _, _)) {
|
||||
if (vec::len(p_elts) != vec::len(a_elts)) {
|
||||
if (ivec::len(p_elts) != ivec::len(a_elts)) {
|
||||
none[vec[invk_binding]]
|
||||
}
|
||||
let uint i = 0u;
|
||||
let vec[invk_binding] res = [];
|
||||
while (i < vec::len(p_elts)) {
|
||||
let (invk_binding)[] res = ~[];
|
||||
while (i < ivec::len(p_elts)) {
|
||||
alt (match_invk(p_elts.(i), a_elts.(i))) {
|
||||
case (some(?v)) { res += v; }
|
||||
case (none) { ret none; }
|
||||
|
@ -207,34 +217,36 @@ fn add_new_extension(&ext_ctxt cx, span sp, &(@ast::expr)[] args,
|
|||
case (expr_path(?a_pth)) {
|
||||
alt (path_to_ident(a_pth)) {
|
||||
case (some(?a_id)) {
|
||||
some([ident_binding
|
||||
(p_id, respan(argument.span,
|
||||
some(~[ident_binding
|
||||
(p_id,
|
||||
respan(argument.span,
|
||||
a_id))])
|
||||
}
|
||||
case (none) {
|
||||
some([path_binding(p_id, @a_pth)])
|
||||
some(~[path_binding(p_id,
|
||||
@a_pth)])
|
||||
}
|
||||
}
|
||||
}
|
||||
case (_) {
|
||||
some([expr_binding(p_id, argument)])
|
||||
some(~[expr_binding(p_id, argument)])
|
||||
}
|
||||
}
|
||||
}
|
||||
// FIXME this still compares on internal spans
|
||||
case (_) { if(pat == arg) { some([]) } else { none } }
|
||||
case (_) { if(pat == arg) { some(~[]) } else { none }}
|
||||
}
|
||||
}
|
||||
// FIXME this still compares on internal spans
|
||||
case (_) { if (pat == arg) { some([]) } else { none } }
|
||||
case (_) { if (pat == arg) { some(~[]) } else { none }}
|
||||
}
|
||||
}
|
||||
|
||||
for (pat_ext pe in *clauses) {
|
||||
if (vec::len(args) != vec::len(pe.invk)) { cont; }
|
||||
if (ivec::len(args) != ivec::len(pe.invk)) { cont; }
|
||||
let uint i = 0u;
|
||||
let vec[invk_binding] bindings = [];
|
||||
while (i < vec::len(args)) {
|
||||
let (invk_binding)[] bindings = ~[];
|
||||
while (i < ivec::len(args)) {
|
||||
alt (match_invk(pe.invk.(i), args.(i))) {
|
||||
case (some(?v)) { bindings += v; }
|
||||
case (none) { cont }
|
||||
|
|
|
@ -126,6 +126,25 @@ fn fold_arg_(&arg a, ast_fold fld) -> arg {
|
|||
ret rec(mode=a.mode, ty=fld.fold_ty(a.ty),
|
||||
ident=fld.fold_ident(a.ident), id=a.id);
|
||||
}
|
||||
//used in noop_fold_expr, and possibly elsewhere in the future
|
||||
fn fold_mac_(&mac m, ast_fold fld) -> mac {
|
||||
ret rec(node=
|
||||
alt(m.node) {
|
||||
case (mac_invoc(?pth,?args,?body)) {
|
||||
mac_invoc(fld.fold_path(pth),
|
||||
ivec::map(fld.fold_expr, args), body)
|
||||
}
|
||||
case (mac_embed_type(?ty)) {
|
||||
mac_embed_type(fld.fold_ty(ty))
|
||||
}
|
||||
case (mac_embed_block(?block)) {
|
||||
mac_embed_block(fld.fold_block(block))
|
||||
}
|
||||
case (mac_elipsis) { mac_elipsis }
|
||||
},
|
||||
span=m.span);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -319,6 +338,7 @@ fn noop_fold_expr(&expr_ e, ast_fold fld) -> expr_ {
|
|||
}
|
||||
auto fold_anon_obj = bind fold_anon_obj_(_,fld);
|
||||
|
||||
auto fold_mac = bind fold_mac_(_,fld);
|
||||
|
||||
ret alt (e) {
|
||||
case (expr_vec(?exprs, ?mut, ?seq_kind)) {
|
||||
|
@ -414,10 +434,6 @@ fn noop_fold_expr(&expr_ e, ast_fold fld) -> expr_ {
|
|||
case (expr_path(?pth)) {
|
||||
expr_path(fld.fold_path(pth))
|
||||
}
|
||||
case (expr_ext(?pth, ?args, ?body)) {
|
||||
expr_ext(fld.fold_path(pth), ivec::map(fld.fold_expr, args),
|
||||
body, fld.fold_expr(expanded))
|
||||
}
|
||||
case (expr_fail(?e)) { expr_fail(option::map(fld.fold_expr, e)) }
|
||||
case (expr_break()) { e }
|
||||
case (expr_cont()) { e }
|
||||
|
@ -445,11 +461,8 @@ fn noop_fold_expr(&expr_ e, ast_fold fld) -> expr_ {
|
|||
case (expr_anon_obj(?ao, ?typms)) {
|
||||
expr_anon_obj(fold_anon_obj(ao), typms)
|
||||
}
|
||||
case (expr_embeded_type(?ty)) {
|
||||
expr_embeded_type(fld.fold_ty(ty))
|
||||
}
|
||||
case (expr_embeded_block(?blk)) {
|
||||
expr_embeded_block(fld.fold_block(blk))
|
||||
case (expr_mac(?mac)) {
|
||||
expr_mac(fold_mac(mac))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -365,7 +365,15 @@ fn next_token(&reader rdr) -> token::token {
|
|||
case ('?') { rdr.bump(); ret token::QUES; }
|
||||
case (';') { rdr.bump(); ret token::SEMI; }
|
||||
case (',') { rdr.bump(); ret token::COMMA; }
|
||||
case ('.') { rdr.bump(); ret token::DOT; }
|
||||
case ('.') {
|
||||
rdr.bump();
|
||||
if (rdr.curr() == '.' && rdr.next() == '.') {
|
||||
rdr.bump();
|
||||
rdr.bump();
|
||||
ret token::ELIPSIS;
|
||||
}
|
||||
ret token::DOT;
|
||||
}
|
||||
case ('(') { rdr.bump(); ret token::LPAREN; }
|
||||
case (')') { rdr.bump(); ret token::RPAREN; }
|
||||
case ('{') { rdr.bump(); ret token::LBRACE; }
|
||||
|
|
|
@ -740,6 +740,12 @@ fn mk_expr(&parser p, uint lo, uint hi, &ast::expr_ node) -> @ast::expr {
|
|||
span=rec(lo=lo, hi=hi));
|
||||
}
|
||||
|
||||
fn mk_mac_expr(&parser p, uint lo, uint hi, &ast::mac_ m) -> @ast::expr {
|
||||
ret @rec(id=p.get_id(),
|
||||
node=ast::expr_mac(rec(node=m, span=rec(lo=lo, hi=hi))),
|
||||
span=rec(lo=lo, hi=hi));
|
||||
}
|
||||
|
||||
fn parse_bottom_expr(&parser p) -> @ast::expr {
|
||||
auto lo = p.get_lo_pos();
|
||||
auto hi = p.get_hi_pos();
|
||||
|
@ -800,11 +806,14 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
|
|||
ex = ast::expr_vec(es, mut, ast::sk_rc);
|
||||
} else if (p.peek() == token::POUND_LT) {
|
||||
p.bump();
|
||||
ex = ast::expr_embeded_type(parse_ty(p));
|
||||
auto ty = parse_ty(p);
|
||||
expect(p, token::GT);
|
||||
/* hack: early return to take advantage of specialized function */
|
||||
ret mk_mac_expr(p, lo, p.get_hi_pos(), ast::mac_embed_type(ty))
|
||||
} else if (p.peek() == token::POUND_LBRACE) {
|
||||
p.bump();
|
||||
ex = ast::expr_embeded_block(parse_block_tail(p));
|
||||
auto blk = ast::mac_embed_block(parse_block_tail(p));
|
||||
ret mk_mac_expr(p, lo, p.get_hi_pos(), blk);
|
||||
} else if (p.peek() == token::TILDE) {
|
||||
p.bump();
|
||||
alt (p.peek()) {
|
||||
|
@ -899,7 +908,7 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
|
|||
ex = ast::expr_bind(e, es.node);
|
||||
} else if (p.peek() == token::POUND) {
|
||||
auto ex_ext = parse_syntax_ext(p);
|
||||
lo = ex_ext.span.lo;
|
||||
hi = ex_ext.span.hi;
|
||||
ex = ex_ext.node;
|
||||
} else if (eat_word(p, "fail")) {
|
||||
if (can_begin_expr(p.peek())) {
|
||||
|
@ -913,18 +922,22 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
|
|||
} else if (eat_word(p, "log")) {
|
||||
auto e = parse_expr(p);
|
||||
ex = ast::expr_log(1, e);
|
||||
hi = e.span.hi;
|
||||
} else if (eat_word(p, "log_err")) {
|
||||
auto e = parse_expr(p);
|
||||
ex = ast::expr_log(0, e);
|
||||
hi = e.span.hi;
|
||||
} else if (eat_word(p, "assert")) {
|
||||
auto e = parse_expr(p);
|
||||
ex = ast::expr_assert(e);
|
||||
hi = e.span.hi;
|
||||
} else if (eat_word(p, "check")) {
|
||||
/* Should be a predicate (pure boolean function) applied to
|
||||
arguments that are all either slot variables or literals.
|
||||
but the typechecker enforces that. */
|
||||
|
||||
auto e = parse_expr(p);
|
||||
hi = e.span.hi;
|
||||
ex = ast::expr_check(ast::checked, e);
|
||||
} else if (eat_word(p, "claim")) {
|
||||
/* Same rules as check, except that if check-claims
|
||||
|
@ -932,6 +945,7 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
|
|||
claims into check */
|
||||
|
||||
auto e = parse_expr(p);
|
||||
hi = e.span.hi;
|
||||
ex = ast::expr_check(ast::unchecked, e);
|
||||
} else if (eat_word(p, "ret")) {
|
||||
alt (p.peek()) {
|
||||
|
@ -946,8 +960,10 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
|
|||
}
|
||||
} else if (eat_word(p, "break")) {
|
||||
ex = ast::expr_break;
|
||||
hi = p.get_hi_pos();
|
||||
} else if (eat_word(p, "cont")) {
|
||||
ex = ast::expr_cont;
|
||||
hi = p.get_hi_pos();
|
||||
} else if (eat_word(p, "put")) {
|
||||
alt (p.peek()) {
|
||||
case (token::SEMI) { ex = ast::expr_put(none); }
|
||||
|
@ -1022,7 +1038,7 @@ fn parse_syntax_ext_naked(&parser p, uint lo) -> @ast::expr {
|
|||
auto es = parse_seq_ivec(token::LPAREN, token::RPAREN,
|
||||
some(token::COMMA), parse_expr, p);
|
||||
auto hi = es.span.hi;
|
||||
ret mk_expr(p, lo, hi, ast::expr_ext(pth, es.node, none));
|
||||
ret mk_mac_expr(p, lo, hi, ast::mac_invoc(pth, es.node, none));
|
||||
}
|
||||
|
||||
fn parse_self_method(&parser p) -> @ast::expr {
|
||||
|
@ -1661,7 +1677,7 @@ fn stmt_ends_with_semi(&ast::stmt stmt) -> bool {
|
|||
case (ast::expr_field(_, _)) { true }
|
||||
case (ast::expr_index(_, _)) { true }
|
||||
case (ast::expr_path(_)) { true }
|
||||
case (ast::expr_ext(_, _, _)) { true }
|
||||
case (ast::expr_mac(_)) { true }
|
||||
case (ast::expr_fail(_)) { true }
|
||||
case (ast::expr_break) { true }
|
||||
case (ast::expr_cont) { true }
|
||||
|
|
|
@ -43,6 +43,7 @@ tag token {
|
|||
/* Structural symbols */
|
||||
AT;
|
||||
DOT;
|
||||
ELIPSIS;
|
||||
COMMA;
|
||||
SEMI;
|
||||
COLON;
|
||||
|
|
|
@ -602,11 +602,19 @@ fn print_stmt(&ps s, &ast::stmt st) {
|
|||
maybe_print_trailing_comment(s, st.span, none[uint]);
|
||||
}
|
||||
|
||||
fn print_block(&ps s, ast::block blk) {
|
||||
fn print_block(&ps s, &ast::block blk) {
|
||||
print_possibly_embedded_block(s, blk, false);
|
||||
}
|
||||
|
||||
fn print_possibly_embedded_block(&ps s, &ast::block blk, bool embedded) {
|
||||
maybe_print_comment(s, blk.span.lo);
|
||||
auto ann_node = node_block(s, blk);
|
||||
s.ann.pre(ann_node);
|
||||
bopen(s);
|
||||
if (embedded) {
|
||||
word(s.s, "#{"); end(s);
|
||||
} else {
|
||||
bopen(s);
|
||||
}
|
||||
for (@ast::stmt st in blk.node.stmts) { print_stmt(s, *st) }
|
||||
alt (blk.node.expr) {
|
||||
case (some(?expr)) {
|
||||
|
@ -662,6 +670,33 @@ fn print_if(&ps s, &@ast::expr test, &ast::block block,
|
|||
do_else(s, elseopt);
|
||||
}
|
||||
|
||||
fn print_mac(&ps s, &ast::mac m) {
|
||||
alt (m.node) {
|
||||
case (ast::mac_invoc(?path, ?args, ?body)) {
|
||||
word(s.s, "#");
|
||||
print_path(s, path);
|
||||
if (ivec::len(args) > 0u) {
|
||||
popen(s);
|
||||
commasep_exprs(s, inconsistent, args);
|
||||
pclose(s);
|
||||
}
|
||||
// FIXME: extension 'body'
|
||||
|
||||
}
|
||||
case (ast::mac_embed_type(?ty)) {
|
||||
word(s.s, "#<");
|
||||
print_type(s, *ty);
|
||||
word(s.s, ">");
|
||||
}
|
||||
case (ast::mac_embed_block(?blk)) {
|
||||
print_possibly_embedded_block(s, blk, true);
|
||||
}
|
||||
case (ast::mac_elipsis) {
|
||||
word(s.s, "...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_expr(&ps s, &@ast::expr expr) {
|
||||
maybe_print_comment(s, expr.span.lo);
|
||||
ibox(s, indent_unit);
|
||||
|
@ -961,16 +996,8 @@ fn print_expr(&ps s, &@ast::expr expr) {
|
|||
print_expr(s, expr);
|
||||
pclose(s);
|
||||
}
|
||||
case (ast::expr_ext(?path, ?args, ?body)) {
|
||||
word(s.s, "#");
|
||||
print_path(s, path);
|
||||
if (ivec::len(args) > 0u) {
|
||||
popen(s);
|
||||
commasep_exprs(s, inconsistent, args);
|
||||
pclose(s);
|
||||
}
|
||||
// FIXME: extension 'body'
|
||||
|
||||
case (ast::expr_mac(?m)) {
|
||||
print_mac(s, m);
|
||||
}
|
||||
case (ast::expr_port(?ot)) {
|
||||
word(s.s, "port");
|
||||
|
|
|
@ -256,6 +256,15 @@ fn visit_exprs[E](&(@expr)[] exprs, &E e, &vt[E] v) {
|
|||
for (@expr ex in exprs) { v.visit_expr(ex, e, v); }
|
||||
}
|
||||
|
||||
fn visit_mac[E](mac m, &E e, &vt[E] v) {
|
||||
alt(m.node) {
|
||||
case (ast::mac_invoc(?pth, ?args, ?body)) { visit_exprs(args, e, v); }
|
||||
case (ast::mac_embed_type(?ty)) { v.visit_ty(ty, e, v); }
|
||||
case (ast::mac_embed_block(?blk)) { v.visit_block(blk, e, v); }
|
||||
case (ast::mac_elipsis) { }
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_expr[E](&@expr ex, &E e, &vt[E] v) {
|
||||
alt (ex.node) {
|
||||
case (expr_vec(?es, _, _)) { visit_exprs(es, e, v); }
|
||||
|
@ -362,11 +371,6 @@ fn visit_expr[E](&@expr ex, &E e, &vt[E] v) {
|
|||
case (expr_path(?p)) {
|
||||
for (@ty tp in p.node.types) { v.visit_ty(tp, e, v); }
|
||||
}
|
||||
case (expr_ext(_, ?args, _)) {
|
||||
for(@ast::expr arg in args) {
|
||||
vt(v).visit_expr(arg, e, v);
|
||||
}
|
||||
}
|
||||
case (expr_fail(?eo)) {
|
||||
visit_expr_opt(eo, e, v);
|
||||
}
|
||||
|
@ -399,11 +403,8 @@ fn visit_expr[E](&@expr ex, &E e, &vt[E] v) {
|
|||
m.node.id, e, v);
|
||||
}
|
||||
}
|
||||
case (expr_embeded_type(?ty)) {
|
||||
vt(v).visit_ty(ty, e, v);
|
||||
}
|
||||
case (expr_embeded_block(?blk)) {
|
||||
vt(v).visit_block(blk, e, v);
|
||||
case (expr_mac(?mac)) {
|
||||
visit_mac(mac, e, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -269,6 +269,15 @@ fn walk_exprs(&ast_visitor v, &(@ast::expr)[] exprs) {
|
|||
for (@ast::expr e in exprs) { walk_expr(v, e); }
|
||||
}
|
||||
|
||||
fn walk_mac(&ast_visitor v, ast::mac mac) {
|
||||
alt(mac.node) {
|
||||
case (ast::mac_invoc(?pth, ?args, ?body)) { walk_exprs(v, args); }
|
||||
case (ast::mac_embed_type(?ty)) { walk_ty(v, ty); }
|
||||
case (ast::mac_embed_block(?blk)) { walk_block(v, blk); }
|
||||
case (ast::mac_elipsis) { }
|
||||
}
|
||||
}
|
||||
|
||||
fn walk_expr(&ast_visitor v, @ast::expr e) {
|
||||
if (!v.keep_going()) { ret; }
|
||||
v.visit_expr_pre(e);
|
||||
|
@ -367,11 +376,6 @@ fn walk_expr(&ast_visitor v, @ast::expr e) {
|
|||
case (ast::expr_path(?p)) {
|
||||
for (@ast::ty tp in p.node.types) { walk_ty(v, tp); }
|
||||
}
|
||||
case (ast::expr_ext(_, ?args, _)) {
|
||||
for (@ast::expr e in args) {
|
||||
walk_expr(v, e);
|
||||
}
|
||||
}
|
||||
case (ast::expr_fail(?eo)) { walk_expr_opt(v, eo); }
|
||||
case (ast::expr_break) { }
|
||||
case (ast::expr_cont) { }
|
||||
|
@ -410,11 +414,8 @@ fn walk_expr(&ast_visitor v, @ast::expr e) {
|
|||
v.visit_method_post(m);
|
||||
}
|
||||
}
|
||||
case (ast::expr_embeded_type(?ty)) {
|
||||
walk_ty(v, ty);
|
||||
}
|
||||
case (ast::expr_embeded_block(?blk)) {
|
||||
walk_block(v, blk);
|
||||
case (ast::expr_mac(?mac)) {
|
||||
walk_mac(v, mac);
|
||||
}
|
||||
}
|
||||
v.visit_expr_post(e);
|
||||
|
|
Loading…
Reference in a new issue