| author | wenzelm | 
| Sun, 12 Sep 2021 20:14:09 +0200 | |
| changeset 74300 | 33f13d2d211c | 
| parent 73359 | d8a0e996614b | 
| child 74671 | df12779c3ce8 | 
| permissions | -rw-r--r-- | 
| 57905 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 1 | /* Title: Pure/PIDE/command_span.scala | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 2 | Author: Makarius | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 3 | |
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 4 | Syntactic representation of command spans. | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 5 | */ | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 6 | |
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 7 | package isabelle | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 8 | |
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 9 | |
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 10 | import scala.collection.mutable | 
| 72946 | 11 | import scala.util.parsing.input.CharSequenceReader | 
| 57905 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 12 | |
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 13 | |
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 14 | object Command_Span | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 15 | {
 | 
| 72743 | 16 | /* loaded files */ | 
| 17 | ||
| 72757 | 18 | object Loaded_Files | 
| 19 |   {
 | |
| 20 | val none: Loaded_Files = Loaded_Files(Nil, -1) | |
| 21 | } | |
| 22 | sealed case class Loaded_Files(files: List[String], index: Int) | |
| 72743 | 23 | |
| 72748 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 24 | class Load_Command(val name: String) extends Isabelle_System.Service | 
| 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 25 |   {
 | 
| 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 26 | override def toString: String = name | 
| 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 27 | |
| 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 28 | def extensions: List[String] = Nil | 
| 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 29 | |
| 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 30 | def loaded_files(tokens: List[(Token, Int)]): Loaded_Files = | 
| 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 31 |       tokens.collectFirst({ case (t, i) if t.is_embedded => (t.content, i) }) match {
 | 
| 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 32 | case Some((file, i)) => | 
| 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 33 |           extensions match {
 | 
| 72757 | 34 | case Nil => Loaded_Files(List(file), i) | 
| 35 | case exts => Loaded_Files(exts.map(ext => file + "." + ext), i) | |
| 72748 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 36 | } | 
| 72757 | 37 | case None => Loaded_Files.none | 
| 72748 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 38 | } | 
| 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 39 | } | 
| 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 40 | |
| 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 41 | lazy val load_commands: List[Load_Command] = | 
| 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 42 |     new Load_Command("") :: Isabelle_System.make_services(classOf[Load_Command])
 | 
| 72743 | 43 | |
| 44 | ||
| 45 | /* span kind */ | |
| 46 | ||
| 57905 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 47 |   sealed abstract class Kind {
 | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 48 | override def toString: String = | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 49 |       this match {
 | 
| 73115 
a8e5d7c9a834
discontinued odd absolute position (amending 85bcdd05c6d0, 1975f397eabb): it violates translation invariance of commands and may lead to redundant re-checking of PIDE document;
 wenzelm parents: 
72946diff
changeset | 50 | case Command_Span(name, _) => proper_string(name) getOrElse "<command>" | 
| 57905 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 51 | case Ignored_Span => "<ignored>" | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 52 | case Malformed_Span => "<malformed>" | 
| 72692 
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
 wenzelm parents: 
68845diff
changeset | 53 | case Theory_Span => "<theory>" | 
| 57905 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 54 | } | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 55 | } | 
| 73115 
a8e5d7c9a834
discontinued odd absolute position (amending 85bcdd05c6d0, 1975f397eabb): it violates translation invariance of commands and may lead to redundant re-checking of PIDE document;
 wenzelm parents: 
72946diff
changeset | 56 | case class Command_Span(name: String, pos: Position.T) extends Kind | 
| 57905 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 57 | case object Ignored_Span extends Kind | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 58 | case object Malformed_Span extends Kind | 
| 72692 
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
 wenzelm parents: 
68845diff
changeset | 59 | case object Theory_Span extends Kind | 
| 57905 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 60 | |
| 72743 | 61 | |
| 62 | /* span */ | |
| 63 | ||
| 57905 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 64 | sealed case class Span(kind: Kind, content: List[Token]) | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 65 |   {
 | 
| 72692 
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
 wenzelm parents: 
68845diff
changeset | 66 | def is_theory: Boolean = kind == Theory_Span | 
| 
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
 wenzelm parents: 
68845diff
changeset | 67 | |
| 59735 | 68 | def name: String = | 
| 72800 | 69 |       kind match { case k: Command_Span => k.name case _ => "" }
 | 
| 58802 | 70 | |
| 59735 | 71 | def position: Position.T = | 
| 72800 | 72 |       kind match { case k: Command_Span => k.pos case _ => Position.none }
 | 
| 73 | ||
| 67895 | 74 | def keyword_pos(start: Token.Pos): Token.Pos = | 
| 75 |       kind match {
 | |
| 76 | case _: Command_Span => | |
| 73359 | 77 | content.iterator.takeWhile(tok => !tok.is_command).foldLeft(start)(_.advance(_)) | 
| 67895 | 78 | case _ => start | 
| 79 | } | |
| 80 | ||
| 68845 
3b2daa7bf9f4
support Thy_Element in Scala, following ML version;
 wenzelm parents: 
68840diff
changeset | 81 | def is_kind(keywords: Keyword.Keywords, pred: String => Boolean, other: Boolean): Boolean = | 
| 68840 | 82 |       keywords.kinds.get(name) match {
 | 
| 83 | case Some(k) => pred(k) | |
| 68845 
3b2daa7bf9f4
support Thy_Element in Scala, following ML version;
 wenzelm parents: 
68840diff
changeset | 84 | case None => other | 
| 68840 | 85 | } | 
| 86 | ||
| 63606 | 87 | def is_begin: Boolean = content.exists(_.is_begin) | 
| 88 | def is_end: Boolean = content.exists(_.is_end) | |
| 89 | ||
| 72946 | 90 | def content_reader: CharSequenceReader = Scan.char_reader(Token.implode(content)) | 
| 91 | ||
| 73359 | 92 | def length: Int = content.foldLeft(0)(_ + _.source.length) | 
| 59705 | 93 | |
| 57905 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 94 | def compact_source: (String, Span) = | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 95 |     {
 | 
| 59735 | 96 | val source = Token.implode(content) | 
| 57905 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 97 | val content1 = new mutable.ListBuffer[Token] | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 98 | var i = 0 | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 99 |       for (Token(kind, s) <- content) {
 | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 100 | val n = s.length | 
| 59735 | 101 | val s1 = source.substring(i, i + n) | 
| 57905 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 102 | content1 += Token(kind, s1) | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 103 | i += n | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 104 | } | 
| 59735 | 105 | (source, Span(kind, content1.toList)) | 
| 57905 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 106 | } | 
| 72742 | 107 | |
| 72743 | 108 | def clean_arguments: List[(Token, Int)] = | 
| 109 |     {
 | |
| 110 |       if (name.nonEmpty) {
 | |
| 111 | def clean(toks: List[(Token, Int)]): List[(Token, Int)] = | |
| 112 |           toks match {
 | |
| 113 | case (t1, i1) :: (t2, i2) :: rest => | |
| 114 | if (t1.is_keyword && t1.source == "%" && t2.is_name) clean(rest) | |
| 115 | else (t1, i1) :: clean((t2, i2) :: rest) | |
| 116 | case _ => toks | |
| 117 | } | |
| 118 |         clean(content.zipWithIndex.filter({ case (t, _) => t.is_proper }))
 | |
| 119 |           .dropWhile({ case (t, _) => !t.is_command })
 | |
| 120 |           .dropWhile({ case (t, _) => t.is_command })
 | |
| 121 | } | |
| 122 | else Nil | |
| 123 | } | |
| 124 | ||
| 72816 
ea4f86914cb2
support for PIDE markup for auxiliary files ("blobs");
 wenzelm parents: 
72800diff
changeset | 125 | def is_load_command(syntax: Outer_Syntax): Boolean = | 
| 
ea4f86914cb2
support for PIDE markup for auxiliary files ("blobs");
 wenzelm parents: 
72800diff
changeset | 126 | syntax.load_command(name).isDefined | 
| 
ea4f86914cb2
support for PIDE markup for auxiliary files ("blobs");
 wenzelm parents: 
72800diff
changeset | 127 | |
| 72743 | 128 | def loaded_files(syntax: Outer_Syntax): Loaded_Files = | 
| 72742 | 129 |       syntax.load_command(name) match {
 | 
| 72757 | 130 | case None => Loaded_Files.none | 
| 72748 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 131 | case Some(a) => | 
| 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 132 |           load_commands.find(_.name == a) match {
 | 
| 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 133 | case Some(load_command) => load_command.loaded_files(clean_arguments) | 
| 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 134 |             case None => error("Undefined load command function: " + a)
 | 
| 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 wenzelm parents: 
72744diff
changeset | 135 | } | 
| 72742 | 136 | } | 
| 57905 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 137 | } | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 138 | |
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 139 | val empty: Span = Span(Ignored_Span, Nil) | 
| 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 140 | |
| 72692 
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
 wenzelm parents: 
68845diff
changeset | 141 | def unparsed(source: String, theory: Boolean): Span = | 
| 
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
 wenzelm parents: 
68845diff
changeset | 142 |   {
 | 
| 
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
 wenzelm parents: 
68845diff
changeset | 143 | val kind = if (theory) Theory_Span else Malformed_Span | 
| 
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
 wenzelm parents: 
68845diff
changeset | 144 | Span(kind, List(Token(Token.Kind.UNPARSED, source))) | 
| 
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
 wenzelm parents: 
68845diff
changeset | 145 | } | 
| 57905 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 wenzelm parents: diff
changeset | 146 | } |