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