1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#![allow(non_camel_case_types)]
use syntax::ast;
use syntax::visit;
use syntax::visit::Visitor;
use time;
pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
local_data_key!(depth: uint);
if !do_it { return f(u); }
let old = depth.get().map(|d| *d).unwrap_or(0);
depth.replace(Some(old + 1));
let start = time::precise_time_s();
let rv = f(u);
let end = time::precise_time_s();
println!("{}time: {:3.3f} s\t{}", " ".repeat(old), end - start, what);
depth.replace(Some(old));
rv
}
pub fn indent<R>(op: || -> R) -> R {debug!(">>");
let r = op();
debug!("<< (Result = {:?})", r);
r
}
pub struct Indenter {
_cannot_construct_outside_of_this_module: ()
}
impl Drop for Indenter {
fn drop(&mut self) { debug!("<<"); }
}
pub fn indenter() -> Indenter {
debug!(">>");
Indenter { _cannot_construct_outside_of_this_module: () }
}
struct LoopQueryVisitor<'a> {
p: |&ast::Expr_|: 'a -> bool,
flag: bool,
}
impl<'a> Visitor<()> for LoopQueryVisitor<'a> {
fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
self.flag |= (self.p)(&e.node);
match e.node {ast::ExprLoop(..) | ast::ExprWhile(..) => {}
_ => visit::walk_expr(self, e, ())
}
}
}pub fn loop_query(b: &ast::Block, p: |&ast::Expr_| -> bool) -> bool {
let mut v = LoopQueryVisitor {
p: p,
flag: false,
};
visit::walk_block(&mut v, b, ());
return v.flag;
}
struct BlockQueryVisitor<'a> {
p: |&ast::Expr|: 'a -> bool,
flag: bool,
}
impl<'a> Visitor<()> for BlockQueryVisitor<'a> {
fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
self.flag |= (self.p)(e);
visit::walk_expr(self, e, ())
}
}pub fn block_query(b: ast::P<ast::Block>, p: |&ast::Expr| -> bool) -> bool {
let mut v = BlockQueryVisitor {
p: p,
flag: false,
};
visit::walk_block(&mut v, &*b, ());
return v.flag;
}