Release coccinelle-0.2.3rc1
[bpt/coccinelle.git] / parsing_cocci / visitor_ast.ml
CommitLineData
9f8e26f4 1(*
ae4735db 2 * Copyright 2005-2010, Ecole des Mines de Nantes, University of Copenhagen
9f8e26f4
C
3 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
4 * This file is part of Coccinelle.
5 *
6 * Coccinelle is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, according to version 2 of the License.
9 *
10 * Coccinelle is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * The authors reserve the right to distribute this or future versions of
19 * Coccinelle under other licenses.
20 *)
21
22
5636bb2c
C
23(*
24 * Copyright 2005-2010, Ecole des Mines de Nantes, University of Copenhagen
25 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
26 * This file is part of Coccinelle.
27 *
28 * Coccinelle is free software: you can redistribute it and/or modify
29 * it under the terms of the GNU General Public License as published by
30 * the Free Software Foundation, according to version 2 of the License.
31 *
32 * Coccinelle is distributed in the hope that it will be useful,
33 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU General Public License for more details.
36 *
37 * You should have received a copy of the GNU General Public License
38 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
39 *
40 * The authors reserve the right to distribute this or future versions of
41 * Coccinelle under other licenses.
42 *)
43
44
b1b2de81 45module Ast0 = Ast0_cocci
34e49164
C
46module Ast = Ast_cocci
47
48(* --------------------------------------------------------------------- *)
49(* Generic traversal: combiner *)
50(* parameters:
51 combining function
52 treatment of: mcode, identifiers, expressions, fullTypes, types,
53 declarations, statements, toplevels
54 default value for options *)
55
56type 'a combiner =
57 {combiner_ident : Ast.ident -> 'a;
58 combiner_expression : Ast.expression -> 'a;
59 combiner_fullType : Ast.fullType -> 'a;
60 combiner_typeC : Ast.typeC -> 'a;
61 combiner_declaration : Ast.declaration -> 'a;
62 combiner_initialiser : Ast.initialiser -> 'a;
63 combiner_parameter : Ast.parameterTypeDef -> 'a;
64 combiner_parameter_list : Ast.parameter_list -> 'a;
65 combiner_rule_elem : Ast.rule_elem -> 'a;
66 combiner_statement : Ast.statement -> 'a;
67 combiner_case_line : Ast.case_line -> 'a;
68 combiner_top_level : Ast.top_level -> 'a;
69 combiner_anything : Ast.anything -> 'a;
70 combiner_expression_dots : Ast.expression Ast.dots -> 'a;
71 combiner_statement_dots : Ast.statement Ast.dots -> 'a;
72 combiner_declaration_dots : Ast.declaration Ast.dots -> 'a}
73
74type ('mc,'a) cmcode = 'a combiner -> 'mc Ast_cocci.mcode -> 'a
75type ('cd,'a) ccode = 'a combiner -> ('cd -> 'a) -> 'cd -> 'a
76
77
faf9a90c 78let combiner bind option_default
34e49164
C
79 meta_mcodefn string_mcodefn const_mcodefn assign_mcodefn fix_mcodefn
80 unary_mcodefn binary_mcodefn
faf9a90c 81 cv_mcodefn sign_mcodefn struct_mcodefn storage_mcodefn
34e49164
C
82 inc_file_mcodefn
83 expdotsfn paramdotsfn stmtdotsfn decldotsfn
84 identfn exprfn ftfn tyfn initfn paramfn declfn rulefn stmtfn casefn
85 topfn anyfn =
86 let multibind l =
87 let rec loop = function
88 [] -> option_default
89 | [x] -> x
90 | x::xs -> bind x (loop xs) in
91 loop l in
92 let get_option f = function
93 Some x -> f x
94 | None -> option_default in
95
96 let rec meta_mcode x = meta_mcodefn all_functions x
97 and string_mcode x = string_mcodefn all_functions x
98 and const_mcode x = const_mcodefn all_functions x
99 and assign_mcode x = assign_mcodefn all_functions x
100 and fix_mcode x = fix_mcodefn all_functions x
101 and unary_mcode x = unary_mcodefn all_functions x
102 and binary_mcode x = binary_mcodefn all_functions x
103 and cv_mcode x = cv_mcodefn all_functions x
34e49164
C
104 and sign_mcode x = sign_mcodefn all_functions x
105 and struct_mcode x = struct_mcodefn all_functions x
106 and storage_mcode x = storage_mcodefn all_functions x
107 and inc_file_mcode x = inc_file_mcodefn all_functions x
108
109 and expression_dots d =
110 let k d =
111 match Ast.unwrap d with
112 Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) ->
113 multibind (List.map expression l) in
114 expdotsfn all_functions k d
115
116 and parameter_dots d =
117 let k d =
118 match Ast.unwrap d with
119 Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) ->
120 multibind (List.map parameterTypeDef l) in
121 paramdotsfn all_functions k d
122
123 and statement_dots d =
124 let k d =
125 match Ast.unwrap d with
126 Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) ->
127 multibind (List.map statement l) in
128 stmtdotsfn all_functions k d
129
130 and declaration_dots d =
131 let k d =
132 match Ast.unwrap d with
133 Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) ->
134 multibind (List.map declaration l) in
135 decldotsfn all_functions k d
136
137 and ident i =
138 let k i =
139 match Ast.unwrap i with
951c7801
C
140 Ast.Id(name) -> string_mcode name
141 | Ast.MetaId(name,_,_,_) -> meta_mcode name
142 | Ast.MetaFunc(name,_,_,_) -> meta_mcode name
143 | Ast.MetaLocalFunc(name,_,_,_) -> meta_mcode name
144 | Ast.OptIdent(id) -> ident id
145 | Ast.UniqueIdent(id) -> ident id in
146 identfn all_functions k i
faf9a90c 147
34e49164
C
148 and expression e =
149 let k e =
150 match Ast.unwrap e with
151 Ast.Ident(id) -> ident id
152 | Ast.Constant(const) -> const_mcode const
153 | Ast.FunCall(fn,lp,args,rp) ->
154 multibind [expression fn; string_mcode lp; expression_dots args;
155 string_mcode rp]
156 | Ast.Assignment(left,op,right,simple) ->
157 multibind [expression left; assign_mcode op; expression right]
158 | Ast.CondExpr(exp1,why,exp2,colon,exp3) ->
159 multibind [expression exp1; string_mcode why;
160 get_option expression exp2; string_mcode colon;
161 expression exp3]
162 | Ast.Postfix(exp,op) -> bind (expression exp) (fix_mcode op)
163 | Ast.Infix(exp,op) -> bind (fix_mcode op) (expression exp)
164 | Ast.Unary(exp,op) -> bind (unary_mcode op) (expression exp)
165 | Ast.Binary(left,op,right) ->
166 multibind [expression left; binary_mcode op; expression right]
167 | Ast.Nested(left,op,right) ->
168 multibind [expression left; binary_mcode op; expression right]
169 | Ast.Paren(lp,exp,rp) ->
170 multibind [string_mcode lp; expression exp; string_mcode rp]
171 | Ast.ArrayAccess(exp1,lb,exp2,rb) ->
172 multibind
173 [expression exp1; string_mcode lb; expression exp2;
174 string_mcode rb]
175 | Ast.RecordAccess(exp,pt,field) ->
176 multibind [expression exp; string_mcode pt; ident field]
177 | Ast.RecordPtAccess(exp,ar,field) ->
178 multibind [expression exp; string_mcode ar; ident field]
179 | Ast.Cast(lp,ty,rp,exp) ->
180 multibind
181 [string_mcode lp; fullType ty; string_mcode rp; expression exp]
182 | Ast.SizeOfExpr(szf,exp) ->
183 multibind [string_mcode szf; expression exp]
184 | Ast.SizeOfType(szf,lp,ty,rp) ->
185 multibind
186 [string_mcode szf; string_mcode lp; fullType ty; string_mcode rp]
187 | Ast.TypeExp(ty) -> fullType ty
188 | Ast.MetaErr(name,_,_,_)
189 | Ast.MetaExpr(name,_,_,_,_,_)
190 | Ast.MetaExprList(name,_,_,_) -> meta_mcode name
191 | Ast.EComma(cm) -> string_mcode cm
192 | Ast.DisjExpr(exp_list) -> multibind (List.map expression exp_list)
5636bb2c
C
193 | Ast.NestExpr(starter,expr_dots,ender,whencode,multi) ->
194 bind (string_mcode starter)
195 (bind (expression_dots expr_dots)
196 (bind (string_mcode ender)
197 (get_option expression whencode)))
34e49164
C
198 | Ast.Edots(dots,whencode) | Ast.Ecircles(dots,whencode)
199 | Ast.Estars(dots,whencode) ->
200 bind (string_mcode dots) (get_option expression whencode)
201 | Ast.OptExp(exp) | Ast.UniqueExp(exp) ->
202 expression exp in
203 exprfn all_functions k e
faf9a90c 204
34e49164
C
205 and fullType ft =
206 let k ft =
207 match Ast.unwrap ft with
208 Ast.Type(cv,ty) -> bind (get_option cv_mcode cv) (typeC ty)
209 | Ast.DisjType(types) -> multibind (List.map fullType types)
210 | Ast.OptType(ty) -> fullType ty
211 | Ast.UniqueType(ty) -> fullType ty in
212 ftfn all_functions k ft
213
214 and function_pointer (ty,lp1,star,rp1,lp2,params,rp2) extra =
215 (* have to put the treatment of the identifier into the right position *)
216 multibind
217 ([fullType ty; string_mcode lp1; string_mcode star] @ extra @
218 [string_mcode rp1;
219 string_mcode lp2; parameter_dots params; string_mcode rp2])
faf9a90c 220
34e49164
C
221 and function_type (ty,lp1,params,rp1) extra =
222 (* have to put the treatment of the identifier into the right position *)
223 multibind
224 ([get_option fullType ty] @ extra @
225 [string_mcode lp1; parameter_dots params; string_mcode rp1])
226
227 and array_type (ty,lb,size,rb) extra =
228 multibind
229 ([fullType ty] @ extra @
230 [string_mcode lb; get_option expression size; string_mcode rb])
faf9a90c 231
34e49164
C
232 and typeC ty =
233 let k ty =
234 match Ast.unwrap ty with
faf9a90c
C
235 Ast.BaseType(ty,strings) -> multibind (List.map string_mcode strings)
236 | Ast.SignedT(sgn,ty) -> bind (sign_mcode sgn) (get_option typeC ty)
34e49164
C
237 | Ast.Pointer(ty,star) ->
238 bind (fullType ty) (string_mcode star)
239 | Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
240 function_pointer (ty,lp1,star,rp1,lp2,params,rp2) []
241 | Ast.FunctionType (_,ty,lp1,params,rp1) ->
242 function_type (ty,lp1,params,rp1) []
243 | Ast.Array(ty,lb,size,rb) -> array_type (ty,lb,size,rb) []
faf9a90c 244 | Ast.EnumName(kind,name) -> bind (string_mcode kind) (ident name)
34e49164
C
245 | Ast.StructUnionName(kind,name) ->
246 bind (struct_mcode kind) (get_option ident name)
247 | Ast.StructUnionDef(ty,lb,decls,rb) ->
248 multibind
249 [fullType ty; string_mcode lb; declaration_dots decls;
250 string_mcode rb]
251 | Ast.TypeName(name) -> string_mcode name
252 | Ast.MetaType(name,_,_) -> meta_mcode name in
253 tyfn all_functions k ty
254
255 and named_type ty id =
256 match Ast.unwrap ty with
257 Ast.Type(None,ty1) ->
258 (match Ast.unwrap ty1 with
259 Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
260 function_pointer (ty,lp1,star,rp1,lp2,params,rp2) [ident id]
261 | Ast.FunctionType(_,ty,lp1,params,rp1) ->
262 function_type (ty,lp1,params,rp1) [ident id]
263 | Ast.Array(ty,lb,size,rb) -> array_type (ty,lb,size,rb) [ident id]
264 | _ -> bind (fullType ty) (ident id))
265 | _ -> bind (fullType ty) (ident id)
266
267 and declaration d =
268 let k d =
269 match Ast.unwrap d with
270 Ast.Init(stg,ty,id,eq,ini,sem) ->
271 bind (get_option storage_mcode stg)
272 (bind (named_type ty id)
273 (multibind
274 [string_mcode eq; initialiser ini; string_mcode sem]))
275 | Ast.UnInit(stg,ty,id,sem) ->
276 bind (get_option storage_mcode stg)
277 (bind (named_type ty id) (string_mcode sem))
278 | Ast.MacroDecl(name,lp,args,rp,sem) ->
279 multibind
280 [ident name; string_mcode lp; expression_dots args;
281 string_mcode rp; string_mcode sem]
282 | Ast.TyDecl(ty,sem) -> bind (fullType ty) (string_mcode sem)
283 | Ast.Typedef(stg,ty,id,sem) ->
284 bind (string_mcode stg)
285 (bind (fullType ty) (bind (typeC id) (string_mcode sem)))
286 | Ast.DisjDecl(decls) -> multibind (List.map declaration decls)
287 | Ast.Ddots(dots,whencode) ->
288 bind (string_mcode dots) (get_option declaration whencode)
289 | Ast.MetaDecl(name,_,_) -> meta_mcode name
290 | Ast.OptDecl(decl) -> declaration decl
291 | Ast.UniqueDecl(decl) -> declaration decl in
292 declfn all_functions k d
293
294 and initialiser i =
295 let k i =
296 match Ast.unwrap i with
113803cf
C
297 Ast.MetaInit(name,_,_) -> meta_mcode name
298 | Ast.InitExpr(exp) -> expression exp
34e49164
C
299 | Ast.InitList(lb,initlist,rb,whencode) ->
300 multibind
301 [string_mcode lb;
302 multibind (List.map initialiser initlist);
303 string_mcode rb;
304 multibind (List.map initialiser whencode)]
34e49164
C
305 | Ast.InitGccName(name,eq,ini) ->
306 multibind [ident name; string_mcode eq; initialiser ini]
113803cf 307 | Ast.InitGccExt(designators,eq,ini) ->
34e49164 308 multibind
113803cf
C
309 ((List.map designator designators) @
310 [string_mcode eq; initialiser ini])
34e49164
C
311 | Ast.IComma(cm) -> string_mcode cm
312 | Ast.OptIni(i) -> initialiser i
313 | Ast.UniqueIni(i) -> initialiser i in
314 initfn all_functions k i
315
113803cf
C
316 and designator = function
317 Ast.DesignatorField(dot,id) -> bind (string_mcode dot) (ident id)
318 | Ast.DesignatorIndex(lb,exp,rb) ->
319 bind (string_mcode lb) (bind (expression exp) (string_mcode rb))
320 | Ast.DesignatorRange(lb,min,dots,max,rb) ->
321 multibind
322 [string_mcode lb; expression min; string_mcode dots;
323 expression max; string_mcode rb]
324
34e49164
C
325 and parameterTypeDef p =
326 let k p =
327 match Ast.unwrap p with
328 Ast.VoidParam(ty) -> fullType ty
329 | Ast.Param(ty,Some id) -> named_type ty id
330 | Ast.Param(ty,None) -> fullType ty
331 | Ast.MetaParam(name,_,_) -> meta_mcode name
332 | Ast.MetaParamList(name,_,_,_) -> meta_mcode name
333 | Ast.PComma(cm) -> string_mcode cm
334 | Ast.Pdots(dots) -> string_mcode dots
335 | Ast.Pcircles(dots) -> string_mcode dots
336 | Ast.OptParam(param) -> parameterTypeDef param
337 | Ast.UniqueParam(param) -> parameterTypeDef param in
338 paramfn all_functions k p
339
340 and rule_elem re =
341 let k re =
342 match Ast.unwrap re with
343 Ast.FunHeader(_,_,fi,name,lp,params,rp) ->
344 multibind
345 ((List.map fninfo fi) @
346 [ident name;string_mcode lp;parameter_dots params;
347 string_mcode rp])
348 | Ast.Decl(_,_,decl) -> declaration decl
349 | Ast.SeqStart(brace) -> string_mcode brace
350 | Ast.SeqEnd(brace) -> string_mcode brace
351 | Ast.ExprStatement(exp,sem) ->
352 bind (expression exp) (string_mcode sem)
353 | Ast.IfHeader(iff,lp,exp,rp) ->
354 multibind [string_mcode iff; string_mcode lp; expression exp;
355 string_mcode rp]
356 | Ast.Else(els) -> string_mcode els
357 | Ast.WhileHeader(whl,lp,exp,rp) ->
faf9a90c 358 multibind [string_mcode whl; string_mcode lp; expression exp;
34e49164
C
359 string_mcode rp]
360 | Ast.DoHeader(d) -> string_mcode d
361 | Ast.WhileTail(whl,lp,exp,rp,sem) ->
faf9a90c 362 multibind [string_mcode whl; string_mcode lp; expression exp;
34e49164
C
363 string_mcode rp; string_mcode sem]
364 | Ast.ForHeader(fr,lp,e1,sem1,e2,sem2,e3,rp) ->
faf9a90c
C
365 multibind [string_mcode fr; string_mcode lp;
366 get_option expression e1; string_mcode sem1;
367 get_option expression e2; string_mcode sem2;
34e49164
C
368 get_option expression e3; string_mcode rp]
369 | Ast.IteratorHeader(nm,lp,args,rp) ->
370 multibind [ident nm; string_mcode lp;
371 expression_dots args; string_mcode rp]
372 | Ast.SwitchHeader(switch,lp,exp,rp) ->
faf9a90c 373 multibind [string_mcode switch; string_mcode lp; expression exp;
34e49164
C
374 string_mcode rp]
375 | Ast.Break(br,sem) -> bind (string_mcode br) (string_mcode sem)
376 | Ast.Continue(cont,sem) -> bind (string_mcode cont) (string_mcode sem)
377 | Ast.Label(l,dd) -> bind (ident l) (string_mcode dd)
378 | Ast.Goto(goto,l,sem) ->
379 bind (string_mcode goto) (bind (ident l) (string_mcode sem))
380 | Ast.Return(ret,sem) -> bind (string_mcode ret) (string_mcode sem)
381 | Ast.ReturnExpr(ret,exp,sem) ->
382 multibind [string_mcode ret; expression exp; string_mcode sem]
383 | Ast.MetaStmt(name,_,_,_) -> meta_mcode name
384 | Ast.MetaStmtList(name,_,_) -> meta_mcode name
385 | Ast.MetaRuleElem(name,_,_) -> meta_mcode name
386 | Ast.Exp(exp) -> expression exp
387 | Ast.TopExp(exp) -> expression exp
388 | Ast.Ty(ty) -> fullType ty
1be43e12 389 | Ast.TopInit(init) -> initialiser init
34e49164
C
390 | Ast.Include(inc,name) -> bind (string_mcode inc) (inc_file_mcode name)
391 | Ast.DefineHeader(def,id,params) ->
392 multibind [string_mcode def; ident id; define_parameters params]
393 | Ast.Default(def,colon) -> bind (string_mcode def) (string_mcode colon)
394 | Ast.Case(case,exp,colon) ->
395 multibind [string_mcode case; expression exp; string_mcode colon]
396 | Ast.DisjRuleElem(res) -> multibind (List.map rule_elem res) in
397 rulefn all_functions k re
398
399 (* not parameterizable for now... *)
400 and define_parameters p =
401 let k p =
402 match Ast.unwrap p with
403 Ast.NoParams -> option_default
404 | Ast.DParams(lp,params,rp) ->
405 multibind
406 [string_mcode lp; define_param_dots params; string_mcode rp] in
407 k p
408
409 and define_param_dots d =
410 let k d =
411 match Ast.unwrap d with
412 Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) ->
413 multibind (List.map define_param l) in
414 k d
415
416 and define_param p =
417 let k p =
418 match Ast.unwrap p with
419 Ast.DParam(id) -> ident id
420 | Ast.DPComma(comma) -> string_mcode comma
421 | Ast.DPdots(d) -> string_mcode d
422 | Ast.DPcircles(c) -> string_mcode c
423 | Ast.OptDParam(dp) -> define_param dp
424 | Ast.UniqueDParam(dp) -> define_param dp in
faf9a90c 425 k p
34e49164
C
426
427 (* discard the result, because the statement is assumed to be already
428 represented elsewhere in the code *)
429 and process_bef_aft s =
430 match Ast.get_dots_bef_aft s with
431 Ast.NoDots -> ()
432 | Ast.DroppingBetweenDots(stm,ind) -> let _ = statement stm in ()
433 | Ast.AddingBetweenDots(stm,ind) -> let _ = statement stm in ()
faf9a90c 434
34e49164
C
435 and statement s =
436 process_bef_aft s;
437 let k s =
438 match Ast.unwrap s with
708f4980
C
439 Ast.Seq(lbrace,body,rbrace) ->
440 multibind [rule_elem lbrace;
34e49164
C
441 statement_dots body; rule_elem rbrace]
442 | Ast.IfThen(header,branch,_) ->
443 multibind [rule_elem header; statement branch]
444 | Ast.IfThenElse(header,branch1,els,branch2,_) ->
445 multibind [rule_elem header; statement branch1; rule_elem els;
446 statement branch2]
447 | Ast.While(header,body,_) ->
448 multibind [rule_elem header; statement body]
449 | Ast.Do(header,body,tail) ->
450 multibind [rule_elem header; statement body; rule_elem tail]
451 | Ast.For(header,body,_) -> multibind [rule_elem header; statement body]
452 | Ast.Iterator(header,body,_) ->
453 multibind [rule_elem header; statement body]
fc1ad971 454 | Ast.Switch(header,lb,decls,cases,rb) ->
34e49164 455 multibind [rule_elem header;rule_elem lb;
fc1ad971 456 statement_dots decls;
34e49164
C
457 multibind (List.map case_line cases);
458 rule_elem rb]
459 | Ast.Atomic(re) -> rule_elem re
460 | Ast.Disj(stmt_dots_list) ->
461 multibind (List.map statement_dots stmt_dots_list)
5636bb2c
C
462 | Ast.Nest(starter,stmt_dots,ender,whn,_,_,_) ->
463 bind (string_mcode starter)
464 (bind (statement_dots stmt_dots)
465 (bind (string_mcode ender)
466 (multibind
467 (List.map (whencode statement_dots statement) whn))))
708f4980 468 | Ast.FunDecl(header,lbrace,body,rbrace) ->
34e49164 469 multibind [rule_elem header; rule_elem lbrace;
708f4980 470 statement_dots body; rule_elem rbrace]
34e49164
C
471 | Ast.Define(header,body) ->
472 bind (rule_elem header) (statement_dots body)
473 | Ast.Dots(d,whn,_,_) | Ast.Circles(d,whn,_,_) | Ast.Stars(d,whn,_,_) ->
474 bind (string_mcode d)
475 (multibind (List.map (whencode statement_dots statement) whn))
476 | Ast.OptStm(stmt) | Ast.UniqueStm(stmt) ->
477 statement stmt in
478 stmtfn all_functions k s
479
480 and fninfo = function
481 Ast.FStorage(stg) -> storage_mcode stg
482 | Ast.FType(ty) -> fullType ty
483 | Ast.FInline(inline) -> string_mcode inline
484 | Ast.FAttr(attr) -> string_mcode attr
485
486 and whencode notfn alwaysfn = function
487 Ast.WhenNot a -> notfn a
488 | Ast.WhenAlways a -> alwaysfn a
489 | Ast.WhenModifier(_) -> option_default
1be43e12
C
490 | Ast.WhenNotTrue(e) -> rule_elem e
491 | Ast.WhenNotFalse(e) -> rule_elem e
faf9a90c 492
34e49164
C
493 and case_line c =
494 let k c =
495 match Ast.unwrap c with
496 Ast.CaseLine(header,code) ->
497 bind (rule_elem header) (statement_dots code)
498 | Ast.OptCase(case) -> case_line case in
499 casefn all_functions k c
500
501 and top_level t =
502 let k t =
503 match Ast.unwrap t with
504 Ast.FILEINFO(old_file,new_file) ->
505 bind (string_mcode old_file) (string_mcode new_file)
506 | Ast.DECL(stmt) -> statement stmt
507 | Ast.CODE(stmt_dots) -> statement_dots stmt_dots
508 | Ast.ERRORWORDS(exps) -> multibind (List.map expression exps) in
509 topfn all_functions k t
510
511 and anything a =
512 let k = function
513 (*in many cases below, the thing is not even mcode, so we do nothing*)
514 Ast.FullTypeTag(ft) -> fullType ft
515 | Ast.BaseTypeTag(bt) -> option_default
516 | Ast.StructUnionTag(su) -> option_default
517 | Ast.SignTag(sgn) -> option_default
518 | Ast.IdentTag(id) -> ident id
519 | Ast.ExpressionTag(exp) -> expression exp
520 | Ast.ConstantTag(cst) -> option_default
521 | Ast.UnaryOpTag(unop) -> option_default
522 | Ast.AssignOpTag(asgnop) -> option_default
523 | Ast.FixOpTag(fixop) -> option_default
524 | Ast.BinaryOpTag(binop) -> option_default
525 | Ast.ArithOpTag(arithop) -> option_default
526 | Ast.LogicalOpTag(logop) -> option_default
527 | Ast.DeclarationTag(decl) -> declaration decl
528 | Ast.InitTag(ini) -> initialiser ini
529 | Ast.StorageTag(stg) -> option_default
530 | Ast.IncFileTag(stg) -> option_default
531 | Ast.Rule_elemTag(rule) -> rule_elem rule
532 | Ast.StatementTag(rule) -> statement rule
533 | Ast.CaseLineTag(case) -> case_line case
534 | Ast.ConstVolTag(cv) -> option_default
535 | Ast.Token(tok,info) -> option_default
0708f913 536 | Ast.Pragma(str) -> option_default
34e49164
C
537 | Ast.Code(cd) -> top_level cd
538 | Ast.ExprDotsTag(ed) -> expression_dots ed
539 | Ast.ParamDotsTag(pd) -> parameter_dots pd
540 | Ast.StmtDotsTag(sd) -> statement_dots sd
541 | Ast.DeclDotsTag(sd) -> declaration_dots sd
542 | Ast.TypeCTag(ty) -> typeC ty
543 | Ast.ParamTag(param) -> parameterTypeDef param
544 | Ast.SgrepStartTag(tok) -> option_default
545 | Ast.SgrepEndTag(tok) -> option_default in
546 anyfn all_functions k a
547
548 and all_functions =
549 {combiner_ident = ident;
550 combiner_expression = expression;
551 combiner_fullType = fullType;
552 combiner_typeC = typeC;
553 combiner_declaration = declaration;
554 combiner_initialiser = initialiser;
555 combiner_parameter = parameterTypeDef;
556 combiner_parameter_list = parameter_dots;
557 combiner_rule_elem = rule_elem;
558 combiner_statement = statement;
559 combiner_case_line = case_line;
560 combiner_top_level = top_level;
561 combiner_anything = anything;
562 combiner_expression_dots = expression_dots;
563 combiner_statement_dots = statement_dots;
564 combiner_declaration_dots = declaration_dots} in
565 all_functions
566
567(* ---------------------------------------------------------------------- *)
568
569type 'a inout = 'a -> 'a (* for specifying the type of rebuilder *)
570
571type rebuilder =
572 {rebuilder_ident : Ast.ident inout;
573 rebuilder_expression : Ast.expression inout;
574 rebuilder_fullType : Ast.fullType inout;
575 rebuilder_typeC : Ast.typeC inout;
576 rebuilder_declaration : Ast.declaration inout;
577 rebuilder_initialiser : Ast.initialiser inout;
578 rebuilder_parameter : Ast.parameterTypeDef inout;
579 rebuilder_parameter_list : Ast.parameter_list inout;
580 rebuilder_statement : Ast.statement inout;
581 rebuilder_case_line : Ast.case_line inout;
582 rebuilder_rule_elem : Ast.rule_elem inout;
583 rebuilder_top_level : Ast.top_level inout;
584 rebuilder_expression_dots : Ast.expression Ast.dots inout;
585 rebuilder_statement_dots : Ast.statement Ast.dots inout;
586 rebuilder_declaration_dots : Ast.declaration Ast.dots inout;
587 rebuilder_define_param_dots : Ast.define_param Ast.dots inout;
588 rebuilder_define_param : Ast.define_param inout;
589 rebuilder_define_parameters : Ast.define_parameters inout;
590 rebuilder_anything : Ast.anything inout}
591
592type 'mc rmcode = 'mc Ast.mcode inout
593type 'cd rcode = rebuilder -> ('cd inout) -> 'cd inout
594
595
596let rebuilder
597 meta_mcode string_mcode const_mcode assign_mcode fix_mcode unary_mcode
faf9a90c 598 binary_mcode cv_mcode sign_mcode struct_mcode storage_mcode
34e49164
C
599 inc_file_mcode
600 expdotsfn paramdotsfn stmtdotsfn decldotsfn
601 identfn exprfn ftfn tyfn initfn paramfn declfn rulefn stmtfn casefn
602 topfn anyfn =
603 let get_option f = function
604 Some x -> Some (f x)
605 | None -> None in
606 let rec expression_dots d =
607 let k d =
608 Ast.rewrap d
609 (match Ast.unwrap d with
610 Ast.DOTS(l) -> Ast.DOTS(List.map expression l)
611 | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map expression l)
612 | Ast.STARS(l) -> Ast.STARS(List.map expression l)) in
613 expdotsfn all_functions k d
614
615 and parameter_dots d =
616 let k d =
617 Ast.rewrap d
618 (match Ast.unwrap d with
619 Ast.DOTS(l) -> Ast.DOTS(List.map parameterTypeDef l)
620 | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map parameterTypeDef l)
621 | Ast.STARS(l) -> Ast.STARS(List.map parameterTypeDef l)) in
622 paramdotsfn all_functions k d
623
624 and statement_dots d =
625 let k d =
626 Ast.rewrap d
627 (match Ast.unwrap d with
628 Ast.DOTS(l) -> Ast.DOTS(List.map statement l)
629 | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map statement l)
630 | Ast.STARS(l) -> Ast.STARS(List.map statement l)) in
631 stmtdotsfn all_functions k d
632
633 and declaration_dots d =
634 let k d =
635 Ast.rewrap d
636 (match Ast.unwrap d with
637 Ast.DOTS(l) -> Ast.DOTS(List.map declaration l)
638 | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map declaration l)
639 | Ast.STARS(l) -> Ast.STARS(List.map declaration l)) in
640 decldotsfn all_functions k d
641
642 and ident i =
643 let k i =
644 Ast.rewrap i
645 (match Ast.unwrap i with
646 Ast.Id(name) -> Ast.Id(string_mcode name)
647 | Ast.MetaId(name,constraints,keep,inherited) ->
648 Ast.MetaId(meta_mcode name,constraints,keep,inherited)
649 | Ast.MetaFunc(name,constraints,keep,inherited) ->
650 Ast.MetaFunc(meta_mcode name,constraints,keep,inherited)
651 | Ast.MetaLocalFunc(name,constraints,keep,inherited) ->
652 Ast.MetaLocalFunc(meta_mcode name,constraints,keep,inherited)
653 | Ast.OptIdent(id) -> Ast.OptIdent(ident id)
654 | Ast.UniqueIdent(id) -> Ast.UniqueIdent(ident id)) in
655 identfn all_functions k i
faf9a90c 656
34e49164
C
657 and expression e =
658 let k e =
659 Ast.rewrap e
660 (match Ast.unwrap e with
661 Ast.Ident(id) -> Ast.Ident(ident id)
662 | Ast.Constant(const) -> Ast.Constant(const_mcode const)
663 | Ast.FunCall(fn,lp,args,rp) ->
664 Ast.FunCall(expression fn, string_mcode lp, expression_dots args,
665 string_mcode rp)
666 | Ast.Assignment(left,op,right,simple) ->
667 Ast.Assignment(expression left, assign_mcode op, expression right,
668 simple)
669 | Ast.CondExpr(exp1,why,exp2,colon,exp3) ->
670 Ast.CondExpr(expression exp1, string_mcode why,
671 get_option expression exp2, string_mcode colon,
672 expression exp3)
673 | Ast.Postfix(exp,op) -> Ast.Postfix(expression exp,fix_mcode op)
674 | Ast.Infix(exp,op) -> Ast.Infix(expression exp,fix_mcode op)
675 | Ast.Unary(exp,op) -> Ast.Unary(expression exp,unary_mcode op)
676 | Ast.Binary(left,op,right) ->
677 Ast.Binary(expression left, binary_mcode op, expression right)
678 | Ast.Nested(left,op,right) ->
679 Ast.Nested(expression left, binary_mcode op, expression right)
680 | Ast.Paren(lp,exp,rp) ->
681 Ast.Paren(string_mcode lp, expression exp, string_mcode rp)
682 | Ast.ArrayAccess(exp1,lb,exp2,rb) ->
683 Ast.ArrayAccess(expression exp1, string_mcode lb, expression exp2,
684 string_mcode rb)
685 | Ast.RecordAccess(exp,pt,field) ->
686 Ast.RecordAccess(expression exp, string_mcode pt, ident field)
687 | Ast.RecordPtAccess(exp,ar,field) ->
688 Ast.RecordPtAccess(expression exp, string_mcode ar, ident field)
689 | Ast.Cast(lp,ty,rp,exp) ->
690 Ast.Cast(string_mcode lp, fullType ty, string_mcode rp,
691 expression exp)
692 | Ast.SizeOfExpr(szf,exp) ->
693 Ast.SizeOfExpr(string_mcode szf, expression exp)
694 | Ast.SizeOfType(szf,lp,ty,rp) ->
faf9a90c 695 Ast.SizeOfType(string_mcode szf,string_mcode lp, fullType ty,
34e49164
C
696 string_mcode rp)
697 | Ast.TypeExp(ty) -> Ast.TypeExp(fullType ty)
698 | Ast.MetaErr(name,constraints,keep,inherited) ->
699 Ast.MetaErr(meta_mcode name,constraints,keep,inherited)
700 | Ast.MetaExpr(name,constraints,keep,ty,form,inherited) ->
701 Ast.MetaExpr(meta_mcode name,constraints,keep,ty,form,inherited)
702 | Ast.MetaExprList(name,lenname_inh,keep,inherited) ->
703 Ast.MetaExprList(meta_mcode name,lenname_inh,keep,inherited)
704 | Ast.EComma(cm) -> Ast.EComma(string_mcode cm)
705 | Ast.DisjExpr(exp_list) -> Ast.DisjExpr(List.map expression exp_list)
5636bb2c
C
706 | Ast.NestExpr(starter,expr_dots,ender,whencode,multi) ->
707 Ast.NestExpr(string_mcode starter,expression_dots expr_dots,
708 string_mcode ender,
34e49164
C
709 get_option expression whencode,multi)
710 | Ast.Edots(dots,whencode) ->
711 Ast.Edots(string_mcode dots,get_option expression whencode)
712 | Ast.Ecircles(dots,whencode) ->
713 Ast.Ecircles(string_mcode dots,get_option expression whencode)
714 | Ast.Estars(dots,whencode) ->
715 Ast.Estars(string_mcode dots,get_option expression whencode)
716 | Ast.OptExp(exp) -> Ast.OptExp(expression exp)
717 | Ast.UniqueExp(exp) -> Ast.UniqueExp(expression exp)) in
718 exprfn all_functions k e
faf9a90c 719
34e49164
C
720 and fullType ft =
721 let k ft =
722 Ast.rewrap ft
723 (match Ast.unwrap ft with
724 Ast.Type(cv,ty) -> Ast.Type (get_option cv_mcode cv, typeC ty)
725 | Ast.DisjType(types) -> Ast.DisjType(List.map fullType types)
726 | Ast.OptType(ty) -> Ast.OptType(fullType ty)
727 | Ast.UniqueType(ty) -> Ast.UniqueType(fullType ty)) in
728 ftfn all_functions k ft
faf9a90c 729
34e49164
C
730 and typeC ty =
731 let k ty =
732 Ast.rewrap ty
733 (match Ast.unwrap ty with
faf9a90c
C
734 Ast.BaseType(ty,strings) ->
735 Ast.BaseType (ty, List.map string_mcode strings)
736 | Ast.SignedT(sgn,ty) ->
737 Ast.SignedT(sign_mcode sgn,get_option typeC ty)
34e49164
C
738 | Ast.Pointer(ty,star) ->
739 Ast.Pointer (fullType ty, string_mcode star)
740 | Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
741 Ast.FunctionPointer(fullType ty,string_mcode lp1,string_mcode star,
742 string_mcode rp1,string_mcode lp2,
743 parameter_dots params,
744 string_mcode rp2)
745 | Ast.FunctionType(allminus,ty,lp,params,rp) ->
746 Ast.FunctionType(allminus,get_option fullType ty,string_mcode lp,
747 parameter_dots params,string_mcode rp)
748 | Ast.Array(ty,lb,size,rb) ->
749 Ast.Array(fullType ty, string_mcode lb,
750 get_option expression size, string_mcode rb)
faf9a90c
C
751 | Ast.EnumName(kind,name) ->
752 Ast.EnumName(string_mcode kind, ident name)
34e49164
C
753 | Ast.StructUnionName(kind,name) ->
754 Ast.StructUnionName (struct_mcode kind, get_option ident name)
755 | Ast.StructUnionDef(ty,lb,decls,rb) ->
756 Ast.StructUnionDef (fullType ty,
757 string_mcode lb, declaration_dots decls,
758 string_mcode rb)
759 | Ast.TypeName(name) -> Ast.TypeName(string_mcode name)
760 | Ast.MetaType(name,keep,inherited) ->
761 Ast.MetaType(meta_mcode name,keep,inherited)) in
762 tyfn all_functions k ty
faf9a90c 763
34e49164
C
764 and declaration d =
765 let k d =
766 Ast.rewrap d
767 (match Ast.unwrap d with
768 Ast.Init(stg,ty,id,eq,ini,sem) ->
769 Ast.Init(get_option storage_mcode stg, fullType ty, ident id,
770 string_mcode eq, initialiser ini, string_mcode sem)
771 | Ast.UnInit(stg,ty,id,sem) ->
772 Ast.UnInit(get_option storage_mcode stg, fullType ty, ident id,
773 string_mcode sem)
774 | Ast.MacroDecl(name,lp,args,rp,sem) ->
775 Ast.MacroDecl(ident name, string_mcode lp, expression_dots args,
776 string_mcode rp,string_mcode sem)
777 | Ast.TyDecl(ty,sem) -> Ast.TyDecl(fullType ty, string_mcode sem)
778 | Ast.Typedef(stg,ty,id,sem) ->
779 Ast.Typedef(string_mcode stg, fullType ty, typeC id,
780 string_mcode sem)
781 | Ast.DisjDecl(decls) -> Ast.DisjDecl(List.map declaration decls)
782 | Ast.Ddots(dots,whencode) ->
783 Ast.Ddots(string_mcode dots, get_option declaration whencode)
784 | Ast.MetaDecl(name,keep,inherited) ->
785 Ast.MetaDecl(meta_mcode name,keep,inherited)
786 | Ast.OptDecl(decl) -> Ast.OptDecl(declaration decl)
787 | Ast.UniqueDecl(decl) -> Ast.UniqueDecl(declaration decl)) in
788 declfn all_functions k d
789
790 and initialiser i =
791 let k i =
792 Ast.rewrap i
793 (match Ast.unwrap i with
113803cf
C
794 Ast.MetaInit(name,keep,inherited) ->
795 Ast.MetaInit(meta_mcode name,keep,inherited)
796 | Ast.InitExpr(exp) -> Ast.InitExpr(expression exp)
34e49164
C
797 | Ast.InitList(lb,initlist,rb,whencode) ->
798 Ast.InitList(string_mcode lb, List.map initialiser initlist,
799 string_mcode rb, List.map initialiser whencode)
34e49164
C
800 | Ast.InitGccName(name,eq,ini) ->
801 Ast.InitGccName(ident name, string_mcode eq, initialiser ini)
113803cf
C
802 | Ast.InitGccExt(designators,eq,ini) ->
803 Ast.InitGccExt
804 (List.map designator designators, string_mcode eq,
34e49164
C
805 initialiser ini)
806 | Ast.IComma(cm) -> Ast.IComma(string_mcode cm)
807 | Ast.OptIni(i) -> Ast.OptIni(initialiser i)
808 | Ast.UniqueIni(i) -> Ast.UniqueIni(initialiser i)) in
809 initfn all_functions k i
faf9a90c 810
113803cf
C
811 and designator = function
812 Ast.DesignatorField(dot,id) ->
813 Ast.DesignatorField(string_mcode dot,ident id)
814 | Ast.DesignatorIndex(lb,exp,rb) ->
815 Ast.DesignatorIndex(string_mcode lb,expression exp,string_mcode rb)
816 | Ast.DesignatorRange(lb,min,dots,max,rb) ->
817 Ast.DesignatorRange(string_mcode lb,expression min,string_mcode dots,
818 expression max,string_mcode rb)
819
34e49164
C
820 and parameterTypeDef p =
821 let k p =
822 Ast.rewrap p
823 (match Ast.unwrap p with
824 Ast.VoidParam(ty) -> Ast.VoidParam(fullType ty)
825 | Ast.Param(ty,id) -> Ast.Param(fullType ty, get_option ident id)
826 | Ast.MetaParam(name,keep,inherited) ->
827 Ast.MetaParam(meta_mcode name,keep,inherited)
828 | Ast.MetaParamList(name,lenname_inh,keep,inherited) ->
829 Ast.MetaParamList(meta_mcode name,lenname_inh,keep,inherited)
830 | Ast.PComma(cm) -> Ast.PComma(string_mcode cm)
831 | Ast.Pdots(dots) -> Ast.Pdots(string_mcode dots)
832 | Ast.Pcircles(dots) -> Ast.Pcircles(string_mcode dots)
833 | Ast.OptParam(param) -> Ast.OptParam(parameterTypeDef param)
834 | Ast.UniqueParam(param) -> Ast.UniqueParam(parameterTypeDef param)) in
835 paramfn all_functions k p
836
837 and rule_elem re =
838 let k re =
839 Ast.rewrap re
840 (match Ast.unwrap re with
841 Ast.FunHeader(bef,allminus,fi,name,lp,params,rp) ->
842 Ast.FunHeader(bef,allminus,List.map fninfo fi,ident name,
843 string_mcode lp, parameter_dots params,
844 string_mcode rp)
845 | Ast.Decl(bef,allminus,decl) ->
846 Ast.Decl(bef,allminus,declaration decl)
847 | Ast.SeqStart(brace) -> Ast.SeqStart(string_mcode brace)
848 | Ast.SeqEnd(brace) -> Ast.SeqEnd(string_mcode brace)
849 | Ast.ExprStatement(exp,sem) ->
850 Ast.ExprStatement (expression exp, string_mcode sem)
851 | Ast.IfHeader(iff,lp,exp,rp) ->
852 Ast.IfHeader(string_mcode iff, string_mcode lp, expression exp,
853 string_mcode rp)
854 | Ast.Else(els) -> Ast.Else(string_mcode els)
855 | Ast.WhileHeader(whl,lp,exp,rp) ->
faf9a90c 856 Ast.WhileHeader(string_mcode whl, string_mcode lp, expression exp,
34e49164
C
857 string_mcode rp)
858 | Ast.DoHeader(d) -> Ast.DoHeader(string_mcode d)
859 | Ast.WhileTail(whl,lp,exp,rp,sem) ->
faf9a90c 860 Ast.WhileTail(string_mcode whl, string_mcode lp, expression exp,
34e49164
C
861 string_mcode rp, string_mcode sem)
862 | Ast.ForHeader(fr,lp,e1,sem1,e2,sem2,e3,rp) ->
faf9a90c
C
863 Ast.ForHeader(string_mcode fr, string_mcode lp,
864 get_option expression e1, string_mcode sem1,
865 get_option expression e2, string_mcode sem2,
34e49164
C
866 get_option expression e3, string_mcode rp)
867 | Ast.IteratorHeader(whl,lp,args,rp) ->
868 Ast.IteratorHeader(ident whl, string_mcode lp,
869 expression_dots args, string_mcode rp)
870 | Ast.SwitchHeader(switch,lp,exp,rp) ->
871 Ast.SwitchHeader(string_mcode switch, string_mcode lp,
872 expression exp, string_mcode rp)
873 | Ast.Break(br,sem) ->
874 Ast.Break(string_mcode br, string_mcode sem)
875 | Ast.Continue(cont,sem) ->
876 Ast.Continue(string_mcode cont, string_mcode sem)
877 | Ast.Label(l,dd) -> Ast.Label(ident l, string_mcode dd)
878 | Ast.Goto(goto,l,sem) ->
879 Ast.Goto(string_mcode goto,ident l,string_mcode sem)
880 | Ast.Return(ret,sem) ->
881 Ast.Return(string_mcode ret, string_mcode sem)
882 | Ast.ReturnExpr(ret,exp,sem) ->
883 Ast.ReturnExpr(string_mcode ret, expression exp, string_mcode sem)
884 | Ast.MetaStmt(name,keep,seqible,inherited) ->
885 Ast.MetaStmt(meta_mcode name,keep,seqible,inherited)
886 | Ast.MetaStmtList(name,keep,inherited) ->
887 Ast.MetaStmtList(meta_mcode name,keep,inherited)
888 | Ast.MetaRuleElem(name,keep,inherited) ->
889 Ast.MetaRuleElem(meta_mcode name,keep,inherited)
890 | Ast.Exp(exp) -> Ast.Exp(expression exp)
891 | Ast.TopExp(exp) -> Ast.TopExp(expression exp)
892 | Ast.Ty(ty) -> Ast.Ty(fullType ty)
1be43e12 893 | Ast.TopInit(init) -> Ast.TopInit(initialiser init)
34e49164
C
894 | Ast.Include(inc,name) ->
895 Ast.Include(string_mcode inc,inc_file_mcode name)
896 | Ast.DefineHeader(def,id,params) ->
897 Ast.DefineHeader(string_mcode def,ident id,
898 define_parameters params)
899 | Ast.Default(def,colon) ->
900 Ast.Default(string_mcode def,string_mcode colon)
901 | Ast.Case(case,exp,colon) ->
902 Ast.Case(string_mcode case,expression exp,string_mcode colon)
903 | Ast.DisjRuleElem(res) -> Ast.DisjRuleElem(List.map rule_elem res)) in
904 rulefn all_functions k re
905
906 (* not parameterizable for now... *)
907 and define_parameters p =
908 let k p =
909 Ast.rewrap p
910 (match Ast.unwrap p with
911 Ast.NoParams -> Ast.NoParams
912 | Ast.DParams(lp,params,rp) ->
913 Ast.DParams(string_mcode lp,define_param_dots params,
914 string_mcode rp)) in
915 k p
916
917 and define_param_dots d =
918 let k d =
919 Ast.rewrap d
920 (match Ast.unwrap d with
921 Ast.DOTS(l) -> Ast.DOTS(List.map define_param l)
922 | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map define_param l)
923 | Ast.STARS(l) -> Ast.STARS(List.map define_param l)) in
924 k d
925
926 and define_param p =
927 let k p =
928 Ast.rewrap p
929 (match Ast.unwrap p with
930 Ast.DParam(id) -> Ast.DParam(ident id)
931 | Ast.DPComma(comma) -> Ast.DPComma(string_mcode comma)
932 | Ast.DPdots(d) -> Ast.DPdots(string_mcode d)
933 | Ast.DPcircles(c) -> Ast.DPcircles(string_mcode c)
934 | Ast.OptDParam(dp) -> Ast.OptDParam(define_param dp)
935 | Ast.UniqueDParam(dp) -> Ast.UniqueDParam(define_param dp)) in
936 k p
937
938 and process_bef_aft s =
939 Ast.set_dots_bef_aft
940 (match Ast.get_dots_bef_aft s with
941 Ast.NoDots -> Ast.NoDots
942 | Ast.DroppingBetweenDots(stm,ind) ->
943 Ast.DroppingBetweenDots(statement stm,ind)
944 | Ast.AddingBetweenDots(stm,ind) ->
945 Ast.AddingBetweenDots(statement stm,ind))
946 s
947
948 and statement s =
949 let k s =
950 Ast.rewrap s
951 (match Ast.unwrap s with
708f4980
C
952 Ast.Seq(lbrace,body,rbrace) ->
953 Ast.Seq(rule_elem lbrace,
34e49164
C
954 statement_dots body, rule_elem rbrace)
955 | Ast.IfThen(header,branch,aft) ->
956 Ast.IfThen(rule_elem header, statement branch,aft)
957 | Ast.IfThenElse(header,branch1,els,branch2,aft) ->
958 Ast.IfThenElse(rule_elem header, statement branch1, rule_elem els,
959 statement branch2, aft)
960 | Ast.While(header,body,aft) ->
961 Ast.While(rule_elem header, statement body, aft)
962 | Ast.Do(header,body,tail) ->
963 Ast.Do(rule_elem header, statement body, rule_elem tail)
964 | Ast.For(header,body,aft) ->
965 Ast.For(rule_elem header, statement body, aft)
966 | Ast.Iterator(header,body,aft) ->
967 Ast.Iterator(rule_elem header, statement body, aft)
fc1ad971 968 | Ast.Switch(header,lb,decls,cases,rb) ->
34e49164 969 Ast.Switch(rule_elem header,rule_elem lb,
fc1ad971 970 statement_dots decls,
34e49164
C
971 List.map case_line cases,rule_elem rb)
972 | Ast.Atomic(re) -> Ast.Atomic(rule_elem re)
973 | Ast.Disj(stmt_dots_list) ->
974 Ast.Disj (List.map statement_dots stmt_dots_list)
5636bb2c
C
975 | Ast.Nest(starter,stmt_dots,ender,whn,multi,bef,aft) ->
976 Ast.Nest(string_mcode starter,statement_dots stmt_dots,
977 string_mcode ender,
34e49164
C
978 List.map (whencode statement_dots statement) whn,
979 multi,bef,aft)
708f4980 980 | Ast.FunDecl(header,lbrace,body,rbrace) ->
34e49164 981 Ast.FunDecl(rule_elem header,rule_elem lbrace,
34e49164
C
982 statement_dots body, rule_elem rbrace)
983 | Ast.Define(header,body) ->
984 Ast.Define(rule_elem header,statement_dots body)
985 | Ast.Dots(d,whn,bef,aft) ->
986 Ast.Dots(string_mcode d,
987 List.map (whencode statement_dots statement) whn,bef,aft)
988 | Ast.Circles(d,whn,bef,aft) ->
989 Ast.Circles(string_mcode d,
990 List.map (whencode statement_dots statement) whn,
991 bef,aft)
992 | Ast.Stars(d,whn,bef,aft) ->
993 Ast.Stars(string_mcode d,
994 List.map (whencode statement_dots statement) whn,bef,aft)
995 | Ast.OptStm(stmt) -> Ast.OptStm(statement stmt)
996 | Ast.UniqueStm(stmt) -> Ast.UniqueStm(statement stmt)) in
997 let s = stmtfn all_functions k s in
998 (* better to do this after, in case there is an equality test on the whole
999 statement, eg in free_vars. equality test would require that this
1000 subterm not already be changed *)
1001 process_bef_aft s
1002
1003 and fninfo = function
1004 Ast.FStorage(stg) -> Ast.FStorage(storage_mcode stg)
1005 | Ast.FType(ty) -> Ast.FType(fullType ty)
1006 | Ast.FInline(inline) -> Ast.FInline(string_mcode inline)
1007 | Ast.FAttr(attr) -> Ast.FAttr(string_mcode attr)
1008
1009 and whencode notfn alwaysfn = function
1010 Ast.WhenNot a -> Ast.WhenNot (notfn a)
1011 | Ast.WhenAlways a -> Ast.WhenAlways (alwaysfn a)
1012 | Ast.WhenModifier(x) -> Ast.WhenModifier(x)
1be43e12
C
1013 | Ast.WhenNotTrue(e) -> Ast.WhenNotTrue(rule_elem e)
1014 | Ast.WhenNotFalse(e) -> Ast.WhenNotFalse(rule_elem e)
34e49164
C
1015
1016 and case_line c =
1017 let k c =
1018 Ast.rewrap c
1019 (match Ast.unwrap c with
1020 Ast.CaseLine(header,code) ->
1021 Ast.CaseLine(rule_elem header,statement_dots code)
1022 | Ast.OptCase(case) -> Ast.OptCase(case_line case)) in
1023 casefn all_functions k c
1024
1025 and top_level t =
1026 let k t =
1027 Ast.rewrap t
1028 (match Ast.unwrap t with
1029 Ast.FILEINFO(old_file,new_file) ->
1030 Ast.FILEINFO (string_mcode old_file, string_mcode new_file)
1031 | Ast.DECL(stmt) -> Ast.DECL(statement stmt)
1032 | Ast.CODE(stmt_dots) -> Ast.CODE(statement_dots stmt_dots)
1033 | Ast.ERRORWORDS(exps) -> Ast.ERRORWORDS (List.map expression exps)) in
1034 topfn all_functions k t
1035
1036 and anything a =
1037 let k = function
1038 (*in many cases below, the thing is not even mcode, so we do nothing*)
1039 Ast.FullTypeTag(ft) -> Ast.FullTypeTag(fullType ft)
1040 | Ast.BaseTypeTag(bt) as x -> x
1041 | Ast.StructUnionTag(su) as x -> x
1042 | Ast.SignTag(sgn) as x -> x
1043 | Ast.IdentTag(id) -> Ast.IdentTag(ident id)
1044 | Ast.ExpressionTag(exp) -> Ast.ExpressionTag(expression exp)
1045 | Ast.ConstantTag(cst) as x -> x
1046 | Ast.UnaryOpTag(unop) as x -> x
1047 | Ast.AssignOpTag(asgnop) as x -> x
1048 | Ast.FixOpTag(fixop) as x -> x
1049 | Ast.BinaryOpTag(binop) as x -> x
1050 | Ast.ArithOpTag(arithop) as x -> x
1051 | Ast.LogicalOpTag(logop) as x -> x
1052 | Ast.InitTag(decl) -> Ast.InitTag(initialiser decl)
1053 | Ast.DeclarationTag(decl) -> Ast.DeclarationTag(declaration decl)
1054 | Ast.StorageTag(stg) as x -> x
1055 | Ast.IncFileTag(stg) as x -> x
1056 | Ast.Rule_elemTag(rule) -> Ast.Rule_elemTag(rule_elem rule)
1057 | Ast.StatementTag(rule) -> Ast.StatementTag(statement rule)
1058 | Ast.CaseLineTag(case) -> Ast.CaseLineTag(case_line case)
1059 | Ast.ConstVolTag(cv) as x -> x
1060 | Ast.Token(tok,info) as x -> x
0708f913 1061 | Ast.Pragma(str) as x -> x
34e49164
C
1062 | Ast.Code(cd) -> Ast.Code(top_level cd)
1063 | Ast.ExprDotsTag(ed) -> Ast.ExprDotsTag(expression_dots ed)
1064 | Ast.ParamDotsTag(pd) -> Ast.ParamDotsTag(parameter_dots pd)
1065 | Ast.StmtDotsTag(sd) -> Ast.StmtDotsTag(statement_dots sd)
1066 | Ast.DeclDotsTag(sd) -> Ast.DeclDotsTag(declaration_dots sd)
1067 | Ast.TypeCTag(ty) -> Ast.TypeCTag(typeC ty)
1068 | Ast.ParamTag(param) -> Ast.ParamTag(parameterTypeDef param)
1069 | Ast.SgrepStartTag(tok) as x -> x
1070 | Ast.SgrepEndTag(tok) as x -> x in
1071 anyfn all_functions k a
1072
1073 and all_functions =
1074 {rebuilder_ident = ident;
1075 rebuilder_expression = expression;
ae4735db 1076 rebuilder_fullType = fullType;
34e49164
C
1077 rebuilder_typeC = typeC;
1078 rebuilder_declaration = declaration;
1079 rebuilder_initialiser = initialiser;
1080 rebuilder_parameter = parameterTypeDef;
1081 rebuilder_parameter_list = parameter_dots;
1082 rebuilder_rule_elem = rule_elem;
1083 rebuilder_statement = statement;
1084 rebuilder_case_line = case_line;
1085 rebuilder_top_level = top_level;
1086 rebuilder_expression_dots = expression_dots;
1087 rebuilder_statement_dots = statement_dots;
1088 rebuilder_declaration_dots = declaration_dots;
1089 rebuilder_define_param_dots = define_param_dots;
1090 rebuilder_define_param = define_param;
1091 rebuilder_define_parameters = define_parameters;
1092 rebuilder_anything = anything} in
1093 all_functions
1094