16 type method_ = Ast.ident * Ast.ident list
19 [ `ExternalClass of Ast.ident * Ast.name * Ast.attr list * method_ list
20 | `External of Ast.ident
23 type 'a info = 'a * 'a Node.t
24 module VSet = Set.Make(struct
25 type t = string Node.t
26 let compare {value=a} {value=b} = Pervasives.compare a b
29 module CSet = Set.Make(struct
30 type t = (string*string) Node.t
31 let compare {value=a} {value=b} = Pervasives.compare a b
46 let (++) {var=v1; klass=k1; meth=m1} {var=v2; klass=k2; meth=m2} = {
47 var = VSet.union v1 v2;
48 klass = CSet.union k1 k2;
49 meth = MSet.union m1 m2;
54 var = List.fold_left (fun set x -> VSet.remove x set) env.var xs}
57 List.fold_left (++) empty
59 let rec unbound_expr : Ast.expr -> env =
61 `Bool _ | `Float _ | `Int _ | `String _ ->
65 var = VSet.singleton (node)}
66 | `Block xs | `Call xs ->
67 union @@ List.map unbound_expr xs
68 | `Let (decls,expr) ->
70 union @@ List.map (unbound_expr$snd) decls in
76 | `LetRec (decls,expr) ->
78 union @@ List.map (unbound_expr$snd) decls in
85 union @@ List.map unbound_expr [a;b;c]
86 | `Lambda (args,body) ->
87 unbound_expr body -- args
88 | `Invoke (name,meth,args) ->
89 let { meth = meths } as env' =
90 unbound_expr name ++ union (List.map unbound_expr args) in
92 meth = MSet.add meth meths}
93 | `New (klass,args) ->
94 let {klass=klasses} as env' =
95 union @@ List.map unbound_expr args in
97 klass = CSet.add klass klasses}
100 | `SlotSet (obj,_,value) ->
101 unbound_expr obj ++ unbound_expr value
103 let unbound_stmt (stmt : stmt) env =
106 unbound_expr expr ++ env
107 | `Define (name,expr) ->
108 unbound_expr expr -- [name]
111 | `Class (name,super,_,methods) ->
114 (fun (name,args,expr) -> (name,unbound_expr expr -- args))
116 let {meth=meths; klass=klasses} as env' =
119 meth = List.fold_left (flip MSet.remove) meths ms;
120 klass = CSet.remove {name with value=("",name.value)} klasses}
121 | `ExternalClass (name,super,_,methods) ->
123 List.map fst methods in
125 meth = List.fold_left (flip MSet.remove) env.meth ms;
126 klass = CSet.remove {name with value=("",name.value)} env.klass}
128 let unbound program =
129 if List.fold_right unbound_stmt program empty = empty then