aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2011-02-14 15:52:38 -0800
committerGraydon Hoare <[email protected]>2011-02-14 15:52:38 -0800
commit59bce06a967b3806c3d874b8956857f0f01287e1 (patch)
tree4f81bc5cf6e0fa94ba9c08000e98264904a3dc53 /src
parentTeach typeck about generic tags. (diff)
downloadrust-59bce06a967b3806c3d874b8956857f0f01287e1.tar.xz
rust-59bce06a967b3806c3d874b8956857f0f01287e1.zip
Expand expr_rec to take its optional trailing 'with' parameter.
Diffstat (limited to 'src')
-rw-r--r--src/comp/front/ast.rs2
-rw-r--r--src/comp/front/parser.rs41
-rw-r--r--src/comp/middle/fold.rs21
-rw-r--r--src/comp/middle/trans.rs9
-rw-r--r--src/comp/middle/ty.rs2
-rw-r--r--src/comp/middle/typeck.rs18
6 files changed, 69 insertions, 24 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index 6aac7b50..3aec3226 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -146,7 +146,7 @@ type expr = spanned[expr_];
tag expr_ {
expr_vec(vec[@expr], ann);
expr_tup(vec[elt], ann);
- expr_rec(vec[field], ann);
+ expr_rec(vec[field], option.t[@expr], ann);
expr_call(@expr, vec[@expr], ann);
expr_bind(@expr, vec[option.t[@expr]], ann);
expr_binary(binop, @expr, @expr, ann);
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index 87bbe57f..2f037dfb 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -529,14 +529,37 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr {
case (token.REC) {
p.bump();
- auto pf = parse_field;
- auto fs =
- parse_seq[ast.field](token.LPAREN,
- token.RPAREN,
- some(token.COMMA),
- pf, p);
- hi = fs.span;
- ex = ast.expr_rec(fs.node, ast.ann_none);
+ expect(p, token.LPAREN);
+ auto fields = vec(parse_field(p));
+
+ auto more = true;
+ auto base = none[@ast.expr];
+ while (more) {
+ alt (p.peek()) {
+ case (token.RPAREN) {
+ hi = p.get_span();
+ p.bump();
+ more = false;
+ }
+ case (token.WITH) {
+ p.bump();
+ base = some[@ast.expr](parse_expr(p));
+ hi = p.get_span();
+ expect(p, token.RPAREN);
+ more = false;
+ }
+ case (token.COMMA) {
+ p.bump();
+ fields += parse_field(p);
+ }
+ case (?t) {
+ unexpected(p, t);
+ }
+ }
+
+ }
+
+ ex = ast.expr_rec(fields, base, ast.ann_none);
}
case (token.BIND) {
@@ -1370,7 +1393,7 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool {
alt (e.node) {
case (ast.expr_vec(_,_)) { ret true; }
case (ast.expr_tup(_,_)) { ret true; }
- case (ast.expr_rec(_,_)) { ret true; }
+ case (ast.expr_rec(_,_,_)) { ret true; }
case (ast.expr_call(_,_,_)) { ret true; }
case (ast.expr_binary(_,_,_,_)) { ret true; }
case (ast.expr_unary(_,_,_)) { ret true; }
diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs
index 5930ba75..4ba65a7b 100644
--- a/src/comp/middle/fold.rs
+++ b/src/comp/middle/fold.rs
@@ -75,7 +75,8 @@ type ast_fold[ENV] =
vec[ast.elt] es, ann a) -> @expr) fold_expr_tup,
(fn(&ENV e, &span sp,
- vec[ast.field] fields, ann a) -> @expr) fold_expr_rec,
+ vec[ast.field] fields,
+ option.t[@expr] base, ann a) -> @expr) fold_expr_rec,
(fn(&ENV e, &span sp,
@expr f, vec[@expr] args,
@@ -479,12 +480,19 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
ret fld.fold_expr_tup(env_, e.span, elts, t);
}
- case (ast.expr_rec(?fs, ?t)) {
+ case (ast.expr_rec(?fs, ?base, ?t)) {
let vec[ast.field] fields = vec();
+ let option.t[@expr] b = none[@expr];
for (ast.field f in fs) {
fields += fold_rec_field(env, fld, f);
}
- ret fld.fold_expr_rec(env_, e.span, fields, t);
+ alt (base) {
+ case (none[@ast.expr]) { }
+ case (some[@ast.expr](?eb)) {
+ b = some[@expr](fold_expr(env_, fld, eb));
+ }
+ }
+ ret fld.fold_expr_rec(env_, e.span, fields, b, t);
}
case (ast.expr_call(?f, ?args, ?t)) {
@@ -1011,8 +1019,9 @@ fn identity_fold_expr_tup[ENV](&ENV env, &span sp,
}
fn identity_fold_expr_rec[ENV](&ENV env, &span sp,
- vec[ast.field] fields, ann a) -> @expr {
- ret @respan(sp, ast.expr_rec(fields, a));
+ vec[ast.field] fields,
+ option.t[@expr] base, ann a) -> @expr {
+ ret @respan(sp, ast.expr_rec(fields, base, a));
}
fn identity_fold_expr_call[ENV](&ENV env, &span sp, @expr f,
@@ -1358,7 +1367,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
fold_expr_vec = bind identity_fold_expr_vec[ENV](_,_,_,_),
fold_expr_tup = bind identity_fold_expr_tup[ENV](_,_,_,_),
- fold_expr_rec = bind identity_fold_expr_rec[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_binary = bind identity_fold_expr_binary[ENV](_,_,_,_,_,_),
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index c1a4aa6f..972683e9 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -2984,7 +2984,10 @@ fn trans_vec(@block_ctxt cx, vec[@ast.expr] args,
}
fn trans_rec(@block_ctxt cx, vec[ast.field] fields,
- &ast.ann ann) -> result {
+ option.t[@ast.expr] base, &ast.ann ann) -> result {
+
+ // FIXME: handle presence of a nonempty base.
+ check (base == none[@ast.expr]);
auto bcx = cx;
auto t = node_ann_type(bcx.fcx.ccx, ann);
@@ -3099,8 +3102,8 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
ret trans_tup(cx, args, ann);
}
- case (ast.expr_rec(?args, ?ann)) {
- ret trans_rec(cx, args, ann);
+ case (ast.expr_rec(?args, ?base, ?ann)) {
+ ret trans_rec(cx, args, base, ann);
}
// lval cases fall through to trans_lval and then
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index b9753474..2083ef2b 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -667,7 +667,7 @@ fn expr_ty(@ast.expr expr) -> @t {
alt (expr.node) {
case (ast.expr_vec(_, ?ann)) { ret ann_to_type(ann); }
case (ast.expr_tup(_, ?ann)) { ret ann_to_type(ann); }
- case (ast.expr_rec(_, ?ann)) { ret ann_to_type(ann); }
+ 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_binary(_, _, _, ?ann)) { ret ann_to_type(ann); }
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index 748dd879..19e4a9b2 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -910,7 +910,12 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
}
e_1 = ast.expr_tup(elts_1, ast.ann_type(t));
}
- case (ast.expr_rec(?fields_0, ?ann)) {
+ case (ast.expr_rec(?fields_0, ?base_0, ?ann)) {
+
+ // FIXME: handle presence of a nonempty base.
+ check (base_0 == none[@ast.expr]);
+ auto base_1 = base_0;
+
auto t = demand(fcx, e.span, expected, ann_to_type(ann));
let vec[ast.field] fields_1 = vec();
alt (t.struct) {
@@ -931,7 +936,7 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
fail;
}
}
- e_1 = ast.expr_rec(fields_1, ast.ann_type(t));
+ e_1 = ast.expr_rec(fields_1, base_1, ast.ann_type(t));
}
case (ast.expr_bind(?sube, ?es, ?ann)) {
auto t = demand(fcx, e.span, expected, ann_to_type(ann));
@@ -1610,7 +1615,12 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
ast.expr_tup(elts_1, ann));
}
- case (ast.expr_rec(?fields, _)) {
+ case (ast.expr_rec(?fields, ?base, _)) {
+
+ // FIXME: handle presence of a nonempty base.
+ check (base == none[@ast.expr]);
+ auto base_1 = base;
+
let vec[ast.field] fields_1 = vec();
let vec[field] fields_t = vec();
@@ -1626,7 +1636,7 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
auto ann = ast.ann_type(plain_ty(ty.ty_rec(fields_t)));
ret @fold.respan[ast.expr_](expr.span,
- ast.expr_rec(fields_1, ann));
+ ast.expr_rec(fields_1, base_1, ann));
}
case (ast.expr_field(?base, ?field, _)) {