author | wenzelm |
Mon, 13 Mar 2023 11:02:26 +0100 | |
changeset 77622 | f458547b4f0f |
parent 77028 | f5896dea6fce |
child 78605 | 0bbbf8e26708 |
permissions | -rw-r--r-- |
71849 | 1 |
/* Title: Pure/System/scala.scala |
43744
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
2 |
Author: Makarius |
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
3 |
|
71849 | 4 |
Support for Scala at runtime. |
43744
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
5 |
*/ |
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
6 |
|
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
7 |
package isabelle |
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
8 |
|
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
9 |
|
75654 | 10 |
import java.io.{File => JFile, PrintStream, ByteArrayOutputStream, OutputStream} |
11 |
||
12 |
import scala.collection.mutable |
|
13 |
import scala.annotation.tailrec |
|
56730
e723f041b6d0
tuned signature -- separate pool for JFuture tasks, which can be canceled;
wenzelm
parents:
56667
diff
changeset
|
14 |
|
75654 | 15 |
import dotty.tools.dotc.CompilationUnit |
16 |
import dotty.tools.dotc.ast.Trees.PackageDef |
|
17 |
import dotty.tools.dotc.ast.untpd |
|
18 |
import dotty.tools.dotc.core.Contexts.{Context => CompilerContext} |
|
19 |
import dotty.tools.dotc.core.NameOps.moduleClassName |
|
20 |
import dotty.tools.dotc.core.{Phases, StdNames} |
|
21 |
import dotty.tools.dotc.interfaces |
|
22 |
import dotty.tools.dotc.reporting.{Diagnostic, ConsoleReporter} |
|
23 |
import dotty.tools.dotc.util.{SourceFile, SourcePosition, NoSourcePosition} |
|
24 |
import dotty.tools.repl |
|
25 |
import dotty.tools.repl.{ReplCompiler, ReplDriver} |
|
26 |
||
43744
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
27 |
|
75393 | 28 |
object Scala { |
72193 | 29 |
/** registered functions **/ |
30 |
||
75393 | 31 |
abstract class Fun(val name: String, val thread: Boolean = false) { |
72193 | 32 |
override def toString: String = name |
75586 | 33 |
def single: Boolean = false |
34 |
def bytes: Boolean = false |
|
72756 | 35 |
def position: Properties.T = here.position |
36 |
def here: Scala_Project.Here |
|
77027 | 37 |
def invoke(session: Session, args: List[Bytes]): List[Bytes] |
73565 | 38 |
} |
39 |
||
75588 | 40 |
trait Single_Fun extends Fun { override def single: Boolean = true } |
41 |
trait Bytes_Fun extends Fun { override def bytes: Boolean = true } |
|
75586 | 42 |
|
73565 | 43 |
abstract class Fun_Strings(name: String, thread: Boolean = false) |
75393 | 44 |
extends Fun(name, thread = thread) { |
77027 | 45 |
override def invoke(session: Session, args: List[Bytes]): List[Bytes] = |
73565 | 46 |
apply(args.map(_.text)).map(Bytes.apply) |
47 |
def apply(args: List[String]): List[String] |
|
48 |
} |
|
49 |
||
50 |
abstract class Fun_String(name: String, thread: Boolean = false) |
|
75588 | 51 |
extends Fun_Strings(name, thread = thread) with Single_Fun { |
73565 | 52 |
override def apply(args: List[String]): List[String] = |
73571 | 53 |
List(apply(Library.the_single(args))) |
72193 | 54 |
def apply(arg: String): String |
55 |
} |
|
56 |
||
75588 | 57 |
abstract class Fun_Bytes(name: String, thread: Boolean = false) |
58 |
extends Fun(name, thread = thread) with Single_Fun with Bytes_Fun { |
|
77027 | 59 |
override def invoke(session: Session, args: List[Bytes]): List[Bytes] = |
75588 | 60 |
List(apply(Library.the_single(args))) |
61 |
def apply(arg: Bytes): Bytes |
|
62 |
} |
|
63 |
||
75586 | 64 |
val encode_fun: XML.Encode.T[Fun] = { fun => |
65 |
import XML.Encode._ |
|
66 |
pair(string, pair(pair(bool, bool), properties))( |
|
67 |
fun.name, ((fun.single, fun.bytes), fun.position)) |
|
68 |
} |
|
69 |
||
72193 | 70 |
class Functions(val functions: Fun*) extends Isabelle_System.Service |
71 |
||
72 |
lazy val functions: List[Fun] = |
|
73 |
Isabelle_System.make_services(classOf[Functions]).flatMap(_.functions) |
|
74 |
||
75 |
||
76 |
||
72152 | 77 |
/** demo functions **/ |
78 |
||
75393 | 79 |
object Echo extends Fun_String("echo") { |
72756 | 80 |
val here = Scala_Project.here |
72193 | 81 |
def apply(arg: String): String = arg |
82 |
} |
|
72152 | 83 |
|
75393 | 84 |
object Sleep extends Fun_String("sleep") { |
72756 | 85 |
val here = Scala_Project.here |
75393 | 86 |
def apply(seconds: String): String = { |
72193 | 87 |
val t = |
88 |
seconds match { |
|
89 |
case Value.Double(s) => Time.seconds(s) |
|
90 |
case _ => error("Malformed argument: " + quote(seconds)) |
|
91 |
} |
|
92 |
val t0 = Time.now() |
|
73702
7202e12cb324
tuned signature --- following hints by IntelliJ IDEA;
wenzelm
parents:
73576
diff
changeset
|
93 |
t.sleep() |
72193 | 94 |
val t1 = Time.now() |
95 |
(t1 - t0).toString |
|
96 |
} |
|
72152 | 97 |
} |
98 |
||
99 |
||
100 |
||
71870 | 101 |
/** compiler **/ |
71850 | 102 |
|
75393 | 103 |
object Compiler { |
75654 | 104 |
object Message { |
105 |
object Kind extends Enumeration { |
|
106 |
val error, warning, info, other = Value |
|
107 |
} |
|
108 |
private val Header = """^--.* (Error|Warning|Info): .*$""".r |
|
109 |
val header_kind: String => Kind.Value = |
|
110 |
{ |
|
111 |
case "Error" => Kind.error |
|
112 |
case "Warning" => Kind.warning |
|
113 |
case "Info" => Kind.info |
|
114 |
case _ => Kind.other |
|
115 |
} |
|
116 |
||
117 |
// see compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala |
|
118 |
def split(str: String): List[Message] = { |
|
119 |
var kind = Kind.other |
|
120 |
val text = new mutable.StringBuilder |
|
121 |
val result = new mutable.ListBuffer[Message] |
|
122 |
||
123 |
def flush(): Unit = { |
|
124 |
if (text.nonEmpty) { result += Message(kind, text.toString) } |
|
125 |
kind = Kind.other |
|
126 |
text.clear() |
|
127 |
} |
|
128 |
||
129 |
for (line <- Library.trim_split_lines(str)) { |
|
130 |
line match { |
|
131 |
case Header(k) => flush(); kind = header_kind(k) |
|
132 |
case _ => if (line.startsWith("-- ")) flush() |
|
133 |
} |
|
134 |
if (text.nonEmpty) { text += '\n' } |
|
135 |
text ++= line |
|
136 |
} |
|
137 |
flush() |
|
138 |
result.toList |
|
139 |
} |
|
140 |
} |
|
141 |
||
142 |
sealed case class Message(kind: Message.Kind.Value, text: String) |
|
143 |
{ |
|
144 |
def is_error: Boolean = kind == Message.Kind.error |
|
145 |
override def toString: String = text |
|
146 |
} |
|
147 |
||
148 |
sealed case class Result( |
|
149 |
state: repl.State, |
|
150 |
messages: List[Message], |
|
151 |
unit: Option[CompilationUnit] = None |
|
152 |
) { |
|
153 |
val errors: List[String] = messages.flatMap(msg => if (msg.is_error) Some(msg.text) else None) |
|
154 |
def ok: Boolean = errors.isEmpty |
|
155 |
def check_state: repl.State = if (ok) state else error(cat_lines(errors)) |
|
156 |
override def toString: String = if (ok) "Result(ok)" else "Result(error)" |
|
157 |
} |
|
75443 | 158 |
|
71868 | 159 |
def context( |
75654 | 160 |
settings: List[String] = Nil, |
75702 | 161 |
jar_files: List[JFile] = Nil, |
75442 | 162 |
class_loader: Option[ClassLoader] = None |
75393 | 163 |
): Context = { |
75654 | 164 |
val isabelle_settings = |
165 |
Word.explode(Isabelle_System.getenv_strict("ISABELLE_SCALAC_OPTIONS")) |
|
75705 | 166 |
val classpath = Classpath(jar_files = jar_files) |
167 |
new Context(isabelle_settings ::: settings, classpath, class_loader) |
|
71864 | 168 |
} |
71850 | 169 |
|
75442 | 170 |
class Context private [Compiler]( |
75705 | 171 |
_settings: List[String], |
172 |
val classpath: Classpath, |
|
75654 | 173 |
val class_loader: Option[ClassLoader] = None |
75442 | 174 |
) { |
75705 | 175 |
def settings: List[String] = |
176 |
_settings ::: List("-classpath", classpath.platform_path) |
|
177 |
||
75654 | 178 |
private val out_stream = new ByteArrayOutputStream(1024) |
179 |
private val out = new PrintStream(out_stream) |
|
180 |
private val driver: ReplDriver = new ReplDriver(settings.toArray, out, class_loader) |
|
71869 | 181 |
|
75654 | 182 |
def init_state: repl.State = driver.initialState |
71850 | 183 |
|
75654 | 184 |
def compile(source: String, state: repl.State = init_state): Result = { |
185 |
out.flush() |
|
186 |
out_stream.reset() |
|
76537 | 187 |
given repl.State = state |
188 |
val state1 = driver.run(source) |
|
75654 | 189 |
out.flush() |
190 |
val messages = Message.split(out_stream.toString(UTF8.charset)) |
|
191 |
out_stream.reset() |
|
192 |
Result(state1, messages) |
|
193 |
} |
|
71864 | 194 |
} |
72194 | 195 |
} |
71850 | 196 |
|
75393 | 197 |
object Toplevel extends Fun_String("scala_toplevel") { |
72756 | 198 |
val here = Scala_Project.here |
75654 | 199 |
def apply(source: String): String = { |
72194 | 200 |
val errors = |
75654 | 201 |
try { Compiler.context().compile(source).errors.map("Scala error: " + _) } |
72194 | 202 |
catch { case ERROR(msg) => List(msg) } |
203 |
locally { import XML.Encode._; YXML.string_of_body(list(string)(errors)) } |
|
72193 | 204 |
} |
71872 | 205 |
} |
206 |
||
71850 | 207 |
|
208 |
||
75444
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
209 |
/** interpreter thread **/ |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
210 |
|
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
211 |
object Interpreter { |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
212 |
/* requests */ |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
213 |
|
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
214 |
sealed abstract class Request |
75654 | 215 |
case class Execute(command: (Compiler.Context, repl.State) => repl.State) extends Request |
75444
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
216 |
case object Shutdown extends Request |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
217 |
|
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
218 |
|
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
219 |
/* known interpreters */ |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
220 |
|
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
221 |
private val known = Synchronized(Set.empty[Interpreter]) |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
222 |
|
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
223 |
def add(interpreter: Interpreter): Unit = known.change(_ + interpreter) |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
224 |
def del(interpreter: Interpreter): Unit = known.change(_ - interpreter) |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
225 |
|
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
226 |
def get[A](which: PartialFunction[Interpreter, A]): Option[A] = |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
227 |
known.value.collectFirst(which) |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
228 |
} |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
229 |
|
75654 | 230 |
class Interpreter(context: Compiler.Context, out: OutputStream = Console.out) { |
75444
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
231 |
interpreter => |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
232 |
|
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
233 |
private val running = Synchronized[Option[Thread]](None) |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
234 |
def running_thread(thread: Thread): Boolean = running.value.contains(thread) |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
235 |
def interrupt_thread(): Unit = running.change({ opt => opt.foreach(_.interrupt()); opt }) |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
236 |
|
75654 | 237 |
private var state = context.init_state |
238 |
||
75444
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
239 |
private lazy val thread: Consumer_Thread[Interpreter.Request] = |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
240 |
Consumer_Thread.fork("Scala.Interpreter") { |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
241 |
case Interpreter.Execute(command) => |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
242 |
try { |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
243 |
running.change(_ => Some(Thread.currentThread())) |
75654 | 244 |
state = command(context, state) |
75444
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
245 |
} |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
246 |
finally { |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
247 |
running.change(_ => None) |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
248 |
Exn.Interrupt.dispose() |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
249 |
} |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
250 |
true |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
251 |
case Interpreter.Shutdown => |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
252 |
Interpreter.del(interpreter) |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
253 |
false |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
254 |
} |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
255 |
|
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
256 |
def shutdown(): Unit = { |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
257 |
thread.send(Interpreter.Shutdown) |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
258 |
interrupt_thread() |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
259 |
thread.shutdown() |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
260 |
} |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
261 |
|
75654 | 262 |
def execute(command: (Compiler.Context, repl.State) => repl.State): Unit = |
75444
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
263 |
thread.send(Interpreter.Execute(command)) |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
264 |
|
75654 | 265 |
def reset(): Unit = |
266 |
thread.send(Interpreter.Execute((context, _) => context.init_state)) |
|
267 |
||
75444
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
268 |
Interpreter.add(interpreter) |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
269 |
thread |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
270 |
} |
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
271 |
|
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
272 |
|
331f96a67924
clarified management of interpreter threads: more generic;
wenzelm
parents:
75443
diff
changeset
|
273 |
|
71871
28def00726ca
more robust isabelle.Functions --- avoid Java reflection with unclear class/object treatment;
wenzelm
parents:
71870
diff
changeset
|
274 |
/** invoke Scala functions from ML **/ |
28def00726ca
more robust isabelle.Functions --- avoid Java reflection with unclear class/object treatment;
wenzelm
parents:
71870
diff
changeset
|
275 |
|
28def00726ca
more robust isabelle.Functions --- avoid Java reflection with unclear class/object treatment;
wenzelm
parents:
71870
diff
changeset
|
276 |
/* invoke function */ |
43748 | 277 |
|
75393 | 278 |
object Tag extends Enumeration { |
65638 | 279 |
val NULL, OK, ERROR, FAIL, INTERRUPT = Value |
43748 | 280 |
} |
43744
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
281 |
|
73419
22f3f2117ed7
clarified signature: function_thread is determined in Isabelle/Scala, not Isabelle/ML;
wenzelm
parents:
73418
diff
changeset
|
282 |
def function_thread(name: String): Boolean = |
22f3f2117ed7
clarified signature: function_thread is determined in Isabelle/Scala, not Isabelle/ML;
wenzelm
parents:
73418
diff
changeset
|
283 |
functions.find(fun => fun.name == name) match { |
22f3f2117ed7
clarified signature: function_thread is determined in Isabelle/Scala, not Isabelle/ML;
wenzelm
parents:
73418
diff
changeset
|
284 |
case Some(fun) => fun.thread |
22f3f2117ed7
clarified signature: function_thread is determined in Isabelle/Scala, not Isabelle/ML;
wenzelm
parents:
73418
diff
changeset
|
285 |
case None => false |
22f3f2117ed7
clarified signature: function_thread is determined in Isabelle/Scala, not Isabelle/ML;
wenzelm
parents:
73418
diff
changeset
|
286 |
} |
22f3f2117ed7
clarified signature: function_thread is determined in Isabelle/Scala, not Isabelle/ML;
wenzelm
parents:
73418
diff
changeset
|
287 |
|
77027 | 288 |
def function_body(session: Session, name: String, args: List[Bytes]): (Tag.Value, List[Bytes]) = |
71873 | 289 |
functions.find(fun => fun.name == name) match { |
290 |
case Some(fun) => |
|
77027 | 291 |
Exn.capture { fun.invoke(session, args) } match { |
73565 | 292 |
case Exn.Res(null) => (Tag.NULL, Nil) |
43748 | 293 |
case Exn.Res(res) => (Tag.OK, res) |
73565 | 294 |
case Exn.Exn(Exn.Interrupt()) => (Tag.INTERRUPT, Nil) |
295 |
case Exn.Exn(e) => (Tag.ERROR, List(Bytes(Exn.message(e)))) |
|
43748 | 296 |
} |
73565 | 297 |
case None => (Tag.FAIL, List(Bytes("Unknown Isabelle/Scala function: " + quote(name)))) |
43748 | 298 |
} |
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
299 |
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
300 |
|
72157 | 301 |
/* protocol handler */ |
302 |
||
75393 | 303 |
class Handler extends Session.Protocol_Handler { |
72157 | 304 |
private var session: Session = null |
305 |
private var futures = Map.empty[String, Future[Unit]] |
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
306 |
|
72213 | 307 |
override def init(session: Session): Unit = |
308 |
synchronized { this.session = session } |
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
309 |
|
75380 | 310 |
override def exit(): Unit = synchronized { |
72157 | 311 |
for ((id, future) <- futures) cancel(id, future) |
312 |
futures = Map.empty |
|
313 |
} |
|
65219 | 314 |
|
73565 | 315 |
private def result(id: String, tag: Scala.Tag.Value, res: List[Bytes]): Unit = |
75380 | 316 |
synchronized { |
72157 | 317 |
if (futures.isDefinedAt(id)) { |
73565 | 318 |
session.protocol_command_raw("Scala.result", Bytes(id) :: Bytes(tag.id.toString) :: res) |
72157 | 319 |
futures -= id |
320 |
} |
|
321 |
} |
|
65220 | 322 |
|
75393 | 323 |
private def cancel(id: String, future: Future[Unit]): Unit = { |
73367 | 324 |
future.cancel() |
73565 | 325 |
result(id, Scala.Tag.INTERRUPT, Nil) |
72157 | 326 |
} |
327 |
||
75380 | 328 |
private def invoke_scala(msg: Prover.Protocol_Output): Boolean = synchronized { |
72157 | 329 |
msg.properties match { |
73419
22f3f2117ed7
clarified signature: function_thread is determined in Isabelle/Scala, not Isabelle/ML;
wenzelm
parents:
73418
diff
changeset
|
330 |
case Markup.Invoke_Scala(name, id) => |
75441
400e325a5416
clarified signature, based on hints by IntelliJ IDEA;
wenzelm
parents:
75440
diff
changeset
|
331 |
def body(): Unit = { |
77027 | 332 |
val (tag, res) = Scala.function_body(session, name, msg.chunks) |
72332
319dd5c618a5
allow Scala function execution on separate thread: better reactivity, but potential overloading of the JVM;
wenzelm
parents:
72294
diff
changeset
|
333 |
result(id, tag, res) |
319dd5c618a5
allow Scala function execution on separate thread: better reactivity, but potential overloading of the JVM;
wenzelm
parents:
72294
diff
changeset
|
334 |
} |
319dd5c618a5
allow Scala function execution on separate thread: better reactivity, but potential overloading of the JVM;
wenzelm
parents:
72294
diff
changeset
|
335 |
val future = |
73419
22f3f2117ed7
clarified signature: function_thread is determined in Isabelle/Scala, not Isabelle/ML;
wenzelm
parents:
73418
diff
changeset
|
336 |
if (Scala.function_thread(name)) { |
75441
400e325a5416
clarified signature, based on hints by IntelliJ IDEA;
wenzelm
parents:
75440
diff
changeset
|
337 |
Future.thread(name = Isabelle_Thread.make_name(base = "invoke_scala"))(body()) |
72332
319dd5c618a5
allow Scala function execution on separate thread: better reactivity, but potential overloading of the JVM;
wenzelm
parents:
72294
diff
changeset
|
338 |
} |
75441
400e325a5416
clarified signature, based on hints by IntelliJ IDEA;
wenzelm
parents:
75440
diff
changeset
|
339 |
else Future.fork(body()) |
72332
319dd5c618a5
allow Scala function execution on separate thread: better reactivity, but potential overloading of the JVM;
wenzelm
parents:
72294
diff
changeset
|
340 |
futures += (id -> future) |
72157 | 341 |
true |
342 |
case _ => false |
|
56387 | 343 |
} |
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
344 |
} |
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
345 |
|
75380 | 346 |
private def cancel_scala(msg: Prover.Protocol_Output): Boolean = synchronized { |
72157 | 347 |
msg.properties match { |
348 |
case Markup.Cancel_Scala(id) => |
|
349 |
futures.get(id) match { |
|
350 |
case Some(future) => cancel(id, future) |
|
351 |
case None => |
|
352 |
} |
|
353 |
true |
|
354 |
case _ => false |
|
355 |
} |
|
356 |
} |
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
357 |
|
75440 | 358 |
override val functions: Session.Protocol_Functions = |
72157 | 359 |
List( |
360 |
Markup.Invoke_Scala.name -> invoke_scala, |
|
361 |
Markup.Cancel_Scala.name -> cancel_scala) |
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
362 |
} |
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
363 |
} |
71871
28def00726ca
more robust isabelle.Functions --- avoid Java reflection with unclear class/object treatment;
wenzelm
parents:
71870
diff
changeset
|
364 |
|
72193 | 365 |
class Scala_Functions extends Scala.Functions( |
366 |
Scala.Echo, |
|
367 |
Scala.Sleep, |
|
72194 | 368 |
Scala.Toplevel, |
75660
45d3497c0baa
support for Isabelle/Scala/Java modules in Isabelle/ML;
wenzelm
parents:
75654
diff
changeset
|
369 |
Scala_Build.Scala_Fun, |
75620 | 370 |
Base64.Decode, |
371 |
Base64.Encode, |
|
76351
2cee31cd92f0
generic support for XZ and Zstd compression in Isabelle/Scala;
wenzelm
parents:
75705
diff
changeset
|
372 |
Compress.XZ_Compress, |
2cee31cd92f0
generic support for XZ and Zstd compression in Isabelle/Scala;
wenzelm
parents:
75705
diff
changeset
|
373 |
Compress.XZ_Uncompress, |
2cee31cd92f0
generic support for XZ and Zstd compression in Isabelle/Scala;
wenzelm
parents:
75705
diff
changeset
|
374 |
Compress.Zstd_Compress, |
2cee31cd92f0
generic support for XZ and Zstd compression in Isabelle/Scala;
wenzelm
parents:
75705
diff
changeset
|
375 |
Compress.Zstd_Uncompress, |
72760
042180540068
clarified protocol: Doc.check at run-time via Scala function;
wenzelm
parents:
72756
diff
changeset
|
376 |
Doc.Doc_Names, |
72763 | 377 |
Bibtex.Check_Database, |
77028
f5896dea6fce
more direct check of bibtex entries via Isabelle/Scala;
wenzelm
parents:
77027
diff
changeset
|
378 |
Bibtex.Session_Entries, |
73314
87403fde8cc3
more direct make_directory in ML and Scala, but ssh still requires perl for Windows UNC paths (see a5dbad753552);
wenzelm
parents:
73228
diff
changeset
|
379 |
Isabelle_System.Make_Directory, |
73322 | 380 |
Isabelle_System.Copy_Dir, |
381 |
Isabelle_System.Copy_File, |
|
382 |
Isabelle_System.Copy_File_Base, |
|
73324 | 383 |
Isabelle_System.Rm_Tree, |
73323 | 384 |
Isabelle_System.Download, |
73523
2cd23d587db9
further clarification of Isabelle distribution identification -- avoid odd patching of sources;
wenzelm
parents:
73431
diff
changeset
|
385 |
Isabelle_System.Isabelle_Id, |
73418
7d7d959547a1
support for SystemOnTPTP in Isabelle/ML and Isabelle/Scala (without perl);
wenzelm
parents:
73367
diff
changeset
|
386 |
Isabelle_Tool.Isabelle_Tools, |
73431
f27d7b12e8a4
support for SystemOnTPTP.run_system, with strict error following scripts/remote_atp;
wenzelm
parents:
73419
diff
changeset
|
387 |
isabelle.atp.SystemOnTPTP.List_Systems, |
76514
2615cf68f6f4
ML support for the Prism.js syntax highlighter -- via Isabelle/Scala;
wenzelm
parents:
76351
diff
changeset
|
388 |
isabelle.atp.SystemOnTPTP.Run_System, |
2615cf68f6f4
ML support for the Prism.js syntax highlighter -- via Isabelle/Scala;
wenzelm
parents:
76351
diff
changeset
|
389 |
Prismjs.Languages, |
2615cf68f6f4
ML support for the Prism.js syntax highlighter -- via Isabelle/Scala;
wenzelm
parents:
76351
diff
changeset
|
390 |
Prismjs.Tokenize) |