ad6caad0ebde4e6e182d9bf37bd22c67c4365ba5
[bpt/coccinelle.git] / popl / insert_befaft.ml
1 (*
2 * Copyright 2010, INRIA, University of Copenhagen
3 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
4 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
5 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
6 * This file is part of Coccinelle.
7 *
8 * Coccinelle is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, according to version 2 of the License.
11 *
12 * Coccinelle is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * The authors reserve the right to distribute this or future versions of
21 * Coccinelle under other licenses.
22 *)
23
24
25 module Past = Ast_popl
26
27 (* --------------------------------------------------------------------- *)
28
29 let rec get_before a = function
30 Past.Seq(elem,seq) ->
31 let (elem,ea) = get_before_element a elem in
32 let (seq,sla) = get_before ea seq in
33 (Past.Seq(elem,seq),sla)
34 | Past.Empty -> (Past.Empty,a)
35 | Past.SExists(var,seq) -> failwith "not possible"
36
37 and get_before_element a = function
38 Past.Term(term) as s -> (s,[s])
39 | Past.Or(seq1,seq2) ->
40 let (seq1,seq1a) = get_before a seq1 in
41 let (seq2,seq2a) = get_before a seq2 in
42 (Past.Or(seq1,seq2),Common.union_set seq1a seq2a)
43 | Past.DInfo(dots,_,seq_aft) ->
44 let dots = get_before_dots a dots in
45 (Past.DInfo(dots,a,seq_aft),a)
46 | Past.EExists(var,seq) -> failwith "not possible"
47
48 and get_before_dots a = function
49 Past.Dots -> Past.Dots
50 | Past.Nest(seq) ->
51 let (seq,_) = get_before a seq in
52 Past.Nest(seq)
53 | Past.When(dots,seq) ->
54 let dots = get_before_dots a dots in
55 let (seq,_) = get_before [] seq in
56 Past.When(dots,seq)
57 | Past.DExists(var,dots) -> failwith "not possible"
58
59 (* --------------------------------------------------------------------- *)
60
61 let rec get_after a = function
62 Past.Seq(elem,seq) ->
63 let (seq,sla) = get_after a seq in
64 let (elem,ea) = get_after_element sla elem in
65 (Past.Seq(elem,seq),ea)
66 | Past.Empty -> (Past.Empty,a)
67 | Past.SExists(var,seq) -> failwith "not possible"
68
69 and get_after_element a = function
70 Past.Term(term) as s -> (s,[s])
71 | Past.Or(seq1,seq2) ->
72 let (seq1,seq1a) = get_after a seq1 in
73 let (seq2,seq2a) = get_after a seq2 in
74 (Past.Or(seq1,seq2),Common.union_set seq1a seq2a)
75 | Past.DInfo(dots,seq_bef,_) ->
76 let dots = get_after_dots a dots in
77 (Past.DInfo(dots,seq_bef,a),a)
78 | Past.EExists(var,seq) -> failwith "not possible"
79
80 and get_after_dots a = function
81 Past.Dots -> Past.Dots
82 | Past.Nest(seq) ->
83 let (seq,_) = get_after (Common.union_set (get_first [] seq) a) seq in
84 Past.Nest(seq)
85 | Past.When(dots,seq) ->
86 let dots = get_after_dots a dots in
87 let (seq,_) = get_after [] seq in
88 Past.When(dots,seq)
89 | Past.DExists(var,dots) -> failwith "not possible"
90
91 (* --------------------------------------------------------------------- *)
92 (* like get_after, but just returns the a component; doesn't modify the term *)
93
94 and get_first a = function
95 Past.Seq(elem,seq) ->
96 let sla = get_first a seq in
97 let ea = get_first_element sla elem in
98 ea
99 | Past.Empty -> a
100 | Past.SExists(var,seq) -> failwith "not possible"
101
102 and get_first_element a = function
103 Past.Term(term) as s -> [s]
104 | Past.Or(seq1,seq2) ->
105 Common.union_set (get_first a seq1) (get_first a seq2)
106 | Past.DInfo(dots,_,_) -> a
107 | Past.EExists(var,seq) -> failwith "not possible"
108
109 (* --------------------------------------------------------------------- *)
110 (* Entry point *)
111
112 let insert_befaft sl =
113 let (sl,_) = get_before [] sl in
114 let (sl,_) = get_after [] sl in
115 sl