@weborigami/language 0.6.8 → 0.6.10

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 +13 -13
  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 +1 -1
  14. package/src/project/jsGlobals.js +3 -3
  15. package/src/protocols/package.js +3 -3
  16. package/src/runtime/asyncStorage.js +7 -0
  17. package/src/runtime/codeFragment.js +4 -3
  18. package/src/runtime/errors.js +82 -129
  19. package/src/runtime/evaluate.js +8 -77
  20. package/src/runtime/execute.js +82 -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 +9 -6
  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 +24 -19
  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 +38 -31
  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 +4 -4
  38. package/test/runtime/ops.test.js +36 -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,13 @@ 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
 
22
23
  test("ops.array creates an array", async () => {
23
24
  const code = createCode([ops.array, 1, 2, 3]);
24
- const result = await evaluate(code);
25
+ const result = await execute(code);
25
26
  assert.deepEqual(result, [1, 2, 3]);
26
27
  });
27
28
 
@@ -44,25 +45,10 @@ describe("ops", () => {
44
45
 
45
46
  test("ops.comma returns the last value", async () => {
46
47
  const code = createCode([ops.comma, 1, 2, 3]);
47
- const result = await evaluate(code);
48
+ const result = await execute(code);
48
49
  assert.strictEqual(result, 3);
49
50
  });
50
51
 
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
52
  test("ops.conditional", async () => {
67
53
  assert.strictEqual(await ops.conditional(true, trueFn, falseFn), true);
68
54
  assert.strictEqual(await ops.conditional(true, falseFn, trueFn), false);
@@ -77,6 +63,21 @@ describe("ops", () => {
77
63
  assert.equal(await ops.construct(String, "hello"), "hello");
78
64
  });
79
65
 
66
+ test("ops.deepText concatenates tree value text", async () => {
67
+ const container = {
68
+ name: "world",
69
+ };
70
+ const code = createCode([
71
+ ops.deepText,
72
+ "Hello, ",
73
+ [[ops.scope, container], "name"],
74
+ ".",
75
+ ]);
76
+
77
+ const result = await execute(code);
78
+ assert.strictEqual(result, "Hello, world.");
79
+ });
80
+
80
81
  test("ops.division divides two numbers", async () => {
81
82
  assert.strictEqual(ops.division(12, 2), 6);
82
83
  assert.strictEqual(ops.division(3, 2), 1.5);
@@ -117,9 +118,9 @@ describe("ops", () => {
117
118
  [ops.literal, "count"],
118
119
  ],
119
120
  ]);
120
- const result = await evaluate(code);
121
+ const result = await execute(code);
121
122
  assert.strictEqual(result, 1);
122
- const result2 = await evaluate(code);
123
+ const result2 = await execute(code);
123
124
  assert.strictEqual(result2, 1);
124
125
  });
125
126
 
@@ -183,7 +184,7 @@ describe("ops", () => {
183
184
  b: {},
184
185
  },
185
186
  },
186
- { deep: true }
187
+ { deep: true },
187
188
  );
188
189
  const b = await Tree.traverse(tree, "a", "b");
189
190
  assert.equal(await ops.inherited(2, { object: b }), tree);
@@ -201,7 +202,7 @@ describe("ops", () => {
201
202
 
202
203
  test("ops.lambda defines a function with no inputs", async () => {
203
204
  const code = createCode([ops.lambda, 0, [], [ops.literal, "result"]]);
204
- const fn = await evaluate(code);
205
+ const fn = await execute(code);
205
206
  assert.equal(fn.length, 0);
206
207
  const result = await fn();
207
208
  assert.strictEqual(result, "result");
@@ -219,7 +220,7 @@ describe("ops", () => {
219
220
  [[ops.scope, container], "message"],
220
221
  ]);
221
222
 
222
- const fn = await evaluate(code);
223
+ const fn = await execute(code);
223
224
  assert.equal(fn.length, 1);
224
225
  const result = await fn();
225
226
  assert.strictEqual(result, "Hello");
@@ -233,9 +234,9 @@ describe("ops", () => {
233
234
  ["a", [[ops.params, 0], 0]],
234
235
  ["b", [[ops.params, 0], 1]],
235
236
  ],
236
- [ops.concat, [[ops.params, 0], "b"], [[ops.params, 0], "a"]],
237
+ [ops.deepText, [[ops.params, 0], "b"], [[ops.params, 0], "a"]],
237
238
  ]);
238
- const fn = await evaluate(code);
239
+ const fn = await execute(code);
239
240
  assert.equal(fn.length, 2);
240
241
  const result = await fn("x", "y");
241
242
  assert.strictEqual(result, "yx");
@@ -311,7 +312,7 @@ describe("ops", () => {
311
312
  ],
312
313
  "_result",
313
314
  ]);
314
- const result = await evaluate(code);
315
+ const result = await execute(code);
315
316
  assert.deepEqual(await Tree.plain(result), { a: 1, b: 2, c: 1 });
316
317
  });
317
318
 
@@ -335,15 +336,15 @@ describe("ops", () => {
335
336
  test("ops.optional", async () => {
336
337
  assert.equal(
337
338
  ops.optional(null, (x) => x.a),
338
- undefined
339
+ undefined,
339
340
  );
340
341
  assert.equal(
341
342
  ops.optional(undefined, (x) => x.a),
342
- undefined
343
+ undefined,
343
344
  );
344
345
  assert.equal(
345
346
  ops.optional({ a: 1 }, (x) => x.a),
346
- 1
347
+ 1,
347
348
  );
348
349
  });
349
350
 
@@ -383,7 +384,7 @@ describe("ops", () => {
383
384
  ["world", [[[ops.scope, container], "upper"], "world"]],
384
385
  ]);
385
386
 
386
- const result = await evaluate(code);
387
+ const result = await execute(code);
387
388
  assert.strictEqual(result.hello, "HELLO");
388
389
  assert.strictEqual(result.world, "WORLD");
389
390
  });
@@ -398,7 +399,7 @@ describe("ops", () => {
398
399
  1,
399
400
  [[[ops.scope, container], "upper"], "world"],
400
401
  ]);
401
- const result = await evaluate(code);
402
+ const result = await execute(code);
402
403
  assert.deepEqual(result, ["Hello", 1, "WORLD"]);
403
404
  });
404
405
 
@@ -407,7 +408,7 @@ describe("ops", () => {
407
408
  const frame1 = { a: 1 };
408
409
  const frame2 = { b: 2 };
409
410
  const stack = [frame1, frame2];
410
- const result = await evaluate(code, { stack });
411
+ const result = await execute(code, { stack });
411
412
  assert.strictEqual(result, frame1);
412
413
  });
413
414
 
@@ -434,7 +435,7 @@ describe("ops", () => {
434
435
  },
435
436
  c: 1,
436
437
  },
437
- { deep: true }
438
+ { deep: true },
438
439
  );
439
440
  const a = await tree.get("a");
440
441
  const b = await a.get("b");
@@ -481,7 +482,7 @@ describe("ops", () => {
481
482
  assert.strictEqual(ops.typeOf(undefined), "undefined");
482
483
  assert.strictEqual(
483
484
  ops.typeOf(() => null),
484
- "function"
485
+ "function",
485
486
  );
486
487
  });
487
488
 
@@ -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", () => {