author | wenzelm |
Wed, 28 Dec 2022 12:30:18 +0100 | |
changeset 76798 | 69d8d16c5612 |
parent 76615 | b865959e2547 |
child 78912 | ff4496b25197 |
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 { |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
58 |
override def toString: String = |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
59 |
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:
72946
diff
changeset
|
60 |
case Command_Span(name, _) => proper_string(name) getOrElse "<command>" |
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
61 |
case Ignored_Span => "<ignored>" |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
62 |
case Malformed_Span => "<malformed>" |
72692
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
wenzelm
parents:
68845
diff
changeset
|
63 |
case Theory_Span => "<theory>" |
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
64 |
} |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
65 |
} |
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:
72946
diff
changeset
|
66 |
case class Command_Span(name: String, pos: Position.T) extends Kind |
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
67 |
case object Ignored_Span extends Kind |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
68 |
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
|
69 |
case object Theory_Span extends Kind |
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
70 |
|
72743 | 71 |
|
72 |
/* span */ |
|
73 |
||
75393 | 74 |
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
|
75 |
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
|
76 |
|
59735 | 77 |
def name: String = |
72800 | 78 |
kind match { case k: Command_Span => k.name case _ => "" } |
58802 | 79 |
|
59735 | 80 |
def position: Position.T = |
72800 | 81 |
kind match { case k: Command_Span => k.pos case _ => Position.none } |
82 |
||
67895 | 83 |
def keyword_pos(start: Token.Pos): Token.Pos = |
84 |
kind match { |
|
85 |
case _: Command_Span => |
|
73359 | 86 |
content.iterator.takeWhile(tok => !tok.is_command).foldLeft(start)(_.advance(_)) |
67895 | 87 |
case _ => start |
88 |
} |
|
89 |
||
68845
3b2daa7bf9f4
support Thy_Element in Scala, following ML version;
wenzelm
parents:
68840
diff
changeset
|
90 |
def is_kind(keywords: Keyword.Keywords, pred: String => Boolean, other: Boolean): Boolean = |
68840 | 91 |
keywords.kinds.get(name) match { |
92 |
case Some(k) => pred(k) |
|
68845
3b2daa7bf9f4
support Thy_Element in Scala, following ML version;
wenzelm
parents:
68840
diff
changeset
|
93 |
case None => other |
68840 | 94 |
} |
95 |
||
63606 | 96 |
def is_begin: Boolean = content.exists(_.is_begin) |
97 |
def is_end: Boolean = content.exists(_.is_end) |
|
98 |
||
72946 | 99 |
def content_reader: CharSequenceReader = Scan.char_reader(Token.implode(content)) |
100 |
||
73359 | 101 |
def length: Int = content.foldLeft(0)(_ + _.source.length) |
59705 | 102 |
|
75393 | 103 |
def compact_source: (String, Span) = { |
59735 | 104 |
val source = Token.implode(content) |
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
105 |
val content1 = new mutable.ListBuffer[Token] |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
106 |
var i = 0 |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
107 |
for (Token(kind, s) <- content) { |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
108 |
val n = s.length |
59735 | 109 |
val s1 = source.substring(i, i + n) |
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
110 |
content1 += Token(kind, s1) |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
111 |
i += n |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
112 |
} |
59735 | 113 |
(source, Span(kind, content1.toList)) |
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
114 |
} |
72742 | 115 |
|
75393 | 116 |
def clean_arguments: List[(Token, Int)] = { |
72743 | 117 |
if (name.nonEmpty) { |
118 |
def clean(toks: List[(Token, Int)]): List[(Token, Int)] = |
|
119 |
toks match { |
|
120 |
case (t1, i1) :: (t2, i2) :: rest => |
|
121 |
if (t1.is_keyword && t1.source == "%" && t2.is_name) clean(rest) |
|
122 |
else (t1, i1) :: clean((t2, i2) :: rest) |
|
123 |
case _ => toks |
|
124 |
} |
|
125 |
clean(content.zipWithIndex.filter({ case (t, _) => t.is_proper })) |
|
126 |
.dropWhile({ case (t, _) => !t.is_command }) |
|
127 |
.dropWhile({ case (t, _) => t.is_command }) |
|
128 |
} |
|
129 |
else Nil |
|
130 |
} |
|
131 |
||
72816
ea4f86914cb2
support for PIDE markup for auxiliary files ("blobs");
wenzelm
parents:
72800
diff
changeset
|
132 |
def is_load_command(syntax: Outer_Syntax): Boolean = |
ea4f86914cb2
support for PIDE markup for auxiliary files ("blobs");
wenzelm
parents:
72800
diff
changeset
|
133 |
syntax.load_command(name).isDefined |
ea4f86914cb2
support for PIDE markup for auxiliary files ("blobs");
wenzelm
parents:
72800
diff
changeset
|
134 |
|
72743 | 135 |
def loaded_files(syntax: Outer_Syntax): Loaded_Files = |
72742 | 136 |
syntax.load_command(name) match { |
72757 | 137 |
case None => Loaded_Files.none |
72748
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
138 |
case Some(a) => |
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
139 |
load_commands.find(_.name == a) match { |
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
140 |
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
|
141 |
case None => error("Undefined load command function: " + a) |
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
142 |
} |
72742 | 143 |
} |
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
144 |
} |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
145 |
|
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
146 |
val empty: Span = Span(Ignored_Span, Nil) |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
147 |
|
75393 | 148 |
def unparsed(source: String, theory: Boolean): Span = { |
72692
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
wenzelm
parents:
68845
diff
changeset
|
149 |
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
|
150 |
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
|
151 |
} |
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
152 |
} |