@weborigami/language 0.0.69 → 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,19 +386,19 @@ 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
 
@@ -431,23 +419,23 @@ describe("Origami parser", () => {
431
419
  ops.getter,
432
420
  [
433
421
  [ops.scope, "fn"],
434
- [ops.primitive, "bar"],
422
+ [ops.literal, "bar"],
435
423
  ],
436
424
  ],
437
425
  ]);
438
426
  });
439
427
 
440
428
  test("objectProperty", () => {
441
- assertParse("objectProperty", "a: 1", ["a", [ops.primitive, 1]]);
429
+ assertParse("objectProperty", "a: 1", ["a", [ops.literal, 1]]);
442
430
  assertParse("objectProperty", "name: 'Alice'", [
443
431
  "name",
444
- [ops.primitive, "Alice"],
432
+ [ops.literal, "Alice"],
445
433
  ]);
446
434
  assertParse("objectProperty", "x: fn('a')", [
447
435
  "x",
448
436
  [
449
437
  [ops.scope, "fn"],
450
- [ops.primitive, "a"],
438
+ [ops.literal, "a"],
451
439
  ],
452
440
  ]);
453
441
  });
@@ -499,19 +487,19 @@ describe("Origami parser", () => {
499
487
  });
500
488
 
501
489
  test("path", () => {
502
- assertParse("path", "tree/", [[ops.primitive, "tree/"]]);
490
+ assertParse("path", "tree/", [[ops.literal, "tree/"]]);
503
491
  assertParse("path", "month/12", [
504
- [ops.primitive, "month/"],
505
- [ops.primitive, "12"],
492
+ [ops.literal, "month/"],
493
+ [ops.literal, "12"],
506
494
  ]);
507
495
  assertParse("path", "tree/foo/bar", [
508
- [ops.primitive, "tree/"],
509
- [ops.primitive, "foo/"],
510
- [ops.primitive, "bar"],
496
+ [ops.literal, "tree/"],
497
+ [ops.literal, "foo/"],
498
+ [ops.literal, "bar"],
511
499
  ]);
512
500
  assertParse("path", "a///b", [
513
- [ops.primitive, "a/"],
514
- [ops.primitive, "b"],
501
+ [ops.literal, "a/"],
502
+ [ops.literal, "b"],
515
503
  ]);
516
504
  });
517
505
 
