@@ -5,107 +5,102 @@ import std.option;
5
5
import std. option . some ;
6
6
import std. option . none ;
7
7
import std. _int ;
8
+ import std. _vec ;
8
9
import util. common ;
9
10
10
11
type fn_id_of_local = std. map. hashmap [ ast. def_id , ast. def_id ] ;
11
- type env = rec ( option . t [ ast. def_id] current_context , // fn or obj
12
+ type env = rec ( mutable vec [ ast. def_id] current_context , // fn or obj
12
13
fn_id_of_local idmap,
13
14
session . session sess) ;
14
15
15
- fn update_env_for_item ( & env e, @ast. item i ) -> env {
16
+ fn current_context ( & env e) -> ast. def_id {
17
+ ret e. current_context . ( _vec . len ( e. current_context ) - 1 u) ;
18
+ }
19
+
20
+ fn enter_item ( @env e , @ast. item i ) {
16
21
alt ( i. node ) {
17
22
case ( ast. item_fn ( ?name, _, _, ?id, _) ) {
18
- ret rec ( current_context = some ( id ) with e ) ;
23
+ _vec . push ( e . current_context , id ) ;
19
24
}
20
25
case ( ast. item_obj ( _, _, _, ?ids, _) ) {
21
- ret rec ( current_context = some ( ids. ty ) with e) ;
26
+ _vec. push ( e. current_context , ids. ty ) ;
27
+ }
28
+ case ( _) { }
29
+ }
30
+ }
31
+
32
+ fn leave_item ( @env e , @ast. item i ) {
33
+ alt ( i. node ) {
34
+ case ( ast. item_fn ( ?name, _, _, ?id, _) ) {
35
+ _vec. pop ( e. current_context ) ;
22
36
}
23
- case ( _ ) {
24
- ret e ;
37
+ case ( ast . item_obj ( _ , _ , _ , ?ids , _ ) ) {
38
+ _vec . pop ( e . current_context ) ;
25
39
}
40
+ case ( _) { }
26
41
}
27
42
}
28
43
29
- fn update_env_for_expr ( & env e, @ast. expr x ) -> env {
44
+ fn walk_expr ( @ env e , @ast. expr x ) {
30
45
alt ( x. node ) {
31
46
case ( ast. expr_for ( ?d, _, _, _) ) {
32
47
alt ( d. node ) {
33
48
case ( ast. decl_local ( ?local) ) {
34
- auto curr_context =
35
- option. get [ ast. def_id ] ( e. current_context ) ;
36
- e. idmap . insert ( local. id , curr_context) ;
37
- }
38
- case ( _) {
49
+ e. idmap . insert ( local. id , current_context ( * e) ) ;
39
50
}
51
+ case ( _) { }
40
52
}
41
53
}
42
54
case ( ast. expr_for_each ( ?d, _, _, _) ) {
43
55
alt ( d. node ) {
44
56
case ( ast. decl_local ( ?local) ) {
45
- auto curr_context =
46
- option. get [ ast. def_id ] ( e. current_context ) ;
47
- e. idmap . insert ( local. id , curr_context) ;
48
- }
49
- case ( _) {
57
+ e. idmap . insert ( local. id , current_context ( * e) ) ;
50
58
}
59
+ case ( _) { }
60
+ }
61
+ }
62
+ case ( ast. expr_path ( _, ?def, _) ) {
63
+ auto local_id;
64
+ alt ( option. get ( def) ) {
65
+ case ( ast. def_local ( ?id) ) { local_id = id; }
66
+ case ( _) { ret; }
67
+ }
68
+
69
+ auto df = ast. def_id_of_def ( option. get ( def) ) ;
70
+ auto def_context = option. get ( e. idmap . find ( df) ) ;
71
+
72
+ if ( current_context ( * e) != def_context) {
73
+ e. sess . span_err ( x. span ,
74
+ "attempted dynamic environment-capture" ) ;
51
75
}
52
76
}
53
77
case ( _) { }
54
78
}
55
- ret e;
56
79
}
57
80
58
- fn update_env_for_block ( & env e, & ast . block b) -> env {
59
- auto curr_context = option. get [ ast. def_id ] ( e. current_context ) ;
60
-
81
+ fn walk_block ( @env e , & ast . block b) {
61
82
for each ( @tup( ast. ident, ast. block_index_entry) it in
62
83
b. node . index . items ( ) ) {
63
84
alt ( it. _1 ) {
64
85
case ( ast. bie_local ( ?local) ) {
65
- e. idmap . insert ( local. id , curr_context) ;
66
- }
67
- case ( _) {
86
+ e. idmap . insert ( local. id , current_context ( * e) ) ;
68
87
}
88
+ case ( _) { }
69
89
}
70
90
}
71
-
72
- ret e;
73
- }
74
-
75
- fn fold_expr_path ( & env e, & ast. span sp , & ast . path p, & option. t[ ast. def] d ,
76
- ast . ann a) -> @ast . expr {
77
- auto local_id;
78
- alt ( option. get [ ast. def ] ( d) ) {
79
- case ( ast. def_local ( ?id) ) {
80
- local_id = id;
81
- }
82
- case ( _) {
83
- ret @fold. respan [ ast. expr_ ] ( sp, ast. expr_path ( p, d, a) ) ;
84
- }
85
- }
86
-
87
- auto curr_context = option. get [ ast. def_id ] ( e. current_context ) ;
88
- auto x = ast. def_id_of_def ( option. get [ ast. def ] ( d) ) ;
89
- auto def_context = option. get [ ast. def_id ] ( e. idmap . find ( x) ) ;
90
-
91
- if ( curr_context != def_context) {
92
- e. sess . span_err ( sp, "attempted dynamic environment-capture" ) ;
93
- }
94
-
95
- ret @fold. respan [ ast. expr_ ] ( sp, ast. expr_path ( p, d, a) ) ;
96
91
}
97
92
98
93
fn check_for_captures ( session . session sess, @ast. crate crate) {
99
- let fold . ast_fold [ env ] fld = fold . new_identity_fold [ env ] ( ) ;
100
- fld = @rec ( update_env_for_item = bind update_env_for_item ( _ , _ ) ,
101
- update_env_for_block = bind update_env_for_block ( _ , _ ) ,
102
- update_env_for_expr = bind update_env_for_expr ( _ , _ ) ,
103
- fold_expr_path = bind fold_expr_path ( _ , _ , _ , _ , _ )
104
- with * fld ) ;
105
- auto idmap = common . new_def_hash [ ast . def_id ] ( ) ;
106
- auto e = rec ( current_context = none [ ast . def_id ] , idmap = idmap ,
107
- sess = sess ) ;
108
- fold . fold_crate [ env ] ( e , fld , crate ) ;
94
+ let vec [ ast . def_id ] curctx = vec ( ) ;
95
+ auto env = @rec ( mutable current_context = curctx ,
96
+ idmap = common . new_def_hash [ ast . def_id ] ( ) ,
97
+ sess = sess ) ;
98
+ auto visitor = rec ( visit_item_pre = bind enter_item ( env , _ ) ,
99
+ visit_item_post = bind leave_item ( env , _ ) ,
100
+ visit_block_pre = bind walk_block ( env , _ ) ,
101
+ visit_expr_pre = bind walk_expr ( env , _ )
102
+ with walk . default_visitor ( ) ) ;
103
+ walk . walk_crate ( visitor , * crate ) ;
109
104
}
110
105
111
106
// Local Variables:
0 commit comments