1 |
b4d9710b
|
xthirioux
|
(********************************************************************)
|
2 |
|
|
(* *)
|
3 |
|
|
(* The LustreC compiler toolset / The LustreC Development Team *)
|
4 |
|
|
(* Copyright 2012 - -- ONERA - CNRS - INPT *)
|
5 |
|
|
(* *)
|
6 |
|
|
(* LustreC is free software, distributed WITHOUT ANY WARRANTY *)
|
7 |
|
|
(* under the terms of the GNU Lesser General Public License *)
|
8 |
|
|
(* version 2.1. *)
|
9 |
|
|
(* *)
|
10 |
|
|
(********************************************************************)
|
11 |
|
|
|
12 |
|
|
open Utils
|
13 |
8446bf03
|
ploc
|
open Lustre_types
|
14 |
b4d9710b
|
xthirioux
|
open Corelang
|
15 |
|
|
|
16 |
|
|
|
17 |
|
|
type aut_state =
|
18 |
|
|
{
|
19 |
|
|
incoming_r' : var_decl;
|
20 |
|
|
incoming_s' : var_decl;
|
21 |
|
|
incoming_r : var_decl;
|
22 |
|
|
incoming_s : var_decl;
|
23 |
|
|
actual_r : var_decl;
|
24 |
|
|
actual_s : var_decl
|
25 |
|
|
}
|
26 |
|
|
|
27 |
|
|
let as_clock var_decl =
|
28 |
|
|
let tydec = var_decl.var_dec_type in
|
29 |
|
|
{ var_decl with var_dec_type = { ty_dec_desc = Tydec_clock tydec.ty_dec_desc; ty_dec_loc = tydec.ty_dec_loc } }
|
30 |
|
|
|
31 |
|
|
let mkbool loc b =
|
32 |
|
|
mkexpr loc (Expr_const (const_of_bool b))
|
33 |
|
|
|
34 |
|
|
let mkident loc id =
|
35 |
|
|
mkexpr loc (Expr_ident id)
|
36 |
|
|
|
37 |
e3a4e911
|
xthirioux
|
let mkconst loc id =
|
38 |
|
|
mkexpr loc (Expr_const (Const_tag id))
|
39 |
|
|
|
40 |
b4d9710b
|
xthirioux
|
let mkfby loc e1 e2 =
|
41 |
|
|
mkexpr loc (Expr_arrow (e1, mkexpr loc (Expr_pre e2)))
|
42 |
|
|
|
43 |
e3a4e911
|
xthirioux
|
let mkpair loc e1 e2 =
|
44 |
|
|
mkexpr loc (Expr_tuple [e1; e2])
|
45 |
|
|
|
46 |
b4d9710b
|
xthirioux
|
let mkidentpair loc restart state =
|
47 |
|
|
mkexpr loc (Expr_tuple [mkident loc restart; mkident loc state])
|
48 |
|
|
|
49 |
|
|
let add_branch (loc, expr, restart, st) cont =
|
50 |
|
|
mkexpr loc (Expr_ite (expr, mkexpr loc (Expr_tuple [mkbool loc restart; mkident loc st]), cont))
|
51 |
|
|
|
52 |
|
|
let mkhandler loc st unless until locals (stmts, asserts, annots) =
|
53 |
|
|
{hand_state = st;
|
54 |
|
|
hand_unless = unless;
|
55 |
|
|
hand_until = until;
|
56 |
|
|
hand_locals = locals;
|
57 |
|
|
hand_stmts = stmts;
|
58 |
|
|
hand_asserts = asserts;
|
59 |
|
|
hand_annots = annots;
|
60 |
|
|
hand_loc = loc}
|
61 |
|
|
|
62 |
|
|
let mkautomata loc id handlers =
|
63 |
|
|
{aut_id = id;
|
64 |
|
|
aut_handlers = handlers;
|
65 |
|
|
aut_loc = loc}
|
66 |
|
|
|
67 |
|
|
let expr_of_exit loc restart state conds tag =
|
68 |
|
|
mkexpr loc (Expr_when (List.fold_right add_branch conds (mkidentpair loc restart state), state, tag))
|
69 |
|
|
|
70 |
ca7e8027
|
Lélio Brun
|
let unless_read reads handler =
|
71 |
60aab16d
|
xthirioux
|
let res =
|
72 |
a6df3992
|
Ploc
|
List.fold_left (fun read (_, c, _, _) -> Utils.ISet.union read (get_expr_vars c)) reads handler.hand_unless
|
73 |
60aab16d
|
xthirioux
|
in
|
74 |
|
|
(
|
75 |
|
|
(*
|
76 |
|
|
Format.eprintf "unless_reads %s = %a@." handler.hand_state (fprintf_list ~sep:" , " (fun fmt v -> Format.fprintf fmt "%s" v)) (ISet.elements reads);
|
77 |
|
|
Format.eprintf "unless_reads' %s = %a@." handler.hand_state (fprintf_list ~sep:" , " (fun fmt v -> Format.fprintf fmt "%s" v)) (ISet.elements res);
|
78 |
|
|
*)
|
79 |
|
|
res
|
80 |
|
|
)
|
81 |
b4d9710b
|
xthirioux
|
|
82 |
ca7e8027
|
Lélio Brun
|
let until_read reads handler =
|
83 |
a6df3992
|
Ploc
|
List.fold_left (fun read (_, c, _, _) -> Utils.ISet.union read (get_expr_vars c)) reads handler.hand_until
|
84 |
b4d9710b
|
xthirioux
|
|
85 |
|
|
let rec handler_read reads handler =
|
86 |
|
|
let locals = List.fold_left (fun locals v -> ISet.add v.var_id locals) ISet.empty handler.hand_locals in
|
87 |
|
|
let allvars =
|
88 |
|
|
List.fold_left (fun read stmt ->
|
89 |
|
|
match stmt with
|
90 |
a6df3992
|
Ploc
|
| Eq eq -> Utils.ISet.union read (get_expr_vars eq.eq_rhs)
|
91 |
60aab16d
|
xthirioux
|
| Aut aut -> automata_read read aut) reads handler.hand_stmts
|
92 |
|
|
in let res = ISet.diff allvars locals
|
93 |
|
|
in
|
94 |
|
|
(
|
95 |
|
|
(*
|
96 |
|
|
Format.eprintf "handler_allvars %s = %a@." handler.hand_state (fprintf_list ~sep:" , " (fun fmt v -> Format.fprintf fmt "%s" v)) (ISet.elements allvars);
|
97 |
|
|
Format.eprintf "handler_read %s = %a@." handler.hand_state (fprintf_list ~sep:" , " (fun fmt v -> Format.fprintf fmt "%s" v)) (ISet.elements res);
|
98 |
|
|
*)
|
99 |
|
|
res
|
100 |
|
|
)
|
101 |
|
|
|
102 |
|
|
and automata_read reads aut =
|
103 |
|
|
List.fold_left (fun read handler -> until_read (handler_read (unless_read read handler) handler) handler) reads aut.aut_handlers
|
104 |
b4d9710b
|
xthirioux
|
|
105 |
|
|
let rec handler_write writes handler =
|
106 |
|
|
let locals = List.fold_left (fun locals v -> ISet.add v.var_id locals) ISet.empty handler.hand_locals in
|
107 |
|
|
let allvars =
|
108 |
|
|
List.fold_left (fun write stmt ->
|
109 |
|
|
match stmt with
|
110 |
|
|
| Eq eq -> List.fold_left (fun write v -> ISet.add v write) write eq.eq_lhs
|
111 |
|
|
| Aut aut -> List.fold_left handler_write write aut.aut_handlers) writes handler.hand_stmts
|
112 |
|
|
in ISet.diff allvars locals
|
113 |
|
|
|
114 |
|
|
let node_vars_of_idents node iset =
|
115 |
|
|
List.fold_right (fun v res -> if ISet.mem v.var_id iset then v :: res else res) (get_node_vars node) []
|
116 |
|
|
|
117 |
66359a5e
|
ploc
|
let mkautomata_state nodeid used typedef loc id =
|
118 |
b4d9710b
|
xthirioux
|
let tydec_bool = { ty_dec_desc = Tydec_bool; ty_dec_loc = loc } in
|
119 |
|
|
let tydec_state id = { ty_dec_desc = Tydec_const id; ty_dec_loc = loc } in
|
120 |
|
|
let ckdec_any = { ck_dec_desc = Ckdec_any; ck_dec_loc = loc } in
|
121 |
|
|
let incoming_r' = mk_new_name used (id ^ "__next_restart_in") in
|
122 |
|
|
let incoming_s' = mk_new_name used (id ^ "__next_state_in") in
|
123 |
|
|
let incoming_r = mk_new_name used (id ^ "__restart_in") in
|
124 |
|
|
let incoming_s = mk_new_name used (id ^ "__state_in") in
|
125 |
|
|
let actual_r = mk_new_name used (id ^ "__restart_act") in
|
126 |
|
|
let actual_s = mk_new_name used (id ^ "__state_act") in
|
127 |
|
|
{
|
128 |
66359a5e
|
ploc
|
incoming_r' = mkvar_decl loc (incoming_r', tydec_bool, ckdec_any, false, None, Some nodeid);
|
129 |
|
|
incoming_s' = mkvar_decl loc (incoming_s', tydec_state typedef.tydef_id, ckdec_any, false, None, Some nodeid);
|
130 |
|
|
incoming_r = mkvar_decl loc (incoming_r, tydec_bool, ckdec_any, false, None, Some nodeid);
|
131 |
|
|
incoming_s = mkvar_decl loc (incoming_s, tydec_state typedef.tydef_id, ckdec_any, false, None, Some nodeid);
|
132 |
|
|
actual_r = mkvar_decl loc (actual_r , tydec_bool, ckdec_any, false, None, Some nodeid);
|
133 |
|
|
actual_s = mkvar_decl loc (actual_s , tydec_state typedef.tydef_id, ckdec_any, false, None, Some nodeid)
|
134 |
b4d9710b
|
xthirioux
|
}
|
135 |
|
|
|
136 |
|
|
let vars_of_aut_state aut_state =
|
137 |
|
|
[aut_state.incoming_r'; aut_state.incoming_r; aut_state.actual_r; aut_state.incoming_s'; as_clock aut_state.incoming_s; as_clock aut_state.actual_s]
|
138 |
|
|
|
139 |
ca7e8027
|
Lélio Brun
|
let node_of_unless nused node aut_id aut_state handler =
|
140 |
60aab16d
|
xthirioux
|
(*Format.eprintf "node_of_unless %s@." node.node_id;*)
|
141 |
b4d9710b
|
xthirioux
|
let inputs = unless_read ISet.empty handler in
|
142 |
28d2185f
|
xthirioux
|
let var_inputs = aut_state.incoming_r (*:: aut_state.incoming_s*) :: (node_vars_of_idents node inputs) in
|
143 |
b4d9710b
|
xthirioux
|
let var_outputs = aut_state.actual_r :: aut_state.actual_s :: [] in
|
144 |
28d2185f
|
xthirioux
|
let init_expr = mkpair handler.hand_loc (mkident handler.hand_loc aut_state.incoming_r.var_id) (mkconst handler.hand_loc handler.hand_state) in
|
145 |
|
|
(* let init_expr = mkidentpair handler.hand_loc aut_state.incoming_r.var_id aut_state.incoming_s.var_id in *)
|
146 |
|
|
let expr_outputs = List.fold_right add_branch handler.hand_unless init_expr in
|
147 |
b4d9710b
|
xthirioux
|
let eq_outputs = Eq (mkeq handler.hand_loc ([aut_state.actual_r.var_id; aut_state.actual_s.var_id], expr_outputs)) in
|
148 |
|
|
let node_id = mk_new_name nused (Format.sprintf "%s__%s_unless" aut_id handler.hand_state) in
|
149 |
|
|
let args = List.map (fun v -> mkexpr handler.hand_loc (Expr_when (mkident handler.hand_loc v.var_id, aut_state.incoming_s.var_id, handler.hand_state))) var_inputs in
|
150 |
|
|
let reset = Some (mkident handler.hand_loc aut_state.incoming_r.var_id) in
|
151 |
|
|
{
|
152 |
|
|
node_id = node_id;
|
153 |
|
|
node_type = Types.new_var ();
|
154 |
|
|
node_clock = Clocks.new_var true;
|
155 |
e3a4e911
|
xthirioux
|
node_inputs = List.map copy_var_decl var_inputs;
|
156 |
|
|
node_outputs = List.map copy_var_decl var_outputs;
|
157 |
b4d9710b
|
xthirioux
|
node_locals = [];
|
158 |
|
|
node_gencalls = [];
|
159 |
|
|
node_checks = [];
|
160 |
|
|
node_asserts = [];
|
161 |
|
|
node_stmts = [ eq_outputs ];
|
162 |
|
|
node_dec_stateless = false;
|
163 |
|
|
node_stateless = None;
|
164 |
|
|
node_spec = None;
|
165 |
f4cba4b8
|
ploc
|
node_annot = [];
|
166 |
|
|
node_iscontract = false;
|
167 |
b4d9710b
|
xthirioux
|
},
|
168 |
|
|
mkexpr handler.hand_loc (Expr_appl (node_id, mkexpr handler.hand_loc (Expr_tuple args), reset))
|
169 |
|
|
|
170 |
|
|
|
171 |
|
|
let rename_output used name = mk_new_name used (Format.sprintf "%s_out" name)
|
172 |
|
|
|
173 |
|
|
let rec rename_stmts_outputs frename stmts =
|
174 |
|
|
match stmts with
|
175 |
|
|
| [] -> []
|
176 |
|
|
| (Eq eq) :: q -> let eq' = Eq { eq with eq_lhs = List.map frename eq.eq_lhs } in
|
177 |
|
|
eq' :: rename_stmts_outputs frename q
|
178 |
|
|
| (Aut aut) :: q -> let handlers' = List.map (fun h -> { h with hand_stmts = rename_stmts_outputs frename h.hand_stmts}) aut.aut_handlers in
|
179 |
|
|
let aut' = Aut { aut with aut_handlers = handlers' } in
|
180 |
|
|
aut' :: rename_stmts_outputs frename q
|
181 |
|
|
|
182 |
|
|
let mk_frename used outputs =
|
183 |
|
|
let table = ISet.fold (fun name table -> IMap.add name (rename_output used name) table) outputs IMap.empty in
|
184 |
|
|
(fun name -> try IMap.find name table with Not_found -> name)
|
185 |
|
|
|
186 |
|
|
let node_of_assign_until nused used node aut_id aut_state handler =
|
187 |
60aab16d
|
xthirioux
|
(*Format.eprintf "node_of_assign_until %s@." node.node_id;*)
|
188 |
b4d9710b
|
xthirioux
|
let writes = handler_write ISet.empty handler in
|
189 |
|
|
let inputs = ISet.diff (handler_read (until_read ISet.empty handler) handler) writes in
|
190 |
|
|
let frename = mk_frename used writes in
|
191 |
28d2185f
|
xthirioux
|
let var_inputs = aut_state.actual_r (*:: aut_state.actual_s*) :: node_vars_of_idents node inputs in
|
192 |
b4d9710b
|
xthirioux
|
let new_var_locals = node_vars_of_idents node writes in
|
193 |
5775ac97
|
xavier.thirioux
|
let var_outputs = List.sort IdentModule.compare (node_vars_of_idents node writes) in
|
194 |
b4d9710b
|
xthirioux
|
let new_var_outputs = List.map (fun vdecl -> { vdecl with var_id = frename vdecl.var_id }) var_outputs in
|
195 |
|
|
let new_output_eqs = List.map2 (fun o o' -> Eq (mkeq handler.hand_loc ([o'.var_id], mkident handler.hand_loc o.var_id))) var_outputs new_var_outputs in
|
196 |
a406ac67
|
xthirioux
|
let init_until = mkpair handler.hand_loc (mkconst handler.hand_loc tag_false) (mkconst handler.hand_loc handler.hand_state) in
|
197 |
|
|
let until_expr = List.fold_right add_branch handler.hand_until init_until in
|
198 |
b4d9710b
|
xthirioux
|
let until_eq = Eq (mkeq handler.hand_loc ([aut_state.incoming_r.var_id; aut_state.incoming_s.var_id], until_expr)) in
|
199 |
|
|
let node_id = mk_new_name nused (Format.sprintf "%s__%s_handler_until" aut_id handler.hand_state) in
|
200 |
|
|
let args = List.map (fun v -> mkexpr handler.hand_loc (Expr_when (mkident handler.hand_loc v.var_id, aut_state.actual_s.var_id, handler.hand_state))) var_inputs in
|
201 |
|
|
let reset = Some (mkident handler.hand_loc aut_state.actual_r.var_id) in
|
202 |
|
|
List.fold_left (fun res v -> ISet.add v.var_id res) ISet.empty var_outputs,
|
203 |
|
|
{
|
204 |
|
|
node_id = node_id;
|
205 |
|
|
node_type = Types.new_var ();
|
206 |
|
|
node_clock = Clocks.new_var true;
|
207 |
e3a4e911
|
xthirioux
|
node_inputs = List.map copy_var_decl var_inputs;
|
208 |
|
|
node_outputs = List.map copy_var_decl (aut_state.incoming_r :: aut_state.incoming_s :: new_var_outputs);
|
209 |
|
|
node_locals = List.map copy_var_decl (new_var_locals @ handler.hand_locals);
|
210 |
b4d9710b
|
xthirioux
|
node_gencalls = [];
|
211 |
|
|
node_checks = [];
|
212 |
|
|
node_asserts = handler.hand_asserts;
|
213 |
|
|
node_stmts = until_eq :: new_output_eqs @ handler.hand_stmts;
|
214 |
|
|
node_dec_stateless = false;
|
215 |
|
|
node_stateless = None;
|
216 |
|
|
node_spec = None;
|
217 |
f4cba4b8
|
ploc
|
node_annot = handler.hand_annots;
|
218 |
|
|
node_iscontract = false;
|
219 |
b4d9710b
|
xthirioux
|
},
|
220 |
|
|
mkexpr handler.hand_loc (Expr_appl (node_id, mkexpr handler.hand_loc (Expr_tuple args), reset))
|
221 |
|
|
|
222 |
|
|
let typedef_of_automata aut =
|
223 |
|
|
let tname = Format.sprintf "%s__type" aut.aut_id in
|
224 |
|
|
{ tydef_id = tname;
|
225 |
|
|
tydef_desc = Tydec_enum (List.map (fun h -> h.hand_state) aut.aut_handlers)
|
226 |
|
|
}
|
227 |
|
|
|
228 |
|
|
let expand_automata nused used owner typedef node aut =
|
229 |
|
|
let initial = (List.hd aut.aut_handlers).hand_state in
|
230 |
66359a5e
|
ploc
|
let aut_state = mkautomata_state node.node_id used typedef aut.aut_loc aut.aut_id in
|
231 |
ca7e8027
|
Lélio Brun
|
let unodes = List.map (fun h -> node_of_unless nused node aut.aut_id aut_state h) aut.aut_handlers in
|
232 |
b4d9710b
|
xthirioux
|
let aunodes = List.map (fun h -> node_of_assign_until nused used node aut.aut_id aut_state h) aut.aut_handlers in
|
233 |
|
|
let all_outputs = List.fold_left (fun all (outputs, _, _) -> ISet.union outputs all) ISet.empty aunodes in
|
234 |
ca7e8027
|
Lélio Brun
|
let unless_handlers = List.map2 (fun h (_, c) -> (h.hand_state, c)) aut.aut_handlers unodes in
|
235 |
b4d9710b
|
xthirioux
|
let unless_expr = mkexpr aut.aut_loc (Expr_merge (aut_state.incoming_s.var_id, unless_handlers)) in
|
236 |
|
|
let unless_eq = mkeq aut.aut_loc ([aut_state.actual_r.var_id; aut_state.actual_s.var_id], unless_expr) in
|
237 |
ca7e8027
|
Lélio Brun
|
let assign_until_handlers = List.map2 (fun h (_, _, c) -> (h.hand_state, c)) aut.aut_handlers aunodes in
|
238 |
b4d9710b
|
xthirioux
|
let assign_until_expr = mkexpr aut.aut_loc (Expr_merge (aut_state.actual_s.var_id, assign_until_handlers)) in
|
239 |
|
|
let assign_until_vars = [aut_state.incoming_r'.var_id; aut_state.incoming_s'.var_id] @ (ISet.elements all_outputs) in
|
240 |
|
|
let assign_until_eq = mkeq aut.aut_loc (assign_until_vars, assign_until_expr) in
|
241 |
e3a4e911
|
xthirioux
|
let fby_incoming_expr = mkfby aut.aut_loc (mkpair aut.aut_loc (mkconst aut.aut_loc tag_false) (mkconst aut.aut_loc initial)) (mkidentpair aut.aut_loc aut_state.incoming_r'.var_id aut_state.incoming_s'.var_id) in
|
242 |
b4d9710b
|
xthirioux
|
let incoming_eq = mkeq aut.aut_loc ([aut_state.incoming_r.var_id; aut_state.incoming_s.var_id], fby_incoming_expr) in
|
243 |
|
|
let locals' = vars_of_aut_state aut_state in
|
244 |
|
|
let eqs' = [Eq unless_eq; Eq assign_until_eq; Eq incoming_eq] in
|
245 |
|
|
( List.map2 (fun h (n, _) -> mktop_decl h.hand_loc owner false (Node n)) aut.aut_handlers unodes
|
246 |
|
|
@ List.map2 (fun h (_, n, _) -> mktop_decl h.hand_loc owner false (Node n)) aut.aut_handlers aunodes,
|
247 |
|
|
locals',
|
248 |
|
|
eqs')
|
249 |
|
|
|
250 |
|
|
let expand_node_stmt nused used owner node (top_types, top_nodes, locals, eqs) stmt =
|
251 |
|
|
match stmt with
|
252 |
|
|
| Eq eq -> (top_types, top_nodes, locals, (Eq eq)::eqs)
|
253 |
|
|
| Aut aut ->
|
254 |
|
|
let typedef = typedef_of_automata aut in
|
255 |
|
|
let used' name = used name || List.exists (fun v -> v.var_id = name) locals in
|
256 |
|
|
let nused' name =
|
257 |
|
|
nused name ||
|
258 |
|
|
List.exists (fun t -> match t.top_decl_desc with
|
259 |
|
|
| ImportedNode nd -> nd.nodei_id = name | Node nd -> nd.node_id = name
|
260 |
|
|
| _ -> false) top_nodes in
|
261 |
|
|
let (top_decls', locals', eqs') = expand_automata nused' used' owner typedef node aut in
|
262 |
|
|
let top_typedef = mktop_decl aut.aut_loc owner false (TypeDef typedef) in
|
263 |
|
|
(top_typedef :: top_types, top_decls'@top_nodes, locals'@locals, eqs'@eqs)
|
264 |
|
|
|
265 |
|
|
let expand_node_stmts nused used loc owner node =
|
266 |
57c96fb7
|
Lélio Brun
|
let top_types', top_nodes', locals', eqs' =
|
267 |
b4d9710b
|
xthirioux
|
List.fold_left (expand_node_stmt nused used owner node) ([], [], [], []) node.node_stmts in
|
268 |
|
|
let node' =
|
269 |
|
|
{ node with node_locals = locals'@node.node_locals; node_stmts = eqs' } in
|
270 |
|
|
let top_node = mktop_decl loc owner false (Node node') in
|
271 |
|
|
top_types', top_node, top_nodes'
|
272 |
|
|
|
273 |
|
|
let rec expand_decls_rec nused top_decls =
|
274 |
|
|
match top_decls with
|
275 |
|
|
| [] -> []
|
276 |
|
|
| top_decl::q ->
|
277 |
|
|
match top_decl.top_decl_desc with
|
278 |
|
|
| Node nd ->
|
279 |
|
|
let used name =
|
280 |
57c96fb7
|
Lélio Brun
|
List.exists (fun v -> v.var_id = name) nd.node_inputs
|
281 |
|
|
|| List.exists (fun v -> v.var_id = name) nd.node_outputs
|
282 |
|
|
|| List.exists (fun v -> v.var_id = name) nd.node_locals in
|
283 |
|
|
let top_types', top_decl', top_nodes' = expand_node_stmts nused used top_decl.top_decl_loc top_decl.top_decl_owner nd in
|
284 |
b4d9710b
|
xthirioux
|
top_types' @ (top_decl' :: expand_decls_rec nused (top_nodes'@q))
|
285 |
|
|
| _ -> top_decl :: expand_decls_rec nused q
|
286 |
|
|
|
287 |
|
|
let expand_decls top_decls =
|
288 |
|
|
let top_names = List.fold_left (fun names t -> match t.top_decl_desc with
|
289 |
57c96fb7
|
Lélio Brun
|
| Node nd -> ISet.add nd.node_id names
|
290 |
|
|
| ImportedNode nd -> ISet.add nd.nodei_id names
|
291 |
|
|
| _ -> names) ISet.empty top_decls in
|
292 |
b4d9710b
|
xthirioux
|
let nused name = ISet.mem name top_names in
|
293 |
|
|
expand_decls_rec nused top_decls
|
294 |
|
|
|
295 |
|
|
(* Local Variables: *)
|
296 |
|
|
(* compile-command:"make -C .." *)
|
297 |
|
|
(* End: *)
|
298 |
|
|
|