diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2011-12-29 20:07:55 -0800 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2011-12-29 20:29:28 -0800 |
| commit | aa5382bb13690ff183f6e94065dadf0524ce1c6e (patch) | |
| tree | 627037c40c72983b75572e1bc3d04c0b3ab3fde4 /src/comp/syntax | |
| parent | d6db9506f421ebc6a48cc101307c1f5dca92c53e (diff) | |
| download | rust-aa5382bb13690ff183f6e94065dadf0524ce1c6e.tar.gz rust-aa5382bb13690ff183f6e94065dadf0524ce1c6e.zip | |
split proto from fn_decl, as not all fn_decls know the proto.
this will address the (crashing) new test added.
Diffstat (limited to 'src/comp/syntax')
| -rw-r--r-- | src/comp/syntax/ast.rs | 7 | ||||
| -rw-r--r-- | src/comp/syntax/fold.rs | 11 | ||||
| -rw-r--r-- | src/comp/syntax/parse/parser.rs | 59 | ||||
| -rw-r--r-- | src/comp/syntax/print/pprust.rs | 20 | ||||
| -rw-r--r-- | src/comp/syntax/visit.rs | 77 |
5 files changed, 89 insertions, 85 deletions
diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs index 04516826ba7..b0d51b58040 100644 --- a/src/comp/syntax/ast.rs +++ b/src/comp/syntax/ast.rs @@ -202,7 +202,7 @@ tag expr_ { expr_for(@local, @expr, blk); expr_do_while(blk, @expr); expr_alt(@expr, [arm]); - expr_fn(fn_decl, blk, @capture_clause); + expr_fn(proto, fn_decl, blk, @capture_clause); expr_fn_block(fn_decl, blk); expr_block(blk); @@ -317,7 +317,7 @@ tag ty_ { ty_port(@ty); ty_chan(@ty); ty_rec([ty_field]); - ty_fn(fn_decl); + ty_fn(proto, fn_decl); ty_obj([ty_method]); ty_tup([@ty]); ty_path(@path, node_id); @@ -368,8 +368,7 @@ type ty_constr = spanned<ty_constr_>; type arg = {mode: mode, ty: @ty, ident: ident, id: node_id}; type fn_decl = - {proto: proto, - inputs: [arg], + {inputs: [arg], output: @ty, purity: purity, cf: ret_style, diff --git a/src/comp/syntax/fold.rs b/src/comp/syntax/fold.rs index d06c98b0a31..9313bbcdc58 100644 --- a/src/comp/syntax/fold.rs +++ b/src/comp/syntax/fold.rs @@ -143,8 +143,7 @@ fn fold_mac_(m: mac, fld: ast_fold) -> mac { } fn fold_fn_decl(decl: ast::fn_decl, fld: ast_fold) -> ast::fn_decl { - ret {proto: decl.proto, - inputs: vec::map(decl.inputs, bind fold_arg_(_, fld)), + ret {inputs: vec::map(decl.inputs, bind fold_arg_(_, fld)), output: fld.fold_ty(decl.output), purity: decl.purity, cf: decl.cf, @@ -192,8 +191,7 @@ fn noop_fold_native_item(&&ni: @native_item, fld: ast_fold) -> @native_item { alt ni.node { native_item_ty. { native_item_ty } native_item_fn(fdec, typms) { - native_item_fn({proto: fdec.proto, - inputs: vec::map(fdec.inputs, fold_arg), + native_item_fn({inputs: vec::map(fdec.inputs, fold_arg), output: fld.fold_ty(fdec.output), purity: fdec.purity, cf: fdec.cf, @@ -398,8 +396,9 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ { expr_alt(expr, arms) { expr_alt(fld.fold_expr(expr), vec::map(arms, fld.fold_arm)) } - expr_fn(decl, body, captures) { - expr_fn(fold_fn_decl(decl, fld), fld.fold_block(body), captures) + expr_fn(proto, decl, body, captures) { + expr_fn(proto, fold_fn_decl(decl, fld), + fld.fold_block(body), captures) } expr_fn_block(decl, body) { expr_fn_block(fold_fn_decl(decl, fld), fld.fold_block(body)) diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index b681f713422..dd649779235 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -280,21 +280,21 @@ fn parse_ty_fn(proto: ast::proto, p: parser) -> ast::ty_ { // auto constrs = parse_constrs(~[], p); let constrs: [@ast::constr] = []; let (ret_style, ret_ty) = parse_ret_ty(p); - ret ast::ty_fn({proto: proto, inputs: inputs.node, output: ret_ty, - purity: ast::impure_fn, cf: ret_style, - constraints: constrs}); + ret ast::ty_fn(proto, {inputs: inputs.node, output: ret_ty, + purity: ast::impure_fn, cf: ret_style, + constraints: constrs}); } fn parse_ty_methods(p: parser, allow_tps: bool) -> [ast::ty_method] { parse_seq(token::LBRACE, token::RBRACE, seq_sep_none(), {|p| let flo = p.get_lo_pos(); - let proto: ast::proto = parse_method_proto(p); + expect_word(p, "fn"); let ident = parse_value_ident(p); let tps = allow_tps ? parse_ty_params(p) : []; - let f = parse_ty_fn(proto, p), fhi = p.get_last_hi_pos(); + let f = parse_ty_fn(ast::proto_bare, p), fhi = p.get_last_hi_pos(); expect(p, token::SEMI); alt f { - ast::ty_fn(d) { + ast::ty_fn(_, d) { {ident: ident, decl: d, tps: tps, span: ast_util::mk_sp(flo, fhi)} } @@ -1284,10 +1284,10 @@ fn parse_capture_clause(p: parser) -> @ast::capture_clause { fn parse_fn_expr(p: parser, proto: ast::proto) -> @ast::expr { let lo = p.get_last_lo_pos(); let capture_clause = parse_capture_clause(p); - let decl = parse_fn_decl(p, proto, ast::impure_fn); + let decl = parse_fn_decl(p, ast::impure_fn); let body = parse_block(p); ret mk_expr(p, lo, body.span.hi, - ast::expr_fn(decl, body, capture_clause)); + ast::expr_fn(proto, decl, body, capture_clause)); } fn parse_fn_block_expr(p: parser) -> @ast::expr { @@ -1738,7 +1738,7 @@ fn parse_ty_params(p: parser) -> [ast::ty_param] { } else { [] } } -fn parse_fn_decl(p: parser, proto: ast::proto, purity: ast::purity) +fn parse_fn_decl(p: parser, purity: ast::purity) -> ast::fn_decl { let inputs: ast::spanned<[ast::arg]> = parse_seq(token::LPAREN, token::RPAREN, seq_sep(token::COMMA), @@ -1752,8 +1752,7 @@ fn parse_fn_decl(p: parser, proto: ast::proto, purity: ast::purity) constrs = parse_constrs({|x| parse_ty_constr(inputs.node, x) }, p); } let (ret_style, ret_ty) = parse_ret_ty(p); - ret {proto: proto, - inputs: inputs.node, + ret {inputs: inputs.node, output: ret_ty, purity: purity, cf: ret_style, @@ -1766,8 +1765,7 @@ fn parse_fn_block_decl(p: parser) -> ast::fn_decl { seq_sep(token::COMMA), parse_fn_block_arg, p).node; let output = eat(p, token::RARROW) ? parse_ty(p, false) : @spanned(p.get_lo_pos(), p.get_hi_pos(), ast::ty_infer); - ret {proto: ast::proto_block, - inputs: inputs, + ret {inputs: inputs, output: output, purity: ast::impure_fn, cf: ast::return_val, @@ -1789,11 +1787,11 @@ fn mk_item(p: parser, lo: uint, hi: uint, ident: ast::ident, node: ast::item_, span: ast_util::mk_sp(lo, hi)}; } -fn parse_item_fn(p: parser, purity: ast::purity, proto: ast::proto, +fn parse_item_fn(p: parser, purity: ast::purity, attrs: [ast::attribute]) -> @ast::item { let lo = p.get_last_lo_pos(); let t = parse_fn_header(p); - let decl = parse_fn_decl(p, proto, purity); + let decl = parse_fn_decl(p, purity); let body = parse_block(p); ret mk_item(p, lo, body.span.hi, t.ident, ast::item_fn(decl, t.tps, body), attrs); @@ -1819,10 +1817,10 @@ fn parse_anon_obj_field(p: parser) -> ast::anon_obj_field { fn parse_method(p: parser, allow_tps: bool) -> @ast::method { let lo = p.get_lo_pos(); - let proto = parse_method_proto(p); + expect_word(p, "fn"); let ident = parse_value_ident(p); let tps = allow_tps ? parse_ty_params(p) : []; - let decl = parse_fn_decl(p, proto, ast::impure_fn); + let decl = parse_fn_decl(p, ast::impure_fn); let body = parse_block(p); @{ident: ident, tps: tps, decl: decl, body: body, id: p.get_id(), span: ast_util::mk_sp(lo, body.span.hi)} @@ -1900,8 +1898,7 @@ fn parse_item_res(p: parser, attrs: [ast::attribute]) -> @ast::item { expect(p, token::RPAREN); let dtor = parse_block_no_value(p); let decl = - {proto: ast::proto_bare, - inputs: + {inputs: [{mode: ast::by_ref, ty: t, ident: arg_ident, id: p.get_id()}], output: @spanned(lo, lo, ast::ty_nil), @@ -1974,7 +1971,7 @@ fn parse_item_native_fn(p: parser, attrs: [ast::attribute], purity: ast::purity) -> @ast::native_item { let lo = p.get_last_lo_pos(); let t = parse_fn_header(p); - let decl = parse_fn_decl(p, ast::proto_bare, purity); + let decl = parse_fn_decl(p, purity); let hi = p.get_hi_pos(); expect(p, token::SEMI); ret @{ident: t.ident, @@ -2107,10 +2104,6 @@ fn parse_item_tag(p: parser, attrs: [ast::attribute]) -> @ast::item { ret mk_item(p, lo, hi, id, ast::item_tag(variants, ty_params), attrs); } -fn parse_fn_item_proto(_p: parser) -> ast::proto { - ast::proto_bare -} - fn parse_fn_ty_proto(p: parser) -> ast::proto { if p.peek() == token::AT { p.bump(); @@ -2120,32 +2113,22 @@ fn parse_fn_ty_proto(p: parser) -> ast::proto { } } -fn parse_method_proto(p: parser) -> ast::proto { - if eat_word(p, "fn") { - ret ast::proto_bare; - } else { unexpected(p, p.peek()); } -} - fn parse_item(p: parser, attrs: [ast::attribute]) -> option::t<@ast::item> { if eat_word(p, "const") { ret some(parse_item_const(p, attrs)); } else if eat_word(p, "inline") { expect_word(p, "fn"); - let proto = parse_fn_item_proto(p); - ret some(parse_item_fn(p, ast::impure_fn, proto, attrs)); + ret some(parse_item_fn(p, ast::impure_fn, attrs)); } else if is_word(p, "fn") && p.look_ahead(1u) != token::LPAREN { p.bump(); - let proto = parse_fn_item_proto(p); - ret some(parse_item_fn(p, ast::impure_fn, proto, attrs)); + ret some(parse_item_fn(p, ast::impure_fn, attrs)); } else if eat_word(p, "pure") { expect_word(p, "fn"); - let proto = parse_fn_item_proto(p); - ret some(parse_item_fn(p, ast::pure_fn, proto, attrs)); + ret some(parse_item_fn(p, ast::pure_fn, attrs)); } else if is_word(p, "unsafe") && p.look_ahead(1u) != token::LBRACE { p.bump(); expect_word(p, "fn"); - let proto = parse_fn_item_proto(p); - ret some(parse_item_fn(p, ast::unsafe_fn, proto, attrs)); + ret some(parse_item_fn(p, ast::unsafe_fn, attrs)); } else if eat_word(p, "mod") { ret some(parse_item_mod(p, attrs)); } else if eat_word(p, "native") { diff --git a/src/comp/syntax/print/pprust.rs b/src/comp/syntax/print/pprust.rs index 48893f67227..c8f6b1b0a87 100644 --- a/src/comp/syntax/print/pprust.rs +++ b/src/comp/syntax/print/pprust.rs @@ -305,8 +305,8 @@ fn print_type(s: ps, &&ty: @ast::ty) { commasep(s, inconsistent, elts, print_type); pclose(s); } - ast::ty_fn(d) { - print_ty_fn(s, d, none::<str>); + ast::ty_fn(proto, d) { + print_ty_fn(s, proto, d, none::<str>); } ast::ty_obj(methods) { head(s, "obj"); @@ -519,7 +519,7 @@ fn print_ty_method(s: ps, m: ast::ty_method) { hardbreak_if_not_bol(s); cbox(s, indent_unit); maybe_print_comment(s, m.span.lo); - print_ty_fn(s, m.decl, some(m.ident)); + print_ty_fn(s, ast::proto_bare, m.decl, some(m.ident)); word(s.s, ";"); end(s); } @@ -840,8 +840,8 @@ fn print_expr(s: ps, &&expr: @ast::expr) { } bclose_(s, expr.span, alt_indent_unit); } - ast::expr_fn(decl, body, captures) { // NDM captures - head(s, proto_to_str(decl.proto)); + ast::expr_fn(proto, decl, body, captures) { // NDM captures + head(s, proto_to_str(proto)); print_fn_args_and_ret(s, decl); space(s.s); print_block(s, body); @@ -1147,8 +1147,9 @@ fn print_pat(s: ps, &&pat: @ast::pat) { fn print_fn(s: ps, decl: ast::fn_decl, name: ast::ident, typarams: [ast::ty_param]) { alt decl.purity { - ast::impure_fn. { head(s, proto_to_str(decl.proto)); } - _ { head(s, "pure fn"); } + ast::impure_fn. { head(s, "fn"); } + ast::unsafe_fn. { head(s, "unsafe fn"); } + ast::pure_fn. { head(s, "pure fn"); } } word(s.s, name); print_type_params(s, typarams); @@ -1360,9 +1361,10 @@ fn print_mt(s: ps, mt: ast::mt) { print_type(s, mt.ty); } -fn print_ty_fn(s: ps, decl: ast::fn_decl, id: option::t<ast::ident>) { +fn print_ty_fn(s: ps, proto: ast::proto, + decl: ast::fn_decl, id: option::t<ast::ident>) { ibox(s, indent_unit); - word(s.s, proto_to_str(decl.proto)); + word(s.s, proto_to_str(proto)); alt id { some(id) { word(s.s, " "); word(s.s, id); } _ { } } zerobreak(s.s); popen(s); diff --git a/src/comp/syntax/visit.rs b/src/comp/syntax/visit.rs index 64dfafb9c4b..e2767160302 100644 --- a/src/comp/syntax/visit.rs +++ b/src/comp/syntax/visit.rs @@ -15,6 +15,28 @@ import codemap::span; // hold functions that take visitors. A vt tag is used to break the cycle. tag vt<E> { mk_vt(visitor<E>); } +tag fn_kind { + fk_item_fn(ident, [ty_param]); //< an item declared with fn() + fk_method(ident, [ty_param]); + fk_res(ident, [ty_param]); + fk_anon(proto); //< an anonymous function like lambda(...) + fk_fn_block; //< a block {||...} +} + +fn name_of_fn(fk: fn_kind) -> ident { + alt fk { + fk_item_fn(name, _) | fk_method(name, _) | fk_res(name, _) { name } + fk_anon(_) | fk_fn_block. { "anon" } + } +} + +fn tps_of_fn(fk: fn_kind) -> [ty_param] { + alt fk { + fk_item_fn(_, tps) | fk_method(_, tps) | fk_res(_, tps) { tps } + fk_anon(_) | fk_fn_block. { [] } + } +} + type visitor<E> = // takes the components so that one function can be // generic over constr and ty_constr @@ -31,8 +53,7 @@ type visitor<E> = visit_expr: fn@(@expr, E, vt<E>), visit_ty: fn@(@ty, E, vt<E>), visit_constr: fn@(@path, span, node_id, E, vt<E>), - visit_fn: fn@(fn_decl, [ty_param], blk, span, fn_ident, node_id, - E, vt<E>)}; + visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id, E, vt<E>)}; fn default_visitor<E>() -> visitor<E> { ret @{visit_mod: bind visit_mod::<E>(_, _, _, _), @@ -48,7 +69,7 @@ fn default_visitor<E>() -> visitor<E> { visit_expr: bind visit_expr::<E>(_, _, _), visit_ty: bind skip_ty::<E>(_, _, _), visit_constr: bind visit_constr::<E>(_, _, _, _, _), - visit_fn: bind visit_fn::<E>(_, _, _, _, _, _, _, _)}; + visit_fn: bind visit_fn::<E>(_, _, _, _, _, _, _)}; } fn visit_crate<E>(c: crate, e: E, v: vt<E>) { @@ -85,7 +106,7 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) { alt i.node { item_const(t, ex) { v.visit_ty(t, e, v); v.visit_expr(ex, e, v); } item_fn(decl, tp, body) { - v.visit_fn(decl, tp, body, i.span, some(i.ident), i.id, e, v); + v.visit_fn(fk_item_fn(i.ident, tp), decl, body, i.span, i.id, e, v); } item_mod(m) { v.visit_mod(m, i.span, e, v); } item_native_mod(nm) { @@ -94,8 +115,8 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) { } item_ty(t, tps) { v.visit_ty(t, e, v); visit_ty_params(tps, e, v); } item_res(decl, tps, body, dtor_id, _) { - v.visit_fn(decl, tps, body, i.span, some(i.ident), dtor_id, - e, v); + v.visit_fn(fk_res(i.ident, tps), decl, body, i.span, + dtor_id, e, v); } item_tag(variants, tps) { visit_ty_params(tps, e, v); @@ -107,8 +128,8 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) { visit_ty_params(tps, e, v); for f: obj_field in ob.fields { v.visit_ty(f.ty, e, v); } for m: @method in ob.methods { - v.visit_fn(m.decl, m.tps, m.body, m.span, - some(m.ident), m.id, e, v); + v.visit_fn(fk_method(m.ident, m.tps), m.decl, m.body, m.span, + m.id, e, v); } } item_impl(tps, ifce, ty, methods) { @@ -116,8 +137,8 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) { alt ifce { some(ty) { v.visit_ty(ty, e, v); } _ {} } v.visit_ty(ty, e, v); for m in methods { - v.visit_fn(m.decl, m.tps, m.body, m.span, - some(m.ident), m.id, e, v); + v.visit_fn(fk_method(m.ident, m.tps), m.decl, m.body, m.span, + m.id, e, v); } } item_iface(tps, methods) { @@ -142,7 +163,7 @@ fn visit_ty<E>(t: @ty, e: E, v: vt<E>) { for f: ty_field in flds { v.visit_ty(f.node.mt.ty, e, v); } } ty_tup(ts) { for tt in ts { v.visit_ty(tt, e, v); } } - ty_fn(decl) { + ty_fn(_, decl) { for a in decl.inputs { v.visit_ty(a.ty, e, v); } for c: @constr in decl.constraints { v.visit_constr(c.node.path, c.span, c.node.id, e, v); @@ -222,10 +243,10 @@ fn visit_fn_decl<E>(fd: fn_decl, e: E, v: vt<E>) { v.visit_ty(fd.output, e, v); } -fn visit_fn<E>(decl: fn_decl, tp: [ty_param], body: blk, _sp: span, - _i: fn_ident, _id: node_id, e: E, v: vt<E>) { +fn visit_fn<E>(fk: fn_kind, decl: fn_decl, body: blk, _sp: span, + _id: node_id, e: E, v: vt<E>) { visit_fn_decl(decl, e, v); - visit_ty_params(tp, e, v); + visit_ty_params(tps_of_fn(fk), e, v); v.visit_block(body, e, v); } @@ -314,11 +335,11 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) { v.visit_expr(x, e, v); for a: arm in arms { v.visit_arm(a, e, v); } } - expr_fn(decl, body, _) { - v.visit_fn(decl, [], body, ex.span, none, ex.id, e, v); + expr_fn(proto, decl, body, _) { + v.visit_fn(fk_anon(proto), decl, body, ex.span, ex.id, e, v); } expr_fn_block(decl, body) { - v.visit_fn(decl, [], body, ex.span, none, ex.id, e, v); + v.visit_fn(fk_fn_block, decl, body, ex.span, ex.id, e, v); } expr_block(b) { v.visit_block(b, e, v); } expr_assign(a, b) { v.visit_expr(b, e, v); v.visit_expr(a, e, v); } @@ -361,8 +382,8 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) { some(ex) { v.visit_expr(ex, e, v); } } for m: @method in anon_obj.methods { - v.visit_fn(m.decl, m.tps, m.body, m.span, - some(m.ident), m.id, e, v); + v.visit_fn(fk_method(m.ident, m.tps), m.decl, m.body, m.span, + m.id, e, v); } } expr_mac(mac) { visit_mac(mac, e, v); } @@ -394,7 +415,7 @@ type simple_visitor = visit_expr: fn@(@expr), visit_ty: fn@(@ty), visit_constr: fn@(@path, span, node_id), - visit_fn: fn@(fn_decl, [ty_param], blk, span, fn_ident, node_id)}; + visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id)}; fn simple_ignore_ty(_t: @ty) {} @@ -412,8 +433,8 @@ fn default_simple_visitor() -> simple_visitor { visit_expr: fn(_e: @expr) { }, visit_ty: simple_ignore_ty, visit_constr: fn(_p: @path, _sp: span, _id: node_id) { }, - visit_fn: fn(_d: fn_decl, _tps: [ty_param], _b: blk, _sp: span, - _ident: fn_ident, _id: node_id) { } + visit_fn: fn(_fk: fn_kind, _d: fn_decl, _b: blk, _sp: span, + _id: node_id) { } }; } @@ -472,11 +493,11 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> { f(pt, sp, id); visit_constr(pt, sp, id, e, v); } - fn v_fn(f: fn@(fn_decl, [ty_param], blk, span, fn_ident, node_id), - decl: fn_decl, tps: [ty_param], body: blk, sp: span, - ident: fn_ident, id: node_id, &&e: (), v: vt<()>) { - f(decl, tps, body, sp, ident, id); - visit_fn(decl, tps, body, sp, ident, id, e, v); + fn v_fn(f: fn@(fn_kind, fn_decl, blk, span, node_id), + fk: fn_kind, decl: fn_decl, body: blk, sp: span, + id: node_id, &&e: (), v: vt<()>) { + f(fk, decl, body, sp, id); + visit_fn(fk, decl, body, sp, id, e, v); } let visit_ty = if v.visit_ty == simple_ignore_ty { bind skip_ty(_, _, _) @@ -497,7 +518,7 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> { visit_expr: bind v_expr(v.visit_expr, _, _, _), visit_ty: visit_ty, visit_constr: bind v_constr(v.visit_constr, _, _, _, _, _), - visit_fn: bind v_fn(v.visit_fn, _, _, _, _, _, _, _, _) + visit_fn: bind v_fn(v.visit_fn, _, _, _, _, _, _, _) }); } |