@@ -539,21 +527,21 @@ describe("Origami parser", () => {
539
527
  test("protocolCall", () => {
540
528
  assertParse("protocolCall", "foo://bar", [
541
529
  [ops.scope, "foo"],
542
- [ops.primitive, "bar"],
530
+ [ops.literal, "bar"],
543
531
  ]);
544
532
  assertParse("protocolCall", "https://example.com/foo/", [
545
533
  ops.https,
546
- [ops.primitive, "example.com"],
547
- [ops.primitive, "foo/"],
534
+ [ops.literal, "example.com"],
535
+ [ops.literal, "foo/"],
548
536
  ]);
549
537
  assertParse("protocolCall", "http:example.com", [
550
538
  ops.http,
551
- [ops.primitive, "example.com"],
539
+ [ops.literal, "example.com"],
552
540
  ]);
553
541
  assertParse("protocolCall", "http://localhost:5000/foo", [
554
542
  ops.http,
555
- [ops.primitive, "localhost:5000"],
556
- [ops.primitive, "foo"],
543
+ [ops.literal, "localhost:5000"],
544
+ [ops.literal, "foo"],
557
545
  ]);
558
546
  });
559
547
 
@@ -562,17 +550,18 @@ describe("Origami parser", () => {
562
550
  });
563
551
 
564
552
  test("scopeTraverse", () => {
553
+ assertParse("scopeTraverse", "tree/", [ops.traverse, [ops.scope, "tree/"]]);
565
554
  assertParse("scopeTraverse", "tree/foo/bar", [
566
555
  ops.traverse,
567
556
  [ops.scope, "tree/"],
568
- [ops.primitive, "foo/"],
569
- [ops.primitive, "bar"],
557
+ [ops.literal, "foo/"],
558
+ [ops.literal, "bar"],
570
559
  ]);
571
560
  assertParse("scopeTraverse", "tree/foo/bar/", [
572
561
  ops.traverse,
573
562
  [ops.scope, "tree/"],
574
- [ops.primitive, "foo/"],
575
- [ops.primitive, "bar/"],
563
+ [ops.literal, "foo/"],
564
+ [ops.literal, "bar/"],
576
565
  ]);
577
566
  });
578
567
 
@@ -582,7 +571,7 @@ describe("Origami parser", () => {
582
571
  `#!/usr/bin/env ori @invoke
583
572
  'Hello'
584
573
  `,
585
- [ops.primitive, "Hello"],
574
+ [ops.literal, "Hello"],
586
575
  false
587
576
  );
588
577
  });
@@ -597,83 +586,82 @@ describe("Origami parser", () => {
597
586
  });
598
587
 
599
588
  test("string", () => {
600
- assertParse("string", '"foo"', [ops.primitive, "foo"]);
601
- assertParse("string", "'bar'", [ops.primitive, "bar"]);
602
- assertParse("string", '"foo bar"', [ops.primitive, "foo bar"]);
603
- assertParse("string", "'bar baz'", [ops.primitive, "bar baz"]);
604
- assertParse("string", `"foo\\"s bar"`, [ops.primitive, `foo"s bar`]);
605
- assertParse("string", `'bar\\'s baz'`, [ops.primitive, `bar's baz`]);
606
- 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"]);
607
596
  assertParse("string", `"\\0\\b\\f\\n\\r\\t\\v"`, [
608
- ops.primitive,
597
+ ops.literal,
609
598
  "\0\b\f\n\r\t\v",
610
599
  ]);
611
600
  });
612
601
 
602
+ test("taggedTemplate", () => {
603
+ assertParse("taggedTemplate", "tag`Hello, world.`", [
604
+ [ops.scope, "tag"],
605
+ [ops.literal, ["Hello, world."]],
606
+ ]);
607
+ });
608
+
613
609
  test("templateDocument", () => {
614
610
  assertParse("templateDocument", "hello${foo}world", [
615
611
  ops.lambda,
616
612
  null,
617
613
  [
618
- ops.concat,
619
- [ops.primitive, "hello"],
620
- [ops.scope, "foo"],
621
- [ops.primitive, "world"],
614
+ ops.template,
615
+ [ops.literal, ["hello", "world"]],
616
+ [ops.concat, [ops.scope, "foo"]],
622
617
  ],
623
618
  ]);
624
619
  assertParse("templateDocument", "Documents can contain ` backticks", [
625
620
  ops.lambda,
626
621
  null,
627
- [ops.primitive, "Documents can contain ` backticks"],
622
+ [ops.template, [ops.literal, ["Documents can contain ` backticks"]]],
628
623
  ]);
629
624
  });
630
625
 
631
626
  test("templateLiteral", () => {
632
627
  assertParse("templateLiteral", "`Hello, world.`", [
633
- ops.primitive,
634
- "Hello, world.",
628
+ ops.template,
629
+ [ops.literal, ["Hello, world."]],
635
630
  ]);
636
631
  assertParse("templateLiteral", "`foo ${x} bar`", [
637
- ops.concat,
638
- [ops.primitive, "foo "],
639
- [ops.scope, "x"],
640
- [ops.primitive, " bar"],
632
+ ops.template,
633
+ [ops.literal, ["foo ", " bar"]],
634
+ [ops.concat, [ops.scope, "x"]],
641
635
  ]);
642
- assertParse("templateLiteral", "`${`nested`}`", [ops.primitive, "nested"]);
643
- assertParse("templateLiteral", "`${map(people, =`${name}`)}`", [
644
- ops.concat,
645
- [
646
- [ops.scope, "map"],
647
- [ops.scope, "people"],
648
- [ops.lambda, null, [ops.concat, [ops.scope, "name"]]],
649
- ],
650
- ]);
651
- });
652
-
653
- test("templateLiteral (JS)", () => {
654
- assertParse("templateLiteral", "`Hello, world.`", [
655
- ops.primitive,
656
- "Hello, world.",
657
- ]);
658
- assertParse("templateLiteral", "`foo ${x} bar`", [
659
- ops.concat,
660
- [ops.primitive, "foo "],
661
- [ops.scope, "x"],
662
- [ops.primitive, " bar"],
636
+ assertParse("templateLiteral", "`${`nested`}`", [
637
+ ops.template,
638
+ [ops.literal, ["", ""]],
639
+ [ops.concat, [ops.template, [ops.literal, ["nested"]]]],
663
640
  ]);
664
- assertParse("templateLiteral", "`${`nested`}`", [ops.primitive, "nested"]);
665
641
  assertParse("templateLiteral", "`${map(people, =`${name}`)}`", [
666
- ops.concat,
642
+ ops.template,
643
+ [ops.literal, ["", ""]],
667
644
  [
668
- [ops.scope, "map"],
669
- [ops.scope, "people"],
670
- [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
+ ],
671
659
  ],
672
660
  ]);
673
661
  });
674
662
 
675
663
  test("templateSubtitution", () => {
676
- assertParse("templateSubstitution", "${foo}", [ops.scope, "foo"]);
664
+ assertParse("templateSubstitution", "${foo}", [ops.scope, "foo"], false);
677
665
  });
678
666
 
679
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
+ });