@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 +3 -3
- package/src/compiler/compile.js +18 -8
- package/src/runtime/ops.js +1 -1
- package/test/runtime/ops.test.js +6 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weborigami/language",
|
|
3
|
-
"version": "0.0.
|
|
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.
|
|
15
|
-
"@weborigami/types": "0.0.
|
|
14
|
+
"@weborigami/async-tree": "0.0.73",
|
|
15
|
+
"@weborigami/types": "0.0.73",
|
|
16
16
|
"watcher": "2.3.1"
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
package/src/compiler/compile.js
CHANGED
|
@@ -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,
|
|
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 =
|
|
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,
|
|
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
|
|
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
|
|
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,
|
|
89
|
+
export function templateDocument(source, options = {}) {
|
|
90
|
+
return compile(source, {
|
|
91
|
+
...options,
|
|
92
|
+
startRule: "templateDocument",
|
|
93
|
+
});
|
|
84
94
|
}
|
package/src/runtime/ops.js
CHANGED
package/test/runtime/ops.test.js
CHANGED
|
@@ -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({
|