syntax: Remove several deep copies that were happening due to misuse of parse_seq

This commit is contained in:
Patrick Walton 2012-06-07 22:09:27 -07:00
parent 26faa37305
commit fd85239119
2 changed files with 91 additions and 77 deletions

View File

@ -209,9 +209,16 @@ impl parser_common for parser {
ret v;
}
// FIXME: A lot of callers go through here, only to copy out the T and
// discard the spanned<> wrapper. I feel as though there should be a
// version of this that does not return a spanned result.
fn parse_unspanned_seq<T: copy>(bra: token::token, ket: token::token,
sep: seq_sep, f: fn(parser) -> T) -> [T] {
self.expect(bra);
let result = self.parse_seq_to_before_end::<T>(ket, sep, f);
self.bump();
ret result;
}
// NB: Do not use this function unless you actually plan to place the
// spanned list in the AST.
fn parse_seq<T: copy>(bra: token::token, ket: token::token, sep: seq_sep,
f: fn(parser) -> T) -> spanned<[T]> {
let lo = self.span.lo;

View File

@ -150,8 +150,8 @@ class parser {
fn parse_ty_fn_decl(purity: ast::purity) -> fn_decl {
let inputs =
self.parse_seq(token::LPAREN, token::RPAREN,
seq_sep(token::COMMA)) { |p|
self.parse_unspanned_seq(token::LPAREN, token::RPAREN,
seq_sep(token::COMMA)) { |p|
let mode = p.parse_arg_mode();
let name = if is_plain_ident(p.token)
&& p.look_ahead(1u) == token::COLON {
@ -170,13 +170,14 @@ class parser {
// story on constrained types.
let constrs: [@constr] = [];
let (ret_style, ret_ty) = self.parse_ret_ty();
ret {inputs: inputs.node, output: ret_ty,
ret {inputs: inputs, output: ret_ty,
purity: purity, cf: ret_style,
constraints: constrs};
}
fn parse_ty_methods() -> [ty_method] {
(self.parse_seq(token::LBRACE, token::RBRACE, seq_sep_none()) { |p|
self.parse_unspanned_seq(token::LBRACE, token::RBRACE,
seq_sep_none()) { |p|
let attrs = p.parse_outer_attributes();
let flo = p.span.lo;
let pur = p.parse_fn_purity();
@ -186,7 +187,7 @@ class parser {
self.expect(token::SEMI);
{ident: ident, attrs: attrs, decl: {purity: pur with d}, tps: tps,
span: mk_sp(flo, fhi)}
}).node
}
}
fn parse_mt() -> mt {
@ -241,21 +242,21 @@ class parser {
fn parse_ty_constr(fn_args: [arg]) -> @constr {
let lo = self.span.lo;
let path = self.parse_path_without_tps();
let args: {node: [@constr_arg], span: span} =
self.parse_seq(token::LPAREN, token::RPAREN,
seq_sep(token::COMMA),
{|p| p.parse_constr_arg(fn_args)});
ret @spanned(lo, args.span.hi,
{path: path, args: args.node, id: self.get_id()});
let args =
self.parse_unspanned_seq(token::LPAREN, token::RPAREN,
seq_sep(token::COMMA),
{|p| p.parse_constr_arg(fn_args)});
ret @spanned(lo, self.span.hi,
{path: path, args: args, id: self.get_id()});
}
fn parse_constr_in_type() -> @ty_constr {
let lo = self.span.lo;
let path = self.parse_path_without_tps();
let args: [@ty_constr_arg] =
self.parse_seq(token::LPAREN, token::RPAREN,
seq_sep(token::COMMA),
{|p| p.parse_type_constr_arg()}).node;
self.parse_unspanned_seq(token::LPAREN, token::RPAREN,
seq_sep(token::COMMA),
{|p| p.parse_type_constr_arg()});
let hi = self.span.lo;
let tc: ty_constr_ = {path: path, args: args, id: self.get_id()};
ret @spanned(lo, hi, tc);
@ -370,15 +371,15 @@ class parser {
self.bump();
ty_ptr(self.parse_mt())
} else if self.token == token::LBRACE {
let elems = self.parse_seq(token::LBRACE, token::RBRACE,
seq_sep_opt(token::COMMA),
{|p| p.parse_ty_field()});
if vec::len(elems.node) == 0u {
let elems = self.parse_unspanned_seq(token::LBRACE, token::RBRACE,
seq_sep_opt(token::COMMA),
{|p| p.parse_ty_field()});
if vec::len(elems) == 0u {
self.unexpected_last(token::RBRACE);
}
let hi = elems.span.hi;
let hi = self.span.hi;
let t = ty_rec(elems.node);
let t = ty_rec(elems);
if self.token == token::COLON {
self.bump();
ty_constr(@{id: self.get_id(),
@ -813,11 +814,11 @@ class parser {
ex = ex_ext.node;
} else if self.eat_keyword("bind") {
let e = self.parse_expr_res(RESTRICT_NO_CALL_EXPRS);
let es = self.parse_seq(token::LPAREN, token::RPAREN,
seq_sep(token::COMMA),
{|p| p.parse_expr_or_hole()});
hi = es.span.hi;
ex = expr_bind(e, es.node);
let es = self.parse_unspanned_seq(token::LPAREN, token::RPAREN,
seq_sep(token::COMMA),
{|p| p.parse_expr_or_hole()});
hi = self.span.hi;
ex = expr_bind(e, es);
} else if self.eat_keyword("fail") {
if can_begin_expr(self.token) {
let e = self.parse_expr();
@ -920,37 +921,37 @@ class parser {
let sep = seq_sep(token::COMMA);
let mut e = none;
if (self.token == token::LPAREN || self.token == token::LBRACKET) {
let lo = self.span.lo;
let es =
if self.token == token::LPAREN {
self.parse_seq(token::LPAREN, token::RPAREN,
sep, {|p| p.parse_expr()})
} else {
self.parse_seq(token::LBRACKET, token::RBRACKET,
sep, {|p| p.parse_expr()})
};
let hi = es.span.hi;
e = some(self.mk_expr(es.span.lo, hi,
expr_vec(es.node, m_imm)));
}
let mut b = none;
if self.token == token::LBRACE {
self.bump();
let lo = self.span.lo;
let mut depth = 1u;
while (depth > 0u) {
alt (self.token) {
token::LBRACE {depth += 1u;}
token::RBRACE {depth -= 1u;}
token::EOF {self.fatal("unexpected EOF in macro body");}
_ {}
}
self.bump();
self.parse_unspanned_seq(token::LPAREN, token::RPAREN,
sep, {|p| p.parse_expr()})
} else {
self.parse_unspanned_seq(token::LBRACKET, token::RBRACKET,
sep, {|p| p.parse_expr()})
};
let hi = self.span.hi;
e = some(self.mk_expr(lo, hi, expr_vec(es, m_imm)));
}
let hi = self.last_span.lo;
b = some({span: mk_sp(lo,hi)});
let mut b = none;
if self.token == token::LBRACE {
self.bump();
let lo = self.span.lo;
let mut depth = 1u;
while (depth > 0u) {
alt (self.token) {
token::LBRACE {depth += 1u;}
token::RBRACE {depth -= 1u;}
token::EOF {self.fatal("unexpected EOF in macro body");}
_ {}
}
self.bump();
}
let hi = self.last_span.lo;
b = some({span: mk_sp(lo,hi)});
}
ret self.mk_mac_expr(lo, self.span.hi, mac_invoc(pth, e, b));
}
ret self.mk_mac_expr(lo, self.span.hi, mac_invoc(pth, e, b));
}
fn parse_dot_or_call_expr() -> pexpr {
let b = self.parse_bottom_expr();
@ -989,16 +990,17 @@ class parser {
alt copy self.token {
// expr(...)
token::LPAREN if self.permits_call() {
let es_opt = self.parse_seq(token::LPAREN, token::RPAREN,
seq_sep(token::COMMA),
{|p| p.parse_expr_or_hole()});
hi = es_opt.span.hi;
let es_opt =
self.parse_unspanned_seq(token::LPAREN, token::RPAREN,
seq_sep(token::COMMA),
{|p| p.parse_expr_or_hole()});
hi = self.span.hi;
let nd =
if vec::any(es_opt.node, {|e| option::is_none(e) }) {
expr_bind(self.to_expr(e), es_opt.node)
if vec::any(es_opt, {|e| option::is_none(e) }) {
expr_bind(self.to_expr(e), es_opt)
} else {
let es = vec::map(es_opt.node) {|e| option::get(e) };
let es = vec::map(es_opt) {|e| option::get(e) };
expr_call(self.to_expr(e), es, false)
};
e = self.mk_pexpr(lo, hi, nd);
@ -1458,11 +1460,12 @@ class parser {
self.expect(token::RPAREN);
}
_ {
let a = self.parse_seq(token::LPAREN, token::RPAREN,
seq_sep(token::COMMA),
{|p| p.parse_pat()});
args = a.node;
hi = a.span.hi;
args =
self.parse_unspanned_seq(token::LPAREN,
token::RPAREN,
seq_sep(token::COMMA),
{|p| p.parse_pat()});
hi = self.span.hi;
}
}
}
@ -1761,8 +1764,8 @@ class parser {
-> (fn_decl, capture_clause) {
let args_or_capture_items: [arg_or_capture_item] =
self.parse_seq(token::LPAREN, token::RPAREN,
seq_sep(token::COMMA), parse_arg_fn).node;
self.parse_unspanned_seq(token::LPAREN, token::RPAREN,
seq_sep(token::COMMA), parse_arg_fn);
let inputs = either::lefts(args_or_capture_items);
let capture_clause = @either::rights(args_or_capture_items);
@ -1788,9 +1791,10 @@ class parser {
if self.eat(token::OROR) {
[]
} else {
self.parse_seq(token::BINOP(token::OR),
token::BINOP(token::OR), seq_sep(token::COMMA),
{|p| p.parse_fn_block_arg()}).node
self.parse_unspanned_seq(token::BINOP(token::OR),
token::BINOP(token::OR),
seq_sep(token::COMMA),
{|p| p.parse_fn_block_arg()})
}
};
let output = if self.eat(token::RARROW) {
@ -2242,10 +2246,12 @@ class parser {
let mut args = [], disr_expr = none;
if self.token == token::LPAREN {
all_nullary = false;
let arg_tys = self.parse_seq(token::LPAREN, token::RPAREN,
let arg_tys =
self.parse_unspanned_seq(token::LPAREN,
token::RPAREN,
seq_sep(token::COMMA),
{|p| p.parse_ty(false)});
for arg_tys.node.each {|ty|
for arg_tys.each {|ty|
args += [{ty: ty, id: self.get_id()}];
}
} else if self.eat(token::EQ) {
@ -2385,9 +2391,10 @@ class parser {
// foo::bar::{a,b,c}
token::LBRACE {
let idents =
self.parse_seq(token::LBRACE, token::RBRACE,
seq_sep(token::COMMA),
{|p| p.parse_path_list_ident()}).node;
self.parse_unspanned_seq(token::LBRACE, token::RBRACE,
seq_sep(token::COMMA),
{|p|
p.parse_path_list_ident()});
let path = @{span: mk_sp(lo, self.span.hi),
global: false, idents: path,
rp: none, types: []};