aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2011-02-14 17:58:32 -0800
committerGraydon Hoare <[email protected]>2011-02-14 17:58:32 -0800
commit15a01f5c3691a152793d8933a7be9d16a0fc7030 (patch)
treeef18ede583e4aae92360e5e2dc033f6c9ffc865f /src/comp
parentMove all non-decl/non-expr stmts to exprs. (diff)
downloadrust-15a01f5c3691a152793d8933a7be9d16a0fc7030.tar.xz
rust-15a01f5c3691a152793d8933a7be9d16a0fc7030.zip
Add basic front-end support for expr_put.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/front/ast.rs1
-rw-r--r--src/comp/front/parser.rs15
-rw-r--r--src/comp/middle/fold.rs20
-rw-r--r--src/comp/middle/trans.rs9
-rw-r--r--src/comp/middle/ty.rs1
-rw-r--r--src/comp/middle/typeck.rs22
6 files changed, 68 insertions, 0 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index 53ffdd87..cb2df2a5 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -162,6 +162,7 @@ tag expr_ {
expr_ext(vec[@expr], option.t[@expr], ann);
expr_fail;
expr_ret(option.t[@expr]);
+ expr_put(option.t[@expr]);
expr_be(@expr);
expr_log(@expr);
expr_check_expr(@expr);
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index 5ffaca19..a779d013 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -638,6 +638,20 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr {
}
}
+ case (token.PUT) {
+ p.bump();
+ alt (p.peek()) {
+ case (token.SEMI) {
+ ex = ast.expr_put(none[@ast.expr]);
+ }
+ case (_) {
+ auto e = parse_expr(p);
+ hi = e.span;
+ ex = ast.expr_put(some[@ast.expr](e));
+ }
+ }
+ }
+
case (token.BE) {
p.bump();
auto e = parse_expr(p);
@@ -1420,6 +1434,7 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool {
case (ast.expr_path(_,_,_)) { ret true; }
case (ast.expr_fail) { ret true; }
case (ast.expr_ret(_)) { ret true; }
+ case (ast.expr_put(_)) { ret true; }
case (ast.expr_be(_)) { ret true; }
case (ast.expr_log(_)) { ret true; }
case (ast.expr_check_expr(_)) { ret true; }
diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs
index 4e8ea317..4d3c2e2d 100644
--- a/src/comp/middle/fold.rs
+++ b/src/comp/middle/fold.rs
@@ -155,6 +155,9 @@ type ast_fold[ENV] =
&option.t[@expr] rv) -> @expr) fold_expr_ret,
(fn(&ENV e, &span sp,
+ &option.t[@expr] rv) -> @expr) fold_expr_put,
+
+ (fn(&ENV e, &span sp,
@expr e) -> @expr) fold_expr_be,
(fn(&ENV e, &span sp,
@@ -640,6 +643,17 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
ret fld.fold_expr_ret(env_, e.span, oee);
}
+ case (ast.expr_put(?oe)) {
+ auto oee = none[@expr];
+ alt (oe) {
+ case (some[@expr](?x)) {
+ oee = some(fold_expr(env_, fld, x));
+ }
+ case (_) { /* fall through */ }
+ }
+ ret fld.fold_expr_put(env_, e.span, oee);
+ }
+
case (ast.expr_be(?x)) {
auto ee = fold_expr(env_, fld, x);
ret fld.fold_expr_be(env_, e.span, ee);
@@ -1130,6 +1144,11 @@ fn identity_fold_expr_ret[ENV](&ENV env, &span sp,
ret @respan(sp, ast.expr_ret(rv));
}
+fn identity_fold_expr_put[ENV](&ENV env, &span sp,
+ &option.t[@expr] rv) -> @expr {
+ ret @respan(sp, ast.expr_put(rv));
+}
+
fn identity_fold_expr_be[ENV](&ENV env, &span sp, @expr x) -> @expr {
ret @respan(sp, ast.expr_be(x));
}
@@ -1396,6 +1415,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
fold_expr_path = bind identity_fold_expr_path[ENV](_,_,_,_,_),
fold_expr_fail = bind identity_fold_expr_fail[ENV](_,_),
fold_expr_ret = bind identity_fold_expr_ret[ENV](_,_,_),
+ fold_expr_put = bind identity_fold_expr_put[ENV](_,_,_),
fold_expr_be = bind identity_fold_expr_be[ENV](_,_,_),
fold_expr_log = bind identity_fold_expr_log[ENV](_,_,_),
fold_expr_check_expr
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index e140ddcc..c8f21dff 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -3122,6 +3122,10 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
ret trans_ret(cx, e);
}
+ case (ast.expr_ret(?e)) {
+ ret trans_put(cx, e);
+ }
+
case (ast.expr_be(?e)) {
ret trans_be(cx, e);
}
@@ -3199,6 +3203,11 @@ fn trans_fail(@block_ctxt cx, common.span sp, str fail_str) -> result {
ret trans_upcall(cx, "upcall_fail", args);
}
+fn trans_put(@block_ctxt cx, &option.t[@ast.expr] e) -> result {
+ cx.fcx.ccx.sess.unimpl("put expr");
+ fail;
+}
+
fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result {
auto bcx = cx;
auto val = C_nil();
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index 58529d0d..f9b2bd9d 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -691,6 +691,7 @@ fn expr_ty(@ast.expr expr) -> @t {
case (ast.expr_log(_)) { ret plain_ty(ty_nil); }
case (ast.expr_check_expr(_)) { ret plain_ty(ty_nil); }
case (ast.expr_ret(_)) { ret plain_ty(ty_nil); }
+ case (ast.expr_put(_)) { ret plain_ty(ty_nil); }
case (ast.expr_be(_)) { ret plain_ty(ty_nil); }
}
fail;
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index d0043c43..5109adb2 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -1040,6 +1040,7 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
case (ast.expr_fail) { e_1 = e.node; }
case (ast.expr_log(_)) { e_1 = e.node; }
case (ast.expr_ret(_)) { e_1 = e.node; }
+ case (ast.expr_put(_)) { e_1 = e.node; }
case (ast.expr_be(_)) { e_1 = e.node; }
case (ast.expr_check_expr(_)) { e_1 = e.node; }
}
@@ -1317,6 +1318,27 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
}
}
+ case (ast.expr_put(?expr_opt)) {
+ alt (expr_opt) {
+ case (none[@ast.expr]) {
+ auto nil = plain_ty(ty.ty_nil);
+ if (!are_compatible(fcx, fcx.ret_ty, nil)) {
+ fcx.ccx.sess.err("put; in function "
+ + "putting non-nil");
+ }
+
+ ret expr;
+ }
+
+ case (some[@ast.expr](?e)) {
+ auto expr_0 = check_expr(fcx, e);
+ auto expr_1 = demand_expr(fcx, fcx.ret_ty, expr_0);
+ ret @fold.respan[ast.expr_](expr.span,
+ ast.expr_put(some(expr_1)));
+ }
+ }
+ }
+
case (ast.expr_be(?e)) {
/* FIXME: prove instead of check */
check ast.is_call_expr(e);