heptagon/compiler/global/clocks.ml

106 lines
2.9 KiB
OCaml
Raw Normal View History

2010-07-23 22:06:06 +02:00
(**************************************************************************)
(* *)
(* Heptagon *)
(* *)
(* Author : Marc Pouzet *)
(* Organization : Demons, LRI, University of Paris-Sud, Orsay *)
(* *)
(**************************************************************************)
open Names
open Idents
open Types
2010-11-04 18:07:17 +01:00
2010-07-23 22:06:06 +02:00
type ct =
| Ck of ck
| Cprod of ct list
and ck =
| Cbase
| Cvar of link ref
| Con of ck * constructor_name * var_ident
and link =
| Cindex of int
| Clink of ck
exception Unify
2010-11-23 17:10:11 +01:00
let invalid_clock = Cprod []
2010-07-23 22:06:06 +02:00
let index = ref 0
let gen_index () = (incr index; !index)
(** returns a new clock variable *)
let fresh_clock () = Cvar { contents = Cindex (gen_index ()); }
2010-07-23 22:06:06 +02:00
(** returns the canonic (short) representant of a [ck]
and update it to this value. *)
let rec ck_repr ck = match ck with
| Cbase | Con _ | Cvar { contents = Cindex _ } -> ck
| Cvar (({ contents = Clink ck } as link)) ->
let ck = ck_repr ck in (link.contents <- Clink ck; ck)
(** verifies that index is fresh in ck. *)
let rec occur_check index ck =
let ck = ck_repr ck in
match ck with
| Cbase -> ()
| Cvar { contents = Cindex n } when index <> n -> ()
| Con (ck, _, _) -> occur_check index ck
| _ -> raise Unify
2010-11-23 17:10:11 +01:00
(** unify ck *)
let rec unify_ck ck1 ck2 =
2010-07-23 22:06:06 +02:00
let ck1 = ck_repr ck1 in
let ck2 = ck_repr ck2 in
if ck1 == ck2
then ()
else
(match (ck1, ck2) with
| (Cbase, Cbase) -> ()
| (Cvar { contents = Cindex n1 }, Cvar { contents = Cindex n2 }) when
n1 = n2 -> ()
| (Cvar (({ contents = Cindex n1 } as v)), _) ->
(occur_check n1 ck2; v.contents <- Clink ck2)
| (_, Cvar (({ contents = Cindex n2 } as v))) ->
(occur_check n2 ck1; v.contents <- Clink ck1)
| (Con (ck1, c1, n1), Con (ck2, c2, n2)) when (c1 = c2) & (n1 = n2) ->
unify_ck ck1 ck2
| _ -> raise Unify)
2010-11-23 17:10:11 +01:00
(** unify ct *)
2010-07-23 22:06:06 +02:00
let rec unify t1 t2 =
2010-11-23 17:10:11 +01:00
if t1 == t2 then () else
2010-07-23 22:06:06 +02:00
match (t1, t2) with
| (Ck ck1, Ck ck2) -> unify_ck ck1 ck2
| (Cprod t1_list, Cprod t2_list) -> unify_list t1_list t2_list
| _ -> raise Unify
and unify_list t1_list t2_list =
2010-11-23 17:10:11 +01:00
try List.iter2 unify t1_list t2_list
with _ -> raise Unify
2010-07-23 22:06:06 +02:00
let rec skeleton ck = function
| Tprod ty_list ->
(match ty_list with
2011-04-14 18:06:54 +02:00
| [] -> Ck ck
| _ -> Cprod (List.map (skeleton ck) ty_list))
2011-03-09 00:02:30 +01:00
| Tarray (t, _) -> skeleton ck t
2011-04-14 18:06:54 +02:00
| Tid _ | Tinvalid -> Ck ck
2010-07-23 22:06:06 +02:00
2010-11-04 18:07:17 +01:00
(* TODO here it implicitely says that the base clock is Cbase
and that all tuple is on Cbase *)
let ckofct = function | Ck ck -> ck_repr ck | Cprod _ -> Cbase
2010-07-23 22:06:06 +02:00