@weborigami/language 0.6.4 → 0.6.5

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.
@@ -117,49 +117,231 @@ describe("Origami parser", () => {
117
117
  );
118
118
  });
119
119
 
120
- test("arrowFunction", () => {
121
- assertParse("arrowFunction", "() => foo", [
122
- ops.lambda,
123
- [],
124
- [markers.traverse, [markers.reference, "foo"]],
125
- ]);
126
- assertParse("arrowFunction", "x => y", [
127
- ops.lambda,
128
- [[ops.literal, "x"]],
129
- [markers.traverse, [markers.reference, "y"]],
130
- ]);
131
- assertParse("arrowFunction", "(a, b, c) ⇒ fn(a, b, c)", [
132
- ops.lambda,
133
- [
134
- [ops.literal, "a"],
135
- [ops.literal, "b"],
136
- [ops.literal, "c"],
137
- ],
138
- [
139
- [markers.traverse, [markers.reference, "fn"]],
140
- [markers.traverse, [markers.reference, "a"]],
141
- [markers.traverse, [markers.reference, "b"]],
142
- [markers.traverse, [markers.reference, "c"]],
143
- ],
144
- ]);
145
- assertParse("arrowFunction", "a => b => fn(a, b)", [
146
- ops.lambda,
147
- [[ops.literal, "a"]],
148
- [
120
+ describe("arrowFunction", () => {
121
+ test("basic arrow functions", () => {
122
+ assertParse("arrowFunction", "() => foo", [
123
+ ops.lambda,
124
+ 0,
125
+ [],
126
+ [markers.traverse, [markers.reference, "foo"]],
127
+ ]);
128
+ assertParse("arrowFunction", "x => y", [
149
129
  ops.lambda,
150
- [[ops.literal, "b"]],
130
+ 1,
131
+ [["x", [[ops.params, 0], 0]]],
132
+ [markers.traverse, [markers.reference, "y"]],
133
+ ]);
134
+ assertParse("arrowFunction", "(a, b, c) ⇒ fn(a, b, c)", [
135
+ ops.lambda,
136
+ 3,
137
+ [
138
+ ["a", [[ops.params, 0], 0]],
139
+ ["b", [[ops.params, 0], 1]],
140
+ ["c", [[ops.params, 0], 2]],
141
+ ],
151
142
  [
152
143
  [markers.traverse, [markers.reference, "fn"]],
153
144
  [markers.traverse, [markers.reference, "a"]],
154
145
  [markers.traverse, [markers.reference, "b"]],
146
+ [markers.traverse, [markers.reference, "c"]],
155
147
  ],
156
- ],
157
- ]);
158
- assertParse("arrowFunction", "async (x) => x", [
159
- ops.lambda,
160
- [[ops.literal, "x"]],
161
- [markers.traverse, [markers.reference, "x"]],
162
- ]);
148
+ ]);
149
+ // `async` keyword is effectively ignored
150
+ assertParse("arrowFunction", "async (x) => x", [
151
+ ops.lambda,
152
+ 1,
153
+ [["x", [[ops.params, 0], 0]]],
154
+ [markers.traverse, [markers.reference, "x"]],
155
+ ]);
156
+ // Can't omit a parameter like you can in an array
157
+ assertThrows("arrowFunction", "(, b) => b", "Expected an expression");
158
+ });
159
+
160
+ test("arrow function with default parameters", () => {
161
+ assertParse("arrowFunction", "(a = 1, b = fn()) => a + b", [
162
+ ops.lambda,
163
+ 0,
164
+ [
165
+ ["a", [ops.defaultValue, [[ops.params, 0], 0], [ops.literal, 1]]],
166
+ [
167
+ "__temp0__",
168
+ [
169
+ ops.defaultValue,
170
+ [[ops.params, 0], 1],
171
+ [
172
+ ops.lambda,
173
+ 0,
174
+ [],
175
+ [[markers.traverse, [markers.reference, "fn"]], undefined],
176
+ ],
177
+ ],
178
+ ],
179
+ ["b", [[ops.inherited, 0], "__temp0__"]],
180
+ ],
181
+ [
182
+ ops.addition,
183
+ [markers.traverse, [markers.reference, "a"]],
184
+ [markers.traverse, [markers.reference, "b"]],
185
+ ],
186
+ ]);
187
+ });
188
+
189
+ test("arrow function with rest parameter", () => {
190
+ assertParse("arrowFunction", "(head, ...tail) => tail", [
191
+ ops.lambda,
192
+ 1,
193
+ [
194
+ ["head", [[ops.params, 0], 0]],
195
+ ["tail", [[[ops.params, 0], "slice"], 1]],
196
+ ],
197
+ [markers.traverse, [markers.reference, "tail"]],
198
+ ]);
199
+ });
200
+
201
+ test("array parameter destructuring", () => {
202
+ assertParse("arrowFunction", "([a, b, c]) => a + b + c", [
203
+ ops.lambda,
204
+ 1,
205
+ [
206
+ ["a", [[[ops.params, 0], 0], 0]],
207
+ ["b", [[[ops.params, 0], 0], 1]],
208
+ ["c", [[[ops.params, 0], 0], 2]],
209
+ ],
210
+ [
211
+ ops.addition,
212
+ [
213
+ ops.addition,
214
+ [markers.traverse, [markers.reference, "a"]],
215
+ [markers.traverse, [markers.reference, "b"]],
216
+ ],
217
+ [markers.traverse, [markers.reference, "c"]],
218
+ ],
219
+ ]);
220
+ assertParse("arrowFunction", "([a, , b]) => a * b", [
221
+ ops.lambda,
222
+ 1,
223
+ [
224
+ ["a", [[[ops.params, 0], 0], 0]],
225
+ ["b", [[[ops.params, 0], 0], 2]],
226
+ ],
227
+ [
228
+ ops.multiplication,
229
+ [markers.traverse, [markers.reference, "a"]],
230
+ [markers.traverse, [markers.reference, "b"]],
231
+ ],
232
+ ]);
233
+ assertParse("arrowFunction", "([a = 1, b = 2]) => a + b", [
234
+ ops.lambda,
235
+ 1,
236
+ [
237
+ [
238
+ "a",
239
+ [ops.defaultValue, [[[ops.params, 0], 0], 0], [ops.literal, 1]],
240
+ ],
241
+ [
242
+ "b",
243
+ [ops.defaultValue, [[[ops.params, 0], 0], 1], [ops.literal, 2]],
244
+ ],
245
+ ],
246
+ [
247
+ ops.addition,
248
+ [markers.traverse, [markers.reference, "a"]],
249
+ [markers.traverse, [markers.reference, "b"]],
250
+ ],
251
+ ]);
252
+ assertParse("arrowFunction", "([head, ...tail]) => tail", [
253
+ ops.lambda,
254
+ 1,
255
+ [
256
+ ["head", [[[ops.params, 0], 0], 0]],
257
+ ["tail", [[[[ops.params, 0], 0], "slice"], 1]],
258
+ ],
259
+ [markers.traverse, [markers.reference, "tail"]],
260
+ ]);
261
+ assertParse("arrowFunction", "(head, ...{ length }) => length", [
262
+ ops.lambda,
263
+ 1,
264
+ [
265
+ ["head", [[ops.params, 0], 0]],
266
+ ["length", [[[[ops.params, 0], "slice"], 1], "length"]],
267
+ ],
268
+ [markers.traverse, [markers.reference, "length"]],
269
+ ]);
270
+ assertThrows(
271
+ "arrowFunction",
272
+ "([a, a]) => a",
273
+ `Duplicate parameter name "a"`
274
+ );
275
+ });
276
+
277
+ test("object parameter destructuring", () => {
278
+ assertParse("arrowFunction", "({ a, b: c }) => a + c", [
279
+ ops.lambda,
280
+ 1,
281
+ [
282
+ ["a", [[[ops.params, 0], 0], "a"]],
283
+ ["c", [[[ops.params, 0], 0], "b"]],
284
+ ],
285
+ [
286
+ ops.addition,
287
+ [markers.traverse, [markers.reference, "a"]],
288
+ [markers.traverse, [markers.reference, "c"]],
289
+ ],
290
+ ]);
291
+ assertParse("arrowFunction", "({ a: { b: { c }}}) => c", [
292
+ ops.lambda,
293
+ 1,
294
+ [["c", [[[[[ops.params, 0], 0], "a"], "b"], "c"]]],
295
+ [markers.traverse, [markers.reference, "c"]],
296
+ ]);
297
+ assertParse("arrowFunction", "({ a = 1 }) => a", [
298
+ ops.lambda,
299
+ 1,
300
+ [
301
+ [
302
+ "a",
303
+ [ops.defaultValue, [[[ops.params, 0], 0], "a"], [ops.literal, 1]],
304
+ ],
305
+ ],
306
+ [markers.traverse, [markers.reference, "a"]],
307
+ ]);
308
+ assertParse("arrowFunction", "({ a, b, ...rest }) => rest", [
309
+ ops.lambda,
310
+ 1,
311
+ [
312
+ ["a", [[[ops.params, 0], 0], "a"]],
313
+ ["b", [[[ops.params, 0], 0], "b"]],
314
+ [
315
+ "rest",
316
+ [ops.objectRest, [[ops.params, 0], 0], [ops.array, "a", "b"]],
317
+ ],
318
+ ],
319
+ [markers.traverse, [markers.reference, "rest"]],
320
+ ]);
321
+ assertThrows(
322
+ "arrowFunction",
323
+ "({ a: c, b: c }) => c",
324
+ `Duplicate parameter name "c"`
325
+ );
326
+ });
327
+
328
+ test("functional arrow functions", () => {
329
+ assertParse("arrowFunction", "a => b => fn(a, b)", [
330
+ ops.lambda,
331
+ 1,
332
+ [["a", [[ops.params, 0], 0]]],
333
+ [
334
+ ops.lambda,
335
+ 1,
336
+ [["b", [[ops.params, 0], 0]]],
337
+ [
338
+ [markers.traverse, [markers.reference, "fn"]],
339
+ [markers.traverse, [markers.reference, "a"]],
340
+ [markers.traverse, [markers.reference, "b"]],
341
+ ],
342
+ ],
343
+ ]);
344
+ });
163
345
  });
164
346
 
165
347
  test("bitwiseAndExpression", () => {
@@ -222,7 +404,8 @@ describe("Origami parser", () => {
222
404
  [markers.traverse, [markers.reference, "a"]],
223
405
  [
224
406
  ops.lambda,
225
- [[ops.literal, "__optional__"]],
407
+ 1,
408
+ [["__optional__", [[ops.params, 0], 0]]],
226
409
  [
227
410
  ops.property,
228
411
  [
@@ -239,7 +422,8 @@ describe("Origami parser", () => {
239
422
  [markers.traverse, [markers.reference, "a"]],
240
423
  [
241
424
  ops.lambda,
242
- [[ops.literal, "__optional__"]],
425
+ 1,
426
+ [["__optional__", [[ops.params, 0], 0]]],
243
427
  [
244
428
  ops.optional,
245
429
  [
@@ -249,7 +433,8 @@ describe("Origami parser", () => {
249
433
  ],
250
434
  [
251
435
  ops.lambda,
252
- [[ops.literal, "__optional__"]],
436
+ 1,
437
+ [["__optional__", [[ops.params, 0], 0]]],
253
438
  [
254
439
  ops.property,
255
440
  [markers.traverse, [markers.reference, "__optional__"]],
@@ -267,7 +452,8 @@ describe("Origami parser", () => {
267
452
  [markers.traverse, [markers.reference, "a"]],
268
453
  [
269
454
  ops.lambda,
270
- [[ops.literal, "__optional__"]],
455
+ 1,
456
+ [["__optional__", [[ops.params, 0], 0]]],
271
457
  [
272
458
  ops.property,
273
459
  [markers.traverse, [markers.reference, "__optional__"]],
@@ -283,7 +469,8 @@ describe("Origami parser", () => {
283
469
  [markers.traverse, [markers.reference, "fn"]],
284
470
  [
285
471
  ops.lambda,
286
- [[ops.literal, "__optional__"]],
472
+ 1,
473
+ [["__optional__", [[ops.params, 0], 0]]],
287
474
  [
288
475
  [markers.traverse, [markers.reference, "__optional__"]],
289
476
  [ops.literal, 0],
@@ -292,6 +479,70 @@ describe("Origami parser", () => {
292
479
  ]);
293
480
  });
294
481
 
482
+ test("paramArray", () => {
483
+ assertParse("paramArray", "[a, b, c]", [
484
+ markers.paramArray,
485
+ [markers.paramName, "a"],
486
+ [markers.paramName, "b"],
487
+ [markers.paramName, "c"],
488
+ ]);
489
+ assertParse("paramArray", "[a, , b]", [
490
+ markers.paramArray,
491
+ [markers.paramName, "a"],
492
+ undefined,
493
+ [markers.paramName, "b"],
494
+ ]);
495
+ assertParse("paramArray", "[head, ...tail]", [
496
+ markers.paramArray,
497
+ [markers.paramName, "head"],
498
+ [markers.paramRest, [markers.paramName, "tail"]],
499
+ ]);
500
+ });
501
+
502
+ test("paramArrayEntry", () => {
503
+ assertParse("paramArrayEntry", "a", [markers.paramName, "a"]);
504
+ assertParse("paramArrayEntry", "a = 1", [
505
+ markers.paramInitializer,
506
+ [markers.paramName, "a"],
507
+ [ops.literal, 1],
508
+ ]);
509
+ assertThrows("paramArrayEntry", "...rest", `but "." found`);
510
+ });
511
+
512
+ test("paramObject", () => {
513
+ assertParse("paramObject", "{}", [markers.paramObject]);
514
+ assertParse("paramObject", "{ a, b: c }", [
515
+ markers.paramObject,
516
+ ["a", [markers.paramName, "a"]],
517
+ ["b", [markers.paramName, "c"]],
518
+ ]);
519
+ assertParse("paramObject", "{ a, b: { c } }", [
520
+ markers.paramObject,
521
+ ["a", [markers.paramName, "a"]],
522
+ ["b", [markers.paramObject, ["c", [markers.paramName, "c"]]]],
523
+ ]);
524
+ });
525
+
526
+ test("paramObjectEntry", () => {
527
+ assertParse("paramObjectEntry", "a", ["a", [markers.paramName, "a"]]);
528
+ assertParse("paramObjectEntry", "a: b", ["a", [markers.paramName, "b"]]);
529
+ assertParse("paramObjectEntry", "[key]: param", [
530
+ [markers.traverse, [markers.reference, "key"]],
531
+ [markers.paramName, "param"],
532
+ ]);
533
+ assertParse("paramObjectEntry", "a = 1", [
534
+ "a",
535
+ [markers.paramInitializer, [markers.paramName, "a"], [ops.literal, 1]],
536
+ ]);
537
+ });
538
+
539
+ test("paramRest", () => {
540
+ assertParse("paramRest", "...rest", [
541
+ markers.paramRest,
542
+ [markers.paramName, "rest"],
543
+ ]);
544
+ });
545
+
295
546
  test("parentheses arguments", () => {
296
547
  assertParse("callExpression", "fn()", [
297
548
  [markers.traverse, [markers.reference, "fn"]],
@@ -440,13 +691,13 @@ describe("Origami parser", () => {
440
691
  assertParse("conditionalExpression", "false ? () => 1 : 0", [
441
692
  ops.conditional,
442
693
  [markers.traverse, [markers.reference, "false"]],
443
- [ops.lambda, [], [ops.lambda, [], [ops.literal, 1]]],
694
+ [ops.lambda, 0, [], [ops.lambda, 0, [], [ops.literal, 1]]],
444
695
  [ops.literal, 0],
445
696
  ]);
446
697
  assertParse("conditionalExpression", "false ? () => 1 : 0", [
447
698
  ops.conditional,
448
699
  [markers.traverse, [markers.reference, "false"]],
449
- [ops.lambda, [], [ops.lambda, [], [ops.literal, 1]]],
700
+ [ops.lambda, 0, [], [ops.lambda, 0, [], [ops.literal, 1]]],
450
701
  [ops.literal, 0],
451
702
  ]);
452
703
  });
@@ -479,6 +730,7 @@ describe("Origami parser", () => {
479
730
  assertThrows("callExpression", "fn(a", "Expected right parenthesis");
480
731
  assertThrows("doubleQuoteString", '"foo', "Expected closing quote");
481
732
  assertThrows("guillemetString", "«foo", "Expected closing guillemet");
733
+ assertThrows("guillemetString", "»foo", "Expected closing guillemet");
482
734
  assertThrows("objectGetter", "a =", "Expected an expression");
483
735
  assertThrows("objectProperty", "a:", "Expected an expression");
484
736
  assertThrows("singleQuoteString", "'foo", "Expected closing quote");
@@ -657,7 +909,8 @@ Body`,
657
909
  [markers.traverse, [markers.reference, "fn"]],
658
910
  [
659
911
  ops.lambda,
660
- [[ops.literal, "_"]],
912
+ 1,
913
+ [["_", [[ops.params, 0], 0]]],
661
914
  [ops.templateText, [ops.literal, ["x"]]],
662
915
  ],
663
916
  ]);
@@ -676,7 +929,8 @@ Body`,
676
929
  [markers.traverse, [markers.reference, "map"]],
677
930
  [
678
931
  ops.lambda,
679
- [[ops.literal, "_"]],
932
+ 1,
933
+ [["_", [[ops.params, 0], 0]]],
680
934
  [
681
935
  ops.templateText,
682
936
  [ops.literal, ["<li>", "</li>"]],
@@ -696,7 +950,8 @@ Body`,
696
950
  ]);
697
951
  assertParse("expression", "=tag`Hello, ${_}!`", [
698
952
  ops.lambda,
699
- [[ops.literal, "_"]],
953
+ 1,
954
+ [["_", [[ops.params, 0], 0]]],
700
955
  [
701
956
  [markers.traverse, [markers.reference, "tag"]],
702
957
  [ops.literal, ["Hello, ", "!"]],
@@ -705,9 +960,10 @@ Body`,
705
960
  ]);
706
961
  assertParse("expression", "(post, slug) => fn.js(post, slug)", [
707
962
  ops.lambda,
963
+ 2,
708
964
  [
709
- [ops.literal, "post"],
710
- [ops.literal, "slug"],
965
+ ["post", [[ops.params, 0], 0]],
966
+ ["slug", [[ops.params, 0], 1]],
711
967
  ],
712
968
  [
713
969
  [markers.traverse, [markers.reference, "fn.js"]],
@@ -777,7 +1033,8 @@ Body`,
777
1033
  `,
778
1034
  [
779
1035
  ops.lambda,
780
- [[ops.literal, "name"]],
1036
+ 1,
1037
+ [["name", [[ops.params, 0], 0]]],
781
1038
  [[markers.traverse, [markers.reference, "_template"]], undefined],
782
1039
  ],
783
1040
  "program",
@@ -897,13 +1154,14 @@ Body`,
897
1154
  assertParse("key", "a~b", "a~b");
898
1155
  assertParse("key", "foo-bar", "foo-bar");
899
1156
  assertParse("key", "package-lock.json", "package-lock.json");
1157
+ assertThrows("key", "...rest", `but "." found`);
900
1158
  });
901
1159
 
902
1160
  test("logicalAndExpression", () => {
903
1161
  assertParse("logicalAndExpression", "true && false", [
904
1162
  ops.logicalAnd,
905
1163
  [markers.traverse, [markers.reference, "true"]],
906
- [ops.lambda, [], [markers.traverse, [markers.reference, "false"]]],
1164
+ [ops.lambda, 0, [], [markers.traverse, [markers.reference, "false"]]],
907
1165
  ]);
908
1166
  });
909
1167
 
@@ -916,13 +1174,13 @@ Body`,
916
1174
  assertParse("logicalOrExpression", "false || false || true", [
917
1175
  ops.logicalOr,
918
1176
  [markers.traverse, [markers.reference, "false"]],
919
- [ops.lambda, [], [markers.traverse, [markers.reference, "false"]]],
920
- [ops.lambda, [], [markers.traverse, [markers.reference, "true"]]],
1177
+ [ops.lambda, 0, [], [markers.traverse, [markers.reference, "false"]]],
1178
+ [ops.lambda, 0, [], [markers.traverse, [markers.reference, "true"]]],
921
1179
  ]);
922
1180
  assertParse("logicalOrExpression", "1 || 2 && 0", [
923
1181
  ops.logicalOr,
924
1182
  [ops.literal, 1],
925
- [ops.lambda, [], [ops.logicalAnd, [ops.literal, 2], [ops.literal, 0]]],
1183
+ [ops.lambda, 0, [], [ops.logicalAnd, [ops.literal, 2], [ops.literal, 0]]],
926
1184
  ]);
927
1185
  });
928
1186
 
@@ -969,20 +1227,34 @@ Body`,
969
1227
  assertParse("nullishCoalescingExpression", "a ?? b", [
970
1228
  ops.nullishCoalescing,
971
1229
  [markers.traverse, [markers.reference, "a"]],
972
- [ops.lambda, [], [markers.traverse, [markers.reference, "b"]]],
1230
+ [ops.lambda, 0, [], [markers.traverse, [markers.reference, "b"]]],
973
1231
  ]);
974
1232
  assertParse("nullishCoalescingExpression", "a ?? b ?? c", [
975
1233
  ops.nullishCoalescing,
976
1234
  [markers.traverse, [markers.reference, "a"]],
977
- [ops.lambda, [], [markers.traverse, [markers.reference, "b"]]],
978
- [ops.lambda, [], [markers.traverse, [markers.reference, "c"]]],
1235
+ [ops.lambda, 0, [], [markers.traverse, [markers.reference, "b"]]],
1236
+ [ops.lambda, 0, [], [markers.traverse, [markers.reference, "c"]]],
979
1237
  ]);
980
1238
  });
981
1239
 
982
- test("numericLiteral", () => {
983
- assertParse("numericLiteral", "123", [ops.literal, 123]);
984
- assertParse("numericLiteral", ".5", [ops.literal, 0.5]);
985
- assertParse("numericLiteral", "123.45", [ops.literal, 123.45]);
1240
+ test("numberLiteral", () => {
1241
+ assertParse("numberLiteral", "123", [ops.literal, 123]);
1242
+ });
1243
+
1244
+ test("number", () => {
1245
+ assertParse("number", "123", 123, undefined, false);
1246
+ assertParse("number", ".5", 0.5, undefined, false);
1247
+ assertParse("number", "123.45", 123.45, undefined, false);
1248
+ assertParse("number", "123_456", 123456, undefined, false);
1249
+ assertParse("number", "0e-5", 0e-5, undefined, false);
1250
+ assertParse("number", "175e-2", 175e-2, undefined, false);
1251
+ assertParse("number", "1e-3", 1e-3, undefined, false);
1252
+ assertParse("number", "123n", 123n, undefined, false);
1253
+ assertParse("number", "0b1010", 0b1010, undefined, false);
1254
+ assertParse("number", "0b100_100", 0b100100, undefined, false);
1255
+ assertParse("number", "0o755", 0o755, undefined, false);
1256
+ assertParse("number", "0x1A3F", 0x1a3f, undefined, false);
1257
+ assertParse("number", "0x1a_3f", 0x1a3f, undefined, false);
986
1258
  });
987
1259
 
988
1260
  describe("objectLiteral", () => {
@@ -1166,7 +1438,8 @@ Body`,
1166
1438
  "a",
1167
1439
  [
1168
1440
  ops.lambda,
1169
- [[ops.literal, "a"]],
1441
+ 1,
1442
+ [["a", [[ops.params, 0], 0]]],
1170
1443
  [markers.traverse, [markers.reference, "a"]],
1171
1444
  ],
1172
1445
  ]);
@@ -1463,12 +1736,14 @@ Body`,
1463
1736
  test("shorthandFunction", () => {
1464
1737
  assertParse("shorthandFunction", "=message", [
1465
1738
  ops.lambda,
1466
- [[ops.literal, "_"]],
1739
+ 1,
1740
+ [["_", [[ops.params, 0], 0]]],
1467
1741
  [markers.traverse, [markers.reference, "message"]],
1468
1742
  ]);
1469
1743
  assertParse("shorthandFunction", "=`Hello, ${name}.`", [
1470
1744
  ops.lambda,
1471
- [[ops.literal, "_"]],
1745
+ 1,
1746
+ [["_", [[ops.params, 0], 0]]],
1472
1747
  [
1473
1748
  ops.templateText,
1474
1749
  [ops.literal, ["Hello, ", "."]],
@@ -1477,7 +1752,8 @@ Body`,
1477
1752
  ]);
1478
1753
  assertParse("shorthandFunction", "=indent`hello`", [
1479
1754
  ops.lambda,
1480
- [[ops.literal, "_"]],
1755
+ 1,
1756
+ [["_", [[ops.params, 0], 0]]],
1481
1757
  [
1482
1758
  [markers.traverse, [markers.reference, "indent"]],
1483
1759
  [ops.literal, ["hello"]],
@@ -1510,6 +1786,7 @@ Body`,
1510
1786
  assertParse("stringLiteral", `"foo\\"s bar"`, [ops.literal, `foo"s bar`]);
1511
1787
  assertParse("stringLiteral", `'bar\\'s baz'`, [ops.literal, `bar's baz`]);
1512
1788
  assertParse("stringLiteral", `«string»`, [ops.literal, "string"]);
1789
+ assertParse("stringLiteral", `»string«`, [ops.literal, "string"]);
1513
1790
  assertParse("stringLiteral", `"\\0\\b\\f\\n\\r\\t\\v"`, [
1514
1791
  ops.literal,
1515
1792
  "\0\b\f\n\r\t\v",
@@ -1531,7 +1808,8 @@ Body`,
1531
1808
  test("templateDocument with no front matter", () => {
1532
1809
  assertParse("templateDocument", "Hello, world!", [
1533
1810
  ops.lambda,
1534
- [[ops.literal, "_"]],
1811
+ 1,
1812
+ [["_", [[ops.params, 0], 0]]],
1535
1813
  [ops.templateIndent, [ops.literal, ["Hello, world!"]]],
1536
1814
  ]);
1537
1815
  });
@@ -1578,32 +1856,6 @@ Body text`,
1578
1856
  );
1579
1857
  });
1580
1858
 
1581
- test.skip("templateDocument with Origami front matter", () => {
1582
- assertParse(
1583
- "templateDocument",
1584
- `---
1585
- {
1586
- title: "Title"
1587
- _body: _template()
1588
- }
1589
- ---
1590
- <h1>\${ title }</h1>
1591
- `,
1592
- [
1593
- ops.object,
1594
- ["title", [ops.literal, "Title"]],
1595
- [
1596
- "_body",
1597
- [
1598
- ops.templateIndent,
1599
- [ops.literal, ["<h1>", "</h1>\n"]],
1600
- [markers.traverse, [markers.reference, "title"]],
1601
- ],
1602
- ],
1603
- ]
1604
- );
1605
- });
1606
-
1607
1859
  test("templateLiteral", () => {
1608
1860
  assertParse("templateLiteral", "`Hello, world.`", [
1609
1861
  ops.templateText,
@@ -1631,7 +1883,8 @@ Body text`,
1631
1883
  [markers.traverse, [markers.reference, "people"]],
1632
1884
  [
1633
1885
  ops.lambda,
1634
- [[ops.literal, "_"]],
1886
+ 1,
1887
+ [["_", [[ops.params, 0], 0]]],
1635
1888
  [
1636
1889
  ops.templateText,
1637
1890
  [ops.literal, ["", ""]],