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

Add expr_spawn, spawn parsing, folding, typechecking, ty_task #296

Closed
wants to merge 1 commit 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
6 changes: 6 additions & 0 deletions src/comp/front/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,13 +219,19 @@ type arm = rec(@pat pat, block block, hashmap[ident,def_id] index);
type elt = rec(mutability mut, @expr expr);
type field = rec(mutability mut, ident ident, @expr expr);

tag spawn_dom {
dom_implicit;
dom_thread;
}

type expr = spanned[expr_];
tag expr_ {
expr_vec(vec[@expr], mutability, ann);
expr_tup(vec[elt], ann);
expr_rec(vec[field], option.t[@expr], ann);
expr_call(@expr, vec[@expr], ann);
expr_bind(@expr, vec[option.t[@expr]], ann);
expr_spawn(spawn_dom, option.t[str], @expr, vec[@expr], ann);
expr_binary(binop, @expr, @expr, ann);
expr_unary(unop, @expr, ann);
expr_lit(@lit, ann);
Expand Down
24 changes: 24 additions & 0 deletions src/comp/front/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,27 @@ impure fn parse_alt_expr(parser p) -> @ast.expr {
ret @spanned(lo, hi, expr);
}

impure fn parse_spawn_expr(parser p) -> @ast.expr {
auto lo = p.get_span();
expect(p, token.SPAWN);

// FIXME: Parse domain and name

auto fn_expr = parse_bottom_expr(p);
auto pf = parse_expr;
auto es = parse_seq[@ast.expr](token.LPAREN,
token.RPAREN,
some(token.COMMA),
pf, p);
auto hi = es.span;
auto spawn_expr = ast.expr_spawn(ast.dom_implicit,
option.none[str],
fn_expr,
es.node,
ast.ann_none);
ret @spanned(lo, hi, spawn_expr);
}

impure fn parse_expr(parser p) -> @ast.expr {
ret parse_expr_res(p, UNRESTRICTED);
}
Expand Down Expand Up @@ -1367,6 +1388,9 @@ impure fn parse_expr_inner(parser p) -> @ast.expr {
case (token.ALT) {
ret parse_alt_expr(p);
}
case (token.SPAWN) {
ret parse_spawn_expr(p);
}
case (_) {
ret parse_assign_expr(p);
}
Expand Down
18 changes: 18 additions & 0 deletions src/comp/middle/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ type ast_fold[ENV] =
@expr f, vec[option.t[@expr]] args,
ann a) -> @expr) fold_expr_bind,

(fn(&ENV e, &span sp,
ast.spawn_dom dom, option.t[str] name,
@expr f, vec[@expr] args,
ann a) -> @expr) fold_expr_spawn,

