starlight-cli 1.0.18 → 1.0.19
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/dist/index.js +73 -30
- package/package.json +1 -1
- package/src/evaluator.js +13 -2
- package/src/lexer.js +38 -26
- package/src/parser.js +21 -1
- package/src/starlight.js +1 -1
package/dist/index.js
CHANGED
|
@@ -1457,9 +1457,20 @@ class Evaluator {
|
|
|
1457
1457
|
return result;
|
|
1458
1458
|
}
|
|
1459
1459
|
|
|
1460
|
-
|
|
1461
|
-
|
|
1460
|
+
evalTemplateLiteral(node, env) {
|
|
1461
|
+
// node.parts is an array from parser: Literal or expression nodes
|
|
1462
|
+
let result = '';
|
|
1463
|
+
for (const part of node.parts) {
|
|
1464
|
+
if (part.type === 'Literal') {
|
|
1465
|
+
result += part.value;
|
|
1466
|
+
} else {
|
|
1467
|
+
const val = this.evaluate(part, env);
|
|
1468
|
+
result += val != null ? val.toString() : '';
|
|
1469
|
+
}
|
|
1462
1470
|
}
|
|
1471
|
+
return result;
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1463
1474
|
|
|
1464
1475
|
evalImport(node, env) {
|
|
1465
1476
|
const spec = node.path;
|
|
@@ -1826,38 +1837,45 @@ class Lexer {
|
|
|
1826
1837
|
}
|
|
1827
1838
|
|
|
1828
1839
|
templateString() {
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
if (this.currentChar === '\\') {
|
|
1839
|
-
this.advance();
|
|
1840
|
-
switch (this.currentChar) {
|
|
1841
|
-
case 'n': result += '\n'; break;
|
|
1842
|
-
case 't': result += '\t'; break;
|
|
1843
|
-
case '`': result += '`'; break;
|
|
1844
|
-
case '\\': result += '\\'; break;
|
|
1845
|
-
default: result += this.currentChar;
|
|
1846
|
-
}
|
|
1847
|
-
} else {
|
|
1848
|
-
result += this.currentChar;
|
|
1840
|
+
this.advance(); // skip initial backtick `
|
|
1841
|
+
let buffer = '';
|
|
1842
|
+
const tokens = [];
|
|
1843
|
+
|
|
1844
|
+
while (this.currentChar && this.currentChar !== '`') {
|
|
1845
|
+
if (this.currentChar === '$' && this.peek() === '{') {
|
|
1846
|
+
if (buffer.length > 0) {
|
|
1847
|
+
tokens.push({ type: 'TEMPLATE_STRING', value: buffer });
|
|
1848
|
+
buffer = '';
|
|
1849
1849
|
}
|
|
1850
|
-
|
|
1850
|
+
tokens.push({ type: 'DOLLAR_LBRACE' }); // ${
|
|
1851
|
+
this.advance(); this.advance();
|
|
1852
|
+
continue;
|
|
1851
1853
|
}
|
|
1852
1854
|
|
|
1853
|
-
if (this.currentChar
|
|
1854
|
-
this.
|
|
1855
|
+
if (this.currentChar === '\\') {
|
|
1856
|
+
this.advance();
|
|
1857
|
+
switch (this.currentChar) {
|
|
1858
|
+
case 'n': buffer += '\n'; break;
|
|
1859
|
+
case 't': buffer += '\t'; break;
|
|
1860
|
+
case '`': buffer += '`'; break;
|
|
1861
|
+
case '\\': buffer += '\\'; break;
|
|
1862
|
+
default: buffer += this.currentChar;
|
|
1863
|
+
}
|
|
1864
|
+
} else {
|
|
1865
|
+
buffer += this.currentChar;
|
|
1855
1866
|
}
|
|
1856
|
-
|
|
1857
1867
|
this.advance();
|
|
1858
|
-
return { type: 'TEMPLATE_STRING', value: result };
|
|
1859
1868
|
}
|
|
1860
1869
|
|
|
1870
|
+
if (buffer.length > 0) tokens.push({ type: 'TEMPLATE_STRING', value: buffer });
|
|
1871
|
+
|
|
1872
|
+
if (this.currentChar !== '`') this.error('Unterminated template string');
|
|
1873
|
+
this.advance(); // skip closing backtick
|
|
1874
|
+
|
|
1875
|
+
return tokens; // return array of tokens
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
|
|
1861
1879
|
getTokens() {
|
|
1862
1880
|
const tokens = [];
|
|
1863
1881
|
|
|
@@ -1867,7 +1885,12 @@ class Lexer {
|
|
|
1867
1885
|
if (/[0-9]/.test(this.currentChar)) { tokens.push(this.number()); continue; }
|
|
1868
1886
|
if (/[A-Za-z_]/.test(this.currentChar)) { tokens.push(this.identifier()); continue; }
|
|
1869
1887
|
if (this.currentChar === '"' || this.currentChar === "'") { tokens.push(this.string()); continue; }
|
|
1870
|
-
if (this.currentChar === '`') {
|
|
1888
|
+
if (this.currentChar === '`') {
|
|
1889
|
+
const tTokens = this.templateString();
|
|
1890
|
+
tokens.push(...tTokens); // push all tokens returned from templateString
|
|
1891
|
+
continue;
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1871
1894
|
|
|
1872
1895
|
const char = this.currentChar;
|
|
1873
1896
|
const next = this.peek();
|
|
@@ -2142,6 +2165,23 @@ class Parser {
|
|
|
2142
2165
|
if (this.current.type === 'SEMICOLON') this.eat('SEMICOLON');
|
|
2143
2166
|
return { type: 'ExpressionStatement', expression: expr };
|
|
2144
2167
|
}
|
|
2168
|
+
parseTemplateLiteral() {
|
|
2169
|
+
const parts = [];
|
|
2170
|
+
while (true) {
|
|
2171
|
+
if (this.current.type === 'TEMPLATE_STRING') {
|
|
2172
|
+
parts.push({ type: 'Literal', value: this.current.value });
|
|
2173
|
+
this.eat('TEMPLATE_STRING');
|
|
2174
|
+
} else if (this.current.type === 'DOLLAR_LBRACE') {
|
|
2175
|
+
this.eat('DOLLAR_LBRACE');
|
|
2176
|
+
const expr = this.expression();
|
|
2177
|
+
parts.push(expr);
|
|
2178
|
+
this.eat('RBRACE');
|
|
2179
|
+
} else {
|
|
2180
|
+
break;
|
|
2181
|
+
}
|
|
2182
|
+
}
|
|
2183
|
+
return { type: 'TemplateLiteral', parts };
|
|
2184
|
+
}
|
|
2145
2185
|
|
|
2146
2186
|
expression() {
|
|
2147
2187
|
return this.assignment();
|
|
@@ -2289,7 +2329,10 @@ class Parser {
|
|
|
2289
2329
|
|
|
2290
2330
|
if (t.type === 'NUMBER') { this.eat('NUMBER'); return { type: 'Literal', value: t.value }; }
|
|
2291
2331
|
if (t.type === 'STRING') { this.eat('STRING'); return { type: 'Literal', value: t.value }; }
|
|
2292
|
-
if (t.type === 'TEMPLATE_STRING'
|
|
2332
|
+
if (t.type === 'TEMPLATE_STRING' || t.type === 'DOLLAR_LBRACE') {
|
|
2333
|
+
return this.parseTemplateLiteral();
|
|
2334
|
+
}
|
|
2335
|
+
|
|
2293
2336
|
if (t.type === 'TRUE') { this.eat('TRUE'); return { type: 'Literal', value: true }; }
|
|
2294
2337
|
if (t.type === 'FALSE') { this.eat('FALSE'); return { type: 'Literal', value: false }; }
|
|
2295
2338
|
if (t.type === 'NULL') { this.eat('NULL'); return { type: 'Literal', value: null }; }
|
|
@@ -2461,7 +2504,7 @@ const Lexer = __nccwpck_require__(211);
|
|
|
2461
2504
|
const Parser = __nccwpck_require__(222);
|
|
2462
2505
|
const Evaluator = __nccwpck_require__(112);
|
|
2463
2506
|
|
|
2464
|
-
const VERSION = '1.0.
|
|
2507
|
+
const VERSION = '1.0.19';
|
|
2465
2508
|
|
|
2466
2509
|
const COLOR = {
|
|
2467
2510
|
reset: '\x1b[0m',
|
package/package.json
CHANGED
package/src/evaluator.js
CHANGED
|
@@ -114,9 +114,20 @@ class Evaluator {
|
|
|
114
114
|
return result;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
evalTemplateLiteral(node, env) {
|
|
118
|
+
// node.parts is an array from parser: Literal or expression nodes
|
|
119
|
+
let result = '';
|
|
120
|
+
for (const part of node.parts) {
|
|
121
|
+
if (part.type === 'Literal') {
|
|
122
|
+
result += part.value;
|
|
123
|
+
} else {
|
|
124
|
+
const val = this.evaluate(part, env);
|
|
125
|
+
result += val != null ? val.toString() : '';
|
|
126
|
+
}
|
|
119
127
|
}
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
|
|
120
131
|
|
|
121
132
|
evalImport(node, env) {
|
|
122
133
|
const spec = node.path;
|
package/src/lexer.js
CHANGED
|
@@ -121,38 +121,45 @@ class Lexer {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
templateString() {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if (this.currentChar === '\\') {
|
|
134
|
-
this.advance();
|
|
135
|
-
switch (this.currentChar) {
|
|
136
|
-
case 'n': result += '\n'; break;
|
|
137
|
-
case 't': result += '\t'; break;
|
|
138
|
-
case '`': result += '`'; break;
|
|
139
|
-
case '\\': result += '\\'; break;
|
|
140
|
-
default: result += this.currentChar;
|
|
141
|
-
}
|
|
142
|
-
} else {
|
|
143
|
-
result += this.currentChar;
|
|
124
|
+
this.advance(); // skip initial backtick `
|
|
125
|
+
let buffer = '';
|
|
126
|
+
const tokens = [];
|
|
127
|
+
|
|
128
|
+
while (this.currentChar && this.currentChar !== '`') {
|
|
129
|
+
if (this.currentChar === '$' && this.peek() === '{') {
|
|
130
|
+
if (buffer.length > 0) {
|
|
131
|
+
tokens.push({ type: 'TEMPLATE_STRING', value: buffer });
|
|
132
|
+
buffer = '';
|
|
144
133
|
}
|
|
145
|
-
|
|
134
|
+
tokens.push({ type: 'DOLLAR_LBRACE' }); // ${
|
|
135
|
+
this.advance(); this.advance();
|
|
136
|
+
continue;
|
|
146
137
|
}
|
|
147
138
|
|
|
148
|
-
if (this.currentChar
|
|
149
|
-
this.
|
|
139
|
+
if (this.currentChar === '\\') {
|
|
140
|
+
this.advance();
|
|
141
|
+
switch (this.currentChar) {
|
|
142
|
+
case 'n': buffer += '\n'; break;
|
|
143
|
+
case 't': buffer += '\t'; break;
|
|
144
|
+
case '`': buffer += '`'; break;
|
|
145
|
+
case '\\': buffer += '\\'; break;
|
|
146
|
+
default: buffer += this.currentChar;
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
buffer += this.currentChar;
|
|
150
150
|
}
|
|
151
|
-
|
|
152
151
|
this.advance();
|
|
153
|
-
return { type: 'TEMPLATE_STRING', value: result };
|
|
154
152
|
}
|
|
155
153
|
|
|
154
|
+
if (buffer.length > 0) tokens.push({ type: 'TEMPLATE_STRING', value: buffer });
|
|
155
|
+
|
|
156
|
+
if (this.currentChar !== '`') this.error('Unterminated template string');
|
|
157
|
+
this.advance(); // skip closing backtick
|
|
158
|
+
|
|
159
|
+
return tokens; // return array of tokens
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
|
|
156
163
|
getTokens() {
|
|
157
164
|
const tokens = [];
|
|
158
165
|
|
|
@@ -162,7 +169,12 @@ class Lexer {
|
|
|
162
169
|
if (/[0-9]/.test(this.currentChar)) { tokens.push(this.number()); continue; }
|
|
163
170
|
if (/[A-Za-z_]/.test(this.currentChar)) { tokens.push(this.identifier()); continue; }
|
|
164
171
|
if (this.currentChar === '"' || this.currentChar === "'") { tokens.push(this.string()); continue; }
|
|
165
|
-
if (this.currentChar === '`') {
|
|
172
|
+
if (this.currentChar === '`') {
|
|
173
|
+
const tTokens = this.templateString();
|
|
174
|
+
tokens.push(...tTokens); // push all tokens returned from templateString
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
|
|
166
178
|
|
|
167
179
|
const char = this.currentChar;
|
|
168
180
|
const next = this.peek();
|
package/src/parser.js
CHANGED
|
@@ -224,6 +224,23 @@ class Parser {
|
|
|
224
224
|
if (this.current.type === 'SEMICOLON') this.eat('SEMICOLON');
|
|
225
225
|
return { type: 'ExpressionStatement', expression: expr };
|
|
226
226
|
}
|
|
227
|
+
parseTemplateLiteral() {
|
|
228
|
+
const parts = [];
|
|
229
|
+
while (true) {
|
|
230
|
+
if (this.current.type === 'TEMPLATE_STRING') {
|
|
231
|
+
parts.push({ type: 'Literal', value: this.current.value });
|
|
232
|
+
this.eat('TEMPLATE_STRING');
|
|
233
|
+
} else if (this.current.type === 'DOLLAR_LBRACE') {
|
|
234
|
+
this.eat('DOLLAR_LBRACE');
|
|
235
|
+
const expr = this.expression();
|
|
236
|
+
parts.push(expr);
|
|
237
|
+
this.eat('RBRACE');
|
|
238
|
+
} else {
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return { type: 'TemplateLiteral', parts };
|
|
243
|
+
}
|
|
227
244
|
|
|
228
245
|
expression() {
|
|
229
246
|
return this.assignment();
|
|
@@ -371,7 +388,10 @@ class Parser {
|
|
|
371
388
|
|
|
372
389
|
if (t.type === 'NUMBER') { this.eat('NUMBER'); return { type: 'Literal', value: t.value }; }
|
|
373
390
|
if (t.type === 'STRING') { this.eat('STRING'); return { type: 'Literal', value: t.value }; }
|
|
374
|
-
if (t.type === 'TEMPLATE_STRING'
|
|
391
|
+
if (t.type === 'TEMPLATE_STRING' || t.type === 'DOLLAR_LBRACE') {
|
|
392
|
+
return this.parseTemplateLiteral();
|
|
393
|
+
}
|
|
394
|
+
|
|
375
395
|
if (t.type === 'TRUE') { this.eat('TRUE'); return { type: 'Literal', value: true }; }
|
|
376
396
|
if (t.type === 'FALSE') { this.eat('FALSE'); return { type: 'Literal', value: false }; }
|
|
377
397
|
if (t.type === 'NULL') { this.eat('NULL'); return { type: 'Literal', value: null }; }
|