about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBrian Anderson <andersrb@gmail.com>2011-03-26 00:53:57 -0400
committerGraydon Hoare <graydon@mozilla.com>2011-03-28 21:13:53 -0700
commit2b27d12ce1b3babf4adea41d669140019cb80b8a (patch)
treec8e113ccede4de3475be1639de445a761b755ae4 /src
parentdb5c809c83815701bb4e629ee52a6de0d480cdd2 (diff)
downloadrust-2b27d12ce1b3babf4adea41d669140019cb80b8a.tar.gz
rust-2b27d12ce1b3babf4adea41d669140019cb80b8a.zip
Add expr_spawn, spawn parsing, folding, typechecking, ty_task
Diffstat (limited to 'src')
-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 c4c1a56b6ef..8458a749d20 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 4a9f37f09e2..06e22ea8818 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 76715a28a9b..3756f9876e8 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 e22ebceab35..f9822d97e55 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 2fd89401c0e..cdb61cbd385 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, _)) {