Skip to content

Parsing and type checking of ports and channels #272

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

Closed
wants to merge 11 commits into from
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