(fn(&ENV e, &span sp,
ast.binop,
@expr lhs, @expr rhs,
Expand Down Expand Up @@ -573,6 +578,12 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
ret fld.fold_expr_bind(env_, e.span, ff, aargs_opt, t);
}

case (ast.expr_spawn(?dom, ?name, ?f, ?args, ?t)) {
auto ff = fold_expr(env_, fld, f);
auto aargs = fold_exprs(env_, fld, args);
ret fld.fold_expr_spawn(env_, e.span, dom, name, ff, aargs, t);
}

case (ast.expr_binary(?op, ?a, ?b, ?t)) {
auto aa = fold_expr(env_, fld, a);
auto bb = fold_expr(env_, fld, b);
Expand Down Expand Up @@ -1168,6 +1179,12 @@ fn identity_fold_expr_bind[ENV](&ENV env, &span sp, @expr f,
ret @respan(sp, ast.expr_bind(f, args_opt, a));
}

fn identity_fold_expr_spawn[ENV](&ENV env, &span sp,
ast.spawn_dom dom, option.t[str] name,
@expr f, vec[@expr] args, ann a) -> @expr {
ret @respan(sp, ast.expr_spawn(dom, name, f, args, a));
}

fn identity_fold_expr_binary[ENV](&ENV env, &span sp, ast.binop b,
@expr lhs, @expr rhs,
ann a) -> @expr {
Expand Down Expand Up @@ -1562,6 +1579,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
fold_expr_rec = bind identity_fold_expr_rec[ENV](_,_,_,_,_),
fold_expr_call = bind identity_fold_expr_call[ENV](_,_,_,_,_),
fold_expr_bind = bind identity_fold_expr_bind[ENV](_,_,_,_,_),
fold_expr_spawn = bind identity_fold_expr_spawn[ENV](_,_,_,_,_,_,_),
fold_expr_binary = bind identity_fold_expr_binary[ENV](_,_,_,_,_,_),
fold_expr_unary = bind identity_fold_expr_unary[ENV](_,_,_,_,_),
fold_expr_lit = bind identity_fold_expr_lit[ENV](_,_,_,_),
Expand Down
3 changes: 3 additions & 0 deletions src/comp/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ tag sty {
ty_vec(mt);
ty_port(@t);
ty_chan(@t);
ty_task;
ty_tup(vec[mt]);
ty_rec(vec[field]);
ty_fn(ast.proto, vec[arg], @t); // TODO: effect
Expand Down Expand Up @@ -756,6 +757,8 @@ fn expr_ty(@ast.expr expr) -> @t {
case (ast.expr_rec(_, _, ?ann)) { ret ann_to_type(ann); }
case (ast.expr_bind(_, _, ?ann)) { ret ann_to_type(ann); }
case (ast.expr_call(_, _, ?ann)) { ret ann_to_type(ann); }
case (ast.expr_spawn(_, _, _, _, ?ann))
{ ret ann_to_type(ann); }
case (ast.expr_binary(_, _, _, ?ann)) { ret ann_to_type(ann); }
case (ast.expr_unary(_, _, ?ann)) { ret ann_to_type(ann); }
case (ast.expr_lit(_, ?ann)) { ret ann_to_type(ann); }
Expand Down
72 changes: 56 additions & 16 deletions src/comp/middle/typeck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1750,6 +1750,27 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
ret tup(lhs_1, rhs_1, ann);
}

// A generic function for checking call expressions
fn check_call(&@fn_ctxt fcx, @ast.expr f, vec[@ast.expr] args)
-> tup(@ast.expr, vec[@ast.expr]) {

let vec[option.t[@ast.expr]] args_opt_0 = vec();
for (@ast.expr arg in args) {
args_opt_0 += vec(some[@ast.expr](arg));
}

// Call the generic checker.
auto result = check_call_or_bind(fcx, f, args_opt_0);

// Pull out the arguments.
let vec[@ast.expr] args_1 = vec();
for (option.t[@ast.expr] arg in result._1) {
args_1 += vec(option.get[@ast.expr](arg));
}

ret tup(result._0, args_1);
}

alt (expr.node) {
case (ast.expr_lit(?lit, _)) {
auto typ = check_lit(lit);
Expand Down Expand Up @@ -2154,23 +2175,13 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
}

case (ast.expr_call(?f, ?args, _)) {
let vec[option.t[@ast.expr]] args_opt_0 = vec();
for (@ast.expr arg in args) {
args_opt_0 += vec(some[@ast.expr](arg));
}

// Call the generic checker.
auto result = check_call_or_bind(fcx, f, args_opt_0);

// Pull out the arguments.
let vec[@ast.expr] args_1 = vec();
for (option.t[@ast.expr] arg in result._1) {
args_1 += vec(option.get[@ast.expr](arg));
}
auto result = check_call(fcx, f, args);
auto f_1 = result._0;
auto args_1 = result._1;

// Pull the return type out of the type of the function.
auto rt_1 = plain_ty(ty.ty_nil); // FIXME: typestate botch
alt (expr_ty(result._0).struct) {
alt (expr_ty(f_1).struct) {
case (ty.ty_fn(_,_,?rt)) { rt_1 = rt; }
case (ty.ty_native_fn(_, _, ?rt)) { rt_1 = rt; }
case (_) {
Expand All @@ -2181,8 +2192,37 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {

auto ann = ast.ann_type(rt_1, none[vec[@ty.t]]);
ret @fold.respan[ast.expr_](expr.span,
ast.expr_call(result._0, args_1,
ann));
ast.expr_call(f_1, args_1, ann));
}

case (ast.expr_spawn(?dom, ?name, ?f, ?args, _)) {
auto result = check_call(fcx, f, args);
auto f_1 = result._0;
auto args_1 = result._1;

// Check the return type
alt (expr_ty(f_1).struct) {
case (ty.ty_fn(_,_,?rt)) {
alt (rt.struct) {
case (ty.ty_nil) {
// This is acceptable
}
case (_) {
auto err = "non-nil return type in "
+ "spawned function";
fcx.ccx.sess.span_err(expr.span, err);
fail;
}
}
}
}

// FIXME: Other typechecks needed

auto ann = ast.ann_type(plain_ty(ty.ty_task), none[vec[@ty.t]]);
ret @fold.respan[ast.expr_](expr.span,
ast.expr_spawn(dom, name,
f_1, args_1, ann));
}

case (ast.expr_cast(?e, ?t, _)) {
Expand Down