Commit | Line | Data |
---|---|---|
34e49164 C |
1 | (* |
2 | * Copyright 2005-2008, 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 | (* Arities matter for the minus slice, but not for the plus slice. *) | |
24 | ||
25 | (* + only allowed on code in a nest (in_nest = true). ? only allowed on | |
26 | rule_elems, and on subterms if the context is ? also. *) | |
27 | ||
28 | module Ast0 = Ast0_cocci | |
29 | module Ast = Ast_cocci | |
30 | module V0 = Visitor_ast0 | |
31 | module V = Visitor_ast | |
32 | ||
33 | let unitary = Type_cocci.Unitary | |
34 | ||
35 | let ctr = ref 0 | |
36 | let get_ctr _ = | |
37 | let c = !ctr in | |
38 | ctr := !ctr + 1; | |
39 | c | |
40 | ||
41 | (* --------------------------------------------------------------------- *) | |
42 | (* Move plus tokens from the MINUS and CONTEXT structured nodes to the | |
43 | corresponding leftmost and rightmost mcodes *) | |
44 | ||
45 | let inline_mcodes = | |
46 | let bind x y = () in | |
47 | let option_default = () in | |
48 | let mcode _ = () in | |
49 | let do_nothing r k e = | |
50 | k e; | |
51 | let einfo = Ast0.get_info e in | |
52 | match (Ast0.get_mcodekind e) with | |
53 | Ast0.MINUS(replacements) -> | |
54 | (match !replacements with | |
55 | ([],_) -> () | |
56 | | replacements -> | |
57 | let minus_try = function | |
58 | (true,mc) -> | |
59 | if List.for_all | |
60 | (function | |
61 | Ast0.MINUS(mreplacements) -> true | _ -> false) | |
62 | mc | |
63 | then | |
64 | (List.iter | |
65 | (function | |
66 | Ast0.MINUS(mreplacements) -> | |
67 | mreplacements := replacements | |
68 | | _ -> ()) | |
69 | mc; | |
70 | true) | |
71 | else false | |
72 | | _ -> false in | |
73 | if not (minus_try(einfo.Ast0.attachable_start, | |
74 | einfo.Ast0.mcode_start) | |
75 | or | |
76 | minus_try(einfo.Ast0.attachable_end, | |
77 | einfo.Ast0.mcode_end)) | |
78 | then | |
79 | failwith "minus tree should not have bad code on both sides") | |
80 | | Ast0.CONTEXT(befaft) | |
81 | | Ast0.MIXED(befaft) -> | |
82 | let concat starter startinfo ender endinfo = | |
83 | let lst = | |
84 | match (starter,ender) with | |
85 | ([],_) -> ender | |
86 | | (_,[]) -> starter | |
87 | | _ -> | |
88 | if startinfo.Ast0.tline_end = endinfo.Ast0.tline_start | |
89 | then (* put them in the same inner list *) | |
90 | let last = List.hd (List.rev starter) in | |
91 | let butlast = List.rev(List.tl(List.rev starter)) in | |
92 | butlast @ (last@(List.hd ender)) :: (List.tl ender) | |
93 | else starter @ ender in | |
94 | (lst, | |
95 | {endinfo with Ast0.tline_start = startinfo.Ast0.tline_start}) in | |
96 | let attach_bef bef beforeinfo = function | |
97 | (true,mcl) -> | |
98 | List.iter | |
99 | (function | |
100 | Ast0.MINUS(mreplacements) -> | |
101 | let (mrepl,tokeninfo) = !mreplacements in | |
102 | mreplacements := concat bef beforeinfo mrepl tokeninfo | |
103 | | Ast0.CONTEXT(mbefaft) -> | |
104 | (match !mbefaft with | |
105 | (Ast.BEFORE(mbef),mbeforeinfo,a) -> | |
106 | let (newbef,newinfo) = | |
107 | concat bef beforeinfo mbef mbeforeinfo in | |
108 | mbefaft := (Ast.BEFORE(newbef),newinfo,a) | |
109 | | (Ast.AFTER(maft),_,a) -> | |
110 | mbefaft := | |
111 | (Ast.BEFOREAFTER(bef,maft),beforeinfo,a) | |
112 | | (Ast.BEFOREAFTER(mbef,maft),mbeforeinfo,a) -> | |
113 | let (newbef,newinfo) = | |
114 | concat bef beforeinfo mbef mbeforeinfo in | |
115 | mbefaft := | |
116 | (Ast.BEFOREAFTER(newbef,maft),newinfo,a) | |
117 | | (Ast.NOTHING,_,a) -> | |
118 | mbefaft := (Ast.BEFORE(bef),beforeinfo,a)) | |
119 | | _ -> failwith "unexpected annotation") | |
120 | mcl | |
121 | | _ -> | |
122 | failwith | |
123 | "context tree should not have bad code on both sides" in | |
124 | let attach_aft aft afterinfo = function | |
125 | (true,mcl) -> | |
126 | List.iter | |
127 | (function | |
128 | Ast0.MINUS(mreplacements) -> | |
129 | let (mrepl,tokeninfo) = !mreplacements in | |
130 | mreplacements := concat mrepl tokeninfo aft afterinfo | |
131 | | Ast0.CONTEXT(mbefaft) -> | |
132 | (match !mbefaft with | |
133 | (Ast.BEFORE(mbef),b,_) -> | |
134 | mbefaft := | |
135 | (Ast.BEFOREAFTER(mbef,aft),b,afterinfo) | |
136 | | (Ast.AFTER(maft),b,mafterinfo) -> | |
137 | let (newaft,newinfo) = | |
138 | concat maft mafterinfo aft afterinfo in | |
139 | mbefaft := (Ast.AFTER(newaft),b,newinfo) | |
140 | | (Ast.BEFOREAFTER(mbef,maft),b,mafterinfo) -> | |
141 | let (newaft,newinfo) = | |
142 | concat maft mafterinfo aft afterinfo in | |
143 | mbefaft := | |
144 | (Ast.BEFOREAFTER(mbef,newaft),b,newinfo) | |
145 | | (Ast.NOTHING,b,_) -> | |
146 | mbefaft := (Ast.AFTER(aft),b,afterinfo)) | |
147 | | _ -> failwith "unexpected annotation") | |
148 | mcl | |
149 | | _ -> | |
150 | failwith | |
151 | "context tree should not have bad code on both sides" in | |
152 | (match !befaft with | |
153 | (Ast.BEFORE(bef),beforeinfo,_) -> | |
154 | attach_bef bef beforeinfo | |
155 | (einfo.Ast0.attachable_start,einfo.Ast0.mcode_start) | |
156 | | (Ast.AFTER(aft),_,afterinfo) -> | |
157 | attach_aft aft afterinfo | |
158 | (einfo.Ast0.attachable_end,einfo.Ast0.mcode_end) | |
159 | | (Ast.BEFOREAFTER(bef,aft),beforeinfo,afterinfo) -> | |
160 | attach_bef bef beforeinfo | |
161 | (einfo.Ast0.attachable_start,einfo.Ast0.mcode_start); | |
162 | attach_aft aft afterinfo | |
163 | (einfo.Ast0.attachable_end,einfo.Ast0.mcode_end) | |
164 | | (Ast.NOTHING,_,_) -> ()) | |
165 | | Ast0.PLUS -> () in | |
166 | V0.combiner bind option_default | |
167 | mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode | |
168 | mcode mcode mcode | |
169 | do_nothing do_nothing do_nothing do_nothing do_nothing do_nothing | |
170 | do_nothing do_nothing do_nothing do_nothing do_nothing do_nothing | |
171 | do_nothing do_nothing do_nothing | |
172 | ||
173 | (* --------------------------------------------------------------------- *) | |
174 | (* For function declarations. Can't use the mcode at the root, because that | |
175 | might be mixed when the function contains ()s, where agglomeration of -s is | |
176 | not possible. *) | |
177 | ||
178 | let check_allminus = | |
179 | let donothing r k e = k e in | |
180 | let bind x y = x && y in | |
181 | let option_default = true in | |
182 | let mcode (_,_,_,mc,_) = | |
183 | match mc with | |
184 | Ast0.MINUS(r) -> let (plusses,_) = !r in plusses = [] | |
185 | | _ -> false in | |
186 | ||
187 | (* special case for disj *) | |
188 | let expression r k e = | |
189 | match Ast0.unwrap e with | |
190 | Ast0.DisjExpr(starter,expr_list,mids,ender) -> | |
191 | List.for_all r.V0.combiner_expression expr_list | |
192 | | _ -> k e in | |
193 | ||
194 | let declaration r k e = | |
195 | match Ast0.unwrap e with | |
196 | Ast0.DisjDecl(starter,decls,mids,ender) -> | |
197 | List.for_all r.V0.combiner_declaration decls | |
198 | | _ -> k e in | |
199 | ||
200 | let typeC r k e = | |
201 | match Ast0.unwrap e with | |
202 | Ast0.DisjType(starter,decls,mids,ender) -> | |
203 | List.for_all r.V0.combiner_typeC decls | |
204 | | _ -> k e in | |
205 | ||
206 | let statement r k e = | |
207 | match Ast0.unwrap e with | |
208 | Ast0.Disj(starter,statement_dots_list,mids,ender) -> | |
209 | List.for_all r.V0.combiner_statement_dots statement_dots_list | |
210 | | _ -> k e in | |
211 | ||
212 | V0.combiner bind option_default | |
213 | mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode | |
214 | mcode mcode mcode | |
215 | donothing donothing donothing donothing donothing donothing | |
216 | donothing expression typeC donothing donothing declaration | |
217 | statement donothing donothing | |
218 | ||
219 | (* --------------------------------------------------------------------- *) | |
220 | (* --------------------------------------------------------------------- *) | |
221 | ||
222 | let get_option fn = function | |
223 | None -> None | |
224 | | Some x -> Some (fn x) | |
225 | ||
226 | (* --------------------------------------------------------------------- *) | |
227 | (* --------------------------------------------------------------------- *) | |
228 | (* Mcode *) | |
229 | ||
230 | let convert_info info = | |
231 | { Ast.line = info.Ast0.line_start; Ast.column = info.Ast0.column; | |
232 | Ast.strbef = info.Ast0.strings_before; | |
233 | Ast.straft = info.Ast0.strings_after; } | |
234 | ||
235 | let convert_mcodekind = function | |
236 | Ast0.MINUS(replacements) -> | |
237 | let (replacements,_) = !replacements in | |
238 | Ast.MINUS(Ast.NoPos,replacements) | |
239 | | Ast0.PLUS -> Ast.PLUS | |
240 | | Ast0.CONTEXT(befaft) -> | |
241 | let (befaft,_,_) = !befaft in Ast.CONTEXT(Ast.NoPos,befaft) | |
242 | | Ast0.MIXED(_) -> failwith "not possible for mcode" | |
243 | ||
244 | let pos_mcode(term,_,info,mcodekind,pos) = | |
245 | (* avoids a recursion problem *) | |
246 | (term,convert_info info,convert_mcodekind mcodekind,Ast.NoMetaPos) | |
247 | ||
248 | let mcode(term,_,info,mcodekind,pos) = | |
249 | let pos = | |
250 | match !pos with | |
251 | Ast0.MetaPos(pos,constraints,per) -> | |
252 | Ast.MetaPos(pos_mcode pos,constraints,per,unitary,false) | |
253 | | _ -> Ast.NoMetaPos in | |
254 | (term,convert_info info,convert_mcodekind mcodekind,pos) | |
255 | ||
256 | (* --------------------------------------------------------------------- *) | |
257 | (* Dots *) | |
258 | let wrap ast line isos = | |
259 | {(Ast.make_term ast) with Ast.node_line = line; | |
260 | Ast.iso_info = isos} | |
261 | ||
262 | let rewrap ast0 isos ast = | |
263 | wrap ast ((Ast0.get_info ast0).Ast0.line_start) isos | |
264 | ||
265 | let no_isos = [] | |
266 | ||
267 | (* no isos on tokens *) | |
268 | let tokenwrap (_,info,_,_) s ast = wrap ast info.Ast.line no_isos | |
269 | let iso_tokenwrap (_,info,_,_) s ast iso = wrap ast info.Ast.line iso | |
270 | ||
271 | let dots fn d = | |
272 | rewrap d no_isos | |
273 | (match Ast0.unwrap d with | |
274 | Ast0.DOTS(x) -> Ast.DOTS(List.map fn x) | |
275 | | Ast0.CIRCLES(x) -> Ast.CIRCLES(List.map fn x) | |
276 | | Ast0.STARS(x) -> Ast.STARS(List.map fn x)) | |
277 | ||
278 | (* --------------------------------------------------------------------- *) | |
279 | (* Identifier *) | |
280 | ||
281 | let rec do_isos l = List.map (function (nm,x) -> (nm,anything x)) l | |
282 | ||
283 | and ident i = | |
284 | rewrap i (do_isos (Ast0.get_iso i)) | |
285 | (match Ast0.unwrap i with | |
286 | Ast0.Id(name) -> Ast.Id(mcode name) | |
287 | | Ast0.MetaId(name,constraints,_) -> | |
288 | let constraints = List.map ident constraints in | |
289 | Ast.MetaId(mcode name,constraints,unitary,false) | |
290 | | Ast0.MetaFunc(name,constraints,_) -> | |
291 | let constraints = List.map ident constraints in | |
292 | Ast.MetaFunc(mcode name,constraints,unitary,false) | |
293 | | Ast0.MetaLocalFunc(name,constraints,_) -> | |
294 | let constraints = List.map ident constraints in | |
295 | Ast.MetaLocalFunc(mcode name,constraints,unitary,false) | |
296 | | Ast0.OptIdent(id) -> Ast.OptIdent(ident id) | |
297 | | Ast0.UniqueIdent(id) -> Ast.UniqueIdent(ident id)) | |
298 | ||
299 | (* --------------------------------------------------------------------- *) | |
300 | (* Expression *) | |
301 | ||
302 | and expression e = | |
303 | let e1 = | |
304 | rewrap e (do_isos (Ast0.get_iso e)) | |
305 | (match Ast0.unwrap e with | |
306 | Ast0.Ident(id) -> Ast.Ident(ident id) | |
307 | | Ast0.Constant(const) -> | |
308 | Ast.Constant(mcode const) | |
309 | | Ast0.FunCall(fn,lp,args,rp) -> | |
310 | let fn = expression fn in | |
311 | let lp = mcode lp in | |
312 | let args = dots expression args in | |
313 | let rp = mcode rp in | |
314 | Ast.FunCall(fn,lp,args,rp) | |
315 | | Ast0.Assignment(left,op,right,simple) -> | |
316 | Ast.Assignment(expression left,mcode op,expression right,simple) | |
317 | | Ast0.CondExpr(exp1,why,exp2,colon,exp3) -> | |
318 | let exp1 = expression exp1 in | |
319 | let why = mcode why in | |
320 | let exp2 = get_option expression exp2 in | |
321 | let colon = mcode colon in | |
322 | let exp3 = expression exp3 in | |
323 | Ast.CondExpr(exp1,why,exp2,colon,exp3) | |
324 | | Ast0.Postfix(exp,op) -> | |
325 | Ast.Postfix(expression exp,mcode op) | |
326 | | Ast0.Infix(exp,op) -> | |
327 | Ast.Infix(expression exp,mcode op) | |
328 | | Ast0.Unary(exp,op) -> | |
329 | Ast.Unary(expression exp,mcode op) | |
330 | | Ast0.Binary(left,op,right) -> | |
331 | Ast.Binary(expression left,mcode op,expression right) | |
332 | | Ast0.Nested(left,op,right) -> | |
333 | Ast.Nested(expression left,mcode op,expression right) | |
334 | | Ast0.Paren(lp,exp,rp) -> | |
335 | Ast.Paren(mcode lp,expression exp,mcode rp) | |
336 | | Ast0.ArrayAccess(exp1,lb,exp2,rb) -> | |
337 | Ast.ArrayAccess(expression exp1,mcode lb,expression exp2,mcode rb) | |
338 | | Ast0.RecordAccess(exp,pt,field) -> | |
339 | Ast.RecordAccess(expression exp,mcode pt,ident field) | |
340 | | Ast0.RecordPtAccess(exp,ar,field) -> | |
341 | Ast.RecordPtAccess(expression exp,mcode ar,ident field) | |
342 | | Ast0.Cast(lp,ty,rp,exp) -> | |
343 | Ast.Cast(mcode lp,typeC ty,mcode rp,expression exp) | |
344 | | Ast0.SizeOfExpr(szf,exp) -> | |
345 | Ast.SizeOfExpr(mcode szf,expression exp) | |
346 | | Ast0.SizeOfType(szf,lp,ty,rp) -> | |
347 | Ast.SizeOfType(mcode szf, mcode lp,typeC ty,mcode rp) | |
348 | | Ast0.TypeExp(ty) -> Ast.TypeExp(typeC ty) | |
349 | | Ast0.MetaErr(name,constraints,_) -> | |
350 | let constraints = List.map expression constraints in | |
351 | Ast.MetaErr(mcode name,constraints,unitary,false) | |
352 | | Ast0.MetaExpr(name,constraints,ty,form,_) -> | |
353 | let constraints = List.map expression constraints in | |
354 | Ast.MetaExpr(mcode name,constraints,unitary,ty,form,false) | |
355 | | Ast0.MetaExprList(name,Some lenname,_) -> | |
356 | Ast.MetaExprList(mcode name,Some (mcode lenname,unitary,false), | |
357 | unitary,false) | |
358 | | Ast0.MetaExprList(name,None,_) -> | |
359 | Ast.MetaExprList(mcode name,None,unitary,false) | |
360 | | Ast0.EComma(cm) -> Ast.EComma(mcode cm) | |
361 | | Ast0.DisjExpr(_,exps,_,_) -> Ast.DisjExpr(List.map expression exps) | |
362 | | Ast0.NestExpr(_,exp_dots,_,whencode,multi) -> | |
363 | let whencode = get_option expression whencode in | |
364 | Ast.NestExpr(dots expression exp_dots,whencode,multi) | |
365 | | Ast0.Edots(dots,whencode) -> | |
366 | let dots = mcode dots in | |
367 | let whencode = get_option expression whencode in | |
368 | Ast.Edots(dots,whencode) | |
369 | | Ast0.Ecircles(dots,whencode) -> | |
370 | let dots = mcode dots in | |
371 | let whencode = get_option expression whencode in | |
372 | Ast.Ecircles(dots,whencode) | |
373 | | Ast0.Estars(dots,whencode) -> | |
374 | let dots = mcode dots in | |
375 | let whencode = get_option expression whencode in | |
376 | Ast.Estars(dots,whencode) | |
377 | | Ast0.OptExp(exp) -> Ast.OptExp(expression exp) | |
378 | | Ast0.UniqueExp(exp) -> Ast.UniqueExp(expression exp)) in | |
379 | if Ast0.get_test_exp e then Ast.set_test_exp e1 else e1 | |
380 | ||
381 | and expression_dots ed = dots expression ed | |
382 | ||
383 | (* --------------------------------------------------------------------- *) | |
384 | (* Types *) | |
385 | ||
386 | and typeC t = | |
387 | rewrap t (do_isos (Ast0.get_iso t)) | |
388 | (match Ast0.unwrap t with | |
389 | Ast0.ConstVol(cv,ty) -> | |
390 | let rec collect_disjs t = | |
391 | match Ast0.unwrap t with | |
392 | Ast0.DisjType(_,types,_,_) -> | |
393 | if Ast0.get_iso t = [] | |
394 | then List.concat (List.map collect_disjs types) | |
395 | else failwith "unexpected iso on a disjtype" | |
396 | | _ -> [t] in | |
397 | let res = | |
398 | List.map | |
399 | (function ty -> | |
400 | Ast.Type | |
401 | (Some (mcode cv), | |
402 | rewrap ty (do_isos (Ast0.get_iso ty)) (base_typeC ty))) | |
403 | (collect_disjs ty) in | |
404 | (* one could worry that isos are lost because we flatten the | |
405 | disjunctions. but there should not be isos on the disjunctions | |
406 | themselves. *) | |
407 | (match res with | |
408 | [ty] -> ty | |
409 | | types -> Ast.DisjType(List.map (rewrap t no_isos) types)) | |
410 | | Ast0.BaseType(_,_) | Ast0.ImplicitInt(_) | Ast0.Pointer(_,_) | |
411 | | Ast0.FunctionPointer(_,_,_,_,_,_,_) | Ast0.FunctionType(_,_,_,_) | |
412 | | Ast0.Array(_,_,_,_) | Ast0.StructUnionName(_,_) | |
413 | | Ast0.StructUnionDef(_,_,_,_) | Ast0.TypeName(_) | Ast0.MetaType(_,_) -> | |
414 | Ast.Type(None,rewrap t no_isos (base_typeC t)) | |
415 | | Ast0.DisjType(_,types,_,_) -> Ast.DisjType(List.map typeC types) | |
416 | | Ast0.OptType(ty) -> Ast.OptType(typeC ty) | |
417 | | Ast0.UniqueType(ty) -> Ast.UniqueType(typeC ty)) | |
418 | ||
419 | and base_typeC t = | |
420 | match Ast0.unwrap t with | |
421 | Ast0.BaseType(ty,sign) -> | |
422 | Ast.BaseType(mcode ty,get_option mcode sign) | |
423 | | Ast0.ImplicitInt(sgn) -> Ast.ImplicitInt(mcode sgn) | |
424 | | Ast0.Pointer(ty,star) -> Ast.Pointer(typeC ty,mcode star) | |
425 | | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> | |
426 | Ast.FunctionPointer | |
427 | (typeC ty,mcode lp1,mcode star,mcode rp1, | |
428 | mcode lp2,parameter_list params,mcode rp2) | |
429 | | Ast0.FunctionType(ret,lp,params,rp) -> | |
430 | let allminus = check_allminus.V0.combiner_typeC t in | |
431 | Ast.FunctionType | |
432 | (allminus,get_option typeC ret,mcode lp, | |
433 | parameter_list params,mcode rp) | |
434 | | Ast0.Array(ty,lb,size,rb) -> | |
435 | Ast.Array(typeC ty,mcode lb,get_option expression size,mcode rb) | |
436 | | Ast0.StructUnionName(kind,name) -> | |
437 | Ast.StructUnionName(mcode kind,get_option ident name) | |
438 | | Ast0.StructUnionDef(ty,lb,decls,rb) -> | |
439 | Ast.StructUnionDef(typeC ty,mcode lb, | |
440 | dots declaration decls, | |
441 | mcode rb) | |
442 | | Ast0.TypeName(name) -> Ast.TypeName(mcode name) | |
443 | | Ast0.MetaType(name,_) -> | |
444 | Ast.MetaType(mcode name,unitary,false) | |
445 | | _ -> failwith "ast0toast: unexpected type" | |
446 | ||
447 | (* --------------------------------------------------------------------- *) | |
448 | (* Variable declaration *) | |
449 | (* Even if the Cocci program specifies a list of declarations, they are | |
450 | split out into multiple declarations of a single variable each. *) | |
451 | ||
452 | and declaration d = | |
453 | rewrap d (do_isos (Ast0.get_iso d)) | |
454 | (match Ast0.unwrap d with | |
455 | Ast0.Init(stg,ty,id,eq,ini,sem) -> | |
456 | let stg = get_option mcode stg in | |
457 | let ty = typeC ty in | |
458 | let id = ident id in | |
459 | let eq = mcode eq in | |
460 | let ini = initialiser ini in | |
461 | let sem = mcode sem in | |
462 | Ast.Init(stg,ty,id,eq,ini,sem) | |
463 | | Ast0.UnInit(stg,ty,id,sem) -> | |
464 | (match Ast0.unwrap ty with | |
465 | Ast0.FunctionType(tyx,lp1,params,rp1) -> | |
466 | let allminus = check_allminus.V0.combiner_declaration d in | |
467 | Ast.UnInit(get_option mcode stg, | |
468 | rewrap ty (do_isos (Ast0.get_iso ty)) | |
469 | (Ast.Type | |
470 | (None, | |
471 | rewrap ty no_isos | |
472 | (Ast.FunctionType | |
473 | (allminus,get_option typeC tyx,mcode lp1, | |
474 | parameter_list params,mcode rp1)))), | |
475 | ident id,mcode sem) | |
476 | | _ -> Ast.UnInit(get_option mcode stg,typeC ty,ident id,mcode sem)) | |
477 | | Ast0.MacroDecl(name,lp,args,rp,sem) -> | |
478 | let name = ident name in | |
479 | let lp = mcode lp in | |
480 | let args = dots expression args in | |
481 | let rp = mcode rp in | |
482 | let sem = mcode sem in | |
483 | Ast.MacroDecl(name,lp,args,rp,sem) | |
484 | | Ast0.TyDecl(ty,sem) -> Ast.TyDecl(typeC ty,mcode sem) | |
485 | | Ast0.Typedef(stg,ty,id,sem) -> | |
486 | let id = typeC id in | |
487 | (match Ast.unwrap id with | |
488 | Ast.Type(None,id) -> (* only MetaType or Id *) | |
489 | Ast.Typedef(mcode stg,typeC ty,id,mcode sem) | |
490 | | _ -> failwith "bad typedef") | |
491 | | Ast0.DisjDecl(_,decls,_,_) -> Ast.DisjDecl(List.map declaration decls) | |
492 | | Ast0.Ddots(dots,whencode) -> | |
493 | let dots = mcode dots in | |
494 | let whencode = get_option declaration whencode in | |
495 | Ast.Ddots(dots,whencode) | |
496 | | Ast0.OptDecl(decl) -> Ast.OptDecl(declaration decl) | |
497 | | Ast0.UniqueDecl(decl) -> Ast.UniqueDecl(declaration decl)) | |
498 | ||
499 | and declaration_dots l = dots declaration l | |
500 | ||
501 | (* --------------------------------------------------------------------- *) | |
502 | (* Initialiser *) | |
503 | ||
504 | and strip_idots initlist = | |
505 | match Ast0.unwrap initlist with | |
506 | Ast0.DOTS(x) -> | |
507 | let (whencode,init) = | |
508 | List.fold_left | |
509 | (function (prevwhen,previnit) -> | |
510 | function cur -> | |
511 | match Ast0.unwrap cur with | |
512 | Ast0.Idots(dots,Some whencode) -> | |
513 | (whencode :: prevwhen, previnit) | |
514 | | Ast0.Idots(dots,None) -> (prevwhen,previnit) | |
515 | | _ -> (prevwhen, cur :: previnit)) | |
516 | ([],[]) x in | |
517 | (List.rev whencode, List.rev init) | |
518 | | Ast0.CIRCLES(x) | Ast0.STARS(x) -> failwith "not possible for an initlist" | |
519 | ||
520 | and initialiser i = | |
521 | rewrap i no_isos | |
522 | (match Ast0.unwrap i with | |
523 | Ast0.InitExpr(exp) -> Ast.InitExpr(expression exp) | |
524 | | Ast0.InitList(lb,initlist,rb) -> | |
525 | let (whencode,initlist) = strip_idots initlist in | |
526 | Ast.InitList(mcode lb,List.map initialiser initlist,mcode rb, | |
527 | List.map initialiser whencode) | |
528 | | Ast0.InitGccDotName(dot,name,eq,ini) -> | |
529 | Ast.InitGccDotName(mcode dot,ident name,mcode eq,initialiser ini) | |
530 | | Ast0.InitGccName(name,eq,ini) -> | |
531 | Ast.InitGccName(ident name,mcode eq,initialiser ini) | |
532 | | Ast0.InitGccIndex(lb,exp,rb,eq,ini) -> | |
533 | Ast.InitGccIndex(mcode lb,expression exp,mcode rb,mcode eq, | |
534 | initialiser ini) | |
535 | | Ast0.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) -> | |
536 | Ast.InitGccRange(mcode lb,expression exp1,mcode dots, | |
537 | expression exp2,mcode rb,mcode eq,initialiser ini) | |
538 | | Ast0.IComma(comma) -> Ast.IComma(mcode comma) | |
539 | | Ast0.Idots(_,_) -> failwith "Idots should have been removed" | |
540 | | Ast0.OptIni(ini) -> Ast.OptIni(initialiser ini) | |
541 | | Ast0.UniqueIni(ini) -> Ast.UniqueIni(initialiser ini)) | |
542 | ||
543 | (* --------------------------------------------------------------------- *) | |
544 | (* Parameter *) | |
545 | ||
546 | and parameterTypeDef p = | |
547 | rewrap p no_isos | |
548 | (match Ast0.unwrap p with | |
549 | Ast0.VoidParam(ty) -> Ast.VoidParam(typeC ty) | |
550 | | Ast0.Param(ty,id) -> Ast.Param(typeC ty,get_option ident id) | |
551 | | Ast0.MetaParam(name,_) -> | |
552 | Ast.MetaParam(mcode name,unitary,false) | |
553 | | Ast0.MetaParamList(name,Some lenname,_) -> | |
554 | Ast.MetaParamList(mcode name,Some(mcode lenname,unitary,false), | |
555 | unitary,false) | |
556 | | Ast0.MetaParamList(name,None,_) -> | |
557 | Ast.MetaParamList(mcode name,None,unitary,false) | |
558 | | Ast0.PComma(cm) -> Ast.PComma(mcode cm) | |
559 | | Ast0.Pdots(dots) -> Ast.Pdots(mcode dots) | |
560 | | Ast0.Pcircles(dots) -> Ast.Pcircles(mcode dots) | |
561 | | Ast0.OptParam(param) -> Ast.OptParam(parameterTypeDef param) | |
562 | | Ast0.UniqueParam(param) -> Ast.UniqueParam(parameterTypeDef param)) | |
563 | ||
564 | and parameter_list l = dots parameterTypeDef l | |
565 | ||
566 | (* --------------------------------------------------------------------- *) | |
567 | (* Top-level code *) | |
568 | ||
569 | and statement s = | |
570 | let rec statement seqible s = | |
571 | let rewrap_stmt ast0 ast = | |
572 | let befaft = | |
573 | match Ast0.get_dots_bef_aft s with | |
574 | Ast0.NoDots -> Ast.NoDots | |
575 | | Ast0.DroppingBetweenDots s -> | |
576 | Ast.DroppingBetweenDots (statement seqible s,get_ctr()) | |
577 | | Ast0.AddingBetweenDots s -> | |
578 | Ast.AddingBetweenDots (statement seqible s,get_ctr()) in | |
579 | Ast.set_dots_bef_aft befaft (rewrap ast0 no_isos ast) in | |
580 | let rewrap_rule_elem ast0 ast = | |
581 | rewrap ast0 (do_isos (Ast0.get_iso ast0)) ast in | |
582 | rewrap_stmt s | |
583 | (match Ast0.unwrap s with | |
584 | Ast0.Decl((_,bef),decl) -> | |
585 | Ast.Atomic(rewrap_rule_elem s | |
586 | (Ast.Decl(convert_mcodekind bef, | |
587 | check_allminus.V0.combiner_statement s, | |
588 | declaration decl))) | |
589 | | Ast0.Seq(lbrace,body,rbrace) -> | |
590 | let lbrace = mcode lbrace in | |
591 | let (decls,body) = separate_decls seqible body in | |
592 | let rbrace = mcode rbrace in | |
593 | Ast.Seq(iso_tokenwrap lbrace s (Ast.SeqStart(lbrace)) | |
594 | (do_isos (Ast0.get_iso s)), | |
595 | decls,body, | |
596 | tokenwrap rbrace s (Ast.SeqEnd(rbrace))) | |
597 | | Ast0.ExprStatement(exp,sem) -> | |
598 | Ast.Atomic(rewrap_rule_elem s | |
599 | (Ast.ExprStatement(expression exp,mcode sem))) | |
600 | | Ast0.IfThen(iff,lp,exp,rp,branch,(_,aft)) -> | |
601 | Ast.IfThen | |
602 | (rewrap_rule_elem s | |
603 | (Ast.IfHeader(mcode iff,mcode lp,expression exp,mcode rp)), | |
604 | statement Ast.NotSequencible branch, | |
605 | ([],[],[],convert_mcodekind aft)) | |
606 | | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,(_,aft)) -> | |
607 | let els = mcode els in | |
608 | Ast.IfThenElse | |
609 | (rewrap_rule_elem s | |
610 | (Ast.IfHeader(mcode iff,mcode lp,expression exp,mcode rp)), | |
611 | statement Ast.NotSequencible branch1, | |
612 | tokenwrap els s (Ast.Else(els)), | |
613 | statement Ast.NotSequencible branch2, | |
614 | ([],[],[],convert_mcodekind aft)) | |
615 | | Ast0.While(wh,lp,exp,rp,body,(_,aft)) -> | |
616 | Ast.While(rewrap_rule_elem s | |
617 | (Ast.WhileHeader | |
618 | (mcode wh,mcode lp,expression exp,mcode rp)), | |
619 | statement Ast.NotSequencible body, | |
620 | ([],[],[],convert_mcodekind aft)) | |
621 | | Ast0.Do(d,body,wh,lp,exp,rp,sem) -> | |
622 | let wh = mcode wh in | |
623 | Ast.Do(rewrap_rule_elem s (Ast.DoHeader(mcode d)), | |
624 | statement Ast.NotSequencible body, | |
625 | tokenwrap wh s | |
626 | (Ast.WhileTail(wh,mcode lp,expression exp,mcode rp, | |
627 | mcode sem))) | |
628 | | Ast0.For(fr,lp,exp1,sem1,exp2,sem2,exp3,rp,body,(_,aft)) -> | |
629 | let fr = mcode fr in | |
630 | let lp = mcode lp in | |
631 | let exp1 = get_option expression exp1 in | |
632 | let sem1 = mcode sem1 in | |
633 | let exp2 = get_option expression exp2 in | |
634 | let sem2= mcode sem2 in | |
635 | let exp3 = get_option expression exp3 in | |
636 | let rp = mcode rp in | |
637 | let body = statement Ast.NotSequencible body in | |
638 | Ast.For(rewrap_rule_elem s | |
639 | (Ast.ForHeader(fr,lp,exp1,sem1,exp2,sem2,exp3,rp)), | |
640 | body,([],[],[],convert_mcodekind aft)) | |
641 | | Ast0.Iterator(nm,lp,args,rp,body,(_,aft)) -> | |
642 | Ast.Iterator(rewrap_rule_elem s | |
643 | (Ast.IteratorHeader | |
644 | (ident nm,mcode lp, | |
645 | dots expression args, | |
646 | mcode rp)), | |
647 | statement Ast.NotSequencible body, | |
648 | ([],[],[],convert_mcodekind aft)) | |
649 | | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) -> | |
650 | let switch = mcode switch in | |
651 | let lp = mcode lp in | |
652 | let exp = expression exp in | |
653 | let rp = mcode rp in | |
654 | let lb = mcode lb in | |
655 | let cases = List.map case_line (Ast0.undots cases) in | |
656 | let rb = mcode rb in | |
657 | Ast.Switch(rewrap_rule_elem s (Ast.SwitchHeader(switch,lp,exp,rp)), | |
658 | tokenwrap lb s (Ast.SeqStart(lb)), | |
659 | cases, | |
660 | tokenwrap rb s (Ast.SeqEnd(rb))) | |
661 | | Ast0.Break(br,sem) -> | |
662 | Ast.Atomic(rewrap_rule_elem s (Ast.Break(mcode br,mcode sem))) | |
663 | | Ast0.Continue(cont,sem) -> | |
664 | Ast.Atomic(rewrap_rule_elem s (Ast.Continue(mcode cont,mcode sem))) | |
665 | | Ast0.Label(l,dd) -> | |
666 | Ast.Atomic(rewrap_rule_elem s (Ast.Label(ident l,mcode dd))) | |
667 | | Ast0.Goto(goto,l,sem) -> | |
668 | Ast.Atomic | |
669 | (rewrap_rule_elem s (Ast.Goto(mcode goto,ident l,mcode sem))) | |
670 | | Ast0.Return(ret,sem) -> | |
671 | Ast.Atomic(rewrap_rule_elem s (Ast.Return(mcode ret,mcode sem))) | |
672 | | Ast0.ReturnExpr(ret,exp,sem) -> | |
673 | Ast.Atomic | |
674 | (rewrap_rule_elem s | |
675 | (Ast.ReturnExpr(mcode ret,expression exp,mcode sem))) | |
676 | | Ast0.MetaStmt(name,_) -> | |
677 | Ast.Atomic(rewrap_rule_elem s | |
678 | (Ast.MetaStmt(mcode name,unitary,seqible,false))) | |
679 | | Ast0.MetaStmtList(name,_) -> | |
680 | Ast.Atomic(rewrap_rule_elem s | |
681 | (Ast.MetaStmtList(mcode name,unitary,false))) | |
682 | | Ast0.TopExp(exp) -> | |
683 | Ast.Atomic(rewrap_rule_elem s (Ast.TopExp(expression exp))) | |
684 | | Ast0.Exp(exp) -> | |
685 | Ast.Atomic(rewrap_rule_elem s (Ast.Exp(expression exp))) | |
1be43e12 C |
686 | | Ast0.TopInit(init) -> |
687 | Ast.Atomic(rewrap_rule_elem s (Ast.TopInit(initialiser init))) | |
34e49164 C |
688 | | Ast0.Ty(ty) -> |
689 | Ast.Atomic(rewrap_rule_elem s (Ast.Ty(typeC ty))) | |
690 | | Ast0.Disj(_,rule_elem_dots_list,_,_) -> | |
691 | Ast.Disj(List.map (function x -> statement_dots seqible x) | |
692 | rule_elem_dots_list) | |
693 | | Ast0.Nest(_,rule_elem_dots,_,whn,multi) -> | |
694 | Ast.Nest | |
695 | (statement_dots Ast.Sequencible rule_elem_dots, | |
696 | List.map | |
697 | (whencode (statement_dots Ast.Sequencible) | |
698 | (statement Ast.NotSequencible)) | |
699 | whn, | |
700 | multi,[],[]) | |
701 | | Ast0.Dots(d,whn) -> | |
702 | let d = mcode d in | |
703 | let whn = | |
704 | List.map | |
705 | (whencode (statement_dots Ast.Sequencible) | |
706 | (statement Ast.NotSequencible)) | |
707 | whn in | |
708 | Ast.Dots(d,whn,[],[]) | |
709 | | Ast0.Circles(d,whn) -> | |
710 | let d = mcode d in | |
711 | let whn = | |
712 | List.map | |
713 | (whencode (statement_dots Ast.Sequencible) | |
714 | (statement Ast.NotSequencible)) | |
715 | whn in | |
716 | Ast.Circles(d,whn,[],[]) | |
717 | | Ast0.Stars(d,whn) -> | |
718 | let d = mcode d in | |
719 | let whn = | |
720 | List.map | |
721 | (whencode (statement_dots Ast.Sequencible) | |
722 | (statement Ast.NotSequencible)) | |
723 | whn in | |
724 | Ast.Stars(d,whn,[],[]) | |
725 | | Ast0.FunDecl((_,bef),fi,name,lp,params,rp,lbrace,body,rbrace) -> | |
726 | let fi = List.map fninfo fi in | |
727 | let name = ident name in | |
728 | let lp = mcode lp in | |
729 | let params = parameter_list params in | |
730 | let rp = mcode rp in | |
731 | let lbrace = mcode lbrace in | |
732 | let (decls,body) = separate_decls seqible body in | |
733 | let rbrace = mcode rbrace in | |
734 | let allminus = check_allminus.V0.combiner_statement s in | |
735 | Ast.FunDecl(rewrap_rule_elem s | |
736 | (Ast.FunHeader(convert_mcodekind bef, | |
737 | allminus,fi,name,lp,params,rp)), | |
738 | tokenwrap lbrace s (Ast.SeqStart(lbrace)), | |
739 | decls,body, | |
740 | tokenwrap rbrace s (Ast.SeqEnd(rbrace))) | |
741 | | Ast0.Include(inc,str) -> | |
742 | Ast.Atomic(rewrap_rule_elem s (Ast.Include(mcode inc,mcode str))) | |
743 | | Ast0.Define(def,id,params,body) -> | |
744 | Ast.Define | |
745 | (rewrap_rule_elem s | |
746 | (Ast.DefineHeader | |
747 | (mcode def,ident id, define_parameters params)), | |
748 | statement_dots Ast.NotSequencible (*not sure*) body) | |
749 | | Ast0.OptStm(stm) -> Ast.OptStm(statement seqible stm) | |
750 | | Ast0.UniqueStm(stm) -> Ast.UniqueStm(statement seqible stm)) | |
751 | ||
752 | and define_parameters p = | |
753 | rewrap p no_isos | |
754 | (match Ast0.unwrap p with | |
755 | Ast0.NoParams -> Ast.NoParams | |
756 | | Ast0.DParams(lp,params,rp) -> | |
757 | Ast.DParams(mcode lp, | |
758 | dots define_param params, | |
759 | mcode rp)) | |
760 | ||
761 | and define_param p = | |
762 | rewrap p no_isos | |
763 | (match Ast0.unwrap p with | |
764 | Ast0.DParam(id) -> Ast.DParam(ident id) | |
765 | | Ast0.DPComma(comma) -> Ast.DPComma(mcode comma) | |
766 | | Ast0.DPdots(d) -> Ast.DPdots(mcode d) | |
767 | | Ast0.DPcircles(c) -> Ast.DPcircles(mcode c) | |
768 | | Ast0.OptDParam(dp) -> Ast.OptDParam(define_param dp) | |
769 | | Ast0.UniqueDParam(dp) -> Ast.UniqueDParam(define_param dp)) | |
770 | ||
771 | and whencode notfn alwaysfn = function | |
772 | Ast0.WhenNot a -> Ast.WhenNot (notfn a) | |
773 | | Ast0.WhenAlways a -> Ast.WhenAlways (alwaysfn a) | |
774 | | Ast0.WhenModifier(x) -> Ast.WhenModifier(x) | |
1be43e12 C |
775 | | x -> |
776 | let rewrap_rule_elem ast0 ast = | |
777 | rewrap ast0 (do_isos (Ast0.get_iso ast0)) ast in | |
778 | match x with | |
779 | Ast0.WhenNotTrue(e) -> | |
780 | Ast.WhenNotTrue(rewrap_rule_elem e (Ast.Exp(expression e))) | |
781 | | Ast0.WhenNotFalse(e) -> | |
782 | Ast.WhenNotFalse(rewrap_rule_elem e (Ast.Exp(expression e))) | |
783 | | _ -> failwith "not possible" | |
34e49164 C |
784 | |
785 | and process_list seqible isos = function | |
786 | [] -> [] | |
787 | | x::rest -> | |
788 | let first = statement seqible x in | |
789 | let first = | |
790 | if !Flag.track_iso_usage | |
791 | then Ast.set_isos first (isos@(Ast.get_isos first)) | |
792 | else first in | |
793 | (match Ast0.unwrap x with | |
794 | Ast0.Dots(_,_) | Ast0.Nest(_) -> | |
795 | first::(process_list (Ast.SequencibleAfterDots []) no_isos rest) | |
796 | | _ -> | |
797 | first::(process_list Ast.Sequencible no_isos rest)) | |
798 | ||
799 | and statement_dots seqible d = | |
800 | let isos = do_isos (Ast0.get_iso d) in | |
801 | rewrap d no_isos | |
802 | (match Ast0.unwrap d with | |
803 | Ast0.DOTS(x) -> Ast.DOTS(process_list seqible isos x) | |
804 | | Ast0.CIRCLES(x) -> Ast.CIRCLES(process_list seqible isos x) | |
805 | | Ast0.STARS(x) -> Ast.STARS(process_list seqible isos x)) | |
806 | ||
807 | and separate_decls seqible d = | |
808 | let rec collect_decls = function | |
809 | [] -> ([],[]) | |
810 | | (x::xs) as l -> | |
811 | (match Ast0.unwrap x with | |
812 | Ast0.Decl(_) -> | |
813 | let (decls,other) = collect_decls xs in | |
814 | (x :: decls,other) | |
815 | | Ast0.Dots(_,_) | Ast0.Nest(_,_,_,_,_) -> | |
816 | let (decls,other) = collect_decls xs in | |
817 | (match decls with | |
818 | [] -> ([],x::other) | |
819 | | _ -> (x :: decls,other)) | |
820 | | Ast0.Disj(starter,stmt_dots_list,mids,ender) -> | |
821 | let disjs = List.map collect_dot_decls stmt_dots_list in | |
822 | let all_decls = List.for_all (function (_,s) -> s=[]) disjs in | |
823 | if all_decls | |
824 | then | |
825 | let (decls,other) = collect_decls xs in | |
826 | (x :: decls,other) | |
827 | else ([],l) | |
828 | | _ -> ([],l)) | |
829 | ||
830 | and collect_dot_decls d = | |
831 | match Ast0.unwrap d with | |
832 | Ast0.DOTS(x) -> collect_decls x | |
833 | | Ast0.CIRCLES(x) -> collect_decls x | |
834 | | Ast0.STARS(x) -> collect_decls x in | |
835 | ||
836 | let process l d fn = | |
837 | let (decls,other) = collect_decls l in | |
838 | (rewrap d no_isos (fn (List.map (statement seqible) decls)), | |
839 | rewrap d no_isos | |
840 | (fn (process_list seqible (do_isos (Ast0.get_iso d)) other))) in | |
841 | match Ast0.unwrap d with | |
842 | Ast0.DOTS(x) -> process x d (function x -> Ast.DOTS x) | |
843 | | Ast0.CIRCLES(x) -> process x d (function x -> Ast.CIRCLES x) | |
844 | | Ast0.STARS(x) -> process x d (function x -> Ast.STARS x) in | |
845 | ||
846 | statement Ast.Sequencible s | |
847 | ||
848 | and fninfo = function | |
849 | Ast0.FStorage(stg) -> Ast.FStorage(mcode stg) | |
850 | | Ast0.FType(ty) -> Ast.FType(typeC ty) | |
851 | | Ast0.FInline(inline) -> Ast.FInline(mcode inline) | |
852 | | Ast0.FAttr(attr) -> Ast.FAttr(mcode attr) | |
853 | ||
854 | and option_to_list = function | |
855 | Some x -> [x] | |
856 | | None -> [] | |
857 | ||
858 | and case_line c = | |
859 | rewrap c no_isos | |
860 | (match Ast0.unwrap c with | |
861 | Ast0.Default(def,colon,code) -> | |
862 | let def = mcode def in | |
863 | let colon = mcode colon in | |
864 | let code = dots statement code in | |
865 | Ast.CaseLine(rewrap c no_isos (Ast.Default(def,colon)),code) | |
866 | | Ast0.Case(case,exp,colon,code) -> | |
867 | let case = mcode case in | |
868 | let exp = expression exp in | |
869 | let colon = mcode colon in | |
870 | let code = dots statement code in | |
871 | Ast.CaseLine(rewrap c no_isos (Ast.Case(case,exp,colon)),code) | |
872 | | Ast0.OptCase(case) -> Ast.OptCase(case_line case)) | |
873 | ||
874 | and statement_dots l = dots statement l | |
875 | ||
876 | (* --------------------------------------------------------------------- *) | |
877 | ||
878 | (* what is possible is only what is at the top level in an iso *) | |
879 | and anything = function | |
880 | Ast0.DotsExprTag(d) -> Ast.ExprDotsTag(expression_dots d) | |
881 | | Ast0.DotsParamTag(d) -> Ast.ParamDotsTag(parameter_list d) | |
882 | | Ast0.DotsInitTag(d) -> failwith "not possible" | |
883 | | Ast0.DotsStmtTag(d) -> Ast.StmtDotsTag(statement_dots d) | |
884 | | Ast0.DotsDeclTag(d) -> Ast.DeclDotsTag(declaration_dots d) | |
885 | | Ast0.DotsCaseTag(d) -> failwith "not possible" | |
886 | | Ast0.IdentTag(d) -> Ast.IdentTag(ident d) | |
887 | | Ast0.ExprTag(d) -> Ast.ExpressionTag(expression d) | |
888 | | Ast0.ArgExprTag(d) | Ast0.TestExprTag(d) -> | |
889 | failwith "only in isos, not converted to ast" | |
890 | | Ast0.TypeCTag(d) -> Ast.FullTypeTag(typeC d) | |
891 | | Ast0.ParamTag(d) -> Ast.ParamTag(parameterTypeDef d) | |
892 | | Ast0.InitTag(d) -> Ast.InitTag(initialiser d) | |
893 | | Ast0.DeclTag(d) -> Ast.DeclarationTag(declaration d) | |
894 | | Ast0.StmtTag(d) -> Ast.StatementTag(statement d) | |
895 | | Ast0.CaseLineTag(d) -> Ast.CaseLineTag(case_line d) | |
896 | | Ast0.TopTag(d) -> Ast.Code(top_level d) | |
897 | | Ast0.IsoWhenTag(_) -> failwith "not possible" | |
1be43e12 C |
898 | | Ast0.IsoWhenTTag(_) -> failwith "not possible" |
899 | | Ast0.IsoWhenFTag(_) -> failwith "not possible" | |
34e49164 C |
900 | | Ast0.MetaPosTag _ -> failwith "not possible" |
901 | ||
902 | (* --------------------------------------------------------------------- *) | |
903 | (* Function declaration *) | |
904 | (* top level isos are probably lost to tracking *) | |
905 | ||
906 | and top_level t = | |
907 | rewrap t no_isos | |
908 | (match Ast0.unwrap t with | |
909 | Ast0.FILEINFO(old_file,new_file) -> | |
910 | Ast.FILEINFO(mcode old_file,mcode new_file) | |
911 | | Ast0.DECL(stmt) -> Ast.DECL(statement stmt) | |
912 | | Ast0.CODE(rule_elem_dots) -> | |
913 | Ast.CODE(statement_dots rule_elem_dots) | |
914 | | Ast0.ERRORWORDS(exps) -> Ast.ERRORWORDS(List.map expression exps) | |
915 | | Ast0.OTHER(_) -> failwith "eliminated by top_level") | |
916 | ||
917 | (* --------------------------------------------------------------------- *) | |
918 | (* Entry point for minus code *) | |
919 | ||
920 | (* Inline_mcodes is very important - sends + code attached to the - code | |
921 | down to the mcodes. The functions above can only be used when there is no | |
922 | attached + code, eg in + code itself. *) | |
923 | let ast0toast_toplevel x = | |
924 | inline_mcodes.V0.combiner_top_level x; | |
925 | top_level x | |
926 | ||
927 | let ast0toast name deps dropped exists x is_exp = | |
928 | List.iter inline_mcodes.V0.combiner_top_level x; | |
929 | Ast.CocciRule (name,(deps,dropped,exists),List.map top_level x,is_exp) |