@weborigami/language 0.0.58 → 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 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.58",
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.12.8",
10
- "peggy": "4.0.2",
11
- "typescript": "5.4.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.58",
15
- "@weborigami/types": "0.0.58",
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
- = inlineSpace+ @list
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
- = key:identifierChar* { return key.join(""); }
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
- = "${" @expression "}"
376
+ = "${" __ @expr __ "}"
368
377
 
369
378
  textChar
370
379
  = escapedChar / .
@@ -1,4 +1,4 @@
1
- // @generated by Peggy 4.0.2.
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 = /^[^\n\r]/;
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$otherExpectation("function call using protocol: syntax");
297
- var peg$e53 = peg$otherExpectation("protocol");
298
- var peg$e54 = peg$otherExpectation("reserved protocol");
299
- var peg$e55 = peg$literalExpectation("https", false);
300
- var peg$e56 = peg$literalExpectation("http", false);
301
- var peg$e57 = peg$literalExpectation("new", false);
302
- var peg$e58 = peg$literalExpectation("package", false);
303
- var peg$e59 = peg$literalExpectation("treehttps", false);
304
- var peg$e60 = peg$literalExpectation("treehttp", false);
305
- var peg$e61 = peg$literalExpectation("tree", false);
306
- var peg$e62 = peg$otherExpectation("scope reference");
307
- var peg$e63 = peg$literalExpectation(",", false);
308
- var peg$e64 = peg$literalExpectation("#!", false);
309
- var peg$e65 = peg$classExpectation(["\n", "\r"], true, false);
310
- var peg$e66 = peg$classExpectation(["+", "-"], false, false);
311
- var peg$e67 = peg$literalExpectation("\u2192", false);
312
- var peg$e68 = peg$literalExpectation("->", false);
313
- var peg$e69 = peg$otherExpectation("single quote string");
314
- var peg$e70 = peg$literalExpectation("'", false);
315
- var peg$e71 = peg$otherExpectation("string");
316
- var peg$e72 = peg$otherExpectation("template");
317
- var peg$e73 = peg$literalExpectation("${", false);
318
- var peg$e74 = peg$otherExpectation("template text");
319
- var peg$e75 = peg$otherExpectation("template literal");
320
- var peg$e76 = peg$literalExpectation("`", false);
321
- var peg$e77 = peg$otherExpectation("template substitution");
322
- var peg$e78 = peg$otherExpectation("tree literal");
323
- var peg$e79 = peg$otherExpectation("tree assignment");
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(key) { return key.join(""); };
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$parselist();
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$parseidentifierChar();
2189
+ s2 = peg$parsepathKeyChar();
2160
2190
  while (s2 !== peg$FAILED) {
2161
2191
  s1.push(s2);
2162
- s2 = peg$parseidentifierChar();
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$e52); }
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$e53); }
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$e55); }
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$e56); }
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$e57); }
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$e58); }
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$e59); }
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$e60); }
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$e61); }
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$e54); }
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$e62); }
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$e63); }
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$e64); }
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$r3.test(s3)) {
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$e65); }
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$r3.test(s3)) {
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$e65); }
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$r4.test(s0)) {
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$e66); }
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$e67); }
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$e68); }
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$r3.test(s3)) {
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$e65); }
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$r3.test(s3)) {
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$e65); }
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$e70); }
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$e70); }
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$e69); }
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$e70); }
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$e71); }
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$e72); }
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$e73); }
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$e74); }
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$e76); }
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$e76); }
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$e75); }
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$e76); }
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$e73); }
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$e73); }
3005
+ if (peg$silentFails === 0) { peg$fail(peg$e74); }
2959
3006
  }
2960
3007
  if (s1 !== peg$FAILED) {
2961
- s2 = peg$parseexpression();
2962
- if (s2 !== peg$FAILED) {
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
- s3 = peg$c2;
3013
+ s5 = peg$c2;
2965
3014
  peg$currPos++;
2966
3015
  } else {
2967
- s3 = peg$FAILED;
3016
+ s5 = peg$FAILED;
2968
3017
  if (peg$silentFails === 0) { peg$fail(peg$e6); }
2969
3018
  }
2970
- if (s3 !== peg$FAILED) {
2971
- s0 = s2;
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$e77); }
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$e78); }
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$e79); }
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",
@@ -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 concatTreeValues.call(this, args);
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
- });