codemirror-lang-raku 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +75 -3
- package/README.md +90 -36
- package/dist/index.cjs +268 -49
- package/dist/index.js +268 -49
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -28,12 +28,13 @@ const smiley = 201,
|
|
|
28
28
|
MethodName = 14,
|
|
29
29
|
declaredName = 206,
|
|
30
30
|
declaredMethodName = 207,
|
|
31
|
+
declaredVariable = 208,
|
|
31
32
|
Version = 15,
|
|
32
|
-
regexStart =
|
|
33
|
-
regexBodyEnd =
|
|
34
|
-
regexLitOpen =
|
|
35
|
-
regexLitClose =
|
|
36
|
-
regexText =
|
|
33
|
+
regexStart = 209,
|
|
34
|
+
regexBodyEnd = 210,
|
|
35
|
+
regexLitOpen = 211,
|
|
36
|
+
regexLitClose = 212,
|
|
37
|
+
regexText = 213,
|
|
37
38
|
CharacterClass = 16,
|
|
38
39
|
Assertion = 17,
|
|
39
40
|
regexQuote = 18,
|
|
@@ -41,18 +42,18 @@ const smiley = 201,
|
|
|
41
42
|
regexComment = 20,
|
|
42
43
|
regexBlockComment = 21,
|
|
43
44
|
regexCapture = 22,
|
|
44
|
-
quoteContent =
|
|
45
|
-
quoteNestOpen =
|
|
46
|
-
quoteNestClose =
|
|
47
|
-
quoteEnd =
|
|
48
|
-
rawString =
|
|
49
|
-
quoteStart =
|
|
45
|
+
quoteContent = 214,
|
|
46
|
+
quoteNestOpen = 215,
|
|
47
|
+
quoteNestClose = 216,
|
|
48
|
+
quoteEnd = 217,
|
|
49
|
+
rawString = 218,
|
|
50
|
+
quoteStart = 219,
|
|
50
51
|
interpolatingWordList = 23,
|
|
51
52
|
regexLiteral = 24,
|
|
52
53
|
transliteration = 25,
|
|
53
|
-
plainName =
|
|
54
|
+
plainName = 220,
|
|
54
55
|
wordOperator = 26,
|
|
55
|
-
multiName =
|
|
56
|
+
multiName = 221,
|
|
56
57
|
operatorVariable = 27,
|
|
57
58
|
LineComment = 28,
|
|
58
59
|
DocComment = 29,
|
|
@@ -93,7 +94,7 @@ const smiley = 201,
|
|
|
93
94
|
// embedded comments. Raku accepts any Unicode bracket pair; this lists
|
|
94
95
|
// the ones that are likely to be typed.
|
|
95
96
|
const brackets$1 = {};
|
|
96
|
-
for (let pair of ["()", "[]", "{}", "<>", "«»", "「」", "『』", "()", "[]", "{}", "【】", "〈〉", "《》", "〔〕"])
|
|
97
|
+
for (let pair of ["()", "[]", "{}", "<>", "«»", "「」", "「」", "『』", "()", "[]", "{}", "【】", "〈〉", "《》", "〔〕"])
|
|
97
98
|
brackets$1[pair.charCodeAt(0)] = pair.charCodeAt(1);
|
|
98
99
|
function isAsciiLetter(ch) { return ch >= 97 /* Ch.a */ && ch <= 122 /* Ch.z */ || ch >= 65 /* Ch.A */ && ch <= 90 /* Ch.Z */; }
|
|
99
100
|
function isDigit(ch) { return ch >= 48 /* Ch._0 */ && ch <= 57 /* Ch._9 */; }
|
|
@@ -269,7 +270,7 @@ for (let term of [VariableName, AttributeName, SpecialVariable, operatorVariable
|
|
|
269
270
|
regexText, CharacterClass, Assertion, regexQuote, regexOperator, regexComment,
|
|
270
271
|
regexBlockComment, regexCapture])
|
|
271
272
|
termModes.set(term, 1 /* Mode.AfterTerm */);
|
|
272
|
-
for (let term of [Identifier, TypeName, smiley, noSmiley, declaredName, declaredMethodName, PackageName, RoutineName,
|
|
273
|
+
for (let term of [Identifier, TypeName, smiley, noSmiley, declaredName, declaredMethodName, declaredVariable, PackageName, RoutineName,
|
|
273
274
|
methodRoutineName, multiName, multiRoutineName, RegexName, EnumName, SubsetName, ConstantName])
|
|
274
275
|
termModes.set(term, 2 /* Mode.AfterName */);
|
|
275
276
|
// The `}` of "{...}" in a string does not take a subscript.
|
|
@@ -283,6 +284,10 @@ function modeAfterOperator(first, second, third, after) {
|
|
|
283
284
|
// A lone `*` is as often the whatever star as a multiplication.
|
|
284
285
|
if (first == 42 /* Ch.Star */ && !isOperatorChar(second))
|
|
285
286
|
return 2 /* Mode.AfterName */;
|
|
287
|
+
// A power in superscript, $x², leaves the term complete. These are
|
|
288
|
+
// the characters that the grammar's Operator token takes for one.
|
|
289
|
+
if (first == 0xb2 || first == 0xb3 || first == 0xb9 || first == 0x2070 || first >= 0x2074 && first <= 0x207b)
|
|
290
|
+
return 1 /* Mode.AfterTerm */;
|
|
286
291
|
// Postfix increment and decrement leave the term complete.
|
|
287
292
|
if ((first == 43 /* Ch.Plus */ || first == 45 /* Ch.Hyphen */) && second == first && !isOperatorChar(third) &&
|
|
288
293
|
(after == 1 /* Mode.AfterTerm */ || after == 3 /* Mode.AfterBlock */))
|
|
@@ -536,16 +541,24 @@ const blockComment = new lr.ExternalTokenizer(input => {
|
|
|
536
541
|
let end = embeddedCommentEnd(input, 0);
|
|
537
542
|
if (!end)
|
|
538
543
|
return;
|
|
544
|
+
// A declarator comment with brackets, #|( ... ) and #=( ... ), is
|
|
545
|
+
// still a declarator comment.
|
|
546
|
+
let term = input.peek(1) == 96 /* Ch.Backtick */ ? BlockComment : DocComment;
|
|
539
547
|
if (end < 0)
|
|
540
548
|
skipToEnd(input);
|
|
541
549
|
else
|
|
542
550
|
input.advance(end);
|
|
543
|
-
input.acceptToken(
|
|
551
|
+
input.acceptToken(term);
|
|
544
552
|
});
|
|
545
553
|
// The offset after the embedded comment that starts at offset `at`.
|
|
546
554
|
// Zero when none starts there, and -1 when it is not closed.
|
|
555
|
+
//
|
|
556
|
+
// A declarator comment with brackets that is not closed is none: it is
|
|
557
|
+
// left to be a comment of one line, so that one that is being typed
|
|
558
|
+
// does not take the declarations after it.
|
|
547
559
|
function embeddedCommentEnd(input, at) {
|
|
548
|
-
|
|
560
|
+
let mark = input.peek(at + 1);
|
|
561
|
+
if (input.peek(at) != 35 /* Ch.Hash */ || mark != 96 /* Ch.Backtick */ && mark != 124 /* Ch.Pipe */ && mark != 61 /* Ch.Equals */)
|
|
549
562
|
return 0;
|
|
550
563
|
let open = input.peek(at + 2), close = brackets$1[open];
|
|
551
564
|
if (close == null)
|
|
@@ -553,7 +566,8 @@ function embeddedCommentEnd(input, at) {
|
|
|
553
566
|
let count = 1;
|
|
554
567
|
while (input.peek(at + 2 + count) == open)
|
|
555
568
|
count++;
|
|
556
|
-
|
|
569
|
+
let end = rawEnd(input, at + 2 + count, { open, close, count, escapes: false });
|
|
570
|
+
return end < 0 && mark != 96 /* Ch.Backtick */ ? 0 : end;
|
|
557
571
|
}
|
|
558
572
|
function isBlank(ch) { return ch == 32 /* Ch.Space */ || ch == 9 /* Ch.Tab */ || ch == 13 /* Ch.Return */; }
|
|
559
573
|
// The offset of the first character at or after `pos` that is not a blank.
|
|
@@ -786,7 +800,9 @@ function quoteCharOpening(open, close, at, interpolates, escapes = true) {
|
|
|
786
800
|
// The delimiters, other than brackets, that are accepted after a quote word.
|
|
787
801
|
function isQuoteDelimiter(ch) {
|
|
788
802
|
return ch == 47 /* Ch.Slash */ || ch == 33 /* Ch.Bang */ || ch == 124 /* Ch.Pipe */ || ch == 126 /* Ch.Tilde */ || ch == 94 /* Ch.Caret */ ||
|
|
789
|
-
ch == 37 /* Ch.Percent */ || ch == 64 /* Ch.At */ || ch == 34 /* Ch.DoubleQuote */ || ch == 39 /* Ch.Apostrophe
|
|
803
|
+
ch == 37 /* Ch.Percent */ || ch == 64 /* Ch.At */ || ch == 34 /* Ch.DoubleQuote */ || ch == 39 /* Ch.Apostrophe */ || ch == 96 /* Ch.Backtick */ ||
|
|
804
|
+
// A symbol outside of ASCII: Q♥a♥
|
|
805
|
+
ch > 0xa0 && ch != 0xd7 && ch != 0xf7 && !isIdentifierStart(ch) && !isSpace(ch) && ch < 0xd800;
|
|
790
806
|
}
|
|
791
807
|
// Reads the start of a quote at offset `at`: a quote character, or a
|
|
792
808
|
// quote word (q, qq, m, s, ...) with its adverbs and its delimiter.
|
|
@@ -801,8 +817,16 @@ function readOpening(input, at = 0) {
|
|
|
801
817
|
return quoteCharOpening(next, 0x201d, at, 63 /* Interpolate.All */);
|
|
802
818
|
if (next == 0x2018 /* ‘ */)
|
|
803
819
|
return quoteCharOpening(next, 0x2019, at, 0);
|
|
820
|
+
if (next == 0x201e /* „ */)
|
|
821
|
+
return quoteCharOpening(next, 0x201d, at, 63 /* Interpolate.All */);
|
|
822
|
+
if (next == 0x201d /* ” */)
|
|
823
|
+
return quoteCharOpening(next, next, at, 63 /* Interpolate.All */);
|
|
824
|
+
if (next == 0x201a /* ‚ */)
|
|
825
|
+
return quoteCharOpening(next, 0x2019, at, 0);
|
|
804
826
|
if (next == 0x300c /* 「 */)
|
|
805
827
|
return quoteCharOpening(next, 0x300d, at, 0, false);
|
|
828
|
+
if (next == 0xff62 /* 「 */)
|
|
829
|
+
return quoteCharOpening(next, 0xff63, at, 0, false);
|
|
806
830
|
if (!isAsciiLetter(next))
|
|
807
831
|
return null;
|
|
808
832
|
let pos = at + 1;
|
|
@@ -881,14 +905,14 @@ function readOpening(input, at = 0) {
|
|
|
881
905
|
// The offset after the delimiter that closes a quote whose content
|
|
882
906
|
// starts at `pos`, or -1 when it is not closed.
|
|
883
907
|
function rawEnd(input, pos, opening) {
|
|
884
|
-
let { open, close, count } = opening;
|
|
908
|
+
let { open, close, count } = opening, other = otherClose(open);
|
|
885
909
|
for (let depth = 1;;) {
|
|
886
910
|
let ch = input.peek(pos);
|
|
887
911
|
if (ch < 0)
|
|
888
912
|
return -1;
|
|
889
913
|
if (ch == 92 /* Ch.Backslash */ && opening.escapes)
|
|
890
914
|
pos += 2;
|
|
891
|
-
else if (ch == close && repeats(input, pos, close, count)) {
|
|
915
|
+
else if (ch == close && repeats(input, pos, close, count) || ch == other) {
|
|
892
916
|
pos += count;
|
|
893
917
|
if (--depth == 0)
|
|
894
918
|
return pos;
|
|
@@ -901,26 +925,111 @@ function rawEnd(input, pos, opening) {
|
|
|
901
925
|
pos++;
|
|
902
926
|
}
|
|
903
927
|
}
|
|
928
|
+
// The character that closes a quote in a regex that opens with `ch`,
|
|
929
|
+
// or 0 when `ch` opens none: 'a', "a", ‘a’, ‚a’, “a”, „a”, 「a」
|
|
930
|
+
function quoteClose(ch) {
|
|
931
|
+
return ch == 39 /* Ch.Apostrophe */ || ch == 34 /* Ch.DoubleQuote */ ? ch : ch == 0x2018 || ch == 0x201a ? 0x2019 :
|
|
932
|
+
ch == 0x201c || ch == 0x201e ? 0x201d : ch == 0xff62 ? 0xff63 : 0;
|
|
933
|
+
}
|
|
934
|
+
// A low quote is also closed by the quote that points the other way:
|
|
935
|
+
// ‚a‘, „a“. This is that quote for the given opening one, or -1.
|
|
936
|
+
function otherClose(open) { return open == 0x201a ? 0x2018 : open == 0x201e ? 0x201c : -1; }
|
|
904
937
|
// The offset after a quoted string that starts at `pos`, or -1.
|
|
905
938
|
function quotedEnd(input, pos) {
|
|
906
|
-
let
|
|
939
|
+
let open = input.peek(pos), close = quoteClose(open), other = otherClose(open);
|
|
907
940
|
for (pos++;;) {
|
|
908
941
|
let ch = input.peek(pos);
|
|
909
942
|
if (ch < 0 || ch == 10 /* Ch.Newline */)
|
|
910
943
|
return -1;
|
|
911
|
-
|
|
944
|
+
// Nothing is escaped in 「...」.
|
|
945
|
+
if (ch == 92 /* Ch.Backslash */ && open != 0xff62)
|
|
912
946
|
pos += 2;
|
|
913
|
-
else if (ch ==
|
|
947
|
+
else if (ch == close || ch == other)
|
|
914
948
|
return pos + 1;
|
|
915
949
|
else
|
|
916
950
|
pos++;
|
|
917
951
|
}
|
|
918
952
|
}
|
|
953
|
+
// The offset after the arguments of the assertion that starts with the
|
|
954
|
+
// `<` at `pos`, or 0 when it has none on its line. The arguments are
|
|
955
|
+
// code, in which the delimiter of the regex does not end it:
|
|
956
|
+
// <name(1/2)>, <:name(/x/)>, <name: /a<b>+/ >
|
|
957
|
+
function assertionArgumentsEnd(input, pos) {
|
|
958
|
+
// An assertion can add up several names: <+:Lu +:name(/SMALL/)>
|
|
959
|
+
for (let at = pos + 1;;) {
|
|
960
|
+
while (isAssertionMark(input.peek(at)) || isBlank(input.peek(at)))
|
|
961
|
+
at++;
|
|
962
|
+
let end = nameEnd(input, at);
|
|
963
|
+
if (end < 0)
|
|
964
|
+
return 0;
|
|
965
|
+
// With parentheses, up to the one that closes them. After a colon
|
|
966
|
+
// and a space, up to the `>` that closes the assertion.
|
|
967
|
+
let open = input.peek(end);
|
|
968
|
+
if (open == 40 /* Ch.ParenOpen */)
|
|
969
|
+
return balancedEnd(input, end + 1, 40 /* Ch.ParenOpen */, 41 /* Ch.ParenClose */);
|
|
970
|
+
if (open == 58 /* Ch.Colon */ && isBlank(input.peek(end + 1)))
|
|
971
|
+
return balancedEnd(input, end + 1, 60 /* Ch.Less */, 62 /* Ch.Greater */);
|
|
972
|
+
at = end;
|
|
973
|
+
if (!isAssertionMark(input.peek(at)) && !isBlank(input.peek(at)))
|
|
974
|
+
return 0;
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
// The characters that come before the name in an assertion: <.ws>, <?before>, <+alpha>
|
|
978
|
+
function isAssertionMark(ch) {
|
|
979
|
+
return ch == 46 /* Ch.Dot */ || ch == 63 /* Ch.Question */ || ch == 33 /* Ch.Bang */ || ch == 58 /* Ch.Colon */ || ch == 38 /* Ch.Amp */ || ch == 43 /* Ch.Plus */ ||
|
|
980
|
+
ch == 45 /* Ch.Hyphen */;
|
|
981
|
+
}
|
|
982
|
+
// The offset after the code that the `<` or `:` at `pos` in a regex
|
|
983
|
+
// starts, or 0 when it starts none.
|
|
984
|
+
function regexCodeEnd(input, pos) {
|
|
985
|
+
return input.peek(pos) == 60 /* Ch.Less */ ? assertionArgumentsEnd(input, pos) : regexDeclarationEnd(input, pos);
|
|
986
|
+
}
|
|
987
|
+
// The offset after the declaration that starts with the `:` at `pos`
|
|
988
|
+
// in a regex, or 0 when none does: `:my $c = $/;`. It is code up to
|
|
989
|
+
// its `;`, in which the delimiter of the regex does not end it.
|
|
990
|
+
function regexDeclarationEnd(input, pos) {
|
|
991
|
+
let end = nameEnd(input, pos + 1);
|
|
992
|
+
if (end < 0 || end - pos > 9 || !isBlank(input.peek(end)) ||
|
|
993
|
+
!/^(my|our|state|constant|temp|let)$/.test(word(input, pos + 1, end)))
|
|
994
|
+
return 0;
|
|
995
|
+
for (;;) {
|
|
996
|
+
let ch = input.peek(end);
|
|
997
|
+
if (ch < 0 || ch == 10 /* Ch.Newline */)
|
|
998
|
+
return 0;
|
|
999
|
+
if (ch == 59 /* Ch.Semicolon */)
|
|
1000
|
+
return end + 1;
|
|
1001
|
+
let quoted = quoteClose(ch) ? quotedEnd(input, end) : -1;
|
|
1002
|
+
end = quoted > 0 ? quoted : end + 1;
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
// The offset after the `close` that matches an `open` before `pos`, or
|
|
1006
|
+
// 0 when there is none on the line. Quotes are gone over.
|
|
1007
|
+
function balancedEnd(input, pos, open, close) {
|
|
1008
|
+
for (let depth = 1;;) {
|
|
1009
|
+
let ch = input.peek(pos);
|
|
1010
|
+
if (ch < 0 || ch == 10 /* Ch.Newline */)
|
|
1011
|
+
return 0;
|
|
1012
|
+
if (ch == 92 /* Ch.Backslash */)
|
|
1013
|
+
pos += 2;
|
|
1014
|
+
else if (quoteClose(ch)) {
|
|
1015
|
+
let quoted = quotedEnd(input, pos);
|
|
1016
|
+
pos = quoted < 0 ? pos + 1 : quoted;
|
|
1017
|
+
}
|
|
1018
|
+
else {
|
|
1019
|
+
pos++;
|
|
1020
|
+
if (ch == open)
|
|
1021
|
+
depth++;
|
|
1022
|
+
else if (ch == close && --depth == 0)
|
|
1023
|
+
return pos;
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
919
1027
|
// The offset of the delimiter that closes a regex whose content starts
|
|
920
1028
|
// at `pos`, or -1. Delimiters do not count inside quotes, character
|
|
921
|
-
// classes, comments and code blocks.
|
|
922
|
-
|
|
923
|
-
|
|
1029
|
+
// classes, comments and code blocks. `code` is set for the inside of a
|
|
1030
|
+
// code block, where a `<` is an operator.
|
|
1031
|
+
function regexEnd(input, { start: pos, open, close, count }, code = false) {
|
|
1032
|
+
for (let depth = 1, codeEnd;;) {
|
|
924
1033
|
let ch = input.peek(pos);
|
|
925
1034
|
if (ch < 0)
|
|
926
1035
|
return -1;
|
|
@@ -936,10 +1045,25 @@ function regexEnd(input, { start: pos, open, close, count }) {
|
|
|
936
1045
|
pos += count;
|
|
937
1046
|
depth++;
|
|
938
1047
|
}
|
|
939
|
-
else if (ch
|
|
1048
|
+
else if (quoteClose(ch)) {
|
|
940
1049
|
let end = quotedEnd(input, pos);
|
|
941
1050
|
pos = end < 0 ? pos + 1 : end;
|
|
942
1051
|
}
|
|
1052
|
+
else if (!code && ch == 60 /* Ch.Less */ && isBlank(input.peek(pos + 1))) {
|
|
1053
|
+
// A list of words, in which quotes are text: < a ' b >
|
|
1054
|
+
let end = pos + 2;
|
|
1055
|
+
while (input.peek(end) != 62 /* Ch.Greater */ && input.peek(end) != 10 /* Ch.Newline */ && input.peek(end) >= 0)
|
|
1056
|
+
end++;
|
|
1057
|
+
pos = input.peek(end) == 62 /* Ch.Greater */ ? end + 1 : pos + 1;
|
|
1058
|
+
}
|
|
1059
|
+
else if (!code && (ch == 60 /* Ch.Less */ || ch == 58 /* Ch.Colon */) && (codeEnd = regexCodeEnd(input, pos)) > 0) {
|
|
1060
|
+
pos = codeEnd;
|
|
1061
|
+
}
|
|
1062
|
+
else if (!code && (ch == 36 /* Ch.Dollar */ || ch == 64 /* Ch.At */) && input.peek(pos + 1) == 40 /* Ch.ParenOpen */) {
|
|
1063
|
+
// Code that is interpolated: $( rx/ a / )
|
|
1064
|
+
let end = balancedEnd(input, pos + 2, 40 /* Ch.ParenOpen */, 41 /* Ch.ParenClose */);
|
|
1065
|
+
pos = end > 0 ? end : pos + 1;
|
|
1066
|
+
}
|
|
943
1067
|
else if (ch == 60 /* Ch.Less */ && (input.peek(pos + 1) == 91 /* Ch.BracketOpen */ ||
|
|
944
1068
|
(input.peek(pos + 1) == 45 /* Ch.Hyphen */ || input.peek(pos + 1) == 43 /* Ch.Plus */) && input.peek(pos + 2) == 91 /* Ch.BracketOpen */)) {
|
|
945
1069
|
// <[...]>, <-[...]>, and combinations: <+[a..z]-[aeiou]>
|
|
@@ -980,7 +1104,7 @@ function regexEnd(input, { start: pos, open, close, count }) {
|
|
|
980
1104
|
pos++;
|
|
981
1105
|
}
|
|
982
1106
|
else if (ch == 123 /* Ch.BraceOpen */ && close != 125 /* Ch.BraceClose */) {
|
|
983
|
-
let end = regexEnd(input, { start: pos + 1, open: 123 /* Ch.BraceOpen */, close: 125 /* Ch.BraceClose */, count: 1 });
|
|
1107
|
+
let end = regexEnd(input, { start: pos + 1, open: 123 /* Ch.BraceOpen */, close: 125 /* Ch.BraceClose */, count: 1 }, true);
|
|
984
1108
|
pos = end < 0 ? pos + 1 : end + 1;
|
|
985
1109
|
}
|
|
986
1110
|
else {
|
|
@@ -988,6 +1112,21 @@ function regexEnd(input, { start: pos, open, close, count }) {
|
|
|
988
1112
|
}
|
|
989
1113
|
}
|
|
990
1114
|
}
|
|
1115
|
+
// The offset after the `/` that closes the replacement of s/a/b/, which
|
|
1116
|
+
// starts at `pos`, or -1. A `$/` in it does not close it, when a `/`
|
|
1117
|
+
// follows on the same line: in s/a/$/, the `$` is text.
|
|
1118
|
+
function replacementEnd(input, pos) {
|
|
1119
|
+
for (let match = false;;) {
|
|
1120
|
+
let ch = input.peek(pos);
|
|
1121
|
+
if (ch < 0 || match && ch == 10 /* Ch.Newline */)
|
|
1122
|
+
return -1;
|
|
1123
|
+
if (ch == 47 /* Ch.Slash */)
|
|
1124
|
+
return pos + 1;
|
|
1125
|
+
if (ch == 36 /* Ch.Dollar */ && input.peek(pos + 1) == 47 /* Ch.Slash */)
|
|
1126
|
+
match = true;
|
|
1127
|
+
pos += match && ch == 36 /* Ch.Dollar */ || ch == 92 /* Ch.Backslash */ ? 2 : 1;
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
991
1130
|
// The offset after a regex or substitution, given its opening, or -1.
|
|
992
1131
|
function regexTokenEnd(input, opening) {
|
|
993
1132
|
let end = regexEnd(input, opening);
|
|
@@ -995,8 +1134,12 @@ function regexTokenEnd(input, opening) {
|
|
|
995
1134
|
return -1;
|
|
996
1135
|
end += opening.count;
|
|
997
1136
|
// s/a/b/ has a second part. s{a} = 'b' does not.
|
|
998
|
-
if (opening.kind != "regex" && opening.open == opening.close)
|
|
999
|
-
|
|
1137
|
+
if (opening.kind != "regex" && opening.open == opening.close) {
|
|
1138
|
+
// A `$/` in the replacement is the match variable, not a `$` before
|
|
1139
|
+
// the closing delimiter: s/(a)/[$/]/. Unless nothing closes it then.
|
|
1140
|
+
let withMatch = opening.close == 47 /* Ch.Slash */ ? replacementEnd(input, end) : -1;
|
|
1141
|
+
end = withMatch < 0 ? rawEnd(input, end, opening) : withMatch;
|
|
1142
|
+
}
|
|
1000
1143
|
return end;
|
|
1001
1144
|
}
|
|
1002
1145
|
// The opening of a bare regex: /a/
|
|
@@ -1100,6 +1243,8 @@ const declarators$1 = /^(sub|method|submethod|token|rule|regex)$/;
|
|
|
1100
1243
|
function startsDeclarator(name) {
|
|
1101
1244
|
return ["sub", "method", "submethod", "token", "rule", "regex"].some(declarator => declarator.startsWith(name));
|
|
1102
1245
|
}
|
|
1246
|
+
// What stands between the parentheses of a set operator.
|
|
1247
|
+
const setOperators = /^(<=?|>=?|<\+|>\+|==|[|&\-^+.]|elem|cont)$/;
|
|
1103
1248
|
const operatorCategory = /^(infix|prefix|postfix|circumfix|postcircumfix|term)$/;
|
|
1104
1249
|
function isWordOperator(name) {
|
|
1105
1250
|
return name == "x" || name == "xx" || name == "min" || name == "max" || name == "Z" || name == "X";
|
|
@@ -1115,6 +1260,16 @@ const termToken = new lr.ExternalTokenizer((input, stack) => {
|
|
|
1115
1260
|
return;
|
|
1116
1261
|
}
|
|
1117
1262
|
let next = input.next, { mode } = context(stack);
|
|
1263
|
+
// The set operators that are written in parentheses: $a (<=) $b, $x (elem) $s
|
|
1264
|
+
// Not right after the term, where the parentheses hold arguments: $f(elem)
|
|
1265
|
+
if (next == 40 /* Ch.ParenOpen */ && mode == 1 /* Mode.AfterTerm */ && isSpace(input.peek(-1))) {
|
|
1266
|
+
let end = 1;
|
|
1267
|
+
while (end < 6 && input.peek(end) != 41 /* Ch.ParenClose */ && input.peek(end) >= 0)
|
|
1268
|
+
end++;
|
|
1269
|
+
if (input.peek(end) == 41 /* Ch.ParenClose */ && setOperators.test(word(input, 1, end)))
|
|
1270
|
+
input.acceptToken(wordOperator, end + 1);
|
|
1271
|
+
return;
|
|
1272
|
+
}
|
|
1118
1273
|
if (isIdentifierStart(next)) {
|
|
1119
1274
|
// The Z, X and R meta operators: Z+, X~, R-, Z=>
|
|
1120
1275
|
if (mode == 1 /* Mode.AfterTerm */ && (next == 90 /* Ch.Z */ || next == 88 /* Ch.X */ || next == 82 /* Ch.R */) &&
|
|
@@ -1157,7 +1312,25 @@ const termToken = new lr.ExternalTokenizer((input, stack) => {
|
|
|
1157
1312
|
// space before it, it is a variable: `my Array[Int] %h`.
|
|
1158
1313
|
if (mode == 1 /* Mode.AfterTerm */ && isIdentifierStart(input.peek(1)) && !isSpace(input.peek(-1)))
|
|
1159
1314
|
return input.acceptToken(wordOperator, 1);
|
|
1160
|
-
// An operator as a routine: &
|
|
1315
|
+
// An operator as a routine: &[+], &[»+»], &[max]
|
|
1316
|
+
// After a term, the `&` is an operator: $a &[1, 2]
|
|
1317
|
+
if (next == 38 /* Ch.Amp */ && input.peek(1) == 91 /* Ch.BracketOpen */ && mode != 1 /* Mode.AfterTerm */) {
|
|
1318
|
+
// A meta operator brings brackets of its own: &[R[~~]]
|
|
1319
|
+
for (let end = 2, depth = 1; end < 14; end++) {
|
|
1320
|
+
let ch = input.peek(end);
|
|
1321
|
+
if (ch < 0 || isSpace(ch))
|
|
1322
|
+
break;
|
|
1323
|
+
if (ch == 91 /* Ch.BracketOpen */)
|
|
1324
|
+
depth++;
|
|
1325
|
+
else if (ch == 93 /* Ch.BracketClose */ && --depth == 0) {
|
|
1326
|
+
if (end > 2)
|
|
1327
|
+
input.acceptToken(operatorVariable, end + 1);
|
|
1328
|
+
break;
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
return;
|
|
1332
|
+
}
|
|
1333
|
+
// The same by its full name: &infix:<+>
|
|
1161
1334
|
if (next == 38 /* Ch.Amp */) {
|
|
1162
1335
|
let end = nameEnd(input, 1);
|
|
1163
1336
|
if (end > 0 && operatorCategory.test(word(input, 1, end))) {
|
|
@@ -1245,7 +1418,7 @@ const quoteToken = new lr.ExternalTokenizer((input, stack) => {
|
|
|
1245
1418
|
let { quote } = context(stack);
|
|
1246
1419
|
if (!quote)
|
|
1247
1420
|
return;
|
|
1248
|
-
let { open, close, count, interpolates } = quote, nests = open != close;
|
|
1421
|
+
let { open, close, count, interpolates } = quote, nests = open != close, other = otherClose(open);
|
|
1249
1422
|
// After a variable, a subscript or a call continues the interpolation.
|
|
1250
1423
|
// `[` and `(` are left to the grammar's own tokens.
|
|
1251
1424
|
if (afterQuotedVariable(stack)) {
|
|
@@ -1263,7 +1436,7 @@ const quoteToken = new lr.ExternalTokenizer((input, stack) => {
|
|
|
1263
1436
|
let next = input.next;
|
|
1264
1437
|
if (next < 0)
|
|
1265
1438
|
break;
|
|
1266
|
-
let atClose = next == close && repeats(input, 0, close, count);
|
|
1439
|
+
let atClose = next == close && repeats(input, 0, close, count) || next == other;
|
|
1267
1440
|
if (atClose || nests && next == open && repeats(input, 0, open, count)) {
|
|
1268
1441
|
if (input.pos > start)
|
|
1269
1442
|
break;
|
|
@@ -1369,14 +1542,21 @@ function isRegexOperator(ch) {
|
|
|
1369
1542
|
// When it is not closed on its line, this is the negated offset of the
|
|
1370
1543
|
// end of the text that was gone over to find that out.
|
|
1371
1544
|
function assertionEnd(input) {
|
|
1545
|
+
// A list of words, in which quotes and brackets are text: < a ' b >
|
|
1546
|
+
let words = isBlank(input.peek(1));
|
|
1372
1547
|
for (let pos = 1, depth = 1;;) {
|
|
1373
1548
|
let ch = input.peek(pos);
|
|
1374
1549
|
if (ch < 0 || ch == 10 /* Ch.Newline */)
|
|
1375
1550
|
return -pos;
|
|
1376
|
-
if (
|
|
1551
|
+
if (words) {
|
|
1552
|
+
pos++;
|
|
1553
|
+
if (ch == 62 /* Ch.Greater */)
|
|
1554
|
+
return pos;
|
|
1555
|
+
}
|
|
1556
|
+
else if (ch == 92 /* Ch.Backslash */) {
|
|
1377
1557
|
pos += input.peek(pos + 1) == 10 /* Ch.Newline */ || input.peek(pos + 1) < 0 ? 1 : 2;
|
|
1378
1558
|
}
|
|
1379
|
-
else if (ch
|
|
1559
|
+
else if (quoteClose(ch)) {
|
|
1380
1560
|
let end = quotedEnd(input, pos);
|
|
1381
1561
|
pos = end < 0 ? pos + 1 : end;
|
|
1382
1562
|
}
|
|
@@ -1470,7 +1650,7 @@ const regexToken = new lr.ExternalTokenizer((input, stack) => {
|
|
|
1470
1650
|
skipLine(input);
|
|
1471
1651
|
return input.acceptToken(regexComment);
|
|
1472
1652
|
}
|
|
1473
|
-
if (next
|
|
1653
|
+
if (quoteClose(next)) {
|
|
1474
1654
|
let end = quotedEnd(input, 0);
|
|
1475
1655
|
if (end > 0 && end <= limit)
|
|
1476
1656
|
return input.acceptToken(regexQuote, end);
|
|
@@ -1536,7 +1716,7 @@ const regexToken = new lr.ExternalTokenizer((input, stack) => {
|
|
|
1536
1716
|
input.advance();
|
|
1537
1717
|
let ch = input.next;
|
|
1538
1718
|
if (ch < 0 || input.pos == literalEnd ||
|
|
1539
|
-
ch == 10 /* Ch.Newline */ || ch == 92 /* Ch.Backslash */ || ch
|
|
1719
|
+
ch == 10 /* Ch.Newline */ || ch == 92 /* Ch.Backslash */ || quoteClose(ch) ||
|
|
1540
1720
|
ch == 60 /* Ch.Less */ || ch == 62 /* Ch.Greater */ || ch == 171 /* Ch.GuillemetOpen */ || ch == 187 /* Ch.GuillemetClose */ ||
|
|
1541
1721
|
ch == 41 /* Ch.ParenClose */ && input.peek(1) == 62 /* Ch.Greater */ ||
|
|
1542
1722
|
ch == 123 /* Ch.BraceOpen */ || ch == 125 /* Ch.BraceClose */ || ch == 35 /* Ch.Hash */ || ch == 36 /* Ch.Dollar */ ||
|
|
@@ -1584,6 +1764,26 @@ function categoryEnd(input, nameStart, pos) {
|
|
|
1584
1764
|
let close = first == 60 /* Ch.Less */ ? 62 /* Ch.Greater */ : first == 171 /* Ch.GuillemetOpen */ ? 187 /* Ch.GuillemetClose */ : -1;
|
|
1585
1765
|
if (close < 0)
|
|
1586
1766
|
return pos;
|
|
1767
|
+
// With double angles, blanks can surround the operator, which can
|
|
1768
|
+
// hold a `>` itself: infix:<< stash-eq >>, infix:<<(>=)>>
|
|
1769
|
+
// When this is not that form, the operator starts with `<`: infix:<<=>
|
|
1770
|
+
if (first == 60 /* Ch.Less */ && input.peek(open + 1) == 60 /* Ch.Less */) {
|
|
1771
|
+
let start = blanksEnd(input, open + 2);
|
|
1772
|
+
let closes = (at) => input.peek(at) == close && input.peek(at + 1) == close && input.peek(at + 2) != close;
|
|
1773
|
+
// An operator is short, and a token must not look far past its end.
|
|
1774
|
+
for (let end = start; end < start + maxGap; end++) {
|
|
1775
|
+
let ch = input.peek(end);
|
|
1776
|
+
// Not a shift in code without spaces: infix:<<=>($a){$a>>1}
|
|
1777
|
+
if (end > start && closes(end) && !continuesName(input, end + 2) && input.peek(end + 2) != 36 /* Ch.Dollar */)
|
|
1778
|
+
return end + 2;
|
|
1779
|
+
if (ch < 0 || isSpace(ch)) {
|
|
1780
|
+
let after = blanksEnd(input, end);
|
|
1781
|
+
if (end > start && closes(after))
|
|
1782
|
+
return after + 2;
|
|
1783
|
+
break;
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1587
1787
|
// The two halves of a circumfix are separated by one space.
|
|
1588
1788
|
let spaces = /circumfix$/.test(word(input, nameStart, pos)) ? 1 : 0;
|
|
1589
1789
|
for (let i = open + 1;; i++) {
|
|
@@ -1599,8 +1799,17 @@ function categoryEnd(input, nameStart, pos) {
|
|
|
1599
1799
|
// specialized identifiers, and specialization does not look at the
|
|
1600
1800
|
// parse state, so these positions get tokens of their own.
|
|
1601
1801
|
const nameToken = new lr.ExternalTokenizer((input, stack) => {
|
|
1802
|
+
let next = input.next;
|
|
1803
|
+
// The name of a constant can have a sigil: constant $LIMIT = 3
|
|
1804
|
+
if ((next == 36 /* Ch.Dollar */ || next == 64 /* Ch.At */ || next == 37 /* Ch.Percent */ || next == 38 /* Ch.Amp */) && stack.canShift(declaredVariable)) {
|
|
1805
|
+
let end = nameEnd(input, 1);
|
|
1806
|
+
// constant &infix:<plus> = &infix:<+>
|
|
1807
|
+
if (end > 0)
|
|
1808
|
+
input.acceptToken(declaredVariable, next == 38 /* Ch.Amp */ ? categoryEnd(input, 1, end) : end);
|
|
1809
|
+
return;
|
|
1810
|
+
}
|
|
1602
1811
|
// Only a method declaration takes a mark: `method !private`, `method ^meta`.
|
|
1603
|
-
let mark =
|
|
1812
|
+
let mark = next == 33 /* Ch.Bang */ || next == 94 /* Ch.Caret */ ? 1 : 0;
|
|
1604
1813
|
let end = nameEnd(input, mark);
|
|
1605
1814
|
if (end < 0)
|
|
1606
1815
|
return;
|
|
@@ -1609,7 +1818,17 @@ const nameToken = new lr.ExternalTokenizer((input, stack) => {
|
|
|
1609
1818
|
input.acceptToken(MethodName, end);
|
|
1610
1819
|
return;
|
|
1611
1820
|
}
|
|
1821
|
+
let named = end;
|
|
1612
1822
|
end = categoryEnd(input, mark, end);
|
|
1823
|
+
// Blanks can come before the `:sym<...>` of a declaration: token c :sym<a> { a }
|
|
1824
|
+
if (end == named) {
|
|
1825
|
+
let sym = gapEnd(input, end);
|
|
1826
|
+
if (sym > end && word(input, sym, sym + 4) == ":sym") {
|
|
1827
|
+
let symEnd = categoryEnd(input, mark, sym);
|
|
1828
|
+
if (symEnd > sym)
|
|
1829
|
+
end = symEnd;
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1613
1832
|
if (!mark && stack.canShift(declaredName))
|
|
1614
1833
|
input.acceptToken(declaredName, end);
|
|
1615
1834
|
else if (stack.canShift(declaredMethodName))
|
|
@@ -1669,11 +1888,11 @@ const spec_identifier = {__proto__:null,class:80, role:82, grammar:84, module:86
|
|
|
1669
1888
|
const spec_capIdentifier = {__proto__:null,True:332, False:334, Nil:336, BEGIN:338, CHECK:340, INIT:342, END:344, ENTER:346, LEAVE:348, KEEP:350, UNDO:352, FIRST:354, NEXT:356, LAST:358, PRE:360, POST:362, CATCH:364, CONTROL:366, QUIT:368, CLOSE:370, DOC:372};
|
|
1670
1889
|
const parser$1 = lr.LRParser.deserialize({
|
|
1671
1890
|
version: 14,
|
|
1672
|
-
states: "/`QfQDdOOO*zO#tOOO+POWOOO+UO,UOOO+uOSO'#C{O,PQDdO'#DPO,WQDdO'#DSO,_QDdO'#D^OOQ.W'#Df'#DfO,fQDdO'#D`O5zQ8WO'#D|OOQ.W'#D}'#D}O6PQ7gO'#EOOOQ.W'#EQ'#EQO6sO!%SO'#EQOOQ.W'#
|
|
1673
|
-
stateData: "!@
|
|
1674
|
-
goto: ",
|
|
1891
|
+
states: "/`QfQDdOOO*zO#tOOO+POWOOO+UO,UOOO+uOSO'#C{O,PQDdO'#DPO,WQDdO'#DSO,_QDdO'#D^OOQ.W'#Df'#DfO,fQDdO'#D`O5zQ8WO'#D|OOQ.W'#D}'#D}O6PQ7gO'#EOOOQ.W'#EQ'#EQO6sO!%SO'#EQOOQ.W'#HV'#HVOOQ.W'#HU'#HUOOQ.W'#Gf'#GfQfQDdOOO6zQEUO'#DTO7RQEUO'#D`O7YQEUO'#D`O@rQEUO'#DgO@|QEUO'#DsOJqQEUO'#DvO!&fQEUO'#DyOOQ.W'#H_'#H_O!0^O!!^OOO!1[O!%SOOOOOS'#Gg'#GgO!1cOSO,59gOOQ.W,59g,59gOOQ.W,59k,59kO!1mQDdO,59kOOQ.W,59n,59nO!1tQDdO,59nOOQ.W,59x,59xO!1{QDdO,59xOOQ.W'#Gh'#GhO!;eQDdO'#HXOOQ.W'#HX'#HXOOQ.W,59z,59zOOQ.W,5:h,5:hOOQ.W,5:j,5:jO!;lO!%SO'#ERO!;sQDdO'#ESOOO&j'#H['#H[O!;zO!0jO'#H[OOO&j'#Gj'#GjO!<xO!%SO,5:lOOQ.W,5:l,5:lOOQ.W-E:d-E:dOOQ.W'#DZ'#DZOOQ.W,59o,59oO,fQDdO,59oOOQ.W'#Db'#DbO,fQDdO,59zOOQ.W'#De'#DeO!=PQDdO,5:ROOQ.W'#Dk'#DkO!=WQ:[O'#DlOOQ.W,5:R,5:RO!=PQDdO,5:ROOQ.W'#Du'#DuOOQ.W,5:_,5:_OOQ.W'#Dx'#DxOOQ.W,5:b,5:bOOQ.W'#D{'#D{OOQ.W,5:e,5:eO!=`QDdO'#DrOOO#t'#HY'#HYOOO#t'#Gi'#GiO!0^O!!^OOQOOOOOO!1[O!%SOOOOOS-E:e-E:eOOQ.W1G/R1G/ROOQ.W1G/V1G/VOOQ.W1G/Y1G/YOOQ.W1G/d1G/dOOQ.W-E:f-E:fOOQ.W,5=s,5=sOOO&j,5:m,5:mO!=gO!%SO,5:mOOO&j,5:n,5:nO!=nQDdO,5:nOOO2Q'#H^'#H^OOO2Q'#Gk'#GkO!=uO!0jO,5=vOOO&j-E:h-E:hOOQ.W1G0W1G0WOOQ.W1G/Z1G/ZOOQ.W1G/f1G/fOOQ.W1G/m1G/mO!?nO!!^O'#DmOOQ.W,5:W,5:WO!?uQ7fO,5:WO!?zQDdO1G/mOOO#t,5:^,5:^O!@RQDdO,5:^OOO#t-E:g-E:gOOO&j1G0X1G0XOOO&j1G0Y1G0YOOO2Q-E:i-E:iO!@YO!!^O,5:XOOQY,5:X,5:XOOQ.W1G/r1G/rOOQ.W7+%X7+%XOOO#t1G/x1G/xOOQY1G/s1G/s",
|
|
1892
|
+
stateData: "!@m~O%wOSlOSmOSPOSZOS[OS~OQSO]YO__Og_Oh_Oi_Oj_Ok_Op_OrTOuUOxcOycOzcO{cO|cO!PVO!R`O!TdO!VeO!WeO![fO!]fO!^fO!c_O!d_O!e_O!hgO!khO!niO!s_O!w_O!xjO!yjO!zjO!{jO!|jO!}jO#OjO#PjO#QjO#RjO#SjO#TjO#UjO#VjO#WjO#XjO#YjO#ZjO#[jO#]jO#^jO#_jO#`jO#ajO#bjO#cjO#djO#ejO#fjO#gjO#hjO#ijO#jjO#kjO#ljO#mjO#njO#ojO#pjO#qjO#rjO#sjO#tjO#ujO#vjO#wjO#xjO#yjO#zjO#{jO#|jO#}jO$OjO$PjO$QjO$RjO$SjO$TjO$UjO$VjO$WjO$XjO$YjO$ZjO$[jO$]jO$^jO$_jO$`jO$ajO$bjO$cjO$djO$ejO$fjO$gjO$hjO$ijO$jjO$kjO$ljO$mjO$njO$ojO$pjO$qjO$rjO$sjO$tjO$ujO$vjO$wjO$xjO$yjO$zjO${jO$|jO$}jO%OjO%PjO%QjO%R_O%S_O%T_O%U_O%r]O%s^O%tZO%uWO%zZO%}[O&P_O~O%kkO~O%elO~O%slO~OSmOTmOUmOVmOWmOXmOYmO%dmO~ORoO%coO~P+ZOqpO~PfOtrO~PfO!OtO~PfOQSO]YO__Og_Oh_Oi_Oj_Ok_Op_OrTOuUOxcOycOzcO{cO|cO!PVO!RxO!TdO!VeO!WeO![fO!]fO!^fO!c_O!d_O!e_O!hgO!khO!niO!s_O!w_O!xjO!yjO!zjO!{jO!|jO!}jO#OjO#PjO#QjO#RjO#SjO#TjO#UjO#VjO#WjO#XjO#YjO#ZjO#[jO#]jO#^jO#_jO#`jO#ajO#bjO#cjO#djO#ejO#fjO#gjO#hjO#ijO#jjO#kjO#ljO#mjO#njO#ojO#pjO#qjO#rjO#sjO#tjO#ujO#vjO#wjO#xjO#yjO#zjO#{jO#|jO#}jO$OjO$PjO$QjO$RjO$SjO$TjO$UjO$VjO$WjO$XjO$YjO$ZjO$[jO$]jO$^jO$_jO$`jO$ajO$bjO$cjO$djO$ejO$fjO$gjO$hjO$ijO$jjO$kjO$ljO$mjO$njO$ojO$pjO$qjO$rjO$sjO$tjO$ujO$vjO$wjO$xjO$yjO$zjO${jO$|jO$}jO%OjO%PjO%QjO%R_O%S_O%T_O%U_O%r]O%s^O%tZO%uWO%zZO%}[O&P_O~O^zO~O%a{O%b{O~O!P}O!b!OO!c!PO!d!PO!e!PO%n!OO%o|O&P!PO~O%q!SO~P6XO%f!UO~P,fO%f!XO~P,fO%g!ZO~P,fOQSO]YO__Og_Oh_Oi_Oj_Ok_Op_OrTOuUOxcOycOzcO{cO|cO!P!^O!TdO!VeO!WeO![fO!]fO!^fO!c_O!d_O!e_O!hgO!khO!niO!s_O!w_O!xjO!yjO!zjO!{jO!|jO!}jO#OjO#PjO#QjO#RjO#SjO#TjO#UjO#VjO#WjO#XjO#YjO#ZjO#[jO#]jO#^jO#_jO#`jO#ajO#bjO#cjO#djO#ejO#fjO#gjO#hjO#ijO#jjO#kjO#ljO#mjO#njO#ojO#pjO#qjO#rjO#sjO#tjO#ujO#vjO#wjO#xjO#yjO#zjO#{jO#|jO#}jO$OjO$PjO$QjO$RjO$SjO$TjO$UjO$VjO$WjO$XjO$YjO$ZjO$[jO$]jO$^jO$_jO$`jO$ajO$bjO$cjO$djO$ejO$fjO$gjO$hjO$ijO$jjO$kjO$ljO$mjO$njO$ojO$pjO$qjO$rjO$sjO$tjO$ujO$vjO$wjO$xjO$yjO$zjO${jO$|jO$}jO%OjO%PjO%QjO%R_O%S_O%T_O%U_O%r]O%s^O%tZO%uWO%zZO%}[O&P_O~O!R!_O%f!]O~P7aO%f!aOQ!gX]!gX_!gXg!gXh!gXi!gXj!gXk!gXp!gXr!gXu!gXx!gXy!gXz!gX{!gX|!gX!P!gX!R!gX!T!gX!V!gX!W!gX![!gX!]!gX!^!gX!c!gX!d!gX!e!gX!h!gX!k!gX!n!gX!s!gX!w!gX!x!gX!y!gX!z!gX!{!gX!|!gX!}!gX#O!gX#P!gX#Q!gX#R!gX#S!gX#T!gX#U!gX#V!gX#W!gX#X!gX#Y!gX#Z!gX#[!gX#]!gX#^!gX#_!gX#`!gX#a!gX#b!gX#c!gX#d!gX#e!gX#f!gX#g!gX#h!gX#i!gX#j!gX#k!gX#l!gX#m!gX#n!gX#o!gX#p!gX#q!gX#r!gX#s!gX#t!gX#u!gX#v!gX#w!gX#x!gX#y!gX#z!gX#{!gX#|!gX#}!gX$O!gX$P!gX$Q!gX$R!gX$S!gX$T!gX$U!gX$V!gX$W!gX$X!gX$Y!gX$Z!gX$[!gX$]!gX$^!gX$_!gX$`!gX$a!gX$b!gX$c!gX$d!gX$e!gX$f!gX$g!gX$h!gX$i!gX$j!gX$k!gX$l!gX$m!gX$n!gX$o!gX$p!gX$q!gX$r!gX$s!gX$t!gX$u!gX$v!gX$w!gX$x!gX$y!gX$z!gX${!gX$|!gX$}!gX%O!gX%P!gX%Q!gX%R!gX%S!gX%T!gX%U!gX%`!gX%r!gX%s!gX%t!gX%u!gX%z!gX%}!gX&P!gXq!gXt!gX!O!gX~O%f!cOQ!jX]!jX_!jXg!jXh!jXi!jXj!jXk!jXp!jXr!jXu!jXx!jXy!jXz!jX{!jX|!jX!P!jX!R!jX!T!jX!V!jX!W!jX![!jX!]!jX!^!jX!c!jX!d!jX!e!jX!h!jX!k!jX!n!jX!s!jX!w!jX!x!jX!y!jX!z!jX!{!jX!|!jX!}!jX#O!jX#P!jX#Q!jX#R!jX#S!jX#T!jX#U!jX#V!jX#W!jX#X!jX#Y!jX#Z!jX#[!jX#]!jX#^!jX#_!jX#`!jX#a!jX#b!jX#c!jX#d!jX#e!jX#f!jX#g!jX#h!jX#i!jX#j!jX#k!jX#l!jX#m!jX#n!jX#o!jX#p!jX#q!jX#r!jX#s!jX#t!jX#u!jX#v!jX#w!jX#x!jX#y!jX#z!jX#{!jX#|!jX#}!jX$O!jX$P!jX$Q!jX$R!jX$S!jX$T!jX$U!jX$V!jX$W!jX$X!jX$Y!jX$Z!jX$[!jX$]!jX$^!jX$_!jX$`!jX$a!jX$b!jX$c!jX$d!jX$e!jX$f!jX$g!jX$h!jX$i!jX$j!jX$k!jX$l!jX$m!jX$n!jX$o!jX$p!jX$q!jX$r!jX$s!jX$t!jX$u!jX$v!jX$w!jX$x!jX$y!jX$z!jX${!jX$|!jX$}!jX%O!jX%P!jX%Q!jX%R!jX%S!jX%T!jX%U!jX%`!jX%r!jX%s!jX%t!jX%u!jX%z!jX%}!jX&P!jXq!jXt!jX!O!jX~O%f!eO%h!eOQ!mX]!mX_!mXg!mXh!mXi!mXj!mXk!mXp!mXr!mXu!mXx!mXy!mXz!mX{!mX|!mX!P!mX!R!mX!T!mX!V!mX!W!mX![!mX!]!mX!^!mX!c!mX!d!mX!e!mX!h!mX!k!mX!n!mX!s!mX!w!mX!x!mX!y!mX!z!mX!{!mX!|!mX!}!mX#O!mX#P!mX#Q!mX#R!mX#S!mX#T!mX#U!mX#V!mX#W!mX#X!mX#Y!mX#Z!mX#[!mX#]!mX#^!mX#_!mX#`!mX#a!mX#b!mX#c!mX#d!mX#e!mX#f!mX#g!mX#h!mX#i!mX#j!mX#k!mX#l!mX#m!mX#n!mX#o!mX#p!mX#q!mX#r!mX#s!mX#t!mX#u!mX#v!mX#w!mX#x!mX#y!mX#z!mX#{!mX#|!mX#}!mX$O!mX$P!mX$Q!mX$R!mX$S!mX$T!mX$U!mX$V!mX$W!mX$X!mX$Y!mX$Z!mX$[!mX$]!mX$^!mX$_!mX$`!mX$a!mX$b!mX$c!mX$d!mX$e!mX$f!mX$g!mX$h!mX$i!mX$j!mX$k!mX$l!mX$m!mX$n!mX$o!mX$p!mX$q!mX$r!mX$s!mX$t!mX$u!mX$v!mX$w!mX$x!mX$y!mX$z!mX${!mX$|!mX$}!mX%O!mX%P!mX%Q!mX%R!mX%S!mX%T!mX%U!mX%`!mX%r!mX%s!mX%t!mX%u!mX%z!mX%}!mX&P!mXq!mXt!mX!O!mX~O`!hOa!hOb!hOc!hOd!hOe!hOf!hO!P!gO!b!hO!c!hO!d!hO!e!hO%l!kO%m!hO~O%q!kO~P6XOR!nO%c!nO~P+ZOq!oO~PfOt!pO~PfO!O!qO~PfOQSO]YO__Og_Oh_Oi_Oj_Ok_Op_OrTOuUOxcOycOzcO{cO|cO!PVO!TdO!VeO!WeO![fO!]fO!^fO!c_O!d_O!e_O!hgO!khO!niO!s_O!w_O!xjO!yjO!zjO!{jO!|jO!}jO#OjO#PjO#QjO#RjO#SjO#TjO#UjO#VjO#WjO#XjO#YjO#ZjO#[jO#]jO#^jO#_jO#`jO#ajO#bjO#cjO#djO#ejO#fjO#gjO#hjO#ijO#jjO#kjO#ljO#mjO#njO#ojO#pjO#qjO#rjO#sjO#tjO#ujO#vjO#wjO#xjO#yjO#zjO#{jO#|jO#}jO$OjO$PjO$QjO$RjO$SjO$TjO$UjO$VjO$WjO$XjO$YjO$ZjO$[jO$]jO$^jO$_jO$`jO$ajO$bjO$cjO$djO$ejO$fjO$gjO$hjO$ijO$jjO$kjO$ljO$mjO$njO$ojO$pjO$qjO$rjO$sjO$tjO$ujO$vjO$wjO$xjO$yjO$zjO${jO$|jO$}jO%OjO%PjO%QjO%R_O%S_O%T_O%U_O%r]O%s^O%tZO%uWO%zZO%}[O&P_O~O!R!sO~P!2SO%p!tO~P6XO!O!vO~PfO]YOrTOuUO%r!xO!P&OX!b&OX!c&OX!d&OX!e&OX%n&OX%o&OX%q&OX&P&OX%p&OX~O%q!|O~P6XO!R#PO~P7aO!O#RO%i#QO~O!O#UO~PfO%p#XO~P6XO!O#YO~PfO]YOrTOuUO%r!xO!P&Oa!b&Oa!c&Oa!d&Oa!e&Oa%n&Oa%o&Oa%q&Oa&P&Oa%p&Oa~O`!hOa!hOb!hOc!hOd!hOe!hOf!hO!P!gO!b!hO!c!hO!d!hO!e!hO%m!hO~O%j#]O~P!>sO!O#^O~O!R#_O~P7aO!O#`O~PfO%j#aO~P!>sOml!d!e!cp!w%R&P%T%U~",
|
|
1893
|
+
goto: ",s&SPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP&TPPP&nPP&n&TPPPPP']PP'`P&TP'yPP'|(P&TPPP(j(m(wPPPP(z&TP)Q&TP)T&TP)W&n&T&TP&T)Z)ZPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP)c)}*T*h*r+QPPPPPPPPPPPPPPPPPPPPPPPP+W+fP,R,aP,gP,o&T!P_OTUVXbcdefqsuw}!W!Y![!`!g!w#T#V!O_OTUVXbcdefqsuw}!W!Y![!`!g!w#T#VT!x!P!zR!Wch`OTUVbqsu}!g!w#V[xXcde!W!YR!swR!YdR!Ye!PXOTUVXbcdefqsuw}!W!Y![!`!g!w#T#VR!`fQ!_fS#P![!`R#_#TR#S!^X!hk!j#Q#[R!bgR!dhR!fi]!O^l|!R!l!uQbOQqTQsUQuV[!Tbqsu!w#VQ!w}R#V!gQnSR!mn[wXcde!W!YQ![fU!rw![#TR#T!`Q!jkS#W!j#[R#[#QQ!R^Q!llQ!u|V!{!R!l!uQ!z!PR#Z!ziaOTUVbqsu}!g!w#Vh`OTUVbqsu}!g!w#VgvXcdefw!W!Y![!`#TUyXdeQ!VcQ!}!WR#O!YX!ik!j#Q#[]!Q^l|!R!l!uT!y!P!z",
|
|
1675
1894
|
nodeNames: "⚠ BlockComment PodDirective PodDirective PodDirective PodHeading PodStrong PodEmphasis PodCode PodLink PodFormat Heredoc Heredoc . MethodName Version CharacterClass Assertion StringLiteral Operator LineComment BlockComment VariableName StringLiteral Regex Regex Operator VariableName LineComment DocComment Program Pod Number ) ( Parens ] [ Brackets PackageDeclaration class role grammar module package PackageName } { Block ; RoutineDeclaration sub RoutineName method submethod RoutineName RoutineName RegexDeclaration token rule regex RegexName Block Regex Escape VariableName AttributeName SpecialVariable Block EnumDeclaration enum EnumName SubsetDeclaration subset SubsetName ConstantDeclaration constant ConstantName MethodCall Identifier TypeName Number StringLiteral NestedDelimiters Interpolation PairKey my our has state temp let anon augment supersede unit multi proto only if elsif else unless with orwith without for while until loop repeat given when default do gather take try return next last redo proceed succeed react whenever supply emit start use need import require no is does of returns handles where will trusts hides and or not xor so andthen orelse notandthen div mod gcd lcm eq ne lt gt le ge cmp leg eqv but self True False Nil BEGIN CHECK INIT END ENTER LEAVE KEEP UNDO FIRST NEXT LAST PRE POST CATCH CONTROL QUIT CLOSE DOC Operator , : . Regex Heredoc StringLiteral",
|
|
1676
|
-
maxTerm:
|
|
1895
|
+
maxTerm: 233,
|
|
1677
1896
|
context: trackContext,
|
|
1678
1897
|
nodeProps: [
|
|
1679
1898
|
["openedBy", 33,"(",36,"[",46,"{"],
|
|
@@ -1681,11 +1900,11 @@ const parser$1 = lr.LRParser.deserialize({
|
|
|
1681
1900
|
],
|
|
1682
1901
|
skippedNodes: [0,1,11,12,28,29],
|
|
1683
1902
|
repeatNodeCount: 6,
|
|
1684
|
-
tokenData: "
|
|
1903
|
+
tokenData: "!'z~R!qX^&Ypq&Yqr&}st(wtu*huv6pvw:Oxy;uyz;zz{&}{|&}|}<P}!O&}!O!P<U!P!Q&}!Q!R<t!R![?T![!]Ax!]!^Go!^!_&}!_!`&}!`!a&}!a!b&}!b!cGt!c!}Ih!}#OLd#O#PLi#P#Q!$Z#Q#R&}#R#S!$`#T#o!$`#o#p!'[#p#q&}#q#r!'a#r#s&}#y#z&Y$f$g&Y$g$p&}$p$q!$`$q$r&}$r$s&}$t$x&}$x$y!'f$y$z!'f$z${&}${$|!$`$|%P&}%P%Q!'f%Q%R!$`%R%S&}%S%V?O%V%W&}%W%o!$`%o%p&}%p&a!$`&a&b&}&b#BY!$`#BY#BZ&Y#BZ$IS!$`$IS$I_&Y$Id$Il&}$It$I|&}$I|$JO&Y$JT$JU&Y$JU$KV&}$KV$KW&Y$Kh$Ki!'f$Kl$Kt!'f%!b%!r?O%#m%#n?O%#t&/x&}&/x&Et!$`&FU&FV&Y&Gh;'S!$`;'S;=`!'O?&r?Bj!$`?Hw?Ic!$`?Ii?JT!$`?J`?L{!$`~&_Y%w~X^&Ypq&Y#y#z&Y$f$g&Y#BY#BZ&Y$IS$I_&Y$I|$JO&Y$JT$JU&Y$KV$KW&Y&FU&FV&YP'Sk%RPqr&}z{&}{|&}}!O&}!P!Q&}!^!_&}!_!`&}!`!a&}!a!b&}#O#P&}#Q#R&}#p#q&}#r#s&}$g$p&}$q$r&}$r$s&}$t$x&}$z${&}$|%P&}%R%S&}%V%W&}%o%p&}&a&b&}$Id$Il&}$It$I|&}$JU$KV&}%#t&/x&}~(|Wl~OY)fZ!_)f!_!`)}!`#p)f#p#q)}#q;'S)f;'S;=`)w<%lO)f~)kSl~OY)fZ;'S)f;'S;=`)w<%lO)f~)zP;=`<%l)f~*USm~l~OY)}Z;'S)};'S;=`*b<%lO)}~*eP;=`<%l)}~*ml&P~qr,ez{0k!O!P/V!P!Q3g!Q![3l![!]3t!_!`0k!a!b0k!c!}4|#Q#R3t#R#S4|#T#o4|#r#s0k$h$i3g$p$q4|${$|4|%Q%R4|%W%o4|%p&a4|&b#BY4|#BZ$IS4|&/x&Et4|&Gh;'S4|;'S;=`6j?&r?Bj4|?Hw?Ic4|?Ii?JT4|?J`?L{4|~,ja!c~!c!}-o#R#S-o#T#o-o$p$q-o${$|-o%Q%R-o%W%o-o%p&a-o&b#BY-o#BZ$IS-o&/x&Et-o&Gh;'S-o;'S;=`0_?&r?Bj-o?Hw?Ic-o?Ii?JT-o?J`?L{-o~-te!d~wx/V}!O/V!Q![-o![!]0e!c!}-o#R#S-o#T#o-o$p$q-o${$|-o%Q%R-o%W%o-o%p&a-o&b#BY-o#BZ$IS-o&/x&Et-o&Gh;'S-o;'S;=`0_?&r?Bj-o?Hw?Ic-o?Ii?JT-o?J`?L{-o~/Ya!c!}-o#R#S-o#T#o-o$p$q-o${$|-o%Q%R-o%W%o-o%p&a-o&b#BY-o#BZ$IS-o&/x&Et-o&Gh;'S-o;'S;=`0_?&r?Bj-o?Hw?Ic-o?Ii?JT-o?J`?L{-o~0bP;=`<%l-o~0hP![!]/V~0na!c!}1s#R#S1s#T#o1s$p$q1s${$|1s%Q%R1s%W%o1s%p&a1s&b#BY1s#BZ$IS1s&/x&Et1s&Gh;'S1s;'S;=`3a?&r?Bj1s?Hw?Ic1s?Ii?JT1s?J`?L{1s~1xe!e~wx0k}!O0k!Q![1s![!]3Z!c!}1s#R#S1s#T#o1s$p$q1s${$|1s%Q%R1s%W%o1s%p&a1s&b#BY1s#BZ$IS1s&/x&Et1s&Gh;'S1s;'S;=`3a?&r?Bj1s?Hw?Ic1s?Ii?JT1s?J`?L{1s~3^P![!]0k~3dP;=`<%l1s~3lO!c~~3qP!c~!Q![3l~3wa!c!}4|#R#S4|#T#o4|$p$q4|${$|4|%Q%R4|%W%o4|%p&a4|&b#BY4|#BZ$IS4|&/x&Et4|&Gh;'S4|;'S;=`6j?&r?Bj4|?Hw?Ic4|?Ii?JT4|?J`?L{4|~5Re!c~wx3t}!O3t!Q![4|![!]6d!c!}4|#R#S4|#T#o4|$p$q4|${$|4|%Q%R4|%W%o4|%p&a4|&b#BY4|#BZ$IS4|&/x&Et4|&Gh;'S4|;'S;=`6j?&r?Bj4|?Hw?Ic4|?Ii?JT4|?J`?L{4|~6gP![!]3t~6mP;=`<%l4|~6uj%RPqr/Vuv8gz{0k!O!P/V![!]3t!_!`8t!a!b0k!c!}4|#Q#R3t#R#S4|#T#o4|#r#s0k$p$q4|${$|4|%Q%R4|%W%o4|%p&a4|&b#BY4|#BZ$IS4|&/x&Et4|&Gh;'S4|;'S;=`6j?&r?Bj4|?Hw?Ic4|?Ii?JT4|?J`?L{4|P8lP%RP!_!`8oP8tO%RP~8ya%RP!c!}1s#R#S1s#T#o1s$p$q1s${$|1s%Q%R1s%W%o1s%p&a1s&b#BY1s#BZ$IS1s&/x&Et1s&Gh;'S1s;'S;=`3a?&r?Bj1s?Hw?Ic1s?Ii?JT1s?J`?L{1s~:Tj%RPqr/Vvw8gz{0k!O!P/V![!]3t!_!`8t!a!b0k!c!}4|#Q#R3t#R#S4|#T#o4|#r#s0k$p$q4|${$|4|%Q%R4|%W%o4|%p&a4|&b#BY4|#BZ$IS4|&/x&Et4|&Gh;'S4|;'S;=`6j?&r?Bj4|?Hw?Ic4|?Ii?JT4|?J`?L{4|~;zOr~~<POq~~<UO%S~~<ZQ%U~!O!P<a!_!`8oP<fQ%RP!O!P<l#Q#R8oP<qP%RP#Q#R8o~<y^!s~!O!P=u!Q![?T!d!e?r!f!g@^!g!h>a!q!r@r!z!{AW#R#S?l#U#V?r#W#X@^#X#Y>a#]#^?O#c#d@r#l#mAW~=xP!Q![={~>QT!s~!Q![={!g!h>a#R#S=u#X#Y>a#]#^?O~>dR{|>m}!O>m!Q![>s~>pP!Q![>s~>xQ!s~!Q![>s#]#^?O~?TO!s~~?YU!s~!O!P=u!Q![?T!g!h>a#R#S?l#X#Y>a#]#^?O~?oP!Q![?T~?uR!Q!R@O!R!S@O#R#S@O~@TR!s~!Q!R@O!R!S@O#R#S@O~@aQ!Q![@g#R#S@g~@lQ!s~!Q![@g#R#S@g~@uQ!Q!Y@{#R#S@{~AQQ!s~!Q!Y@{#R#S@{~AZS!Q![Ag!c!iAg#R#SAg#T#ZAg~AlS!s~!Q![Ag!c!iAg#R#SAg#T#ZAg~A}e%T~qrC`!Q![F[![!]Gc!_!`8o!c!}Dh#R#SDh#T#oDh$p$qDh${$|Dh%Q%RDh%W%oDh%p&aDh&b#BYDh#BZ$ISDh&/x&EtDh&Gh;'SDh;'S;=`FU?&r?BjDh?Hw?IcDh?Ii?JTDh?J`?L{Dh~Cca!c!}Dh#R#SDh#T#oDh$p$qDh${$|Dh%Q%RDh%W%oDh%p&aDh&b#BYDh#BZ$ISDh&/x&EtDh&Gh;'SDh;'S;=`FU?&r?BjDh?Hw?IcDh?Ii?JTDh?J`?L{Dh~Dme!w~wxC`}!OC`!Q![Dh![!]FO!c!}Dh#R#SDh#T#oDh$p$qDh${$|Dh%Q%RDh%W%oDh%p&aDh&b#BYDh#BZ$ISDh&/x&EtDh&Gh;'SDh;'S;=`FU?&r?BjDh?Hw?IcDh?Ii?JTDh?J`?L{Dh~FRP![!]C`~FXP;=`<%lDh~F_Q!Q![F[!^!_Fe~FhT!O!PFw!Q![Fw!c!}Fw#R#SFw#T#oFw~FzU!O!PFw!Q![Fw!`!aG^!c!}Fw#R#SFw#T#oFw~GcOp~PGfP![!]GiPGlP!_!`8o~GtO!R~~Gyi&P~qr/Vz{0k!O!P/V![!]3t!_!`0k!a!b0k!c!}4|#Q#R3t#R#S4|#T#o4|#r#s0k$p$q4|${$|4|%Q%R4|%W%o4|%p&a4|&b#BY4|#BZ$IS4|&/x&Et4|&Gh;'S4|;'S;=`6j?&r?Bj4|?Hw?Ic4|?Ii?JT4|?J`?L{4|~Ime%}~wxKO}!OKO!Q![Ih![!]L^!c!}Ih#R#SIh#T#oIh$p$qIh${$|Ih%Q%RIh%W%oIh%p&aIh&b#BYIh#BZ$ISIh&/x&EtIh&Gh;'SIh;'S;=`LW?&r?BjIh?Hw?IcIh?Ii?JTIh?J`?L{Ih~KRa!c!}Ih#R#SIh#T#oIh$p$qIh${$|Ih%Q%RIh%W%oIh%p&aIh&b#BYIh#BZ$ISIh&/x&EtIh&Gh;'SIh;'S;=`LW?&r?BjIh?Hw?IcIh?Ii?JTIh?J`?L{Ih~LZP;=`<%lIh~LaP![!]KO~LiOu~RLn!U%RPOq!!Qqr!!Vrz!!Qz{!!V{|!!V|}!!Q}!O!!V!O!P!!Q!P!Q!!V!Q!^!!Q!^!_!!V!_!`!!V!`!a!!V!a!b!!V!b#O!!Q#O#P!!V#P#Q!!Q#Q#R!!V#R#p!!Q#p#q!!V#q#r!!Q#r#s!!V#s$g!!Q$g$p!!V$p$q!!Q$q$r!!V$r$s!!V$s$t!!Q$t$x!!V$x$z!!Q$z${!!V${$|!!Q$|%P!!V%P%R!!Q%R%S!!V%S%V!!Q%V%W!!V%W%o!!Q%o%p!!V%p&a!!Q&a&b!!V&b$Id!!Q$Id$Il!!V$Il$It!!Q$It$I|!!V$I|$JU!!Q$JU$KV!!V$KV%#t!!Q%#t&/x!!V&/x;'S!!Q;'S;=`!$R;=`O!!QQ!!VO!bQR!!^k!bQ%RPqr&}z{&}{|&}}!O&}!P!Q&}!^!_&}!_!`&}!`!a&}!a!b&}#O#P&}#Q#R&}#p#q&}#r#s&}$g$p&}$q$r&}$r$s&}$t$x&}$z${&}$|%P&}%R%S&}%V%W&}%o%p&}&a&b&}$Id$Il&}$It$I|&}$JU$KV&}%#t&/x&}Q!$WP!bQ;=`<%l!!Q~!$`Ot~~!$ee%z~wx!%v}!O!%v!Q![!$`![!]!'U!c!}!$`#R#S!$`#T#o!$`$p$q!$`${$|!$`%Q%R!$`%W%o!$`%p&a!$`&b#BY!$`#BZ$IS!$`&/x&Et!$`&Gh;'S!$`;'S;=`!'O?&r?Bj!$`?Hw?Ic!$`?Ii?JT!$`?J`?L{!$`~!%ya!c!}!$`#R#S!$`#T#o!$`$p$q!$`${$|!$`%Q%R!$`%W%o!$`%p&a!$`&b#BY!$`#BZ$IS!$`&/x&Et!$`&Gh;'S!$`;'S;=`!'O?&r?Bj!$`?Hw?Ic!$`?Ii?JT!$`?J`?L{!$`~!'RP;=`<%l!$`~!'XP![!]!%v~!'aO!P~~!'fO!O~P!'kT%RP$x$y!'f$y$z!'f%P%Q!'f$Kh$Ki!'f$Kl$Kt!'f",
|
|
1685
1904
|
tokenizers: [smileyToken, blockComment, podToken, heredocToken, methodDotToken, nameToken, versionToken, regexToken, quoteToken, termToken, 0, 1],
|
|
1686
1905
|
topRules: {"Program":[0,30],"Regex":[1,191],"Heredoc":[2,192],"StringLiteral":[3,193]},
|
|
1687
|
-
specialized: [{term:
|
|
1688
|
-
tokenPrec:
|
|
1906
|
+
specialized: [{term: 226, get: (value) => spec_identifier[value] || -1},{term: 229, get: (value) => spec_capIdentifier[value] || -1}],
|
|
1907
|
+
tokenPrec: 3559
|
|
1689
1908
|
});
|
|
1690
1909
|
|
|
1691
1910
|
// The keywords of the grammar, with the tag each is highlighted with.
|
|
@@ -1814,8 +2033,8 @@ class Gatherer {
|
|
|
1814
2033
|
this.declaration(child);
|
|
1815
2034
|
else if (child.firstChild)
|
|
1816
2035
|
this.content(child);
|
|
1817
|
-
//
|
|
1818
|
-
// declaration node: constant
|
|
2036
|
+
// A constant that is declared with a backslash has its name after
|
|
2037
|
+
// the declaration node: constant \limit = 3
|
|
1819
2038
|
declaring = name == "ConstantDeclaration" && child.lastChild.name == "constant";
|
|
1820
2039
|
}
|
|
1821
2040
|
}
|
|
@@ -2382,7 +2601,7 @@ const baseLanguage = language.LRLanguage.define({
|
|
|
2382
2601
|
Parens: language.delimitedIndent({ closing: ")" }),
|
|
2383
2602
|
Brackets: language.delimitedIndent({ closing: "]" }),
|
|
2384
2603
|
// The lines of these are text, which keeps its indentation.
|
|
2385
|
-
"StringLiteral Heredoc Pod BlockComment": () => null
|
|
2604
|
+
"StringLiteral Heredoc Pod BlockComment DocComment": () => null
|
|
2386
2605
|
}),
|
|
2387
2606
|
language.foldNodeProp.add({
|
|
2388
2607
|
"Block Parens Brackets": language.foldInside,
|