aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
authorBrian Anderson <[email protected]>2011-03-26 00:53:57 -0400
committerGraydon Hoare <[email protected]>2011-03-28 21:13:53 -0700
commit2b27d12ce1b3babf4adea41d669140019cb80b8a (patch)
treec8e113ccede4de3475be1639de445a761b755ae4 /src/comp
parentAdd 'self' keyword. (diff)
downloadrust-2b27d12ce1b3babf4adea41d669140019cb80b8a.tar.xz
rust-2b27d12ce1b3babf4adea41d669140019cb80b8a.zip
Add expr_spawn, spawn parsing, folding, typechecking, ty_task
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/front/ast.rs6
-rw-r--r--src/comp/front/parser.rs24
-rw-r--r--src/comp/middle/fold.rs18
-rw-r--r--src/comp/middle/ty.rs3
-rw-r--r--src/comp/middle/typeck.rs72
5 files changed, 107 insertions, 16 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index c4c1a56b..8458a749 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 4a9f37f0..06e22ea8 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 76715a28..3756f987 100644
--- a/src/comp/middle/fold.rs
+++ b/src/comp/middle/fold.rs
@@ -91,6 +91,11 @@ type ast_fold[ENV] =
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,
ann a) -> @expr) fold_expr_binary,
@@ -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 e22ebcea..f9822d97 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 2fd89401..cdb61cbd 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, _)) {