2010-09-01 15:24:14 -05:00
|
|
|
import std._uint;
|
2010-09-23 19:16:34 -05:00
|
|
|
import std._int;
|
2011-04-07 20:15:56 -05:00
|
|
|
import std._vec;
|
2011-04-12 14:16:21 -05:00
|
|
|
import std.option.none;
|
2010-10-19 16:54:10 -05:00
|
|
|
import front.ast;
|
2011-04-12 14:16:21 -05:00
|
|
|
import util.typestate_ann.ts_ann;
|
2010-09-01 15:24:14 -05:00
|
|
|
|
2011-04-12 14:16:21 -05:00
|
|
|
import std.io.stdout;
|
|
|
|
import std.io.str_writer;
|
|
|
|
import std.io.string_writer;
|
|
|
|
import pretty.pprust.print_block;
|
|
|
|
import pretty.pprust.print_expr;
|
|
|
|
import pretty.pprust.print_decl;
|
|
|
|
import pretty.pp.mkstate;
|
2011-02-23 16:37:39 -06:00
|
|
|
|
|
|
|
type filename = str;
|
2011-04-08 11:44:20 -05:00
|
|
|
type span = rec(uint lo, uint hi);
|
2010-10-05 20:21:44 -05:00
|
|
|
type spanned[T] = rec(T node, span span);
|
2010-08-18 13:34:47 -05:00
|
|
|
|
2010-09-09 17:59:29 -05:00
|
|
|
tag ty_mach {
|
2010-09-21 01:56:43 -05:00
|
|
|
ty_i8;
|
|
|
|
ty_i16;
|
|
|
|
ty_i32;
|
|
|
|
ty_i64;
|
|
|
|
|
|
|
|
ty_u8;
|
|
|
|
ty_u16;
|
|
|
|
ty_u32;
|
|
|
|
ty_u64;
|
|
|
|
|
|
|
|
ty_f32;
|
|
|
|
ty_f64;
|
2010-09-09 17:59:29 -05:00
|
|
|
}
|
2010-08-18 13:34:47 -05:00
|
|
|
|
2010-08-20 13:41:34 -05:00
|
|
|
fn ty_mach_to_str(ty_mach tm) -> str {
|
|
|
|
alt (tm) {
|
2010-09-21 01:56:43 -05:00
|
|
|
case (ty_u8) { ret "u8"; }
|
|
|
|
case (ty_u16) { ret "u16"; }
|
|
|
|
case (ty_u32) { ret "u32"; }
|
|
|
|
case (ty_u64) { ret "u64"; }
|
|
|
|
|
|
|
|
case (ty_i8) { ret "i8"; }
|
|
|
|
case (ty_i16) { ret "i16"; }
|
|
|
|
case (ty_i32) { ret "i32"; }
|
|
|
|
case (ty_i64) { ret "i64"; }
|
|
|
|
|
|
|
|
case (ty_f32) { ret "f32"; }
|
|
|
|
case (ty_f64) { ret "f64"; }
|
2010-08-20 13:41:34 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-21 18:22:32 -05:00
|
|
|
fn new_str_hash[V]() -> std.map.hashmap[str,V] {
|
|
|
|
let std.map.hashfn[str] hasher = std._str.hash;
|
|
|
|
let std.map.eqfn[str] eqer = std._str.eq;
|
|
|
|
ret std.map.mk_hashmap[str,V](hasher, eqer);
|
|
|
|
}
|
|
|
|
|
2011-03-08 13:59:38 -06:00
|
|
|
fn def_eq(&ast.def_id a, &ast.def_id b) -> bool {
|
|
|
|
ret a._0 == b._0 && a._1 == b._1;
|
|
|
|
}
|
|
|
|
|
2011-03-31 13:55:28 -05:00
|
|
|
fn hash_def(&ast.def_id d) -> uint {
|
|
|
|
auto h = 5381u;
|
|
|
|
h = ((h << 5u) + h) ^ (d._0 as uint);
|
|
|
|
h = ((h << 5u) + h) ^ (d._1 as uint);
|
|
|
|
ret h;
|
|
|
|
}
|
2010-10-19 16:54:10 -05:00
|
|
|
|
2011-03-31 13:55:28 -05:00
|
|
|
fn new_def_hash[V]() -> std.map.hashmap[ast.def_id,V] {
|
|
|
|
let std.map.hashfn[ast.def_id] hasher = hash_def;
|
2011-03-08 13:59:38 -06:00
|
|
|
let std.map.eqfn[ast.def_id] eqer = def_eq;
|
2010-10-19 16:54:10 -05:00
|
|
|
ret std.map.mk_hashmap[ast.def_id,V](hasher, eqer);
|
|
|
|
}
|
|
|
|
|
2011-03-25 12:42:57 -05:00
|
|
|
fn new_int_hash[V]() -> std.map.hashmap[int,V] {
|
|
|
|
fn hash_int(&int x) -> uint { ret x as uint; }
|
|
|
|
fn eq_int(&int a, &int b) -> bool { ret a == b; }
|
|
|
|
auto hasher = hash_int;
|
|
|
|
auto eqer = eq_int;
|
|
|
|
ret std.map.mk_hashmap[int,V](hasher, eqer);
|
|
|
|
}
|
|
|
|
|
2011-04-11 18:54:05 -05:00
|
|
|
fn new_uint_hash[V]() -> std.map.hashmap[uint,V] {
|
|
|
|
fn hash_uint(&uint x) -> uint { ret x; }
|
|
|
|
fn eq_uint(&uint a, &uint b) -> bool { ret a == b; }
|
|
|
|
auto hasher = hash_uint;
|
|
|
|
auto eqer = eq_uint;
|
|
|
|
ret std.map.mk_hashmap[uint,V](hasher, eqer);
|
|
|
|
}
|
|
|
|
|
2010-09-23 19:16:34 -05:00
|
|
|
fn istr(int i) -> str {
|
|
|
|
ret _int.to_str(i, 10u);
|
|
|
|
}
|
|
|
|
|
2011-04-07 20:15:56 -05:00
|
|
|
fn uistr(uint i) -> str {
|
|
|
|
ret _uint.to_str(i, 10u);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn elt_expr(&ast.elt e) -> @ast.expr { ret e.expr; }
|
|
|
|
|
|
|
|
fn elt_exprs(vec[ast.elt] elts) -> vec[@ast.expr] {
|
|
|
|
auto f = elt_expr;
|
|
|
|
be _vec.map[ast.elt, @ast.expr](f, elts);
|
|
|
|
}
|
|
|
|
|
2011-04-12 14:16:21 -05:00
|
|
|
fn field_expr(&ast.field f) -> @ast.expr { ret f.expr; }
|
|
|
|
|
|
|
|
fn field_exprs(vec[ast.field] fields) -> vec [@ast.expr] {
|
|
|
|
auto f = field_expr;
|
|
|
|
ret _vec.map[ast.field, @ast.expr](f, fields);
|
|
|
|
}
|
|
|
|
|
2011-04-20 20:52:04 -05:00
|
|
|
fn plain_ann(@middle.ty.type_store tystore) -> ast.ann {
|
|
|
|
ret ast.ann_type(middle.ty.mk_nil(tystore),
|
2011-04-22 14:27:28 -05:00
|
|
|
none[vec[middle.ty.t]], none[@ts_ann]);
|
2011-04-12 14:16:21 -05:00
|
|
|
}
|
|
|
|
|
2011-04-13 17:34:10 -05:00
|
|
|
fn log_expr(&ast.expr e) -> () {
|
2011-04-12 14:16:21 -05:00
|
|
|
let str_writer s = string_writer();
|
|
|
|
auto out_ = mkstate(s.get_writer(), 80u);
|
|
|
|
auto out = @rec(s=out_,
|
|
|
|
comments=none[vec[front.lexer.cmnt]],
|
|
|
|
mutable cur_cmnt=0u);
|
|
|
|
|
2011-04-13 17:34:10 -05:00
|
|
|
print_expr(out, @e);
|
2011-04-12 14:16:21 -05:00
|
|
|
log(s.get_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
fn log_block(&ast.block b) -> () {
|
|
|
|
let str_writer s = string_writer();
|
|
|
|
auto out_ = mkstate(s.get_writer(), 80u);
|
|
|
|
auto out = @rec(s=out_,
|
|
|
|
comments=none[vec[front.lexer.cmnt]],
|
|
|
|
mutable cur_cmnt=0u);
|
|
|
|
|
|
|
|
print_block(out, b);
|
|
|
|
log(s.get_str());
|
|
|
|
}
|
|
|
|
|
Handle nested items correctly in typestate_check
Summary says it all. Actually, only nested objects and functions
are handled, but that's better than before. The fold that I was using
before to traverse a crate wasn't working correctly, because annotations
have to reflect the number of local variables of the nearest enclosing
function (in turn, because annotations are represented as bit vectors).
The fold was traversing the AST in the wrong order, first filling in
the annotations correctly, but then re-traversing them with the bit
vector length for any outer nested functions, and so on.
Remedying this required writing a lot of tedious boilerplate code
because I scrapped the idea of using a fold altogether.
I also made typestate_check handle unary, field, alt, and fail.
Also, some miscellaneous changes:
* added annotations to blocks in typeck
* fix pprust so it can handle spawn
* added more logging functions in util.common
* fixed _vec.or
* added maybe and from_maybe in option
* removed fold_block field from ast_fold, since it was never used
2011-04-18 17:33:10 -05:00
|
|
|
fn log_ann(&ast.ann a) -> () {
|
|
|
|
alt (a) {
|
|
|
|
case (ast.ann_none) {
|
|
|
|
log("ann_none");
|
|
|
|
}
|
|
|
|
case (ast.ann_type(_,_,_)) {
|
|
|
|
log("ann_type");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn log_stmt(ast.stmt st) -> () {
|
|
|
|
let str_writer s = string_writer();
|
|
|
|
auto out_ = mkstate(s.get_writer(), 80u);
|
|
|
|
auto out = @rec(s=out_,
|
|
|
|
comments=none[vec[front.lexer.cmnt]],
|
|
|
|
mutable cur_cmnt=0u);
|
|
|
|
alt (st.node) {
|
|
|
|
case (ast.stmt_decl(?decl,_)) {
|
|
|
|
print_decl(out, decl);
|
|
|
|
}
|
|
|
|
case (ast.stmt_expr(?ex,_)) {
|
|
|
|
print_expr(out, ex);
|
|
|
|
}
|
|
|
|
case (_) { /* do nothing */ }
|
|
|
|
}
|
|
|
|
log(s.get_str());
|
|
|
|
}
|
|
|
|
|
2010-08-18 13:34:47 -05:00
|
|
|
//
|
|
|
|
// Local Variables:
|
|
|
|
// mode: rust
|
|
|
|
// fill-column: 78;
|
|
|
|
// indent-tabs-mode: nil
|
|
|
|
// c-basic-offset: 4
|
|
|
|
// buffer-file-coding-system: utf-8-unix
|
2011-03-25 17:07:27 -05:00
|
|
|
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
2010-08-18 13:34:47 -05:00
|
|
|
// End:
|
|
|
|
//
|