1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
(**************************************************************************)
(* *)
(* OCaml *)
(* *)
(* Luc Maranget, projet Moscova, INRIA Rocquencourt *)
(* *)
(* Copyright 2000 Institut National de Recherche en Informatique et *)
(* en Automatique. *)
(* *)
(* All rights reserved. This file is distributed under the terms of *)
(* the GNU Lesser General Public License version 2.1, with the *)
(* special exception on linking described in the file LICENSE. *)
(* *)
(**************************************************************************)
(*
This module transforms generic switches in combinations
of if tests and switches.
*)
(* For detecting action sharing, object style *)
(* Store for actions in object style:
act_store : store an action, returns index in table
In case an action with equal key exists, returns index
of the stored action. Otherwise add entry in table.
act_store_shared : This stored action will always be shared.
act_get : retrieve table
act_get_shared : retrieve table, with sharing explicit
*)
type 'a shared = Shared of 'a | Single of 'a
type ('a, 'ctx) t_store =
{act_get : unit -> 'a array ;
act_get_shared : unit -> 'a shared array ;
act_store : 'ctx -> 'a -> int ;
act_store_shared : 'ctx -> 'a -> int ; }
module type Stored = sig
type t
type key
val compare_key : key -> key -> int
val make_key : t -> key option
end
module type CtxStored = sig
include Stored
type context
val make_key : context -> t -> key option
end
module CtxStore(A:CtxStored) :
sig
val mk_store : unit -> (A.t, A.context) t_store
end
module Store(A:Stored) :
sig
val mk_store : unit -> (A.t, unit) t_store
end
(* Arguments to the Make functor *)
module type S =
sig
(* type of basic tests *)
type primitive
(* basic tests themselves *)
val eqint : primitive
val neint : primitive
val leint : primitive
val ltint : primitive
val geint : primitive
val gtint : primitive
(* type of source locations *)
type loc
(* type of switch scrutinees *)
type arg
(* type of tests on scrutinees *)
type test
(* type of actions *)
type act
(* Various constructors, for making a binder,
adding one integer, etc. *)
(* [bind arg cont] should bind the expression arg to a variable,
then call [cont] on that variable, and return the term made of
the binding and the result of the call. *)
val bind : arg -> (arg -> act) -> act
(* [make_const n] generates a term for the integer constant [n] *)
val make_const : int -> arg
(* [make_offset arg n] generates a term for adding the constant
integer [n] to the term [arg] *)
val make_offset : arg -> int -> arg
(* [make_prim p args] generates a test using the primitive operation [p]
applied to arguments [args] *)
val make_prim : primitive -> arg list -> test
(* [make_isout h arg] generates a test that holds when [arg] is out of
the interval [0, h] *)
val make_isout : arg -> arg -> test
(* [make_isin h arg] generates a test that holds when [arg] is in
the interval [0, h] *)
val make_isin : arg -> arg -> test
(* [make_is_nonzero arg] generates a test that holds when [arg] is any
value except 0 *)
val make_is_nonzero : arg -> test
(* [arg_as_test arg] casts [arg], known to be either 0 or 1,
to a boolean test *)
val arg_as_test : arg -> test
(* [make_if cond ifso ifnot] generates a conditional branch *)
val make_if : test -> act -> act -> act
(* construct an actual switch :
make_switch arg cases acts
NB: cases is in the value form *)
val make_switch : loc -> arg -> int array -> act array -> act
(* Build last minute sharing of action stuff *)
val make_catch : act -> int * (act -> act)
val make_exit : int -> act
end
(*
Make.zyva arg low high cases actions where
- arg is the argument of the switch.
- low, high are the interval limits.
- cases is a list of sub-interval and action indices
- actions is an array of actions.
All these arguments specify a switch construct and zyva
returns an action that performs the switch.
*)
module Make :
functor (Arg : S) ->
sig
(* Standard entry point, sharing is tracked *)
val zyva :
Arg.loc ->
(int * int) ->
Arg.arg ->
(int * int * int) array ->
(Arg.act, _) t_store ->
Arg.act
(* Output test sequence, sharing tracked *)
val test_sequence :
Arg.arg ->
(int * int * int) array ->
(Arg.act, _) t_store ->
Arg.act
end
|