diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index edc9c4a25c0..d768f93552a 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -278,12 +278,12 @@ tag ty_ { ty_str; ty_box(@ty); ty_vec(@ty); + ty_port(@ty); + ty_chan(@ty); ty_tup(vec[@ty]); ty_rec(vec[ty_field]); ty_fn(proto, vec[ty_arg], @ty); // TODO: effect ty_obj(vec[ty_method]); - ty_chan(@ty); - ty_port(@ty); ty_path(path, option.t[def]); ty_mutable(@ty); ty_type; diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs index bb2af12194e..320033cdc8c 100644 --- a/src/comp/middle/fold.rs +++ b/src/comp/middle/fold.rs @@ -179,6 +179,18 @@ type ast_fold[ENV] = (fn(&ENV e, &span sp, @expr e) -> @expr) fold_expr_check_expr, + (fn(&ENV e, &span sp, + ann a) -> @expr) fold_expr_port, + + (fn(&ENV e, &span sp, + @expr e, ann a) -> @expr) fold_expr_chan, + + (fn(&ENV e, &span sp, + @expr lhs, @expr rhs, ann a) -> @expr) fold_expr_send, + + (fn(&ENV e, &span sp, + @expr lhs, @expr rhs, ann a) -> @expr) fold_expr_recv, + // Decl folds. (fn(&ENV e, &span sp, @ast.local local) -> @decl) fold_decl_local, @@ -717,6 +729,26 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr { ret fld.fold_expr_check_expr(env_, e.span, ee); } + case (ast.expr_port(?t)) { + ret fld.fold_expr_port(env_, e.span, t); + } + + case (ast.expr_chan(?x, ?t)) { + auto ee = fold_expr(env_, fld, x); + ret fld.fold_expr_chan(env_, e.span, ee, t); + } + + case (ast.expr_send(?lhs, ?rhs, ?t)) { + auto llhs = fold_expr(env_, fld, lhs); + auto rrhs = fold_expr(env_, fld, rhs); + ret fld.fold_expr_send(env_, e.span, llhs, rrhs, t); + } + + case (ast.expr_recv(?lhs, ?rhs, ?t)) { + auto llhs = fold_expr(env_, fld, lhs); + auto rrhs = fold_expr(env_, fld, rhs); + ret fld.fold_expr_recv(env_, e.span, llhs, rrhs, t); + } } fail; @@ -1255,6 +1287,23 @@ fn identity_fold_expr_check_expr[ENV](&ENV e, &span sp, @expr x) -> @expr { ret @respan(sp, ast.expr_check_expr(x)); } +fn identity_fold_expr_port[ENV](&ENV e, &span sp, ann a) -> @expr { + ret @respan(sp, ast.expr_port(a)); +} + +fn identity_fold_expr_chan[ENV](&ENV e, &span sp, @expr x, ann a) -> @expr { + ret @respan(sp, ast.expr_chan(x, a)); +} + +fn identity_fold_expr_send[ENV](&ENV e, &span sp, + @expr lhs, @expr rhs, ann a) -> @expr { + ret @respan(sp, ast.expr_send(lhs, rhs, a)); +} + +fn identity_fold_expr_recv[ENV](&ENV e, &span sp, + @expr lhs, @expr rhs, ann a) -> @expr { + ret @respan(sp, ast.expr_recv(lhs, rhs, a)); +} // Decl identities. @@ -1527,6 +1576,10 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] { fold_expr_log = bind identity_fold_expr_log[ENV](_,_,_), fold_expr_check_expr = bind identity_fold_expr_check_expr[ENV](_,_,_), + fold_expr_port = bind identity_fold_expr_port[ENV](_,_,_), + fold_expr_chan = bind identity_fold_expr_chan[ENV](_,_,_,_), + fold_expr_send = bind identity_fold_expr_send[ENV](_,_,_,_,_), + fold_expr_recv = bind identity_fold_expr_recv[ENV](_,_,_,_,_), fold_decl_local = bind identity_fold_decl_local[ENV](_,_,_), fold_decl_item = bind identity_fold_decl_item[ENV](_,_,_), diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index bd3e3263820..73b519ba3dd 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -38,6 +38,8 @@ tag sty { ty_tag(ast.def_id, vec[@t]); ty_box(@t); ty_vec(@t); + ty_port(@t); + ty_chan(@t); ty_tup(vec[@t]); ty_rec(vec[field]); ty_fn(ast.proto, vec[arg], @t); // TODO: effect @@ -240,6 +242,12 @@ fn fold_ty(ty_fold fld, @t ty) -> @t { case (ty_vec(?subty)) { ret rewrap(ty, ty_vec(fold_ty(fld, subty))); } + case (ty_port(?subty)) { + ret rewrap(ty, ty_port(fold_ty(fld, subty))); + } + case (ty_chan(?subty)) { + ret rewrap(ty, ty_chan(fold_ty(fld, subty))); + } case (ty_tag(?tid, ?subtys)) { let vec[@t] new_subtys = vec(); for (@t subty in subtys) { @@ -1159,6 +1167,52 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler) } } + case (ty.ty_port(?expected_sub)) { + alt (actual.struct) { + case (ty.ty_port(?actual_sub)) { + auto result = unify_step(bindings, + expected_sub, + actual_sub, + handler); + alt (result) { + case (ures_ok(?result_sub)) { + ret ures_ok(plain_ty(ty.ty_port(result_sub))); + } + case (_) { + ret result; + } + } + } + + case (_) { + ret ures_err(terr_mismatch, expected, actual); + } + } + } + + case (ty.ty_chan(?expected_sub)) { + alt (actual.struct) { + case (ty.ty_chan(?actual_sub)) { + auto result = unify_step(bindings, + expected_sub, + actual_sub, + handler); + alt (result) { + case (ures_ok(?result_sub)) { + ret ures_ok(plain_ty(ty.ty_chan(result_sub))); + } + case (_) { + ret result; + } + } + } + + case (_) { + ret ures_err(terr_mismatch, expected, actual); + } + } + } + case (ty.ty_tup(?expected_elems)) { alt (actual.struct) { case (ty.ty_tup(?actual_elems)) { diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 7dfe918c065..78524c2d4b2 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -308,6 +308,15 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t { case (ast.ty_str) { sty = ty.ty_str; } case (ast.ty_box(?t)) { sty = ty.ty_box(ast_ty_to_ty(getter, t)); } case (ast.ty_vec(?t)) { sty = ty.ty_vec(ast_ty_to_ty(getter, t)); } + + case (ast.ty_port(?t)) { + sty = ty.ty_port(ast_ty_to_ty(getter, t)); + } + + case (ast.ty_chan(?t)) { + sty = ty.ty_chan(ast_ty_to_ty(getter, t)); + } + case (ast.ty_tup(?fields)) { let vec[@ty.t] flds = vec(); for (@ast.ty field in fields) { @@ -1387,6 +1396,28 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e, case (ast.expr_put(_)) { e_1 = e.node; } case (ast.expr_be(_)) { e_1 = e.node; } case (ast.expr_check_expr(_)) { e_1 = e.node; } + + case (ast.expr_port(?ann)) { + auto t = demand(fcx, e.span, expected, ann_to_type(ann)); + e_1 = ast.expr_port(ast.ann_type(t, none[vec[@ty.t]])); + } + + case (ast.expr_chan(?es, ?ann)) { + auto t = demand(fcx, e.span, expected, ann_to_type(ann)); + let @ast.expr es_1; + alt (t.struct) { + case (ty.ty_chan(?subty)) { + auto pt = plain_ty(ty.ty_port(subty)); + es_1 = demand_expr(fcx, pt, es); + } + case (_) { + log "chan expr doesn't have a chan type!"; + fail; + } + } + e_1 = ast.expr_chan(es_1, ast.ann_type(t, none[vec[@ty.t]])); + } + case (_) { fcx.ccx.sess.unimpl("type unification for expression variant"); fail; @@ -2257,6 +2288,31 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr { } } + case (ast.expr_port(_)) { + auto t = next_ty_var(fcx.ccx); + auto pt = plain_ty(ty.ty_port(t)); + auto ann = ast.ann_type(pt, none[vec[@ty.t]]); + ret @fold.respan[ast.expr_](expr.span, ast.expr_port(ann)); + } + + case (ast.expr_chan(?x, _)) { + auto expr_1 = check_expr(fcx, x); + auto port_t = expr_ty(expr_1); + alt (port_t.struct) { + case (ty.ty_port(?subtype)) { + auto ct = plain_ty(ty.ty_chan(subtype)); + auto ann = ast.ann_type(ct, none[vec[@ty.t]]); + ret @fold.respan[ast.expr_](expr.span, + ast.expr_chan(expr_1, ann)); + } + case (_) { + fcx.ccx.sess.span_err(expr.span, + "bad port type: " + + ty_to_str(port_t)); + } + } + } + case (_) { fcx.ccx.sess.unimpl("expr type in typeck.check_expr"); // TODO