src/Pure/PIDE/command.scala
author wenzelm
Sun Aug 22 16:37:15 2010 +0200 (2010-08-22)
changeset 38575 80d962964216
parent 38574 79cb7b4c908a
child 38577 4e4d3ea3725a
permissions -rw-r--r--
Isabelle_Hyperlinks: select relevant information directly from Markup_Tree, without intermediate RefInfo;
     1 /*  Title:      Pure/PIDE/command.scala
     2     Author:     Fabian Immler, TU Munich
     3     Author:     Makarius
     4 
     5 Prover commands with semantic state.
     6 */
     7 
     8 package isabelle
     9 
    10 
    11 import scala.actors.Actor, Actor._
    12 import scala.collection.mutable
    13 
    14 
    15 object Command
    16 {
    17   /** accumulated results from prover **/
    18 
    19   case class State(
    20     val command: Command,
    21     val status: List[XML.Tree],
    22     val reverse_results: List[XML.Tree],
    23     val markup: Markup_Tree)
    24   {
    25     /* content */
    26 
    27     lazy val results = reverse_results.reverse
    28 
    29     def add_result(result: XML.Tree): State = copy(reverse_results = result :: reverse_results)
    30 
    31     def add_markup(node: Markup_Tree.Node[Any]): State = copy(markup = markup + node)
    32 
    33     def markup_root_node: Markup_Tree.Node[Any] =
    34       new Markup_Tree.Node(command.range, XML.Elem(Markup(Markup.STATUS, Nil), status))
    35     def markup_root: Markup_Tree = markup + markup_root_node
    36 
    37 
    38     /* message dispatch */
    39 
    40     def accumulate(message: XML.Tree): Command.State =
    41       message match {
    42         case XML.Elem(Markup(Markup.STATUS, _), body) => copy(status = body ::: status)
    43         case XML.Elem(Markup(Markup.REPORT, _), msgs) =>
    44           (this /: msgs)((state, msg) =>
    45             msg match {
    46               case XML.Elem(Markup(name, atts), args)
    47               if Position.get_id(atts) == Some(command.id) && Position.get_range(atts).isDefined =>
    48                 val range = command.decode_range(Position.get_range(atts).get)
    49                 val props = atts.filterNot(p => Markup.POSITION_PROPERTIES(p._1))
    50                 val node = Markup_Tree.Node[Any](range, XML.Elem(Markup(name, props), args))
    51                 add_markup(node)
    52               case _ => System.err.println("Ignored report message: " + msg); state
    53             })
    54         case _ => add_result(message)
    55       }
    56   }
    57 
    58 
    59   /* unparsed dummy commands */
    60 
    61   def unparsed(source: String) =
    62     new Command(Document.NO_ID, List(Token(Token.Kind.UNPARSED, source)))
    63 }
    64 
    65 
    66 class Command(
    67     val id: Document.Command_ID,
    68     val span: List[Token])
    69 {
    70   /* classification */
    71 
    72   def is_command: Boolean = !span.isEmpty && span.head.is_command
    73   def is_ignored: Boolean = span.forall(_.is_ignored)
    74   def is_malformed: Boolean = !is_command && !is_ignored
    75 
    76   def is_unparsed = id == Document.NO_ID
    77 
    78   def name: String = if (is_command) span.head.content else ""
    79   override def toString =
    80     id + "/" + (if (is_command) name else if (is_ignored) "IGNORED" else "MALFORMED")
    81 
    82 
    83   /* source text */
    84 
    85   val source: String = span.map(_.source).mkString
    86   def source(range: Text.Range): String = source.substring(range.start, range.stop)
    87   def length: Int = source.length
    88 
    89   val range: Text.Range = Text.Range(0, length)
    90 
    91   lazy val symbol_index = new Symbol.Index(source)
    92   def decode_range(r: Text.Range): Text.Range = symbol_index.decode(r)
    93 
    94 
    95   /* accumulated results */
    96 
    97   val empty_state: Command.State = Command.State(this, Nil, Nil, Markup_Tree.empty)
    98 }