@weborigami/language 0.6.9 → 0.6.11

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.
Files changed (39) hide show
  1. package/index.ts +19 -4
  2. package/main.js +5 -2
  3. package/package.json +2 -2
  4. package/src/compiler/compile.js +11 -3
  5. package/src/compiler/origami.pegjs +4 -2
  6. package/src/compiler/parse.js +77 -68
  7. package/src/compiler/parserHelpers.js +16 -17
  8. package/src/handlers/getPackedPath.js +17 -0
  9. package/src/handlers/jpeg_handler.js +5 -0
  10. package/src/handlers/js_handler.js +3 -3
  11. package/src/handlers/json_handler.js +3 -1
  12. package/src/handlers/tsv_handler.js +1 -1
  13. package/src/handlers/yaml_handler.js +9 -3
  14. package/src/project/jsGlobals.js +3 -12
  15. package/src/protocols/package.js +20 -11
  16. package/src/runtime/asyncStorage.js +7 -0
  17. package/src/runtime/codeFragment.js +4 -3
  18. package/src/runtime/errors.js +86 -128
  19. package/src/runtime/evaluate.js +8 -77
  20. package/src/runtime/execute.js +85 -0
  21. package/src/runtime/explainReferenceError.js +248 -0
  22. package/src/runtime/explainTraverseError.js +77 -0
  23. package/src/runtime/expressionFunction.js +8 -7
  24. package/src/runtime/expressionObject.js +4 -3
  25. package/src/runtime/handleExtension.js +22 -8
  26. package/src/runtime/internal.js +1 -1
  27. package/src/runtime/interop.js +15 -0
  28. package/src/runtime/ops.js +51 -21
  29. package/src/runtime/symbols.js +0 -1
  30. package/src/runtime/typos.js +22 -3
  31. package/test/compiler/compile.test.js +7 -103
  32. package/test/compiler/parse.test.js +42 -39
  33. package/test/project/fixtures/withPackageJson/subfolder/README.md +1 -0
  34. package/test/runtime/errors.test.js +296 -0
  35. package/test/runtime/evaluate.test.js +110 -34
  36. package/test/runtime/execute.test.js +41 -0
  37. package/test/runtime/expressionObject.test.js +3 -3
  38. package/test/runtime/ops.test.js +42 -35
  39. package/test/runtime/typos.test.js +2 -0
@@ -2,7 +2,8 @@ import { ObjectMap, Tree } from "@weborigami/async-tree";
2
2
  import assert from "node:assert";
3
3
  import { describe, test } from "node:test";
4
4
 
5
- import { evaluate, ops } from "../../src/runtime/internal.js";
5
+ import execute from "../../src/runtime/execute.js";
6
+ import { ops } from "../../src/runtime/internal.js";
6
7
  import { createCode } from "../compiler/codeHelpers.js";
7
8
 
