author | wenzelm |
Fri, 27 Nov 2020 23:47:06 +0100 | |
changeset 72748 | 04d5f6d769a7 |
parent 72744 | 0017eb17ac1c |
child 72757 | 38e05b7ded61 |
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 |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
11 |
|
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 |
object Command_Span |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
14 |
{ |
72743 | 15 |
/* loaded files */ |
16 |
||
17 |
type Loaded_Files = (List[String], Int) |
|
18 |
||
19 |
val no_loaded_files: Loaded_Files = (Nil, -1) |
|
20 |
||
72748
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
21 |
class Load_Command(val name: String) extends Isabelle_System.Service |
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
22 |
{ |
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
23 |
override def toString: String = name |
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
24 |
|
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
25 |
def extensions: List[String] = Nil |
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
26 |
|
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
27 |
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
|
28 |
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
|
29 |
case Some((file, i)) => |
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
30 |
extensions match { |
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
31 |
case Nil => (List(file), i) |
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
32 |
case exts => (exts.map(ext => file + "." + ext), i) |
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
33 |
} |
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
34 |
case None => no_loaded_files |
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
35 |
} |
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
36 |
} |
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 |
lazy val load_commands: List[Load_Command] = |
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
39 |
new Load_Command("") :: Isabelle_System.make_services(classOf[Load_Command]) |
72743 | 40 |
|
41 |
||
42 |
/* span kind */ |
|
43 |
||
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
44 |
sealed abstract class Kind { |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
45 |
override def toString: String = |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
46 |
this match { |
65717 | 47 |
case Command_Span(name, _) => proper_string(name) getOrElse "<command>" |
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
48 |
case Ignored_Span => "<ignored>" |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
49 |
case Malformed_Span => "<malformed>" |
72692
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
wenzelm
parents:
68845
diff
changeset
|
50 |
case Theory_Span => "<theory>" |
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
51 |
} |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
52 |
} |
57910 | 53 |
case class Command_Span(name: String, pos: Position.T) extends Kind |
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
54 |
case object Ignored_Span extends Kind |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
55 |
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
|
56 |
case object Theory_Span extends Kind |
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
57 |
|
72743 | 58 |
|
59 |
/* span */ |
|
60 |
||
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
61 |
sealed case class Span(kind: Kind, content: List[Token]) |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
62 |
{ |
72692
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
wenzelm
parents:
68845
diff
changeset
|
63 |
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
|
64 |
|
59735 | 65 |
def name: String = |
66 |
kind match { case Command_Span(name, _) => name case _ => "" } |
|
58802 | 67 |
|
59735 | 68 |
def position: Position.T = |
69 |
kind match { case Command_Span(_, pos) => pos case _ => Position.none } |
|
70 |
||
67895 | 71 |
def keyword_pos(start: Token.Pos): Token.Pos = |
72 |
kind match { |
|
73 |
case _: Command_Span => |
|
74 |
(start /: content.iterator.takeWhile(tok => !tok.is_command))(_.advance(_)) |
|
75 |
case _ => start |
|
76 |
} |
|
77 |
||
68845
3b2daa7bf9f4
support Thy_Element in Scala, following ML version;
wenzelm
parents:
68840
diff
changeset
|
78 |
def is_kind(keywords: Keyword.Keywords, pred: String => Boolean, other: Boolean): Boolean = |
68840 | 79 |
keywords.kinds.get(name) match { |
80 |
case Some(k) => pred(k) |
|
68845
3b2daa7bf9f4
support Thy_Element in Scala, following ML version;
wenzelm
parents:
68840
diff
changeset
|
81 |
case None => other |
68840 | 82 |
} |
83 |
||
63606 | 84 |
def is_begin: Boolean = content.exists(_.is_begin) |
85 |
def is_end: Boolean = content.exists(_.is_end) |
|
86 |
||
59735 | 87 |
def length: Int = (0 /: content)(_ + _.source.length) |
59705 | 88 |
|
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
89 |
def compact_source: (String, Span) = |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
90 |
{ |
59735 | 91 |
val source = Token.implode(content) |
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
92 |
val content1 = new mutable.ListBuffer[Token] |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
93 |
var i = 0 |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
94 |
for (Token(kind, s) <- content) { |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
95 |
val n = s.length |
59735 | 96 |
val s1 = source.substring(i, i + n) |
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
97 |
content1 += Token(kind, s1) |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
98 |
i += n |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
99 |
} |
59735 | 100 |
(source, Span(kind, content1.toList)) |
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
101 |
} |
72742 | 102 |
|
72743 | 103 |
def clean_arguments: List[(Token, Int)] = |
104 |
{ |
|
105 |
if (name.nonEmpty) { |
|
106 |
def clean(toks: List[(Token, Int)]): List[(Token, Int)] = |
|
107 |
toks match { |
|
108 |
case (t1, i1) :: (t2, i2) :: rest => |
|
109 |
if (t1.is_keyword && t1.source == "%" && t2.is_name) clean(rest) |
|
110 |
else (t1, i1) :: clean((t2, i2) :: rest) |
|
111 |
case _ => toks |
|
112 |
} |
|
113 |
clean(content.zipWithIndex.filter({ case (t, _) => t.is_proper })) |
|
114 |
.dropWhile({ case (t, _) => !t.is_command }) |
|
115 |
.dropWhile({ case (t, _) => t.is_command }) |
|
116 |
} |
|
117 |
else Nil |
|
118 |
} |
|
119 |
||
120 |
def loaded_files(syntax: Outer_Syntax): Loaded_Files = |
|
72742 | 121 |
syntax.load_command(name) match { |
72743 | 122 |
case None => no_loaded_files |
72748
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
123 |
case Some(a) => |
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
124 |
load_commands.find(_.name == a) match { |
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
125 |
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
|
126 |
case None => error("Undefined load command function: " + a) |
04d5f6d769a7
more flexible syntax for theory load commands via Isabelle/Scala;
wenzelm
parents:
72744
diff
changeset
|
127 |
} |
72742 | 128 |
} |
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
129 |
} |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
130 |
|
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
131 |
val empty: Span = Span(Ignored_Span, Nil) |
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
132 |
|
72692
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
wenzelm
parents:
68845
diff
changeset
|
133 |
def unparsed(source: String, theory: Boolean): Span = |
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
wenzelm
parents:
68845
diff
changeset
|
134 |
{ |
22aeec526ffd
support for PIDE markup in batch build (inactive due to pide_reports=false);
wenzelm
parents:
68845
diff
changeset
|
135 |
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
|
136 |
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
|
137 |
} |
57905
c0c5652e796e
separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff
changeset
|
138 |
} |