2011-05-17 13:41:41 -05:00
|
|
|
import std::vec;
|
|
|
|
import std::vec::plus_option;
|
2011-05-14 21:02:30 -05:00
|
|
|
|
|
|
|
import front::ast;
|
|
|
|
import front::ast::crate;
|
|
|
|
import front::ast::ann;
|
|
|
|
import front::ast::arg;
|
|
|
|
import front::ast::method;
|
|
|
|
import front::ast::local;
|
|
|
|
import front::ast::item;
|
|
|
|
import front::ast::item_fn;
|
|
|
|
import front::ast::item_obj;
|
|
|
|
import front::ast::_obj;
|
|
|
|
import front::ast::obj_def_ids;
|
|
|
|
import front::ast::_fn;
|
|
|
|
import front::ast::ty_param;
|
|
|
|
import front::ast::_mod;
|
|
|
|
import front::ast::decl;
|
|
|
|
import front::ast::decl_local;
|
|
|
|
import front::ast::def_id;
|
|
|
|
import front::ast::ident;
|
2011-05-16 19:49:46 -05:00
|
|
|
|
|
|
|
import middle::walk::walk_crate;
|
|
|
|
import middle::walk::walk_fn;
|
|
|
|
import middle::walk::ast_visitor;
|
2011-05-14 21:02:30 -05:00
|
|
|
|
|
|
|
import aux::fn_info;
|
|
|
|
import aux::var_info;
|
|
|
|
import aux::crate_ctxt;
|
|
|
|
|
|
|
|
import util::common::new_def_hash;
|
2011-05-18 17:43:05 -05:00
|
|
|
import util::common::uistr;
|
2011-05-31 20:24:06 -05:00
|
|
|
import util::common::span;
|
2011-05-14 21:02:30 -05:00
|
|
|
|
2011-05-26 18:02:25 -05:00
|
|
|
type identifier = rec(ident name, def_id id, span sp);
|
|
|
|
|
2011-05-14 21:02:30 -05:00
|
|
|
fn var_is_local(def_id v, fn_info m) -> bool {
|
|
|
|
ret (m.vars.contains_key(v));
|
|
|
|
}
|
|
|
|
|
2011-05-26 18:02:25 -05:00
|
|
|
fn collect_local(&@vec[identifier] vars, &@decl d) -> () {
|
2011-05-18 17:43:05 -05:00
|
|
|
alt (d.node) {
|
|
|
|
case (decl_local(?loc)) {
|
|
|
|
log("collect_local: pushing " + loc.ident);
|
2011-05-26 18:02:25 -05:00
|
|
|
vec::push[identifier](*vars, rec(name=loc.ident,
|
|
|
|
id=loc.id,
|
|
|
|
sp=d.span));
|
2011-05-18 17:43:05 -05:00
|
|
|
}
|
|
|
|
case (_) { ret; }
|
|
|
|
}
|
2011-05-14 21:02:30 -05:00
|
|
|
}
|
|
|
|
|
2011-05-26 18:02:25 -05:00
|
|
|
fn find_locals(&_fn f, &span sp, &ident i, &def_id d, &ann a)
|
|
|
|
-> @vec[identifier] {
|
|
|
|
auto res = @vec::alloc[identifier](0u);
|
2011-05-16 19:49:46 -05:00
|
|
|
auto visitor = walk::default_visitor();
|
|
|
|
visitor = rec(visit_decl_pre=bind collect_local(res,_) with visitor);
|
2011-05-26 18:02:25 -05:00
|
|
|
walk_fn(visitor, f, sp, i, d, a);
|
2011-05-14 21:02:30 -05:00
|
|
|
ret res;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-05-26 18:02:25 -05:00
|
|
|
fn add_var(def_id v, span sp, ident nm, uint next, fn_info tbl) -> uint {
|
2011-05-14 21:02:30 -05:00
|
|
|
log(nm + " |-> " + util::common::uistr(next));
|
2011-05-26 18:02:25 -05:00
|
|
|
tbl.vars.insert(v, rec(bit_num=next, name=nm, sp=sp));
|
2011-05-14 21:02:30 -05:00
|
|
|
ret (next + 1u);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* builds a table mapping each local var defined in f
|
|
|
|
to a bit number in the precondition/postcondition vectors */
|
2011-05-26 18:02:25 -05:00
|
|
|
fn mk_fn_info(&crate_ctxt ccx, &_fn f, &span f_sp,
|
|
|
|
&ident f_name, &def_id f_id, &ann a)
|
2011-05-18 20:01:53 -05:00
|
|
|
-> () {
|
2011-05-14 21:02:30 -05:00
|
|
|
auto res = rec(vars=@new_def_hash[var_info](),
|
|
|
|
cf=f.decl.cf);
|
|
|
|
let uint next = 0u;
|
|
|
|
let vec[arg] f_args = f.decl.inputs;
|
|
|
|
|
|
|
|
/* ignore args, which we know are initialized;
|
|
|
|
just collect locally declared vars */
|
|
|
|
|
2011-05-26 18:02:25 -05:00
|
|
|
let @vec[identifier] locals = find_locals(f, f_sp, f_name, f_id, a);
|
|
|
|
for (identifier p in *locals) {
|
|
|
|
next = add_var(p.id, p.sp, p.name, next, res);
|
2011-05-14 21:02:30 -05:00
|
|
|
}
|
|
|
|
/* add a pseudo-entry for the function's return value
|
|
|
|
we can safely use the function's name itself for this purpose */
|
2011-05-26 18:02:25 -05:00
|
|
|
add_var(f_id, f_sp, f_name, next, res);
|
2011-05-14 21:02:30 -05:00
|
|
|
|
2011-05-26 18:02:25 -05:00
|
|
|
log(f_name + " has " + uistr(vec::len[identifier](*locals))
|
2011-05-18 17:43:05 -05:00
|
|
|
+ " locals");
|
|
|
|
|
2011-05-18 19:07:49 -05:00
|
|
|
ccx.fm.insert(f_id, res);
|
2011-05-14 21:02:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/* initializes the global fn_info_map (mapping each function ID, including
|
|
|
|
nested locally defined functions, onto a mapping from local variable name
|
|
|
|
to bit number) */
|
|
|
|
fn mk_f_to_fn_info(&crate_ctxt ccx, @crate c) -> () {
|
2011-05-16 19:49:46 -05:00
|
|
|
let ast_visitor vars_visitor = walk::default_visitor();
|
2011-05-26 18:02:25 -05:00
|
|
|
vars_visitor = rec(visit_fn_pre=bind mk_fn_info(ccx,_,_,_,_,_)
|
2011-05-18 17:43:05 -05:00
|
|
|
with vars_visitor);
|
2011-05-14 21:02:30 -05:00
|
|
|
|
2011-05-16 19:49:46 -05:00
|
|
|
walk_crate(vars_visitor, *c);
|
2011-05-14 21:02:30 -05:00
|
|
|
}
|
2011-05-16 19:49:46 -05:00
|
|
|
|
|
|
|
//
|
|
|
|
// Local Variables:
|
|
|
|
// mode: rust
|
|
|
|
// fill-column: 78;
|
|
|
|
// indent-tabs-mode: nil
|
|
|
|
// c-basic-offset: 4
|
|
|
|
// buffer-file-coding-system: utf-8-unix
|
|
|
|
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
|
|
|
// End:
|
|
|
|
//
|
|
|
|
|