author | wenzelm |
Wed, 27 May 2020 20:51:25 +0200 | |
changeset 71912 | b9fbc93f3a24 |
parent 71911 | d25093536482 |
child 72103 | 7b318273a4aa |
permissions | -rw-r--r-- |
71849 | 1 |
(* Title: Pure/System/scala.ML |
43748 | 2 |
Author: Makarius |
3 |
||
71849 | 4 |
Support for Scala at runtime. |
43748 | 5 |
*) |
6 |
||
71849 | 7 |
signature SCALA = |
43748 | 8 |
sig |
71881 | 9 |
val functions: unit -> string list |
10 |
val check_function: Proof.context -> string * Position.T -> string |
|
71871
28def00726ca
more robust isabelle.Functions --- avoid Java reflection with unclear class/object treatment;
wenzelm
parents:
71849
diff
changeset
|
11 |
val promise_function: string -> string -> string future |
28def00726ca
more robust isabelle.Functions --- avoid Java reflection with unclear class/object treatment;
wenzelm
parents:
71849
diff
changeset
|
12 |
val function: string -> string -> string |
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
50682
diff
changeset
|
13 |
exception Null |
43748 | 14 |
end; |
15 |
||
71849 | 16 |
structure Scala: SCALA = |
43748 | 17 |
struct |
18 |
||
71871
28def00726ca
more robust isabelle.Functions --- avoid Java reflection with unclear class/object treatment;
wenzelm
parents:
71849
diff
changeset
|
19 |
(** invoke Scala functions from ML **) |
71849 | 20 |
|
21 |
val _ = Session.protocol_handler "isabelle.Scala"; |
|
43749 | 22 |
|
23 |
||
43748 | 24 |
(* pending promises *) |
25 |
||
52537 | 26 |
val new_id = string_of_int o Counter.make (); |
43748 | 27 |
|
28 |
val promises = |
|
71849 | 29 |
Synchronized.var "Scala.promises" (Symtab.empty: string future Symtab.table); |
43748 | 30 |
|
31 |
||
71871
28def00726ca
more robust isabelle.Functions --- avoid Java reflection with unclear class/object treatment;
wenzelm
parents:
71849
diff
changeset
|
32 |
(* invoke function *) |
43748 | 33 |
|
71871
28def00726ca
more robust isabelle.Functions --- avoid Java reflection with unclear class/object treatment;
wenzelm
parents:
71849
diff
changeset
|
34 |
fun promise_function name arg = |
43748 | 35 |
let |
71876 | 36 |
val _ = if Resources.is_pide () then () else raise Fail "PIDE session required"; |
43748 | 37 |
val id = new_id (); |
56333
38f1422ef473
support bulk messages consisting of small string segments, which are more healthy to the Poly/ML RTS and might prevent spurious GC crashes such as MTGCProcessMarkPointers::ScanAddressesInObject;
wenzelm
parents:
52537
diff
changeset
|
38 |
fun abort () = Output.protocol_message (Markup.cancel_scala id) []; |
66166 | 39 |
val promise = Future.promise_name "invoke_scala" abort : string future; |
43748 | 40 |
val _ = Synchronized.change promises (Symtab.update (id, promise)); |
70991
f9f7c34b7dd4
more scalable protocol_message: use XML.body directly (Output.output hook is not required);
wenzelm
parents:
66166
diff
changeset
|
41 |
val _ = Output.protocol_message (Markup.invoke_scala name id) [XML.Text arg]; |
43748 | 42 |
in promise end; |
43 |
||
71871
28def00726ca
more robust isabelle.Functions --- avoid Java reflection with unclear class/object treatment;
wenzelm
parents:
71849
diff
changeset
|
44 |
fun function name arg = Future.join (promise_function name arg); |
28def00726ca
more robust isabelle.Functions --- avoid Java reflection with unclear class/object treatment;
wenzelm
parents:
71849
diff
changeset
|
45 |
|
43748 | 46 |
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
50682
diff
changeset
|
47 |
(* fulfill *) |
43748 | 48 |
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
50682
diff
changeset
|
49 |
exception Null; |
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
50682
diff
changeset
|
50 |
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
50682
diff
changeset
|
51 |
fun fulfill id tag res = |
43748 | 52 |
let |
53 |
val result = |
|
54 |
(case tag of |
|
55 |
"0" => Exn.Exn Null |
|
43761
e72ba84ae58f
tuned signature -- corresponding to Scala version;
wenzelm
parents:
43749
diff
changeset
|
56 |
| "1" => Exn.Res res |
43748 | 57 |
| "2" => Exn.Exn (ERROR res) |
58 |
| "3" => Exn.Exn (Fail res) |
|
49470 | 59 |
| "4" => Exn.Exn Exn.Interrupt |
43748 | 60 |
| _ => raise Fail "Bad tag"); |
61 |
val promise = |
|
62 |
Synchronized.change_result promises |
|
63 |
(fn tab => (the (Symtab.lookup tab id), Symtab.delete id tab)); |
|
64 |
val _ = Future.fulfill_result promise result; |
|
65 |
in () end; |
|
66 |
||
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
50682
diff
changeset
|
67 |
val _ = |
71849 | 68 |
Isabelle_Process.protocol_command "Scala.fulfill" |
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
50682
diff
changeset
|
69 |
(fn [id, tag, res] => |
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
50682
diff
changeset
|
70 |
fulfill id tag res |
62505 | 71 |
handle exn => if Exn.is_interrupt exn then () else Exn.reraise exn); |
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
50682
diff
changeset
|
72 |
|
71872 | 73 |
|
71881 | 74 |
(* registered functions *) |
71872 | 75 |
|
71881 | 76 |
fun functions () = space_explode "," (getenv "ISABELLE_SCALA_FUNCTIONS"); |
71872 | 77 |
|
71911 | 78 |
fun check_function ctxt arg = |
71912 | 79 |
Completion.check_entity Markup.scala_functionN |
80 |
(functions () |> sort_strings |> map (rpair Position.none)) ctxt arg; |
|
71881 | 81 |
|
82 |
val _ = Theory.setup |
|
71898 | 83 |
(ML_Antiquotation.inline_embedded \<^binding>\<open>scala_function\<close> |
71881 | 84 |
(Args.context -- Scan.lift Parse.embedded_position |
85 |
>> (uncurry check_function #> ML_Syntax.print_string)) #> |
|
86 |
ML_Antiquotation.value_embedded \<^binding>\<open>scala\<close> |
|
87 |
(Args.context -- Scan.lift Args.embedded_position >> (fn (ctxt, arg) => |
|
88 |
let val name = check_function ctxt arg |
|
89 |
in ML_Syntax.atomic ("Scala.function " ^ ML_Syntax.print_string name) end))); |
|
71872 | 90 |
|
43748 | 91 |
end; |