src/Pure/PIDE/command.scala
author wenzelm
Wed Aug 25 22:37:53 2010 +0200 (2010-08-25)
changeset 38722 ba31936497c2
parent 38714 31da698fc4e5
child 38723 6a55b8978a56
permissions -rw-r--r--
organized markup properties via apply/unapply patterns;
     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 object Command
    12 {
    13   /** accumulated results from prover **/
    14 
    15   case class State(
    16     val command: Command,
    17     val status: List[Markup],
    18     val reverse_results: List[XML.Tree],
    19     val markup: Markup_Tree)
    20   {
    21     /* content */
    22 
    23     lazy val results = reverse_results.reverse
    24 
    25     def add_status(st: Markup): State = copy(status = st :: status)
    26     def add_markup(info: Text.Info[Any]): State = copy(markup = markup + info)
    27     def add_result(result: XML.Tree): State = copy(reverse_results = result :: reverse_results)
    28 
    29     def root_info: Text.Info[Any] =
    30       new Text.Info(command.range,
    31         XML.Elem(Markup(Markup.STATUS, Nil), status.reverse.map(XML.Elem(_, Nil))))
    32     def root_markup: Markup_Tree = markup + root_info
    33 
    34 
    35     /* message dispatch */
    36 
    37     def accumulate(message: XML.Tree): Command.State =
    38       message match {
    39         case XML.Elem(Markup(Markup.STATUS, _), msgs) =>
    40           (this /: msgs)((state, msg) =>
    41             msg match {
    42               case XML.Elem(markup, Nil) => state.add_status(markup)
    43               case _ => System.err.println("Ignored status message: " + msg); state
    44             })
    45 
    46         case XML.Elem(Markup(Markup.REPORT, _), msgs) =>
    47           (this /: msgs)((state, msg) =>
    48             msg match {
    49               case XML.Elem(Markup(name, atts), args) =>
    50                 atts match {
    51                   case Position.Range(range) if Position.Id.unapply(atts) == Some(command.id) =>
    52                     val props = atts.filterNot(p => Markup.POSITION_PROPERTIES(p._1))
    53                     val info =
    54                       Text.Info[Any](command.decode(range), XML.Elem(Markup(name, props), args))
    55                     state.add_markup(info)
    56                   case _ => System.err.println("Ignored report message: " + msg); state
    57                 }
    58               case _ => System.err.println("Ignored report message: " + msg); state
    59             })
    60         case _ => add_result(message)
    61       }
    62   }
    63 
    64 
    65   /* unparsed dummy commands */
    66 
    67   def unparsed(source: String) =
    68     new Command(Document.NO_ID, List(Token(Token.Kind.UNPARSED, source)))
    69 }
    70 
    71 
    72 class Command(
    73     val id: Document.Command_ID,
    74     val span: List[Token])
    75 {
    76   /* classification */
    77 
    78   def is_command: Boolean = !span.isEmpty && span.head.is_command
    79   def is_ignored: Boolean = span.forall(_.is_ignored)
    80   def is_malformed: Boolean = !is_command && !is_ignored
    81 
    82   def is_unparsed = id == Document.NO_ID
    83 
    84   def name: String = if (is_command) span.head.content else ""
    85   override def toString =
    86     id + "/" + (if (is_command) name else if (is_ignored) "IGNORED" else "MALFORMED")
    87 
    88 
    89   /* source text */
    90 
    91   val source: String = span.map(_.source).mkString
    92   def source(range: Text.Range): String = source.substring(range.start, range.stop)
    93   def length: Int = source.length
    94 
    95   val range: Text.Range = Text.Range(0, length)
    96 
    97   lazy val symbol_index = new Symbol.Index(source)
    98   def decode(i: Text.Offset): Text.Offset = symbol_index.decode(i)
    99   def decode(r: Text.Range): Text.Range = symbol_index.decode(r)
   100 
   101 
   102   /* accumulated results */
   103 
   104   val empty_state: Command.State = Command.State(this, Nil, Nil, Markup_Tree.empty)
   105 }