@weborigami/language 0.5.4 → 0.5.6
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/index.ts +16 -6
- package/main.js +9 -4
- package/package.json +4 -3
- package/src/compiler/compile.js +10 -4
- package/src/compiler/optimize.js +115 -97
- package/src/compiler/origami.pegjs +1 -4
- package/src/compiler/parse.js +568 -588
- package/src/compiler/parserHelpers.js +3 -3
- package/src/handlers/css_handler.js +7 -0
- package/src/handlers/csv_handler.js +129 -0
- package/src/handlers/handlers.js +33 -0
- package/src/handlers/htm_handler.js +2 -0
- package/src/handlers/html_handler.js +7 -0
- package/src/handlers/jpeg_handler.js +62 -0
- package/src/handlers/jpg_handler.js +2 -0
- package/src/handlers/js_handler.js +51 -0
- package/src/handlers/json_handler.js +26 -0
- package/src/handlers/md_handler.js +7 -0
- package/src/handlers/mjs_handler.js +2 -0
- package/src/handlers/ori_handler.js +47 -0
- package/src/handlers/oridocument_handler.js +77 -0
- package/src/handlers/parseFrontMatter.js +16 -0
- package/src/handlers/ts_handler.js +1 -0
- package/src/handlers/txt_handler.js +108 -0
- package/src/handlers/wasm_handler.js +15 -0
- package/src/handlers/xhtml_handler.js +2 -0
- package/src/handlers/yaml_handler.js +33 -0
- package/src/handlers/yml_handler.js +2 -0
- package/src/project/builtins.js +5 -0
- package/src/project/coreGlobals.js +17 -0
- package/src/{runtime → project}/jsGlobals.js +3 -1
- package/src/project/projectConfig.js +36 -0
- package/src/project/projectGlobals.js +19 -0
- package/src/project/projectRoot.js +59 -0
- package/src/protocols/constructHref.js +20 -0
- package/src/protocols/constructSiteTree.js +26 -0
- package/src/protocols/explore.js +14 -0
- package/src/protocols/fetchAndHandleExtension.js +25 -0
- package/src/protocols/files.js +26 -0
- package/src/protocols/http.js +15 -0
- package/src/protocols/https.js +15 -0
- package/src/protocols/httpstree.js +14 -0
- package/src/protocols/httptree.js +14 -0
- package/src/protocols/node.js +13 -0
- package/src/protocols/package.js +67 -0
- package/src/protocols/protocolGlobals.js +12 -0
- package/src/protocols/protocols.js +8 -0
- package/src/runtime/EventTargetMixin.js +1 -1
- package/src/runtime/HandleExtensionsTransform.js +3 -12
- package/src/runtime/ImportModulesMixin.js +4 -10
- package/src/runtime/InvokeFunctionsTransform.js +1 -1
- package/src/runtime/errors.js +2 -2
- package/src/runtime/evaluate.js +15 -8
- package/src/runtime/expressionFunction.js +5 -7
- package/src/runtime/expressionObject.js +10 -20
- package/src/runtime/functionResultsMap.js +5 -12
- package/src/runtime/{handlers.js → handleExtension.js} +14 -12
- package/src/runtime/mergeTrees.js +2 -10
- package/src/runtime/ops.js +91 -106
- package/test/compiler/compile.test.js +20 -19
- package/test/compiler/optimize.test.js +60 -25
- package/test/compiler/parse.test.js +10 -10
- package/test/generator/oriEval.js +4 -5
- package/test/handlers/csv.handler.test.js +36 -0
- package/test/handlers/fixtures/add.wasm +0 -0
- package/test/handlers/fixtures/exif.jpeg +0 -0
- package/test/handlers/fixtures/frontMatter.md +5 -0
- package/test/handlers/fixtures/list.js +4 -0
- package/test/handlers/fixtures/multiple.js +4 -0
- package/test/handlers/fixtures/obj.js +3 -0
- package/test/handlers/fixtures/site.ori +5 -0
- package/test/handlers/fixtures/string.js +1 -0
- package/test/handlers/fixtures/tag.yaml +5 -0
- package/test/handlers/fixtures/test.ori +9 -0
- package/test/handlers/jpeg.handler.test.js +18 -0
- package/test/handlers/js.handler.test.js +46 -0
- package/test/handlers/json.handler.test.js +14 -0
- package/test/handlers/ori.handler.test.js +87 -0
- package/test/handlers/oridocument.handler.test.js +68 -0
- package/test/handlers/txt.handler.test.js +41 -0
- package/test/handlers/wasm.handler.test.js +20 -0
- package/test/handlers/yaml.handler.test.js +17 -0
- package/test/project/fixtures/withConfig/config.ori +4 -0
- package/test/project/fixtures/withConfig/subfolder/greet.js +1 -0
- package/test/project/fixtures/withPackageJson/package.json +0 -0
- package/test/project/jsGlobals.test.js +21 -0
- package/test/project/projectConfig.test.js +28 -0
- package/test/project/projectRoot.test.js +40 -0
- package/test/protocols/package.test.js +11 -0
- package/test/runtime/evaluate.test.js +26 -42
- package/test/runtime/expressionObject.test.js +16 -20
- package/test/runtime/functionResultsMap.test.js +5 -9
- package/test/runtime/{handlers.test.js → handleExtension.test.js} +4 -20
- package/test/runtime/jsGlobals.test.js +4 -6
- package/test/runtime/mergeTrees.test.js +2 -4
- package/test/runtime/ops.test.js +70 -72
- package/src/runtime/getHandlers.js +0 -10
package/test/runtime/ops.test.js
CHANGED
|
@@ -21,7 +21,7 @@ describe("ops", () => {
|
|
|
21
21
|
|
|
22
22
|
test("ops.array creates an array", async () => {
|
|
23
23
|
const code = createCode([ops.array, 1, 2, 3]);
|
|
24
|
-
const result = await evaluate
|
|
24
|
+
const result = await evaluate(code);
|
|
25
25
|
assert.deepEqual(result, [1, 2, 3]);
|
|
26
26
|
});
|
|
27
27
|
|
|
@@ -44,23 +44,22 @@ describe("ops", () => {
|
|
|
44
44
|
|
|
45
45
|
test("ops.comma returns the last value", async () => {
|
|
46
46
|
const code = createCode([ops.comma, 1, 2, 3]);
|
|
47
|
-
const result = await evaluate
|
|
47
|
+
const result = await evaluate(code);
|
|
48
48
|
assert.strictEqual(result, 3);
|
|
49
49
|
});
|
|
50
50
|
|
|
51
51
|
test("ops.concat concatenates tree value text", async () => {
|
|
52
|
-
const
|
|
52
|
+
const container = {
|
|
53
53
|
name: "world",
|
|
54
|
-
}
|
|
55
|
-
|
|
54
|
+
};
|
|
56
55
|
const code = createCode([
|
|
57
56
|
ops.concat,
|
|
58
57
|
"Hello, ",
|
|
59
|
-
[[ops.scope], "name"],
|
|
58
|
+
[[ops.scope, container], "name"],
|
|
60
59
|
".",
|
|
61
60
|
]);
|
|
62
61
|
|
|
63
|
-
const result = await evaluate
|
|
62
|
+
const result = await evaluate(code);
|
|
64
63
|
assert.strictEqual(result, "Hello, world.");
|
|
65
64
|
});
|
|
66
65
|
|
|
@@ -78,20 +77,6 @@ describe("ops", () => {
|
|
|
78
77
|
assert.equal(await ops.construct(String, "hello"), "hello");
|
|
79
78
|
});
|
|
80
79
|
|
|
81
|
-
test("ops.context", async () => {
|
|
82
|
-
const tree = new DeepObjectTree({
|
|
83
|
-
a: {
|
|
84
|
-
b: {
|
|
85
|
-
c: {},
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
});
|
|
89
|
-
const b = await Tree.traverse(tree, "a", "b");
|
|
90
|
-
const c = await b.get("c");
|
|
91
|
-
assert.equal(ops.context.call(c), c);
|
|
92
|
-
assert.equal(ops.context.call(c, 1), b);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
80
|
test("ops.division divides two numbers", async () => {
|
|
96
81
|
assert.strictEqual(ops.division(12, 2), 6);
|
|
97
82
|
assert.strictEqual(ops.division(3, 2), 1.5);
|
|
@@ -114,23 +99,27 @@ describe("ops", () => {
|
|
|
114
99
|
|
|
115
100
|
test("ops.cache evaluates code and cache its result", async () => {
|
|
116
101
|
let count = 0;
|
|
117
|
-
const
|
|
102
|
+
const container = {
|
|
118
103
|
group: {
|
|
119
104
|
get count() {
|
|
120
105
|
// Use promise to test async behavior
|
|
121
106
|
return Promise.resolve(++count);
|
|
122
107
|
},
|
|
123
108
|
},
|
|
124
|
-
}
|
|
109
|
+
};
|
|
125
110
|
const code = createCode([
|
|
126
111
|
ops.cache,
|
|
127
112
|
{},
|
|
128
113
|
"group/count",
|
|
129
|
-
[
|
|
114
|
+
[
|
|
115
|
+
[ops.scope, container],
|
|
116
|
+
[ops.literal, "group"],
|
|
117
|
+
[ops.literal, "count"],
|
|
118
|
+
],
|
|
130
119
|
]);
|
|
131
|
-
const result = await evaluate
|
|
120
|
+
const result = await evaluate(code);
|
|
132
121
|
assert.strictEqual(result, 1);
|
|
133
|
-
const result2 = await evaluate
|
|
122
|
+
const result2 = await evaluate(code);
|
|
134
123
|
assert.strictEqual(result2, 1);
|
|
135
124
|
});
|
|
136
125
|
|
|
@@ -166,22 +155,36 @@ describe("ops", () => {
|
|
|
166
155
|
assert(ops.greaterThanOrEqual("ab", "aa"));
|
|
167
156
|
});
|
|
168
157
|
|
|
158
|
+
test("ops.inherited walks up the object parent chain", async () => {
|
|
159
|
+
const tree = new DeepObjectTree({
|
|
160
|
+
a: {
|
|
161
|
+
b: {},
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
const b = await Tree.traverse(tree, "a", "b");
|
|
165
|
+
assert.equal(await ops.inherited(2, { object: b }), tree);
|
|
166
|
+
});
|
|
167
|
+
|
|
169
168
|
test("ops.lambda defines a function with no inputs", async () => {
|
|
170
169
|
const code = createCode([ops.lambda, [], [ops.literal, "result"]]);
|
|
171
|
-
const fn = await evaluate
|
|
172
|
-
const result = await fn
|
|
170
|
+
const fn = await evaluate(code);
|
|
171
|
+
const result = await fn();
|
|
173
172
|
assert.strictEqual(result, "result");
|
|
174
173
|
});
|
|
175
174
|
|
|
176
175
|
test("ops.lambda defines a function with underscore input", async () => {
|
|
177
|
-
const
|
|
176
|
+
const container = {
|
|
178
177
|
message: "Hello",
|
|
179
|
-
}
|
|
178
|
+
};
|
|
180
179
|
|
|
181
|
-
const code = createCode([
|
|
180
|
+
const code = createCode([
|
|
181
|
+
ops.lambda,
|
|
182
|
+
["_"],
|
|
183
|
+
[[ops.scope, container], "message"],
|
|
184
|
+
]);
|
|
182
185
|
|
|
183
|
-
const fn = await evaluate
|
|
184
|
-
const result = await fn
|
|
186
|
+
const fn = await evaluate(code);
|
|
187
|
+
const result = await fn();
|
|
185
188
|
assert.strictEqual(result, "Hello");
|
|
186
189
|
});
|
|
187
190
|
|
|
@@ -192,9 +195,9 @@ describe("ops", () => {
|
|
|
192
195
|
[ops.literal, "a"],
|
|
193
196
|
[ops.literal, "b"],
|
|
194
197
|
],
|
|
195
|
-
[ops.concat, [[ops.
|
|
198
|
+
[ops.concat, [[ops.params, 0], "b"], [[ops.params, 0], "a"]],
|
|
196
199
|
]);
|
|
197
|
-
const fn = await evaluate
|
|
200
|
+
const fn = await evaluate(code);
|
|
198
201
|
const result = await fn("x", "y");
|
|
199
202
|
assert.strictEqual(result, "yx");
|
|
200
203
|
});
|
|
@@ -249,27 +252,27 @@ describe("ops", () => {
|
|
|
249
252
|
// ...more
|
|
250
253
|
// c: a
|
|
251
254
|
// }
|
|
252
|
-
const
|
|
255
|
+
const container = {
|
|
253
256
|
more: { b: 2 },
|
|
254
|
-
}
|
|
257
|
+
};
|
|
255
258
|
const code = createCode([
|
|
256
259
|
[
|
|
257
260
|
ops.object,
|
|
258
261
|
["a", [ops.literal, 1]],
|
|
259
|
-
["c", [[ops.
|
|
262
|
+
["c", [[ops.inherited, 0], "a"]],
|
|
260
263
|
[
|
|
261
264
|
"_result",
|
|
262
265
|
[
|
|
263
266
|
ops.merge,
|
|
264
|
-
[ops.object, ["a", [ops.getter, [[ops.
|
|
265
|
-
[[ops.scope], "more"],
|
|
266
|
-
[ops.object, ["c", [ops.getter, [[ops.
|
|
267
|
+
[ops.object, ["a", [ops.getter, [[ops.inherited, 1], "a"]]]],
|
|
268
|
+
[[ops.scope, container], "more"],
|
|
269
|
+
[ops.object, ["c", [ops.getter, [[ops.inherited, 1], "c"]]]],
|
|
267
270
|
],
|
|
268
271
|
],
|
|
269
272
|
],
|
|
270
273
|
"_result",
|
|
271
274
|
]);
|
|
272
|
-
const result = await evaluate
|
|
275
|
+
const result = await evaluate(code);
|
|
273
276
|
assert.deepEqual(await Tree.plain(result), { a: 1, b: 2, c: 1 });
|
|
274
277
|
});
|
|
275
278
|
|
|
@@ -280,10 +283,10 @@ describe("ops", () => {
|
|
|
280
283
|
assert.strictEqual(ops.multiplication("foo", 2), NaN);
|
|
281
284
|
});
|
|
282
285
|
|
|
283
|
-
test("ops.optionalTraverse", async () => {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
});
|
|
286
|
+
// test("ops.optionalTraverse", async () => {
|
|
287
|
+
// assert.equal(await ops.optionalTraverse(null, "a"), undefined);
|
|
288
|
+
// assert.equal(await ops.optionalTraverse({ a: 1 }, "a"), 1);
|
|
289
|
+
// });
|
|
287
290
|
|
|
288
291
|
test("ops.notEqual", () => {
|
|
289
292
|
assert(!ops.notEqual(1, 1));
|
|
@@ -311,35 +314,44 @@ describe("ops", () => {
|
|
|
311
314
|
});
|
|
312
315
|
|
|
313
316
|
test("ops.object instantiates an object", async () => {
|
|
314
|
-
const
|
|
317
|
+
const container = {
|
|
315
318
|
upper: (s) => s.toUpperCase(),
|
|
316
|
-
}
|
|
319
|
+
};
|
|
317
320
|
|
|
318
321
|
const code = createCode([
|
|
319
322
|
ops.object,
|
|
320
|
-
["hello", [[[ops.scope], "upper"], "hello"]],
|
|
321
|
-
["world", [[[ops.scope], "upper"], "world"]],
|
|
323
|
+
["hello", [[[ops.scope, container], "upper"], "hello"]],
|
|
324
|
+
["world", [[[ops.scope, container], "upper"], "world"]],
|
|
322
325
|
]);
|
|
323
326
|
|
|
324
|
-
const result = await evaluate
|
|
327
|
+
const result = await evaluate(code);
|
|
325
328
|
assert.strictEqual(result.hello, "HELLO");
|
|
326
329
|
assert.strictEqual(result.world, "WORLD");
|
|
327
330
|
});
|
|
328
331
|
|
|
329
332
|
test("ops.object instantiates an array", async () => {
|
|
330
|
-
const
|
|
333
|
+
const container = {
|
|
331
334
|
upper: (s) => s.toUpperCase(),
|
|
332
|
-
}
|
|
335
|
+
};
|
|
333
336
|
const code = createCode([
|
|
334
337
|
ops.array,
|
|
335
338
|
"Hello",
|
|
336
339
|
1,
|
|
337
|
-
[[[ops.scope], "upper"], "world"],
|
|
340
|
+
[[[ops.scope, container], "upper"], "world"],
|
|
338
341
|
]);
|
|
339
|
-
const result = await evaluate
|
|
342
|
+
const result = await evaluate(code);
|
|
340
343
|
assert.deepEqual(result, ["Hello", 1, "WORLD"]);
|
|
341
344
|
});
|
|
342
345
|
|
|
346
|
+
test("ops.params returns a stack frame", async () => {
|
|
347
|
+
const code = createCode([ops.params, 1]);
|
|
348
|
+
const frame1 = { a: 1 };
|
|
349
|
+
const frame2 = { b: 2 };
|
|
350
|
+
const stack = [frame1, frame2];
|
|
351
|
+
const result = await evaluate(code, { stack });
|
|
352
|
+
assert.strictEqual(result, frame1);
|
|
353
|
+
});
|
|
354
|
+
|
|
343
355
|
test("ops.property returns a property if defined, otherwise traverses", async () => {
|
|
344
356
|
assert.equal(await ops.property({ a: 1 }, "a"), 1);
|
|
345
357
|
assert.equal(await ops.property({ a: 1 }, "b"), undefined);
|
|
@@ -355,30 +367,16 @@ describe("ops", () => {
|
|
|
355
367
|
});
|
|
356
368
|
|
|
357
369
|
describe("ops.scope", () => {
|
|
358
|
-
test("returns the scope of the
|
|
359
|
-
const tree = new DeepObjectTree({
|
|
360
|
-
a: {
|
|
361
|
-
b: {},
|
|
362
|
-
},
|
|
363
|
-
c: 1,
|
|
364
|
-
});
|
|
365
|
-
const a = await tree.get("a");
|
|
366
|
-
const b = await a.get("b");
|
|
367
|
-
const scope = await ops.scope.call(b);
|
|
368
|
-
assert.equal(await scope?.get("c"), 1);
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
test("accepts an optional context", async () => {
|
|
370
|
+
test("returns the scope of the given tree", async () => {
|
|
372
371
|
const tree = new DeepObjectTree({
|
|
373
372
|
a: {
|
|
374
373
|
b: {},
|
|
375
|
-
c: 0, // shouldn't get this
|
|
376
374
|
},
|
|
377
375
|
c: 1,
|
|
378
376
|
});
|
|
379
377
|
const a = await tree.get("a");
|
|
380
378
|
const b = await a.get("b");
|
|
381
|
-
const scope = await ops.scope
|
|
379
|
+
const scope = await ops.scope(b);
|
|
382
380
|
assert.equal(await scope?.get("c"), 1);
|
|
383
381
|
});
|
|
384
382
|
});
|
|
@@ -439,7 +437,7 @@ describe("ops", () => {
|
|
|
439
437
|
test("ops.unpack unpacks a value", async () => {
|
|
440
438
|
const fixture = new String("packed");
|
|
441
439
|
/** @type {any} */ (fixture).unpack = async () => "unpacked";
|
|
442
|
-
const result = await ops.unpack
|
|
440
|
+
const result = await ops.unpack(fixture);
|
|
443
441
|
assert.strictEqual(result, "unpacked");
|
|
444
442
|
});
|
|
445
443
|
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Tree } from "@weborigami/async-tree";
|
|
2
|
-
|
|
3
|
-
// Return the extension handlers for the given tree
|
|
4
|
-
export default function getHandlers(tree) {
|
|
5
|
-
if (!tree) {
|
|
6
|
-
return null;
|
|
7
|
-
}
|
|
8
|
-
const root = Tree.root(tree);
|
|
9
|
-
return /** @type {any} */ (root).handlers;
|
|
10
|
-
}
|