libisabelle-protocol/isabelle-common/protocol.ML
changeset 59209 907ce624bd20
parent 59208 109e995e5e3b
child 59210 df727a458e7c
     1.1 --- a/libisabelle-protocol/isabelle-common/protocol.ML	Thu Jan 21 17:29:33 2016 +0100
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,119 +0,0 @@
     1.4 -signature PROTOCOL = sig
     1.5 -  type name = string
     1.6 -  type ('i, 'o) operation =
     1.7 -    {from_lib : 'i codec,
     1.8 -     to_lib : 'o codec,
     1.9 -     action : 'i -> 'o}
    1.10 -
    1.11 -  type flags = {sequential: bool, bracket: bool, auto: bool (* ignored *)}
    1.12 -
    1.13 -  val default_flags : flags
    1.14 -  val join_flags : flags -> flags -> flags
    1.15 -  val print_flags : flags -> string
    1.16 -
    1.17 -  val add_operation : name -> ('i, 'o) operation -> flags -> unit
    1.18 -  val get_operation : name -> int -> XML.tree -> XML.tree
    1.19 -end
    1.20 -
    1.21 -structure Protocol: PROTOCOL = struct
    1.22 -
    1.23 -type name = string
    1.24 -type ('i, 'o) operation =
    1.25 -  {from_lib : 'i codec,
    1.26 -   to_lib : 'o codec,
    1.27 -   action : 'i -> 'o}
    1.28 -
    1.29 -type flags = {sequential: bool, bracket: bool, auto: bool}
    1.30 -
    1.31 -val default_flags = {sequential = false, bracket = false, auto = false}
    1.32 -
    1.33 -fun join_flags
    1.34 -  {sequential = seq1, bracket = br1, auto = a1}
    1.35 -  {sequential = seq2, bracket = br2, auto = a2} =
    1.36 -  {sequential = seq1 orelse seq2, bracket = br1 orelse br2, auto = a1 orelse a2}
    1.37 -
    1.38 -fun print_flags {sequential, bracket, auto} =
    1.39 -  "({sequential=" ^ Markup.print_bool sequential ^ "," ^
    1.40 -    "bracket=" ^ Markup.print_bool bracket ^ "," ^
    1.41 -    "auto=" ^ Markup.print_bool auto ^ "})"
    1.42 -
    1.43 -type raw_operation = int -> XML.tree -> XML.tree
    1.44 -
    1.45 -exception GENERIC of string
    1.46 -
    1.47 -val operations =
    1.48 -  Synchronized.var "libisabelle.operations" (Symtab.empty: raw_operation Symtab.table)
    1.49 -
    1.50 -val requests =
    1.51 -  Synchronized.var "libisabelle.requests" (Inttab.empty: (unit -> unit) Inttab.table)
    1.52 -
    1.53 -fun sequentialize name f =
    1.54 -  let
    1.55 -    val var = Synchronized.var ("libisabelle." ^ name) ()
    1.56 -  in
    1.57 -    fn x => Synchronized.change_result var (fn _ => (f x, ()))
    1.58 -  end
    1.59 -
    1.60 -fun bracketize f id x =
    1.61 -  let
    1.62 -    val start = [(Markup.functionN, "libisabelle_start"), ("id", Markup.print_int id)]
    1.63 -    val stop = [(Markup.functionN, "libisabelle_stop"), ("id", Markup.print_int id)]
    1.64 -    val _ = Output.protocol_message start []
    1.65 -    val res = f id x
    1.66 -    val _ = Output.protocol_message stop []
    1.67 -  in res end
    1.68 -
    1.69 -fun add_operation name {from_lib, to_lib, action} {sequential, bracket, ...} =
    1.70 -  let
    1.71 -    fun raw _ tree =
    1.72 -      case Codec.decode from_lib tree of
    1.73 -        Codec.Success i => Codec.encode to_lib (action i)
    1.74 -      | Codec.Failure (msg, _) => raise Fail ("decoding input failed for operation " ^ name ^ ": " ^ msg)
    1.75 -    val raw' = raw
    1.76 -      |> (if bracket then bracketize else I)
    1.77 -      |> (if sequential then sequentialize name else I)
    1.78 -  in
    1.79 -    Synchronized.change operations (Symtab.update (name, raw'))
    1.80 -  end
    1.81 -
    1.82 -fun get_operation name =
    1.83 -  case Symtab.lookup (Synchronized.value operations) name of
    1.84 -    SOME operation => operation
    1.85 -  | NONE => fn _ => raise Fail "libisabelle: unknown command"
    1.86 -
    1.87 -val _ = Isabelle_Process.protocol_command "libisabelle"
    1.88 -  (fn id :: name :: [arg] =>
    1.89 -    let
    1.90 -      val id = Markup.parse_int id
    1.91 -      val response = [(Markup.functionN, "libisabelle_response"), ("id", Markup.print_int id)]
    1.92 -      val args = YXML.parse arg
    1.93 -      fun exec f =
    1.94 -        let
    1.95 -          val future = Future.fork (fn () =>
    1.96 -            let
    1.97 -              val res = Exn.interruptible_capture (f id) args
    1.98 -              val yxml = YXML.string_of (Codec.encode (Codec.exn_result Codec.id) res)
    1.99 -            in
   1.100 -              Output.protocol_message response [yxml]
   1.101 -            end)
   1.102 -        in
   1.103 -          Synchronized.change requests (Inttab.update_new (id, fn () => Future.cancel future))
   1.104 -        end
   1.105 -    in
   1.106 -      exec (get_operation name)
   1.107 -    end)
   1.108 -
   1.109 -val _ = Isabelle_Process.protocol_command "libisabelle_cancel"
   1.110 -  (fn ids =>
   1.111 -    let
   1.112 -      fun remove id tab = (Inttab.lookup tab id, Inttab.delete_safe id tab)
   1.113 -      val _ =
   1.114 -        map Markup.parse_int ids
   1.115 -        |> fold_map remove
   1.116 -        |> Synchronized.change_result requests
   1.117 -        |> map (fn NONE => () | SOME f => f ())
   1.118 -    in
   1.119 -      ()
   1.120 -    end)
   1.121 -
   1.122 -end
   1.123 \ No newline at end of file