diff options
Diffstat (limited to 'lib/protocols')
| -rw-r--r-- | lib/protocols/Admission.ml | 21 | ||||
| -rw-r--r-- | lib/protocols/Admission.mli | 11 | ||||
| -rw-r--r-- | lib/protocols/Evaluator.ml | 10 | ||||
| -rw-r--r-- | lib/protocols/Evaluator.mli | 15 | ||||
| -rw-r--r-- | lib/protocols/Executable.ml | 12 | ||||
| -rw-r--r-- | lib/protocols/Executable.mli | 19 | ||||
| -rw-r--r-- | lib/protocols/Handle.ml | 1 | ||||
| -rw-r--r-- | lib/protocols/Handle.mli | 1 | ||||
| -rw-r--r-- | lib/protocols/Relation.ml | 20 | ||||
| -rw-r--r-- | lib/protocols/Relation.mli | 10 |
10 files changed, 116 insertions, 4 deletions
diff --git a/lib/protocols/Admission.ml b/lib/protocols/Admission.ml new file mode 100644 index 0000000..c29f192 --- /dev/null +++ b/lib/protocols/Admission.ml @@ -0,0 +1,21 @@ +module Error = struct + open Concepts.Condition + + let not_admitting () = + condition "not-admitting" "A handle was expected to carry the admission protocol and did not" + empty +end + +type violations = (string * Concepts.Tuple.t) list + +class type implementation = object + method check : (violations, Concepts.Condition.condition) result +end + +type Handle.protocol += Admission of implementation +type t = implementation + +let make impl = Admission (impl :> implementation) +let from handle = Handle.into handle (function Admission impl -> Some impl | _ -> None) +let require handle = from handle |> Option.to_result ~none:(Error.not_admitting ()) +let check i = Handle.invoke i (fun o -> o#check) diff --git a/lib/protocols/Admission.mli b/lib/protocols/Admission.mli new file mode 100644 index 0000000..7f0c596 --- /dev/null +++ b/lib/protocols/Admission.mli @@ -0,0 +1,11 @@ +type t +type violations = (string * Concepts.Tuple.t) list + +class type implementation = object + method check : (violations, Concepts.Condition.condition) result +end + +val make : #implementation -> Handle.protocol +val from : Handle.t -> t Handle.interface option +val require : Handle.t -> (t Handle.interface, Concepts.Condition.condition) result +val check : t Handle.interface -> (violations, Concepts.Condition.condition) result diff --git a/lib/protocols/Evaluator.ml b/lib/protocols/Evaluator.ml index 789fb9d..6a63431 100644 --- a/lib/protocols/Evaluator.ml +++ b/lib/protocols/Evaluator.ml @@ -1,5 +1,10 @@ +type kind = .. + class type implementation = object - method invoke : Handle.t -> (Handle.t, Concepts.Condition.condition) result + method parse : string -> (kind, Concepts.Condition.condition) result + + method eval : + kind -> Handle.t list -> within:Handle.t -> (Handle.t, Concepts.Condition.condition) result end type Handle.protocol += Evaluator of implementation @@ -8,4 +13,5 @@ type t = implementation let make impl = Evaluator (impl :> implementation) let from handle = Handle.into handle (function Evaluator impl -> Some impl | _ -> None) let require = Handle.require from -let invoke i program = Handle.invoke i (fun o -> o#invoke program) +let parse i source = Handle.invoke i (fun o -> o#parse source) +let eval i kind inputs ~within = Handle.invoke i (fun o -> o#eval kind inputs ~within) diff --git a/lib/protocols/Evaluator.mli b/lib/protocols/Evaluator.mli index 3d42b5c..934c5e3 100644 --- a/lib/protocols/Evaluator.mli +++ b/lib/protocols/Evaluator.mli @@ -1,10 +1,21 @@ type t +type kind = .. class type implementation = object - method invoke : Handle.t -> (Handle.t, Concepts.Condition.condition) result + method parse : string -> (kind, Concepts.Condition.condition) result + + method eval : + kind -> Handle.t list -> within:Handle.t -> (Handle.t, Concepts.Condition.condition) result end val make : #implementation -> Handle.protocol val from : Handle.t -> t Handle.interface option val require : Handle.t -> (t Handle.interface, Concepts.Condition.condition) result -val invoke : t Handle.interface -> Handle.t -> (Handle.t, Concepts.Condition.condition) result +val parse : t Handle.interface -> string -> (kind, Concepts.Condition.condition) result + +val eval : + t Handle.interface -> + kind -> + Handle.t list -> + within:Handle.t -> + (Handle.t, Concepts.Condition.condition) result diff --git a/lib/protocols/Executable.ml b/lib/protocols/Executable.ml new file mode 100644 index 0000000..5dea52c --- /dev/null +++ b/lib/protocols/Executable.ml @@ -0,0 +1,12 @@ +class type implementation = object + method invoke : + Handle.t list -> within:Handle.t -> (Handle.t, Concepts.Condition.condition) result +end + +type Handle.protocol += Executable of implementation +type t = implementation + +let make impl = Executable (impl :> implementation) +let from handle = Handle.into handle (function Executable impl -> Some impl | _ -> None) +let require = Handle.require from +let invoke i inputs ~within = Handle.invoke i (fun o -> o#invoke inputs ~within) diff --git a/lib/protocols/Executable.mli b/lib/protocols/Executable.mli new file mode 100644 index 0000000..ccb63e1 --- /dev/null +++ b/lib/protocols/Executable.mli @@ -0,0 +1,19 @@ +type t + +(** [within] is the directory the program's paths resolve against: the + branch state a stored program was read through, or whatever part of + the tree a caller hands over. *) +class type implementation = object + method invoke : + Handle.t list -> within:Handle.t -> (Handle.t, Concepts.Condition.condition) result +end + +val make : #implementation -> Handle.protocol +val from : Handle.t -> t Handle.interface option +val require : Handle.t -> (t Handle.interface, Concepts.Condition.condition) result + +val invoke : + t Handle.interface -> + Handle.t list -> + within:Handle.t -> + (Handle.t, Concepts.Condition.condition) result diff --git a/lib/protocols/Handle.ml b/lib/protocols/Handle.ml index dd923c6..0c5f3cc 100644 --- a/lib/protocols/Handle.ml +++ b/lib/protocols/Handle.ml @@ -91,4 +91,5 @@ let move handle = let equal h1 h2 = Concepts.Hash.hash_equals (object_of h1)#hash (object_of h2)#hash let hash h = (object_of h)#hash let protocols h = (object_of h)#protocols +let releasing handle f = Fun.protect ~finally:(fun () -> release handle) f let require f h = Option.to_result ~none:(Error.unimplemented_protocol (to_string h)) (f h) diff --git a/lib/protocols/Handle.mli b/lib/protocols/Handle.mli index 1c3b9d4..94734e4 100644 --- a/lib/protocols/Handle.mli +++ b/lib/protocols/Handle.mli @@ -19,6 +19,7 @@ val copy : t -> t option val move : t -> t val equal : t -> t -> bool val release : t -> unit +val releasing : t -> (unit -> 'a) -> 'a val hash : t -> Concepts.Hash.hash val protocols : t -> protocol list val to_string : t -> string diff --git a/lib/protocols/Relation.ml b/lib/protocols/Relation.ml index 3962c9c..c1cdfee 100644 --- a/lib/protocols/Relation.ml +++ b/lib/protocols/Relation.ml @@ -8,6 +8,7 @@ end class type implementation = object method contains : Concepts.Tuple.t -> (bool, Concepts.Condition.condition) result + method modes : (Concepts.Mode.t, Concepts.Condition.condition) result end type Handle.protocol += Relation of implementation @@ -17,3 +18,22 @@ let make impl = Relation (impl :> implementation) let from handle = Handle.into handle (function Relation impl -> Some impl | _ -> None) let require handle = from handle |> Option.to_result ~none:(Error.not_a_relation ()) let contains i tuple = Handle.invoke i (fun o -> o#contains tuple) +let modes i = Handle.invoke i (fun o -> o#modes) + +let heading relation = + let open Utilities.Result in + let* schematics = Handle.require Schematics.from relation in + let* description = Schematics.describe schematics in + match description with + | Schematics.Relation heading -> Ok heading + | _ -> Error (Error.not_a_relation ()) + +let read relation = + let open Utilities.Result in + let* heading = heading relation in + let* enumerable = Enumerable.require relation in + let* cursor = Enumerable.enumerate enumerable in + Handle.releasing cursor (fun () -> + let* scan = Cursor.require cursor in + let* tuples = Cursor.drain scan () in + Ok (heading, BatFingerTree.to_list tuples) ) diff --git a/lib/protocols/Relation.mli b/lib/protocols/Relation.mli index be11cc1..28dfdff 100644 --- a/lib/protocols/Relation.mli +++ b/lib/protocols/Relation.mli @@ -2,9 +2,19 @@ type t class type implementation = object method contains : Concepts.Tuple.t -> (bool, Concepts.Condition.condition) result + method modes : (Concepts.Mode.t, Concepts.Condition.condition) result end val make : #implementation -> Handle.protocol val from : Handle.t -> t Handle.interface option val require : Handle.t -> (t Handle.interface, Concepts.Condition.condition) result val contains : t Handle.interface -> Concepts.Tuple.t -> (bool, Concepts.Condition.condition) result +val modes : t Handle.interface -> (Concepts.Mode.t, Concepts.Condition.condition) result + +(** the heading a relation describes itself with. *) +val heading : Handle.t -> (Schematics.relation_description, Concepts.Condition.condition) result + +(** the heading and tuples of a relation, read whole. *) +val read : + Handle.t -> + (Schematics.relation_description * Concepts.Tuple.t list, Concepts.Condition.condition) result |
