Add expr_spawn, spawn parsing, folding, typechecking, ty_task
This commit is contained in:
parent
db5c809c83
commit
2b27d12ce1
5 changed files with 107 additions and 16 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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](_,_,_,_),
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
|
|
|
|||
|
|
@ -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, _)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue