@weborigami/language 0.0.57 → 0.0.59
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/main.js +0 -1
- package/package.json +6 -6
- package/src/compiler/origami.pegjs +12 -3
- package/src/compiler/parse.js +136 -86
- package/src/runtime/ops.js +2 -2
- package/test/compiler/parse.test.js +7 -0
- package/test/runtime/mergeTrees.test.js +5 -1
- package/src/runtime/concatTreeValues.js +0 -59
- package/test/runtime/concatTreeValues.test.js +0 -33
package/main.js
CHANGED
|
@@ -13,7 +13,6 @@ export { default as OrigamiTree } from "./src/runtime/OrigamiTree.js";
|
|
|
13
13
|
export { default as Scope } from "./src/runtime/Scope.js";
|
|
14
14
|
export { default as TreeEvent } from "./src/runtime/TreeEvent.js";
|
|
15
15
|
export { default as WatchFilesMixin } from "./src/runtime/WatchFilesMixin.js";
|
|
16
|
-
export { default as concatTreeValues } from "./src/runtime/concatTreeValues.js";
|
|
17
16
|
export { default as evaluate } from "./src/runtime/evaluate.js";
|
|
18
17
|
export * as expressionFunction from "./src/runtime/expressionFunction.js";
|
|
19
18
|
export { default as extname } from "./src/runtime/extname.js";
|
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weborigami/language",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.59",
|
|
4
4
|
"description": "Web Origami expression language compiler and runtime",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./main.js",
|
|
7
7
|
"types": "./index.ts",
|
|
8
8
|
"devDependencies": {
|
|
9
|
-
"@types/node": "20.
|
|
10
|
-
"peggy": "4.0.
|
|
11
|
-
"typescript": "5.
|
|
9
|
+
"@types/node": "20.14.9",
|
|
10
|
+
"peggy": "4.0.3",
|
|
11
|
+
"typescript": "5.5.3"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@weborigami/async-tree": "0.0.
|
|
15
|
-
"@weborigami/types": "0.0.
|
|
14
|
+
"@weborigami/async-tree": "0.0.59",
|
|
15
|
+
"@weborigami/types": "0.0.59",
|
|
16
16
|
"watcher": "2.3.1"
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
|
@@ -160,7 +160,9 @@ identifierOrString
|
|
|
160
160
|
/ string
|
|
161
161
|
|
|
162
162
|
implicitParensArgs "arguments with implicit parentheses"
|
|
163
|
-
|
|
163
|
+
// Implicit parens args are a separate list of `step`, not `expr`, because
|
|
164
|
+
// they can't contain a pipeline.
|
|
165
|
+
= inlineSpace+ @step|1.., separator| separator?
|
|
164
166
|
|
|
165
167
|
inlineSpace
|
|
166
168
|
= [ \t]
|
|
@@ -244,7 +246,14 @@ path "slash-separated path"
|
|
|
244
246
|
|
|
245
247
|
// A single key in a slash-separated path
|
|
246
248
|
pathKey "path element"
|
|
247
|
-
=
|
|
249
|
+
= chars:pathKeyChar* { return chars.join(""); }
|
|
250
|
+
|
|
251
|
+
// A single character in a slash-separated path.
|
|
252
|
+
pathKeyChar
|
|
253
|
+
// This is more permissive than an identifier. It allows some characters like
|
|
254
|
+
// brackets or quotes that are not allowed in identifiers.
|
|
255
|
+
= [^(){}\[\],:/\\ \t\n\r]
|
|
256
|
+
/ escapedChar
|
|
248
257
|
|
|
249
258
|
// Parse a protocol call like `fn://foo/bar`.
|
|
250
259
|
// There can be zero, one, or two slashes after the colon.
|
|
@@ -364,7 +373,7 @@ templateLiteralText
|
|
|
364
373
|
|
|
365
374
|
// A substitution in a template literal: `${x}`
|
|
366
375
|
templateSubstitution "template substitution"
|
|
367
|
-
= "${" @
|
|
376
|
+
= "${" __ @expr __ "}"
|
|
368
377
|
|
|
369
378
|
textChar
|
|
370
379
|
= escapedChar / .
|
package/src/compiler/parse.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @generated by Peggy 4.0.
|
|
1
|
+
// @generated by Peggy 4.0.3.
|
|
2
2
|
//
|
|
3
3
|
// https://peggyjs.org/
|
|
4
4
|
|
|
@@ -193,7 +193,7 @@ function peg$parse(input, options) {
|
|
|
193
193
|
var peg$FAILED = {};
|
|
194
194
|
var peg$source = options.grammarSource;
|
|
195
195
|
|
|
196
|
-
var peg$startRuleFunctions = { __: peg$parse__, absoluteFilePath: peg$parseabsoluteFilePath, args: peg$parseargs, array: peg$parsearray, arrayEntries: peg$parsearrayEntries, arrayEntry: peg$parsearrayEntry, callTarget: peg$parsecallTarget, closingBrace: peg$parseclosingBrace, closingBracket: peg$parseclosingBracket, closingParen: peg$parseclosingParen, comment: peg$parsecomment, digits: peg$parsedigits, doubleArrow: peg$parsedoubleArrow, doubleQuoteString: peg$parsedoubleQuoteString, doubleQuoteStringChar: peg$parsedoubleQuoteStringChar, ellipsis: peg$parseellipsis, escapedChar: peg$parseescapedChar, expr: peg$parseexpr, expression: peg$parseexpression, float: peg$parsefloat, functionComposition: peg$parsefunctionComposition, group: peg$parsegroup, host: peg$parsehost, identifier: peg$parseidentifier, identifierChar: peg$parseidentifierChar, identifierList: peg$parseidentifierList, identifierOrString: peg$parseidentifierOrString, implicitParensArgs: peg$parseimplicitParensArgs, inlineSpace: peg$parseinlineSpace, integer: peg$parseinteger, lambda: peg$parselambda, leadingSlashPath: peg$parseleadingSlashPath, list: peg$parselist, multiLineComment: peg$parsemultiLineComment, newLine: peg$parsenewLine, number: peg$parsenumber, object: peg$parseobject, objectEntries: peg$parseobjectEntries, objectEntry: peg$parseobjectEntry, objectProperty: peg$parseobjectProperty, parameterizedLambda: peg$parseparameterizedLambda, parensArgs: peg$parseparensArgs, pipeline: peg$parsepipeline, path: peg$parsepath, pathKey: peg$parsepathKey, protocolCall: peg$parseprotocolCall, protocol: peg$parseprotocol, reservedProtocol: peg$parsereservedProtocol, scopeReference: peg$parsescopeReference, separator: peg$parseseparator, shebang: peg$parseshebang, sign: peg$parsesign, singleArrow: peg$parsesingleArrow, singleLineComment: peg$parsesingleLineComment, singleQuoteString: peg$parsesingleQuoteString, singleQuoteStringChar: peg$parsesingleQuoteStringChar, spread: peg$parsespread, step: peg$parsestep, start: peg$parsestart, string: peg$parsestring, templateDocument: peg$parsetemplateDocument, templateDocumentChar: peg$parsetemplateDocumentChar, templateDocumentContents: peg$parsetemplateDocumentContents, templateDocumentText: peg$parsetemplateDocumentText, templateLiteral: peg$parsetemplateLiteral, templateLiteralChar: peg$parsetemplateLiteralChar, templateLiteralContents: peg$parsetemplateLiteralContents, templateLiteralText: peg$parsetemplateLiteralText, templateSubstitution: peg$parsetemplateSubstitution, textChar: peg$parsetextChar, tree: peg$parsetree, treeAssignment: peg$parsetreeAssignment, treeEntries: peg$parsetreeEntries, treeEntry: peg$parsetreeEntry, whitespaceWithNewLine: peg$parsewhitespaceWithNewLine };
|
|
196
|
+
var peg$startRuleFunctions = { __: peg$parse__, absoluteFilePath: peg$parseabsoluteFilePath, args: peg$parseargs, array: peg$parsearray, arrayEntries: peg$parsearrayEntries, arrayEntry: peg$parsearrayEntry, callTarget: peg$parsecallTarget, closingBrace: peg$parseclosingBrace, closingBracket: peg$parseclosingBracket, closingParen: peg$parseclosingParen, comment: peg$parsecomment, digits: peg$parsedigits, doubleArrow: peg$parsedoubleArrow, doubleQuoteString: peg$parsedoubleQuoteString, doubleQuoteStringChar: peg$parsedoubleQuoteStringChar, ellipsis: peg$parseellipsis, escapedChar: peg$parseescapedChar, expr: peg$parseexpr, expression: peg$parseexpression, float: peg$parsefloat, functionComposition: peg$parsefunctionComposition, group: peg$parsegroup, host: peg$parsehost, identifier: peg$parseidentifier, identifierChar: peg$parseidentifierChar, identifierList: peg$parseidentifierList, identifierOrString: peg$parseidentifierOrString, implicitParensArgs: peg$parseimplicitParensArgs, inlineSpace: peg$parseinlineSpace, integer: peg$parseinteger, lambda: peg$parselambda, leadingSlashPath: peg$parseleadingSlashPath, list: peg$parselist, multiLineComment: peg$parsemultiLineComment, newLine: peg$parsenewLine, number: peg$parsenumber, object: peg$parseobject, objectEntries: peg$parseobjectEntries, objectEntry: peg$parseobjectEntry, objectProperty: peg$parseobjectProperty, parameterizedLambda: peg$parseparameterizedLambda, parensArgs: peg$parseparensArgs, pipeline: peg$parsepipeline, path: peg$parsepath, pathKey: peg$parsepathKey, pathKeyChar: peg$parsepathKeyChar, protocolCall: peg$parseprotocolCall, protocol: peg$parseprotocol, reservedProtocol: peg$parsereservedProtocol, scopeReference: peg$parsescopeReference, separator: peg$parseseparator, shebang: peg$parseshebang, sign: peg$parsesign, singleArrow: peg$parsesingleArrow, singleLineComment: peg$parsesingleLineComment, singleQuoteString: peg$parsesingleQuoteString, singleQuoteStringChar: peg$parsesingleQuoteStringChar, spread: peg$parsespread, step: peg$parsestep, start: peg$parsestart, string: peg$parsestring, templateDocument: peg$parsetemplateDocument, templateDocumentChar: peg$parsetemplateDocumentChar, templateDocumentContents: peg$parsetemplateDocumentContents, templateDocumentText: peg$parsetemplateDocumentText, templateLiteral: peg$parsetemplateLiteral, templateLiteralChar: peg$parsetemplateLiteralChar, templateLiteralContents: peg$parsetemplateLiteralContents, templateLiteralText: peg$parsetemplateLiteralText, templateSubstitution: peg$parsetemplateSubstitution, textChar: peg$parsetextChar, tree: peg$parsetree, treeAssignment: peg$parsetreeAssignment, treeEntries: peg$parsetreeEntries, treeEntry: peg$parsetreeEntry, whitespaceWithNewLine: peg$parsewhitespaceWithNewLine };
|
|
197
197
|
var peg$startRuleFunction = peg$parse__;
|
|
198
198
|
|
|
199
199
|
var peg$c0 = "//";
|
|
@@ -238,8 +238,9 @@ function peg$parse(input, options) {
|
|
|
238
238
|
var peg$r0 = /^[0-9]/;
|
|
239
239
|
var peg$r1 = /^[^(){}[\]<>\-=,\/:`"'\\ \u2192\u21D2\t\n\r]/;
|
|
240
240
|
var peg$r2 = /^[ \t]/;
|
|
241
|
-
var peg$r3 = /^[
|
|
242
|
-
var peg$r4 = /^[
|
|
241
|
+
var peg$r3 = /^[^(){}[\],:\/\\ \t\n\r]/;
|
|
242
|
+
var peg$r4 = /^[^\n\r]/;
|
|
243
|
+
var peg$r5 = /^[+\-]/;
|
|
243
244
|
|
|
244
245
|
var peg$e0 = peg$otherExpectation("absolute file path");
|
|
245
246
|
var peg$e1 = peg$literalExpectation("//", false);
|
|
@@ -293,34 +294,35 @@ function peg$parse(input, options) {
|
|
|
293
294
|
var peg$e49 = peg$otherExpectation("function arguments in parentheses");
|
|
294
295
|
var peg$e50 = peg$otherExpectation("slash-separated path");
|
|
295
296
|
var peg$e51 = peg$otherExpectation("path element");
|
|
296
|
-
var peg$e52 = peg$
|
|
297
|
-
var peg$e53 = peg$otherExpectation("protocol");
|
|
298
|
-
var peg$e54 = peg$otherExpectation("
|
|
299
|
-
var peg$e55 = peg$
|
|
300
|
-
var peg$e56 = peg$literalExpectation("
|
|
301
|
-
var peg$e57 = peg$literalExpectation("
|
|
302
|
-
var peg$e58 = peg$literalExpectation("
|
|
303
|
-
var peg$e59 = peg$literalExpectation("
|
|
304
|
-
var peg$e60 = peg$literalExpectation("
|
|
305
|
-
var peg$e61 = peg$literalExpectation("
|
|
306
|
-
var peg$e62 = peg$
|
|
307
|
-
var peg$e63 = peg$
|
|
308
|
-
var peg$e64 = peg$literalExpectation("
|
|
309
|
-
var peg$e65 = peg$
|
|
310
|
-
var peg$e66 = peg$classExpectation(["
|
|
311
|
-
var peg$e67 = peg$
|
|
312
|
-
var peg$e68 = peg$literalExpectation("
|
|
313
|
-
var peg$e69 = peg$
|
|
314
|
-
var peg$e70 = peg$
|
|
315
|
-
var peg$e71 = peg$
|
|
316
|
-
var peg$e72 = peg$otherExpectation("
|
|
317
|
-
var peg$e73 = peg$
|
|
318
|
-
var peg$e74 = peg$
|
|
319
|
-
var peg$e75 = peg$otherExpectation("template
|
|
320
|
-
var peg$e76 = peg$
|
|
321
|
-
var peg$e77 = peg$
|
|
322
|
-
var peg$e78 = peg$otherExpectation("
|
|
323
|
-
var peg$e79 = peg$otherExpectation("tree
|
|
297
|
+
var peg$e52 = peg$classExpectation(["(", ")", "{", "}", "[", "]", ",", ":", "/", "\\", " ", "\t", "\n", "\r"], true, false);
|
|
298
|
+
var peg$e53 = peg$otherExpectation("function call using protocol: syntax");
|
|
299
|
+
var peg$e54 = peg$otherExpectation("protocol");
|
|
300
|
+
var peg$e55 = peg$otherExpectation("reserved protocol");
|
|
301
|
+
var peg$e56 = peg$literalExpectation("https", false);
|
|
302
|
+
var peg$e57 = peg$literalExpectation("http", false);
|
|
303
|
+
var peg$e58 = peg$literalExpectation("new", false);
|
|
304
|
+
var peg$e59 = peg$literalExpectation("package", false);
|
|
305
|
+
var peg$e60 = peg$literalExpectation("treehttps", false);
|
|
306
|
+
var peg$e61 = peg$literalExpectation("treehttp", false);
|
|
307
|
+
var peg$e62 = peg$literalExpectation("tree", false);
|
|
308
|
+
var peg$e63 = peg$otherExpectation("scope reference");
|
|
309
|
+
var peg$e64 = peg$literalExpectation(",", false);
|
|
310
|
+
var peg$e65 = peg$literalExpectation("#!", false);
|
|
311
|
+
var peg$e66 = peg$classExpectation(["\n", "\r"], true, false);
|
|
312
|
+
var peg$e67 = peg$classExpectation(["+", "-"], false, false);
|
|
313
|
+
var peg$e68 = peg$literalExpectation("\u2192", false);
|
|
314
|
+
var peg$e69 = peg$literalExpectation("->", false);
|
|
315
|
+
var peg$e70 = peg$otherExpectation("single quote string");
|
|
316
|
+
var peg$e71 = peg$literalExpectation("'", false);
|
|
317
|
+
var peg$e72 = peg$otherExpectation("string");
|
|
318
|
+
var peg$e73 = peg$otherExpectation("template");
|
|
319
|
+
var peg$e74 = peg$literalExpectation("${", false);
|
|
320
|
+
var peg$e75 = peg$otherExpectation("template text");
|
|
321
|
+
var peg$e76 = peg$otherExpectation("template literal");
|
|
322
|
+
var peg$e77 = peg$literalExpectation("`", false);
|
|
323
|
+
var peg$e78 = peg$otherExpectation("template substitution");
|
|
324
|
+
var peg$e79 = peg$otherExpectation("tree literal");
|
|
325
|
+
var peg$e80 = peg$otherExpectation("tree assignment");
|
|
324
326
|
|
|
325
327
|
var peg$f0 = function() { return ""; };
|
|
326
328
|
var peg$f1 = function(path) {
|
|
@@ -376,7 +378,7 @@ function peg$parse(input, options) {
|
|
|
376
378
|
var peg$f20 = function(steps) {
|
|
377
379
|
return annotate(makePipeline(steps), location());
|
|
378
380
|
};
|
|
379
|
-
var peg$f21 = function(
|
|
381
|
+
var peg$f21 = function(chars) { return chars.join(""); };
|
|
380
382
|
var peg$f22 = function(protocol, host, path) {
|
|
381
383
|
return annotate([protocol, host, ...(path ?? [])], location());
|
|
382
384
|
};
|
|
@@ -1447,7 +1449,7 @@ function peg$parse(input, options) {
|
|
|
1447
1449
|
}
|
|
1448
1450
|
|
|
1449
1451
|
function peg$parseimplicitParensArgs() {
|
|
1450
|
-
var s0, s1, s2;
|
|
1452
|
+
var s0, s1, s2, s3, s4, s5;
|
|
1451
1453
|
|
|
1452
1454
|
peg$silentFails++;
|
|
1453
1455
|
s0 = peg$currPos;
|
|
@@ -1462,8 +1464,36 @@ function peg$parse(input, options) {
|
|
|
1462
1464
|
s1 = peg$FAILED;
|
|
1463
1465
|
}
|
|
1464
1466
|
if (s1 !== peg$FAILED) {
|
|
1465
|
-
s2 = peg$
|
|
1467
|
+
s2 = peg$currPos;
|
|
1468
|
+
s3 = [];
|
|
1469
|
+
s4 = peg$parsestep();
|
|
1470
|
+
while (s4 !== peg$FAILED) {
|
|
1471
|
+
s3.push(s4);
|
|
1472
|
+
s4 = peg$currPos;
|
|
1473
|
+
s5 = peg$parseseparator();
|
|
1474
|
+
if (s5 !== peg$FAILED) {
|
|
1475
|
+
s5 = peg$parsestep();
|
|
1476
|
+
if (s5 === peg$FAILED) {
|
|
1477
|
+
peg$currPos = s4;
|
|
1478
|
+
s4 = peg$FAILED;
|
|
1479
|
+
} else {
|
|
1480
|
+
s4 = s5;
|
|
1481
|
+
}
|
|
1482
|
+
} else {
|
|
1483
|
+
s4 = s5;
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
if (s3.length < 1) {
|
|
1487
|
+
peg$currPos = s2;
|
|
1488
|
+
s2 = peg$FAILED;
|
|
1489
|
+
} else {
|
|
1490
|
+
s2 = s3;
|
|
1491
|
+
}
|
|
1466
1492
|
if (s2 !== peg$FAILED) {
|
|
1493
|
+
s3 = peg$parseseparator();
|
|
1494
|
+
if (s3 === peg$FAILED) {
|
|
1495
|
+
s3 = null;
|
|
1496
|
+
}
|
|
1467
1497
|
s0 = s2;
|
|
1468
1498
|
} else {
|
|
1469
1499
|
peg$currPos = s0;
|
|
@@ -2156,10 +2186,10 @@ function peg$parse(input, options) {
|
|
|
2156
2186
|
peg$silentFails++;
|
|
2157
2187
|
s0 = peg$currPos;
|
|
2158
2188
|
s1 = [];
|
|
2159
|
-
s2 = peg$
|
|
2189
|
+
s2 = peg$parsepathKeyChar();
|
|
2160
2190
|
while (s2 !== peg$FAILED) {
|
|
2161
2191
|
s1.push(s2);
|
|
2162
|
-
s2 = peg$
|
|
2192
|
+
s2 = peg$parsepathKeyChar();
|
|
2163
2193
|
}
|
|
2164
2194
|
peg$savedPos = s0;
|
|
2165
2195
|
s1 = peg$f21(s1);
|
|
@@ -2171,6 +2201,23 @@ function peg$parse(input, options) {
|
|
|
2171
2201
|
return s0;
|
|
2172
2202
|
}
|
|
2173
2203
|
|
|
2204
|
+
function peg$parsepathKeyChar() {
|
|
2205
|
+
var s0;
|
|
2206
|
+
|
|
2207
|
+
s0 = input.charAt(peg$currPos);
|
|
2208
|
+
if (peg$r3.test(s0)) {
|
|
2209
|
+
peg$currPos++;
|
|
2210
|
+
} else {
|
|
2211
|
+
s0 = peg$FAILED;
|
|
2212
|
+
if (peg$silentFails === 0) { peg$fail(peg$e52); }
|
|
2213
|
+
}
|
|
2214
|
+
if (s0 === peg$FAILED) {
|
|
2215
|
+
s0 = peg$parseescapedChar();
|
|
2216
|
+
}
|
|
2217
|
+
|
|
2218
|
+
return s0;
|
|
2219
|
+
}
|
|
2220
|
+
|
|
2174
2221
|
function peg$parseprotocolCall() {
|
|
2175
2222
|
var s0, s1, s2, s3, s4, s5;
|
|
2176
2223
|
|
|
@@ -2231,7 +2278,7 @@ function peg$parse(input, options) {
|
|
|
2231
2278
|
peg$silentFails--;
|
|
2232
2279
|
if (s0 === peg$FAILED) {
|
|
2233
2280
|
s1 = peg$FAILED;
|
|
2234
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2281
|
+
if (peg$silentFails === 0) { peg$fail(peg$e53); }
|
|
2235
2282
|
}
|
|
2236
2283
|
|
|
2237
2284
|
return s0;
|
|
@@ -2248,7 +2295,7 @@ function peg$parse(input, options) {
|
|
|
2248
2295
|
peg$silentFails--;
|
|
2249
2296
|
if (s0 === peg$FAILED) {
|
|
2250
2297
|
s1 = peg$FAILED;
|
|
2251
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2298
|
+
if (peg$silentFails === 0) { peg$fail(peg$e54); }
|
|
2252
2299
|
}
|
|
2253
2300
|
|
|
2254
2301
|
return s0;
|
|
@@ -2264,7 +2311,7 @@ function peg$parse(input, options) {
|
|
|
2264
2311
|
peg$currPos += 5;
|
|
2265
2312
|
} else {
|
|
2266
2313
|
s1 = peg$FAILED;
|
|
2267
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2314
|
+
if (peg$silentFails === 0) { peg$fail(peg$e56); }
|
|
2268
2315
|
}
|
|
2269
2316
|
if (s1 !== peg$FAILED) {
|
|
2270
2317
|
peg$savedPos = s0;
|
|
@@ -2278,7 +2325,7 @@ function peg$parse(input, options) {
|
|
|
2278
2325
|
peg$currPos += 4;
|
|
2279
2326
|
} else {
|
|
2280
2327
|
s1 = peg$FAILED;
|
|
2281
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2328
|
+
if (peg$silentFails === 0) { peg$fail(peg$e57); }
|
|
2282
2329
|
}
|
|
2283
2330
|
if (s1 !== peg$FAILED) {
|
|
2284
2331
|
peg$savedPos = s0;
|
|
@@ -2292,7 +2339,7 @@ function peg$parse(input, options) {
|
|
|
2292
2339
|
peg$currPos += 3;
|
|
2293
2340
|
} else {
|
|
2294
2341
|
s1 = peg$FAILED;
|
|
2295
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2342
|
+
if (peg$silentFails === 0) { peg$fail(peg$e58); }
|
|
2296
2343
|
}
|
|
2297
2344
|
if (s1 !== peg$FAILED) {
|
|
2298
2345
|
peg$savedPos = s0;
|
|
@@ -2306,7 +2353,7 @@ function peg$parse(input, options) {
|
|
|
2306
2353
|
peg$currPos += 7;
|
|
2307
2354
|
} else {
|
|
2308
2355
|
s1 = peg$FAILED;
|
|
2309
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2356
|
+
if (peg$silentFails === 0) { peg$fail(peg$e59); }
|
|
2310
2357
|
}
|
|
2311
2358
|
if (s1 !== peg$FAILED) {
|
|
2312
2359
|
peg$savedPos = s0;
|
|
@@ -2320,7 +2367,7 @@ function peg$parse(input, options) {
|
|
|
2320
2367
|
peg$currPos += 9;
|
|
2321
2368
|
} else {
|
|
2322
2369
|
s1 = peg$FAILED;
|
|
2323
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2370
|
+
if (peg$silentFails === 0) { peg$fail(peg$e60); }
|
|
2324
2371
|
}
|
|
2325
2372
|
if (s1 !== peg$FAILED) {
|
|
2326
2373
|
peg$savedPos = s0;
|
|
@@ -2334,7 +2381,7 @@ function peg$parse(input, options) {
|
|
|
2334
2381
|
peg$currPos += 8;
|
|
2335
2382
|
} else {
|
|
2336
2383
|
s1 = peg$FAILED;
|
|
2337
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2384
|
+
if (peg$silentFails === 0) { peg$fail(peg$e61); }
|
|
2338
2385
|
}
|
|
2339
2386
|
if (s1 !== peg$FAILED) {
|
|
2340
2387
|
peg$savedPos = s0;
|
|
@@ -2348,7 +2395,7 @@ function peg$parse(input, options) {
|
|
|
2348
2395
|
peg$currPos += 4;
|
|
2349
2396
|
} else {
|
|
2350
2397
|
s1 = peg$FAILED;
|
|
2351
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2398
|
+
if (peg$silentFails === 0) { peg$fail(peg$e62); }
|
|
2352
2399
|
}
|
|
2353
2400
|
if (s1 !== peg$FAILED) {
|
|
2354
2401
|
peg$savedPos = s0;
|
|
@@ -2364,7 +2411,7 @@ function peg$parse(input, options) {
|
|
|
2364
2411
|
peg$silentFails--;
|
|
2365
2412
|
if (s0 === peg$FAILED) {
|
|
2366
2413
|
s1 = peg$FAILED;
|
|
2367
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2414
|
+
if (peg$silentFails === 0) { peg$fail(peg$e55); }
|
|
2368
2415
|
}
|
|
2369
2416
|
|
|
2370
2417
|
return s0;
|
|
@@ -2384,7 +2431,7 @@ function peg$parse(input, options) {
|
|
|
2384
2431
|
peg$silentFails--;
|
|
2385
2432
|
if (s0 === peg$FAILED) {
|
|
2386
2433
|
s1 = peg$FAILED;
|
|
2387
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2434
|
+
if (peg$silentFails === 0) { peg$fail(peg$e63); }
|
|
2388
2435
|
}
|
|
2389
2436
|
|
|
2390
2437
|
return s0;
|
|
@@ -2400,7 +2447,7 @@ function peg$parse(input, options) {
|
|
|
2400
2447
|
peg$currPos++;
|
|
2401
2448
|
} else {
|
|
2402
2449
|
s2 = peg$FAILED;
|
|
2403
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2450
|
+
if (peg$silentFails === 0) { peg$fail(peg$e64); }
|
|
2404
2451
|
}
|
|
2405
2452
|
if (s2 !== peg$FAILED) {
|
|
2406
2453
|
s3 = peg$parse__();
|
|
@@ -2426,25 +2473,25 @@ function peg$parse(input, options) {
|
|
|
2426
2473
|
peg$currPos += 2;
|
|
2427
2474
|
} else {
|
|
2428
2475
|
s1 = peg$FAILED;
|
|
2429
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2476
|
+
if (peg$silentFails === 0) { peg$fail(peg$e65); }
|
|
2430
2477
|
}
|
|
2431
2478
|
if (s1 !== peg$FAILED) {
|
|
2432
2479
|
s2 = [];
|
|
2433
2480
|
s3 = input.charAt(peg$currPos);
|
|
2434
|
-
if (peg$
|
|
2481
|
+
if (peg$r4.test(s3)) {
|
|
2435
2482
|
peg$currPos++;
|
|
2436
2483
|
} else {
|
|
2437
2484
|
s3 = peg$FAILED;
|
|
2438
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2485
|
+
if (peg$silentFails === 0) { peg$fail(peg$e66); }
|
|
2439
2486
|
}
|
|
2440
2487
|
while (s3 !== peg$FAILED) {
|
|
2441
2488
|
s2.push(s3);
|
|
2442
2489
|
s3 = input.charAt(peg$currPos);
|
|
2443
|
-
if (peg$
|
|
2490
|
+
if (peg$r4.test(s3)) {
|
|
2444
2491
|
peg$currPos++;
|
|
2445
2492
|
} else {
|
|
2446
2493
|
s3 = peg$FAILED;
|
|
2447
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2494
|
+
if (peg$silentFails === 0) { peg$fail(peg$e66); }
|
|
2448
2495
|
}
|
|
2449
2496
|
}
|
|
2450
2497
|
peg$savedPos = s0;
|
|
@@ -2461,11 +2508,11 @@ function peg$parse(input, options) {
|
|
|
2461
2508
|
var s0;
|
|
2462
2509
|
|
|
2463
2510
|
s0 = input.charAt(peg$currPos);
|
|
2464
|
-
if (peg$
|
|
2511
|
+
if (peg$r5.test(s0)) {
|
|
2465
2512
|
peg$currPos++;
|
|
2466
2513
|
} else {
|
|
2467
2514
|
s0 = peg$FAILED;
|
|
2468
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2515
|
+
if (peg$silentFails === 0) { peg$fail(peg$e67); }
|
|
2469
2516
|
}
|
|
2470
2517
|
|
|
2471
2518
|
return s0;
|
|
@@ -2479,7 +2526,7 @@ function peg$parse(input, options) {
|
|
|
2479
2526
|
peg$currPos++;
|
|
2480
2527
|
} else {
|
|
2481
2528
|
s0 = peg$FAILED;
|
|
2482
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2529
|
+
if (peg$silentFails === 0) { peg$fail(peg$e68); }
|
|
2483
2530
|
}
|
|
2484
2531
|
if (s0 === peg$FAILED) {
|
|
2485
2532
|
if (input.substr(peg$currPos, 2) === peg$c34) {
|
|
@@ -2487,7 +2534,7 @@ function peg$parse(input, options) {
|
|
|
2487
2534
|
peg$currPos += 2;
|
|
2488
2535
|
} else {
|
|
2489
2536
|
s0 = peg$FAILED;
|
|
2490
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2537
|
+
if (peg$silentFails === 0) { peg$fail(peg$e69); }
|
|
2491
2538
|
}
|
|
2492
2539
|
}
|
|
2493
2540
|
|
|
@@ -2508,20 +2555,20 @@ function peg$parse(input, options) {
|
|
|
2508
2555
|
if (s1 !== peg$FAILED) {
|
|
2509
2556
|
s2 = [];
|
|
2510
2557
|
s3 = input.charAt(peg$currPos);
|
|
2511
|
-
if (peg$
|
|
2558
|
+
if (peg$r4.test(s3)) {
|
|
2512
2559
|
peg$currPos++;
|
|
2513
2560
|
} else {
|
|
2514
2561
|
s3 = peg$FAILED;
|
|
2515
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2562
|
+
if (peg$silentFails === 0) { peg$fail(peg$e66); }
|
|
2516
2563
|
}
|
|
2517
2564
|
while (s3 !== peg$FAILED) {
|
|
2518
2565
|
s2.push(s3);
|
|
2519
2566
|
s3 = input.charAt(peg$currPos);
|
|
2520
|
-
if (peg$
|
|
2567
|
+
if (peg$r4.test(s3)) {
|
|
2521
2568
|
peg$currPos++;
|
|
2522
2569
|
} else {
|
|
2523
2570
|
s3 = peg$FAILED;
|
|
2524
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2571
|
+
if (peg$silentFails === 0) { peg$fail(peg$e66); }
|
|
2525
2572
|
}
|
|
2526
2573
|
}
|
|
2527
2574
|
peg$savedPos = s0;
|
|
@@ -2544,7 +2591,7 @@ function peg$parse(input, options) {
|
|
|
2544
2591
|
peg$currPos++;
|
|
2545
2592
|
} else {
|
|
2546
2593
|
s1 = peg$FAILED;
|
|
2547
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2594
|
+
if (peg$silentFails === 0) { peg$fail(peg$e71); }
|
|
2548
2595
|
}
|
|
2549
2596
|
if (s1 !== peg$FAILED) {
|
|
2550
2597
|
s2 = [];
|
|
@@ -2558,7 +2605,7 @@ function peg$parse(input, options) {
|
|
|
2558
2605
|
peg$currPos++;
|
|
2559
2606
|
} else {
|
|
2560
2607
|
s3 = peg$FAILED;
|
|
2561
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2608
|
+
if (peg$silentFails === 0) { peg$fail(peg$e71); }
|
|
2562
2609
|
}
|
|
2563
2610
|
if (s3 !== peg$FAILED) {
|
|
2564
2611
|
peg$savedPos = s0;
|
|
@@ -2574,7 +2621,7 @@ function peg$parse(input, options) {
|
|
|
2574
2621
|
peg$silentFails--;
|
|
2575
2622
|
if (s0 === peg$FAILED) {
|
|
2576
2623
|
s1 = peg$FAILED;
|
|
2577
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2624
|
+
if (peg$silentFails === 0) { peg$fail(peg$e70); }
|
|
2578
2625
|
}
|
|
2579
2626
|
|
|
2580
2627
|
return s0;
|
|
@@ -2591,7 +2638,7 @@ function peg$parse(input, options) {
|
|
|
2591
2638
|
peg$currPos++;
|
|
2592
2639
|
} else {
|
|
2593
2640
|
s2 = peg$FAILED;
|
|
2594
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2641
|
+
if (peg$silentFails === 0) { peg$fail(peg$e71); }
|
|
2595
2642
|
}
|
|
2596
2643
|
if (s2 === peg$FAILED) {
|
|
2597
2644
|
s2 = peg$parsenewLine();
|
|
@@ -2704,7 +2751,7 @@ function peg$parse(input, options) {
|
|
|
2704
2751
|
peg$silentFails--;
|
|
2705
2752
|
if (s0 === peg$FAILED) {
|
|
2706
2753
|
s1 = peg$FAILED;
|
|
2707
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2754
|
+
if (peg$silentFails === 0) { peg$fail(peg$e72); }
|
|
2708
2755
|
}
|
|
2709
2756
|
|
|
2710
2757
|
return s0;
|
|
@@ -2721,7 +2768,7 @@ function peg$parse(input, options) {
|
|
|
2721
2768
|
s0 = s1;
|
|
2722
2769
|
peg$silentFails--;
|
|
2723
2770
|
s1 = peg$FAILED;
|
|
2724
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2771
|
+
if (peg$silentFails === 0) { peg$fail(peg$e73); }
|
|
2725
2772
|
|
|
2726
2773
|
return s0;
|
|
2727
2774
|
}
|
|
@@ -2737,7 +2784,7 @@ function peg$parse(input, options) {
|
|
|
2737
2784
|
peg$currPos += 2;
|
|
2738
2785
|
} else {
|
|
2739
2786
|
s2 = peg$FAILED;
|
|
2740
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2787
|
+
if (peg$silentFails === 0) { peg$fail(peg$e74); }
|
|
2741
2788
|
}
|
|
2742
2789
|
peg$silentFails--;
|
|
2743
2790
|
if (s2 === peg$FAILED) {
|
|
@@ -2808,7 +2855,7 @@ function peg$parse(input, options) {
|
|
|
2808
2855
|
peg$silentFails--;
|
|
2809
2856
|
if (s0 === peg$FAILED) {
|
|
2810
2857
|
s1 = peg$FAILED;
|
|
2811
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2858
|
+
if (peg$silentFails === 0) { peg$fail(peg$e75); }
|
|
2812
2859
|
}
|
|
2813
2860
|
|
|
2814
2861
|
return s0;
|
|
@@ -2824,7 +2871,7 @@ function peg$parse(input, options) {
|
|
|
2824
2871
|
peg$currPos++;
|
|
2825
2872
|
} else {
|
|
2826
2873
|
s1 = peg$FAILED;
|
|
2827
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2874
|
+
if (peg$silentFails === 0) { peg$fail(peg$e77); }
|
|
2828
2875
|
}
|
|
2829
2876
|
if (s1 !== peg$FAILED) {
|
|
2830
2877
|
s2 = peg$parsetemplateLiteralContents();
|
|
@@ -2833,7 +2880,7 @@ function peg$parse(input, options) {
|
|
|
2833
2880
|
peg$currPos++;
|
|
2834
2881
|
} else {
|
|
2835
2882
|
s3 = peg$FAILED;
|
|
2836
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2883
|
+
if (peg$silentFails === 0) { peg$fail(peg$e77); }
|
|
2837
2884
|
}
|
|
2838
2885
|
if (s3 !== peg$FAILED) {
|
|
2839
2886
|
s0 = s2;
|
|
@@ -2848,7 +2895,7 @@ function peg$parse(input, options) {
|
|
|
2848
2895
|
peg$silentFails--;
|
|
2849
2896
|
if (s0 === peg$FAILED) {
|
|
2850
2897
|
s1 = peg$FAILED;
|
|
2851
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2898
|
+
if (peg$silentFails === 0) { peg$fail(peg$e76); }
|
|
2852
2899
|
}
|
|
2853
2900
|
|
|
2854
2901
|
return s0;
|
|
@@ -2865,7 +2912,7 @@ function peg$parse(input, options) {
|
|
|
2865
2912
|
peg$currPos++;
|
|
2866
2913
|
} else {
|
|
2867
2914
|
s2 = peg$FAILED;
|
|
2868
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2915
|
+
if (peg$silentFails === 0) { peg$fail(peg$e77); }
|
|
2869
2916
|
}
|
|
2870
2917
|
if (s2 === peg$FAILED) {
|
|
2871
2918
|
if (input.substr(peg$currPos, 2) === peg$c36) {
|
|
@@ -2873,7 +2920,7 @@ function peg$parse(input, options) {
|
|
|
2873
2920
|
peg$currPos += 2;
|
|
2874
2921
|
} else {
|
|
2875
2922
|
s2 = peg$FAILED;
|
|
2876
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2923
|
+
if (peg$silentFails === 0) { peg$fail(peg$e74); }
|
|
2877
2924
|
}
|
|
2878
2925
|
}
|
|
2879
2926
|
peg$silentFails--;
|
|
@@ -2946,7 +2993,7 @@ function peg$parse(input, options) {
|
|
|
2946
2993
|
}
|
|
2947
2994
|
|
|
2948
2995
|
function peg$parsetemplateSubstitution() {
|
|
2949
|
-
var s0, s1, s2, s3;
|
|
2996
|
+
var s0, s1, s2, s3, s4, s5;
|
|
2950
2997
|
|
|
2951
2998
|
peg$silentFails++;
|
|
2952
2999
|
s0 = peg$currPos;
|
|
@@ -2955,20 +3002,22 @@ function peg$parse(input, options) {
|
|
|
2955
3002
|
peg$currPos += 2;
|
|
2956
3003
|
} else {
|
|
2957
3004
|
s1 = peg$FAILED;
|
|
2958
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
3005
|
+
if (peg$silentFails === 0) { peg$fail(peg$e74); }
|
|
2959
3006
|
}
|
|
2960
3007
|
if (s1 !== peg$FAILED) {
|
|
2961
|
-
s2 = peg$
|
|
2962
|
-
|
|
3008
|
+
s2 = peg$parse__();
|
|
3009
|
+
s3 = peg$parsepipeline();
|
|
3010
|
+
if (s3 !== peg$FAILED) {
|
|
3011
|
+
s4 = peg$parse__();
|
|
2963
3012
|
if (input.charCodeAt(peg$currPos) === 125) {
|
|
2964
|
-
|
|
3013
|
+
s5 = peg$c2;
|
|
2965
3014
|
peg$currPos++;
|
|
2966
3015
|
} else {
|
|
2967
|
-
|
|
3016
|
+
s5 = peg$FAILED;
|
|
2968
3017
|
if (peg$silentFails === 0) { peg$fail(peg$e6); }
|
|
2969
3018
|
}
|
|
2970
|
-
if (
|
|
2971
|
-
s0 =
|
|
3019
|
+
if (s5 !== peg$FAILED) {
|
|
3020
|
+
s0 = s3;
|
|
2972
3021
|
} else {
|
|
2973
3022
|
peg$currPos = s0;
|
|
2974
3023
|
s0 = peg$FAILED;
|
|
@@ -2984,7 +3033,7 @@ function peg$parse(input, options) {
|
|
|
2984
3033
|
peg$silentFails--;
|
|
2985
3034
|
if (s0 === peg$FAILED) {
|
|
2986
3035
|
s1 = peg$FAILED;
|
|
2987
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
3036
|
+
if (peg$silentFails === 0) { peg$fail(peg$e78); }
|
|
2988
3037
|
}
|
|
2989
3038
|
|
|
2990
3039
|
return s0;
|
|
@@ -3041,7 +3090,7 @@ function peg$parse(input, options) {
|
|
|
3041
3090
|
peg$silentFails--;
|
|
3042
3091
|
if (s0 === peg$FAILED) {
|
|
3043
3092
|
s1 = peg$FAILED;
|
|
3044
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
3093
|
+
if (peg$silentFails === 0) { peg$fail(peg$e79); }
|
|
3045
3094
|
}
|
|
3046
3095
|
|
|
3047
3096
|
return s0;
|
|
@@ -3082,7 +3131,7 @@ function peg$parse(input, options) {
|
|
|
3082
3131
|
peg$silentFails--;
|
|
3083
3132
|
if (s0 === peg$FAILED) {
|
|
3084
3133
|
s1 = peg$FAILED;
|
|
3085
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
3134
|
+
if (peg$silentFails === 0) { peg$fail(peg$e80); }
|
|
3086
3135
|
}
|
|
3087
3136
|
|
|
3088
3137
|
return s0;
|
|
@@ -3252,6 +3301,7 @@ const peg$allowedStartRules = [
|
|
|
3252
3301
|
"pipeline",
|
|
3253
3302
|
"path",
|
|
3254
3303
|
"pathKey",
|
|
3304
|
+
"pathKeyChar",
|
|
3255
3305
|
"protocolCall",
|
|
3256
3306
|
"protocol",
|
|
3257
3307
|
"reservedProtocol",
|
package/src/runtime/ops.js
CHANGED
|
@@ -8,11 +8,11 @@ import {
|
|
|
8
8
|
SiteTree,
|
|
9
9
|
Tree,
|
|
10
10
|
isUnpackable,
|
|
11
|
+
concat as treeConcat,
|
|
11
12
|
} from "@weborigami/async-tree";
|
|
12
13
|
import HandleExtensionsTransform from "./HandleExtensionsTransform.js";
|
|
13
14
|
import OrigamiFiles from "./OrigamiFiles.js";
|
|
14
15
|
import Scope from "./Scope.js";
|
|
15
|
-
import concatTreeValues from "./concatTreeValues.js";
|
|
16
16
|
import handleExtension from "./handleExtension.js";
|
|
17
17
|
import { OrigamiTree, evaluate, expressionFunction } from "./internal.js";
|
|
18
18
|
import mergeTrees from "./mergeTrees.js";
|
|
@@ -42,7 +42,7 @@ export const assign = "«ops.assign»";
|
|
|
42
42
|
* @param {any[]} args
|
|
43
43
|
*/
|
|
44
44
|
export async function concat(...args) {
|
|
45
|
-
return
|
|
45
|
+
return treeConcat.call(this, args);
|
|
46
46
|
}
|
|
47
47
|
concat.toString = () => "«ops.concat»";
|
|
48
48
|
|
|
@@ -383,6 +383,13 @@ describe("Origami parser", () => {
|
|
|
383
383
|
[ops.scope, "input"],
|
|
384
384
|
],
|
|
385
385
|
]);
|
|
386
|
+
assertParse("pipeline", "fn a -> b", [
|
|
387
|
+
[ops.scope, "b"],
|
|
388
|
+
[
|
|
389
|
+
[ops.scope, "fn"],
|
|
390
|
+
[ops.scope, "a"],
|
|
391
|
+
],
|
|
392
|
+
]);
|
|
386
393
|
});
|
|
387
394
|
|
|
388
395
|
test("protocolCall", () => {
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { Tree } from "@weborigami/async-tree";
|
|
2
|
-
import { ExpressionTree, expressionFunction, ops } from "@weborigami/language";
|
|
3
2
|
import assert from "node:assert";
|
|
4
3
|
import { describe, test } from "node:test";
|
|
4
|
+
import {
|
|
5
|
+
ExpressionTree,
|
|
6
|
+
expressionFunction,
|
|
7
|
+
ops,
|
|
8
|
+
} from "../../src/runtime/internal.js";
|
|
5
9
|
import mergeTrees from "../../src/runtime/mergeTrees.js";
|
|
6
10
|
|
|
7
11
|
describe("mergeTrees", () => {
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { Tree, getRealmObjectPrototype } from "@weborigami/async-tree";
|
|
2
|
-
|
|
3
|
-
const textDecoder = new TextDecoder();
|
|
4
|
-
const TypedArray = Object.getPrototypeOf(Uint8Array);
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Concatenate the text values in a tree.
|
|
8
|
-
*
|
|
9
|
-
* This is a map-reduce operation: convert everything to strings, then
|
|
10
|
-
* concatenate the strings.
|
|
11
|
-
*
|
|
12
|
-
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
13
|
-
*
|
|
14
|
-
* @this {AsyncTree|null}
|
|
15
|
-
* @param {import("@weborigami/async-tree").Treelike} treelike
|
|
16
|
-
*/
|
|
17
|
-
export default async function concatTreeValues(treelike) {
|
|
18
|
-
const scope = this;
|
|
19
|
-
const mapFn = async (value) => getText(value, scope);
|
|
20
|
-
const reduceFn = (values) => values.join("");
|
|
21
|
-
return Tree.mapReduce(treelike, mapFn, reduceFn);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async function getText(value, scope) {
|
|
25
|
-
// If the value is a function (e.g., a lambda), call it and use its result.
|
|
26
|
-
if (typeof value === "function") {
|
|
27
|
-
value = await value.call(scope);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (Tree.isTreelike(value)) {
|
|
31
|
-
// The mapReduce operation above only implicit casts its top-level input to
|
|
32
|
-
// a tree. If we're asked for the text of a treelike value, we need to
|
|
33
|
-
// explicitly recurse.
|
|
34
|
-
return concatTreeValues.call(scope, value);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Convert to text, preferring .toString but avoiding dumb Object.toString.
|
|
38
|
-
// Exception: if the result is an array, we'll concatenate the values.
|
|
39
|
-
let text;
|
|
40
|
-
if (value == null || value === false) {
|
|
41
|
-
// Treat falsy values (but not zero) as the empty string.
|
|
42
|
-
text = "";
|
|
43
|
-
} else if (typeof value === "string") {
|
|
44
|
-
text = value;
|
|
45
|
-
} else if (value instanceof ArrayBuffer || value instanceof TypedArray) {
|
|
46
|
-
// Serialize data as UTF-8.
|
|
47
|
-
text = textDecoder.decode(value);
|
|
48
|
-
} else if (
|
|
49
|
-
!(value instanceof Array) &&
|
|
50
|
-
value.toString !== getRealmObjectPrototype(value)?.toString
|
|
51
|
-
) {
|
|
52
|
-
text = value.toString();
|
|
53
|
-
} else {
|
|
54
|
-
// Anything else maps to the empty string.
|
|
55
|
-
text = "";
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return text;
|
|
59
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { FunctionTree, Tree } from "@weborigami/async-tree";
|
|
2
|
-
import assert from "node:assert";
|
|
3
|
-
import { describe, test } from "node:test";
|
|
4
|
-
import concatTreeValues from "../../src/runtime/concatTreeValues.js";
|
|
5
|
-
|
|
6
|
-
describe("concatTreeValues", () => {
|
|
7
|
-
test("concatenates deep tree values", async () => {
|
|
8
|
-
const tree = Tree.from({
|
|
9
|
-
a: "A",
|
|
10
|
-
b: "B",
|
|
11
|
-
c: "C",
|
|
12
|
-
more: {
|
|
13
|
-
d: "D",
|
|
14
|
-
e: "E",
|
|
15
|
-
},
|
|
16
|
-
});
|
|
17
|
-
const result = await concatTreeValues.call(null, tree);
|
|
18
|
-
assert.equal(result, "ABCDE");
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
test("concatenates deep tree-like values", async () => {
|
|
22
|
-
const letters = ["a", "b", "c"];
|
|
23
|
-
const specimens = new FunctionTree(
|
|
24
|
-
(letter) => ({
|
|
25
|
-
lowercase: letter,
|
|
26
|
-
uppercase: letter.toUpperCase(),
|
|
27
|
-
}),
|
|
28
|
-
letters
|
|
29
|
-
);
|
|
30
|
-
const result = await concatTreeValues.call(null, specimens);
|
|
31
|
-
assert.equal(result, "aAbBcC");
|
|
32
|
-
});
|
|
33
|
-
});
|