~ubuntu-branches/debian/sid/frama-c/sid

« back to all changes in this revision

Viewing changes to src/project/computation.ml

  • Committer: Bazaar Package Importer
  • Author(s): Mehdi Dogguy
  • Date: 2009-06-03 08:19:25 UTC
  • Revision ID: james.westby@ubuntu.com-20090603081925-kihvxvt0wy3zc4ar
Tags: upstream-20081201.dfsg
ImportĀ upstreamĀ versionĀ 20081201.dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
(**************************************************************************)
 
2
(*                                                                        *)
 
3
(*  This file is part of Frama-C.                                         *)
 
4
(*                                                                        *)
 
5
(*  Copyright (C) 2007-2008                                               *)
 
6
(*    CEA (Commissariat ļæ½ l'ļæ½nergie Atomique)                             *)
 
7
(*                                                                        *)
 
8
(*  you can redistribute it and/or modify it under the terms of the GNU   *)
 
9
(*  Lesser General Public License as published by the Free Software       *)
 
10
(*  Foundation, version 2.1.                                              *)
 
11
(*                                                                        *)
 
12
(*  It 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 Lesser General Public License for more details.                   *)
 
16
(*                                                                        *)
 
17
(*  See the GNU Lesser General Public License version 2.1                 *)
 
18
(*  for more details (enclosed in the file licenses/LGPLv2.1).            *)
 
19
(*                                                                        *)
 
20
(**************************************************************************)
 
21
 
 
22
(* $Id: computation.ml,v 1.15 2008/11/18 12:13:41 uid568 Exp $ *)
 
23
 
 
24
module type HASHTBL = sig
 
25
  include Datatype.HASHTBL
 
26
  val clear: 'a t -> unit
 
27
  val find: 'a t -> key -> 'a
 
28
  val remove: 'a t -> key -> unit
 
29
  val mem: 'a t -> key -> bool
 
30
end
 
31
 
 
32
module type HASHTBL_OUTPUT = sig
 
33
  include Project.Computation.OUTPUT
 
34
  type key
 
35
  type data
 
36
  val replace: key -> data -> unit 
 
37
  val add: key -> data -> unit
 
38
  val clear: unit -> unit
 
39
  val length: unit -> int
 
40
  val iter: (key -> data -> unit) -> unit
 
41
  val fold: (key -> data -> 'a -> 'a) -> 'a -> 'a
 
42
  val memo: ?change:(data -> data) -> (key -> data) -> key -> data
 
43
    (** @plugin development guide *)
 
44
  val find: key -> data
 
45
  val find_all: key -> data list
 
46
  val unsafe_find: key -> data
 
47
  val mem: key -> bool
 
48
  val remove: key -> unit
 
49
end
 
50
 
 
51
module Make_Hashtbl
 
52
  (H:HASHTBL)(Data:Project.Datatype.S)(Info:Signature.NAME_SIZE_DPDS) = 
 
53
struct
 
54
 
 
55
  type key = H.key
 
56
  type data = Data.t
 
57
      
 
58
  let create () = H.create Info.size
 
59
    
 
60
  let state = ref (create ())
 
61
    
 
62
  include Project.Computation.Register
 
63
  (Datatype.Make_Hashtbl(H)(Data))
 
64
  (struct
 
65
     type t = data H.t
 
66
     let create = create
 
67
     let clear = H.clear
 
68
     let get () = !state
 
69
     let set x = state := x
 
70
   end)
 
71
  (Info)
 
72
 
 
73
  let clear () = H.clear !state
 
74
  let length () = H.length !state
 
75
  let replace key v = H.replace !state key v
 
76
  let add key v = H.add !state key v
 
77
  let find key = H.find !state key
 
78
  let find_all key = H.find_all !state key
 
79
  let unsafe_find key = try find key with Not_found -> assert false
 
80
  let mem key = H.mem !state key
 
81
  let remove key = H.remove !state key
 
82
  let iter f = H.iter f !state
 
83
  let fold f acc = H.fold f !state acc
 
84
 
 
85
  let memo ?change f key =
 
86
    try
 
87
      let old = find key in
 
88
      Extlib.may_map 
 
89
        ~dft:old (fun f -> let v = f old in replace key v; v) change
 
90
    with Not_found ->
 
91
      let data = f key in
 
92
      replace key data;
 
93
      data
 
94
 
 
95
end
 
96
 
 
97
module Hashtbl(Key:Hashtbl.HashedType) = Make_Hashtbl(Hashtbl.Make(Key))
 
98
 
 
99
module type REF_INPUT = sig
 
100
  include Project.Datatype.S
 
101
  val default: unit -> t
 
102
end
 
103
 
 
104
module type REF_OUTPUT = sig
 
105
  include Project.Computation.OUTPUT
 
106
  type data
 
107
  val set: data -> unit
 
108
  val get: unit -> data
 
109
  val clear: unit -> unit
 
110
end
 
111
 
 
112
module Ref(Data:REF_INPUT)(Info:Signature.NAME_DPDS) = struct
 
113
 
 
114
  type data = Data.t
 
115
 
 
116
  let create () = ref (Data.default ())
 
117
  let state = ref (create ())
 
118
 
 
119
  include Project.Computation.Register
 
120
  (Datatype.Ref(Data))
 
121
  (struct
 
122
     type t = data ref
 
123
     let create = create
 
124
     let clear tbl = tbl := Data.default ()
 
125
     let get () = !state
 
126
     let set x = state := x
 
127
   end)
 
128
  (Info)
 
129
 
 
130
  let set v = !state := v
 
131
  let get () = !(!state)
 
132
  let clear () = !state := Data.default ()
 
133
 
 
134
end
 
135
 
 
136
module type OPTION_REF_OUTPUT = sig
 
137
  include REF_OUTPUT
 
138
  val memo: ?change:(data -> data) -> (unit -> data) -> data
 
139
  val map: (data -> data) -> data option
 
140
  val may: (data -> unit) -> unit
 
141
end
 
142
 
 
143
module OptionRef
 
144
  (Data:Project.Datatype.S)(Info:Signature.NAME_DPDS) = struct
 
145
 
 
146
  type data = Data.t
 
147
 
 
148
  let create () = ref None
 
149
  let state = ref (create ())
 
150
 
 
151
  include Project.Computation.Register
 
152
  (Datatype.OptionRef(Data))
 
153
  (struct
 
154
     type t = data option ref
 
155
     let create = create
 
156
     let clear tbl = tbl := None
 
157
     let get () = !state
 
158
     let set x = state := x
 
159
   end)
 
160
  (Info)
 
161
 
 
162
  let set v = !state := Some v
 
163
  let get () = match !(!state) with None -> raise Not_found | Some v -> v
 
164
  let clear () = !state := None
 
165
 
 
166
  let memo ?change f =
 
167
    try
 
168
      let old = get () in
 
169
      Extlib.may_map 
 
170
        ~dft:old (fun f -> let v = f old in set v; v) change
 
171
    with Not_found ->
 
172
      let data = f () in
 
173
      set data;
 
174
      data
 
175
 
 
176
  let map f = Extlib.opt_map f !(!state)
 
177
  let may f = Extlib.may f !(!state)
 
178
 
 
179
end
 
180
 
 
181
module type SET = sig
 
182
  type elt
 
183
  type t
 
184
  val empty: t
 
185
  val singleton: elt -> t
 
186
  val is_empty: t -> bool
 
187
  val add: elt -> t -> t
 
188
  val mem: elt -> t -> bool
 
189
  val fold: (elt -> 'a -> 'a) -> t -> 'a -> 'a
 
190
  val iter: (elt -> unit) -> t -> unit
 
191
end
 
192
 
 
193
module type SET_REF_OUTPUT = sig
 
194
  include Project.Computation.OUTPUT
 
195
  type elt
 
196
  val add: elt -> unit
 
197
  val mem: elt -> bool
 
198
  val is_empty: unit -> bool
 
199
  val fold: (elt -> 'a -> 'a) -> 'a -> 'a
 
200
  val iter: (elt -> unit) -> unit
 
201
end
 
202
 
 
203
module Make_SetRef
 
204
  (Set:SET)
 
205
  (Data:Project.Datatype.S with type t = Set.elt)
 
206
  (Info:Signature.NAME_DPDS) = 
 
207
struct
 
208
  include Ref
 
209
    (struct 
 
210
       include Datatype.Make_Set(Set)(Data)
 
211
       let default () = Set.empty
 
212
     end)
 
213
    (Info)
 
214
  type elt = Set.elt
 
215
  let apply f = f (get ())
 
216
  let is_empty () = apply Set.is_empty
 
217
  let add x = set (apply (Set.add x))
 
218
  let mem x = apply (Set.mem x)
 
219
  let fold f = apply (Set.fold f)
 
220
  let iter f = apply (Set.iter f)
 
221
end
 
222
 
 
223
module SetRef(Data:Project.Datatype.S) = Make_SetRef(Set.Make(Data))(Data)
 
224
 
 
225
(** {3 Queue} *)
 
226
 
 
227
module type QUEUE = sig
 
228
  type elt
 
229
  val add: elt -> unit
 
230
  val iter: (elt -> unit) -> unit
 
231
  val is_empty: unit -> bool
 
232
end
 
233
 
 
234
module Queue(Data:Project.Datatype.S)(Info:Signature.NAME_DPDS) = struct
 
235
 
 
236
  type elt = Data.t
 
237
      
 
238
  let state = ref (Queue.create ())
 
239
    
 
240
  include Project.Computation.Register
 
241
  (Datatype.Queue(Data))
 
242
  (struct
 
243
     type t = elt Queue.t
 
244
     let create = Queue.create
 
245
     let clear = Queue.clear
 
246
     let get () = !state
 
247
     let set x = state := x
 
248
   end)
 
249
  (Info)
 
250
 
 
251
  let add x = Queue.add x !state
 
252
  let iter f = Queue.iter f !state
 
253
  let is_empty () = Queue.is_empty !state
 
254
 
 
255
end
 
256
 
 
257
(** {3 Project itself} *)
 
258
 
 
259
module Project(Info:Signature.NAME_DPDS) = 
 
260
  Ref 
 
261
    (struct include Datatype.Project let default () = Project.dummy end)
 
262
    (Info)
 
263
 
 
264
(** {3 Apply Once} *)
 
265
 
 
266
let apply_once name dep f =
 
267
  let module First = 
 
268
    Ref
 
269
      (struct include Datatype.Bool let default () = true end)
 
270
      (struct let dependencies = dep let name = name end)
 
271
  in 
 
272
  (fun () ->
 
273
     if First.get () then begin
 
274
       First.set false;
 
275
       try f () with exn -> First.set true; raise exn
 
276
     end),
 
277
  First.self
 
278
 
 
279
(*
 
280
Local Variables:
 
281
compile-command: "LC_ALL=C make -C ../.. -j"
 
282
End:
 
283
*)