diff options
| author | Tim Chevalier <[email protected]> | 2011-03-24 12:12:04 -0700 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2011-04-01 11:27:32 -0700 |
| commit | 3130348ee177f1716488b6caca6c7852fe47754c (patch) | |
| tree | ee090db0203277e2adf4686fe26bbc3d3f024fbb /src/comp/front | |
| parent | rustc: Remove useless call to tag_variant_with_id() (diff) | |
| download | rust-3130348ee177f1716488b6caca6c7852fe47754c.tar.xz rust-3130348ee177f1716488b6caca6c7852fe47754c.zip | |
Started adding support for typestate checking.
I added a new field to the ast "ann" type for typestate information.
Currently, the field contains a record of a precondition bit vector and
postcondition vector, but I tried to structure things so as to make
it easy to change the representation of the typestate annotation type.
I also had to add annotations to some syntactic forms that didn't have
them before (fail, ret, be...), with all the boilerplate changes
that that would imply.
The main call to the typestate_check entry point is commented out and
the actual pre-postcondition algorithm only has a few cases
implemented, though the overall AST traversal is there. The rest of
the typestate algorithm isn't implemented yet.
Diffstat (limited to 'src/comp/front')
| -rw-r--r-- | src/comp/front/ast.rs | 21 | ||||
| -rw-r--r-- | src/comp/front/lexer.rs | 2 | ||||
| -rw-r--r-- | src/comp/front/parser.rs | 36 |
3 files changed, 31 insertions, 28 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index 0bd18382..46666a34 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -6,6 +6,7 @@ import util.common.span; import util.common.spanned; import util.common.ty_mach; import util.common.filename; +import util.typestate_ann.ts_ann; type ident = str; @@ -21,7 +22,9 @@ type ty_param = rec(ident ident, def_id id); // Annotations added during successive passes. tag ann { ann_none; - ann_type(@middle.ty.t, option.t[vec[@middle.ty.t]] /* ty param substs */); + ann_type(@middle.ty.t, + option.t[vec[@middle.ty.t]], /* ty param substs */ + option.t[@ts_ann]); /* pre- and postcondition for typestate */ } tag def { @@ -274,14 +277,14 @@ tag expr_ { expr_index(@expr, @expr, ann); expr_path(path, option.t[def], ann); expr_ext(path, vec[@expr], option.t[@expr], @expr, ann); - expr_fail; - expr_break; - expr_cont; - expr_ret(option.t[@expr]); - expr_put(option.t[@expr]); - expr_be(@expr); - expr_log(@expr); - expr_check_expr(@expr); + expr_fail(ann); + expr_break(ann); + expr_cont(ann); + expr_ret(option.t[@expr], ann); + expr_put(option.t[@expr], ann); + expr_be(@expr, ann); + expr_log(@expr, ann); + expr_check_expr(@expr, ann); expr_port(ann); expr_chan(@expr, ann); } diff --git a/src/comp/front/lexer.rs b/src/comp/front/lexer.rs index 6cead0bc..5a9c2b11 100644 --- a/src/comp/front/lexer.rs +++ b/src/comp/front/lexer.rs @@ -419,7 +419,7 @@ impure fn scan_number(mutable char c, reader rdr) -> token.token { if (is_dec_integer) { accum_int = digits_to_string(dec_str); } - + c = rdr.curr(); n = rdr.next(); diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index f7d355a4..4c3e6cf0 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -794,14 +794,14 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr { case (token.FAIL) { p.bump(); - ex = ast.expr_fail; + ex = ast.expr_fail(ast.ann_none); } case (token.LOG) { p.bump(); auto e = parse_expr(p); auto hi = e.span; - ex = ast.expr_log(e); + ex = ast.expr_log(e, ast.ann_none); } case (token.CHECK) { @@ -810,7 +810,7 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr { case (token.LPAREN) { auto e = parse_expr(p); auto hi = e.span; - ex = ast.expr_check_expr(e); + ex = ast.expr_check_expr(e, ast.ann_none); } case (_) { p.get_session().unimpl("constraint-check stmt"); @@ -822,36 +822,36 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr { p.bump(); alt (p.peek()) { case (token.SEMI) { - ex = ast.expr_ret(none[@ast.expr]); + ex = ast.expr_ret(none[@ast.expr], ast.ann_none); } case (_) { auto e = parse_expr(p); hi = e.span; - ex = ast.expr_ret(some[@ast.expr](e)); + ex = ast.expr_ret(some[@ast.expr](e), ast.ann_none); } } } case (token.BREAK) { p.bump(); - ex = ast.expr_break; + ex = ast.expr_break(ast.ann_none); } case (token.CONT) { p.bump(); - ex = ast.expr_cont; + ex = ast.expr_cont(ast.ann_none); } case (token.PUT) { p.bump(); alt (p.peek()) { case (token.SEMI) { - ex = ast.expr_put(none[@ast.expr]); + ex = ast.expr_put(none[@ast.expr], ast.ann_none); } case (_) { auto e = parse_expr(p); hi = e.span; - ex = ast.expr_put(some[@ast.expr](e)); + ex = ast.expr_put(some[@ast.expr](e), ast.ann_none); } } } @@ -862,7 +862,7 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr { // FIXME: Is this the right place for this check? if /*check*/ (ast.is_call_expr(e)) { hi = e.span; - ex = ast.expr_be(e); + ex = ast.expr_be(e, ast.ann_none); } else { p.err("Non-call expression in tail call"); @@ -1651,14 +1651,14 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool { case (ast.expr_field(_,_,_)) { ret true; } case (ast.expr_index(_,_,_)) { ret true; } case (ast.expr_path(_,_,_)) { ret true; } - case (ast.expr_fail) { ret true; } - case (ast.expr_break) { ret true; } - case (ast.expr_cont) { ret true; } - case (ast.expr_ret(_)) { ret true; } - case (ast.expr_put(_)) { ret true; } - case (ast.expr_be(_)) { ret true; } - case (ast.expr_log(_)) { ret true; } - case (ast.expr_check_expr(_)) { ret true; } + case (ast.expr_fail(_)) { ret true; } + case (ast.expr_break(_)) { ret true; } + case (ast.expr_cont(_)) { ret true; } + case (ast.expr_ret(_,_)) { ret true; } + case (ast.expr_put(_,_)) { ret true; } + case (ast.expr_be(_,_)) { ret true; } + case (ast.expr_log(_,_)) { ret true; } + case (ast.expr_check_expr(_,_)) { ret true; } } } // We should not be calling this on a cdir. |