@@ -4,6 +4,7 @@ import * as path from "node:path"
44interface GrammarPattern {
55 readonly name ?: string
66 readonly match ?: string
7+ readonly captures ?: Record < string , GrammarPattern >
78 readonly begin ?: string
89 readonly beginCaptures ?: Record < string , GrammarPattern >
910 readonly end ?: string
@@ -15,18 +16,57 @@ interface TolkGrammar {
1516}
1617
1718describe ( "Tolk TextMate grammar" , ( ) => {
18- it ( "scopes integer literals with separators" , ( ) => {
19+ it ( "scopes integer literals with compiler-compatible separators" , ( ) => {
1920 const grammar = readTolkGrammar ( )
2021 const numericPattern = grammar . patterns . find ( pattern => pattern . name === "constant.numeric" )
2122 const numericRegex = new RegExp ( numericPattern ?. match ?? "" , "u" )
2223
2324 expect ( numericRegex . exec ( "100_000" ) ?. [ 0 ] ) . toBe ( "100_000" )
2425 expect ( numericRegex . exec ( "0xFF_FF" ) ?. [ 0 ] ) . toBe ( "0xFF_FF" )
2526 expect ( numericRegex . exec ( "0b1010_0011" ) ?. [ 0 ] ) . toBe ( "0b1010_0011" )
27+ expect ( numericRegex . exec ( "123_" ) ?. [ 0 ] ) . toBe ( "123_" )
28+ expect ( numericRegex . exec ( "0b0_____1" ) ?. [ 0 ] ) . toBe ( "0b0_____1" )
29+ expect ( numericRegex . exec ( "0b_0____1" ) ?. [ 0 ] ) . toBe ( "0b_0____1" )
30+ expect ( numericRegex . exec ( "0x" ) ?. [ 0 ] ) . toBe ( "0x" )
31+ expect ( numericRegex . exec ( "0b" ) ?. [ 0 ] ) . toBe ( "0b" )
32+ expect ( numericRegex . exec ( "0x_FF" ) ?. [ 0 ] ) . toBe ( "0x_FF" )
33+ expect ( numericRegex . exec ( "0b_" ) ?. [ 0 ] ) . toBe ( "0b_" )
2634
27- expect ( numericRegex . exec ( "100_" ) ) . toBeNull ( )
28- expect ( numericRegex . exec ( "0x_FF" ) ) . toBeNull ( )
29- expect ( numericRegex . exec ( "0b_1010" ) ) . toBeNull ( )
35+ expect ( numericRegex . exec ( "_100" ) ) . toBeNull ( )
36+ } )
37+
38+ it ( "scopes only ordinary string escapes accepted by the compiler" , ( ) => {
39+ const grammar = readTolkGrammar ( )
40+ const stringPattern = grammar . patterns . find (
41+ pattern => pattern . name === "string.quoted.double.tolk" ,
42+ )
43+ const escapePattern = stringPattern ?. patterns ?. find (
44+ pattern => pattern . name === "constant.character.escape.tolk" ,
45+ )
46+ const escapeRegex = new RegExp ( escapePattern ?. match ?? "" , "u" )
47+
48+ for ( const validEscape of [ "\\n" , "\\r" , "\\t" , "\\\\" , "\\'" , '\\"' ] ) {
49+ expect ( escapeRegex . exec ( validEscape ) ?. [ 0 ] ) . toBe ( validEscape )
50+ }
51+
52+ expect ( escapeRegex . exec ( "\\0" ) ) . toBeNull ( )
53+ expect ( escapeRegex . exec ( "\\u" ) ) . toBeNull ( )
54+ expect ( escapeRegex . exec ( "\\u1234" ) ) . toBeNull ( )
55+ } )
56+
57+ it ( "keeps triple-quoted string escapes broad for asm strings" , ( ) => {
58+ const grammar = readTolkGrammar ( )
59+ const stringPattern = grammar . patterns . find (
60+ pattern => pattern . name === "string.quoted.triple.tolk" ,
61+ )
62+ const escapePattern = stringPattern ?. patterns ?. find (
63+ pattern => pattern . name === "constant.character.escape.tolk" ,
64+ )
65+ const escapeRegex = new RegExp ( escapePattern ?. match ?? "" , "u" )
66+
67+ for ( const escape of [ "\\n" , "\\0" , "\\u" , "\\u1234" , "\\x" ] ) {
68+ expect ( escapeRegex . exec ( escape ) ?. [ 0 ] ) . toBe ( escape . slice ( 0 , 2 ) )
69+ }
3070 } )
3171
3272 it ( "scopes dotted annotation names without scoping dots" , ( ) => {
0 commit comments