src/Pure/System/scala.scala
changeset 75393 87ebf5a50283
parent 75380 2cb2606ce075
child 75417 2c861b196d52
equal deleted inserted replaced
75388:b3ca4a6ed74b 75393:87ebf5a50283
    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)) {