codemirror-lang-raku 0.3.0 → 0.4.0
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 +46 -0
- package/README.md +16 -5
- package/dist/index.cjs +268 -49
- package/dist/index.js +268 -49
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -26,12 +26,13 @@ const smiley = 201,
|
|
|
26
26
|
MethodName = 14,
|
|
27
27
|
declaredName = 206,
|
|
28
28
|
declaredMethodName = 207,
|
|
29
|
+
declaredVariable = 208,
|
|
29
30
|
Version = 15,
|
|
30
|
-
regexStart =
|
|
31
|
-
regexBodyEnd =
|
|
32
|
-
regexLitOpen =
|
|
33
|
-
regexLitClose =
|
|
34
|
-
regexText =
|
|
31
|
+
regexStart = 209,
|
|
32
|
+
regexBodyEnd = 210,
|
|
33
|
+
regexLitOpen = 211,
|
|
34
|
+
regexLitClose = 212,
|
|
35
|
+
regexText = 213,
|
|
35
36
|
CharacterClass = 16,
|
|
36
37
|
Assertion = 17,
|
|
37
38
|
regexQuote = 18,
|
|
@@ -39,18 +40,18 @@ const smiley = 201,
|
|
|
39
40
|
regexComment = 20,
|
|
40
41
|
regexBlockComment = 21,
|
|
41
42
|
regexCapture = 22,
|
|
42
|
-
quoteContent =
|
|
43
|
-
quoteNestOpen =
|
|
44
|
-
quoteNestClose =
|
|
45
|
-
quoteEnd =
|
|
46
|
-
rawString =
|
|
47
|
-
quoteStart =
|
|
43
|
+
quoteContent = 214,
|
|
44
|
+
quoteNestOpen = 215,
|
|
45
|
+
quoteNestClose = 216,
|
|
46
|
+
quoteEnd = 217,
|
|
47
|
+
rawString = 218,
|
|
48
|
+
quoteStart = 219,
|
|
48
49
|
interpolatingWordList = 23,
|
|
49
50
|
regexLiteral = 24,
|
|
50
51
|
transliteration = 25,
|
|
51
|
-
plainName =
|
|
52
|
+
plainName = 220,
|
|
52
53
|
wordOperator = 26,
|
|
53
|
-
multiName =
|
|
54
|
+
multiName = 221,
|
|
54
55
|
operatorVariable = 27,
|
|
55
56
|
LineComment = 28,
|
|
56
57
|
DocComment = 29,
|
|
@@ -91,7 +92,7 @@ const smiley = 201,
|
|
|
91
92
|
// embedded comments. Raku accepts any Unicode bracket pair; this lists
|
|
92
93
|
// the ones that are likely to be typed.
|
|
93
94
|
const brackets$1 = {};
|
|
94
|
-
for (let pair of ["()", "[]", "{}", "<>", "«»", "「」", "『』", "()", "[]", "{}", "【】", "〈〉", "《》", "〔〕"])
|
|
95
|
+
for (let pair of ["()", "[]", "{}", "<>", "«»", "「」", "「」", "『』", "()", "[]", "{}", "【】", "〈〉", "《》", "〔〕"])
|
|
95
96
|
brackets$1[pair.charCodeAt(0)] = pair.charCodeAt(1);
|
|
96
97
|
function isAsciiLetter(ch) { return ch >= 97 /* Ch.a */ && ch <= 122 /* Ch.z */ || ch >= 65 /* Ch.A */ && ch <= 90 /* Ch.Z */; }
|
|
97
98
|
function isDigit(ch) { return ch >= 48 /* Ch._0 */ && ch <= 57 /* Ch._9 */; }
|
|
@@ -267,7 +268,7 @@ for (let term of [VariableName, AttributeName, SpecialVariable, operatorVariable
|
|
|
267
268
|
regexText, CharacterClass, Assertion, regexQuote, regexOperator, regexComment,
|
|
268
269
|
regexBlockComment, regexCapture])
|
|
269
270
|
termModes.set(term, 1 /* Mode.AfterTerm */);
|
|
270
|
-
for (let term of [Identifier, TypeName, smiley, noSmiley, declaredName, declaredMethodName, PackageName, RoutineName,
|
|
271
|
+
for (let term of [Identifier, TypeName, smiley, noSmiley, declaredName, declaredMethodName, declaredVariable, PackageName, RoutineName,
|
|
271
272
|
methodRoutineName, multiName, multiRoutineName, RegexName, EnumName, SubsetName, ConstantName])
|
|
272
273
|
termModes.set(term, 2 /* Mode.AfterName */);
|
|
273
274
|
// The `}` of "{...}" in a string does not take a subscript.
|
|
@@ -281,6 +282,10 @@ function modeAfterOperator(first, second, third, after) {
|
|
|
281
282
|
// A lone `*` is as often the whatever star as a multiplication.
|
|
282
283
|
if (first == 42 /* Ch.Star */ && !isOperatorChar(second))
|
|
283
284
|
return 2 /* Mode.AfterName */;
|
|
285
|
+
// A power in superscript, $x², leaves the term complete. These are
|
|
286
|
+
// the characters that the grammar's Operator token takes for one.
|
|
287
|
+
if (first == 0xb2 || first == 0xb3 || first == 0xb9 || first == 0x2070 || first >= 0x2074 && first <= 0x207b)
|
|
288
|
+
return 1 /* Mode.AfterTerm */;
|
|
284
289
|
// Postfix increment and decrement leave the term complete.
|
|
285
290
|
if ((first == 43 /* Ch.Plus */ || first == 45 /* Ch.Hyphen */) && second == first && !isOperatorChar(third) &&
|
|
286
291
|
(after == 1 /* Mode.AfterTerm */ || after == 3 /* Mode.AfterBlock */))
|
|
@@ -534,16 +539,24 @@ const blockComment = new ExternalTokenizer(input => {
|
|
|
534
539
|
let end = embeddedCommentEnd(input, 0);
|
|
535
540
|
if (!end)
|
|
536
541
|
return;
|
|
542
|
+
// A declarator comment with brackets, #|( ... ) and #=( ... ), is
|
|
543
|
+
// still a declarator comment.
|
|
544
|
+
let term = input.peek(1) == 96 /* Ch.Backtick */ ? BlockComment : DocComment;
|
|
537
545
|
if (end < 0)
|
|
538
546
|
skipToEnd(input);
|
|
539
547
|
else
|
|
540
548
|
input.advance(end);
|
|
541
|
-
input.acceptToken(
|
|
549
|
+
input.acceptToken(term);
|
|
542
550
|
});
|
|
543
551
|
// The offset after the embedded comment that starts at offset `at`.
|
|
544
552
|
// Zero when none starts there, and -1 when it is not closed.
|
|
553
|
+
//
|
|
554
|
+
// A declarator comment with brackets that is not closed is none: it is
|
|
555
|
+
// left to be a comment of one line, so that one that is being typed
|
|
556
|
+
// does not take the declarations after it.
|
|
545
557
|
function embeddedCommentEnd(input, at) {
|
|
546
|
-
|
|
558
|
+
let mark = input.peek(at + 1);
|
|
559
|
+
if (input.peek(at) != 35 /* Ch.Hash */ || mark != 96 /* Ch.Backtick */ && mark != 124 /* Ch.Pipe */ && mark != 61 /* Ch.Equals */)
|
|
547
560
|
return 0;
|
|
548
561
|
let open = input.peek(at + 2), close = brackets$1[open];
|
|
549
562
|
if (close == null)
|
|
@@ -551,7 +564,8 @@ function embeddedCommentEnd(input, at) {
|
|
|
551
564
|
let count = 1;
|
|
552
565
|
while (input.peek(at + 2 + count) == open)
|
|
553
566
|
count++;
|
|
554
|
-
|
|
567
|
+
let end = rawEnd(input, at + 2 + count, { open, close, count, escapes: false });
|
|
568
|
+
return end < 0 && mark != 96 /* Ch.Backtick */ ? 0 : end;
|
|
555
569
|
}
|
|
556
570
|
function isBlank(ch) { return ch == 32 /* Ch.Space */ || ch == 9 /* Ch.Tab */ || ch == 13 /* Ch.Return */; }
|
|
557
571
|
// The offset of the first character at or after `pos` that is not a blank.
|
|
@@ -784,7 +798,9 @@ function quoteCharOpening(open, close, at, interpolates, escapes = true) {
|
|
|
784
798
|
// The delimiters, other than brackets, that are accepted after a quote word.
|
|
785
799
|
function isQuoteDelimiter(ch) {
|
|
786
800
|
return ch == 47 /* Ch.Slash */ || ch == 33 /* Ch.Bang */ || ch == 124 /* Ch.Pipe */ || ch == 126 /* Ch.Tilde */ || ch == 94 /* Ch.Caret */ ||
|
|
787
|
-
ch == 37 /* Ch.Percent */ || ch == 64 /* Ch.At */ || ch == 34 /* Ch.DoubleQuote */ || ch == 39 /* Ch.Apostrophe
|
|
801
|
+
ch == 37 /* Ch.Percent */ || ch == 64 /* Ch.At */ || ch == 34 /* Ch.DoubleQuote */ || ch == 39 /* Ch.Apostrophe */ || ch == 96 /* Ch.Backtick */ ||
|
|
802
|
+
// A symbol outside of ASCII: Q♥a♥
|
|
803
|
+
ch > 0xa0 && ch != 0xd7 && ch != 0xf7 && !isIdentifierStart(ch) && !isSpace(ch) && ch < 0xd800;
|
|
788
804
|
}
|
|
789
805
|
// Reads the start of a quote at offset `at`: a quote character, or a
|
|
790
806
|
// quote word (q, qq, m, s, ...) with its adverbs and its delimiter.
|
|
@@ -799,8 +815,16 @@ function readOpening(input, at = 0) {
|
|
|
799
815
|
return quoteCharOpening(next, 0x201d, at, 63 /* Interpolate.All */);
|
|
800
816
|
if (next == 0x2018 /* ‘ */)
|
|
801
817
|
return quoteCharOpening(next, 0x2019, at, 0);
|
|
818
|
+
if (next == 0x201e /* „ */)
|
|
819
|
+
return quoteCharOpening(next, 0x201d, at, 63 /* Interpolate.All */);
|
|
820
|
+
if (next == 0x201d /* ” */)
|
|
821
|
+
return quoteCharOpening(next, next, at, 63 /* Interpolate.All */);
|
|
822
|
+
if (next == 0x201a /* ‚ */)
|
|
823
|
+
return quoteCharOpening(next, 0x2019, at, 0);
|
|
802
824
|
if (next == 0x300c /* 「 */)
|
|
803
825
|
return quoteCharOpening(next, 0x300d, at, 0, false);
|
|
826
|
+
if (next == 0xff62 /* 「 */)
|
|
827
|
+
return quoteCharOpening(next, 0xff63, at, 0, false);
|
|
804
828
|
if (!isAsciiLetter(next))
|
|
805
829
|
return null;
|
|
806
830
|
let pos = at + 1;
|
|
@@ -879,14 +903,14 @@ function readOpening(input, at = 0) {
|
|
|
879
903
|
// The offset after the delimiter that closes a quote whose content
|
|
880
904
|
// starts at `pos`, or -1 when it is not closed.
|
|
881
905
|
function rawEnd(input, pos, opening) {
|
|
882
|
-
let { open, close, count } = opening;
|
|
906
|
+
let { open, close, count } = opening, other = otherClose(open);
|
|
883
907
|
for (let depth = 1;;) {
|
|
884
908
|
let ch = input.peek(pos);
|
|
885
909
|
if (ch < 0)
|
|
886
910
|
return -1;
|
|
887
911
|
if (ch == 92 /* Ch.Backslash */ && opening.escapes)
|
|
888
912
|
pos += 2;
|
|
889
|
-
else if (ch == close && repeats(input, pos, close, count)) {
|
|
913
|
+
else if (ch == close && repeats(input, pos, close, count) || ch == other) {
|
|
890
914
|
pos += count;
|
|
891
915
|
if (--depth == 0)
|
|
892
916
|
return pos;
|
|
@@ -899,26 +923,111 @@ function rawEnd(input, pos, opening) {
|
|
|
899
923
|
pos++;
|
|
900
924
|
}
|
|
901
925
|
}
|
|
926
|
+
// The character that closes a quote in a regex that opens with `ch`,
|
|
927
|
+
// or 0 when `ch` opens none: 'a', "a", ‘a’, ‚a’, “a”, „a”, 「a」
|
|
928
|
+
function quoteClose(ch) {
|
|
929
|
+
return ch == 39 /* Ch.Apostrophe */ || ch == 34 /* Ch.DoubleQuote */ ? ch : ch == 0x2018 || ch == 0x201a ? 0x2019 :
|
|
930
|
+
ch == 0x201c || ch == 0x201e ? 0x201d : ch == 0xff62 ? 0xff63 : 0;
|
|
931
|
+
}
|
|
932
|
+
// A low quote is also closed by the quote that points the other way:
|
|
933
|
+
// ‚a‘, „a“. This is that quote for the given opening one, or -1.
|
|
934
|
+
function otherClose(open) { return open == 0x201a ? 0x2018 : open == 0x201e ? 0x201c : -1; }
|
|
902
935
|
// The offset after a quoted string that starts at `pos`, or -1.
|
|
903
936
|
function quotedEnd(input, pos) {
|
|
904
|
-
let
|
|
937
|
+
let open = input.peek(pos), close = quoteClose(open), other = otherClose(open);
|
|
905
938
|
for (pos++;;) {
|
|
906
939
|
let ch = input.peek(pos);
|
|
907
940
|
if (ch < 0 || ch == 10 /* Ch.Newline */)
|
|
908
941
|
return -1;
|
|
909
|
-
|
|
942
|
+
// Nothing is escaped in 「...」.
|
|
943
|
+
if (ch == 92 /* Ch.Backslash */ && open != 0xff62)
|
|
910
944
|
pos += 2;
|
|
911
|
-
else if (ch ==
|
|
945
|
+
else if (ch == close || ch == other)
|
|
912
946
|
return pos + 1;
|
|
913
947
|
else
|
|
914
948
|
pos++;
|
|
915
949
|
}
|
|
916
950
|
}
|
|
951
|
+
// The offset after the arguments of the assertion that starts with the
|
|
952
|
+
// `<` at `pos`, or 0 when it has none on its line. The arguments are
|
|
953
|
+
// code, in which the delimiter of the regex does not end it:
|
|
954
|
+
// <name(1/2)>, <:name(/x/)>, <name: /a<b>+/ >
|
|
955
|
+
function assertionArgumentsEnd(input, pos) {
|
|
956
|
+
// An assertion can add up several names: <+:Lu +:name(/SMALL/)>
|
|
957
|
+
for (let at = pos + 1;;) {
|
|
958
|
+
while (isAssertionMark(input.peek(at)) || isBlank(input.peek(at)))
|
|
959
|
+
at++;
|
|
960
|
+
let end = nameEnd(input, at);
|
|
961
|
+
if (end < 0)
|
|
962
|
+
return 0;
|
|
963
|
+
// With parentheses, up to the one that closes them. After a colon
|
|
964
|
+
// and a space, up to the `>` that closes the assertion.
|
|
965
|
+
let open = input.peek(end);
|
|
966
|
+
if (open == 40 /* Ch.ParenOpen */)
|
|
967
|
+
return balancedEnd(input, end + 1, 40 /* Ch.ParenOpen */, 41 /* Ch.ParenClose */);
|
|
968
|
+
if (open == 58 /* Ch.Colon */ && isBlank(input.peek(end + 1)))
|
|
969
|
+
return balancedEnd(input, end + 1, 60 /* Ch.Less */, 62 /* Ch.Greater */);
|
|
970
|
+
at = end;
|
|
971
|
+
if (!isAssertionMark(input.peek(at)) && !isBlank(input.peek(at)))
|
|
972
|
+
return 0;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
// The characters that come before the name in an assertion: <.ws>, <?before>, <+alpha>
|
|
976
|
+
function isAssertionMark(ch) {
|
|
977
|
+
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 */ ||
|
|
978
|
+
ch == 45 /* Ch.Hyphen */;
|
|
979
|
+
}
|
|
980
|
+
// The offset after the code that the `<` or `:` at `pos` in a regex
|
|
981
|
+
// starts, or 0 when it starts none.
|
|
982
|
+
function regexCodeEnd(input, pos) {
|
|
983
|
+
return input.peek(pos) == 60 /* Ch.Less */ ? assertionArgumentsEnd(input, pos) : regexDeclarationEnd(input, pos);
|
|
984
|
+
}
|
|
985
|
+
// The offset after the declaration that starts with the `:` at `pos`
|
|
986
|
+
// in a regex, or 0 when none does: `:my $c = $/;`. It is code up to
|
|
987
|
+
// its `;`, in which the delimiter of the regex does not end it.
|
|
988
|
+
function regexDeclarationEnd(input, pos) {
|
|
989
|
+
let end = nameEnd(input, pos + 1);
|
|
990
|
+
if (end < 0 || end - pos > 9 || !isBlank(input.peek(end)) ||
|
|
991
|
+
!/^(my|our|state|constant|temp|let)$/.test(word(input, pos + 1, end)))
|
|
992
|
+
return 0;
|
|
993
|
+
for (;;) {
|
|
994
|
+
let ch = input.peek(end);
|
|
995
|
+
if (ch < 0 || ch == 10 /* Ch.Newline */)
|
|
996
|
+
return 0;
|
|
997
|
+
if (ch == 59 /* Ch.Semicolon */)
|
|
998
|
+
return end + 1;
|
|
999
|
+
let quoted = quoteClose(ch) ? quotedEnd(input, end) : -1;
|
|
1000
|
+
end = quoted > 0 ? quoted : end + 1;
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
// The offset after the `close` that matches an `open` before `pos`, or
|
|
1004
|
+
// 0 when there is none on the line. Quotes are gone over.
|
|
1005
|
+
function balancedEnd(input, pos, open, close) {
|
|
1006
|
+
for (let depth = 1;;) {
|
|
1007
|
+
let ch = input.peek(pos);
|
|
1008
|
+
if (ch < 0 || ch == 10 /* Ch.Newline */)
|
|
1009
|
+
return 0;
|
|
1010
|
+
if (ch == 92 /* Ch.Backslash */)
|
|
1011
|
+
pos += 2;
|
|
1012
|
+
else if (quoteClose(ch)) {
|
|
1013
|
+
let quoted = quotedEnd(input, pos);
|
|
1014
|
+
pos = quoted < 0 ? pos + 1 : quoted;
|
|
1015
|
+
}
|
|
1016
|
+
else {
|
|
1017
|
+
pos++;
|
|
1018
|
+
if (ch == open)
|
|
1019
|
+
depth++;
|
|
1020
|
+
else if (ch == close && --depth == 0)
|
|
1021
|
+
return pos;
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
917
1025
|
// The offset of the delimiter that closes a regex whose content starts
|
|
918
1026
|
// at `pos`, or -1. Delimiters do not count inside quotes, character
|
|
919
|
-
// classes, comments and code blocks.
|
|
920
|
-
|
|
921
|
-
|
|
1027
|
+
// classes, comments and code blocks. `code` is set for the inside of a
|
|
1028
|
+
// code block, where a `<` is an operator.
|
|
1029
|
+
function regexEnd(input, { start: pos, open, close, count }, code = false) {
|
|
1030
|
+
for (let depth = 1, codeEnd;;) {
|
|
922
1031
|
let ch = input.peek(pos);
|
|
923
1032
|
if (ch < 0)
|
|
924
1033
|
return -1;
|
|
@@ -934,10 +1043,25 @@ function regexEnd(input, { start: pos, open, close, count }) {
|
|
|
934
1043
|
pos += count;
|
|
935
1044
|
depth++;
|
|
936
1045
|
}
|
|
937
|
-
else if (ch
|
|
1046
|
+
else if (quoteClose(ch)) {
|
|
938
1047
|
let end = quotedEnd(input, pos);
|
|
939
1048
|
pos = end < 0 ? pos + 1 : end;
|
|
940
1049
|
}
|
|
1050
|
+
else if (!code && ch == 60 /* Ch.Less */ && isBlank(input.peek(pos + 1))) {
|
|
1051
|
+
// A list of words, in which quotes are text: < a ' b >
|
|
1052
|
+
let end = pos + 2;
|
|
1053
|
+
while (input.peek(end) != 62 /* Ch.Greater */ && input.peek(end) != 10 /* Ch.Newline */ && input.peek(end) >= 0)
|
|
1054
|
+
end++;
|
|
1055
|
+
pos = input.peek(end) == 62 /* Ch.Greater */ ? end + 1 : pos + 1;
|
|
1056
|
+
}
|
|
1057
|
+
else if (!code && (ch == 60 /* Ch.Less */ || ch == 58 /* Ch.Colon */) && (codeEnd = regexCodeEnd(input, pos)) > 0) {
|
|
1058
|
+
pos = codeEnd;
|
|
1059
|
+
}
|
|
1060
|
+
else if (!code && (ch == 36 /* Ch.Dollar */ || ch == 64 /* Ch.At */) && input.peek(pos + 1) == 40 /* Ch.ParenOpen */) {
|
|
1061
|
+
// Code that is interpolated: $( rx/ a / )
|
|
1062
|
+
let end = balancedEnd(input, pos + 2, 40 /* Ch.ParenOpen */, 41 /* Ch.ParenClose */);
|
|
1063
|
+
pos = end > 0 ? end : pos + 1;
|
|
1064
|
+
}
|
|
941
1065
|
else if (ch == 60 /* Ch.Less */ && (input.peek(pos + 1) == 91 /* Ch.BracketOpen */ ||
|
|
942
1066
|
(input.peek(pos + 1) == 45 /* Ch.Hyphen */ || input.peek(pos + 1) == 43 /* Ch.Plus */) && input.peek(pos + 2) == 91 /* Ch.BracketOpen */)) {
|
|
943
1067
|
// <[...]>, <-[...]>, and combinations: <+[a..z]-[aeiou]>
|
|
@@ -978,7 +1102,7 @@ function regexEnd(input, { start: pos, open, close, count }) {
|
|
|
978
1102
|
pos++;
|
|
979
1103
|
}
|
|
980
1104
|
else if (ch == 123 /* Ch.BraceOpen */ && close != 125 /* Ch.BraceClose */) {
|
|
981
|
-
let end = regexEnd(input, { start: pos + 1, open: 123 /* Ch.BraceOpen */, close: 125 /* Ch.BraceClose */, count: 1 });
|
|
1105
|
+
let end = regexEnd(input, { start: pos + 1, open: 123 /* Ch.BraceOpen */, close: 125 /* Ch.BraceClose */, count: 1 }, true);
|
|
982
1106
|
pos = end < 0 ? pos + 1 : end + 1;
|
|
983
1107
|
}
|
|
984
1108
|
else {
|
|
@@ -986,6 +1110,21 @@ function regexEnd(input, { start: pos, open, close, count }) {
|
|
|
986
1110
|
}
|
|
987
1111
|
}
|
|
988
1112
|
}
|
|
1113
|
+
// The offset after the `/` that closes the replacement of s/a/b/, which
|
|
1114
|
+
// starts at `pos`, or -1. A `$/` in it does not close it, when a `/`
|
|
1115
|
+
// follows on the same line: in s/a/$/, the `$` is text.
|
|
1116
|
+
function replacementEnd(input, pos) {
|
|
1117
|
+
for (let match = false;;) {
|
|
1118
|
+
let ch = input.peek(pos);
|
|
1119
|
+
if (ch < 0 || match && ch == 10 /* Ch.Newline */)
|
|
1120
|
+
return -1;
|
|
1121
|
+
if (ch == 47 /* Ch.Slash */)
|
|
1122
|
+
return pos + 1;
|
|
1123
|
+
if (ch == 36 /* Ch.Dollar */ && input.peek(pos + 1) == 47 /* Ch.Slash */)
|
|
1124
|
+
match = true;
|
|
1125
|
+
pos += match && ch == 36 /* Ch.Dollar */ || ch == 92 /* Ch.Backslash */ ? 2 : 1;
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
989
1128
|
// The offset after a regex or substitution, given its opening, or -1.
|
|
990
1129
|
function regexTokenEnd(input, opening) {
|
|
991
1130
|
let end = regexEnd(input, opening);
|
|
@@ -993,8 +1132,12 @@ function regexTokenEnd(input, opening) {
|
|
|
993
1132
|
return -1;
|
|
994
1133
|
end += opening.count;
|
|
995
1134
|
// s/a/b/ has a second part. s{a} = 'b' does not.
|
|
996
|
-
if (opening.kind != "regex" && opening.open == opening.close)
|
|
997
|
-
|
|
1135
|
+
if (opening.kind != "regex" && opening.open == opening.close) {
|
|
1136
|
+
// A `$/` in the replacement is the match variable, not a `$` before
|
|
1137
|
+
// the closing delimiter: s/(a)/[$/]/. Unless nothing closes it then.
|
|
1138
|
+
let withMatch = opening.close == 47 /* Ch.Slash */ ? replacementEnd(input, end) : -1;
|
|
1139
|
+
end = withMatch < 0 ? rawEnd(input, end, opening) : withMatch;
|
|
1140
|
+
}
|
|
998
1141
|
return end;
|
|
999
1142
|
}
|
|
1000
1143
|
// The opening of a bare regex: /a/
|
|
@@ -1098,6 +1241,8 @@ const declarators$1 = /^(sub|method|submethod|token|rule|regex)$/;
|
|
|
1098
1241
|
function startsDeclarator(name) {
|
|
1099
1242
|
return ["sub", "method", "submethod", "token", "rule", "regex"].some(declarator => declarator.startsWith(name));
|
|
1100
1243
|
}
|
|
1244
|
+
// What stands between the parentheses of a set operator.
|
|
1245
|
+
const setOperators = /^(<=?|>=?|<\+|>\+|==|[|&\-^+.]|elem|cont)$/;
|
|
1101
1246
|
const operatorCategory = /^(infix|prefix|postfix|circumfix|postcircumfix|term)$/;
|
|
1102
1247
|
function isWordOperator(name) {
|
|
1103
1248
|
return name == "x" || name == "xx" || name == "min" || name == "max" || name == "Z" || name == "X";
|
|
@@ -1113,6 +1258,16 @@ const termToken = new ExternalTokenizer((input, stack) => {
|
|
|
1113
1258
|
return;
|
|
1114
1259
|
}
|
|
1115
1260
|
let next = input.next, { mode } = context(stack);
|
|
1261
|
+
// The set operators that are written in parentheses: $a (<=) $b, $x (elem) $s
|
|
1262
|
+
// Not right after the term, where the parentheses hold arguments: $f(elem)
|
|
1263
|
+
if (next == 40 /* Ch.ParenOpen */ && mode == 1 /* Mode.AfterTerm */ && isSpace(input.peek(-1))) {
|
|
1264
|
+
let end = 1;
|
|
1265
|
+
while (end < 6 && input.peek(end) != 41 /* Ch.ParenClose */ && input.peek(end) >= 0)
|
|
1266
|
+
end++;
|
|
1267
|
+
if (input.peek(end) == 41 /* Ch.ParenClose */ && setOperators.test(word(input, 1, end)))
|
|
1268
|
+
input.acceptToken(wordOperator, end + 1);
|
|
1269
|
+
return;
|
|
1270
|
+
}
|
|
1116
1271
|
if (isIdentifierStart(next)) {
|
|
1117
1272
|
// The Z, X and R meta operators: Z+, X~, R-, Z=>
|
|
1118
1273
|
if (mode == 1 /* Mode.AfterTerm */ && (next == 90 /* Ch.Z */ || next == 88 /* Ch.X */ || next == 82 /* Ch.R */) &&
|
|
@@ -1155,7 +1310,25 @@ const termToken = new ExternalTokenizer((input, stack) => {
|
|
|
1155
1310
|
// space before it, it is a variable: `my Array[Int] %h`.
|
|
1156
1311
|
if (mode == 1 /* Mode.AfterTerm */ && isIdentifierStart(input.peek(1)) && !isSpace(input.peek(-1)))
|
|
1157
1312
|
return input.acceptToken(wordOperator, 1);
|
|
1158
|
-
// An operator as a routine: &
|
|
1313
|
+
// An operator as a routine: &[+], &[»+»], &[max]
|
|
1314
|
+
// After a term, the `&` is an operator: $a &[1, 2]
|
|
1315
|
+
if (next == 38 /* Ch.Amp */ && input.peek(1) == 91 /* Ch.BracketOpen */ && mode != 1 /* Mode.AfterTerm */) {
|
|
1316
|
+
// A meta operator brings brackets of its own: &[R[~~]]
|
|
1317
|
+
for (let end = 2, depth = 1; end < 14; end++) {
|
|
1318
|
+
let ch = input.peek(end);
|
|
1319
|
+
if (ch < 0 || isSpace(ch))
|
|
1320
|
+
break;
|
|
1321
|
+
if (ch == 91 /* Ch.BracketOpen */)
|
|
1322
|
+
depth++;
|
|
1323
|
+
else if (ch == 93 /* Ch.BracketClose */ && --depth == 0) {
|
|
1324
|
+
if (end > 2)
|
|
1325
|
+
input.acceptToken(operatorVariable, end + 1);
|
|
1326
|
+
break;
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
return;
|
|
1330
|
+
}
|
|
1331
|
+
// The same by its full name: &infix:<+>
|
|
1159
1332
|
if (next == 38 /* Ch.Amp */) {
|
|
1160
1333
|
let end = nameEnd(input, 1);
|
|
1161
1334
|
if (end > 0 && operatorCategory.test(word(input, 1, end))) {
|
|
@@ -1243,7 +1416,7 @@ const quoteToken = new ExternalTokenizer((input, stack) => {
|
|
|
1243
1416
|
let { quote } = context(stack);
|
|
1244
1417
|
if (!quote)
|
|
1245
1418
|
return;
|
|
1246
|
-
let { open, close, count, interpolates } = quote, nests = open != close;
|
|
1419
|
+
let { open, close, count, interpolates } = quote, nests = open != close, other = otherClose(open);
|
|
1247
1420
|
// After a variable, a subscript or a call continues the interpolation.
|
|
1248
1421
|
// `[` and `(` are left to the grammar's own tokens.
|
|
1249
1422
|
if (afterQuotedVariable(stack)) {
|
|
@@ -1261,7 +1434,7 @@ const quoteToken = new ExternalTokenizer((input, stack) => {
|
|
|
1261
1434
|
let next = input.next;
|
|
1262
1435
|
if (next < 0)
|
|
1263
1436
|
break;
|
|
1264
|
-
let atClose = next == close && repeats(input, 0, close, count);
|
|
1437
|
+
let atClose = next == close && repeats(input, 0, close, count) || next == other;
|
|
1265
1438
|
if (atClose || nests && next == open && repeats(input, 0, open, count)) {
|
|
1266
1439
|
if (input.pos > start)
|
|
1267
1440
|
break;
|
|
@@ -1367,14 +1540,21 @@ function isRegexOperator(ch) {
|
|
|
1367
1540
|
// When it is not closed on its line, this is the negated offset of the
|
|
1368
1541
|
// end of the text that was gone over to find that out.
|
|
1369
1542
|
function assertionEnd(input) {
|
|
1543
|
+
// A list of words, in which quotes and brackets are text: < a ' b >
|
|
1544
|
+
let words = isBlank(input.peek(1));
|
|
1370
1545
|
for (let pos = 1, depth = 1;;) {
|
|
1371
1546
|
let ch = input.peek(pos);
|
|
1372
1547
|
if (ch < 0 || ch == 10 /* Ch.Newline */)
|
|
1373
1548
|
return -pos;
|
|
1374
|
-
if (
|
|
1549
|
+
if (words) {
|
|
1550
|
+
pos++;
|
|
1551
|
+
if (ch == 62 /* Ch.Greater */)
|
|
1552
|
+
return pos;
|
|
1553
|
+
}
|
|
1554
|
+
else if (ch == 92 /* Ch.Backslash */) {
|
|
1375
1555
|
pos += input.peek(pos + 1) == 10 /* Ch.Newline */ || input.peek(pos + 1) < 0 ? 1 : 2;
|
|
1376
1556
|
}
|
|
1377
|
-
else if (ch
|
|
1557
|
+
else if (quoteClose(ch)) {
|
|
1378
1558
|
let end = quotedEnd(input, pos);
|
|
1379
1559
|
pos = end < 0 ? pos + 1 : end;
|
|
1380
1560
|
}
|
|
@@ -1468,7 +1648,7 @@ const regexToken = new ExternalTokenizer((input, stack) => {
|
|
|
1468
1648
|
skipLine(input);
|
|
1469
1649
|
return input.acceptToken(regexComment);
|
|
1470
1650
|
}
|
|
1471
|
-
if (next
|
|
1651
|
+
if (quoteClose(next)) {
|
|
1472
1652
|
let end = quotedEnd(input, 0);
|
|
1473
1653
|
if (end > 0 && end <= limit)
|
|
1474
1654
|
return input.acceptToken(regexQuote, end);
|
|
@@ -1534,7 +1714,7 @@ const regexToken = new ExternalTokenizer((input, stack) => {
|
|
|
1534
1714
|
input.advance();
|
|
1535
1715
|
let ch = input.next;
|
|
1536
1716
|
if (ch < 0 || input.pos == literalEnd ||
|
|
1537
|
-
ch == 10 /* Ch.Newline */ || ch == 92 /* Ch.Backslash */ || ch
|
|
1717
|
+
ch == 10 /* Ch.Newline */ || ch == 92 /* Ch.Backslash */ || quoteClose(ch) ||
|
|
1538
1718
|
ch == 60 /* Ch.Less */ || ch == 62 /* Ch.Greater */ || ch == 171 /* Ch.GuillemetOpen */ || ch == 187 /* Ch.GuillemetClose */ ||
|
|
1539
1719
|
ch == 41 /* Ch.ParenClose */ && input.peek(1) == 62 /* Ch.Greater */ ||
|
|
1540
1720
|
ch == 123 /* Ch.BraceOpen */ || ch == 125 /* Ch.BraceClose */ || ch == 35 /* Ch.Hash */ || ch == 36 /* Ch.Dollar */ ||
|
|
@@ -1582,6 +1762,26 @@ function categoryEnd(input, nameStart, pos) {
|
|
|
1582
1762
|
let close = first == 60 /* Ch.Less */ ? 62 /* Ch.Greater */ : first == 171 /* Ch.GuillemetOpen */ ? 187 /* Ch.GuillemetClose */ : -1;
|
|
1583
1763
|
if (close < 0)
|
|
1584
1764
|
return pos;
|
|
1765
|
+
// With double angles, blanks can surround the operator, which can
|
|
1766
|
+
// hold a `>` itself: infix:<< stash-eq >>, infix:<<(>=)>>
|
|
1767
|
+
// When this is not that form, the operator starts with `<`: infix:<<=>
|
|
1768
|
+
if (first == 60 /* Ch.Less */ && input.peek(open + 1) == 60 /* Ch.Less */) {
|
|
1769
|
+
let start = blanksEnd(input, open + 2);
|
|
1770
|
+
let closes = (at) => input.peek(at) == close && input.peek(at + 1) == close && input.peek(at + 2) != close;
|
|
1771
|
+
// An operator is short, and a token must not look far past its end.
|
|
1772
|
+
for (let end = start; end < start + maxGap; end++) {
|
|
1773
|
+
let ch = input.peek(end);
|
|
1774
|
+
// Not a shift in code without spaces: infix:<<=>($a){$a>>1}
|
|
1775
|
+
if (end > start && closes(end) && !continuesName(input, end + 2) && input.peek(end + 2) != 36 /* Ch.Dollar */)
|
|
1776
|
+
return end + 2;
|
|
1777
|
+
if (ch < 0 || isSpace(ch)) {
|
|
1778
|
+
let after = blanksEnd(input, end);
|
|
1779
|
+
if (end > start && closes(after))
|
|
1780
|
+
return after + 2;
|
|
1781
|
+
break;
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1585
1785
|
// The two halves of a circumfix are separated by one space.
|
|
1586
1786
|
let spaces = /circumfix$/.test(word(input, nameStart, pos)) ? 1 : 0;
|
|
1587
1787
|
for (let i = open + 1;; i++) {
|
|
@@ -1597,8 +1797,17 @@ function categoryEnd(input, nameStart, pos) {
|
|
|
1597
1797
|
// specialized identifiers, and specialization does not look at the
|
|
1598
1798
|
// parse state, so these positions get tokens of their own.
|
|
1599
1799
|
const nameToken = new ExternalTokenizer((input, stack) => {
|
|
1800
|
+
let next = input.next;
|
|
1801
|
+
// The name of a constant can have a sigil: constant $LIMIT = 3
|
|
1802
|
+
if ((next == 36 /* Ch.Dollar */ || next == 64 /* Ch.At */ || next == 37 /* Ch.Percent */ || next == 38 /* Ch.Amp */) && stack.canShift(declaredVariable)) {
|
|
1803
|
+
let end = nameEnd(input, 1);
|
|
1804
|
+
// constant &infix:<plus> = &infix:<+>
|
|
1805
|
+
if (end > 0)
|
|
1806
|
+
input.acceptToken(declaredVariable, next == 38 /* Ch.Amp */ ? categoryEnd(input, 1, end) : end);
|
|
1807
|
+
return;
|
|
1808
|
+
}
|
|
1600
1809
|
// Only a method declaration takes a mark: `method !private`, `method ^meta`.
|
|
1601
|
-
let mark =
|
|
1810
|
+
let mark = next == 33 /* Ch.Bang */ || next == 94 /* Ch.Caret */ ? 1 : 0;
|
|
1602
1811
|
let end = nameEnd(input, mark);
|
|
1603
1812
|
if (end < 0)
|
|
1604
1813
|
return;
|
|
@@ -1607,7 +1816,17 @@ const nameToken = new ExternalTokenizer((input, stack) => {
|
|
|
1607
1816
|
input.acceptToken(MethodName, end);
|
|
1608
1817
|
return;
|
|
1609
1818
|
}
|
|
1819
|
+
let named = end;
|
|
1610
1820
|
end = categoryEnd(input, mark, end);
|
|
1821
|
+
// Blanks can come before the `:sym<...>` of a declaration: token c :sym<a> { a }
|
|
1822
|
+
if (end == named) {
|
|
1823
|
+
let sym = gapEnd(input, end);
|
|
1824
|
+
if (sym > end && word(input, sym, sym + 4) == ":sym") {
|
|
1825
|
+
let symEnd = categoryEnd(input, mark, sym);
|
|
1826
|
+
if (symEnd > sym)
|
|
1827
|
+
end = symEnd;
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1611
1830
|
if (!mark && stack.canShift(declaredName))
|
|
1612
1831
|
input.acceptToken(declaredName, end);
|
|
1613
1832
|
else if (stack.canShift(declaredMethodName))
|
|
@@ -1667,11 +1886,11 @@ const spec_identifier = {__proto__:null,class:80, role:82, grammar:84, module:86
|
|
|
1667
1886
|
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};
|
|
1668
1887
|
const parser$1 = LRParser.deserialize({
|
|
1669
1888
|
version: 14,
|
|
1670
|
-
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'#
|
|
1671
|
-
stateData: "!@
|
|
1672
|
-
goto: ",
|
|
1889
|
+
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",
|
|
1890
|
+
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~",
|
|
1891
|
+
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",
|
|
1673
1892
|
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",
|
|
1674
|
-
maxTerm:
|
|
1893
|
+
maxTerm: 233,
|
|
1675
1894
|
context: trackContext,
|
|
1676
1895
|
nodeProps: [
|
|
1677
1896
|
["openedBy", 33,"(",36,"[",46,"{"],
|
|
@@ -1679,11 +1898,11 @@ const parser$1 = LRParser.deserialize({
|
|
|
1679
1898
|
],
|
|
1680
1899
|
skippedNodes: [0,1,11,12,28,29],
|
|
1681
1900
|
repeatNodeCount: 6,
|
|
1682
|
-
tokenData: "
|
|
1901
|
+
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",
|
|
1683
1902
|
tokenizers: [smileyToken, blockComment, podToken, heredocToken, methodDotToken, nameToken, versionToken, regexToken, quoteToken, termToken, 0, 1],
|
|
1684
1903
|
topRules: {"Program":[0,30],"Regex":[1,191],"Heredoc":[2,192],"StringLiteral":[3,193]},
|
|
1685
|
-
specialized: [{term:
|
|
1686
|
-
tokenPrec:
|
|
1904
|
+
specialized: [{term: 226, get: (value) => spec_identifier[value] || -1},{term: 229, get: (value) => spec_capIdentifier[value] || -1}],
|
|
1905
|
+
tokenPrec: 3559
|
|
1687
1906
|
});
|
|
1688
1907
|
|
|
1689
1908
|
// The keywords of the grammar, with the tag each is highlighted with.
|
|
@@ -1812,8 +2031,8 @@ class Gatherer {
|
|
|
1812
2031
|
this.declaration(child);
|
|
1813
2032
|
else if (child.firstChild)
|
|
1814
2033
|
this.content(child);
|
|
1815
|
-
//
|
|
1816
|
-
// declaration node: constant
|
|
2034
|
+
// A constant that is declared with a backslash has its name after
|
|
2035
|
+
// the declaration node: constant \limit = 3
|
|
1817
2036
|
declaring = name == "ConstantDeclaration" && child.lastChild.name == "constant";
|
|
1818
2037
|
}
|
|
1819
2038
|
}
|
|
@@ -2380,7 +2599,7 @@ const baseLanguage = LRLanguage.define({
|
|
|
2380
2599
|
Parens: delimitedIndent({ closing: ")" }),
|
|
2381
2600
|
Brackets: delimitedIndent({ closing: "]" }),
|
|
2382
2601
|
// The lines of these are text, which keeps its indentation.
|
|
2383
|
-
"StringLiteral Heredoc Pod BlockComment": () => null
|
|
2602
|
+
"StringLiteral Heredoc Pod BlockComment DocComment": () => null
|
|
2384
2603
|
}),
|
|
2385
2604
|
foldNodeProp.add({
|
|
2386
2605
|
"Block Parens Brackets": foldInside,
|