Skip to content
Closed
6 changes: 6 additions & 0 deletions src/comp/front/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ tag expr_ {
expr_block(block, ann);
expr_assign(@expr /* TODO: @expr|is_lval */, @expr, ann);
expr_assign_op(binop, @expr /* TODO: @expr|is_lval */, @expr, ann);
expr_send(@expr /* TODO: @expr|is_lval */, @expr, ann);
expr_recv(@expr /* TODO: @expr|is_lval */, @expr, ann);
expr_field(@expr, ident, ann);
expr_index(@expr, @expr, ann);
expr_path(path, option.t[def], ann);
Expand All @@ -242,6 +244,8 @@ tag expr_ {
expr_be(@expr);
expr_log(@expr);
expr_check_expr(@expr);
expr_port(ann);
expr_chan(@expr, ann);
}

type lit = spanned[lit_];
Expand Down Expand Up @@ -274,6 +278,8 @@ 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
Expand Down
45 changes: 45 additions & 0 deletions src/comp/front/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,22 @@ impure fn parse_ty(parser p) -> @ast.ty {
t = parse_ty_obj(p, hi);
}

case (token.PORT) {
p.bump();
expect(p, token.LBRACKET);
t = ast.ty_port(parse_ty(p));
hi = p.get_span();
expect(p, token.RBRACKET);
}

case (token.CHAN) {
p.bump();
expect(p, token.LBRACKET);
t = ast.ty_chan(parse_ty(p));
hi = p.get_span();
expect(p, token.RBRACKET);
}

case (token.IDENT(_)) {
t = ast.ty_path(parse_path(p, GREEDY), none[ast.def]);
}
Expand Down Expand Up @@ -799,6 +815,23 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr {
}
}

case (token.PORT) {
p.bump();
expect(p, token.LPAREN);
expect(p, token.RPAREN);
hi = p.get_span();
ex = ast.expr_port(ast.ann_none);
}

case (token.CHAN) {
p.bump();
expect(p, token.LPAREN);
auto e = parse_expr(p);
hi = e.span;
expect(p, token.RPAREN);
ex = ast.expr_chan(e, ast.ann_none);
}

case (_) {
auto lit = parse_lit(p);
hi = lit.span;
Expand Down Expand Up @@ -1080,6 +1113,18 @@ impure fn parse_assign_expr(parser p) -> @ast.expr {
ret @spanned(lo, rhs.span,
ast.expr_assign_op(aop, lhs, rhs, ast.ann_none));
}
case (token.SEND) {
p.bump();
auto rhs = parse_expr(p);
ret @spanned(lo, rhs.span,
ast.expr_send(lhs, rhs, ast.ann_none));
}
case (token.LARROW) {
p.bump();
auto rhs = parse_expr(p);
ret @spanned(lo, rhs.span,
ast.expr_recv(lhs, rhs, ast.ann_none));
}
case (_) { /* fall through */ }
}
ret lhs;
Expand Down
75 changes: 75 additions & 0 deletions src/comp/middle/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ type ast_fold[ENV] =
&option.t[def] d) -> @ty) fold_ty_path,

(fn(&ENV e, &span sp, @ty t) -> @ty) fold_ty_mutable,
(fn(&ENV e, &span sp, @ty t) -> @ty) fold_ty_chan,
(fn(&ENV e, &span sp, @ty t) -> @ty) fold_ty_port,

// Expr folds.
(fn(&ENV e, &span sp,
Expand Down Expand Up @@ -141,6 +143,12 @@ type ast_fold[ENV] =
@expr lhs, @expr rhs,
ann a) -> @expr) fold_expr_assign_op,

(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,

(fn(&ENV e, &span sp,
@expr e, ident i,
ann a) -> @expr) fold_expr_field,
Expand Down Expand Up @@ -177,6 +185,13 @@ 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,


// Decl folds.
(fn(&ENV e, &span sp,
@ast.local local) -> @decl) fold_decl_local,
Expand Down Expand Up @@ -386,6 +401,16 @@ fn fold_ty[ENV](&ENV env, ast_fold[ENV] fld, @ty t) -> @ty {
case (ast.ty_fn(?proto, ?inputs, ?output)) {
ret fold_ty_fn(env_, fld, t.span, proto, inputs, output);
}

case (ast.ty_chan(?ty)) {
auto ty_ = fold_ty(env, fld, ty);
ret fld.fold_ty_chan(env_, t.span, ty_);
}

case (ast.ty_port(?ty)) {
auto ty_ = fold_ty(env, fld, ty);
ret fld.fold_ty_port(env_, t.span, ty_);
}
}
}

Expand Down Expand Up @@ -640,6 +665,18 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
ret fld.fold_expr_assign_op(env_, e.span, op, llhs, rrhs, 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);
}

