# HG changeset patch # User wenzelm # Date 1344533862 -7200 # Node ID 9e1b2aafbc7f039b50dc34e406583a76d4909010 # Parent 184158734fba6418c0f6d23d8de02c18983265d1 more direct Linear_Set.reverse, swapping orientation of the graph; tuned; diff -r 184158734fba -r 9e1b2aafbc7f src/Pure/General/linear_set.scala --- a/src/Pure/General/linear_set.scala Thu Aug 09 17:13:46 2012 +0200 +++ b/src/Pure/General/linear_set.scala Thu Aug 09 19:37:42 2012 +0200 @@ -34,6 +34,8 @@ { override def companion: GenericCompanion[Linear_Set] = Linear_Set + def reverse: Linear_Set[A] = new Linear_Set(end, start, prevs, nexts) + /* relative addressing */ @@ -132,26 +134,22 @@ def contains(elem: A): Boolean = !isEmpty && (end.get == elem || nexts.isDefinedAt(elem)) - private def make_iterator(from: Option[A], which: Map[A, A]): Iterator[A] = new Iterator[A] { + private def make_iterator(from: Option[A]): Iterator[A] = new Iterator[A] { private var next_elem = from def hasNext(): Boolean = next_elem.isDefined def next(): A = next_elem match { case Some(elem) => - next_elem = which.get(elem) + next_elem = nexts.get(elem) elem case None => Iterator.empty.next() } } - override def iterator: Iterator[A] = make_iterator(start, nexts) + override def iterator: Iterator[A] = make_iterator(start) def iterator(elem: A): Iterator[A] = - if (contains(elem)) make_iterator(Some(elem), nexts) - else throw new Linear_Set.Undefined(elem) - - def reverse_iterator(elem: A): Iterator[A] = - if (contains(elem)) make_iterator(Some(elem), prevs) + if (contains(elem)) make_iterator(Some(elem)) else throw new Linear_Set.Undefined(elem) def + (elem: A): Linear_Set[A] = insert_after(end, elem) diff -r 184158734fba -r 9e1b2aafbc7f src/Pure/Thy/thy_syntax.scala --- a/src/Pure/Thy/thy_syntax.scala Thu Aug 09 17:13:46 2012 +0200 +++ b/src/Pure/Thy/thy_syntax.scala Thu Aug 09 19:37:42 2012 +0200 @@ -196,41 +196,42 @@ /* phase 2: recover command spans */ - @tailrec private def recover_spans( + private def recover_spans( syntax: Outer_Syntax, node_name: Document.Node.Name, - commands: Linear_Set[Command]): Linear_Set[Command] = + old_commands: Linear_Set[Command]): Linear_Set[Command] = { - commands.iterator.find(cmd => !cmd.is_defined) match { - case Some(first_undefined) => - val first = - commands.reverse_iterator(first_undefined). - dropWhile(_.newlines == 0).find(_.is_command) getOrElse commands.head - val last = - commands.iterator(first_undefined). - dropWhile(_.newlines == 0).find(_.is_command) getOrElse commands.last - val range = - commands.iterator(first).takeWhile(_ != last).toList ::: List(last) + def bound(commands: Linear_Set[Command], cmd: Command): Command = + commands.iterator(cmd).dropWhile(_.newlines == 0).find(_.is_command) getOrElse commands.last - val spans0 = parse_spans(syntax.scan(range.map(_.source).mkString)) + @tailrec def recover(commands: Linear_Set[Command]): Linear_Set[Command] = + commands.iterator.find(cmd => !cmd.is_defined) match { + case Some(first_undefined) => + val first = bound(commands.reverse, first_undefined) + val last = bound(commands, first_undefined) + val range = + commands.iterator(first).takeWhile(_ != last).toList ::: List(last) + + val spans0 = parse_spans(syntax.scan(range.map(_.source).mkString)) - val (before_edit, spans1) = - if (!spans0.isEmpty && first.is_command && first.span == spans0.head) - (Some(first), spans0.tail) - else (commands.prev(first), spans0) + val (before_edit, spans1) = + if (!spans0.isEmpty && first.is_command && first.span == spans0.head) + (Some(first), spans0.tail) + else (commands.prev(first), spans0) - val (after_edit, spans2) = - if (!spans1.isEmpty && last.is_command && last.span == spans1.last) - (Some(last), spans1.take(spans1.length - 1)) - else (commands.next(last), spans1) + val (after_edit, spans2) = + if (!spans1.isEmpty && last.is_command && last.span == spans1.last) + (Some(last), spans1.take(spans1.length - 1)) + else (commands.next(last), spans1) - val inserted = spans2.map(span => Command(Document.new_id(), node_name, span)) - val new_commands = - commands.delete_between(before_edit, after_edit).append_after(before_edit, inserted) - recover_spans(syntax, node_name, new_commands) + val inserted = spans2.map(span => Command(Document.new_id(), node_name, span)) + val new_commands = + commands.delete_between(before_edit, after_edit).append_after(before_edit, inserted) + recover(new_commands) - case None => commands - } + case None => commands + } + recover(old_commands) }