aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Walton <[email protected]>2010-10-13 12:43:35 -0700
committerPatrick Walton <[email protected]>2010-10-14 15:20:27 -0700
commit699ef987d78db9d74a2f4e3e5849355998d7b407 (patch)
tree9b85b1b6172cbe5ababfaf3f58d62bd2c973063b
parentTypecheck tags in "alt" patterns (diff)
downloadrust-699ef987d78db9d74a2f4e3e5849355998d7b407.tar.xz
rust-699ef987d78db9d74a2f4e3e5849355998d7b407.zip
rustc: Start work on lvals
-rw-r--r--src/comp/front/ast.rs12
-rw-r--r--src/comp/front/parser.rs52
-rw-r--r--src/comp/middle/fold.rs132
3 files changed, 137 insertions, 59 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index aa4ed1e7..5af9fa8b 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -89,12 +89,18 @@ tag expr_ {
expr_binary(binop, @expr, @expr);
expr_unary(unop, @expr);
expr_lit(@lit);
- expr_name(name, option[referent]);
- expr_field(@expr, ident);
- expr_index(@expr, @expr);
expr_cast(@expr, @ty);
expr_if(@expr, block, option[block]);
expr_block(block);
+ expr_assign(@lval, @expr);
+ expr_lval(@lval);
+}
+
+type lval = spanned[lval_];
+tag lval_ {
+ lval_field(@expr, ident);
+ lval_index(@expr, @expr);
+ lval_name(name, option[referent]);
}
type lit = spanned[lit_];
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index d731bf70..d6968a5b 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -238,6 +238,25 @@ io fn parse_possibly_mutable_expr(parser p) -> tup(bool, @ast.expr) {
ret tup(mut, parse_expr(p));
}
+io fn parse_lval(parser p) -> option[@ast.lval] {
+ auto lo = p.get_span();
+
+ alt (p.peek()) {
+ case (token.IDENT(?i)) {
+ auto n = parse_name(p, i);
+ auto hi = n.span;
+ auto lval = ast.lval_name(n, none[ast.referent]);
+ ret some(@spanned(lo, hi, lval));
+ }
+
+ case (_) {
+ ret none[@ast.lval];
+ }
+ }
+
+ fail;
+}
+
io fn parse_bottom_expr(parser p) -> @ast.expr {
auto lo = p.get_span();
@@ -297,21 +316,22 @@ io fn parse_bottom_expr(parser p) -> @ast.expr {
ex = ast.expr_rec(es.node);
}
- case (token.IDENT(?i)) {
- auto n = parse_name(p, i);
- hi = n.span;
- ex = ast.expr_name(n, none[ast.referent]);
- }
-
case (_) {
- alt (parse_lit(p)) {
- case (some[ast.lit](?lit)) {
- hi = lit.span;
- ex = ast.expr_lit(@lit);
+ alt (parse_lval(p)) {
+ case (some[@ast.lval](?lval)) {
+ hi = lval.span;
+ ex = ast.expr_lval(lval);
}
- case (none[ast.lit]) {
- p.err("expecting expression");
- fail;
+ case (none[@ast.lval]) {
+ alt (parse_lit(p)) {
+ case (some[ast.lit](?lit)) {
+ hi = lit.span;
+ ex = ast.expr_lit(@lit);
+ }
+ case (none[ast.lit]) {
+ p.err("expecting expression");
+ }
+ }
}
}
}
@@ -332,13 +352,15 @@ io fn parse_path_expr(parser p) -> @ast.expr {
case (token.IDENT(?i)) {
hi = p.get_span();
p.bump();
- e = @spanned(lo, hi, ast.expr_field(e, i));
+ auto lv = @spanned(lo, hi, ast.lval_field(e, i));
+ e = @spanned(lo, hi, ast.expr_lval(lv));
}
case (token.LPAREN) {
auto ix = parse_bottom_expr(p);
hi = ix.span;
- e = @spanned(lo, hi, ast.expr_index(e, ix));
+ auto lv = @spanned(lo, hi, ast.lval_index(e, ix));
+ e = @spanned(lo, hi, ast.expr_lval(lv));
}
}
}
diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs
index 5445d3c1..a43eb1ac 100644
--- a/src/comp/middle/fold.rs
+++ b/src/comp/middle/fold.rs
@@ -13,6 +13,7 @@ import front.ast.ident;
import front.ast.name;
import front.ast.ty;
import front.ast.expr;
+import front.ast.lval;
import front.ast.stmt;
import front.ast.block;
import front.ast.item;
@@ -66,22 +67,28 @@ type ast_fold[ENV] =
@ast.lit) -> @expr) fold_expr_lit,
(fn(&ENV e, &span sp,
- &name n,
- &option[referent] r) -> @expr) fold_expr_name,
+ @expr cond, block thn,
+ &option[block] els) -> @expr) fold_expr_if,
(fn(&ENV e, &span sp,
- @expr e, ident i) -> @expr) fold_expr_field,
+ block blk) -> @expr) fold_expr_block,
(fn(&ENV e, &span sp,
- @expr e, @expr ix) -> @expr) fold_expr_index,
+ @lval lhs, @expr rhs) -> @expr) fold_expr_assign,
(fn(&ENV e, &span sp,
- @expr cond, block thn,
- &option[block] els) -> @expr) fold_expr_if,
+ @lval lv) -> @expr) fold_expr_lval,
+ // Lvalue folds.
(fn(&ENV e, &span sp,
- block blk) -> @expr) fold_expr_block,
+ @expr e, ident i) -> @lval) fold_lval_field,
+ (fn(&ENV e, &span sp,
+ @expr e, @expr ix) -> @lval) fold_lval_index,
+
+ (fn(&ENV e, &span sp,
+ &name n,
+ &option[referent] r) -> @lval) fold_lval_name,
// Decl folds.
(fn(&ENV e, &span sp,
@@ -131,6 +138,7 @@ type ast_fold[ENV] =
(fn(&ENV e, @ast.crate c) -> ENV) update_env_for_crate,
(fn(&ENV e, @item i) -> ENV) update_env_for_item,
(fn(&ENV e, @stmt s) -> ENV) update_env_for_stmt,
+ (fn(&ENV e, @lval l) -> ENV) update_env_for_lval,
(fn(&ENV e, @expr x) -> ENV) update_env_for_expr,
(fn(&ENV e, @ty t) -> ENV) update_env_for_ty,
@@ -156,6 +164,33 @@ fn fold_decl[ENV](&ENV env, ast_fold[ENV] fld, @decl d) -> @decl {
ret d;
}
+fn fold_lval[ENV](&ENV env, ast_fold[ENV] fld, @lval lv) -> @lval {
+ let ENV env_ = fld.update_env_for_lval(env, lv);
+
+ if (!fld.keep_going(env_)) {
+ ret lv;
+ }
+
+ alt (lv.node) {
+ case (ast.lval_field(?e, ?i)) {
+ auto ee = fold_expr(env_, fld, e);
+ ret fld.fold_lval_field(env_, lv.span, ee, i);
+ }
+
+ case (ast.lval_index(?e, ?ix)) {
+ auto ee = fold_expr(env_, fld, e);
+ auto iix = fold_expr(env_, fld, ix);
+ ret fld.fold_lval_index(env_, lv.span, ee, iix);
+ }
+
+ case (ast.lval_name(?n, ?r)) {
+ ret fld.fold_lval_name(env_, lv.span, n, r);
+ }
+ }
+
+ fail; // shoudn't be reached
+}
+
fn fold_exprs[ENV](&ENV env, ast_fold[ENV] fld, vec[@expr] e) -> vec[@expr] {
let operator[@expr, @expr] fe = bind fold_expr[ENV](env, fld, _);
ret _vec.map[@expr, @expr](fe, e);
@@ -220,22 +255,6 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
ret fld.fold_expr_lit(env_, e.span, lit);
}
- case (ast.expr_name(?n, ?r)) {
- auto nn = fold_expr_name(env_, fld, n, r);
- ret fld.fold_expr_name(env_, e.span, nn._0, nn._1);
- }
-
- case (ast.expr_field(?e, ?i)) {
- auto ee = fold_expr(env_, fld, e);
- ret fld.fold_expr_field(env_, e.span, ee, i);
- }
-
- case (ast.expr_index(?e, ?i)) {
- auto ee = fold_expr(env_, fld, e);
- auto ii = fold_expr(env_, fld, i);
- ret fld.fold_expr_index(env_, e.span, ee, ii);
- }
-
case (ast.expr_if(?cnd, ?thn, ?els)) {
auto ccnd = fold_expr(env_, fld, cnd);
auto tthn = fold_block(env_, fld, thn);
@@ -252,6 +271,17 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
auto bb = fold_block(env_, fld, b);
ret fld.fold_expr_block(env_, e.span, bb);
}
+
+ case (ast.expr_assign(?lhs, ?rhs)) {
+ auto llhs = fold_lval(env_, fld, lhs);
+ auto rrhs = fold_expr(env_, fld, rhs);
+ ret fld.fold_expr_assign(env_, e.span, llhs, rrhs);
+ }
+
+ case (ast.expr_lval(?lv)) {
+ auto llv = fold_lval(env_, fld, lv);
+ ret fld.fold_expr_lval(env_, e.span, llv);
+ }
}
ret e;
@@ -462,21 +492,6 @@ fn identity_fold_expr_lit[ENV](&ENV env, &span sp, @ast.lit lit) -> @expr {
ret @respan(sp, ast.expr_lit(lit));
}
-fn identity_fold_expr_name[ENV](&ENV env, &span sp, &name n,
- &option[referent] r) -> @expr {
- ret @respan(sp, ast.expr_name(n, r));
-}
-
-fn identity_fold_expr_field[ENV](&ENV env, &span sp,
- @expr e, ident i) -> @expr {
- ret @respan(sp, ast.expr_field(e, i));
-}
-
-fn identity_fold_expr_index[ENV](&ENV env, &span sp,
- @expr e, @expr ix) -> @expr {
- ret @respan(sp, ast.expr_index(e, ix));
-}
-
fn identity_fold_expr_if[ENV](&ENV env, &span sp,
@expr cond, block thn,
&option[block] els) -> @expr {
@@ -487,6 +502,33 @@ fn identity_fold_expr_block[ENV](&ENV env, &span sp, block blk) -> @expr {
ret @respan(sp, ast.expr_block(blk));
}
+fn identity_fold_expr_assign[ENV](&ENV env, &span sp,
+ @lval lhs, @expr rhs) -> @expr {
+ ret @respan(sp, ast.expr_assign(lhs, rhs));
+}
+
+fn identity_fold_expr_lval[ENV](&ENV env, &span sp, @lval lv) -> @expr {
+ ret @respan(sp, ast.expr_lval(lv));
+}
+
+
+// Lvalue identities.
+
+fn identity_fold_lval_field[ENV](&ENV env, &span sp,
+ @expr e, ident i) -> @lval {
+ ret @respan(sp, ast.lval_field(e, i));
+}
+
+fn identity_fold_lval_index[ENV](&ENV env, &span sp,
+ @expr e, @expr ix) -> @lval {
+ ret @respan(sp, ast.lval_index(e, ix));
+}
+
+fn identity_fold_lval_name[ENV](&ENV env, &span sp,
+ &name n, &option[referent] r) -> @lval {
+ ret @respan(sp, ast.lval_name(n, r));
+}
+
// Decl identities.
@@ -575,6 +617,10 @@ fn identity_update_env_for_stmt[ENV](&ENV e, @stmt s) -> ENV {
ret e;
}
+fn identity_update_env_for_lval[ENV](&ENV e, @lval l) -> ENV {
+ ret e;
+}
+
fn identity_update_env_for_expr[ENV](&ENV e, @expr x) -> ENV {
ret e;
}
@@ -613,11 +659,14 @@ fn new_identity_fold[ENV]() -> ast_fold[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](_,_,_),
- fold_expr_name = bind identity_fold_expr_name[ENV](_,_,_,_),
- fold_expr_field = bind identity_fold_expr_field[ENV](_,_,_,_),
- fold_expr_index = bind identity_fold_expr_index[ENV](_,_,_,_),
fold_expr_if = bind identity_fold_expr_if[ENV](_,_,_,_,_),
fold_expr_block = bind identity_fold_expr_block[ENV](_,_,_),
+ fold_expr_assign = bind identity_fold_expr_assign[ENV](_,_,_,_),
+ fold_expr_lval = bind identity_fold_expr_lval[ENV](_,_,_),
+
+ fold_lval_field = bind identity_fold_lval_field[ENV](_,_,_,_),
+ fold_lval_index = bind identity_fold_lval_index[ENV](_,_,_,_),
+ fold_lval_name = bind identity_fold_lval_name[ENV](_,_,_,_),
fold_decl_local = bind identity_fold_decl_local[ENV](_,_,_,_,_),
fold_decl_item = bind identity_fold_decl_item[ENV](_,_,_,_),
@@ -639,6 +688,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
update_env_for_crate = bind identity_update_env_for_crate[ENV](_,_),
update_env_for_item = bind identity_update_env_for_item[ENV](_,_),
update_env_for_stmt = bind identity_update_env_for_stmt[ENV](_,_),
+ update_env_for_lval = bind identity_update_env_for_lval[ENV](_,_),
update_env_for_expr = bind identity_update_env_for_expr[ENV](_,_),
update_env_for_ty = bind identity_update_env_for_ty[ENV](_,_),