8
9
  describe("ops", () => {
@@ -15,13 +16,19 @@ describe("ops", () => {
15
16
  assert.strictEqual(ops.addition("hello ", "everyone"), "hello everyone");
16
17
  assert.strictEqual(
17
18
  ops.addition("2001", ": A Space Odyssey"),
18
- "2001: A Space Odyssey"
19
+ "2001: A Space Odyssey",
19
20
  );
20
21
  });
21
22
 
23
+ test("ops.apply applies a function to arguments", async () => {
24
+ const code = createCode([ops.apply, ops.addition, [ops.array, 1, 2]]);
25
+ const result = await execute(code);
26
+ assert.strictEqual(result, 3);
27
+ });
28
+
22
29
  test("ops.array creates an array", async () => {
23
30
  const code = createCode([ops.array, 1, 2, 3]);
24
- const result = await evaluate(code);
31
+ const result = await execute(code);
25
32
  assert.deepEqual(result, [1, 2, 3]);
26
33
  });
27
34
 
@@ -44,25 +51,10 @@ describe("ops", () => {
44
51
 
45
52
  test("ops.comma returns the last value", async () => {
46
53
  const code = createCode([ops.comma, 1, 2, 3]);
47
- const result = await evaluate(code);
54
+ const result = await execute(code);
48
55
  assert.strictEqual(result, 3);
49
56
  });
50
57
 
51
- test("ops.concat concatenates tree value text", async () => {
52
- const container = {
53
- name: "world",
54
- };
55
- const code = createCode([
56
- ops.concat,
57
- "Hello, ",
58
- [[ops.scope, container], "name"],
59
- ".",
60
- ]);
61
-
62
- const result = await evaluate(code);
63
- assert.strictEqual(result, "Hello, world.");
64
- });
65
-
66
58
  test("ops.conditional", async () => {
67
59
  assert.strictEqual(await ops.conditional(true, trueFn, falseFn), true);
68
60
  assert.strictEqual(await ops.conditional(true, falseFn, trueFn), false);
@@ -77,6 +69,21 @@ describe("ops", () => {
77
69
  assert.equal(await ops.construct(String, "hello"), "hello");
78
70
  });
79
71
 
72
+ test("ops.deepText concatenates tree value text", async () => {
73
+ const container = {
74
+ name: "world",
75
+ };
76
+ const code = createCode([
77
+ ops.deepText,
78
+ "Hello, ",
79
+ [[ops.scope, container], "name"],
80
+ ".",
81
+ ]);
82
+
83
+ const result = await execute(code);
84
+ assert.strictEqual(result, "Hello, world.");
85
+ });
86
+
80
87
  test("ops.division divides two numbers", async () => {
81
88
  assert.strictEqual(ops.division(12, 2), 6);
82
89
  assert.strictEqual(ops.division(3, 2), 1.5);
@@ -117,9 +124,9 @@ describe("ops", () => {
117
124
  [ops.literal, "count"],
118
125
  ],
119
126
  ]);
120
- const result = await evaluate(code);
127
+ const result = await execute(code);
121
128
  assert.strictEqual(result, 1);
122
- const result2 = await evaluate(code);
129
+ const result2 = await execute(code);
123
130
  assert.strictEqual(result2, 1);
124
131
  });
125
132
 
@@ -183,7 +190,7 @@ describe("ops", () => {
183
190
  b: {},
184
191
  },
185
192
  },
186
- { deep: true }
193
+ { deep: true },
187
194
  );
188
195
  const b = await Tree.traverse(tree, "a", "b");
189
196
  assert.equal(await ops.inherited(2, { object: b }), tree);
@@ -201,7 +208,7 @@ describe("ops", () => {
201
208
 
202
209
  test("ops.lambda defines a function with no inputs", async () => {
203
210
  const code = createCode([ops.lambda, 0, [], [ops.literal, "result"]]);
204
- const fn = await evaluate(code);
211
+ const fn = await execute(code);
205
212
  assert.equal(fn.length, 0);
206
213
  const result = await fn();
207
214
  assert.strictEqual(result, "result");
@@ -219,7 +226,7 @@ describe("ops", () => {
219
226
  [[ops.scope, container], "message"],
220
227
  ]);
221
228
 
222
- const fn = await evaluate(code);
229
+ const fn = await execute(code);
223
230
  assert.equal(fn.length, 1);
224
231
  const result = await fn();
225
232
  assert.strictEqual(result, "Hello");
@@ -233,9 +240,9 @@ describe("ops", () => {
233
240
  ["a", [[ops.params, 0], 0]],
234
241
  ["b", [[ops.params, 0], 1]],
235
242
  ],
236
- [ops.concat, [[ops.params, 0], "b"], [[ops.params, 0], "a"]],
243
+ [ops.deepText, [[ops.params, 0], "b"], [[ops.params, 0], "a"]],
237
244
  ]);
238
- const fn = await evaluate(code);
245
+ const fn = await execute(code);
239
246
  assert.equal(fn.length, 2);
240
247
  const result = await fn("x", "y");
241
248
  assert.strictEqual(result, "yx");
@@ -311,7 +318,7 @@ describe("ops", () => {
311
318
  ],
312
319
  "_result",
313
320
  ]);
314
- const result = await evaluate(code);
321
+ const result = await execute(code);
315
322
  assert.deepEqual(await Tree.plain(result), { a: 1, b: 2, c: 1 });
316
323
  });
317
324
 
@@ -335,15 +342,15 @@ describe("ops", () => {
335
342
  test("ops.optional", async () => {
336
343
  assert.equal(
337
344
  ops.optional(null, (x) => x.a),
338
- undefined
345
+ undefined,
339
346
  );
340
347
  assert.equal(
341
348
  ops.optional(undefined, (x) => x.a),
342
- undefined
349
+ undefined,
343
350
  );
344
351
  assert.equal(
345
352
  ops.optional({ a: 1 }, (x) => x.a),
346
- 1
353
+ 1,
347
354
  );
348
355
  });
349
356
 
@@ -383,7 +390,7 @@ describe("ops", () => {
383
390
  ["world", [[[ops.scope, container], "upper"], "world"]],
384
391
  ]);
385
392
 
386
- const result = await evaluate(code);
393
+ const result = await execute(code);
387
394
  assert.strictEqual(result.hello, "HELLO");
388
395
  assert.strictEqual(result.world, "WORLD");
389
396
  });
@@ -398,7 +405,7 @@ describe("ops", () => {
398
405
  1,
399
406
  [[[ops.scope, container], "upper"], "world"],
400
407
  ]);
401
- const result = await evaluate(code);
408
+ const result = await execute(code);
402
409
  assert.deepEqual(result, ["Hello", 1, "WORLD"]);
403
410
  });
404
411
 
@@ -407,7 +414,7 @@ describe("ops", () => {
407
414
  const frame1 = { a: 1 };
408
415
  const frame2 = { b: 2 };
409
416
  const stack = [frame1, frame2];
410
- const result = await evaluate(code, { stack });
417
+ const result = await execute(code, { stack });
411
418
  assert.strictEqual(result, frame1);
412
419
  });
413
420
 
@@ -434,7 +441,7 @@ describe("ops", () => {
434
441
  },
435
442
  c: 1,
436
443
  },
437
- { deep: true }
444
+ { deep: true },
438
445
  );
439
446
  const a = await tree.get("a");
440
447
  const b = await a.get("b");
@@ -481,7 +488,7 @@ describe("ops", () => {
481
488
  assert.strictEqual(ops.typeOf(undefined), "undefined");
482
489
  assert.strictEqual(
483
490
  ops.typeOf(() => null),
484
- "function"
491
+ "function",
485
492
  );
486
493
  });
487
494
 
@@ -13,6 +13,8 @@ describe("typos", () => {
13
13
  assert(isTypo("cat", "act")); // transposition
14
14
  assert(!isTypo("cat", "dog")); // more than 1 edit
15
15
  assert(!isTypo("a", "b")); // single character
16
+ assert(isTypo("cat", "CAT")); // differ only by case
17
+ assert(isTypo("café", "cafe")); // differ only by accents
16
18
  });
17
19
 
18
20
  test("typos", () => {