@weborigami/language 0.0.72 → 0.0.73

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weborigami/language",
3
- "version": "0.0.72",
3
+ "version": "0.0.73",
4
4
  "description": "Web Origami expression language compiler and runtime",
5
5
  "type": "module",
6
6
  "main": "./main.js",
@@ -11,8 +11,8 @@
11
11
  "typescript": "5.6.2"
12
12
  },
13
13
  "dependencies": {
14
- "@weborigami/async-tree": "0.0.72",
15
- "@weborigami/types": "0.0.72",
14
+ "@weborigami/async-tree": "0.0.73",
15
+ "@weborigami/types": "0.0.73",
16
16
  "watcher": "2.3.1"
17
17
  },
18
18
  "scripts": {
@@ -3,7 +3,9 @@ import { createExpressionFunction } from "../runtime/expressionFunction.js";
3
3
  import { ops } from "../runtime/internal.js";
4
4
  import { parse } from "./parse.js";
5
5
 
6
- function compile(source, startRule) {
6
+ function compile(source, options) {
7
+ const { startRule } = options;
8
+ const scopeCaching = options.scopeCaching ?? true;
7
9
  if (typeof source === "string") {
8
10
  source = { text: source };
9
11
  }
@@ -12,20 +14,25 @@ function compile(source, startRule) {
12
14
  startRule,
13
15
  });
14
16
  const cache = {};
15
- const modified = cacheNonLocalScopeReferences(code, cache);
17
+ const modified = scopeCaching
18
+ ? cacheExternalScopeReferences(code, cache)
19
+ : code;
16
20
  // const modified = code;
17
21
  const fn = createExpressionFunction(modified);
18
22
  return fn;
19
23
  }
20
24
 
21
- export function expression(source) {
22
- return compile(source, "expression");
25
+ export function expression(source, options = {}) {
26
+ return compile(source, {
27
+ ...options,
28
+ startRule: "expression",
29
+ });
23
30
  }
24
31
 
25
32
  // Given code containing ops.scope calls, upgrade them to ops.cache calls unless
26
33
  // they refer to local variables: variables defined by object literals or lambda
27
34
  // parameters.
28
- export function cacheNonLocalScopeReferences(code, cache, locals = {}) {
35
+ export function cacheExternalScopeReferences(code, cache, locals = {}) {
29
36
  const [fn, ...args] = code;
30
37
 
31
38
  let additionalLocalNames;
@@ -67,7 +74,7 @@ export function cacheNonLocalScopeReferences(code, cache, locals = {}) {
67
74
  // be preferable to only descend into instructions. This would require
68
75
  // surrounding ops.lambda parameters with ops.literal, and ops.object
69
76
  // entries with ops.array.
70
- return cacheNonLocalScopeReferences(child, cache, updatedLocals);
77
+ return cacheExternalScopeReferences(child, cache, updatedLocals);
71
78
  } else {
72
79
  return child;
73
80
  }
@@ -79,6 +86,9 @@ export function cacheNonLocalScopeReferences(code, cache, locals = {}) {
79
86
  return modified;
80
87
  }
81
88
 
82
- export function templateDocument(source) {
83
- return compile(source, "templateDocument");
89
+ export function templateDocument(source, options = {}) {
90
+ return compile(source, {
91
+ ...options,
92
+ startRule: "templateDocument",
93
+ });
84
94
  }
@@ -39,7 +39,7 @@ function addOpLabel(op, label) {
39
39
  * @param {any[]} items
40
40
  */
41
41
  export async function array(...items) {
42
- return Array(...items);
42
+ return items;
43
43
  }
44
44
  addOpLabel(array, "«ops.array»");
45
45
 
@@ -5,6 +5,12 @@ import { describe, test } from "node:test";
5
5
  import { evaluate, ops } from "../../src/runtime/internal.js";
6
6
 
7
7
  describe("ops", () => {
8
+ test("ops.array creates an array", async () => {
9
+ const code = createCode([ops.array, 1, 2, 3]);
10
+ const result = await evaluate.call(null, code);
11
+ assert.deepEqual(result, [1, 2, 3]);
12
+ });
13
+
8
14
  test("ops.cache looks up a value in scope and memoizes it", async () => {
9
15
  let count = 0;
10
16
  const tree = new ObjectTree({