Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Local declarations with receive #286

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/comp/front/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,18 @@ tag stmt_ {
stmt_crate_directive(@crate_directive);
}

tag init_op {
init_assign;
init_recv;
}

type initializer = rec(init_op op,
@expr expr);

type local = rec(option.t[@ty] ty,
bool infer,
ident ident,
option.t[@expr] init,
option.t[initializer] init,
def_id id,
ann ann);

Expand Down
23 changes: 17 additions & 6 deletions src/comp/front/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1364,13 +1364,22 @@ impure fn parse_expr_inner(parser p) -> @ast.expr {
}
}

impure fn parse_initializer(parser p) -> option.t[@ast.expr] {
if (p.peek() == token.EQ) {
p.bump();
ret some(parse_expr(p));
impure fn parse_initializer(parser p) -> option.t[ast.initializer] {
alt (p.peek()) {
case (token.EQ) {
p.bump();
ret some(rec(op = ast.init_assign,
expr = parse_expr(p)));
}
case (token.LARROW) {
p.bump();
ret some(rec(op = ast.init_recv,
expr = parse_expr(p)));
}
case (_) {
ret none[ast.initializer];
}
}

ret none[@ast.expr];
}

impure fn parse_pat(parser p) -> @ast.pat {
Expand Down Expand Up @@ -1612,6 +1621,8 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool {
case (ast.expr_assign(_,_,_)) { ret true; }
case (ast.expr_assign_op(_,_,_,_))
{ ret true; }
case (ast.expr_send(_,_,_)) { ret true; }
case (ast.expr_recv(_,_,_)) { ret true; }
case (ast.expr_field(_,_,_)) { ret true; }
case (ast.expr_index(_,_,_)) { ret true; }
case (ast.expr_path(_,_,_)) { ret true; }
Expand Down
7 changes: 4 additions & 3 deletions src/comp/middle/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,16 +437,17 @@ fn fold_decl[ENV](&ENV env, ast_fold[ENV] fld, @decl d) -> @decl {
alt (d.node) {
case (ast.decl_local(?local)) {
auto ty_ = none[@ast.ty];
auto init_ = none[@ast.expr];
auto init_ = none[ast.initializer];
alt (local.ty) {
case (some[@ast.ty](?t)) {
ty_ = some[@ast.ty](fold_ty(env, fld, t));
}
case (_) { /* fall through */ }
}
alt (local.init) {
case (some[@ast.expr](?e)) {
init_ = some[@ast.expr](fold_expr(env, fld, e));
case (some[ast.initializer](?init)) {
auto e = fold_expr(env, fld, init.expr);
init_ = some[ast.initializer](rec(expr = e with init));
}
case (_) { /* fall through */ }
}
Expand Down
32 changes: 24 additions & 8 deletions src/comp/middle/trans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4839,22 +4839,31 @@ fn trans_recv(@block_ctxt cx, @ast.expr lhs, @ast.expr rhs,
auto data = trans_lval(bcx, lhs);
check (data.is_mem);
bcx = data.res.bcx;
auto unit_ty = node_ann_type(bcx.fcx.ccx, ann);

// FIXME: calculate copy init-ness in typestate.
ret recv_val(bcx, data.res.val, rhs, unit_ty, DROP_EXISTING);
}

fn recv_val(@block_ctxt cx, ValueRef lhs, @ast.expr rhs,
@ty.t unit_ty, copy_action action) -> result {

auto bcx = cx;
auto prt = trans_expr(bcx, rhs);
bcx = prt.bcx;

auto sub = trans_upcall(bcx, "upcall_recv",
vec(vp2i(bcx, data.res.val),
vec(vp2i(bcx, lhs),
vp2i(bcx, prt.val)));
bcx = sub.bcx;

auto unit_ty = node_ann_type(cx.fcx.ccx, ann);
auto data_load = load_scalar_or_boxed(bcx, data.res.val, unit_ty);
auto cp = copy_ty(bcx, DROP_EXISTING, data.res.val, data_load, unit_ty);
auto data_load = load_scalar_or_boxed(bcx, lhs, unit_ty);
auto cp = copy_ty(bcx, action, lhs, data_load, unit_ty);
bcx = cp.bcx;

// TODO: Any cleanup need to be done here?

ret res(bcx, data.res.val);
ret res(bcx, lhs);
}

fn init_local(@block_ctxt cx, @ast.local local) -> result {
Expand All @@ -4869,9 +4878,16 @@ fn init_local(@block_ctxt cx, @ast.local local) -> result {
vec(clean(bind drop_slot(_, llptr, ty)));

alt (local.init) {
case (some[@ast.expr](?e)) {
auto sub = trans_expr(bcx, e);
bcx = copy_ty(sub.bcx, INIT, llptr, sub.val, ty).bcx;
case (some[ast.initializer](?init)) {
alt (init.op) {
case (ast.init_assign) {
auto sub = trans_expr(bcx, init.expr);
bcx = copy_ty(sub.bcx, INIT, llptr, sub.val, ty).bcx;
}
case (ast.init_recv) {
bcx = recv_val(bcx, llptr, init.expr, ty, INIT).bcx;
}
}
}
case (_) {
if (middle.ty.type_has_dynamic_size(ty)) {
Expand Down
22 changes: 16 additions & 6 deletions src/comp/middle/typeck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2404,17 +2404,27 @@ fn check_decl_local(&@fn_ctxt fcx, &@ast.decl decl) -> @ast.decl {
}
}

auto init = local.init;
auto initopt = local.init;
alt (local.init) {
case (some[@ast.expr](?expr)) {
auto expr_0 = check_expr(fcx, expr);
case (some[ast.initializer](?init)) {
auto expr_0 = check_expr(fcx, init.expr);
auto lty = plain_ty(ty.ty_local(local.id));
auto expr_1 = demand_expr(fcx, lty, expr_0);
init = some[@ast.expr](expr_1);
auto expr_1;
alt (init.op) {
case (ast.init_assign) {
expr_1 = demand_expr(fcx, lty, expr_0);
}
case (ast.init_recv) {
auto port_ty = plain_ty(ty.ty_port(lty));
expr_1 = demand_expr(fcx, port_ty, expr_0);
}
}
auto init_0 = rec(expr = expr_1 with init);
initopt = some[ast.initializer](init_0);
}
case (_) { /* fall through */ }
}
auto local_1 = @rec(init = init with *local);
auto local_1 = @rec(init = initopt with *local);
ret @rec(node=ast.decl_local(local_1)
with *decl);
}
Expand Down
38 changes: 35 additions & 3 deletions src/comp/pretty/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ impure fn print_type(ps s, &@ast.ty ty) {
case (ast.ty_str) {wrd(s, "str");}
case (ast.ty_box(?mt)) {wrd(s, "@"); print_mt(s, mt);}
case (ast.ty_vec(?mt)) {wrd(s, "vec["); print_mt(s, mt); wrd(s, "]");}
case (ast.ty_port(?t)) {wrd(s, "port["); print_type(s, t); wrd(s, "]");}
case (ast.ty_chan(?t)) {wrd(s, "chan["); print_type(s, t); wrd(s, "]");}
case (ast.ty_type) {wrd(s, "type");}
case (ast.ty_tup(?elts)) {
wrd(s, "tup");
Expand Down Expand Up @@ -481,6 +483,18 @@ impure fn print_expr(ps s, &@ast.expr expr) {
wrd1(s, "=");
print_expr(s, rhs);
}
case (ast.expr_send(?lhs, ?rhs, _)) {
print_expr(s, lhs);
space(s);
wrd1(s, "<|");
print_expr(s, rhs);
}
case (ast.expr_recv(?lhs, ?rhs, _)) {
print_expr(s, lhs);
space(s);
wrd1(s, "<-");
print_expr(s, rhs);
}
case (ast.expr_field(?expr,?id,_)) {
print_expr(s, expr);
wrd(s, ".");
Expand Down Expand Up @@ -541,6 +555,17 @@ impure fn print_expr(ps s, &@ast.expr expr) {
}
// TODO: extension 'body'
}
case (ast.expr_port(_)) {
wrd(s, "port");
popen(s);
pclose(s);
}
case (ast.expr_chan(?expr, _)) {
wrd(s, "chan");
popen(s);
print_expr(s, expr);
pclose(s);
}
}
end(s);
}
Expand All @@ -561,10 +586,17 @@ impure fn print_decl(ps s, @ast.decl decl) {
}
wrd(s, loc.ident);
alt (loc.init) {
case (option.some[@ast.expr](?init)) {
case (option.some[ast.initializer](?init)) {
space(s);
wrd1(s, "=");
print_expr(s, init);
alt (init.op) {
case (ast.init_assign) {
wrd1(s, "=");
}
case (ast.init_recv) {
wrd1(s, "<-");
}
}
print_expr(s, init.expr);
}
case (_) {}
}
Expand Down
14 changes: 14 additions & 0 deletions src/test/run-pass/decl-with-recv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// -*- rust -*-

impure fn main() {
let port[int] po = port();
let chan[int] ch = chan(po);

ch <| 10;
let int i <- po;
check (i == 10);

ch <| 11;
auto j <- po;
check (j == 11);
}