| author | nipkow | 
| Tue, 25 Jun 2024 11:08:00 +0200 | |
| changeset 80404 | f34e62eda167 | 
| parent 78913 | ecb02f288636 | 
| child 82952 | 430dcd883bbc | 
| 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  | 
|
| 75393 | 14  | 
object Command_Span {
 | 
| 72743 | 15  | 
/* loaded files */  | 
16  | 
||
| 75393 | 17  | 
  object Loaded_Files {
 | 
| 72757 | 18  | 
val none: Loaded_Files = Loaded_Files(Nil, -1)  | 
19  | 
}  | 
|
20  | 
sealed case class Loaded_Files(files: List[String], index: Int)  | 
|
| 72743 | 21  | 
|
| 74671 | 22  | 
abstract class Load_Command(val name: String, val here: Scala_Project.Here)  | 
| 75393 | 23  | 
  extends Isabelle_System.Service {
 | 
| 76798 | 24  | 
    override def toString: String = print("")
 | 
25  | 
||
26  | 
def print(body: String): String =  | 
|
27  | 
      if (body.nonEmpty) "Load_Command(" + body + ")"
 | 
|
28  | 
      else if (name.nonEmpty) print("name = " + quote(name))
 | 
|
29  | 
else "Load_Command"  | 
|
30  | 
||
31  | 
def print_extensions: String =  | 
|
32  | 
      print("name = " + quote(name) + ", extensions = " + commas_quote(extensions))
 | 
|
| 
72748
 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 
wenzelm 
parents: 
72744 
diff
changeset
 | 
33  | 
|
| 74671 | 34  | 
def position: Position.T = here.position  | 
35  | 
||
| 
72748
 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 
wenzelm 
parents: 
72744 
diff
changeset
 | 
36  | 
def extensions: List[String] = Nil  | 
| 
 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 
wenzelm 
parents: 
72744 
diff
changeset
 | 
37  | 
|
| 
 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 
wenzelm 
parents: 
72744 
diff
changeset
 | 
38  | 
def loaded_files(tokens: List[(Token, Int)]): Loaded_Files =  | 
| 
 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 
wenzelm 
parents: 
72744 
diff
changeset
 | 
39  | 
      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: 
72744 
diff
changeset
 | 
40  | 
case Some((file, i)) =>  | 
| 
 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 
wenzelm 
parents: 
72744 
diff
changeset
 | 
41  | 
          extensions match {
 | 
| 72757 | 42  | 
case Nil => Loaded_Files(List(file), i)  | 
43  | 
case exts => Loaded_Files(exts.map(ext => file + "." + ext), i)  | 
|
| 
72748
 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 
wenzelm 
parents: 
72744 
diff
changeset
 | 
44  | 
}  | 
| 72757 | 45  | 
case None => Loaded_Files.none  | 
| 
72748
 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 
wenzelm 
parents: 
72744 
diff
changeset
 | 
46  | 
}  | 
| 
 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 
wenzelm 
parents: 
72744 
diff
changeset
 | 
47  | 
}  | 
| 
 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 
wenzelm 
parents: 
72744 
diff
changeset
 | 
48  | 
|
| 76615 | 49  | 
  object Load_Default extends Load_Command("", Scala_Project.here)
 | 
| 74671 | 50  | 
|
| 
72748
 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 
wenzelm 
parents: 
72744 
diff
changeset
 | 
51  | 
lazy val load_commands: List[Load_Command] =  | 
| 76615 | 52  | 
Load_Default :: Isabelle_System.make_services(classOf[Load_Command])  | 
| 72743 | 53  | 
|
54  | 
||
55  | 
/* span kind */  | 
|
56  | 
||
| 
57905
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
57  | 
  sealed abstract class Kind {
 | 
| 
78912
 
ff4496b25197
clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
 
wenzelm 
parents: 
76798 
diff
changeset
 | 
58  | 
def keyword_kind: Option[String] = None  | 
| 
 
ff4496b25197
clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
 
wenzelm 
parents: 
76798 
diff
changeset
 | 
59  | 
|
| 
57905
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
60  | 
override def toString: String =  | 
| 
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
61  | 
      this match {
 | 
| 
78912
 
ff4496b25197
clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
 
wenzelm 
parents: 
76798 
diff
changeset
 | 
62  | 
case command: Command_Span => proper_string(command.name) getOrElse "<command>"  | 
| 
57905
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
63  | 
case Ignored_Span => "<ignored>"  | 
| 
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
64  | 
case Malformed_Span => "<malformed>"  | 
| 
72692
 
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
 
wenzelm 
parents: 
68845 
diff
changeset
 | 
65  | 
case Theory_Span => "<theory>"  | 
| 
57905
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
66  | 
}  | 
| 
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
67  | 
}  | 
| 
78912
 
