diff options
| author | Patrick Walton <[email protected]> | 2010-11-24 15:45:59 -0800 |
|---|---|---|
| committer | Patrick Walton <[email protected]> | 2010-11-24 15:45:59 -0800 |
| commit | f075b10af2c2a1088d72fff0bff1918a8e74fbf0 (patch) | |
| tree | 6e65a8ce0c606bcd132aa9e6f7a7efd20dc94bd2 /src | |
| parent | rustc: Parse simple patterns (diff) | |
| download | rust-f075b10af2c2a1088d72fff0bff1918a8e74fbf0.tar.xz rust-f075b10af2c2a1088d72fff0bff1918a8e74fbf0.zip | |
rustc: Add patterns to fold
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp/front/ast.rs | 10 | ||||
| -rw-r--r-- | src/comp/front/parser.rs | 14 | ||||
| -rw-r--r-- | src/comp/middle/fold.rs | 83 |
3 files changed, 98 insertions, 9 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index 954440dd..cc0f2961 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -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); diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 16c6ed11..a3cc00a0 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -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)); diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs index f32eddae..eea114ac 100644 --- a/src/comp/middle/fold.rs +++ b/src/comp/middle/fold.rs @@ -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; @@ -95,6 +97,10 @@ type ast_fold[ENV] = 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, (fn(&ENV e, &span sp, @@ -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](_,_), |