jslike 1.6.3 → 1.7.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/dist/esm/interpreter/interpreter.js +103 -0
- package/dist/index.cjs +73 -0
- package/dist/index.d.cts +103 -0
- package/dist/index.d.ts +103 -0
- package/dist/index.js +73 -0
- package/package.json +1 -1
|
@@ -219,6 +219,56 @@ export class Interpreter {
|
|
|
219
219
|
return result;
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
+
if (node.type === 'TaggedTemplateExpression') {
|
|
223
|
+
// 1. Evaluate tag function async (may contain awaits)
|
|
224
|
+
let thisContext = undefined;
|
|
225
|
+
let tagFunction;
|
|
226
|
+
|
|
227
|
+
if (node.tag.type === 'MemberExpression') {
|
|
228
|
+
thisContext = await this.evaluateAsync(node.tag.object, env);
|
|
229
|
+
const prop = node.tag.computed
|
|
230
|
+
? await this.evaluateAsync(node.tag.property, env)
|
|
231
|
+
: node.tag.property.name;
|
|
232
|
+
tagFunction = thisContext[prop];
|
|
233
|
+
} else {
|
|
234
|
+
tagFunction = await this.evaluateAsync(node.tag, env);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// 2. Build strings array (synchronous - no awaits in quasis)
|
|
238
|
+
const strings = [];
|
|
239
|
+
const rawStrings = [];
|
|
240
|
+
for (const quasi of node.quasi.quasis) {
|
|
241
|
+
strings.push(quasi.value.cooked || quasi.value.raw);
|
|
242
|
+
rawStrings.push(quasi.value.raw);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
Object.defineProperty(strings, 'raw', {
|
|
246
|
+
value: Object.freeze(rawStrings),
|
|
247
|
+
writable: false,
|
|
248
|
+
enumerable: false,
|
|
249
|
+
configurable: false
|
|
250
|
+
});
|
|
251
|
+
Object.freeze(strings);
|
|
252
|
+
|
|
253
|
+
// 3. Evaluate expressions async (may contain awaits)
|
|
254
|
+
const values = [];
|
|
255
|
+
for (const expr of node.quasi.expressions) {
|
|
256
|
+
values.push(await this.evaluateAsync(expr, env));
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// 4. Call tag function (may be async)
|
|
260
|
+
if (typeof tagFunction === 'function') {
|
|
261
|
+
if (thisContext !== undefined) {
|
|
262
|
+
return await tagFunction.call(thisContext, strings, ...values);
|
|
263
|
+
}
|
|
264
|
+
return await tagFunction(strings, ...values);
|
|
265
|
+
} else if (tagFunction && tagFunction.__isFunction) {
|
|
266
|
+
return await this.callUserFunction(tagFunction, [strings, ...values], env, thisContext);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
throw new TypeError('Tag must be a function');
|
|
270
|
+
}
|
|
271
|
+
|
|
222
272
|
// For logical expressions with async operands (await support)
|
|
223
273
|
if (node.type === 'LogicalExpression') {
|
|
224
274
|
const left = await this.evaluateAsync(node.left, env);
|
|
@@ -822,6 +872,9 @@ export class Interpreter {
|
|
|
822
872
|
case 'TemplateLiteral':
|
|
823
873
|
return this.evaluateTemplateLiteral(node, env);
|
|
824
874
|
|
|
875
|
+
case 'TaggedTemplateExpression':
|
|
876
|
+
return this.evaluateTaggedTemplateExpression(node, env);
|
|
877
|
+
|
|
825
878
|
case 'ClassDeclaration':
|
|
826
879
|
return this.evaluateClassDeclaration(node, env);
|
|
827
880
|
|
|
@@ -2066,6 +2119,56 @@ export class Interpreter {
|
|
|
2066
2119
|
return result;
|
|
2067
2120
|
}
|
|
2068
2121
|
|
|
2122
|
+
evaluateTaggedTemplateExpression(node, env) {
|
|
2123
|
+
// 1. Evaluate the tag function, preserving 'this' context for member expressions
|
|
2124
|
+
let thisContext = undefined;
|
|
2125
|
+
let tagFunction;
|
|
2126
|
+
|
|
2127
|
+
if (node.tag.type === 'MemberExpression') {
|
|
2128
|
+
// For method calls like obj.tag`...`, set this to obj
|
|
2129
|
+
thisContext = this.evaluate(node.tag.object, env);
|
|
2130
|
+
const prop = node.tag.computed
|
|
2131
|
+
? this.evaluate(node.tag.property, env)
|
|
2132
|
+
: node.tag.property.name;
|
|
2133
|
+
tagFunction = thisContext[prop];
|
|
2134
|
+
} else {
|
|
2135
|
+
tagFunction = this.evaluate(node.tag, env);
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2138
|
+
// 2. Build the strings array from quasis (cooked values)
|
|
2139
|
+
const strings = [];
|
|
2140
|
+
const rawStrings = [];
|
|
2141
|
+
for (const quasi of node.quasi.quasis) {
|
|
2142
|
+
strings.push(quasi.value.cooked || quasi.value.raw);
|
|
2143
|
+
rawStrings.push(quasi.value.raw);
|
|
2144
|
+
}
|
|
2145
|
+
|
|
2146
|
+
// 3. Add the raw property (frozen per ES6 spec)
|
|
2147
|
+
Object.defineProperty(strings, 'raw', {
|
|
2148
|
+
value: Object.freeze(rawStrings),
|
|
2149
|
+
writable: false,
|
|
2150
|
+
enumerable: false,
|
|
2151
|
+
configurable: false
|
|
2152
|
+
});
|
|
2153
|
+
Object.freeze(strings);
|
|
2154
|
+
|
|
2155
|
+
// 4. Evaluate the embedded expressions
|
|
2156
|
+
const values = node.quasi.expressions.map(expr => this.evaluate(expr, env));
|
|
2157
|
+
|
|
2158
|
+
// 5. Call the tag function with proper this context
|
|
2159
|
+
if (typeof tagFunction === 'function') {
|
|
2160
|
+
if (thisContext !== undefined) {
|
|
2161
|
+
return tagFunction.call(thisContext, strings, ...values);
|
|
2162
|
+
}
|
|
2163
|
+
return tagFunction(strings, ...values);
|
|
2164
|
+
} else if (tagFunction && tagFunction.__isFunction) {
|
|
2165
|
+
// User-defined function
|
|
2166
|
+
return this.callUserFunction(tagFunction, [strings, ...values], env, thisContext);
|
|
2167
|
+
}
|
|
2168
|
+
|
|
2169
|
+
throw new TypeError('Tag must be a function');
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2069
2172
|
evaluateClassDeclaration(node, env) {
|
|
2070
2173
|
const className = node.id.name;
|
|
2071
2174
|
const classFunc = this.createClass(node, env);
|
package/dist/index.cjs
CHANGED
|
@@ -6632,6 +6632,43 @@ var Interpreter = class _Interpreter {
|
|
|
6632
6632
|
}
|
|
6633
6633
|
return result;
|
|
6634
6634
|
}
|
|
6635
|
+
if (node.type === "TaggedTemplateExpression") {
|
|
6636
|
+
let thisContext = void 0;
|
|
6637
|
+
let tagFunction;
|
|
6638
|
+
if (node.tag.type === "MemberExpression") {
|
|
6639
|
+
thisContext = await this.evaluateAsync(node.tag.object, env);
|
|
6640
|
+
const prop = node.tag.computed ? await this.evaluateAsync(node.tag.property, env) : node.tag.property.name;
|
|
6641
|
+
tagFunction = thisContext[prop];
|
|
6642
|
+
} else {
|
|
6643
|
+
tagFunction = await this.evaluateAsync(node.tag, env);
|
|
6644
|
+
}
|
|
6645
|
+
const strings = [];
|
|
6646
|
+
const rawStrings = [];
|
|
6647
|
+
for (const quasi of node.quasi.quasis) {
|
|
6648
|
+
strings.push(quasi.value.cooked || quasi.value.raw);
|
|
6649
|
+
rawStrings.push(quasi.value.raw);
|
|
6650
|
+
}
|
|
6651
|
+
Object.defineProperty(strings, "raw", {
|
|
6652
|
+
value: Object.freeze(rawStrings),
|
|
6653
|
+
writable: false,
|
|
6654
|
+
enumerable: false,
|
|
6655
|
+
configurable: false
|
|
6656
|
+
});
|
|
6657
|
+
Object.freeze(strings);
|
|
6658
|
+
const values = [];
|
|
6659
|
+
for (const expr of node.quasi.expressions) {
|
|
6660
|
+
values.push(await this.evaluateAsync(expr, env));
|
|
6661
|
+
}
|
|
6662
|
+
if (typeof tagFunction === "function") {
|
|
6663
|
+
if (thisContext !== void 0) {
|
|
6664
|
+
return await tagFunction.call(thisContext, strings, ...values);
|
|
6665
|
+
}
|
|
6666
|
+
return await tagFunction(strings, ...values);
|
|
6667
|
+
} else if (tagFunction && tagFunction.__isFunction) {
|
|
6668
|
+
return await this.callUserFunction(tagFunction, [strings, ...values], env, thisContext);
|
|
6669
|
+
}
|
|
6670
|
+
throw new TypeError("Tag must be a function");
|
|
6671
|
+
}
|
|
6635
6672
|
if (node.type === "LogicalExpression") {
|
|
6636
6673
|
const left = await this.evaluateAsync(node.left, env);
|
|
6637
6674
|
if (node.operator === "&&") {
|
|
@@ -7115,6 +7152,8 @@ var Interpreter = class _Interpreter {
|
|
|
7115
7152
|
// ES6+ Features
|
|
7116
7153
|
case "TemplateLiteral":
|
|
7117
7154
|
return this.evaluateTemplateLiteral(node, env);
|
|
7155
|
+
case "TaggedTemplateExpression":
|
|
7156
|
+
return this.evaluateTaggedTemplateExpression(node, env);
|
|
7118
7157
|
case "ClassDeclaration":
|
|
7119
7158
|
return this.evaluateClassDeclaration(node, env);
|
|
7120
7159
|
case "ClassExpression":
|
|
@@ -8058,6 +8097,40 @@ var Interpreter = class _Interpreter {
|
|
|
8058
8097
|
}
|
|
8059
8098
|
return result;
|
|
8060
8099
|
}
|
|
8100
|
+
evaluateTaggedTemplateExpression(node, env) {
|
|
8101
|
+
let thisContext = void 0;
|
|
8102
|
+
let tagFunction;
|
|
8103
|
+
if (node.tag.type === "MemberExpression") {
|
|
8104
|
+
thisContext = this.evaluate(node.tag.object, env);
|
|
8105
|
+
const prop = node.tag.computed ? this.evaluate(node.tag.property, env) : node.tag.property.name;
|
|
8106
|
+
tagFunction = thisContext[prop];
|
|
8107
|
+
} else {
|
|
8108
|
+
tagFunction = this.evaluate(node.tag, env);
|
|
8109
|
+
}
|
|
8110
|
+
const strings = [];
|
|
8111
|
+
const rawStrings = [];
|
|
8112
|
+
for (const quasi of node.quasi.quasis) {
|
|
8113
|
+
strings.push(quasi.value.cooked || quasi.value.raw);
|
|
8114
|
+
rawStrings.push(quasi.value.raw);
|
|
8115
|
+
}
|
|
8116
|
+
Object.defineProperty(strings, "raw", {
|
|
8117
|
+
value: Object.freeze(rawStrings),
|
|
8118
|
+
writable: false,
|
|
8119
|
+
enumerable: false,
|
|
8120
|
+
configurable: false
|
|
8121
|
+
});
|
|
8122
|
+
Object.freeze(strings);
|
|
8123
|
+
const values = node.quasi.expressions.map((expr) => this.evaluate(expr, env));
|
|
8124
|
+
if (typeof tagFunction === "function") {
|
|
8125
|
+
if (thisContext !== void 0) {
|
|
8126
|
+
return tagFunction.call(thisContext, strings, ...values);
|
|
8127
|
+
}
|
|
8128
|
+
return tagFunction(strings, ...values);
|
|
8129
|
+
} else if (tagFunction && tagFunction.__isFunction) {
|
|
8130
|
+
return this.callUserFunction(tagFunction, [strings, ...values], env, thisContext);
|
|
8131
|
+
}
|
|
8132
|
+
throw new TypeError("Tag must be a function");
|
|
8133
|
+
}
|
|
8061
8134
|
evaluateClassDeclaration(node, env) {
|
|
8062
8135
|
const className = node.id.name;
|
|
8063
8136
|
const classFunc = this.createClass(node, env);
|
package/dist/index.d.cts
CHANGED
|
@@ -7384,6 +7384,56 @@ class Interpreter {
|
|
|
7384
7384
|
return result;
|
|
7385
7385
|
}
|
|
7386
7386
|
|
|
7387
|
+
if (node.type === 'TaggedTemplateExpression') {
|
|
7388
|
+
// 1. Evaluate tag function async (may contain awaits)
|
|
7389
|
+
let thisContext = undefined;
|
|
7390
|
+
let tagFunction;
|
|
7391
|
+
|
|
7392
|
+
if (node.tag.type === 'MemberExpression') {
|
|
7393
|
+
thisContext = await this.evaluateAsync(node.tag.object, env);
|
|
7394
|
+
const prop = node.tag.computed
|
|
7395
|
+
? await this.evaluateAsync(node.tag.property, env)
|
|
7396
|
+
: node.tag.property.name;
|
|
7397
|
+
tagFunction = thisContext[prop];
|
|
7398
|
+
} else {
|
|
7399
|
+
tagFunction = await this.evaluateAsync(node.tag, env);
|
|
7400
|
+
}
|
|
7401
|
+
|
|
7402
|
+
// 2. Build strings array (synchronous - no awaits in quasis)
|
|
7403
|
+
const strings = [];
|
|
7404
|
+
const rawStrings = [];
|
|
7405
|
+
for (const quasi of node.quasi.quasis) {
|
|
7406
|
+
strings.push(quasi.value.cooked || quasi.value.raw);
|
|
7407
|
+
rawStrings.push(quasi.value.raw);
|
|
7408
|
+
}
|
|
7409
|
+
|
|
7410
|
+
Object.defineProperty(strings, 'raw', {
|
|
7411
|
+
value: Object.freeze(rawStrings),
|
|
7412
|
+
writable: false,
|
|
7413
|
+
enumerable: false,
|
|
7414
|
+
configurable: false
|
|
7415
|
+
});
|
|
7416
|
+
Object.freeze(strings);
|
|
7417
|
+
|
|
7418
|
+
// 3. Evaluate expressions async (may contain awaits)
|
|
7419
|
+
const values = [];
|
|
7420
|
+
for (const expr of node.quasi.expressions) {
|
|
7421
|
+
values.push(await this.evaluateAsync(expr, env));
|
|
7422
|
+
}
|
|
7423
|
+
|
|
7424
|
+
// 4. Call tag function (may be async)
|
|
7425
|
+
if (typeof tagFunction === 'function') {
|
|
7426
|
+
if (thisContext !== undefined) {
|
|
7427
|
+
return await tagFunction.call(thisContext, strings, ...values);
|
|
7428
|
+
}
|
|
7429
|
+
return await tagFunction(strings, ...values);
|
|
7430
|
+
} else if (tagFunction && tagFunction.__isFunction) {
|
|
7431
|
+
return await this.callUserFunction(tagFunction, [strings, ...values], env, thisContext);
|
|
7432
|
+
}
|
|
7433
|
+
|
|
7434
|
+
throw new TypeError('Tag must be a function');
|
|
7435
|
+
}
|
|
7436
|
+
|
|
7387
7437
|
// For logical expressions with async operands (await support)
|
|
7388
7438
|
if (node.type === 'LogicalExpression') {
|
|
7389
7439
|
const left = await this.evaluateAsync(node.left, env);
|
|
@@ -7987,6 +8037,9 @@ class Interpreter {
|
|
|
7987
8037
|
case 'TemplateLiteral':
|
|
7988
8038
|
return this.evaluateTemplateLiteral(node, env);
|
|
7989
8039
|
|
|
8040
|
+
case 'TaggedTemplateExpression':
|
|
8041
|
+
return this.evaluateTaggedTemplateExpression(node, env);
|
|
8042
|
+
|
|
7990
8043
|
case 'ClassDeclaration':
|
|
7991
8044
|
return this.evaluateClassDeclaration(node, env);
|
|
7992
8045
|
|
|
@@ -9231,6 +9284,56 @@ class Interpreter {
|
|
|
9231
9284
|
return result;
|
|
9232
9285
|
}
|
|
9233
9286
|
|
|
9287
|
+
evaluateTaggedTemplateExpression(node, env) {
|
|
9288
|
+
// 1. Evaluate the tag function, preserving 'this' context for member expressions
|
|
9289
|
+
let thisContext = undefined;
|
|
9290
|
+
let tagFunction;
|
|
9291
|
+
|
|
9292
|
+
if (node.tag.type === 'MemberExpression') {
|
|
9293
|
+
// For method calls like obj.tag`...`, set this to obj
|
|
9294
|
+
thisContext = this.evaluate(node.tag.object, env);
|
|
9295
|
+
const prop = node.tag.computed
|
|
9296
|
+
? this.evaluate(node.tag.property, env)
|
|
9297
|
+
: node.tag.property.name;
|
|
9298
|
+
tagFunction = thisContext[prop];
|
|
9299
|
+
} else {
|
|
9300
|
+
tagFunction = this.evaluate(node.tag, env);
|
|
9301
|
+
}
|
|
9302
|
+
|
|
9303
|
+
// 2. Build the strings array from quasis (cooked values)
|
|
9304
|
+
const strings = [];
|
|
9305
|
+
const rawStrings = [];
|
|
9306
|
+
for (const quasi of node.quasi.quasis) {
|
|
9307
|
+
strings.push(quasi.value.cooked || quasi.value.raw);
|
|
9308
|
+
rawStrings.push(quasi.value.raw);
|
|
9309
|
+
}
|
|
9310
|
+
|
|
9311
|
+
// 3. Add the raw property (frozen per ES6 spec)
|
|
9312
|
+
Object.defineProperty(strings, 'raw', {
|
|
9313
|
+
value: Object.freeze(rawStrings),
|
|
9314
|
+
writable: false,
|
|
9315
|
+
enumerable: false,
|
|
9316
|
+
configurable: false
|
|
9317
|
+
});
|
|
9318
|
+
Object.freeze(strings);
|
|
9319
|
+
|
|
9320
|
+
// 4. Evaluate the embedded expressions
|
|
9321
|
+
const values = node.quasi.expressions.map(expr => this.evaluate(expr, env));
|
|
9322
|
+
|
|
9323
|
+
// 5. Call the tag function with proper this context
|
|
9324
|
+
if (typeof tagFunction === 'function') {
|
|
9325
|
+
if (thisContext !== undefined) {
|
|
9326
|
+
return tagFunction.call(thisContext, strings, ...values);
|
|
9327
|
+
}
|
|
9328
|
+
return tagFunction(strings, ...values);
|
|
9329
|
+
} else if (tagFunction && tagFunction.__isFunction) {
|
|
9330
|
+
// User-defined function
|
|
9331
|
+
return this.callUserFunction(tagFunction, [strings, ...values], env, thisContext);
|
|
9332
|
+
}
|
|
9333
|
+
|
|
9334
|
+
throw new TypeError('Tag must be a function');
|
|
9335
|
+
}
|
|
9336
|
+
|
|
9234
9337
|
evaluateClassDeclaration(node, env) {
|
|
9235
9338
|
const className = node.id.name;
|
|
9236
9339
|
const classFunc = this.createClass(node, env);
|
package/dist/index.d.ts
CHANGED
|
@@ -7384,6 +7384,56 @@ class Interpreter {
|
|
|
7384
7384
|
return result;
|
|
7385
7385
|
}
|
|
7386
7386
|
|
|
7387
|
+
if (node.type === 'TaggedTemplateExpression') {
|
|
7388
|
+
// 1. Evaluate tag function async (may contain awaits)
|
|
7389
|
+
let thisContext = undefined;
|
|
7390
|
+
let tagFunction;
|
|
7391
|
+
|
|
7392
|
+
if (node.tag.type === 'MemberExpression') {
|
|
7393
|
+
thisContext = await this.evaluateAsync(node.tag.object, env);
|
|
7394
|
+
const prop = node.tag.computed
|
|
7395
|
+
? await this.evaluateAsync(node.tag.property, env)
|
|
7396
|
+
: node.tag.property.name;
|
|
7397
|
+
tagFunction = thisContext[prop];
|
|
7398
|
+
} else {
|
|
7399
|
+
tagFunction = await this.evaluateAsync(node.tag, env);
|
|
7400
|
+
}
|
|
7401
|
+
|
|
7402
|
+
// 2. Build strings array (synchronous - no awaits in quasis)
|
|
7403
|
+
const strings = [];
|
|
7404
|
+
const rawStrings = [];
|
|
7405
|
+
for (const quasi of node.quasi.quasis) {
|
|
7406
|
+
strings.push(quasi.value.cooked || quasi.value.raw);
|
|
7407
|
+
rawStrings.push(quasi.value.raw);
|
|
7408
|
+
}
|
|
7409
|
+
|
|
7410
|
+
Object.defineProperty(strings, 'raw', {
|
|
7411
|
+
value: Object.freeze(rawStrings),
|
|
7412
|
+
writable: false,
|
|
7413
|
+
enumerable: false,
|
|
7414
|
+
configurable: false
|
|
7415
|
+
});
|
|
7416
|
+
Object.freeze(strings);
|
|
7417
|
+
|
|
7418
|
+
// 3. Evaluate expressions async (may contain awaits)
|
|
7419
|
+
const values = [];
|
|
7420
|
+
for (const expr of node.quasi.expressions) {
|
|
7421
|
+
values.push(await this.evaluateAsync(expr, env));
|
|
7422
|
+
}
|
|
7423
|
+
|
|
7424
|
+
// 4. Call tag function (may be async)
|
|
7425
|
+
if (typeof tagFunction === 'function') {
|
|
7426
|
+
if (thisContext !== undefined) {
|
|
7427
|
+
return await tagFunction.call(thisContext, strings, ...values);
|
|
7428
|
+
}
|
|
7429
|
+
return await tagFunction(strings, ...values);
|
|
7430
|
+
} else if (tagFunction && tagFunction.__isFunction) {
|
|
7431
|
+
return await this.callUserFunction(tagFunction, [strings, ...values], env, thisContext);
|
|
7432
|
+
}
|
|
7433
|
+
|
|
7434
|
+
throw new TypeError('Tag must be a function');
|
|
7435
|
+
}
|
|
7436
|
+
|
|
7387
7437
|
// For logical expressions with async operands (await support)
|
|
7388
7438
|
if (node.type === 'LogicalExpression') {
|
|
7389
7439
|
const left = await this.evaluateAsync(node.left, env);
|
|
@@ -7987,6 +8037,9 @@ class Interpreter {
|
|
|
7987
8037
|
case 'TemplateLiteral':
|
|
7988
8038
|
return this.evaluateTemplateLiteral(node, env);
|
|
7989
8039
|
|
|
8040
|
+
case 'TaggedTemplateExpression':
|
|
8041
|
+
return this.evaluateTaggedTemplateExpression(node, env);
|
|
8042
|
+
|
|
7990
8043
|
case 'ClassDeclaration':
|
|
7991
8044
|
return this.evaluateClassDeclaration(node, env);
|
|
7992
8045
|
|
|
@@ -9231,6 +9284,56 @@ class Interpreter {
|
|
|
9231
9284
|
return result;
|
|
9232
9285
|
}
|
|
9233
9286
|
|
|
9287
|
+
evaluateTaggedTemplateExpression(node, env) {
|
|
9288
|
+
// 1. Evaluate the tag function, preserving 'this' context for member expressions
|
|
9289
|
+
let thisContext = undefined;
|
|
9290
|
+
let tagFunction;
|
|
9291
|
+
|
|
9292
|
+
if (node.tag.type === 'MemberExpression') {
|
|
9293
|
+
// For method calls like obj.tag`...`, set this to obj
|
|
9294
|
+
thisContext = this.evaluate(node.tag.object, env);
|
|
9295
|
+
const prop = node.tag.computed
|
|
9296
|
+
? this.evaluate(node.tag.property, env)
|
|
9297
|
+
: node.tag.property.name;
|
|
9298
|
+
tagFunction = thisContext[prop];
|
|
9299
|
+
} else {
|
|
9300
|
+
tagFunction = this.evaluate(node.tag, env);
|
|
9301
|
+
}
|
|
9302
|
+
|
|
9303
|
+
// 2. Build the strings array from quasis (cooked values)
|
|
9304
|
+
const strings = [];
|
|
9305
|
+
const rawStrings = [];
|
|
9306
|
+
for (const quasi of node.quasi.quasis) {
|
|
9307
|
+
strings.push(quasi.value.cooked || quasi.value.raw);
|
|
9308
|
+
rawStrings.push(quasi.value.raw);
|
|
9309
|
+
}
|
|
9310
|
+
|
|
9311
|
+
// 3. Add the raw property (frozen per ES6 spec)
|
|
9312
|
+
Object.defineProperty(strings, 'raw', {
|
|
9313
|
+
value: Object.freeze(rawStrings),
|
|
9314
|
+
writable: false,
|
|
9315
|
+
enumerable: false,
|
|
9316
|
+
configurable: false
|
|
9317
|
+
});
|
|
9318
|
+
Object.freeze(strings);
|
|
9319
|
+
|
|
9320
|
+
// 4. Evaluate the embedded expressions
|
|
9321
|
+
const values = node.quasi.expressions.map(expr => this.evaluate(expr, env));
|
|
9322
|
+
|
|
9323
|
+
// 5. Call the tag function with proper this context
|
|
9324
|
+
if (typeof tagFunction === 'function') {
|
|
9325
|
+
if (thisContext !== undefined) {
|
|
9326
|
+
return tagFunction.call(thisContext, strings, ...values);
|
|
9327
|
+
}
|
|
9328
|
+
return tagFunction(strings, ...values);
|
|
9329
|
+
} else if (tagFunction && tagFunction.__isFunction) {
|
|
9330
|
+
// User-defined function
|
|
9331
|
+
return this.callUserFunction(tagFunction, [strings, ...values], env, thisContext);
|
|
9332
|
+
}
|
|
9333
|
+
|
|
9334
|
+
throw new TypeError('Tag must be a function');
|
|
9335
|
+
}
|
|
9336
|
+
|
|
9234
9337
|
evaluateClassDeclaration(node, env) {
|
|
9235
9338
|
const className = node.id.name;
|
|
9236
9339
|
const classFunc = this.createClass(node, env);
|
package/dist/index.js
CHANGED
|
@@ -6598,6 +6598,43 @@ var Interpreter = class _Interpreter {
|
|
|
6598
6598
|
}
|
|
6599
6599
|
return result;
|
|
6600
6600
|
}
|
|
6601
|
+
if (node.type === "TaggedTemplateExpression") {
|
|
6602
|
+
let thisContext = void 0;
|
|
6603
|
+
let tagFunction;
|
|
6604
|
+
if (node.tag.type === "MemberExpression") {
|
|
6605
|
+
thisContext = await this.evaluateAsync(node.tag.object, env);
|
|
6606
|
+
const prop = node.tag.computed ? await this.evaluateAsync(node.tag.property, env) : node.tag.property.name;
|
|
6607
|
+
tagFunction = thisContext[prop];
|
|
6608
|
+
} else {
|
|
6609
|
+
tagFunction = await this.evaluateAsync(node.tag, env);
|
|
6610
|
+
}
|
|
6611
|
+
const strings = [];
|
|
6612
|
+
const rawStrings = [];
|
|
6613
|
+
for (const quasi of node.quasi.quasis) {
|
|
6614
|
+
strings.push(quasi.value.cooked || quasi.value.raw);
|
|
6615
|
+
rawStrings.push(quasi.value.raw);
|
|
6616
|
+
}
|
|
6617
|
+
Object.defineProperty(strings, "raw", {
|
|
6618
|
+
value: Object.freeze(rawStrings),
|
|
6619
|
+
writable: false,
|
|
6620
|
+
enumerable: false,
|
|
6621
|
+
configurable: false
|
|
6622
|
+
});
|
|
6623
|
+
Object.freeze(strings);
|
|
6624
|
+
const values = [];
|
|
6625
|
+
for (const expr of node.quasi.expressions) {
|
|
6626
|
+
values.push(await this.evaluateAsync(expr, env));
|
|
6627
|
+
}
|
|
6628
|
+
if (typeof tagFunction === "function") {
|
|
6629
|
+
if (thisContext !== void 0) {
|
|
6630
|
+
return await tagFunction.call(thisContext, strings, ...values);
|
|
6631
|
+
}
|
|
6632
|
+
return await tagFunction(strings, ...values);
|
|
6633
|
+
} else if (tagFunction && tagFunction.__isFunction) {
|
|
6634
|
+
return await this.callUserFunction(tagFunction, [strings, ...values], env, thisContext);
|
|
6635
|
+
}
|
|
6636
|
+
throw new TypeError("Tag must be a function");
|
|
6637
|
+
}
|
|
6601
6638
|
if (node.type === "LogicalExpression") {
|
|
6602
6639
|
const left = await this.evaluateAsync(node.left, env);
|
|
6603
6640
|
if (node.operator === "&&") {
|
|
@@ -7081,6 +7118,8 @@ var Interpreter = class _Interpreter {
|
|
|
7081
7118
|
// ES6+ Features
|
|
7082
7119
|
case "TemplateLiteral":
|
|
7083
7120
|
return this.evaluateTemplateLiteral(node, env);
|
|
7121
|
+
case "TaggedTemplateExpression":
|
|
7122
|
+
return this.evaluateTaggedTemplateExpression(node, env);
|
|
7084
7123
|
case "ClassDeclaration":
|
|
7085
7124
|
return this.evaluateClassDeclaration(node, env);
|
|
7086
7125
|
case "ClassExpression":
|
|
@@ -8024,6 +8063,40 @@ var Interpreter = class _Interpreter {
|
|
|
8024
8063
|
}
|
|
8025
8064
|
return result;
|
|
8026
8065
|
}
|
|
8066
|
+
evaluateTaggedTemplateExpression(node, env) {
|
|
8067
|
+
let thisContext = void 0;
|
|
8068
|
+
let tagFunction;
|
|
8069
|
+
if (node.tag.type === "MemberExpression") {
|
|
8070
|
+
thisContext = this.evaluate(node.tag.object, env);
|
|
8071
|
+
const prop = node.tag.computed ? this.evaluate(node.tag.property, env) : node.tag.property.name;
|
|
8072
|
+
tagFunction = thisContext[prop];
|
|
8073
|
+
} else {
|
|
8074
|
+
tagFunction = this.evaluate(node.tag, env);
|
|
8075
|
+
}
|
|
8076
|
+
const strings = [];
|
|
8077
|
+
const rawStrings = [];
|
|
8078
|
+
for (const quasi of node.quasi.quasis) {
|
|
8079
|
+
strings.push(quasi.value.cooked || quasi.value.raw);
|
|
8080
|
+
rawStrings.push(quasi.value.raw);
|
|
8081
|
+
}
|
|
8082
|
+
Object.defineProperty(strings, "raw", {
|
|
8083
|
+
value: Object.freeze(rawStrings),
|
|
8084
|
+
writable: false,
|
|
8085
|
+
enumerable: false,
|
|
8086
|
+
configurable: false
|
|
8087
|
+
});
|
|
8088
|
+
Object.freeze(strings);
|
|
8089
|
+
const values = node.quasi.expressions.map((expr) => this.evaluate(expr, env));
|
|
8090
|
+
if (typeof tagFunction === "function") {
|
|
8091
|
+
if (thisContext !== void 0) {
|
|
8092
|
+
return tagFunction.call(thisContext, strings, ...values);
|
|
8093
|
+
}
|
|
8094
|
+
return tagFunction(strings, ...values);
|
|
8095
|
+
} else if (tagFunction && tagFunction.__isFunction) {
|
|
8096
|
+
return this.callUserFunction(tagFunction, [strings, ...values], env, thisContext);
|
|
8097
|
+
}
|
|
8098
|
+
throw new TypeError("Tag must be a function");
|
|
8099
|
+
}
|
|
8027
8100
|
evaluateClassDeclaration(node, env) {
|
|
8028
8101
|
const className = node.id.name;
|
|
8029
8102
|
const classFunc = this.createClass(node, env);
|