src/Pure/PIDE/document.scala
changeset 52563 f9a20c2c3b70
parent 52531 21f8e0e151f5
child 52564 4e855c120f6a
equal deleted inserted replaced
52562:3261ee47bb95 52563:f9a20c2c3b70
   273       range: Text.Range,
   273       range: Text.Range,
   274       elements: Option[Set[String]],
   274       elements: Option[Set[String]],
   275       result: Command.State => PartialFunction[Text.Markup, A]): Stream[Text.Info[A]]
   275       result: Command.State => PartialFunction[Text.Markup, A]): Stream[Text.Info[A]]
   276   }
   276   }
   277 
   277 
   278   type Assign = List[(Document_ID.Command, List[Document_ID.Exec])]  // exec state assignment
   278   type Assign_Update =
       
   279     List[(Document_ID.Command, List[Document_ID.Exec])]  // update of exec state assignment
   279 
   280 
   280   object State
   281   object State
   281   {
   282   {
   282     class Fail(state: State) extends Exception
   283     class Fail(state: State) extends Exception
   283 
   284 
   291       val is_finished: Boolean = false)
   292       val is_finished: Boolean = false)
   292     {
   293     {
   293       def check_finished: Assignment = { require(is_finished); this }
   294       def check_finished: Assignment = { require(is_finished); this }
   294       def unfinished: Assignment = new Assignment(command_execs, false)
   295       def unfinished: Assignment = new Assignment(command_execs, false)
   295 
   296 
   296       def assign(
   297       def assign(update: Assign_Update): Assignment =
   297         add_command_execs: List[(Document_ID.Command, List[Document_ID.Exec])]): Assignment =
       
   298       {
   298       {
   299         require(!is_finished)
   299         require(!is_finished)
   300         val command_execs1 =
   300         val command_execs1 =
   301           (command_execs /: add_command_execs) {
   301           (command_execs /: update) {
   302             case (res, (command_id, Nil)) => res - command_id
   302             case (res, (command_id, exec_ids)) =>
   303             case (res, assign) => res + assign
   303               if (exec_ids.isEmpty) res - command_id
       
   304               else res + (command_id -> exec_ids)
   304           }
   305           }
   305         new Assignment(command_execs1, true)
   306         new Assignment(command_execs1, true)
   306       }
   307       }
   307     }
   308     }
   308 
   309 
   309     val init: State =
   310     val init: State =
   310       State().define_version(Version.init, Assignment.init).assign(Version.init.id)._2
   311       State().define_version(Version.init, Assignment.init).assign(Version.init.id, Nil)._2
   311   }
   312   }
   312 
   313 
   313   final case class State private(
   314   final case class State private(
   314     val versions: Map[Document_ID.Version, Version] = Map.empty,
   315     val versions: Map[Document_ID.Version, Version] = Map.empty,
   315     val commands: Map[Document_ID.Command, Command.State] = Map.empty,  // static markup from define_command
   316     val commands: Map[Document_ID.Command, Command.State] = Map.empty,  // static markup from define_command
   344       }
   345       }
   345 
   346 
   346     def the_version(id: Document_ID.Version): Version = versions.getOrElse(id, fail)
   347     def the_version(id: Document_ID.Version): Version = versions.getOrElse(id, fail)
   347     def the_read_state(id: Document_ID.Command): Command.State = commands.getOrElse(id, fail)
   348     def the_read_state(id: Document_ID.Command): Command.State = commands.getOrElse(id, fail)
   348     def the_exec_state(id: Document_ID.Exec): Command.State = execs.getOrElse(id, fail)
   349     def the_exec_state(id: Document_ID.Exec): Command.State = execs.getOrElse(id, fail)
   349     def the_assignment(version: Version): State.Assignment =
   350     def the_assignment(version: Version): State.Assignment = assignments.getOrElse(version.id, fail)
   350       assignments.getOrElse(version.id, fail)
       
   351 
   351 
   352     def accumulate(id: Document_ID.Generic, message: XML.Elem): (Command.State, State) =
   352     def accumulate(id: Document_ID.Generic, message: XML.Elem): (Command.State, State) =
   353       execs.get(id) match {
   353       execs.get(id) match {
   354         case Some(st) =>
   354         case Some(st) =>
   355           val new_st = st + (id, message)
   355           val new_st = st + (id, message)
   361               (new_st, copy(commands = commands + (id -> new_st)))
   361               (new_st, copy(commands = commands + (id -> new_st)))
   362             case None => fail
   362             case None => fail
   363           }
   363           }
   364       }
   364       }
   365 
   365 
   366     def assign(id: Document_ID.Version, command_execs: Assign = Nil): (List[Command], State) =
   366     def assign(id: Document_ID.Version, update: Assign_Update): (List[Command], State) =
   367     {
   367     {
   368       val version = the_version(id)
   368       val version = the_version(id)
   369 
   369 
   370       val (changed_commands, new_execs) =
   370       val (changed_commands, new_execs) =
   371         ((Nil: List[Command], execs) /: command_execs) {
   371         ((Nil: List[Command], execs) /: update) {
   372           case ((commands1, execs1), (cmd_id, exec)) =>
   372           case ((commands1, execs1), (cmd_id, exec)) =>
   373             val st1 = the_read_state(cmd_id)
   373             val st1 = the_read_state(cmd_id)
   374             val command = st1.command
   374             val command = st1.command
   375             val st0 = command.empty_state
   375             val st0 = command.empty_state
   376 
   376 
   382                   execs1 + (eval_id -> execs.getOrElse(eval_id, st1)) ++
   382                   execs1 + (eval_id -> execs.getOrElse(eval_id, st1)) ++
   383                     print_ids.iterator.map(id => id -> execs.getOrElse(id, st0))
   383                     print_ids.iterator.map(id => id -> execs.getOrElse(id, st0))
   384               }
   384               }
   385             (commands2, execs2)
   385             (commands2, execs2)
   386         }
   386         }
   387       val new_assignment = the_assignment(version).assign(command_execs)
   387       val new_assignment = the_assignment(version).assign(update)
   388       val new_state = copy(assignments = assignments + (id -> new_assignment), execs = new_execs)
   388       val new_state = copy(assignments = assignments + (id -> new_assignment), execs = new_execs)
   389 
   389 
   390       (changed_commands, new_state)
   390       (changed_commands, new_state)
   391     }
   391     }
   392 
   392