Add operator 'copy', translates as fall-through.

This commit is contained in:
Graydon Hoare 2011-08-15 15:35:40 -07:00
parent 9ca8df93b3
commit 814bf41d89
13 changed files with 51 additions and 9 deletions

View File

@ -5052,6 +5052,10 @@ fn trans_expr_out(cx: &@block_ctxt, e: &@ast::expr, output: out_method) ->
sub.bcx.build.Br(next_cx.llbb);
ret rslt(next_cx, sub.val);
}
ast::expr_copy(a) {
// FIXME: this has more-subtle semantics than just "fall through".
ret trans_expr_out(cx, a, output);
}
ast::expr_move(dst, src) {
let lhs_res = trans_lval(cx, dst);
assert (lhs_res.is_mem);

View File

@ -517,12 +517,13 @@ fn mk_fail(cx: &@block_ctxt, sp: &span,
// Not alt-related, but similar to the pattern-munging code above
fn bind_irrefutable_pat(bcx: @block_ctxt, pat: &@ast::pat, val: ValueRef,
table: hashmap[ast::node_id, ValueRef], copy: bool)
table: hashmap[ast::node_id, ValueRef],
make_copy: bool)
-> @block_ctxt {
let ccx = bcx.fcx.lcx.ccx;
alt pat.node {
ast::pat_bind(_) {
if copy {
if make_copy {
let ty = ty::node_id_to_monotype(ccx.tcx, pat.id);
let llty = trans::type_of(ccx, pat.span, ty);
let alloc = trans::alloca(bcx, llty);
@ -541,7 +542,8 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: &@ast::pat, val: ValueRef,
let args = extract_variant_args(bcx, pat.id, vdefs, val);
let i = 0;
for argval: ValueRef in args.vals {
bcx = bind_irrefutable_pat(bcx, sub.(i), argval, table, copy);
bcx = bind_irrefutable_pat(bcx, sub.(i), argval, table,
make_copy);
i += 1;
}
}
@ -553,7 +555,7 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: &@ast::pat, val: ValueRef,
let ix: uint =
ty::field_idx(ccx.sess, pat.span, f.ident, rec_fields);
let r = trans::GEP_tup_like(bcx, rec_ty, val, ~[0, ix as int]);
bcx = bind_irrefutable_pat(r.bcx, f.pat, r.val, table, copy);
bcx = bind_irrefutable_pat(r.bcx, f.pat, r.val, table, make_copy);
}
}
ast::pat_tup(elems) {
@ -561,7 +563,7 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: &@ast::pat, val: ValueRef,
let i = 0u;
for elem in elems {
let r = trans::GEP_tup_like(bcx, tup_ty, val, ~[0, i as int]);
bcx = bind_irrefutable_pat(r.bcx, elem, r.val, table, copy);
bcx = bind_irrefutable_pat(r.bcx, elem, r.val, table, make_copy);
i += 1u;
}
}

View File

@ -406,6 +406,10 @@ fn find_pre_post_expr(fcx: &fn_ctxt, e: @expr) {
expr_tup(elts) {
find_pre_post_exprs(fcx, elts, e.id);
}
expr_copy(a) {
find_pre_post_expr(fcx, a);
copy_pre_post(fcx.ccx, e.id, a);
}
expr_move(lhs, rhs) { handle_update(fcx, e, lhs, rhs, oper_move); }
expr_swap(lhs, rhs) { handle_update(fcx, e, lhs, rhs, oper_swap); }
expr_assign(lhs, rhs) { handle_update(fcx, e, lhs, rhs, oper_assign); }

View File

@ -393,6 +393,9 @@ fn find_pre_post_state_expr(fcx: &fn_ctxt, pres: &prestate, e: @expr) ->
ivec::len(elts)),
elts, return);
}
expr_copy(a) {
ret find_pre_post_state_sub(fcx, pres, a, e.id, none);
}
expr_move(lhs, rhs) {
ret find_pre_post_state_two(fcx, pres, lhs, rhs, e.id, oper_move);
}

View File

@ -204,8 +204,8 @@ fn tritv_copy(target: &t, source: &t) -> bool {
let changed =
!bitv::equal(target.uncertain, source.uncertain) ||
!bitv::equal(target.val, source.val);
bitv::copy(target.uncertain, source.uncertain);
bitv::copy(target.val, source.val);
bitv::assign(target.uncertain, source.uncertain);
bitv::assign(target.val, source.val);
ret changed;
}

View File

@ -1942,6 +1942,13 @@ fn check_binop_type_compat(fcx: &@fn_ctxt, span: span, ty: ty::t,
bot = check_expr_with(fcx, e, ty::mk_bool(tcx));
write::nil_ty(tcx, id);
}
ast::expr_copy(a) {
bot = check_expr_with_unifier(fcx, a, unify, expected);
let tpot = ty::node_id_to_ty_param_substs_opt_and_ty(fcx.ccx.tcx,
a.id);
write::ty_fixup(fcx, id, tpot);
}
ast::expr_move(lhs, rhs) {
require_impure(tcx.sess, fcx.purity, expr.span);
bot = check_assignment(fcx, expr.span, lhs, rhs, id);

View File

@ -317,6 +317,7 @@ fn unop_to_str(op: unop) -> str {
* FIXME: many of these @exprs should be constrained with
* is_lval once we have constrained types working.
*/
expr_copy(@expr);
expr_move(@expr, @expr);
expr_assign(@expr, @expr);
expr_swap(@expr, @expr);

View File

@ -397,6 +397,9 @@ fn fold_anon_obj_field_(aof: &anon_obj_field, fld: ast_fold) ->
expr_move(el, er) {
expr_move(fld.fold_expr(el), fld.fold_expr(er))
}
expr_copy(e) {
expr_copy(fld.fold_expr(e))
}
expr_assign(el, er) {
expr_assign(fld.fold_expr(el), fld.fold_expr(er))
}

View File

@ -180,6 +180,7 @@ fn bad_expr_word_table() -> hashmap[str, ()] {
words.insert("log_err", ());
words.insert("tag", ());
words.insert("obj", ());
words.insert("copy", ());
ret words;
}
@ -999,6 +1000,10 @@ fn parse_expr_opt(p: &parser) -> option::t[@ast::expr] {
hi = e.span.hi;
expect(p, token::RPAREN);
ex = ast::expr_chan(e);
} else if (eat_word(p, "copy")) {
let e = parse_expr(p);
ex = ast::expr_copy(e);
hi = e.span.hi;
} else if (eat_word(p, "self")) {
log "parsing a self-call...";
expect(p, token::DOT);

View File

@ -881,6 +881,10 @@ fn print_opt(s: &ps, expr: &option::t[@ast::expr]) {
ibox(s, 0u);
print_block(s, blk);
}
ast::expr_copy(e) {
word_space(s, "copy");
print_expr(s, e);
}
ast::expr_move(lhs, rhs) {
print_expr(s, lhs);
space(s.s);

View File

@ -299,6 +299,7 @@ fn visit_expr[E](ex: &@expr, e: &E, v: &vt[E]) {
expr_fn(f) { 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); }
expr_move(a, b) { v.visit_expr(b, e, v); v.visit_expr(a, e, v); }
expr_swap(a, b) { v.visit_expr(a, e, v); v.visit_expr(b, e, v); }
expr_assign_op(_, a, b) {

View File

@ -3,7 +3,7 @@
export create;
export union;
export intersect;
export copy;
export assign;
export clone;
export get;
export equal;
@ -63,7 +63,10 @@ fn intersect(v0: &t, v1: &t) -> bool {
fn right(w0: uint, w1: uint) -> uint { ret w1; }
fn copy(v0: &t, v1: t) -> bool { let sub = right; ret process(sub, v0, v1); }
fn assign(v0: &t, v1: t) -> bool {
let sub = right;
ret process(sub, v0, v1);
}
fn clone(v: t) -> t {
let storage = ivec::init_elt_mut[uint](0u, v.nbits / uint_bits() + 1u);

View File

@ -0,0 +1,5 @@
fn main() {
let x = 10;
let y = copy x;
log y;
}