@@ -37,33 +37,11 @@ export default function read_pattern(parser) {
37
37
e . expected_pattern ( i ) ;
38
38
}
39
39
40
- /** @type {string[] } */
41
- const bracket_stack = [ ] ;
42
-
43
- while ( i < parser . template . length ) {
44
- const char = parser . template [ i ] ;
45
-
46
- if ( is_bracket_open ( char ) ) {
47
- bracket_stack . push ( char ) ;
48
- } else if ( is_bracket_close ( char ) ) {
49
- const popped = /** @type {string } */ ( bracket_stack . pop ( ) ) ;
50
- const expected = /** @type {string } */ ( get_bracket_close ( popped ) ) ;
51
-
52
- if ( char !== expected ) {
53
- e . expected_token ( i , expected ) ;
54
- }
55
-
56
- if ( bracket_stack . length === 0 ) {
57
- i += 1 ;
58
- break ;
59
- }
60
- }
61
- i += 1 ;
62
- }
63
-
40
+ i = match_bracket ( parser , start ) ;
64
41
parser . index = i ;
65
42
66
43
const pattern_string = parser . template . slice ( start , i ) ;
44
+
67
45
try {
68
46
// the length of the `space_with_newline` has to be start - 1
69
47
// because we added a `(` in front of the pattern_string,
@@ -93,6 +71,75 @@ export default function read_pattern(parser) {
93
71
}
94
72
}
95
73
74
+ /**
75
+ * @param {Parser } parser
76
+ * @param {number } start
77
+ */
78
+ function match_bracket ( parser , start ) {
79
+ const bracket_stack = [ ] ;
80
+
81
+ let i = start ;
82
+
83
+ while ( i < parser . template . length ) {
84
+ let char = parser . template [ i ++ ] ;
85
+
86
+ if ( char === "'" || char === '"' || char === '`' ) {
87
+ i = match_quote ( parser , i , char ) ;
88
+ continue ;
89
+ }
90
+
91
+ if ( is_bracket_open ( char ) ) {
92
+ bracket_stack . push ( char ) ;
93
+ } else if ( is_bracket_close ( char ) ) {
94
+ const popped = /** @type {string } */ ( bracket_stack . pop ( ) ) ;
95
+ const expected = /** @type {string } */ ( get_bracket_close ( popped ) ) ;
96
+
97
+ if ( char !== expected ) {
98
+ e . expected_token ( i - 1 , expected ) ;
99
+ }
100
+
101
+ if ( bracket_stack . length === 0 ) {
102
+ return i ;
103
+ }
104
+ }
105
+ }
106
+
107
+ e . unexpected_eof ( parser . template . length ) ;
108
+ }
109
+
110
+ /**
111
+ * @param {Parser } parser
112
+ * @param {number } start
113
+ * @param {string } quote
114
+ */
115
+ function match_quote ( parser , start , quote ) {
116
+ let is_escaped = false ;
117
+ let i = start ;
118
+
119
+ while ( i < parser . template . length ) {
120
+ const char = parser . template [ i ++ ] ;
121
+
122
+ if ( is_escaped ) {
123
+ is_escaped = false ;
124
+ continue ;
125
+ }
126
+
127
+ if ( char === quote ) {
128
+ return i ;
129
+ }
130
+
131
+ if ( char === '\\' ) {
132
+ is_escaped = true ;
133
+ }
134
+
135
+ if ( quote === '`' && char === '$' && parser . template [ i ] === '{' ) {
136
+ i = match_bracket ( parser , i ) ;
137
+ }
138
+ }
139
+
140
+ e . unterminated_string_constant ( start ) ;
141
+ }
142
+
96
143
/**
97
144
* @param {Parser } parser
98
145
* @returns {any }
0 commit comments