@weborigami/language 0.2.1 → 0.2.3

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.
@@ -202,7 +202,7 @@ function peg$parse(input, options) {
202
202
  var peg$FAILED = {};
203
203
  var peg$source = options.grammarSource;
204
204
 
205
- var peg$startRuleFunctions = { __: peg$parse__, additiveExpression: peg$parseadditiveExpression, additiveOperator: peg$parseadditiveOperator, arguments: peg$parsearguments, arrayLiteral: peg$parsearrayLiteral, arrayEntries: peg$parsearrayEntries, arrayEntry: peg$parsearrayEntry, arrowFunction: peg$parsearrowFunction, bitwiseAndExpression: peg$parsebitwiseAndExpression, bitwiseAndOperator: peg$parsebitwiseAndOperator, bitwiseOrExpression: peg$parsebitwiseOrExpression, bitwiseOrOperator: peg$parsebitwiseOrOperator, bitwiseXorExpression: peg$parsebitwiseXorExpression, bitwiseXorOperator: peg$parsebitwiseXorOperator, callExpression: peg$parsecallExpression, closingBrace: peg$parseclosingBrace, closingBracket: peg$parseclosingBracket, closingParenthesis: peg$parseclosingParenthesis, commaExpression: peg$parsecommaExpression, comment: peg$parsecomment, conditionalExpression: peg$parseconditionalExpression, digits: peg$parsedigits, doubleArrow: peg$parsedoubleArrow, doubleQuoteString: peg$parsedoubleQuoteString, doubleQuoteStringChar: peg$parsedoubleQuoteStringChar, ellipsis: peg$parseellipsis, equalityExpression: peg$parseequalityExpression, equalityOperator: peg$parseequalityOperator, escapedChar: peg$parseescapedChar, exponentiationExpression: peg$parseexponentiationExpression, expression: peg$parseexpression, floatLiteral: peg$parsefloatLiteral, group: peg$parsegroup, guillemetString: peg$parseguillemetString, guillemetStringChar: peg$parseguillemetStringChar, homeDirectory: peg$parsehomeDirectory, host: peg$parsehost, identifier: peg$parseidentifier, identifierChar: peg$parseidentifierChar, identifierList: peg$parseidentifierList, implicitParenthesesCallExpression: peg$parseimplicitParenthesesCallExpression, implicitParensthesesArguments: peg$parseimplicitParensthesesArguments, inlineSpace: peg$parseinlineSpace, integerLiteral: peg$parseintegerLiteral, list: peg$parselist, literal: peg$parseliteral, logicalAndExpression: peg$parselogicalAndExpression, logicalOrExpression: peg$parselogicalOrExpression, multiLineComment: peg$parsemultiLineComment, multiplicativeExpression: peg$parsemultiplicativeExpression, multiplicativeOperator: peg$parsemultiplicativeOperator, namespace: peg$parsenamespace, newLine: peg$parsenewLine, numericLiteral: peg$parsenumericLiteral, nullishCoalescingExpression: peg$parsenullishCoalescingExpression, objectLiteral: peg$parseobjectLiteral, objectEntries: peg$parseobjectEntries, objectEntry: peg$parseobjectEntry, objectGetter: peg$parseobjectGetter, objectHiddenKey: peg$parseobjectHiddenKey, objectKey: peg$parseobjectKey, objectProperty: peg$parseobjectProperty, objectShorthandProperty: peg$parseobjectShorthandProperty, objectPublicKey: peg$parseobjectPublicKey, parenthesesArguments: peg$parseparenthesesArguments, path: peg$parsepath, pathArguments: peg$parsepathArguments, pathKey: peg$parsepathKey, pathSegment: peg$parsepathSegment, pathSegmentChar: peg$parsepathSegmentChar, pipelineExpression: peg$parsepipelineExpression, primary: peg$parseprimary, program: peg$parseprogram, protocolExpression: peg$parseprotocolExpression, qualifiedReference: peg$parsequalifiedReference, reference: peg$parsereference, relationalExpression: peg$parserelationalExpression, relationalOperator: peg$parserelationalOperator, rootDirectory: peg$parserootDirectory, scopeReference: peg$parsescopeReference, separator: peg$parseseparator, slashFollows: peg$parseslashFollows, shebang: peg$parseshebang, shiftExpression: peg$parseshiftExpression, shiftOperator: peg$parseshiftOperator, shorthandFunction: peg$parseshorthandFunction, singleArrow: peg$parsesingleArrow, singleLineComment: peg$parsesingleLineComment, singleQuoteString: peg$parsesingleQuoteString, singleQuoteStringChar: peg$parsesingleQuoteStringChar, spread: peg$parsespread, stringLiteral: peg$parsestringLiteral, 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, unaryExpression: peg$parseunaryExpression, unaryOperator: peg$parseunaryOperator, whitespaceWithNewLine: peg$parsewhitespaceWithNewLine };
205
+ var peg$startRuleFunctions = { __: peg$parse__, additiveExpression: peg$parseadditiveExpression, additiveOperator: peg$parseadditiveOperator, arguments: peg$parsearguments, arrayLiteral: peg$parsearrayLiteral, arrayEntries: peg$parsearrayEntries, arrayEntry: peg$parsearrayEntry, arrowFunction: peg$parsearrowFunction, bitwiseAndExpression: peg$parsebitwiseAndExpression, bitwiseAndOperator: peg$parsebitwiseAndOperator, bitwiseOrExpression: peg$parsebitwiseOrExpression, bitwiseOrOperator: peg$parsebitwiseOrOperator, bitwiseXorExpression: peg$parsebitwiseXorExpression, bitwiseXorOperator: peg$parsebitwiseXorOperator, callExpression: peg$parsecallExpression, closingBrace: peg$parseclosingBrace, closingBracket: peg$parseclosingBracket, closingParenthesis: peg$parseclosingParenthesis, commaExpression: peg$parsecommaExpression, comment: peg$parsecomment, conditionalExpression: peg$parseconditionalExpression, digits: peg$parsedigits, doubleArrow: peg$parsedoubleArrow, doubleQuoteString: peg$parsedoubleQuoteString, doubleQuoteStringChar: peg$parsedoubleQuoteStringChar, ellipsis: peg$parseellipsis, equalityExpression: peg$parseequalityExpression, equalityOperator: peg$parseequalityOperator, escapedChar: peg$parseescapedChar, exponentiationExpression: peg$parseexponentiationExpression, expression: peg$parseexpression, floatLiteral: peg$parsefloatLiteral, group: peg$parsegroup, guillemetString: peg$parseguillemetString, guillemetStringChar: peg$parseguillemetStringChar, homeDirectory: peg$parsehomeDirectory, host: peg$parsehost, identifier: peg$parseidentifier, identifierChar: peg$parseidentifierChar, identifierList: peg$parseidentifierList, implicitParenthesesCallExpression: peg$parseimplicitParenthesesCallExpression, implicitParensthesesArguments: peg$parseimplicitParensthesesArguments, inlineSpace: peg$parseinlineSpace, integerLiteral: peg$parseintegerLiteral, list: peg$parselist, literal: peg$parseliteral, logicalAndExpression: peg$parselogicalAndExpression, logicalOrExpression: peg$parselogicalOrExpression, multiLineComment: peg$parsemultiLineComment, multiplicativeExpression: peg$parsemultiplicativeExpression, multiplicativeOperator: peg$parsemultiplicativeOperator, namespace: peg$parsenamespace, newLine: peg$parsenewLine, numericLiteral: peg$parsenumericLiteral, nullishCoalescingExpression: peg$parsenullishCoalescingExpression, objectLiteral: peg$parseobjectLiteral, objectEntries: peg$parseobjectEntries, objectEntry: peg$parseobjectEntry, objectGetter: peg$parseobjectGetter, objectHiddenKey: peg$parseobjectHiddenKey, objectKey: peg$parseobjectKey, objectProperty: peg$parseobjectProperty, objectShorthandProperty: peg$parseobjectShorthandProperty, objectPublicKey: peg$parseobjectPublicKey, parenthesesArguments: peg$parseparenthesesArguments, path: peg$parsepath, pathArguments: peg$parsepathArguments, pathKey: peg$parsepathKey, pathSegment: peg$parsepathSegment, pathSegmentChar: peg$parsepathSegmentChar, pipelineExpression: peg$parsepipelineExpression, primary: peg$parseprimary, program: peg$parseprogram, protocolExpression: peg$parseprotocolExpression, qualifiedReference: peg$parsequalifiedReference, reference: peg$parsereference, relationalExpression: peg$parserelationalExpression, relationalOperator: peg$parserelationalOperator, rootDirectory: peg$parserootDirectory, scopeReference: peg$parsescopeReference, separator: peg$parseseparator, slashFollows: peg$parseslashFollows, shebang: peg$parseshebang, shiftExpression: peg$parseshiftExpression, shiftOperator: peg$parseshiftOperator, shorthandFunction: peg$parseshorthandFunction, singleArrow: peg$parsesingleArrow, singleLineComment: peg$parsesingleLineComment, singleQuoteString: peg$parsesingleQuoteString, singleQuoteStringChar: peg$parsesingleQuoteStringChar, spreadElement: peg$parsespreadElement, stringLiteral: peg$parsestringLiteral, templateDocument: peg$parsetemplateDocument, templateDocumentChar: peg$parsetemplateDocumentChar, templateDocumentText: peg$parsetemplateDocumentText, templateLiteral: peg$parsetemplateLiteral, templateLiteralChar: peg$parsetemplateLiteralChar, templateLiteralText: peg$parsetemplateLiteralText, templateSubstitution: peg$parsetemplateSubstitution, textChar: peg$parsetextChar, unaryExpression: peg$parseunaryExpression, unaryOperator: peg$parseunaryOperator, whitespaceWithNewLine: peg$parsewhitespaceWithNewLine };
206
206
  var peg$startRuleFunction = peg$parse__;
207
207
 
208
208
  var peg$c0 = "[";
@@ -412,7 +412,7 @@ function peg$parse(input, options) {
412
412
  return annotate(tail.reduce(makeCall, head), location());
413
413
  };
414
414
  var peg$f11 = function() {
415
- error("Expected right curly brace");
415
+ error(`An object ended without a closing brace, or contained something that wasn't expected.\nThe top level of an object can only contain definitions ("a: b" or "a = b") or spreads ("...a").`);
416
416
  };
417
417
  var peg$f12 = function() {
418
418
  error("Expected right bracket");
@@ -425,12 +425,15 @@ function peg$parse(input, options) {
425
425
  ? list[0]
426
426
  : annotate([ops.comma, ...list], location());
427
427
  };
428
- var peg$f15 = function(condition, truthy, falsy) {
428
+ var peg$f15 = function(condition, tail) {
429
+ if (!tail) {
430
+ return condition;
431
+ }
429
432
  return annotate([
430
433
  ops.conditional,
431
434
  downgradeReference(condition),
432
- [ops.lambda, [], downgradeReference(truthy)],
433
- [ops.lambda, [], downgradeReference(falsy)]
435
+ [ops.lambda, [], downgradeReference(tail[0])],
436
+ [ops.lambda, [], downgradeReference(tail[1])]
434
437
  ], location());
435
438
  };
436
439
  var peg$f16 = function(chars) {
@@ -447,7 +450,7 @@ function peg$parse(input, options) {
447
450
  var peg$f23 = function() { return "\t"; };
448
451
  var peg$f24 = function() { return "\v"; };
449
452
  var peg$f25 = function(left, right) {
450
- return annotate([ops.exponentiation, left, right], location());
453
+ return right ? annotate([ops.exponentiation, left, right], location()) : left;
451
454
  };
452
455
  var peg$f26 = function() {
453
456
  return annotate([ops.literal, parseFloat(text())], location());
@@ -600,25 +603,25 @@ function peg$parse(input, options) {
600
603
  var peg$f68 = function(value) {
601
604
  return annotate([ops.spread, value], location());
602
605
  };
603
- var peg$f69 = function(contents) {
604
- return annotate([ops.lambda, ["_"], contents], location());
605
- };
606
- var peg$f70 = function(head, tail) {
607
- return annotate(makeTemplate(ops.template, head, tail), location());
606
+ var peg$f69 = function(head, tail) {
607
+ return annotate(
608
+ [ops.lambda, ["_"], makeTemplate(ops.templateIndent, head, tail)],
609
+ location()
610
+ );
608
611
  };
609
- var peg$f71 = function(chars) {
612
+ var peg$f70 = function(chars) {
610
613
  return chars.join("");
611
614
  };
612
- var peg$f72 = function(contents) {
613
- return annotate(makeTemplate(ops.template, contents[0], contents[1]), location());
615
+ var peg$f71 = function(head, tail) {
616
+ return annotate(makeTemplate(ops.template, head, tail), location());
614
617
  };
615
- var peg$f73 = function(chars) {
618
+ var peg$f72 = function(chars) {
616
619
  return chars.join("");
617
620
  };
618
- var peg$f74 = function(expression) {
621
+ var peg$f73 = function(expression) {
619
622
  return annotate(expression, location());
620
623
  };
621
- var peg$f75 = function(operator, expression) {
624
+ var peg$f74 = function(operator, expression) {
622
625
  return annotate(makeUnaryOperation(operator, expression), location());
623
626
  };
624
627
  var peg$currPos = options.peg$currPos | 0;
@@ -985,7 +988,7 @@ function peg$parse(input, options) {
985
988
  function peg$parsearrayEntry() {
986
989
  var s0, s1, s2, s3;
987
990
 
988
- s0 = peg$parsespread();
991
+ s0 = peg$parsespreadElement();
989
992
  if (s0 === peg$FAILED) {
990
993
  s0 = peg$parsepipelineExpression();
991
994
  if (s0 === peg$FAILED) {
@@ -1546,60 +1549,62 @@ function peg$parse(input, options) {
1546
1549
  }
1547
1550
 
1548
1551
  function peg$parseconditionalExpression() {
1549
- var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;
1552
+ var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10;
1550
1553
 
1551
1554
  s0 = peg$currPos;
1552
1555
  s1 = peg$parselogicalOrExpression();
1553
1556
  if (s1 !== peg$FAILED) {
1554
- s2 = peg$parse__();
1557
+ s2 = peg$currPos;
1558
+ s3 = peg$parse__();
1555
1559
  if (input.charCodeAt(peg$currPos) === 63) {
1556
- s3 = peg$c9;
1560
+ s4 = peg$c9;
1557
1561
  peg$currPos++;
1558
1562
  } else {
1559
- s3 = peg$FAILED;
1563
+ s4 = peg$FAILED;
1560
1564
  if (peg$silentFails === 0) { peg$fail(peg$e15); }
1561
1565
  }
1562
- if (s3 !== peg$FAILED) {
1563
- s4 = peg$parse__();
1564
- s5 = peg$parsepipelineExpression();
1565
- if (s5 !== peg$FAILED) {
1566
- s6 = peg$parse__();
1566
+ if (s4 !== peg$FAILED) {
1567
+ s5 = peg$parse__();
1568
+ s6 = peg$parsepipelineExpression();
1569
+ if (s6 !== peg$FAILED) {
1570
+ s7 = peg$parse__();
1567
1571
  if (input.charCodeAt(peg$currPos) === 58) {
1568
- s7 = peg$c10;
1572
+ s8 = peg$c10;
1569
1573
  peg$currPos++;
1570
1574
  } else {
1571
- s7 = peg$FAILED;
1575
+ s8 = peg$FAILED;
1572
1576
  if (peg$silentFails === 0) { peg$fail(peg$e16); }
1573
1577
  }
1574
- if (s7 !== peg$FAILED) {
1575
- s8 = peg$parse__();
1576
- s9 = peg$parsepipelineExpression();
1577
- if (s9 !== peg$FAILED) {
1578
- peg$savedPos = s0;
1579
- s0 = peg$f15(s1, s5, s9);
1578
+ if (s8 !== peg$FAILED) {
1579
+ s9 = peg$parse__();
1580
+ s10 = peg$parsepipelineExpression();
1581
+ if (s10 !== peg$FAILED) {
1582
+ s2 = [ s6, s10 ];
1580
1583
  } else {
1581
- peg$currPos = s0;
1582
- s0 = peg$FAILED;
1584
+ peg$currPos = s2;
1585
+ s2 = peg$FAILED;
1583
1586
  }
1584
1587
  } else {
1585
- peg$currPos = s0;
1586
- s0 = peg$FAILED;
1588
+ peg$currPos = s2;
1589
+ s2 = peg$FAILED;
1587
1590
  }
1588
1591
  } else {
1589
- peg$currPos = s0;
1590
- s0 = peg$FAILED;
1592
+ peg$currPos = s2;
1593
+ s2 = peg$FAILED;
1591
1594
  }
1592
1595
  } else {
1593
- peg$currPos = s0;
1594
- s0 = peg$FAILED;
1596
+ peg$currPos = s2;
1597
+ s2 = peg$FAILED;
1598
+ }
1599
+ if (s2 === peg$FAILED) {
1600
+ s2 = null;
1595
1601
  }
1602
+ peg$savedPos = s0;
1603
+ s0 = peg$f15(s1, s2);
1596
1604
  } else {
1597
1605
  peg$currPos = s0;
1598
1606
  s0 = peg$FAILED;
1599
1607
  }
1600
- if (s0 === peg$FAILED) {
1601
- s0 = peg$parselogicalOrExpression();
1602
- }
1603
1608
 
1604
1609
  return s0;
1605
1610
  }
@@ -2009,40 +2014,42 @@ function peg$parse(input, options) {
2009
2014
  }
2010
2015
 
2011
2016
  function peg$parseexponentiationExpression() {
2012
- var s0, s1, s2, s3, s4, s5;
2017
+ var s0, s1, s2, s3, s4, s5, s6;
2013
2018
 
2014
2019
  s0 = peg$currPos;
2015
2020
  s1 = peg$parseunaryExpression();
2016
2021
  if (s1 !== peg$FAILED) {
2017
- s2 = peg$parse__();
2022
+ s2 = peg$currPos;
2023
+ s3 = peg$parse__();
2018
2024
  if (input.substr(peg$currPos, 2) === peg$c28) {
2019
- s3 = peg$c28;
2025
+ s4 = peg$c28;
2020
2026
  peg$currPos += 2;
2021
2027
  } else {
2022
- s3 = peg$FAILED;
2028
+ s4 = peg$FAILED;
2023
2029
  if (peg$silentFails === 0) { peg$fail(peg$e37); }
2024
2030
  }
2025
- if (s3 !== peg$FAILED) {
2026
- s4 = peg$parse__();
2027
- s5 = peg$parseexponentiationExpression();
2028
- if (s5 !== peg$FAILED) {
2029
- peg$savedPos = s0;
2030
- s0 = peg$f25(s1, s5);
2031
+ if (s4 !== peg$FAILED) {
2032
+ s5 = peg$parse__();
2033
+ s6 = peg$parseexponentiationExpression();
2034
+ if (s6 !== peg$FAILED) {
2035
+ s2 = s6;
2031
2036
  } else {
2032
- peg$currPos = s0;
2033
- s0 = peg$FAILED;
2037
+ peg$currPos = s2;
2038
+ s2 = peg$FAILED;
2034
2039
  }
2035
2040
  } else {
2036
- peg$currPos = s0;
2037
- s0 = peg$FAILED;
2041
+ peg$currPos = s2;
2042
+ s2 = peg$FAILED;
2043
+ }
2044
+ if (s2 === peg$FAILED) {
2045
+ s2 = null;
2038
2046
  }
2047
+ peg$savedPos = s0;
2048
+ s0 = peg$f25(s1, s2);
2039
2049
  } else {
2040
2050
  peg$currPos = s0;
2041
2051
  s0 = peg$FAILED;
2042
2052
  }
2043
- if (s0 === peg$FAILED) {
2044
- s0 = peg$parseunaryExpression();
2045
- }
2046
2053
 
2047
2054
  return s0;
2048
2055
  }
@@ -3173,7 +3180,7 @@ function peg$parse(input, options) {
3173
3180
  function peg$parseobjectEntry() {
3174
3181
  var s0;
3175
3182
 
3176
- s0 = peg$parsespread();
3183
+ s0 = peg$parsespreadElement();
3177
3184
  if (s0 === peg$FAILED) {
3178
3185
  s0 = peg$parseobjectProperty();
3179
3186
  if (s0 === peg$FAILED) {
@@ -4307,14 +4314,14 @@ function peg$parse(input, options) {
4307
4314
  return s0;
4308
4315
  }
4309
4316
 
4310
- function peg$parsespread() {
4317
+ function peg$parsespreadElement() {
4311
4318
  var s0, s1, s2, s3;
4312
4319
 
4313
4320
  s0 = peg$currPos;
4314
4321
  s1 = peg$parseellipsis();
4315
4322
  if (s1 !== peg$FAILED) {
4316
4323
  s2 = peg$parse__();
4317
- s3 = peg$parseconditionalExpression();
4324
+ s3 = peg$parsepipelineExpression();
4318
4325
  if (s3 !== peg$FAILED) {
4319
4326
  peg$savedPos = s0;
4320
4327
  s0 = peg$f68(s3);
@@ -4351,14 +4358,37 @@ function peg$parse(input, options) {
4351
4358
  }
4352
4359
 
4353
4360
  function peg$parsetemplateDocument() {
4354
- var s0, s1;
4361
+ var s0, s1, s2, s3, s4, s5;
4355
4362
 
4356
4363
  peg$silentFails++;
4357
4364
  s0 = peg$currPos;
4358
- s1 = peg$parsetemplateDocumentContents();
4365
+ s1 = peg$parsetemplateDocumentText();
4366
+ s2 = [];
4367
+ s3 = peg$currPos;
4368
+ s4 = peg$parsetemplateSubstitution();
4369
+ if (s4 !== peg$FAILED) {
4370
+ s5 = peg$parsetemplateDocumentText();
4371
+ s4 = [s4, s5];
4372
+ s3 = s4;
4373
+ } else {
4374
+ peg$currPos = s3;
4375
+ s3 = peg$FAILED;
4376
+ }
4377
+ while (s3 !== peg$FAILED) {
4378
+ s2.push(s3);
4379
+ s3 = peg$currPos;
4380
+ s4 = peg$parsetemplateSubstitution();
4381
+ if (s4 !== peg$FAILED) {
4382
+ s5 = peg$parsetemplateDocumentText();
4383
+ s4 = [s4, s5];
4384
+ s3 = s4;
4385
+ } else {
4386
+ peg$currPos = s3;
4387
+ s3 = peg$FAILED;
4388
+ }
4389
+ }
4359
4390
  peg$savedPos = s0;
4360
- s1 = peg$f69(s1);
4361
- s0 = s1;
4391
+ s0 = peg$f69(s1, s2);
4362
4392
  peg$silentFails--;
4363
4393
  s1 = peg$FAILED;
4364
4394
  if (peg$silentFails === 0) { peg$fail(peg$e94); }
@@ -4402,41 +4432,6 @@ function peg$parse(input, options) {
4402
4432
  return s0;
4403
4433
  }
4404
4434
 
4405
- function peg$parsetemplateDocumentContents() {
4406
- var s0, s1, s2, s3, s4, s5;
4407
-
4408
- s0 = peg$currPos;
4409
- s1 = peg$parsetemplateDocumentText();
4410
- s2 = [];
4411
- s3 = peg$currPos;
4412
- s4 = peg$parsetemplateSubstitution();
4413
- if (s4 !== peg$FAILED) {
4414
- s5 = peg$parsetemplateDocumentText();
4415
- s4 = [s4, s5];
4416
- s3 = s4;
4417
- } else {
4418
- peg$currPos = s3;
4419
- s3 = peg$FAILED;
4420
- }
4421
- while (s3 !== peg$FAILED) {
4422
- s2.push(s3);
4423
- s3 = peg$currPos;
4424
- s4 = peg$parsetemplateSubstitution();
4425
- if (s4 !== peg$FAILED) {
4426
- s5 = peg$parsetemplateDocumentText();
4427
- s4 = [s4, s5];
4428
- s3 = s4;
4429
- } else {
4430
- peg$currPos = s3;
4431
- s3 = peg$FAILED;
4432
- }
4433
- }
4434
- peg$savedPos = s0;
4435
- s0 = peg$f70(s1, s2);
4436
-
4437
- return s0;
4438
- }
4439
-
4440
4435
  function peg$parsetemplateDocumentText() {
4441
4436
  var s0, s1, s2;
4442
4437
 
@@ -4449,7 +4444,7 @@ function peg$parse(input, options) {
4449
4444
  s2 = peg$parsetemplateDocumentChar();
4450
4445
  }
4451
4446
  peg$savedPos = s0;
4452
- s1 = peg$f71(s1);
4447
+ s1 = peg$f70(s1);
4453
4448
  s0 = s1;
4454
4449
  peg$silentFails--;
4455
4450
  s1 = peg$FAILED;
@@ -4459,7 +4454,7 @@ function peg$parse(input, options) {
4459
4454
  }
4460
4455
 
4461
4456
  function peg$parsetemplateLiteral() {
4462
- var s0, s1, s2, s3;
4457
+ var s0, s1, s2, s3, s4, s5, s6;
4463
4458
 
4464
4459
  peg$silentFails++;
4465
4460
  s0 = peg$currPos;
@@ -4471,17 +4466,41 @@ function peg$parse(input, options) {
4471
4466
  if (peg$silentFails === 0) { peg$fail(peg$e98); }
4472
4467
  }
4473
4468
  if (s1 !== peg$FAILED) {
4474
- s2 = peg$parsetemplateLiteralContents();
4469
+ s2 = peg$parsetemplateLiteralText();
4470
+ s3 = [];
4471
+ s4 = peg$currPos;
4472
+ s5 = peg$parsetemplateSubstitution();
4473
+ if (s5 !== peg$FAILED) {
4474
+ s6 = peg$parsetemplateLiteralText();
4475
+ s5 = [s5, s6];
4476
+ s4 = s5;
4477
+ } else {
4478
+ peg$currPos = s4;
4479
+ s4 = peg$FAILED;
4480
+ }
4481
+ while (s4 !== peg$FAILED) {
4482
+ s3.push(s4);
4483
+ s4 = peg$currPos;
4484
+ s5 = peg$parsetemplateSubstitution();
4485
+ if (s5 !== peg$FAILED) {
4486
+ s6 = peg$parsetemplateLiteralText();
4487
+ s5 = [s5, s6];
4488
+ s4 = s5;
4489
+ } else {
4490
+ peg$currPos = s4;
4491
+ s4 = peg$FAILED;
4492
+ }
4493
+ }
4475
4494
  if (input.charCodeAt(peg$currPos) === 96) {
4476
- s3 = peg$c59;
4495
+ s4 = peg$c59;
4477
4496
  peg$currPos++;
4478
4497
  } else {
4479
- s3 = peg$FAILED;
4498
+ s4 = peg$FAILED;
4480
4499
  if (peg$silentFails === 0) { peg$fail(peg$e98); }
4481
4500
  }
4482
- if (s3 !== peg$FAILED) {
4501
+ if (s4 !== peg$FAILED) {
4483
4502
  peg$savedPos = s0;
4484
- s0 = peg$f72(s2);
4503
+ s0 = peg$f71(s2, s3);
4485
4504
  } else {
4486
4505
  peg$currPos = s0;
4487
4506
  s0 = peg$FAILED;
@@ -4544,41 +4563,6 @@ function peg$parse(input, options) {
4544
4563
  return s0;
4545
4564
  }
4546
4565
 
4547
- function peg$parsetemplateLiteralContents() {
4548
- var s0, s1, s2, s3, s4, s5;
4549
-
4550
- s0 = peg$currPos;
4551
- s1 = peg$parsetemplateLiteralText();
4552
- s2 = [];
4553
- s3 = peg$currPos;
4554
- s4 = peg$parsetemplateSubstitution();
4555
- if (s4 !== peg$FAILED) {
4556
- s5 = peg$parsetemplateLiteralText();
4557
- s4 = [s4, s5];
4558
- s3 = s4;
4559
- } else {
4560
- peg$currPos = s3;
4561
- s3 = peg$FAILED;
4562
- }
4563
- while (s3 !== peg$FAILED) {
4564
- s2.push(s3);
4565
- s3 = peg$currPos;
4566
- s4 = peg$parsetemplateSubstitution();
4567
- if (s4 !== peg$FAILED) {
4568
- s5 = peg$parsetemplateLiteralText();
4569
- s4 = [s4, s5];
4570
- s3 = s4;
4571
- } else {
4572
- peg$currPos = s3;
4573
- s3 = peg$FAILED;
4574
- }
4575
- }
4576
- s1 = [s1, s2];
4577
- s0 = s1;
4578
-
4579
- return s0;
4580
- }
4581
-
4582
4566
  function peg$parsetemplateLiteralText() {
4583
4567
  var s0, s1, s2;
4584
4568
 
@@ -4590,7 +4574,7 @@ function peg$parse(input, options) {
4590
4574
  s2 = peg$parsetemplateLiteralChar();
4591
4575
  }
4592
4576
  peg$savedPos = s0;
4593
- s1 = peg$f73(s1);
4577
+ s1 = peg$f72(s1);
4594
4578
  s0 = s1;
4595
4579
 
4596
4580
  return s0;
@@ -4620,7 +4604,7 @@ function peg$parse(input, options) {
4620
4604
  }
4621
4605
  if (s3 !== peg$FAILED) {
4622
4606
  peg$savedPos = s0;
4623
- s0 = peg$f74(s2);
4607
+ s0 = peg$f73(s2);
4624
4608
  } else {
4625
4609
  peg$currPos = s0;
4626
4610
  s0 = peg$FAILED;
@@ -4669,7 +4653,7 @@ function peg$parse(input, options) {
4669
4653
  s3 = peg$parseunaryExpression();
4670
4654
  if (s3 !== peg$FAILED) {
4671
4655
  peg$savedPos = s0;
4672
- s0 = peg$f75(s1, s3);
4656
+ s0 = peg$f74(s1, s3);
4673
4657
  } else {
4674
4658
  peg$currPos = s0;
4675
4659
  s0 = peg$FAILED;
@@ -4845,15 +4829,13 @@ const peg$allowedStartRules = [
4845
4829
  "singleLineComment",
4846
4830
  "singleQuoteString",
4847
4831
  "singleQuoteStringChar",
4848
- "spread",
4832
+ "spreadElement",
4849
4833
  "stringLiteral",
4850
4834
  "templateDocument",
4851
4835
  "templateDocumentChar",
4852
- "templateDocumentContents",
4853
4836
  "templateDocumentText",
4854
4837
  "templateLiteral",
4855
4838
  "templateLiteralChar",
4856
- "templateLiteralContents",
4857
4839
  "templateLiteralText",
4858
4840
  "templateSubstitution",
4859
4841
  "textChar",
@@ -76,22 +76,6 @@ export function downgradeReference(code) {
76
76
  }
77
77
  }
78
78
 
79
- // Return true if the code will generate an async object.
80
- function isCodeForAsyncObject(code) {
81
- if (!(code instanceof Array)) {
82
- return false;
83
- }
84
- if (code[0] !== ops.object) {
85
- return false;
86
- }
87
- // Are any of the properties getters?
88
- const entries = code.slice(1);
89
- const hasGetter = entries.some(([key, value]) => {
90
- return value instanceof Array && value[0] === ops.getter;
91
- });
92
- return hasGetter;
93
- }
94
-
95
79
  export function makeArray(entries) {
96
80
  let currentEntries = [];
97
81
  const spreads = [];
@@ -260,17 +244,24 @@ export function makeObject(entries, op) {
260
244
  continue;
261
245
  }
262
246
 
263
- if (
264
- value instanceof Array &&
265
- value[0] === ops.getter &&
266
- value[1] instanceof Array &&
267
- value[1][0] === ops.literal
268
- ) {
269
- // Simplify a getter for a primitive value to a regular property
270
- value = value[1];
271
- } else if (isCodeForAsyncObject(value)) {
272
- // Add a trailing slash to key to indicate value is a subtree
273
- key = key + "/";
247
+ if (value instanceof Array) {
248
+ if (
249
+ value[0] === ops.getter &&
250
+ value[1] instanceof Array &&
251
+ value[1][0] === ops.literal
252
+ ) {
253
+ // Optimize a getter for a primitive value to a regular property
254
+ value = value[1];
255
+ }
256
+ // else if (
257
+ // value[0] === ops.object ||
258
+ // (value[0] === ops.getter &&
259
+ // value[1] instanceof Array &&
260
+ // (value[1][0] === ops.object || value[1][0] === ops.merge))
261
+ // ) {
262
+ // // Add a trailing slash to key to indicate value is a subtree
263
+ // key = trailingSlash.add(key);
264
+ // }
274
265
  }
275
266
 
276
267
  currentEntries.push([key, value]);
@@ -1,6 +1,10 @@
1
1
  // Text we look for in an error stack to guess whether a given line represents a
2
2
 
3
- import { scope as scopeFn, trailingSlash } from "@weborigami/async-tree";
3
+ import {
4
+ scope as scopeFn,
5
+ trailingSlash,
6
+ TraverseError,
7
+ } from "@weborigami/async-tree";
4
8
  import codeFragment from "./codeFragment.js";
5
9
  import { typos } from "./typos.js";
6
10
 
@@ -13,19 +17,24 @@ const origamiSourceSignals = [
13
17
  ];
14
18
 
15
19
  export async function builtinReferenceError(tree, builtins, key) {
16
- const messages = [
17
- `"${key}" is being called as if it were a builtin function, but it's not.`,
18
- ];
19
20
  // See if the key is in scope (but not as a builtin)
20
21
  const scope = scopeFn(tree);
21
22
  const value = await scope.get(key);
23
+ let message;
22
24
  if (value === undefined) {
25
+ const messages = [
26
+ `"${key}" is being called as if it were a builtin function, but it's not.`,
27
+ ];
23
28
  const typos = await formatScopeTypos(builtins, key);
24
29
  messages.push(typos);
30
+ message = messages.join(" ");
25
31
  } else {
26
- messages.push(`Use "${key}/" instead.`);
32
+ const messages = [
33
+ `To call a function like "${key}" that's not a builtin, include a slash: ${key}/( )`,
34
+ `Details: https://weborigami.org/language/syntax.html#shorthand-for-builtin-functions`,
35
+ ];
36
+ message = messages.join("\n");
27
37
  }
28
- const message = messages.join(" ");
29
38
  return new ReferenceError(message);
30
39
  }
31
40
 
@@ -36,37 +45,50 @@ export async function builtinReferenceError(tree, builtins, key) {
36
45
  */
37
46
  export function formatError(error) {
38
47
  let message;
48
+
49
+ let location = /** @type {any} */ (error).location;
50
+ const fragment = location ? codeFragment(location) : null;
51
+ let fragmentInMessage = false;
52
+
39
53
  if (error.stack) {
40
54
  // Display the stack only until we reach the Origami source code.
41
55
  message = "";
42
56
  let lines = error.stack.split("\n");
43
57
  for (let i = 0; i < lines.length; i++) {
44
- const line = lines[i];
58
+ let line = lines[i];
45
59
  if (maybeOrigamiSourceCode(line)) {
46
60
  break;
47
61
  }
62
+ if (
63
+ error instanceof TraverseError &&
64
+ error.message === "A null or undefined value can't be traversed"
65
+ ) {
66
+ // Provide more meaningful message for TraverseError
67
+ line = `TraverseError: This part of the path is null or undefined: ${fragment}`;
68
+ fragmentInMessage = true;
69
+ }
48
70
  if (message) {
49
71
  message += "\n";
50
72
  }
51
- message += lines[i];
73
+ message += line;
52
74
  }
53
75
  } else {
54
76
  message = error.toString();
55
77
  }
56
78
 
57
79
  // Add location
58
- let location = /** @type {any} */ (error).location;
59
80
  if (location) {
60
- const fragment = codeFragment(location);
61
81
  let { source, start } = location;
62
-
63
- message += `\nevaluating: ${fragment}`;
82
+ if (!fragmentInMessage) {
83
+ message += `\nevaluating: ${fragment}`;
84
+ }
64
85
  if (typeof source === "object" && source.url) {
65
86
  message += `\n at ${source.url.href}:${start.line}:${start.column}`;
66
87
  } else if (source.text.includes("\n")) {
67
88
  message += `\n at line ${start.line}, column ${start.column}`;
68
89
  }
69
90
  }
91
+
70
92
  return message;
71
93
  }
72
94