From 966ce9ee12f02762c6c5695a32add9c840f30437 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 26 Mar 2011 00:53:57 -0400 Subject: [PATCH] Add expr_spawn, spawn parsing, folding, typechecking, ty_task --- src/comp/front/ast.rs | 6 ++++ src/comp/front/parser.rs | 24 +++++++++++++ src/comp/middle/fold.rs | 18 ++++++++++ src/comp/middle/ty.rs | 3 ++ src/comp/middle/typeck.rs | 72 ++++++++++++++++++++++++++++++--------- 5 files changed, 107 insertions(+), 16 deletions(-) diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index c4c1a56b6ef78..8458a749d2062 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -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); diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 4a9f37f09e209..06e22ea881873 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -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); } diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs index 76715a28a9b7b..3756f9876e804 100644 --- a/src/comp/middle/fold.rs +++ b/src/comp/middle/fold.rs @@ -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](_,_,_,_), diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index e22ebceab35af..f9822d97e55b3 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -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); } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 2fd89401c0e04..cdb61cbd3856a 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -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, _)) {