@weborigami/language 0.0.68 → 0.0.70

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.
@@ -8,8 +8,8 @@ describe("Origami parser", () => {
8
8
  test("absoluteFilePath", () => {
9
9
  assertParse("absoluteFilePath", "/foo/bar", [
10
10
  [ops.filesRoot],
11
- [ops.primitive, "foo/"],
12
- [ops.primitive, "bar"],
11
+ [ops.literal, "foo/"],
12
+ [ops.literal, "bar"],
13
13
  ]);
14
14
  });
15
15
 
@@ -17,20 +17,20 @@ describe("Origami parser", () => {
17
17
  assertParse("array", "[]", [ops.array]);
18
18
  assertParse("array", "[1, 2, 3]", [
19
19
  ops.array,
20
- [ops.primitive, 1],
21
- [ops.primitive, 2],
22
- [ops.primitive, 3],
20
+ [ops.literal, 1],
21
+ [ops.literal, 2],
22
+ [ops.literal, 3],
23
23
  ]);
24
24
  assertParse("array", "[ 1 , 2 , 3 ]", [
25
25
  ops.array,
26
- [ops.primitive, 1],
27
- [ops.primitive, 2],
28
- [ops.primitive, 3],
26
+ [ops.literal, 1],
27
+ [ops.literal, 2],
28
+ [ops.literal, 3],
29
29
  ]);
30
30
  assertParse("array", "[ 1, ...[2, 3]]", [
31
31
  ops.merge,
32
- [ops.array, [ops.primitive, 1]],
33
- [ops.array, [ops.primitive, 2], [ops.primitive, 3]],
32
+ [ops.array, [ops.literal, 1]],
33
+ [ops.array, [ops.literal, 2], [ops.literal, 3]],
34
34
  ]);
35
35
  });
36
36
 
@@ -44,26 +44,26 @@ describe("Origami parser", () => {
44
44
  ]);
45
45
  assertParse("expr", "foo.bar('hello', 'world')", [
46
46
  [ops.scope, "foo.bar"],
47
- [ops.primitive, "hello"],
48
- [ops.primitive, "world"],
47
+ [ops.literal, "hello"],
48
+ [ops.literal, "world"],
49
49
  ]);
50
50
  assertParse("expr", "(fn)('a')", [
51
51
  [ops.scope, "fn"],
52
- [ops.primitive, "a"],
52
+ [ops.literal, "a"],
53
53
  ]);
54
- assertParse("expr", "1", [ops.primitive, 1]);
54
+ assertParse("expr", "1", [ops.literal, 1]);
55
55
  assertParse("expr", "{ a: 1, b: 2 }", [
56
56
  ops.object,
57
- ["a", [ops.primitive, 1]],
58
- ["b", [ops.primitive, 2]],
57
+ ["a", [ops.literal, 1]],
58
+ ["b", [ops.literal, 2]],
59
59
  ]);
60
60
  assertParse("expr", "serve { index.html: 'hello' }", [
61
61
  [ops.scope, "serve"],
62
- [ops.object, ["index.html", [ops.primitive, "hello"]]],
62
+ [ops.object, ["index.html", [ops.literal, "hello"]]],
63
63
  ]);
64
64
  assertParse("expr", "fn =`x`", [
65
65
  [ops.scope, "fn"],
66
- [ops.lambda, null, [ops.primitive, "x"]],
66
+ [ops.lambda, null, [ops.template, [ops.literal, ["x"]]]],
67
67
  ]);
68
68
  assertParse("expr", "copy app(formulas), files 'snapshot'", [
69
69
  [ops.scope, "copy"],
@@ -73,7 +73,7 @@ describe("Origami parser", () => {
73
73
  ],
74
74
  [
75
75
  [ops.scope, "files"],
76
- [ops.primitive, "snapshot"],
76
+ [ops.literal, "snapshot"],
77
77
  ],
78
78
  ]);
79
79
  assertParse("expr", "@map =`<li>${_}</li>`", [
@@ -82,20 +82,24 @@ describe("Origami parser", () => {
82
82
  ops.lambda,
83
83
  null,
84
84
  [
85
- ops.concat,
86
- [ops.primitive, "<li>"],
87
- [ops.scope, "_"],
88
- [ops.primitive, "</li>"],
85
+ ops.template,
86
+ [ops.literal, ["<li>", "</li>"]],
87
+ [ops.concat, [ops.scope, "_"]],
89
88
  ],
90
89
  ],
91
90
  ]);
92
91
  assertParse("expr", `"https://example.com"`, [
93
- ops.primitive,
92
+ ops.literal,
94
93
  "https://example.com",
95
94
  ]);
96
95
  assertParse("expr", "'Hello' -> test.orit", [
97
96
  [ops.scope, "test.orit"],
98
- [ops.primitive, "Hello"],
97
+ [ops.literal, "Hello"],
98
+ ]);
99
+ assertParse("expr", "tag`Hello, ${name}!`", [
100
+ [ops.scope, "tag"],
101
+ [ops.literal, ["Hello, ", "!"]],
102
+ [ops.concat, [ops.scope, "name"]],
99
103
  ]);
100
104
  });
101
105
 
@@ -138,12 +142,12 @@ describe("Origami parser", () => {
138
142
  assertParse("expression", "path//key", [
139
143
  ops.traverse,
140
144
  [ops.scope, "path/"],
141
- [ops.primitive, "key"],
145
+ [ops.literal, "key"],
142
146
  ]);
143
147
  // Single slash at start of something = absolute file path
144
148
  assertParse("expression", "/path", [
145
149
  [ops.filesRoot],
146
- [ops.primitive, "path"],
150
+ [ops.literal, "path"],
147
151
  ]);
148
152
  // Consecutive slashes at start of something = comment
149
153
  assertParse("expression", "path //comment", [ops.scope, "path"], false);
@@ -172,25 +176,10 @@ describe("Origami parser", () => {
172
176
  assertParse("functionComposition", "fn()/key", [
173
177
  ops.traverse,
174
178
  [[ops.scope, "fn"], undefined],
175
- [ops.primitive, "key"],
176
- ]);
177
- assertParse("functionComposition", "tree/", [
178
- ops.traverse,
179
- [ops.scope, "tree/"],
180
- ]);
181
- assertParse("functionComposition", "tree/key", [
182
- ops.traverse,
183
- [ops.scope, "tree/"],
184
- [ops.primitive, "key"],
185
- ]);
186
- assertParse("functionComposition", "tree/foo/bar", [
187
- ops.traverse,
188
- [ops.scope, "tree/"],
189
- [ops.primitive, "foo/"],
190
- [ops.primitive, "bar"],
179
+ [ops.literal, "key"],
191
180
  ]);
192
181
  assertParse("functionComposition", "tree/key()", [
193
- [ops.traverse, [ops.scope, "tree/"], [ops.primitive, "key"]],
182
+ [ops.traverse, [ops.scope, "tree/"], [ops.literal, "key"]],
194
183
  undefined,
195
184
  ]);
196
185
  assertParse("functionComposition", "(tree)/", [
@@ -198,19 +187,19 @@ describe("Origami parser", () => {
198
187
  [ops.scope, "tree"],
199
188
  ]);
200
189
  assertParse("functionComposition", "fn()/key()", [
201
- [ops.traverse, [[ops.scope, "fn"], undefined], [ops.primitive, "key"]],
190
+ [ops.traverse, [[ops.scope, "fn"], undefined], [ops.literal, "key"]],
202
191
  undefined,
203
192
  ]);
204
193
  assertParse("functionComposition", "(fn())('arg')", [
205
194
  [[ops.scope, "fn"], undefined],
206
- [ops.primitive, "arg"],
195
+ [ops.literal, "arg"],
207
196
  ]);
208
197
  assertParse("functionComposition", "fn('a')('b')", [
209
198
  [
210
199
  [ops.scope, "fn"],
211
- [ops.primitive, "a"],
200
+ [ops.literal, "a"],
212
201
  ],
213
- [ops.primitive, "b"],
202
+ [ops.literal, "b"],
214
203
  ]);
215
204
  assertParse("functionComposition", "(fn())(a, b)", [
216
205
  [[ops.scope, "fn"], undefined],
@@ -219,8 +208,8 @@ describe("Origami parser", () => {
219
208
  ]);
220
209
  assertParse("functionComposition", "{ a: 1, b: 2}/b", [
221
210
  ops.traverse,
222
- [ops.object, ["a", [ops.primitive, 1]], ["b", [ops.primitive, 2]]],
223
- [ops.primitive, "b"],
211
+ [ops.object, ["a", [ops.literal, 1]], ["b", [ops.literal, 2]]],
212
+ [ops.literal, "b"],
224
213
  ]);
225
214
  assertParse("functionComposition", "fn arg", [
226
215
  [ops.scope, "fn"],
@@ -228,8 +217,8 @@ describe("Origami parser", () => {
228
217
  ]);
229
218
  assertParse("functionComposition", "fn 'a', 'b'", [
230
219
  [ops.scope, "fn"],
231
- [ops.primitive, "a"],
232
- [ops.primitive, "b"],
220
+ [ops.literal, "a"],
221
+ [ops.literal, "b"],
233
222
  ]);
234
223
  assertParse("functionComposition", "fn a(b), c", [
235
224
  [ops.scope, "fn"],
@@ -243,20 +232,20 @@ describe("Origami parser", () => {
243
232
  [ops.scope, "fn1"],
244
233
  [
245
234
  [ops.scope, "fn2"],
246
- [ops.primitive, "arg"],
235
+ [ops.literal, "arg"],
247
236
  ],
248
237
  ]);
249
238
  assertParse("functionComposition", "(fn()) 'arg'", [
250
239
  [[ops.scope, "fn"], undefined],
251
- [ops.primitive, "arg"],
240
+ [ops.literal, "arg"],
252
241
  ]);
253
242
  assertParse("functionComposition", "tree/key arg", [
254
- [ops.traverse, [ops.scope, "tree/"], [ops.primitive, "key"]],
243
+ [ops.traverse, [ops.scope, "tree/"], [ops.literal, "key"]],
255
244
  [ops.scope, "arg"],
256
245
  ]);
257
246
  assertParse("functionComposition", "https://example.com/tree.yaml 'key'", [
258
- [ops.https, [ops.primitive, "example.com"], [ops.primitive, "tree.yaml"]],
259
- [ops.primitive, "key"],
247
+ [ops.https, [ops.literal, "example.com"], [ops.literal, "tree.yaml"]],
248
+ [ops.literal, "key"],
260
249
  ]);
261
250
  });
262
251
 
@@ -267,9 +256,9 @@ describe("Origami parser", () => {
267
256
  });
268
257
 
269
258
  test("host", () => {
270
- assertParse("host", "abc", [ops.primitive, "abc"]);
271
- assertParse("host", "abc:123", [ops.primitive, "abc:123"]);
272
- assertParse("host", "foo\\ bar", [ops.primitive, "foo bar"]);
259
+ assertParse("host", "abc", [ops.literal, "abc"]);
260
+ assertParse("host", "abc:123", [ops.literal, "abc:123"]);
261
+ assertParse("host", "foo\\ bar", [ops.literal, "foo bar"]);
273
262
  });
274
263
 
275
264
  test("identifier", () => {
@@ -289,46 +278,45 @@ describe("Origami parser", () => {
289
278
  ops.lambda,
290
279
  null,
291
280
  [
292
- ops.concat,
293
- [ops.primitive, "Hello, "],
294
- [ops.scope, "name"],
295
- [ops.primitive, "."],
281
+ ops.template,
282
+ [ops.literal, ["Hello, ", "."]],
283
+ [ops.concat, [ops.scope, "name"]],
296
284
  ],
297
285
  ]);
298
286
  });
299
287
 
300
288
  test("leadingSlashPath", () => {
301
289
  assertParse("leadingSlashPath", "/", []);
302
- assertParse("leadingSlashPath", "/tree", [[ops.primitive, "tree"]]);
303
- assertParse("leadingSlashPath", "/tree/", [[ops.primitive, "tree/"]]);
290
+ assertParse("leadingSlashPath", "/tree", [[ops.literal, "tree"]]);
291
+ assertParse("leadingSlashPath", "/tree/", [[ops.literal, "tree/"]]);
304
292
  });
305
293
 
306
294
  test("list", () => {
307
- assertParse("list", "1", [[ops.primitive, 1]]);
295
+ assertParse("list", "1", [[ops.literal, 1]]);
308
296
  assertParse("list", "1,2,3", [
309
- [ops.primitive, 1],
310
- [ops.primitive, 2],
311
- [ops.primitive, 3],
297
+ [ops.literal, 1],
298
+ [ops.literal, 2],
299
+ [ops.literal, 3],
312
300
  ]);
313
301
  assertParse("list", "1, 2, 3,", [
314
- [ops.primitive, 1],
315
- [ops.primitive, 2],
316
- [ops.primitive, 3],
302
+ [ops.literal, 1],
303
+ [ops.literal, 2],
304
+ [ops.literal, 3],
317
305
  ]);
318
306
  assertParse("list", "1 , 2 , 3", [
319
- [ops.primitive, 1],
320
- [ops.primitive, 2],
321
- [ops.primitive, 3],
307
+ [ops.literal, 1],
308
+ [ops.literal, 2],
309
+ [ops.literal, 3],
322
310
  ]);
323
311
  assertParse("list", "1\n2\n3", [
324
- [ops.primitive, 1],
325
- [ops.primitive, 2],
326
- [ops.primitive, 3],
312
+ [ops.literal, 1],
313
+ [ops.literal, 2],
314
+ [ops.literal, 3],
327
315
  ]);
328
316
  assertParse("list", "'a' , 'b' , 'c'", [
329
- [ops.primitive, "a"],
330
- [ops.primitive, "b"],
331
- [ops.primitive, "c"],
317
+ [ops.literal, "a"],
318
+ [ops.literal, "b"],
319
+ [ops.literal, "c"],
332
320
  ]);
333
321
  });
334
322
 
@@ -338,53 +326,53 @@ describe("Origami parser", () => {
338
326
 
339
327
  test("new", () => {
340
328
  assertParse("expression", "new:@js/Date('2025-01-01')", [
341
- [ops.constructor, [ops.primitive, "@js"], [ops.primitive, "Date"]],
342
- [ops.primitive, "2025-01-01"],
329
+ [ops.constructor, [ops.literal, "@js"], [ops.literal, "Date"]],
330
+ [ops.literal, "2025-01-01"],
343
331
  ]);
344
332
  });
345
333
 
346
334
  test("number", () => {
347
- assertParse("number", "123", [ops.primitive, 123]);
348
- assertParse("number", "-456", [ops.primitive, -456]);
349
- assertParse("number", ".5", [ops.primitive, 0.5]);
350
- assertParse("number", "123.45", [ops.primitive, 123.45]);
351
- assertParse("number", "-678.90", [ops.primitive, -678.9]);
352
- assertParse("number", "+123", [ops.primitive, 123]);
353
- assertParse("number", "+456.78", [ops.primitive, 456.78]);
335
+ assertParse("number", "123", [ops.literal, 123]);
336
+ assertParse("number", "-456", [ops.literal, -456]);
337
+ assertParse("number", ".5", [ops.literal, 0.5]);
338
+ assertParse("number", "123.45", [ops.literal, 123.45]);
339
+ assertParse("number", "-678.90", [ops.literal, -678.9]);
340
+ assertParse("number", "+123", [ops.literal, 123]);
341
+ assertParse("number", "+456.78", [ops.literal, 456.78]);
354
342
  });
355
343
 
356
344
  test("object", () => {
357
345
  assertParse("object", "{}", [ops.object]);
358
346
  assertParse("object", "{ a: 1, b }", [
359
347
  ops.object,
360
- ["a", [ops.primitive, 1]],
348
+ ["a", [ops.literal, 1]],
361
349
  ["b", [ops.inherited, "b"]],
362
350
  ]);
363
351
  assertParse("object", "{ sub: { a: 1 } }", [
364
352
  ops.object,
365
- ["sub", [ops.object, ["a", [ops.primitive, 1]]]],
353
+ ["sub", [ops.object, ["a", [ops.literal, 1]]]],
366
354
  ]);
367
355
  assertParse("object", "{ sub: { a/: 1 } }", [
368
356
  ops.object,
369
- ["sub", [ops.object, ["a/", [ops.primitive, 1]]]],
357
+ ["sub", [ops.object, ["a/", [ops.literal, 1]]]],
370
358
  ]);
371
359
  assertParse("object", `{ "a": 1, "b": 2 }`, [
372
360
  ops.object,
373
- ["a", [ops.primitive, 1]],
374
- ["b", [ops.primitive, 2]],
361
+ ["a", [ops.literal, 1]],
362
+ ["b", [ops.literal, 2]],
375
363
  ]);
376
364
  assertParse("object", "{ a = b, b = 2 }", [
377
365
  ops.object,
378
366
  ["a", [ops.getter, [ops.scope, "b"]]],
379
- ["b", [ops.primitive, 2]],
367
+ ["b", [ops.literal, 2]],
380
368
  ]);
381
369
  assertParse("object", "{ a: { b: 1 } }", [
382
370
  ops.object,
383
- ["a", [ops.object, ["b", [ops.primitive, 1]]]],
371
+ ["a", [ops.object, ["b", [ops.literal, 1]]]],
384
372
  ]);
385
373
  assertParse("object", "{ a: { b = 1 } }", [
386
374
  ops.object,
387
- ["a", [ops.object, ["b", [ops.primitive, 1]]]],
375
+ ["a", [ops.object, ["b", [ops.literal, 1]]]],
388
376
  ]);
389
377
  assertParse("object", "{ a: { b = fn() } }", [
390
378
  ops.object,
@@ -398,25 +386,26 @@ describe("Origami parser", () => {
398
386
  ops.getter,
399
387
  [
400
388
  [ops.scope, "fn"],
401
- [ops.primitive, "a"],
389
+ [ops.literal, "a"],
402
390
  ],
403
391
  ],
404
392
  ],
405
393
  ]);
406
394
  assertParse("object", "{ a: 1, ...b }", [
407
395
  ops.merge,
408
- [ops.object, ["a", [ops.primitive, 1]]],
396
+ [ops.object, ["a", [ops.literal, 1]]],
409
397
  [ops.scope, "b"],
410
398
  ]);
411
399
  assertParse("object", "{ (a): 1 }", [
412
400
  ops.object,
413
- ["(a)", [ops.primitive, 1]],
401
+ ["(a)", [ops.literal, 1]],
414
402
  ]);
415
403
  });
416
404
 
417
405
  test("objectEntry", () => {
418
406
  assertParse("objectEntry", "foo", ["foo", [ops.inherited, "foo"]]);
419
407
  assertParse("objectEntry", "x: y", ["x", [ops.scope, "y"]]);
408
+ assertParse("objectEntry", "a: a", ["a", [ops.inherited, "a"]]);
420
409
  });
421
410
 
422
411
  test("objectGetter", () => {
@@ -430,23 +419,23 @@ describe("Origami parser", () => {
430
419
  ops.getter,
431
420
  [
432
421
  [ops.scope, "fn"],
433
- [ops.primitive, "bar"],
422
+ [ops.literal, "bar"],
434
423
  ],
435
424
  ],
436
425
  ]);
437
426
  });
438
427
 
439
428
  test("objectProperty", () => {
440
- assertParse("objectProperty", "a: 1", ["a", [ops.primitive, 1]]);
429
+ assertParse("objectProperty", "a: 1", ["a", [ops.literal, 1]]);
441
430
  assertParse("objectProperty", "name: 'Alice'", [
442
431
  "name",
443
- [ops.primitive, "Alice"],
432
+ [ops.literal, "Alice"],
444
433
  ]);
445
434
  assertParse("objectProperty", "x: fn('a')", [
446
435
  "x",
447
436
  [
448
437
  [ops.scope, "fn"],
449
- [ops.primitive, "a"],
438
+ [ops.literal, "a"],
450
439
  ],
451
440
  ]);
452
441
  });
@@ -498,19 +487,19 @@ describe("Origami parser", () => {
498
487
  });
499
488
 
500
489
  test("path", () => {
501
- assertParse("path", "tree/", [[ops.primitive, "tree/"]]);
490
+ assertParse("path", "tree/", [[ops.literal, "tree/"]]);
502
491
  assertParse("path", "month/12", [
503
- [ops.primitive, "month/"],
504
- [ops.primitive, "12"],
492
+ [ops.literal, "month/"],
493
+ [ops.literal, "12"],
505
494
  ]);
506
495
  assertParse("path", "tree/foo/bar", [
507
- [ops.primitive, "tree/"],
508
- [ops.primitive, "foo/"],
509
- [ops.primitive, "bar"],
496
+ [ops.literal, "tree/"],
497
+ [ops.literal, "foo/"],
498
+ [ops.literal, "bar"],
510
499
  ]);
511
500
  assertParse("path", "a///b", [
512
- [ops.primitive, "a/"],
513
- [ops.primitive, "b"],
501
+ [ops.literal, "a/"],
502
+ [ops.literal, "b"],
514
503
  ]);
515
504
  });
516
505
 
@@ -538,21 +527,21 @@ describe("Origami parser", () => {
538
527
  test("protocolCall", () => {
539
528
  assertParse("protocolCall", "foo://bar", [
540
529
  [ops.scope, "foo"],
541
- [ops.primitive, "bar"],
530
+ [ops.literal, "bar"],
542
531
  ]);
543
532
  assertParse("protocolCall", "https://example.com/foo/", [
544
533
  ops.https,
545
- [ops.primitive, "example.com"],
546
- [ops.primitive, "foo/"],
534
+ [ops.literal, "example.com"],
535
+ [ops.literal, "foo/"],
547
536
  ]);
548
537
  assertParse("protocolCall", "http:example.com", [
549
538
  ops.http,
550
- [ops.primitive, "example.com"],
539
+ [ops.literal, "example.com"],
551
540
  ]);
552
541
  assertParse("protocolCall", "http://localhost:5000/foo", [
553
542
  ops.http,
554
- [ops.primitive, "localhost:5000"],
555
- [ops.primitive, "foo"],
543
+ [ops.literal, "localhost:5000"],
544
+ [ops.literal, "foo"],
556
545
  ]);
557
546
  });
558
547
 
@@ -561,17 +550,18 @@ describe("Origami parser", () => {
561
550
  });
562
551
 
563
552
  test("scopeTraverse", () => {
553
+ assertParse("scopeTraverse", "tree/", [ops.traverse, [ops.scope, "tree/"]]);
564
554
  assertParse("scopeTraverse", "tree/foo/bar", [
565
555
  ops.traverse,
566
556
  [ops.scope, "tree/"],
567
- [ops.primitive, "foo/"],
568
- [ops.primitive, "bar"],
557
+ [ops.literal, "foo/"],
558
+ [ops.literal, "bar"],
569
559
  ]);
570
560
  assertParse("scopeTraverse", "tree/foo/bar/", [
571
561
  ops.traverse,
572
562
  [ops.scope, "tree/"],
573
- [ops.primitive, "foo/"],
574
- [ops.primitive, "bar/"],
563
+ [ops.literal, "foo/"],
564
+ [ops.literal, "bar/"],
575
565
  ]);
576
566
  });
577
567
 
@@ -581,7 +571,7 @@ describe("Origami parser", () => {
581
571
  `#!/usr/bin/env ori @invoke
582
572
  'Hello'
583
573
  `,
584
- [ops.primitive, "Hello"],
574
+ [ops.literal, "Hello"],
585
575
  false
586
576
  );
587
577
  });
@@ -596,83 +586,82 @@ describe("Origami parser", () => {
596
586
  });
597
587
 
598
588
  test("string", () => {
599
- assertParse("string", '"foo"', [ops.primitive, "foo"]);
600
- assertParse("string", "'bar'", [ops.primitive, "bar"]);
601
- assertParse("string", '"foo bar"', [ops.primitive, "foo bar"]);
602
- assertParse("string", "'bar baz'", [ops.primitive, "bar baz"]);
603
- assertParse("string", `"foo\\"s bar"`, [ops.primitive, `foo"s bar`]);
604
- assertParse("string", `'bar\\'s baz'`, [ops.primitive, `bar's baz`]);
605
- assertParse("string", `«string»`, [ops.primitive, "string"]);
589
+ assertParse("string", '"foo"', [ops.literal, "foo"]);
590
+ assertParse("string", "'bar'", [ops.literal, "bar"]);
591
+ assertParse("string", '"foo bar"', [ops.literal, "foo bar"]);
592
+ assertParse("string", "'bar baz'", [ops.literal, "bar baz"]);
593
+ assertParse("string", `"foo\\"s bar"`, [ops.literal, `foo"s bar`]);
594
+ assertParse("string", `'bar\\'s baz'`, [ops.literal, `bar's baz`]);
595
+ assertParse("string", `«string»`, [ops.literal, "string"]);
606
596
  assertParse("string", `"\\0\\b\\f\\n\\r\\t\\v"`, [
607
- ops.primitive,
597
+ ops.literal,
608
598
  "\0\b\f\n\r\t\v",
609
599
  ]);
610
600
  });
611
601
 
602
+ test("taggedTemplate", () => {
603
+ assertParse("taggedTemplate", "tag`Hello, world.`", [
604
+ [ops.scope, "tag"],
605
+ [ops.literal, ["Hello, world."]],
606
+ ]);
607
+ });
608
+
612
609
  test("templateDocument", () => {
613
610
  assertParse("templateDocument", "hello${foo}world", [
614
611
  ops.lambda,
615
612
  null,
616
613
  [
617
- ops.concat,
618
- [ops.primitive, "hello"],
619
- [ops.scope, "foo"],
620
- [ops.primitive, "world"],
614
+ ops.template,
615
+ [ops.literal, ["hello", "world"]],
616
+ [ops.concat, [ops.scope, "foo"]],
621
617
  ],
622
618
  ]);
623
619
  assertParse("templateDocument", "Documents can contain ` backticks", [
624
620
  ops.lambda,
625
621
  null,
626
- [ops.primitive, "Documents can contain ` backticks"],
622
+ [ops.template, [ops.literal, ["Documents can contain ` backticks"]]],
627
623
  ]);
628
624
  });
629
625
 
630
626
  test("templateLiteral", () => {
631
627
  assertParse("templateLiteral", "`Hello, world.`", [
632
- ops.primitive,
633
- "Hello, world.",
628
+ ops.template,
629
+ [ops.literal, ["Hello, world."]],
634
630
  ]);
635
631
  assertParse("templateLiteral", "`foo ${x} bar`", [
636
- ops.concat,
637
- [ops.primitive, "foo "],
638
- [ops.scope, "x"],
639
- [ops.primitive, " bar"],
632
+ ops.template,
633
+ [ops.literal, ["foo ", " bar"]],
634
+ [ops.concat, [ops.scope, "x"]],
640
635
  ]);
641
- assertParse("templateLiteral", "`${`nested`}`", [ops.primitive, "nested"]);
642
- assertParse("templateLiteral", "`${map(people, =`${name}`)}`", [
643
- ops.concat,
644
- [
645
- [ops.scope, "map"],
646
- [ops.scope, "people"],
647
- [ops.lambda, null, [ops.concat, [ops.scope, "name"]]],
648
- ],
649
- ]);
650
- });
651
-
652
- test("templateLiteral (JS)", () => {
653
- assertParse("templateLiteral", "`Hello, world.`", [
654
- ops.primitive,
655
- "Hello, world.",
656
- ]);
657
- assertParse("templateLiteral", "`foo ${x} bar`", [
658
- ops.concat,
659
- [ops.primitive, "foo "],
660
- [ops.scope, "x"],
661
- [ops.primitive, " bar"],
636
+ assertParse("templateLiteral", "`${`nested`}`", [
637
+ ops.template,
638
+ [ops.literal, ["", ""]],
639
+ [ops.concat, [ops.template, [ops.literal, ["nested"]]]],
662
640
  ]);
663
- assertParse("templateLiteral", "`${`nested`}`", [ops.primitive, "nested"]);
664
641
  assertParse("templateLiteral", "`${map(people, =`${name}`)}`", [
665
- ops.concat,
642
+ ops.template,
643
+ [ops.literal, ["", ""]],
666
644
  [
667
- [ops.scope, "map"],
668
- [ops.scope, "people"],
669
- [ops.lambda, null, [ops.concat, [ops.scope, "name"]]],
645
+ ops.concat,
646
+ [
647
+ [ops.scope, "map"],
648
+ [ops.scope, "people"],
649
+ [
650
+ ops.lambda,
651
+ null,
652
+ [
653
+ ops.template,
654
+ [ops.literal, ["", ""]],
655
+ [ops.concat, [ops.scope, "name"]],
656
+ ],
657
+ ],
658
+ ],
670
659
  ],
671
660
  ]);
672
661
  });
673
662
 
674
663
  test("templateSubtitution", () => {
675
- assertParse("templateSubstitution", "${foo}", [ops.scope, "foo"]);
664
+ assertParse("templateSubstitution", "${foo}", [ops.scope, "foo"], false);
676
665
  });
677
666
 
678
667
  test("whitespace block", () => {
@@ -0,0 +1,10 @@
1
+ import assert from "node:assert";
2
+ import { describe, test } from "node:test";
3
+ import taggedTemplate from "../../src/runtime/taggedTemplate.js";
4
+
5
+ describe("taggedTemplate", () => {
6
+ test("joins strings and values together", () => {
7
+ const result = taggedTemplate`a ${"b"} c`;
8
+ assert.equal(result, "a b c");
9
+ });
10
+ });