ff4496b25197
clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
 
wenzelm 
parents: 
76798 
diff
changeset
 | 
68  | 
case class Command_Span(override val keyword_kind: Option[String], name: String, pos: Position.T)  | 
| 
 
ff4496b25197
clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
 
wenzelm 
parents: 
76798 
diff
changeset
 | 
69  | 
extends Kind  | 
| 
57905
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
70  | 
case object Ignored_Span extends Kind  | 
| 
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
71  | 
case object Malformed_Span extends Kind  | 
| 
72692
 
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
 
wenzelm 
parents: 
68845 
diff
changeset
 | 
72  | 
case object Theory_Span extends Kind  | 
| 
57905
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
73  | 
|
| 72743 | 74  | 
|
75  | 
/* span */  | 
|
76  | 
||
| 75393 | 77  | 
  sealed case class Span(kind: Kind, content: List[Token]) {
 | 
| 
72692
 
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
 
wenzelm 
parents: 
68845 
diff
changeset
 | 
78  | 
def is_theory: Boolean = kind == Theory_Span  | 
| 
 
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
 
wenzelm 
parents: 
68845 
diff
changeset
 | 
79  | 
|
| 59735 | 80  | 
def name: String =  | 
| 72800 | 81  | 
      kind match { case k: Command_Span => k.name case _ => "" }
 | 
| 58802 | 82  | 
|
| 59735 | 83  | 
def position: Position.T =  | 
| 72800 | 84  | 
      kind match { case k: Command_Span => k.pos case _ => Position.none }
 | 
85  | 
||
| 67895 | 86  | 
def keyword_pos(start: Token.Pos): Token.Pos =  | 
87  | 
      kind match {
 | 
|
88  | 
case _: Command_Span =>  | 
|
| 73359 | 89  | 
content.iterator.takeWhile(tok => !tok.is_command).foldLeft(start)(_.advance(_))  | 
| 67895 | 90  | 
case _ => start  | 
91  | 
}  | 
|
92  | 
||
| 
78912
 
ff4496b25197
clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
 
wenzelm 
parents: 
76798 
diff
changeset
 | 
93  | 
def is_keyword_kind(pred: String => Boolean, other: Boolean = false): Boolean =  | 
| 
 
ff4496b25197
clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
 
wenzelm 
parents: 
76798 
diff
changeset
 | 
94  | 
      kind.keyword_kind match {
 | 
| 68840 | 95  | 
case Some(k) => pred(k)  | 
| 
68845
 
3b2daa7bf9f4
support Thy_Element in Scala, following ML version;
 
wenzelm 
parents: 
68840 
diff
changeset
 | 
96  | 
case None => other  | 
| 68840 | 97  | 
}  | 
98  | 
||
| 63606 | 99  | 
def is_begin: Boolean = content.exists(_.is_begin)  | 
100  | 
def is_end: Boolean = content.exists(_.is_end)  | 
|
101  | 
||
| 72946 | 102  | 
def content_reader: CharSequenceReader = Scan.char_reader(Token.implode(content))  | 
103  | 
||
| 73359 | 104  | 
def length: Int = content.foldLeft(0)(_ + _.source.length)  | 
| 59705 | 105  | 
|
| 75393 | 106  | 
    def compact_source: (String, Span) = {
 | 
| 59735 | 107  | 
val source = Token.implode(content)  | 
| 
57905
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
108  | 
val content1 = new mutable.ListBuffer[Token]  | 
| 
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
109  | 
var i = 0  | 
| 
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
110  | 
      for (Token(kind, s) <- content) {
 | 
| 
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
111  | 
val n = s.length  | 
| 59735 | 112  | 
val s1 = source.substring(i, i + n)  | 
| 
57905
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
113  | 
content1 += Token(kind, s1)  | 
| 
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
114  | 
i += n  | 
| 
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
115  | 
}  | 
| 59735 | 116  | 
(source, Span(kind, content1.toList))  | 
| 
57905
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
117  | 
}  | 
| 72742 | 118  | 
|
| 75393 | 119  | 
    def clean_arguments: List[(Token, Int)] = {
 | 
| 72743 | 120  | 
      if (name.nonEmpty) {
 | 
121  | 
def clean(toks: List[(Token, Int)]): List[(Token, Int)] =  | 
|
122  | 
          toks match {
 | 
|
123  | 
case (t1, i1) :: (t2, i2) :: rest =>  | 
|
124  | 
if (t1.is_keyword && t1.source == "%" && t2.is_name) clean(rest)  | 
|
125  | 
else (t1, i1) :: clean((t2, i2) :: rest)  | 
|
126  | 
case _ => toks  | 
|
127  | 
}  | 
|
128  | 
        clean(content.zipWithIndex.filter({ case (t, _) => t.is_proper }))
 | 
|
129  | 
          .dropWhile({ case (t, _) => !t.is_command })
 | 
|
130  | 
          .dropWhile({ case (t, _) => t.is_command })
 | 
|
131  | 
}  | 
|
132  | 
else Nil  | 
|
133  | 
}  | 
|
134  | 
||
| 
72816
 
ea4f86914cb2
support for PIDE markup for auxiliary files ("blobs");
 
wenzelm 
parents: 
72800 
diff
changeset
 | 
135  | 
def is_load_command(syntax: Outer_Syntax): Boolean =  | 
| 
 
ea4f86914cb2
support for PIDE markup for auxiliary files ("blobs");
 
wenzelm 
parents: 
72800 
diff
changeset
 | 
136  | 
syntax.load_command(name).isDefined  | 
| 
 
ea4f86914cb2
support for PIDE markup for auxiliary files ("blobs");
 
wenzelm 
parents: 
72800 
diff
changeset
 | 
137  | 
|
| 72743 | 138  | 
def loaded_files(syntax: Outer_Syntax): Loaded_Files =  | 
| 72742 | 139  | 
      syntax.load_command(name) match {
 | 
| 72757 | 140  | 
case None => Loaded_Files.none  | 
| 
72748
 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 
wenzelm 
parents: 
72744 
diff
changeset
 | 
141  | 
case Some(a) =>  | 
| 
 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 
wenzelm 
parents: 
72744 
diff
changeset
 | 
142  | 
          load_commands.find(_.name == a) match {
 | 
| 
 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 
wenzelm 
parents: 
72744 
diff
changeset
 | 
143  | 
case Some(load_command) => load_command.loaded_files(clean_arguments)  | 
| 
 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 
wenzelm 
parents: 
72744 
diff
changeset
 | 
144  | 
            case None => error("Undefined load command function: " + a)
 | 
| 
 
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
 
wenzelm 
parents: 
72744 
diff
changeset
 | 
145  | 
}  | 
| 72742 | 146  | 
}  | 
| 
57905
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
147  | 
}  | 
| 
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
148  | 
|
| 
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
149  | 
val empty: Span = Span(Ignored_Span, Nil)  | 
| 
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
150  | 
|
| 78913 | 151  | 
  def unparsed(source: String, theory: Boolean = false): Span = {
 | 
| 
72692
 
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
 
wenzelm 
parents: 
68845 
diff
changeset
 | 
152  | 
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: 
68845 
diff
changeset
 | 
153  | 
Span(kind, List(Token(Token.Kind.UNPARSED, source)))  | 
| 
 
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
 
wenzelm 
parents: 
68845 
diff
changeset
 | 
154  | 
}  | 
| 
57905
 
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
 
wenzelm 
parents:  
diff
changeset
 | 
155  | 
}  |