Add expr_spawn, spawn parsing, folding, typechecking, ty_task

This commit is contained in:
Brian Anderson 2011-03-26 00:53:57 -04:00 committed by Graydon Hoare
parent db5c809c83
commit 2b27d12ce1
5 changed files with 107 additions and 16 deletions

View file

@ -219,6 +219,11 @@ 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);
@ -226,6 +231,7 @@ tag expr_ {
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);

View file

@ -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);
}
@ -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);
}

View file

@ -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,
@ -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);
@ -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 {
@ -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](_,_,_,_),

View file

@ -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
@ -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); }

View file

@ -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);
@ -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 (_) {
@ -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, _)) {