first attempt, not happy with it

This commit is contained in:
Niko Matsakis 2011-12-09 08:16:04 -08:00
parent 941101a9cd
commit c28ada0368
14 changed files with 66 additions and 67 deletions

View file

@ -237,8 +237,8 @@ tag expr_ {
// At the moment, one can only capture local variables.
type capture_ = {
is_send: bool,
copies: [ident],
moves: [ident]
copies: [spanned<ident>],
moves: [spanned<ident>]
};
type capture = spanned<capture_>;

View file

@ -381,7 +381,8 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
expr_alt(expr, arms) {
expr_alt(fld.fold_expr(expr), vec::map(fld.fold_arm, arms))
}
expr_fn(f) { expr_fn(fld.fold_fn(f)) }
// NDM fold_captures
expr_fn(f, captures) { expr_fn(fld.fold_fn(f), captures) }
expr_block(blk) { expr_block(fld.fold_block(blk)) }
expr_move(el, er) {
expr_move(fld.fold_expr(el), fld.fold_expr(er))

View file

@ -18,7 +18,7 @@ tag fn_kw {
fn_kw_fn;
fn_kw_lambda;
fn_kw_block;
};
}
type parse_sess = @{cm: codemap::codemap, mutable next_id: node_id};
@ -1292,7 +1292,7 @@ fn parse_if_expr(p: parser) -> @ast::expr {
// CC := [send; copy ID*; move ID*]
//
// where any part is optional and trailing ; is permitted.
fn parse_capture_clause(p: parser) -> (bool, @ast::capture) {
fn parse_capture_clause(p: parser) -> @ast::capture {
fn expect_opt_trailing_semi(p: parser) {
if !eat(p, token::SEMI) {
if p.peek() != token::RBRACE {
@ -1301,12 +1301,13 @@ fn parse_capture_clause(p: parser) -> (bool, @ast::capture) {
}
}
fn eat_ident_list(p: parser) -> [ast::ident] {
fn eat_ident_list(p: parser) -> [ast::spanned<ast::ident>] {
let res = [];
while true {
alt p.peek() {
token::IDENT(_, _) {
res += parse_ident(p);
let i = spanned(p.get_lo_pos(), p.get_hi_pos(), parse_ident(p));
res += [i];
if !eat(p, token::COMMA) {
ret res;
}
@ -1321,52 +1322,53 @@ fn parse_capture_clause(p: parser) -> (bool, @ast::capture) {
let copies = [];
let moves = [];
if p.peek() != token::LBRACE {
ret (is_send, captures);
}
expect(p, token::LBRACE);
while p.peek() != token::RBRACE {
if eat_word(p, "send") {
is_send = true;
expect_opt_trailing_semi(p);
} else if eat_word(p, "copy") {
copies += eat_ident_list();
expect_opt_trailing_semi(p);
} else if eat_word(p, "move") {
moves += eat_ident_list();
expect_opt_trailing_semi(p);
} else {
let s: str = "expecting send, copy, or move clause";
p.fatal(s);
let lo = p.get_lo_pos();
if eat(p, token::LBRACE) {
while !eat(p, token::RBRACE) {
if eat_word(p, "send") {
is_send = true;
expect_opt_trailing_semi(p);
} else if eat_word(p, "copy") {
copies += eat_ident_list(p);
expect_opt_trailing_semi(p);
} else if eat_word(p, "move") {
moves += eat_ident_list(p);
expect_opt_trailing_semi(p);
} else {
let s: str = "expecting send, copy, or move clause";
p.fatal(s);
}
}
}
let hi = p.get_last_hi_pos();
ret @{is_send: is_send, copies: copies, moves: moves};
ret @spanned(lo, hi, {is_send: is_send, copies: copies, moves: moves});
}
fn parse_fn_expr(p: parser, kw: fn_kw) -> @ast::expr {
let lo = p.get_last_lo_pos();
let cap = parse_capture_clause(p);
let captures = parse_capture_clause(p);
let decl = parse_fn_decl(p, ast::impure_fn, ast::il_normal);
let body = parse_block(p);
let proto = alt (kw, cap.is_send) {
let proto = alt (kw, captures.node.is_send) {
(fn_kw_fn., true) { ast::proto_bare }
(fn_kw_lambda., true) { ast::proto_send }
(fn_kw_lambda., false) { ast::proto_shared(ast::sugar_sexy) }
(fn_kw_block., false) { ast::proto_block }
(_, true) { p.fatal("only lambda can be declared sendable"); }
}
};
let _fn = {decl: decl, proto: proto, body: body};
ret mk_expr(p, lo, body.span.hi, ast::expr_fn(_fn, cap));
ret mk_expr(p, lo, body.span.hi, ast::expr_fn(_fn, captures));
}
fn parse_fn_block_expr(p: parser) -> @ast::expr {
let lo = p.get_last_lo_pos();
let decl = parse_fn_block_decl(p);
let mid = p.get_last_hi_pos();
let body = parse_block_tail(p, lo, ast::default_blk);
let _fn = {decl: decl, proto: ast::proto_block, body: body};
ret mk_expr(p, lo, body.span.hi, ast::expr_fn(_fn));
let captures = @spanned(lo, mid, {is_send: false, copies: [], moves: []});
ret mk_expr(p, lo, body.span.hi, ast::expr_fn(_fn, captures));
}
fn parse_else_expr(p: parser) -> @ast::expr {

View file

@ -818,7 +818,7 @@ fn print_expr(s: ps, &&expr: @ast::expr) {
}
bclose_(s, expr.span, alt_indent_unit);
}
ast::expr_fn(f) {
ast::expr_fn(f, captures) { // NDM captures
// If the return type is the magic ty_infer, then we need to
// pretty print as a lambda-block

View file

@ -273,7 +273,8 @@ 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(f) { v.visit_fn(f, [], ex.span, none, ex.id, e, v); }
// NDM add visit routine?
expr_fn(f, captures) { v.visit_fn(f, [], ex.span, none, 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); }
expr_copy(a) { v.visit_expr(a, e, v); }