rustc: Add patterns to fold

This commit is contained in:
Patrick Walton 2010-11-24 15:45:59 -08:00
parent 756880a5f5
commit f075b10af2
3 changed files with 98 additions and 9 deletions

View File

@ -41,13 +41,11 @@ type block_ = rec(vec[@stmt] stmts,
type pat = spanned[pat_];
tag pat_ {
pat_wild;
pat_bind(ident);
pat_tag(ident, vec[@pat]);
pat_wild(ann);
pat_bind(ident, ann);
pat_tag(ident, vec[@pat], ann);
}
type arm = rec(@pat pat, block block);
tag binop {
add;
sub;
@ -100,6 +98,8 @@ tag decl_ {
decl_item(@item);
}
type arm = rec(@pat pat, block block);
type expr = spanned[expr_];
tag expr_ {
expr_vec(vec[@expr], ann);

View File

@ -815,13 +815,19 @@ impure fn parse_initializer(parser p) -> option.t[@ast.expr] {
impure fn parse_pat(parser p) -> @ast.pat {
auto lo = p.get_span();
auto pat = ast.pat_wild; // FIXME: typestate bug
auto pat = ast.pat_wild(ast.ann_none); // FIXME: typestate bug
alt (p.peek()) {
case (token.UNDERSCORE) { p.bump(); pat = ast.pat_wild; }
case (token.UNDERSCORE) {
p.bump();
pat = ast.pat_wild(ast.ann_none);
}
case (token.QUES) {
p.bump();
alt (p.peek()) {
case (token.IDENT(?id)) { p.bump(); pat = ast.pat_bind(id); }
case (token.IDENT(?id)) {
p.bump();
pat = ast.pat_bind(id, ast.ann_none);
}
case (?tok) {
p.err("expected identifier after '?' in pattern but " +
"found " + token.to_str(tok));
@ -842,7 +848,7 @@ impure fn parse_pat(parser p) -> @ast.pat {
case (_) { args = vec(); }
}
pat = ast.pat_tag(id, args);
pat = ast.pat_tag(id, args, ast.ann_none);
}
case (?tok) {
p.err("expected pattern but found " + token.to_str(tok));

View File

@ -19,7 +19,9 @@ import front.ast.stmt;
import front.ast.block;
import front.ast.item;
import front.ast.arg;
import front.ast.pat;
import front.ast.decl;
import front.ast.arm;
import front.ast.def;
import front.ast.def_id;
import front.ast.ann;
@ -94,6 +96,10 @@ type ast_fold[ENV] =
&block body, @expr cond,
ann a) -> @expr) fold_expr_do_while,
(fn(&ENV e, &span sp,
@expr e, vec[arm] arms,
ann a) -> @expr) fold_expr_alt,
(fn(&ENV e, &span sp,
&block blk, ann a) -> @expr) fold_expr_block,
@ -122,6 +128,18 @@ type ast_fold[ENV] =
@item item) -> @decl) fold_decl_item,
// Pat folds.
(fn(&ENV e, &span sp,
ann a) -> @pat) fold_pat_wild,
(fn(&ENV e, &span sp,
ident i, ann a) -> @pat) fold_pat_bind,
(fn(&ENV e, &span sp,
ident i, vec[@pat] args,
ann a) -> @pat) fold_pat_tag,
// Stmt folds.
(fn(&ENV e, &span sp,
@decl decl) -> @stmt) fold_stmt_decl,
@ -170,6 +188,7 @@ type ast_fold[ENV] =
(fn(&ENV e, &block b) -> ENV) update_env_for_block,
(fn(&ENV e, @stmt s) -> ENV) update_env_for_stmt,
(fn(&ENV e, @decl i) -> ENV) update_env_for_decl,
(fn(&ENV e, @pat p) -> ENV) update_env_for_pat,
(fn(&ENV e, @expr x) -> ENV) update_env_for_expr,
(fn(&ENV e, @ty t) -> ENV) update_env_for_ty,
@ -275,6 +294,28 @@ fn fold_decl[ENV](&ENV env, ast_fold[ENV] fld, @decl d) -> @decl {
fail;
}
fn fold_pat[ENV](&ENV env, ast_fold[ENV] fld, @ast.pat p) -> @ast.pat {
let ENV env_ = fld.update_env_for_pat(env, p);
if (!fld.keep_going(env_)) {
ret p;
}
alt (p.node) {
case (ast.pat_wild(?t)) { ret fld.fold_pat_wild(env_, p.span, t); }
case (ast.pat_bind(?id, ?t)) {
ret fld.fold_pat_bind(env_, p.span, id, t);
}
case (ast.pat_tag(?id, ?pats, ?t)) {
let vec[@ast.pat] ppats = vec();
for (@ast.pat pat in pats) {
ppats += vec(fold_pat(env_, fld, pat));
}
ret fld.fold_pat_tag(env_, p.span, id, ppats, t);
}
}
}
fn fold_exprs[ENV](&ENV env, ast_fold[ENV] fld, vec[@expr] es) -> vec[@expr] {
let vec[@expr] exprs = vec();
for (@expr e in es) {
@ -368,6 +409,17 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
ret fld.fold_expr_do_while(env_, e.span, bbody, ccnd, t);
}
case (ast.expr_alt(?expr, ?arms, ?t)) {
auto eexpr = fold_expr(env_, fld, expr);
let vec[ast.arm] aarms = vec();
for (ast.arm arm in arms) {
auto ppat = fold_pat(env_, fld, arm.pat);
auto bblock = fold_block(env_, fld, arm.block);
aarms += vec(rec(pat=ppat, block=bblock));
}
ret fld.fold_expr_alt(env_, e.span, eexpr, aarms, t);
}
case (ast.expr_block(?b, ?t)) {
auto bb = fold_block(env_, fld, b);
ret fld.fold_expr_block(env_, e.span, bb, t);
@ -658,6 +710,11 @@ fn identity_fold_expr_do_while[ENV](&ENV env, &span sp,
ret @respan(sp, ast.expr_do_while(body, cond, a));
}
fn identity_fold_expr_alt[ENV](&ENV env, &span sp,
@expr e, vec[arm] arms, ann a) -> @expr {
ret @respan(sp, ast.expr_alt(e, arms, a));
}
fn identity_fold_expr_block[ENV](&ENV env, &span sp, &block blk,
ann a) -> @expr {
ret @respan(sp, ast.expr_block(blk, a));
@ -698,6 +755,22 @@ fn identity_fold_decl_item[ENV](&ENV e, &span sp, @item i) -> @decl {
}
// Pat identities.
fn identity_fold_pat_wild[ENV](&ENV e, &span sp, ann a) -> @pat {
ret @respan(sp, ast.pat_wild(a));
}
fn identity_fold_pat_bind[ENV](&ENV e, &span sp, ident i, ann a) -> @pat {
ret @respan(sp, ast.pat_bind(i, a));
}
fn identity_fold_pat_tag[ENV](&ENV e, &span sp, ident i, vec[@pat] args,
ann a) -> @pat {
ret @respan(sp, ast.pat_tag(i, args, a));
}
// Stmt identities.
fn identity_fold_stmt_decl[ENV](&ENV env, &span sp, @decl d) -> @stmt {
@ -790,6 +863,10 @@ fn identity_update_env_for_decl[ENV](&ENV e, @decl d) -> ENV {
ret e;
}
fn identity_update_env_for_pat[ENV](&ENV e, @pat p) -> ENV {
ret e;
}
fn identity_update_env_for_expr[ENV](&ENV e, @expr x) -> ENV {
ret e;
}
@ -835,6 +912,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
fold_expr_while = bind identity_fold_expr_while[ENV](_,_,_,_,_),
fold_expr_do_while
= bind identity_fold_expr_do_while[ENV](_,_,_,_,_),
fold_expr_alt = bind identity_fold_expr_alt[ENV](_,_,_,_,_),
fold_expr_block = bind identity_fold_expr_block[ENV](_,_,_,_),
fold_expr_assign = bind identity_fold_expr_assign[ENV](_,_,_,_,_),
fold_expr_field = bind identity_fold_expr_field[ENV](_,_,_,_,_),
@ -844,6 +922,10 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
fold_decl_local = bind identity_fold_decl_local[ENV](_,_,_),
fold_decl_item = bind identity_fold_decl_item[ENV](_,_,_),
fold_pat_wild = bind identity_fold_pat_wild[ENV](_,_,_),
fold_pat_bind = bind identity_fold_pat_bind[ENV](_,_,_,_),
fold_pat_tag = bind identity_fold_pat_tag[ENV](_,_,_,_,_),
fold_stmt_decl = bind identity_fold_stmt_decl[ENV](_,_,_),
fold_stmt_ret = bind identity_fold_stmt_ret[ENV](_,_,_),
fold_stmt_log = bind identity_fold_stmt_log[ENV](_,_,_),
@ -866,6 +948,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
update_env_for_block = bind identity_update_env_for_block[ENV](_,_),
update_env_for_stmt = bind identity_update_env_for_stmt[ENV](_,_),
update_env_for_decl = bind identity_update_env_for_decl[ENV](_,_),
update_env_for_pat = bind identity_update_env_for_pat[ENV](_,_),
update_env_for_expr = bind identity_update_env_for_expr[ENV](_,_),
update_env_for_ty = bind identity_update_env_for_ty[ENV](_,_),