11 |
11 |
12 import scala.tools.nsc.{GenericRunnerSettings, ConsoleWriter, NewLinePrintWriter} |
12 import scala.tools.nsc.{GenericRunnerSettings, ConsoleWriter, NewLinePrintWriter} |
13 import scala.tools.nsc.interpreter.{IMain, Results} |
13 import scala.tools.nsc.interpreter.{IMain, Results} |
14 import scala.tools.nsc.interpreter.shell.ReplReporterImpl |
14 import scala.tools.nsc.interpreter.shell.ReplReporterImpl |
15 |
15 |
16 object Scala |
16 object Scala { |
17 { |
|
18 /** registered functions **/ |
17 /** registered functions **/ |
19 |
18 |
20 abstract class Fun(val name: String, val thread: Boolean = false) |
19 abstract class Fun(val name: String, val thread: Boolean = false) { |
21 { |
|
22 override def toString: String = name |
20 override def toString: String = name |
23 def multi: Boolean = true |
21 def multi: Boolean = true |
24 def position: Properties.T = here.position |
22 def position: Properties.T = here.position |
25 def here: Scala_Project.Here |
23 def here: Scala_Project.Here |
26 def invoke(args: List[Bytes]): List[Bytes] |
24 def invoke(args: List[Bytes]): List[Bytes] |
27 } |
25 } |
28 |
26 |
29 abstract class Fun_Strings(name: String, thread: Boolean = false) |
27 abstract class Fun_Strings(name: String, thread: Boolean = false) |
30 extends Fun(name, thread = thread) |
28 extends Fun(name, thread = thread) { |
31 { |
|
32 override def invoke(args: List[Bytes]): List[Bytes] = |
29 override def invoke(args: List[Bytes]): List[Bytes] = |
33 apply(args.map(_.text)).map(Bytes.apply) |
30 apply(args.map(_.text)).map(Bytes.apply) |
34 def apply(args: List[String]): List[String] |
31 def apply(args: List[String]): List[String] |
35 } |
32 } |
36 |
33 |
37 abstract class Fun_String(name: String, thread: Boolean = false) |
34 abstract class Fun_String(name: String, thread: Boolean = false) |
38 extends Fun_Strings(name, thread = thread) |
35 extends Fun_Strings(name, thread = thread) { |
39 { |
|
40 override def multi: Boolean = false |
36 override def multi: Boolean = false |
41 override def apply(args: List[String]): List[String] = |
37 override def apply(args: List[String]): List[String] = |
42 List(apply(Library.the_single(args))) |
38 List(apply(Library.the_single(args))) |
43 def apply(arg: String): String |
39 def apply(arg: String): String |
44 } |
40 } |
50 |
46 |
51 |
47 |
52 |
48 |
53 /** demo functions **/ |
49 /** demo functions **/ |
54 |
50 |
55 object Echo extends Fun_String("echo") |
51 object Echo extends Fun_String("echo") { |
56 { |
|
57 val here = Scala_Project.here |
52 val here = Scala_Project.here |
58 def apply(arg: String): String = arg |
53 def apply(arg: String): String = arg |
59 } |
54 } |
60 |
55 |
61 object Sleep extends Fun_String("sleep") |
56 object Sleep extends Fun_String("sleep") { |
62 { |
|
63 val here = Scala_Project.here |
57 val here = Scala_Project.here |
64 def apply(seconds: String): String = |
58 def apply(seconds: String): String = { |
65 { |
|
66 val t = |
59 val t = |
67 seconds match { |
60 seconds match { |
68 case Value.Double(s) => Time.seconds(s) |
61 case Value.Double(s) => Time.seconds(s) |
69 case _ => error("Malformed argument: " + quote(seconds)) |
62 case _ => error("Malformed argument: " + quote(seconds)) |
70 } |
63 } |
84 prop <- List("isabelle.scala.classpath", "java.class.path") |
77 prop <- List("isabelle.scala.classpath", "java.class.path") |
85 elems = System.getProperty(prop, "") if elems.nonEmpty |
78 elems = System.getProperty(prop, "") if elems.nonEmpty |
86 elem <- space_explode(JFile.pathSeparatorChar, elems) if elem.nonEmpty |
79 elem <- space_explode(JFile.pathSeparatorChar, elems) if elem.nonEmpty |
87 } yield elem |
80 } yield elem |
88 |
81 |
89 object Compiler |
82 object Compiler { |
90 { |
|
91 def context( |
83 def context( |
92 error: String => Unit = Exn.error, |
84 error: String => Unit = Exn.error, |
93 jar_dirs: List[JFile] = Nil): Context = |
85 jar_dirs: List[JFile] = Nil |
94 { |
86 ): Context = { |
95 def find_jars(dir: JFile): List[String] = |
87 def find_jars(dir: JFile): List[String] = |
96 File.find_files(dir, file => file.getName.endsWith(".jar")). |
88 File.find_files(dir, file => file.getName.endsWith(".jar")). |
97 map(File.absolute_name) |
89 map(File.absolute_name) |
98 |
90 |
99 val settings = new GenericRunnerSettings(error) |
91 val settings = new GenericRunnerSettings(error) |
104 } |
96 } |
105 |
97 |
106 def default_print_writer: PrintWriter = |
98 def default_print_writer: PrintWriter = |
107 new NewLinePrintWriter(new ConsoleWriter, true) |
99 new NewLinePrintWriter(new ConsoleWriter, true) |
108 |
100 |
109 class Context private [Compiler](val settings: GenericRunnerSettings) |
101 class Context private [Compiler](val settings: GenericRunnerSettings) { |
110 { |
|
111 override def toString: String = settings.toString |
102 override def toString: String = settings.toString |
112 |
103 |
113 def interpreter( |
104 def interpreter( |
114 print_writer: PrintWriter = default_print_writer, |
105 print_writer: PrintWriter = default_print_writer, |
115 class_loader: ClassLoader = null): IMain = |
106 class_loader: ClassLoader = null |
116 { |
107 ): IMain = { |
117 new IMain(settings, new ReplReporterImpl(settings, print_writer)) |
108 new IMain(settings, new ReplReporterImpl(settings, print_writer)) { |
118 { |
|
119 override def parentClassLoader: ClassLoader = |
109 override def parentClassLoader: ClassLoader = |
120 if (class_loader == null) super.parentClassLoader |
110 if (class_loader == null) super.parentClassLoader |
121 else class_loader |
111 else class_loader |
122 } |
112 } |
123 } |
113 } |
124 |
114 |
125 def toplevel(interpret: Boolean, source: String): List[String] = |
115 def toplevel(interpret: Boolean, source: String): List[String] = { |
126 { |
|
127 val out = new StringWriter |
116 val out = new StringWriter |
128 val interp = interpreter(new PrintWriter(out)) |
117 val interp = interpreter(new PrintWriter(out)) |
129 val marker = '\u000b' |
118 val marker = '\u000b' |
130 val ok = |
119 val ok = |
131 interp.withLabel(marker.toString) { |
120 interp.withLabel(marker.toString) { |
142 if (!ok && errors.isEmpty) List("Error") else errors |
131 if (!ok && errors.isEmpty) List("Error") else errors |
143 } |
132 } |
144 } |
133 } |
145 } |
134 } |
146 |
135 |
147 object Toplevel extends Fun_String("scala_toplevel") |
136 object Toplevel extends Fun_String("scala_toplevel") { |
148 { |
|
149 val here = Scala_Project.here |
137 val here = Scala_Project.here |
150 def apply(arg: String): String = |
138 def apply(arg: String): String = { |
151 { |
|
152 val (interpret, source) = |
139 val (interpret, source) = |
153 YXML.parse_body(arg) match { |
140 YXML.parse_body(arg) match { |
154 case Nil => (false, "") |
141 case Nil => (false, "") |
155 case List(XML.Text(source)) => (false, source) |
142 case List(XML.Text(source)) => (false, source) |
156 case body => import XML.Decode._; pair(bool, string)(body) |
143 case body => import XML.Decode._; pair(bool, string)(body) |
166 |
153 |
167 /** invoke Scala functions from ML **/ |
154 /** invoke Scala functions from ML **/ |
168 |
155 |
169 /* invoke function */ |
156 /* invoke function */ |
170 |
157 |
171 object Tag extends Enumeration |
158 object Tag extends Enumeration { |
172 { |
|
173 val NULL, OK, ERROR, FAIL, INTERRUPT = Value |
159 val NULL, OK, ERROR, FAIL, INTERRUPT = Value |
174 } |
160 } |
175 |
161 |
176 def function_thread(name: String): Boolean = |
162 def function_thread(name: String): Boolean = |
177 functions.find(fun => fun.name == name) match { |
163 functions.find(fun => fun.name == name) match { |
192 } |
178 } |
193 |
179 |
194 |
180 |
195 /* protocol handler */ |
181 /* protocol handler */ |
196 |
182 |
197 class Handler extends Session.Protocol_Handler |
183 class Handler extends Session.Protocol_Handler { |
198 { |
|
199 private var session: Session = null |
184 private var session: Session = null |
200 private var futures = Map.empty[String, Future[Unit]] |
185 private var futures = Map.empty[String, Future[Unit]] |
201 |
186 |
202 override def init(session: Session): Unit = |
187 override def init(session: Session): Unit = |
203 synchronized { this.session = session } |
188 synchronized { this.session = session } |
213 session.protocol_command_raw("Scala.result", Bytes(id) :: Bytes(tag.id.toString) :: res) |
198 session.protocol_command_raw("Scala.result", Bytes(id) :: Bytes(tag.id.toString) :: res) |
214 futures -= id |
199 futures -= id |
215 } |
200 } |
216 } |
201 } |
217 |
202 |
218 private def cancel(id: String, future: Future[Unit]): Unit = |
203 private def cancel(id: String, future: Future[Unit]): Unit = { |
219 { |
|
220 future.cancel() |
204 future.cancel() |
221 result(id, Scala.Tag.INTERRUPT, Nil) |
205 result(id, Scala.Tag.INTERRUPT, Nil) |
222 } |
206 } |
223 |
207 |
224 private def invoke_scala(msg: Prover.Protocol_Output): Boolean = synchronized { |
208 private def invoke_scala(msg: Prover.Protocol_Output): Boolean = synchronized { |
225 msg.properties match { |
209 msg.properties match { |
226 case Markup.Invoke_Scala(name, id) => |
210 case Markup.Invoke_Scala(name, id) => |
227 def body: Unit = |
211 def body: Unit = { |
228 { |
|
229 val (tag, res) = Scala.function_body(name, msg.chunks) |
212 val (tag, res) = Scala.function_body(name, msg.chunks) |
230 result(id, tag, res) |
213 result(id, tag, res) |
231 } |
214 } |
232 val future = |
215 val future = |
233 if (Scala.function_thread(name)) { |
216 if (Scala.function_thread(name)) { |