Expand expr_rec to take its optional trailing 'with' parameter.

This commit is contained in:
Graydon Hoare 2011-02-14 15:52:38 -08:00
parent 6393a34e6e
commit 59bce06a96
6 changed files with 69 additions and 24 deletions

View file

@ -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);

View file

@ -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; }

View file

@ -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](_,_,_,_,_,_),

View file

@ -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

View file

@ -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); }

View file

@ -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, _)) {