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)) {
|
case (ast::expr_rec(?args, ?base)) {
|
||||||
ret trans_rec(cx, args, base, e.id);
|
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");
|
ret cx.fcx.lcx.ccx.sess.bug("unexpanded macro");
|
||||||
}
|
}
|
||||||
case (ast::expr_fail(?expr)) {
|
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_break) { clear_pp(expr_pp(fcx.ccx, e)); }
|
||||||
case (expr_cont) { 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_port(_)) { clear_pp(expr_pp(fcx.ccx, e)); }
|
||||||
case (expr_ext(_, _, _)) {
|
case (expr_mac(_)) {
|
||||||
fcx.ccx.tcx.sess.bug("unexpanded macro");
|
fcx.ccx.tcx.sess.bug("unexpanded macro");
|
||||||
}
|
}
|
||||||
case (expr_anon_obj(?anon_obj, _)) {
|
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)) {
|
case (expr_chan(?ex)) {
|
||||||
ret find_pre_post_state_sub(fcx, pres, ex, e.id, none);
|
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");
|
fcx.ccx.tcx.sess.bug("unexpanded macro");
|
||||||
}
|
}
|
||||||
case (expr_put(?maybe_e)) {
|
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);
|
write::ty_only_fixup(fcx, id, tpt._1);
|
||||||
}
|
}
|
||||||
case (ast::expr_ext(_,_,_)) {
|
case (ast::expr_mac(_)) {
|
||||||
fcx.ccx.tcx.sess.bug("unexpanded macro");
|
fcx.ccx.tcx.sess.bug("unexpanded macro");
|
||||||
}
|
}
|
||||||
case (ast::expr_fail(?expr_opt)) {
|
case (ast::expr_fail(?expr_opt)) {
|
||||||
|
|
|
@ -305,7 +305,6 @@ tag expr_ {
|
||||||
expr_field(@expr, ident);
|
expr_field(@expr, ident);
|
||||||
expr_index(@expr, @expr);
|
expr_index(@expr, @expr);
|
||||||
expr_path(path);
|
expr_path(path);
|
||||||
expr_ext(path, (@expr)[], option::t[str]);
|
|
||||||
expr_fail(option::t[@expr]);
|
expr_fail(option::t[@expr]);
|
||||||
expr_break;
|
expr_break;
|
||||||
expr_cont;
|
expr_cont;
|
||||||
|
@ -323,7 +322,18 @@ tag expr_ {
|
||||||
to expr_if_check. */
|
to expr_if_check. */
|
||||||
expr_if_check(@expr, block, option::t[@expr]);
|
expr_if_check(@expr, block, option::t[@expr]);
|
||||||
expr_port(option::t[@ty]);
|
expr_port(option::t[@ty]);
|
||||||
|
expr_chan(@expr);
|
||||||
expr_anon_obj(anon_obj, ty_param[]);
|
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_];
|
type lit = spanned[lit_];
|
||||||
|
@ -433,6 +443,7 @@ tag ty_ {
|
||||||
ty_path(path, node_id);
|
ty_path(path, node_id);
|
||||||
ty_type;
|
ty_type;
|
||||||
ty_constr(@ty, (@constr)[]);
|
ty_constr(@ty, (@constr)[]);
|
||||||
|
ty_mac(mac);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@ import codemap::emit_error;
|
||||||
import driver::session;
|
import driver::session;
|
||||||
import syntax::ast::crate;
|
import syntax::ast::crate;
|
||||||
import syntax::ast::expr_;
|
import syntax::ast::expr_;
|
||||||
import syntax::ast::expr_ext;
|
import syntax::ast::expr_mac;
|
||||||
|
import syntax::ast::mac_invoc;
|
||||||
import syntax::fold::*;
|
import syntax::fold::*;
|
||||||
|
|
||||||
import std::option::none;
|
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,
|
&session::session sess, &expr_ e, ast_fold fld,
|
||||||
&fn(&ast::expr_, ast_fold) -> expr_ orig) -> expr_ {
|
&fn(&ast::expr_, ast_fold) -> expr_ orig) -> expr_ {
|
||||||
ret alt(e) {
|
ret alt(e) {
|
||||||
case (expr_ext(?pth, ?args, ?body)) {
|
case (expr_mac(?mac)) {
|
||||||
assert(ivec::len(pth.node.idents) > 0u);
|
alt(mac.node) {
|
||||||
auto extname = pth.node.idents.(0);
|
case (mac_invoc(?pth, ?args, ?body)) {
|
||||||
auto ext_cx = base::mk_ctxt(sess);
|
assert(ivec::len(pth.node.idents) > 0u);
|
||||||
alt (exts.find(extname)) {
|
auto extname = pth.node.idents.(0);
|
||||||
case (none) {
|
auto ext_cx = base::mk_ctxt(sess);
|
||||||
emit_error(some(pth.span), "unknown syntax expander: '"
|
alt (exts.find(extname)) {
|
||||||
+ extname + "'", sess.get_codemap());
|
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
|
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) }
|
case (_) { orig(e, fld) }
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,11 +22,12 @@ import ast::path;
|
||||||
import ast::path_;
|
import ast::path_;
|
||||||
import ast::expr_path;
|
import ast::expr_path;
|
||||||
import ast::expr_vec;
|
import ast::expr_vec;
|
||||||
import ast::expr_ext;
|
import ast::expr_mac;
|
||||||
|
import ast::mac_invoc;
|
||||||
|
|
||||||
export add_new_extension;
|
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) {
|
for (invk_binding ib in ibs) {
|
||||||
alt (ib) {
|
alt (ib) {
|
||||||
case (ident_binding(?p_id, _)) { if (i == p_id) { ret some(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?
|
// maybe box?
|
||||||
tag invk_binding {
|
tag invk_binding {
|
||||||
|
@ -113,6 +114,24 @@ fn path_to_ident(&path pth) -> option::t[ident] {
|
||||||
ret none;
|
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,
|
fn add_new_extension(&ext_ctxt cx, span sp, &(@ast::expr)[] args,
|
||||||
option::t[str] body) -> tup(str, syntax_extension) {
|
option::t[str] body) -> tup(str, syntax_extension) {
|
||||||
let option::t[str] macro_name = none;
|
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) {
|
alt(arg.node) {
|
||||||
case(expr_vec(?elts, ?mut, ?seq_kind)) {
|
case(expr_vec(?elts, ?mut, ?seq_kind)) {
|
||||||
|
|
||||||
if (len(elts) != 2u) {
|
if (ivec::len(elts) != 2u) {
|
||||||
cx.span_fatal((*arg).span,
|
cx.span_fatal((*arg).span,
|
||||||
"extension clause must consist of [" +
|
"extension clause must consist of [" +
|
||||||
"macro invocation, expansion body]");
|
"macro invocation, expansion body]");
|
||||||
}
|
}
|
||||||
alt(elts.(0u).node) {
|
alt(elts.(0u).node) {
|
||||||
case(expr_ext(?pth, ?invk_args, ?body)) {
|
case(expr_mac(?mac)) {
|
||||||
let str clause_name = alt(path_to_ident(pth)) {
|
alt (mac.node) {
|
||||||
case (some(?id)) { id }
|
case (mac_invoc(?pth, ?invoc_args, ?body)) {
|
||||||
case (none) {
|
process_clause(cx, pat_exts, macro_name,
|
||||||
cx.span_fatal
|
pth, invoc_args, elts.(1u));
|
||||||
(elts.(0u).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(elts.(0u).span, "macros must have"
|
|
||||||
+ " only one name");
|
|
||||||
}
|
}
|
||||||
pat_exts += [rec(invk=invk_args, body=elts.(1u))];
|
|
||||||
}
|
}
|
||||||
case(_) {
|
case(_) {
|
||||||
cx.span_fatal(elts.(0u).span, "extension clause must"
|
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));
|
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)
|
option::t[str] body, @vec[pat_ext] clauses)
|
||||||
-> @ast::expr {
|
-> @ast::expr {
|
||||||
|
|
||||||
/* returns a list of bindings, or none if the match fails. */
|
/* returns a list of bindings, or none if the match fails. */
|
||||||
fn match_invk(@ast::expr pattern, @ast::expr argument)
|
fn match_invk(@ast::expr pattern, @ast::expr argument)
|
||||||
-> option::t[vec[invk_binding]] {
|
-> option::t[(invk_binding)[]] {
|
||||||
auto pat = pattern.node;
|
auto pat = pattern.node;
|
||||||
auto arg = argument.node;
|
auto arg = argument.node;
|
||||||
ret alt (pat) {
|
ret alt (pat) {
|
||||||
case (expr_vec(?p_elts, _, _)) {
|
case (expr_vec(?p_elts, _, _)) {
|
||||||
alt (arg) {
|
alt (arg) {
|
||||||
case (expr_vec(?a_elts, _, _)) {
|
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]]
|
none[vec[invk_binding]]
|
||||||
}
|
}
|
||||||
let uint i = 0u;
|
let uint i = 0u;
|
||||||
let vec[invk_binding] res = [];
|
let (invk_binding)[] res = ~[];
|
||||||
while (i < vec::len(p_elts)) {
|
while (i < ivec::len(p_elts)) {
|
||||||
alt (match_invk(p_elts.(i), a_elts.(i))) {
|
alt (match_invk(p_elts.(i), a_elts.(i))) {
|
||||||
case (some(?v)) { res += v; }
|
case (some(?v)) { res += v; }
|
||||||
case (none) { ret none; }
|
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)) {
|
case (expr_path(?a_pth)) {
|
||||||
alt (path_to_ident(a_pth)) {
|
alt (path_to_ident(a_pth)) {
|
||||||
case (some(?a_id)) {
|
case (some(?a_id)) {
|
||||||
some([ident_binding
|
some(~[ident_binding
|
||||||
(p_id, respan(argument.span,
|
(p_id,
|
||||||
|
respan(argument.span,
|
||||||
a_id))])
|
a_id))])
|
||||||
}
|
}
|
||||||
case (none) {
|
case (none) {
|
||||||
some([path_binding(p_id, @a_pth)])
|
some(~[path_binding(p_id,
|
||||||
|
@a_pth)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case (_) {
|
case (_) {
|
||||||
some([expr_binding(p_id, argument)])
|
some(~[expr_binding(p_id, argument)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// FIXME this still compares on internal spans
|
// 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
|
// 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) {
|
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 uint i = 0u;
|
||||||
let vec[invk_binding] bindings = [];
|
let (invk_binding)[] bindings = ~[];
|
||||||
while (i < vec::len(args)) {
|
while (i < ivec::len(args)) {
|
||||||
alt (match_invk(pe.invk.(i), args.(i))) {
|
alt (match_invk(pe.invk.(i), args.(i))) {
|
||||||
case (some(?v)) { bindings += v; }
|
case (some(?v)) { bindings += v; }
|
||||||
case (none) { cont }
|
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),
|
ret rec(mode=a.mode, ty=fld.fold_ty(a.ty),
|
||||||
ident=fld.fold_ident(a.ident), id=a.id);
|
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_anon_obj = bind fold_anon_obj_(_,fld);
|
||||||
|
|
||||||
|
auto fold_mac = bind fold_mac_(_,fld);
|
||||||
|
|
||||||
ret alt (e) {
|
ret alt (e) {
|
||||||
case (expr_vec(?exprs, ?mut, ?seq_kind)) {
|
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)) {
|
case (expr_path(?pth)) {
|
||||||
expr_path(fld.fold_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_fail(?e)) { expr_fail(option::map(fld.fold_expr, e)) }
|
||||||
case (expr_break()) { e }
|
case (expr_break()) { e }
|
||||||
case (expr_cont()) { 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)) {
|
case (expr_anon_obj(?ao, ?typms)) {
|
||||||
expr_anon_obj(fold_anon_obj(ao), typms)
|
expr_anon_obj(fold_anon_obj(ao), typms)
|
||||||
}
|
}
|
||||||
case (expr_embeded_type(?ty)) {
|
case (expr_mac(?mac)) {
|
||||||
expr_embeded_type(fld.fold_ty(ty))
|
expr_mac(fold_mac(mac))
|
||||||
}
|
|
||||||
case (expr_embeded_block(?blk)) {
|
|
||||||
expr_embeded_block(fld.fold_block(blk))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -365,7 +365,15 @@ fn next_token(&reader rdr) -> token::token {
|
||||||
case ('?') { rdr.bump(); ret token::QUES; }
|
case ('?') { rdr.bump(); ret token::QUES; }
|
||||||
case (';') { rdr.bump(); ret token::SEMI; }
|
case (';') { rdr.bump(); ret token::SEMI; }
|
||||||
case (',') { rdr.bump(); ret token::COMMA; }
|
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::LPAREN; }
|
||||||
case (')') { rdr.bump(); ret token::RPAREN; }
|
case (')') { rdr.bump(); ret token::RPAREN; }
|
||||||
case ('{') { rdr.bump(); ret token::LBRACE; }
|
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));
|
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 {
|
fn parse_bottom_expr(&parser p) -> @ast::expr {
|
||||||
auto lo = p.get_lo_pos();
|
auto lo = p.get_lo_pos();
|
||||||
auto hi = p.get_hi_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);
|
ex = ast::expr_vec(es, mut, ast::sk_rc);
|
||||||
} else if (p.peek() == token::POUND_LT) {
|
} else if (p.peek() == token::POUND_LT) {
|
||||||
p.bump();
|
p.bump();
|
||||||
ex = ast::expr_embeded_type(parse_ty(p));
|
auto ty = parse_ty(p);
|
||||||
expect(p, token::GT);
|
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) {
|
} else if (p.peek() == token::POUND_LBRACE) {
|
||||||
p.bump();
|
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) {
|
} else if (p.peek() == token::TILDE) {
|
||||||
p.bump();
|
p.bump();
|
||||||
alt (p.peek()) {
|
alt (p.peek()) {
|
||||||
|
@ -899,7 +908,7 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
|
||||||
ex = ast::expr_bind(e, es.node);
|
ex = ast::expr_bind(e, es.node);
|
||||||
} else if (p.peek() == token::POUND) {
|
} else if (p.peek() == token::POUND) {
|
||||||
auto ex_ext = parse_syntax_ext(p);
|
auto ex_ext = parse_syntax_ext(p);
|
||||||
lo = ex_ext.span.lo;
|
hi = ex_ext.span.hi;
|
||||||
ex = ex_ext.node;
|
ex = ex_ext.node;
|
||||||
} else if (eat_word(p, "fail")) {
|
} else if (eat_word(p, "fail")) {
|
||||||
if (can_begin_expr(p.peek())) {
|
if (can_begin_expr(p.peek())) {
|
||||||
|
@ -913,18 +922,22 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
|
||||||
} else if (eat_word(p, "log")) {
|
} else if (eat_word(p, "log")) {
|
||||||
auto e = parse_expr(p);
|
auto e = parse_expr(p);
|
||||||
ex = ast::expr_log(1, e);
|
ex = ast::expr_log(1, e);
|
||||||
|
hi = e.span.hi;
|
||||||
} else if (eat_word(p, "log_err")) {
|
} else if (eat_word(p, "log_err")) {
|
||||||
auto e = parse_expr(p);
|
auto e = parse_expr(p);
|
||||||
ex = ast::expr_log(0, e);
|
ex = ast::expr_log(0, e);
|
||||||
|
hi = e.span.hi;
|
||||||
} else if (eat_word(p, "assert")) {
|
} else if (eat_word(p, "assert")) {
|
||||||
auto e = parse_expr(p);
|
auto e = parse_expr(p);
|
||||||
ex = ast::expr_assert(e);
|
ex = ast::expr_assert(e);
|
||||||
|
hi = e.span.hi;
|
||||||
} else if (eat_word(p, "check")) {
|
} else if (eat_word(p, "check")) {
|
||||||
/* Should be a predicate (pure boolean function) applied to
|
/* Should be a predicate (pure boolean function) applied to
|
||||||
arguments that are all either slot variables or literals.
|
arguments that are all either slot variables or literals.
|
||||||
but the typechecker enforces that. */
|
but the typechecker enforces that. */
|
||||||
|
|
||||||
auto e = parse_expr(p);
|
auto e = parse_expr(p);
|
||||||
|
hi = e.span.hi;
|
||||||
ex = ast::expr_check(ast::checked, e);
|
ex = ast::expr_check(ast::checked, e);
|
||||||
} else if (eat_word(p, "claim")) {
|
} else if (eat_word(p, "claim")) {
|
||||||
/* Same rules as check, except that if check-claims
|
/* Same rules as check, except that if check-claims
|
||||||
|
@ -932,6 +945,7 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
|
||||||
claims into check */
|
claims into check */
|
||||||
|
|
||||||
auto e = parse_expr(p);
|
auto e = parse_expr(p);
|
||||||
|
hi = e.span.hi;
|
||||||
ex = ast::expr_check(ast::unchecked, e);
|
ex = ast::expr_check(ast::unchecked, e);
|
||||||
} else if (eat_word(p, "ret")) {
|
} else if (eat_word(p, "ret")) {
|
||||||
alt (p.peek()) {
|
alt (p.peek()) {
|
||||||
|
@ -946,8 +960,10 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
|
||||||
}
|
}
|
||||||
} else if (eat_word(p, "break")) {
|
} else if (eat_word(p, "break")) {
|
||||||
ex = ast::expr_break;
|
ex = ast::expr_break;
|
||||||
|
hi = p.get_hi_pos();
|
||||||
} else if (eat_word(p, "cont")) {
|
} else if (eat_word(p, "cont")) {
|
||||||
ex = ast::expr_cont;
|
ex = ast::expr_cont;
|
||||||
|
hi = p.get_hi_pos();
|
||||||
} else if (eat_word(p, "put")) {
|
} else if (eat_word(p, "put")) {
|
||||||
alt (p.peek()) {
|
alt (p.peek()) {
|
||||||
case (token::SEMI) { ex = ast::expr_put(none); }
|
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,
|
auto es = parse_seq_ivec(token::LPAREN, token::RPAREN,
|
||||||
some(token::COMMA), parse_expr, p);
|
some(token::COMMA), parse_expr, p);
|
||||||
auto hi = es.span.hi;
|
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 {
|
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_field(_, _)) { true }
|
||||||
case (ast::expr_index(_, _)) { true }
|
case (ast::expr_index(_, _)) { true }
|
||||||
case (ast::expr_path(_)) { true }
|
case (ast::expr_path(_)) { true }
|
||||||
case (ast::expr_ext(_, _, _)) { true }
|
case (ast::expr_mac(_)) { true }
|
||||||
case (ast::expr_fail(_)) { true }
|
case (ast::expr_fail(_)) { true }
|
||||||
case (ast::expr_break) { true }
|
case (ast::expr_break) { true }
|
||||||
case (ast::expr_cont) { true }
|
case (ast::expr_cont) { true }
|
||||||
|
|
|
@ -43,6 +43,7 @@ tag token {
|
||||||
/* Structural symbols */
|
/* Structural symbols */
|
||||||
AT;
|
AT;
|
||||||
DOT;
|
DOT;
|
||||||
|
ELIPSIS;
|
||||||
COMMA;
|
COMMA;
|
||||||
SEMI;
|
SEMI;
|
||||||
COLON;
|
COLON;
|
||||||
|
|
|
@ -602,11 +602,19 @@ fn print_stmt(&ps s, &ast::stmt st) {
|
||||||
maybe_print_trailing_comment(s, st.span, none[uint]);
|
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);
|
maybe_print_comment(s, blk.span.lo);
|
||||||
auto ann_node = node_block(s, blk);
|
auto ann_node = node_block(s, blk);
|
||||||
s.ann.pre(ann_node);
|
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) }
|
for (@ast::stmt st in blk.node.stmts) { print_stmt(s, *st) }
|
||||||
alt (blk.node.expr) {
|
alt (blk.node.expr) {
|
||||||
case (some(?expr)) {
|
case (some(?expr)) {
|
||||||
|
@ -662,6 +670,33 @@ fn print_if(&ps s, &@ast::expr test, &ast::block block,
|
||||||
do_else(s, elseopt);
|
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) {
|
fn print_expr(&ps s, &@ast::expr expr) {
|
||||||
maybe_print_comment(s, expr.span.lo);
|
maybe_print_comment(s, expr.span.lo);
|
||||||
ibox(s, indent_unit);
|
ibox(s, indent_unit);
|
||||||
|
@ -961,16 +996,8 @@ fn print_expr(&ps s, &@ast::expr expr) {
|
||||||
print_expr(s, expr);
|
print_expr(s, expr);
|
||||||
pclose(s);
|
pclose(s);
|
||||||
}
|
}
|
||||||
case (ast::expr_ext(?path, ?args, ?body)) {
|
case (ast::expr_mac(?m)) {
|
||||||
word(s.s, "#");
|
print_mac(s, m);
|
||||||
print_path(s, path);
|
|
||||||
if (ivec::len(args) > 0u) {
|
|
||||||
popen(s);
|
|
||||||
commasep_exprs(s, inconsistent, args);
|
|
||||||
pclose(s);
|
|
||||||
}
|
|
||||||
// FIXME: extension 'body'
|
|
||||||
|
|
||||||
}
|
}
|
||||||
case (ast::expr_port(?ot)) {
|
case (ast::expr_port(?ot)) {
|
||||||
word(s.s, "port");
|
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); }
|
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) {
|
fn visit_expr[E](&@expr ex, &E e, &vt[E] v) {
|
||||||
alt (ex.node) {
|
alt (ex.node) {
|
||||||
case (expr_vec(?es, _, _)) { visit_exprs(es, e, v); }
|
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)) {
|
case (expr_path(?p)) {
|
||||||
for (@ty tp in p.node.types) { v.visit_ty(tp, e, v); }
|
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)) {
|
case (expr_fail(?eo)) {
|
||||||
visit_expr_opt(eo, e, v);
|
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);
|
m.node.id, e, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case (expr_embeded_type(?ty)) {
|
case (expr_mac(?mac)) {
|
||||||
vt(v).visit_ty(ty, e, v);
|
visit_mac(mac, e, v);
|
||||||
}
|
|
||||||
case (expr_embeded_block(?blk)) {
|
|
||||||
vt(v).visit_block(blk, 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); }
|
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) {
|
fn walk_expr(&ast_visitor v, @ast::expr e) {
|
||||||
if (!v.keep_going()) { ret; }
|
if (!v.keep_going()) { ret; }
|
||||||
v.visit_expr_pre(e);
|
v.visit_expr_pre(e);
|
||||||
|
@ -367,11 +376,6 @@ fn walk_expr(&ast_visitor v, @ast::expr e) {
|
||||||
case (ast::expr_path(?p)) {
|
case (ast::expr_path(?p)) {
|
||||||
for (@ast::ty tp in p.node.types) { walk_ty(v, tp); }
|
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_fail(?eo)) { walk_expr_opt(v, eo); }
|
||||||
case (ast::expr_break) { }
|
case (ast::expr_break) { }
|
||||||
case (ast::expr_cont) { }
|
case (ast::expr_cont) { }
|
||||||
|
@ -410,11 +414,8 @@ fn walk_expr(&ast_visitor v, @ast::expr e) {
|
||||||
v.visit_method_post(m);
|
v.visit_method_post(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case (ast::expr_embeded_type(?ty)) {
|
case (ast::expr_mac(?mac)) {
|
||||||
walk_ty(v, ty);
|
walk_mac(v, mac);
|
||||||
}
|
|
||||||
case (ast::expr_embeded_block(?blk)) {
|
|
||||||
walk_block(v, blk);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v.visit_expr_post(e);
|
v.visit_expr_post(e);
|
||||||
|
|
Loading…
Reference in a new issue