Coccinelle release 1.0.0-rc15
[bpt/coccinelle.git] / parsing_cocci / get_metas.ml
CommitLineData
17ba0788
C
1(*
2 * Copyright 2012, INRIA
3 * Julia Lawall, Gilles Muller
4 * Copyright 2010-2011, INRIA, University of Copenhagen
5 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
6 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
7 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
8 * This file is part of Coccinelle.
9 *
10 * Coccinelle is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, according to version 2 of the License.
13 *
14 * Coccinelle is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
d6ce1786
C
20 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
21 *
22 * The authors reserve the right to distribute this or future versions of
23 * Coccinelle under other licenses.
24 *)
25
26
feec80c3 27# 0 "./get_metas.ml"
17ba0788
C
28(* --------------------------------------------------------------------- *)
29(* creates AsExpr, etc *)
30(* @ attached metavariables can only be associated with positions, so nothing
31to do for them *)
32
33module Ast = Ast_cocci
34module Ast0 = Ast0_cocci
35
36let map_split f l = List.split(List.map f l)
37
38let rewrap x (n,e) = (n,Ast0.rewrap x e)
39
40let mcode x =
41 let nonpos l =
42 List.filter (function Ast0.MetaPosTag _ -> false | _ -> true) l in
43 (nonpos(Ast0.get_pos x),x)
44
45let option_default = []
46
47let bind l1 l2 =
48 let oldnames = List.map Ast0.meta_pos_name l2 in
49 List.fold_left
50 (function prev -> function e1 ->
51 if List.mem (Ast0.meta_pos_name e1) oldnames then prev else e1::prev)
52 l2 l1
53
54let multibind l =
55 let rec loop = function
56 [] -> option_default
57 | [x] -> x
58 | x::xs -> bind x (loop xs) in
59 loop l
60
61let map_split_bind f l =
62 let (n,e) = List.split(List.map f l) in (multibind n,e)
63
64let get_option f = function
65 Some x -> let (n,e) = f x in (n,Some e)
66 | None -> (option_default,None)
67
68let do_disj starter lst mids ender processor rebuilder =
69 let (starter_n,starter) = mcode starter in
70 let (lst_n,lst) = map_split processor lst in
71 let (mids_n,mids) = map_split mcode mids in
72 let (ender_n,ender) = mcode ender in
73 (multibind
74 [starter_n;List.hd lst_n;
75 multibind (List.map2 bind mids_n (List.tl lst_n));ender_n],
76 rebuilder starter lst mids ender)
77
78let dots fn d =
79 rewrap d
80 (match Ast0.unwrap d with
81 Ast0.DOTS(l) ->
82 let (n,l) = map_split_bind fn l in (n, Ast0.DOTS(l))
83 | Ast0.CIRCLES(l) ->
84 let (n,l) = map_split_bind fn l in (n, Ast0.CIRCLES(l))
85 | Ast0.STARS(l) ->
86 let (n,l) = map_split_bind fn l in (n, Ast0.STARS(l)))
87
88let rec ident i =
d6ce1786 89 let (metas,i) =
17ba0788
C
90 rewrap i
91 (match Ast0.unwrap i with
92 Ast0.Id(name) ->
93 let (n,name) = mcode name in (n,Ast0.Id(name))
94 | Ast0.MetaId(name,constraints,seed,pure) ->
95 let (n,name) = mcode name in
96 (n,Ast0.MetaId(name,constraints,seed,pure))
97 | Ast0.MetaFunc(name,constraints,pure) ->
98 let (n,name) = mcode name in
99 (n,Ast0.MetaFunc(name,constraints,pure))
100 | Ast0.MetaLocalFunc(name,constraints,pure) ->
101 let (n,name) = mcode name in
102 (n,Ast0.MetaLocalFunc(name,constraints,pure))
d6ce1786 103 | Ast0.AsIdent _ -> failwith "not possible"
17ba0788
C
104 | Ast0.DisjId(starter,id_list,mids,ender) ->
105 do_disj starter id_list mids ender ident
106 (fun starter id_list mids ender ->
107 Ast0.DisjId(starter,id_list,mids,ender))
108 | Ast0.OptIdent(id) ->
109 let (n,id) = ident id in (n,Ast0.OptIdent(id))
110 | Ast0.UniqueIdent(id) ->
d6ce1786
C
111 let (n,id) = ident id in (n,Ast0.UniqueIdent(id))) in
112 List.fold_left
113 (function (other_metas,id) ->
114 function
115 Ast0.IdentTag(id_meta) ->
116 (other_metas,Ast0.rewrap id (Ast0.AsIdent(id,id_meta)))
117 | x -> (x::other_metas,id))
118 ([],i) metas
119
17ba0788
C
120and expression e =
121 let (metas,e) =
122 rewrap e
123 (match Ast0.unwrap e with
124 Ast0.Ident(id) ->
125 let (n,id) = ident id in (n,Ast0.Ident(id))
126 | Ast0.Constant(const) ->
127 let (n,const) = mcode const in (n,Ast0.Constant(const))
128 | Ast0.FunCall(fn,lp,args,rp) ->
129 let (fn_n,fn) = expression fn in
130 let (lp_n,lp) = mcode lp in
131 let (args_n,args) = dots expression args in
132 let (rp_n,rp) = mcode rp in
133 (multibind [fn_n;lp_n;args_n;rp_n], Ast0.FunCall(fn,lp,args,rp))
134 | Ast0.Assignment(left,op,right,simple) ->
135 let (left_n,left) = expression left in
136 let (op_n,op) = mcode op in
137 let (right_n,right) = expression right in
138 (multibind [left_n;op_n;right_n],
139 Ast0.Assignment(left,op,right,simple))
140 | Ast0.Sequence(left,op,right) ->
141 let (left_n,left) = expression left in
142 let (op_n,op) = mcode op in
143 let (right_n,right) = expression right in
144 (multibind [left_n;op_n;right_n],
145 Ast0.Sequence(left,op,right))
146 | Ast0.CondExpr(exp1,why,exp2,colon,exp3) ->
147 let (exp1_n,exp1) = expression exp1 in
148 let (why_n,why) = mcode why in
149 let (exp2_n,exp2) = get_option expression exp2 in
150 let (colon_n,colon) = mcode colon in
151 let (exp3_n,exp3) = expression exp3 in
152 (multibind [exp1_n;why_n;exp2_n;colon_n;exp3_n],
153 Ast0.CondExpr(exp1,why,exp2,colon,exp3))
154 | Ast0.Postfix(exp,op) ->
155 let (exp_n,exp) = expression exp in
156 let (op_n,op) = mcode op in
157 (bind exp_n op_n, Ast0.Postfix(exp,op))
158 | Ast0.Infix(exp,op) ->
159 let (exp_n,exp) = expression exp in
160 let (op_n,op) = mcode op in
161 (bind op_n exp_n, Ast0.Infix(exp,op))
162 | Ast0.Unary(exp,op) ->
163 let (exp_n,exp) = expression exp in
164 let (op_n,op) = mcode op in
165 (bind op_n exp_n, Ast0.Unary(exp,op))
166 | Ast0.Binary(left,op,right) ->
167 let (left_n,left) = expression left in
168 let (op_n,op) = mcode op in
169 let (right_n,right) = expression right in
170 (multibind [left_n;op_n;right_n], Ast0.Binary(left,op,right))
171 | Ast0.Nested(left,op,right) ->
172 let (left_n,left) = expression left in
173 let (op_n,op) = mcode op in
174 let (right_n,right) = expression right in
175 (multibind [left_n;op_n;right_n], Ast0.Nested(left,op,right))
176 | Ast0.Paren(lp,exp,rp) ->
177 let (lp_n,lp) = mcode lp in
178 let (exp_n,exp) = expression exp in
179 let (rp_n,rp) = mcode rp in
180 (multibind [lp_n;exp_n;rp_n], Ast0.Paren(lp,exp,rp))
181 | Ast0.ArrayAccess(exp1,lb,exp2,rb) ->
182 let (exp1_n,exp1) = expression exp1 in
183 let (lb_n,lb) = mcode lb in
184 let (exp2_n,exp2) = expression exp2 in
185 let (rb_n,rb) = mcode rb in
186 (multibind [exp1_n;lb_n;exp2_n;rb_n],
187 Ast0.ArrayAccess(exp1,lb,exp2,rb))
188 | Ast0.RecordAccess(exp,pt,field) ->
189 let (exp_n,exp) = expression exp in
190 let (pt_n,pt) = mcode pt in
191 let (field_n,field) = ident field in
192 (multibind [exp_n;pt_n;field_n], Ast0.RecordAccess(exp,pt,field))
193 | Ast0.RecordPtAccess(exp,ar,field) ->
194 let (exp_n,exp) = expression exp in
195 let (ar_n,ar) = mcode ar in
196 let (field_n,field) = ident field in
197 (multibind [exp_n;ar_n;field_n], Ast0.RecordPtAccess(exp,ar,field))
198 | Ast0.Cast(lp,ty,rp,exp) ->
199 let (lp_n,lp) = mcode lp in
200 let (ty_n,ty) = typeC ty in
201 let (rp_n,rp) = mcode rp in
202 let (exp_n,exp) = expression exp in
203 (multibind [lp_n;ty_n;rp_n;exp_n], Ast0.Cast(lp,ty,rp,exp))
204 | Ast0.SizeOfExpr(szf,exp) ->
205 let (szf_n,szf) = mcode szf in
206 let (exp_n,exp) = expression exp in
207 (multibind [szf_n;exp_n],Ast0.SizeOfExpr(szf,exp))
208 | Ast0.SizeOfType(szf,lp,ty,rp) ->
209 let (szf_n,szf) = mcode szf in
210 let (lp_n,lp) = mcode lp in
211 let (ty_n,ty) = typeC ty in
212 let (rp_n,rp) = mcode rp in
213 (multibind [szf_n;lp_n;ty_n;rp_n], Ast0.SizeOfType(szf,lp,ty,rp))
214 | Ast0.TypeExp(ty) ->
215 let (ty_n,ty) = typeC ty in
216 (ty_n,Ast0.TypeExp(ty))
217 | Ast0.Constructor(lp,ty,rp,init) ->
218 let (lp_n,lp) = mcode lp in
219 let (ty_n,ty) = typeC ty in
220 let (rp_n,rp) = mcode rp in
221 let (init_n,init) = initialiser init in
222 (multibind [lp_n;ty_n;rp_n;init_n], Ast0.Constructor(lp,ty,rp,init))
223 | Ast0.MetaErr(name,constraints,pure) ->
224 let (name_n,name) = mcode name in
225 (name_n,Ast0.MetaErr(name,constraints,pure))
226 | Ast0.MetaExpr(name,constraints,ty,form,pure) ->
227 let (name_n,name) = mcode name in
228 (name_n,Ast0.MetaExpr(name,constraints,ty,form,pure))
229 | Ast0.MetaExprList(name,lenname,pure) ->
230 let (name_n,name) = mcode name in
231 (name_n,Ast0.MetaExprList(name,lenname,pure))
232 | Ast0.AsExpr _ -> failwith "not possible"
233 | Ast0.EComma(cm) ->
234 let (cm_n,cm) = mcode cm in (cm_n,Ast0.EComma(cm))
235 | Ast0.DisjExpr(starter,expr_list,mids,ender) ->
236 do_disj starter expr_list mids ender expression
237 (fun starter expr_list mids ender ->
238 Ast0.DisjExpr(starter,expr_list,mids,ender))
239 | Ast0.NestExpr(starter,expr_dots,ender,whencode,multi) ->
240 let (starter_n,starter) = mcode starter in
241 let (expr_dots_n,expr_dots) = dots expression expr_dots in
242 let (ender_n,ender) = mcode ender in
243 let (whencode_n,whencode) = get_option expression whencode in
244 (multibind [starter_n;expr_dots_n;ender_n;whencode_n],
245 Ast0.NestExpr(starter,expr_dots,ender,whencode,multi))
246 | Ast0.Edots(dots,whencode) ->
247 let (dots_n,dots) = mcode dots in
248 let (whencode_n,whencode) = get_option expression whencode in
249 (bind dots_n whencode_n,Ast0.Edots(dots,whencode))
250 | Ast0.Ecircles(dots,whencode) ->
251 let (dots_n,dots) = mcode dots in
252 let (whencode_n,whencode) = get_option expression whencode in
253 (bind dots_n whencode_n,Ast0.Ecircles(dots,whencode))
254 | Ast0.Estars(dots,whencode) ->
255 let (dots_n,dots) = mcode dots in
256 let (whencode_n,whencode) = get_option expression whencode in
257 (bind dots_n whencode_n,Ast0.Estars(dots,whencode))
258 | Ast0.OptExp(exp) ->
259 let (exp_n,exp) = expression exp in
260 (exp_n,Ast0.OptExp(exp))
261 | Ast0.UniqueExp(exp) ->
262 let (exp_n,exp) = expression exp in
263 (exp_n,Ast0.UniqueExp(exp))) in
264 List.fold_left
265 (function (other_metas,exp) ->
266 function
267 Ast0.ExprTag(exp_meta) ->
268 (other_metas,Ast0.rewrap exp (Ast0.AsExpr(exp,exp_meta)))
d6ce1786
C
269 | Ast0.IdentTag(id_meta) ->
270 (other_metas,
271 Ast0.rewrap exp
272 (Ast0.AsExpr(exp,Ast0.rewrap exp (Ast0.Ident(id_meta)))))
17ba0788
C
273 | x -> (x::other_metas,exp))
274 ([],e) metas
275
276and typeC t =
277 let (metas,t) =
278 rewrap t
279 (match Ast0.unwrap t with
280 Ast0.ConstVol(cv,ty) ->
281 let (cv_n,cv) = mcode cv in
282 let (ty_n,ty) = typeC ty in
283 (bind cv_n ty_n, Ast0.ConstVol(cv,ty))
284 | Ast0.BaseType(ty,strings) ->
285 let (strings_n,strings) = map_split_bind mcode strings in
286 (strings_n, Ast0.BaseType(ty,strings))
287 | Ast0.Signed(sign,ty) ->
288 let (sign_n,sign) = mcode sign in
289 let (ty_n,ty) = get_option typeC ty in
290 (bind sign_n ty_n, Ast0.Signed(sign,ty))
291 | Ast0.Pointer(ty,star) ->
292 let (ty_n,ty) = typeC ty in
293 let (star_n,star) = mcode star in
294 (bind ty_n star_n, Ast0.Pointer(ty,star))
295 | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
296 function_pointer (ty,lp1,star,rp1,lp2,params,rp2) []
297 | Ast0.FunctionType(ty,lp1,params,rp1) ->
298 function_type (ty,lp1,params,rp1) []
299 | Ast0.Array(ty,lb,size,rb) -> array_type (ty,lb,size,rb) []
300 | Ast0.EnumName(kind,name) ->
301 let (kind_n,kind) = mcode kind in
302 let (name_n,name) = get_option ident name in
303 (bind kind_n name_n, Ast0.EnumName(kind,name))
304 | Ast0.EnumDef(ty,lb,ids,rb) ->
305 let (ty_n,ty) = typeC ty in
306 let (lb_n,lb) = mcode lb in
307 let (ids_n,ids) = dots expression ids in
308 let (rb_n,rb) = mcode rb in
309 (multibind [ty_n;lb_n;ids_n;rb_n], Ast0.EnumDef(ty,lb,ids,rb))
310 | Ast0.StructUnionName(kind,name) ->
311 let (kind_n,kind) = mcode kind in
312 let (name_n,name) = get_option ident name in
313 (bind kind_n name_n, Ast0.StructUnionName(kind,name))
314 | Ast0.StructUnionDef(ty,lb,decls,rb) ->
315 let (ty_n,ty) = typeC ty in
316 let (lb_n,lb) = mcode lb in
317 let (decls_n,decls) = dots declaration decls in
318 let (rb_n,rb) = mcode rb in
319 (multibind [ty_n;lb_n;decls_n;rb_n],
320 Ast0.StructUnionDef(ty,lb,decls,rb))
321 | Ast0.TypeName(name) ->
322 let (name_n,name) = mcode name in
323 (name_n,Ast0.TypeName(name))
324 | Ast0.MetaType(name,pure) ->
325 let (name_n,name) = mcode name in
326 (name_n,Ast0.MetaType(name,pure))
327 | Ast0.AsType _ -> failwith "not possible"
328 | Ast0.DisjType(starter,types,mids,ender) ->
329 do_disj starter types mids ender typeC
330 (fun starter types mids ender ->
331 Ast0.DisjType(starter,types,mids,ender))
332 | Ast0.OptType(ty) ->
333 let (ty_n,ty) = typeC ty in (ty_n, Ast0.OptType(ty))
334 | Ast0.UniqueType(ty) ->
335 let (ty_n,ty) = typeC ty in (ty_n, Ast0.UniqueType(ty))) in
336 List.fold_left
337 (function (other_metas,ty) ->
338 function
339 Ast0.TypeCTag(ty_meta) ->
340 (other_metas,Ast0.rewrap ty (Ast0.AsType(ty,ty_meta)))
341 | x -> (x::other_metas,ty))
342 ([],t) metas
343
344and function_pointer (ty,lp1,star,rp1,lp2,params,rp2) extra =
345 let (ty_n,ty) = typeC ty in
346 let (lp1_n,lp1) = mcode lp1 in
347 let (star_n,star) = mcode star in
348 let (rp1_n,rp1) = mcode rp1 in
349 let (lp2_n,lp2) = mcode lp2 in
350 let (params_n,params) = dots parameterTypeDef params in
351 let (rp2_n,rp2) = mcode rp2 in
352 (* have to put the treatment of the identifier into the right position *)
353 (multibind ([ty_n;lp1_n;star_n] @ extra @ [rp1_n;lp2_n;params_n;rp2_n]),
354 Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2))
355and function_type (ty,lp1,params,rp1) extra =
356 let (ty_n,ty) = get_option typeC ty in
357 let (lp1_n,lp1) = mcode lp1 in
358 let (params_n,params) = dots parameterTypeDef params in
359 let (rp1_n,rp1) = mcode rp1 in
360 (* have to put the treatment of the identifier into the right position *)
361 (multibind (ty_n :: extra @ [lp1_n;params_n;rp1_n]),
362 Ast0.FunctionType(ty,lp1,params,rp1))
363and array_type (ty,lb,size,rb) extra =
364 let (ty_n,ty) = typeC ty in
365 let (lb_n,lb) = mcode lb in
366 let (size_n,size) = get_option expression size in
367 let (rb_n,rb) = mcode rb in
368 (multibind (ty_n :: extra @ [lb_n;size_n;rb_n]),
369 Ast0.Array(ty,lb,size,rb))
370
371and named_type ty id =
372 let (id_n,id) = ident id in
373 match Ast0.unwrap ty with
374 Ast0.FunctionPointer(rty,lp1,star,rp1,lp2,params,rp2) ->
375 let tyres =
376 function_pointer (rty,lp1,star,rp1,lp2,params,rp2) [id_n] in
377 (rewrap ty tyres, id)
378 | Ast0.FunctionType(rty,lp1,params,rp1) ->
379 let tyres = function_type (rty,lp1,params,rp1) [id_n] in
380 (rewrap ty tyres, id)
381 | Ast0.Array(rty,lb,size,rb) ->
382 let tyres = array_type (rty,lb,size,rb) [id_n] in
383 (rewrap ty tyres, id)
384 | _ -> let (ty_n,ty) = typeC ty in ((bind ty_n id_n, ty), id)
385
386and declaration d =
387 let (metas,d) =
388 rewrap d
389 (match Ast0.unwrap d with
390 Ast0.MetaDecl(name,pure) ->
391 let (n,name) = mcode name in
392 (n,Ast0.MetaDecl(name,pure))
393 | Ast0.MetaField(name,pure) ->
394 let (n,name) = mcode name in
395 (n,Ast0.MetaField(name,pure))
396 | Ast0.MetaFieldList(name,lenname,pure) ->
397 let (n,name) = mcode name in
398 (n,Ast0.MetaFieldList(name,lenname,pure))
399 | Ast0.AsDecl _ -> failwith "not possible"
400 | Ast0.Init(stg,ty,id,eq,ini,sem) ->
401 let (stg_n,stg) = get_option mcode stg in
402 let ((ty_id_n,ty),id) = named_type ty id in
403 let (eq_n,eq) = mcode eq in
404 let (ini_n,ini) = initialiser ini in
405 let (sem_n,sem) = mcode sem in
406 (multibind [stg_n;ty_id_n;eq_n;ini_n;sem_n],
407 Ast0.Init(stg,ty,id,eq,ini,sem))
408 | Ast0.UnInit(stg,ty,id,sem) ->
409 let (stg_n,stg) = get_option mcode stg in
410 let ((ty_id_n,ty),id) = named_type ty id in
411 let (sem_n,sem) = mcode sem in
412 (multibind [stg_n;ty_id_n;sem_n], Ast0.UnInit(stg,ty,id,sem))
413 | Ast0.MacroDecl(name,lp,args,rp,sem) ->
414 let (name_n,name) = ident name in
415 let (lp_n,lp) = mcode lp in
416 let (args_n,args) = dots expression args in
417 let (rp_n,rp) = mcode rp in
418 let (sem_n,sem) = mcode sem in
419 (multibind [name_n;lp_n;args_n;rp_n;sem_n],
420 Ast0.MacroDecl(name,lp,args,rp,sem))
421 | Ast0.MacroDeclInit(name,lp,args,rp,eq,ini,sem) ->
422 let (name_n,name) = ident name in
423 let (lp_n,lp) = mcode lp in
424 let (args_n,args) = dots expression args in
425 let (rp_n,rp) = mcode rp in
426 let (eq_n,eq) = mcode eq in
427 let (ini_n,ini) = initialiser ini in
428 let (sem_n,sem) = mcode sem in
429 (multibind [name_n;lp_n;args_n;rp_n;eq_n;ini_n;sem_n],
430 Ast0.MacroDeclInit(name,lp,args,rp,eq,ini,sem))
431 | Ast0.TyDecl(ty,sem) ->
432 let (ty_n,ty) = typeC ty in
433 let (sem_n,sem) = mcode sem in
434 (bind ty_n sem_n, Ast0.TyDecl(ty,sem))
435 | Ast0.Typedef(stg,ty,id,sem) ->
436 let (stg_n,stg) = mcode stg in
437 let (ty_n,ty) = typeC ty in
438 let (id_n,id) = typeC id in
439 let (sem_n,sem) = mcode sem in
440 (multibind [stg_n;ty_n;id_n;sem_n], Ast0.Typedef(stg,ty,id,sem))
441 | Ast0.DisjDecl(starter,decls,mids,ender) ->
442 do_disj starter decls mids ender declaration
443 (fun starter decls mids ender ->
444 Ast0.DisjDecl(starter,decls,mids,ender))
445 | Ast0.Ddots(dots,whencode) ->
446 let (dots_n,dots) = mcode dots in
447 let (whencode_n,whencode) = get_option declaration whencode in
448 (bind dots_n whencode_n, Ast0.Ddots(dots,whencode))
449 | Ast0.OptDecl(decl) ->
450 let (n,decl) = declaration decl in (n,Ast0.OptDecl(decl))
451 | Ast0.UniqueDecl(decl) ->
452 let (n,decl) = declaration decl in (n,Ast0.UniqueDecl(decl))) in
453 List.fold_left
454 (function (other_metas,decl) ->
455 function
456 Ast0.DeclTag(decl_meta) ->
457 (other_metas,Ast0.rewrap decl (Ast0.AsDecl(decl,decl_meta)))
458 | x -> (x::other_metas,decl))
459 ([],d) metas
460
461and initialiser i =
462 let (metas,i) =
463 rewrap i
464 (match Ast0.unwrap i with
465 Ast0.MetaInit(name,pure) ->
466 let (name_n,name) = mcode name in
467 (name_n,Ast0.MetaInit(name,pure))
468 | Ast0.MetaInitList(name,lenname,pure) ->
469 let (name_n,name) = mcode name in
470 (name_n,Ast0.MetaInitList(name,lenname,pure))
471 | Ast0.AsInit _ -> failwith "not possible"
472 | Ast0.InitExpr(exp) ->
473 let (exp_n,exp) = expression exp in
474 (exp_n,Ast0.InitExpr(exp))
475 | Ast0.InitList(lb,initlist,rb,ordered) ->
476 let (lb_n,lb) = mcode lb in
477 let (initlist_n,initlist) = dots initialiser initlist in
478 let (rb_n,rb) = mcode rb in
479 (multibind [lb_n;initlist_n;rb_n],
480 Ast0.InitList(lb,initlist,rb,ordered))
481 | Ast0.InitGccExt(designators,eq,ini) ->
482 let (dn,designators) = map_split_bind designator designators in
483 let (eq_n,eq) = mcode eq in
484 let (ini_n,ini) = initialiser ini in
485 (multibind [dn;eq_n;ini_n], Ast0.InitGccExt(designators,eq,ini))
486 | Ast0.InitGccName(name,eq,ini) ->
487 let (name_n,name) = ident name in
488 let (eq_n,eq) = mcode eq in
489 let (ini_n,ini) = initialiser ini in
490 (multibind [name_n;eq_n;ini_n], Ast0.InitGccName(name,eq,ini))
491 | Ast0.IComma(cm) ->
492 let (n,cm) = mcode cm in (n,Ast0.IComma(cm))
493 | Ast0.Idots(d,whencode) ->
494 let (d_n,d) = mcode d in
495 let (whencode_n,whencode) = get_option initialiser whencode in
496 (bind d_n whencode_n, Ast0.Idots(d,whencode))
497 | Ast0.OptIni(i) ->
498 let (n,i) = initialiser i in (n,Ast0.OptIni(i))
499 | Ast0.UniqueIni(i) ->
500 let (n,i) = initialiser i in (n,Ast0.UniqueIni(i))) in
501 List.fold_left
502 (function (other_metas,init) ->
503 function
504 Ast0.InitTag(init_meta) ->
505 (other_metas,Ast0.rewrap init (Ast0.AsInit(init,init_meta)))
506 | x -> (x::other_metas,init))
507 ([],i) metas
508
509and designator = function
510 Ast0.DesignatorField(dot,id) ->
511 let (dot_n,dot) = mcode dot in
512 let (id_n,id) = ident id in
513 (bind dot_n id_n, Ast0.DesignatorField(dot,id))
514 | Ast0.DesignatorIndex(lb,exp,rb) ->
515 let (lb_n,lb) = mcode lb in
516 let (exp_n,exp) = expression exp in
517 let (rb_n,rb) = mcode rb in
518 (multibind [lb_n;exp_n;rb_n], Ast0.DesignatorIndex(lb,exp,rb))
519 | Ast0.DesignatorRange(lb,min,dots,max,rb) ->
520 let (lb_n,lb) = mcode lb in
521 let (min_n,min) = expression min in
522 let (dots_n,dots) = mcode dots in
523 let (max_n,max) = expression max in
524 let (rb_n,rb) = mcode rb in
525 (multibind [lb_n;min_n;dots_n;max_n;rb_n],
526 Ast0.DesignatorRange(lb,min,dots,max,rb))
527
528and parameterTypeDef p =
529 rewrap p
530 (match Ast0.unwrap p with
531 Ast0.VoidParam(ty) ->
532 let (n,ty) = typeC ty in (n,Ast0.VoidParam(ty))
533 | Ast0.Param(ty,Some id) ->
534 let ((ty_id_n,ty),id) = named_type ty id in
535 (ty_id_n, Ast0.Param(ty,Some id))
536 | Ast0.Param(ty,None) ->
537 let (ty_n,ty) = typeC ty in
538 (ty_n, Ast0.Param(ty,None))
539 | Ast0.MetaParam(name,pure) ->
540 let (n,name) = mcode name in
541 (n,Ast0.MetaParam(name,pure))
542 | Ast0.MetaParamList(name,lenname,pure) ->
543 let (n,name) = mcode name in
544 (n,Ast0.MetaParamList(name,lenname,pure))
545 | Ast0.PComma(cm) ->
546 let (n,cm) = mcode cm in (n,Ast0.PComma(cm))
547 | Ast0.Pdots(dots) ->
548 let (n,dots) = mcode dots in (n,Ast0.Pdots(dots))
549 | Ast0.Pcircles(dots) ->
550 let (n,dots) = mcode dots in (n,Ast0.Pcircles(dots))
551 | Ast0.OptParam(param) ->
552 let (n,param) = parameterTypeDef param in (n,Ast0.OptParam(param))
553 | Ast0.UniqueParam(param) ->
554 let (n,param) = parameterTypeDef param in
555 (n,Ast0.UniqueParam(param)))
556
557and statement s =
558 let (metas,s) =
559 rewrap s
560 (match Ast0.unwrap s with
561 Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace) ->
562 let (fi_n,fi) = map_split_bind fninfo fi in
563 let (name_n,name) = ident name in
564 let (lp_n,lp) = mcode lp in
565 let (params_n,params) = dots parameterTypeDef params in
566 let (rp_n,rp) = mcode rp in
567 let (lbrace_n,lbrace) = mcode lbrace in
568 let (body_n,body) = dots statement body in
569 let (rbrace_n,rbrace) = mcode rbrace in
570 (multibind
571 [fi_n;name_n;lp_n;params_n;rp_n;lbrace_n;body_n;rbrace_n],
572 Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace))
573 | Ast0.Decl(bef,decl) ->
574 let (decl_n,decl) = declaration decl in
575 (decl_n,Ast0.Decl(bef,decl))
576 | Ast0.Seq(lbrace,body,rbrace) ->
577 let (lbrace_n,lbrace) = mcode lbrace in
578 let (body_n,body) = dots statement body in
579 let (rbrace_n,rbrace) = mcode rbrace in
580 (multibind [lbrace_n;body_n;rbrace_n],
581 Ast0.Seq(lbrace,body,rbrace))
582 | Ast0.ExprStatement(exp,sem) ->
583 let (exp_n,exp) = get_option expression exp in
584 let (sem_n,sem) = mcode sem in
585 (bind exp_n sem_n, Ast0.ExprStatement(exp,sem))
586 | Ast0.IfThen(iff,lp,exp,rp,branch1,aft) ->
587 let (iff_n,iff) = mcode iff in
588 let (lp_n,lp) = mcode lp in
589 let (exp_n,exp) = expression exp in
590 let (rp_n,rp) = mcode rp in
591 let (branch1_n,branch1) = statement branch1 in
592 (multibind [iff_n;lp_n;exp_n;rp_n;branch1_n],
593 Ast0.IfThen(iff,lp,exp,rp,branch1,aft))
594 | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft) ->
595 let (iff_n,iff) = mcode iff in
596 let (lp_n,lp) = mcode lp in
597 let (exp_n,exp) = expression exp in
598 let (rp_n,rp) = mcode rp in
599 let (branch1_n,branch1) = statement branch1 in
600 let (els_n,els) = mcode els in
601 let (branch2_n,branch2) = statement branch2 in
602 (multibind [iff_n;lp_n;exp_n;rp_n;branch1_n;els_n;branch2_n],
603 Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft))
604 | Ast0.While(whl,lp,exp,rp,body,aft) ->
605 let (whl_n,whl) = mcode whl in
606 let (lp_n,lp) = mcode lp in
607 let (exp_n,exp) = expression exp in
608 let (rp_n,rp) = mcode rp in
609 let (body_n,body) = statement body in
610 (multibind [whl_n;lp_n;exp_n;rp_n;body_n],
611 Ast0.While(whl,lp,exp,rp,body,aft))
612 | Ast0.Do(d,body,whl,lp,exp,rp,sem) ->
613 let (d_n,d) = mcode d in
614 let (body_n,body) = statement body in
615 let (whl_n,whl) = mcode whl in
616 let (lp_n,lp) = mcode lp in
617 let (exp_n,exp) = expression exp in
618 let (rp_n,rp) = mcode rp in
619 let (sem_n,sem) = mcode sem in
620 (multibind [d_n;body_n;whl_n;lp_n;exp_n;rp_n;sem_n],
621 Ast0.Do(d,body,whl,lp,exp,rp,sem))
755320b0 622 | Ast0.For(fr,lp,first,e2,sem2,e3,rp,body,aft) ->
17ba0788
C
623 let (fr_n,fr) = mcode fr in
624 let (lp_n,lp) = mcode lp in
755320b0
C
625 let (first_n,first) =
626 match Ast0.unwrap first with
627 Ast0.ForExp(e1,sem1) ->
628 let (e1_n,e1) = get_option expression e1 in
629 let (sem1_n,sem1) = mcode sem1 in
630 (bind e1_n sem1_n, Ast0.rewrap first (Ast0.ForExp(e1,sem1)))
631 | Ast0.ForDecl (bef,decl) ->
632 let (decl_n,decl) = declaration decl in
633 (decl_n,Ast0.rewrap first (Ast0.ForDecl (bef,decl))) in
17ba0788
C
634 let (e2_n,e2) = get_option expression e2 in
635 let (sem2_n,sem2) = mcode sem2 in
636 let (e3_n,e3) = get_option expression e3 in
637 let (rp_n,rp) = mcode rp in
638 let (body_n,body) = statement body in
755320b0
C
639 (multibind [fr_n;lp_n;first_n;e2_n;sem2_n;e3_n;rp_n;body_n],
640 Ast0.For(fr,lp,first,e2,sem2,e3,rp,body,aft))
17ba0788
C
641 | Ast0.Iterator(nm,lp,args,rp,body,aft) ->
642 let (nm_n,nm) = ident nm in
643 let (lp_n,lp) = mcode lp in
644 let (args_n,args) = dots expression args in
645 let (rp_n,rp) = mcode rp in
646 let (body_n,body) = statement body in
647 (multibind [nm_n;lp_n;args_n;rp_n;body_n],
648 Ast0.Iterator(nm,lp,args,rp,body,aft))
649 | Ast0.Switch(switch,lp,exp,rp,lb,decls,cases,rb) ->
650 let (switch_n,switch) = mcode switch in
651 let (lp_n,lp) = mcode lp in
652 let (exp_n,exp) = expression exp in
653 let (rp_n,rp) = mcode rp in
654 let (lb_n,lb) = mcode lb in
655 let (decls_n,decls) = dots statement decls in
656 let (cases_n,cases) = dots case_line cases in
657 let (rb_n,rb) = mcode rb in
658 (multibind [switch_n;lp_n;exp_n;rp_n;lb_n;decls_n;cases_n;rb_n],
659 Ast0.Switch(switch,lp,exp,rp,lb,decls,cases,rb))
660 | Ast0.Break(br,sem) ->
661 let (br_n,br) = mcode br in
662 let (sem_n,sem) = mcode sem in
663 (bind br_n sem_n, Ast0.Break(br,sem))
664 | Ast0.Continue(cont,sem) ->
665 let (cont_n,cont) = mcode cont in
666 let (sem_n,sem) = mcode sem in
667 (bind cont_n sem_n, Ast0.Continue(cont,sem))
668 | Ast0.Label(l,dd) ->
669 let (l_n,l) = ident l in
670 let (dd_n,dd) = mcode dd in
671 (bind l_n dd_n, Ast0.Label(l,dd))
672 | Ast0.Goto(goto,l,sem) ->
673 let (goto_n,goto) = mcode goto in
674 let (l_n,l) = ident l in
675 let (sem_n,sem) = mcode sem in
676 (bind goto_n (bind l_n sem_n), Ast0.Goto(goto,l,sem))
677 | Ast0.Return(ret,sem) ->
678 let (ret_n,ret) = mcode ret in
679 let (sem_n,sem) = mcode sem in
680 (bind ret_n sem_n, Ast0.Return(ret,sem))
681 | Ast0.ReturnExpr(ret,exp,sem) ->
682 let (ret_n,ret) = mcode ret in
683 let (exp_n,exp) = expression exp in
684 let (sem_n,sem) = mcode sem in
685 (multibind [ret_n;exp_n;sem_n], Ast0.ReturnExpr(ret,exp,sem))
686 | Ast0.MetaStmt(name,pure) ->
687 let (name_n,name) = mcode name in
688 (name_n,Ast0.MetaStmt(name,pure))
689 | Ast0.MetaStmtList(name,pure) ->
690 let (name_n,name) = mcode name in
691 (name_n,Ast0.MetaStmtList(name,pure))
692 | Ast0.AsStmt _ -> failwith "not possible"
693 | Ast0.Disj(starter,statement_dots_list,mids,ender) ->
694 do_disj starter statement_dots_list mids ender (dots statement)
695 (fun starter statement_dots_list mids ender ->
696 Ast0.Disj(starter,statement_dots_list,mids,ender))
697 | Ast0.Nest(starter,stmt_dots,ender,whn,multi) ->
698 let (starter_n,starter) = mcode starter in
699 let (stmt_dots_n,stmt_dots) = dots statement stmt_dots in
700 let (ender_n,ender) = mcode ender in
701 let (whn_n,whn) =
702 map_split_bind (whencode (dots statement) statement) whn in
703 (multibind [starter_n;stmt_dots_n;ender_n;whn_n],
704 Ast0.Nest(starter,stmt_dots,ender,whn,multi))
705 | Ast0.Exp(exp) ->
706 let (exp_n,exp) = expression exp in
707 (exp_n,Ast0.Exp(exp))
708 | Ast0.TopExp(exp) ->
709 let (exp_n,exp) = expression exp in
710 (exp_n,Ast0.TopExp(exp))
711 | Ast0.Ty(ty) ->
712 let (ty_n,ty) = typeC ty in
713 (ty_n,Ast0.Ty(ty))
714 | Ast0.TopInit(init) ->
715 let (init_n,init) = initialiser init in
716 (init_n,Ast0.TopInit(init))
717 | Ast0.Dots(d,whn) ->
718 let (d_n,d) = mcode d in
719 let (whn_n,whn) =
720 map_split_bind (whencode (dots statement) statement) whn in
721 (bind d_n whn_n, Ast0.Dots(d,whn))
722 | Ast0.Circles(d,whn) ->
723 let (d_n,d) = mcode d in
724 let (whn_n,whn) =
725 map_split_bind (whencode (dots statement) statement) whn in
726 (bind d_n whn_n, Ast0.Circles(d,whn))
727 | Ast0.Stars(d,whn) ->
728 let (d_n,d) = mcode d in
729 let (whn_n,whn) =
730 map_split_bind (whencode (dots statement) statement) whn in
731 (bind d_n whn_n, Ast0.Stars(d,whn))
732 | Ast0.Include(inc,name) ->
733 let (inc_n,inc) = mcode inc in
734 let (name_n,name) = mcode name in
735 (bind inc_n name_n, Ast0.Include(inc,name))
736 | Ast0.Undef(def,id) ->
737 let (def_n,def) = mcode def in
738 let (id_n,id) = ident id in
739 (multibind [def_n;id_n],Ast0.Undef(def,id))
740 | Ast0.Define(def,id,params,body) ->
741 let (def_n,def) = mcode def in
742 let (id_n,id) = ident id in
743 let (params_n,params) = define_parameters params in
744 let (body_n,body) = dots statement body in
745 (multibind [def_n;id_n;params_n;body_n],
746 Ast0.Define(def,id,params,body))
747 | Ast0.OptStm(re) ->
748 let (re_n,re) = statement re in (re_n,Ast0.OptStm(re))
749 | Ast0.UniqueStm(re) ->
750 let (re_n,re) = statement re in (re_n,Ast0.UniqueStm(re))) in
751 List.fold_left
752 (function (other_metas,stmt) ->
753 function
754 Ast0.StmtTag(stmt_meta) ->
755 (other_metas,Ast0.rewrap stmt (Ast0.AsStmt(stmt,stmt_meta)))
756 | x -> (x::other_metas,stmt))
757 ([],s) metas
758
759 (* not parameterizable for now... *)
760and define_parameters p =
761 rewrap p
762 (match Ast0.unwrap p with
763 Ast0.NoParams -> (option_default,Ast0.NoParams)
764 | Ast0.DParams(lp,params,rp) ->
765 let (lp_n,lp) = mcode lp in
766 let (params_n,params) = dots define_param params in
767 let (rp_n,rp) = mcode rp in
768 (multibind [lp_n;params_n;rp_n], Ast0.DParams(lp,params,rp)))
769
770and define_param p =
771 rewrap p
772 (match Ast0.unwrap p with
773 Ast0.DParam(id) -> let (n,id) = ident id in (n,Ast0.DParam(id))
774 | Ast0.DPComma(comma) ->
775 let (n,comma) = mcode comma in (n,Ast0.DPComma(comma))
776 | Ast0.DPdots(d) ->
777 let (n,d) = mcode d in (n,Ast0.DPdots(d))
778 | Ast0.DPcircles(c) ->
779 let (n,c) = mcode c in (n,Ast0.DPcircles(c))
780 | Ast0.OptDParam(dp) ->
781 let (n,dp) = define_param dp in (n,Ast0.OptDParam(dp))
782 | Ast0.UniqueDParam(dp) ->
783 let (n,dp) = define_param dp in (n,Ast0.UniqueDParam(dp)))
784
785and fninfo = function
786 Ast0.FStorage(stg) ->
787 let (n,stg) = mcode stg in (n,Ast0.FStorage(stg))
788 | Ast0.FType(ty) -> let (n,ty) = typeC ty in (n,Ast0.FType(ty))
789 | Ast0.FInline(inline) ->
790 let (n,inline) = mcode inline in (n,Ast0.FInline(inline))
791 | Ast0.FAttr(init) ->
792 let (n,init) = mcode init in (n,Ast0.FAttr(init))
793
794and whencode notfn alwaysfn = function
795 Ast0.WhenNot a -> let (n,a) = notfn a in (n,Ast0.WhenNot(a))
796 | Ast0.WhenAlways a -> let (n,a) = alwaysfn a in (n,Ast0.WhenAlways(a))
797 | Ast0.WhenModifier(x) -> (option_default,Ast0.WhenModifier(x))
798 | Ast0.WhenNotTrue(e) ->
799 let (n,e) = expression e in (n,Ast0.WhenNotTrue(e))
800 | Ast0.WhenNotFalse(e) ->
801 let (n,e) = expression e in (n,Ast0.WhenNotFalse(e))
802
803and case_line c =
804 rewrap c
805 (match Ast0.unwrap c with
806 Ast0.Default(def,colon,code) ->
807 let (def_n,def) = mcode def in
808 let (colon_n,colon) = mcode colon in
809 let (code_n,code) = dots statement code in
810 (multibind [def_n;colon_n;code_n], Ast0.Default(def,colon,code))
811 | Ast0.Case(case,exp,colon,code) ->
812 let (case_n,case) = mcode case in
813 let (exp_n,exp) = expression exp in
814 let (colon_n,colon) = mcode colon in
815 let (code_n,code) = dots statement code in
816 (multibind [case_n;exp_n;colon_n;code_n],
817 Ast0.Case(case,exp,colon,code))
818 | Ast0.DisjCase(starter,case_lines,mids,ender) ->
819 do_disj starter case_lines mids ender case_line
820 (fun starter case_lines mids ender ->
821 Ast0.DisjCase(starter,case_lines,mids,ender))
822 | Ast0.OptCase(case) ->
823 let (n,case) = case_line case in (n,Ast0.OptCase(case)))
824
825and top_level t =
826 rewrap t
827 (match Ast0.unwrap t with
828 Ast0.FILEINFO(old_file,new_file) ->
829 let (old_file_n,old_file) = mcode old_file in
830 let (new_file_n,new_file) = mcode new_file in
831 (bind old_file_n new_file_n,Ast0.FILEINFO(old_file,new_file))
832 | Ast0.NONDECL(statement_dots) ->
833 let (n,statement_dots) = statement statement_dots in
834 (n,Ast0.NONDECL(statement_dots))
835 | Ast0.CODE(stmt_dots) ->
836 let (stmt_dots_n,stmt_dots) = dots statement stmt_dots in
837 (stmt_dots_n, Ast0.CODE(stmt_dots))
838 | Ast0.TOPCODE(stmt_dots) ->
839 let (stmt_dots_n,stmt_dots) = dots statement stmt_dots in
840 (stmt_dots_n, Ast0.TOPCODE(stmt_dots))
841 | Ast0.ERRORWORDS(exps) ->
842 let (n,exps) = map_split_bind expression exps in
843 (n, Ast0.ERRORWORDS(exps))
844 | Ast0.OTHER(_) -> failwith "unexpected code")
845
846let process t =
847 List.map
848 (function x ->
849 match top_level x with
850 ([],code) -> code
851 | (l,_) ->
852 failwith
853 (Printf.sprintf
854 "rule starting on line %d contains unattached metavariables: %s"
855 (Ast0.get_line x)
856 (String.concat ", "
857 (List.map
858 (function nm ->
859 let (r,n) = Ast0.unwrap_mcode nm in r^"."^n)
860 (List.map Ast0.meta_pos_name l)))))
861 t