case (ast.expr_field(?e, ?i, ?t)) {
auto ee = fold_expr(env_, fld, e);
ret fld.fold_expr_field(env_, e.span, ee, i, t);
Expand Down Expand Up @@ -705,6 +742,14 @@ 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);
}
}

fail;
Expand Down Expand Up @@ -1083,6 +1128,13 @@ fn identity_fold_ty_mutable[ENV](&ENV env, &span sp, @ty t) -> @ty {
ret @respan(sp, ast.ty_mutable(t));
}

fn identity_fold_ty_chan[ENV](&ENV env, &span sp, @ty t) -> @ty {
ret @respan(sp, ast.ty_chan(t));
}

fn identity_fold_ty_port[ENV](&ENV env, &span sp, @ty t) -> @ty {
ret @respan(sp, ast.ty_port(t));
}

// Expr identities.

Expand Down Expand Up @@ -1186,6 +1238,16 @@ fn identity_fold_expr_assign_op[ENV](&ENV env, &span sp, ast.binop op,
ret @respan(sp, ast.expr_assign_op(op, lhs, rhs, 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));
}

fn identity_fold_expr_field[ENV](&ENV env, &span sp,
@expr e, ident i, ann a) -> @expr {
ret @respan(sp, ast.expr_field(e, i, a));
Expand Down Expand Up @@ -1236,6 +1298,13 @@ 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));
}

// Decl identities.

Expand Down Expand Up @@ -1473,6 +1542,8 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
fold_ty_fn = bind identity_fold_ty_fn[ENV](_,_,_,_,_),
fold_ty_path = bind identity_fold_ty_path[ENV](_,_,_,_),
fold_ty_mutable = bind identity_fold_ty_mutable[ENV](_,_,_),
fold_ty_chan = bind identity_fold_ty_chan[ENV](_,_,_),
fold_ty_port = bind identity_fold_ty_port[ENV](_,_,_),

fold_expr_vec = bind identity_fold_expr_vec[ENV](_,_,_,_),
fold_expr_tup = bind identity_fold_expr_tup[ENV](_,_,_,_),
Expand All @@ -1495,6 +1566,8 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
fold_expr_assign = bind identity_fold_expr_assign[ENV](_,_,_,_,_),
fold_expr_assign_op
= bind identity_fold_expr_assign_op[ENV](_,_,_,_,_,_),
fold_expr_send = bind identity_fold_expr_send[ENV](_,_,_,_,_),
fold_expr_recv = bind identity_fold_expr_recv[ENV](_,_,_,_,_),
fold_expr_field = bind identity_fold_expr_field[ENV](_,_,_,_,_),
fold_expr_index = bind identity_fold_expr_index[ENV](_,_,_,_,_),
fold_expr_path = bind identity_fold_expr_path[ENV](_,_,_,_,_),
Expand All @@ -1506,6 +1579,8 @@ 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_decl_local = bind identity_fold_decl_local[ENV](_,_,_),
fold_decl_item = bind identity_fold_decl_item[ENV](_,_,_),
Expand Down
78 changes: 67 additions & 11 deletions src/comp/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -146,17 +148,19 @@ fn ty_to_str(&@t typ) -> str {
}

alt (typ.struct) {
case (ty_native) { s = "native"; }
case (ty_nil) { s = "()"; }
case (ty_bool) { s = "bool"; }
case (ty_int) { s = "int"; }
case (ty_uint) { s = "uint"; }
case (ty_machine(?tm)) { s = common.ty_mach_to_str(tm); }
case (ty_char) { s = "char"; }
case (ty_str) { s = "str"; }
case (ty_box(?t)) { s = "@" + ty_to_str(t); }
case (ty_vec(?t)) { s = "vec[" + ty_to_str(t) + "]"; }
case (ty_type) { s = "type"; }
case (ty_native) { s = "native"; }
case (ty_nil) { s = "()"; }
case (ty_bool) { s = "bool"; }
case (ty_int) { s = "int"; }
case (ty_uint) { s = "uint"; }
case (ty_machine(?tm)) { s = common.ty_mach_to_str(tm); }
case (ty_char) { s = "char"; }
case (ty_str) { s = "str"; }
case (ty_box(?t)) { s = "@" + ty_to_str(t); }
case (ty_vec(?t)) { s = "vec[" + ty_to_str(t) + "]"; }
case (ty_port(?t)) { s = "port[" + ty_to_str(t) + "]"; }
case (ty_chan(?t)) { s = "chan[" + ty_to_str(t) + "]"; }
case (ty_type) { s = "type"; }

case (ty_tup(?elems)) {
auto f = ty_to_str;
Expand Down Expand Up @@ -240,6 +244,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) {
Expand Down Expand Up @@ -1159,6 +1169,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)) {
Expand Down
Loading