@weborigami/language 0.2.2 → 0.2.4
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/LICENSE +21 -0
- package/main.js +1 -0
- package/package.json +7 -7
- package/src/compiler/compile.js +43 -23
- package/src/compiler/origami.pegjs +17 -19
- package/src/compiler/parse.js +160 -142
- package/src/compiler/parserHelpers.js +18 -27
- package/src/runtime/expressionObject.js +56 -13
- package/src/runtime/mergeTrees.js +23 -3
- package/src/runtime/ops.js +10 -1
- package/src/runtime/taggedTemplate.js +1 -1
- package/src/runtime/taggedTemplateIndent.js +115 -0
- package/test/compiler/compile.test.js +19 -5
- package/test/compiler/parse.test.js +18 -3
- package/test/runtime/expressionObject.test.js +19 -1
- package/test/runtime/mergeTrees.test.js +33 -15
- package/test/runtime/taggedTemplateIndent.test.js +44 -0
package/src/compiler/parse.js
CHANGED
|
@@ -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, spreadElement: peg$parsespreadElement, stringLiteral: peg$parsestringLiteral, templateDocument: peg$parsetemplateDocument, templateDocumentChar: peg$parsetemplateDocumentChar,
|
|
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, whitespace: peg$parsewhitespace, whitespaceWithNewLine: peg$parsewhitespaceWithNewLine };
|
|
206
206
|
var peg$startRuleFunction = peg$parse__;
|
|
207
207
|
|
|
208
208
|
var peg$c0 = "[";
|
|
@@ -603,25 +603,25 @@ function peg$parse(input, options) {
|
|
|
603
603
|
var peg$f68 = function(value) {
|
|
604
604
|
return annotate([ops.spread, value], location());
|
|
605
605
|
};
|
|
606
|
-
var peg$f69 = function(
|
|
607
|
-
return annotate(
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
606
|
+
var peg$f69 = function(head, tail) {
|
|
607
|
+
return annotate(
|
|
608
|
+
[ops.lambda, ["_"], makeTemplate(ops.templateIndent, head, tail)],
|
|
609
|
+
location()
|
|
610
|
+
);
|
|
611
611
|
};
|
|
612
|
-
var peg$
|
|
612
|
+
var peg$f70 = function(chars) {
|
|
613
613
|
return chars.join("");
|
|
614
614
|
};
|
|
615
|
-
var peg$
|
|
616
|
-
return annotate(makeTemplate(ops.template,
|
|
615
|
+
var peg$f71 = function(head, tail) {
|
|
616
|
+
return annotate(makeTemplate(ops.template, head, tail), location());
|
|
617
617
|
};
|
|
618
|
-
var peg$
|
|
618
|
+
var peg$f72 = function(chars) {
|
|
619
619
|
return chars.join("");
|
|
620
620
|
};
|
|
621
|
-
var peg$
|
|
621
|
+
var peg$f73 = function(expression) {
|
|
622
622
|
return annotate(expression, location());
|
|
623
623
|
};
|
|
624
|
-
var peg$
|
|
624
|
+
var peg$f74 = function(operator, expression) {
|
|
625
625
|
return annotate(makeUnaryOperation(operator, expression), location());
|
|
626
626
|
};
|
|
627
627
|
var peg$currPos = options.peg$currPos | 0;
|
|
@@ -791,22 +791,10 @@ function peg$parse(input, options) {
|
|
|
791
791
|
|
|
792
792
|
s0 = peg$currPos;
|
|
793
793
|
s1 = [];
|
|
794
|
-
s2 = peg$
|
|
795
|
-
if (s2 === peg$FAILED) {
|
|
796
|
-
s2 = peg$parsenewLine();
|
|
797
|
-
if (s2 === peg$FAILED) {
|
|
798
|
-
s2 = peg$parsecomment();
|
|
799
|
-
}
|
|
800
|
-
}
|
|
794
|
+
s2 = peg$parsewhitespace();
|
|
801
795
|
while (s2 !== peg$FAILED) {
|
|
802
796
|
s1.push(s2);
|
|
803
|
-
s2 = peg$
|
|
804
|
-
if (s2 === peg$FAILED) {
|
|
805
|
-
s2 = peg$parsenewLine();
|
|
806
|
-
if (s2 === peg$FAILED) {
|
|
807
|
-
s2 = peg$parsecomment();
|
|
808
|
-
}
|
|
809
|
-
}
|
|
797
|
+
s2 = peg$parsewhitespace();
|
|
810
798
|
}
|
|
811
799
|
peg$savedPos = s0;
|
|
812
800
|
s1 = peg$f0();
|
|
@@ -823,13 +811,23 @@ function peg$parse(input, options) {
|
|
|
823
811
|
if (s1 !== peg$FAILED) {
|
|
824
812
|
s2 = [];
|
|
825
813
|
s3 = peg$currPos;
|
|
826
|
-
s4 = peg$
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
814
|
+
s4 = peg$parsewhitespace();
|
|
815
|
+
if (s4 !== peg$FAILED) {
|
|
816
|
+
s5 = peg$parseadditiveOperator();
|
|
817
|
+
if (s5 !== peg$FAILED) {
|
|
818
|
+
s6 = peg$parsewhitespace();
|
|
819
|
+
if (s6 !== peg$FAILED) {
|
|
820
|
+
s7 = peg$parsemultiplicativeExpression();
|
|
821
|
+
if (s7 !== peg$FAILED) {
|
|
822
|
+
s3 = [ s5, s7 ];
|
|
823
|
+
} else {
|
|
824
|
+
peg$currPos = s3;
|
|
825
|
+
s3 = peg$FAILED;
|
|
826
|
+
}
|
|
827
|
+
} else {
|
|
828
|
+
peg$currPos = s3;
|
|
829
|
+
s3 = peg$FAILED;
|
|
830
|
+
}
|
|
833
831
|
} else {
|
|
834
832
|
peg$currPos = s3;
|
|
835
833
|
s3 = peg$FAILED;
|
|
@@ -841,13 +839,23 @@ function peg$parse(input, options) {
|
|
|
841
839
|
while (s3 !== peg$FAILED) {
|
|
842
840
|
s2.push(s3);
|
|
843
841
|
s3 = peg$currPos;
|
|
844
|
-
s4 = peg$
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
842
|
+
s4 = peg$parsewhitespace();
|
|
843
|
+
if (s4 !== peg$FAILED) {
|
|
844
|
+
s5 = peg$parseadditiveOperator();
|
|
845
|
+
if (s5 !== peg$FAILED) {
|
|
846
|
+
s6 = peg$parsewhitespace();
|
|
847
|
+
if (s6 !== peg$FAILED) {
|
|
848
|
+
s7 = peg$parsemultiplicativeExpression();
|
|
849
|
+
if (s7 !== peg$FAILED) {
|
|
850
|
+
s3 = [ s5, s7 ];
|
|
851
|
+
} else {
|
|
852
|
+
peg$currPos = s3;
|
|
853
|
+
s3 = peg$FAILED;
|
|
854
|
+
}
|
|
855
|
+
} else {
|
|
856
|
+
peg$currPos = s3;
|
|
857
|
+
s3 = peg$FAILED;
|
|
858
|
+
}
|
|
851
859
|
} else {
|
|
852
860
|
peg$currPos = s3;
|
|
853
861
|
s3 = peg$FAILED;
|
|
@@ -1565,7 +1573,7 @@ function peg$parse(input, options) {
|
|
|
1565
1573
|
}
|
|
1566
1574
|
if (s4 !== peg$FAILED) {
|
|
1567
1575
|
s5 = peg$parse__();
|
|
1568
|
-
s6 = peg$
|
|
1576
|
+
s6 = peg$parseshorthandFunction();
|
|
1569
1577
|
if (s6 !== peg$FAILED) {
|
|
1570
1578
|
s7 = peg$parse__();
|
|
1571
1579
|
if (input.charCodeAt(peg$currPos) === 58) {
|
|
@@ -1577,7 +1585,7 @@ function peg$parse(input, options) {
|
|
|
1577
1585
|
}
|
|
1578
1586
|
if (s8 !== peg$FAILED) {
|
|
1579
1587
|
s9 = peg$parse__();
|
|
1580
|
-
s10 = peg$
|
|
1588
|
+
s10 = peg$parseshorthandFunction();
|
|
1581
1589
|
if (s10 !== peg$FAILED) {
|
|
1582
1590
|
s2 = [ s6, s10 ];
|
|
1583
1591
|
} else {
|
|
@@ -2863,13 +2871,23 @@ function peg$parse(input, options) {
|
|
|
2863
2871
|
if (s1 !== peg$FAILED) {
|
|
2864
2872
|
s2 = [];
|
|
2865
2873
|
s3 = peg$currPos;
|
|
2866
|
-
s4 = peg$
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2874
|
+
s4 = peg$parsewhitespace();
|
|
2875
|
+
if (s4 !== peg$FAILED) {
|
|
2876
|
+
s5 = peg$parsemultiplicativeOperator();
|
|
2877
|
+
if (s5 !== peg$FAILED) {
|
|
2878
|
+
s6 = peg$parsewhitespace();
|
|
2879
|
+
if (s6 !== peg$FAILED) {
|
|
2880
|
+
s7 = peg$parseexponentiationExpression();
|
|
2881
|
+
if (s7 !== peg$FAILED) {
|
|
2882
|
+
s3 = [ s5, s7 ];
|
|
2883
|
+
} else {
|
|
2884
|
+
peg$currPos = s3;
|
|
2885
|
+
s3 = peg$FAILED;
|
|
2886
|
+
}
|
|
2887
|
+
} else {
|
|
2888
|
+
peg$currPos = s3;
|
|
2889
|
+
s3 = peg$FAILED;
|
|
2890
|
+
}
|
|
2873
2891
|
} else {
|
|
2874
2892
|
peg$currPos = s3;
|
|
2875
2893
|
s3 = peg$FAILED;
|
|
@@ -2881,13 +2899,23 @@ function peg$parse(input, options) {
|
|
|
2881
2899
|
while (s3 !== peg$FAILED) {
|
|
2882
2900
|
s2.push(s3);
|
|
2883
2901
|
s3 = peg$currPos;
|
|
2884
|
-
s4 = peg$
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2902
|
+
s4 = peg$parsewhitespace();
|
|
2903
|
+
if (s4 !== peg$FAILED) {
|
|
2904
|
+
s5 = peg$parsemultiplicativeOperator();
|
|
2905
|
+
if (s5 !== peg$FAILED) {
|
|
2906
|
+
s6 = peg$parsewhitespace();
|
|
2907
|
+
if (s6 !== peg$FAILED) {
|
|
2908
|
+
s7 = peg$parseexponentiationExpression();
|
|
2909
|
+
if (s7 !== peg$FAILED) {
|
|
2910
|
+
s3 = [ s5, s7 ];
|
|
2911
|
+
} else {
|
|
2912
|
+
peg$currPos = s3;
|
|
2913
|
+
s3 = peg$FAILED;
|
|
2914
|
+
}
|
|
2915
|
+
} else {
|
|
2916
|
+
peg$currPos = s3;
|
|
2917
|
+
s3 = peg$FAILED;
|
|
2918
|
+
}
|
|
2891
2919
|
} else {
|
|
2892
2920
|
peg$currPos = s3;
|
|
2893
2921
|
s3 = peg$FAILED;
|
|
@@ -4358,14 +4386,37 @@ function peg$parse(input, options) {
|
|
|
4358
4386
|
}
|
|
4359
4387
|
|
|
4360
4388
|
function peg$parsetemplateDocument() {
|
|
4361
|
-
var s0, s1;
|
|
4389
|
+
var s0, s1, s2, s3, s4, s5;
|
|
4362
4390
|
|
|
4363
4391
|
peg$silentFails++;
|
|
4364
4392
|
s0 = peg$currPos;
|
|
4365
|
-
s1 = peg$
|
|
4393
|
+
s1 = peg$parsetemplateDocumentText();
|
|
4394
|
+
s2 = [];
|
|
4395
|
+
s3 = peg$currPos;
|
|
4396
|
+
s4 = peg$parsetemplateSubstitution();
|
|
4397
|
+
if (s4 !== peg$FAILED) {
|
|
4398
|
+
s5 = peg$parsetemplateDocumentText();
|
|
4399
|
+
s4 = [s4, s5];
|
|
4400
|
+
s3 = s4;
|
|
4401
|
+
} else {
|
|
4402
|
+
peg$currPos = s3;
|
|
4403
|
+
s3 = peg$FAILED;
|
|
4404
|
+
}
|
|
4405
|
+
while (s3 !== peg$FAILED) {
|
|
4406
|
+
s2.push(s3);
|
|
4407
|
+
s3 = peg$currPos;
|
|
4408
|
+
s4 = peg$parsetemplateSubstitution();
|
|
4409
|
+
if (s4 !== peg$FAILED) {
|
|
4410
|
+
s5 = peg$parsetemplateDocumentText();
|
|
4411
|
+
s4 = [s4, s5];
|
|
4412
|
+
s3 = s4;
|
|
4413
|
+
} else {
|
|
4414
|
+
peg$currPos = s3;
|
|
4415
|
+
s3 = peg$FAILED;
|
|
4416
|
+
}
|
|
4417
|
+
}
|
|
4366
4418
|
peg$savedPos = s0;
|
|
4367
|
-
|
|
4368
|
-
s0 = s1;
|
|
4419
|
+
s0 = peg$f69(s1, s2);
|
|
4369
4420
|
peg$silentFails--;
|
|
4370
4421
|
s1 = peg$FAILED;
|
|
4371
4422
|
if (peg$silentFails === 0) { peg$fail(peg$e94); }
|
|
@@ -4409,41 +4460,6 @@ function peg$parse(input, options) {
|
|
|
4409
4460
|
return s0;
|
|
4410
4461
|
}
|
|
4411
4462
|
|
|
4412
|
-
function peg$parsetemplateDocumentContents() {
|
|
4413
|
-
var s0, s1, s2, s3, s4, s5;
|
|
4414
|
-
|
|
4415
|
-
s0 = peg$currPos;
|
|
4416
|
-
s1 = peg$parsetemplateDocumentText();
|
|
4417
|
-
s2 = [];
|
|
4418
|
-
s3 = peg$currPos;
|
|
4419
|
-
s4 = peg$parsetemplateSubstitution();
|
|
4420
|
-
if (s4 !== peg$FAILED) {
|
|
4421
|
-
s5 = peg$parsetemplateDocumentText();
|
|
4422
|
-
s4 = [s4, s5];
|
|
4423
|
-
s3 = s4;
|
|
4424
|
-
} else {
|
|
4425
|
-
peg$currPos = s3;
|
|
4426
|
-
s3 = peg$FAILED;
|
|
4427
|
-
}
|
|
4428
|
-
while (s3 !== peg$FAILED) {
|
|
4429
|
-
s2.push(s3);
|
|
4430
|
-
s3 = peg$currPos;
|
|
4431
|
-
s4 = peg$parsetemplateSubstitution();
|
|
4432
|
-
if (s4 !== peg$FAILED) {
|
|
4433
|
-
s5 = peg$parsetemplateDocumentText();
|
|
4434
|
-
s4 = [s4, s5];
|
|
4435
|
-
s3 = s4;
|
|
4436
|
-
} else {
|
|
4437
|
-
peg$currPos = s3;
|
|
4438
|
-
s3 = peg$FAILED;
|
|
4439
|
-
}
|
|
4440
|
-
}
|
|
4441
|
-
peg$savedPos = s0;
|
|
4442
|
-
s0 = peg$f70(s1, s2);
|
|
4443
|
-
|
|
4444
|
-
return s0;
|
|
4445
|
-
}
|
|
4446
|
-
|
|
4447
4463
|
function peg$parsetemplateDocumentText() {
|
|
4448
4464
|
var s0, s1, s2;
|
|
4449
4465
|
|
|
@@ -4456,7 +4472,7 @@ function peg$parse(input, options) {
|
|
|
4456
4472
|
s2 = peg$parsetemplateDocumentChar();
|
|
4457
4473
|
}
|
|
4458
4474
|
peg$savedPos = s0;
|
|
4459
|
-
s1 = peg$
|
|
4475
|
+
s1 = peg$f70(s1);
|
|
4460
4476
|
s0 = s1;
|
|
4461
4477
|
peg$silentFails--;
|
|
4462
4478
|
s1 = peg$FAILED;
|
|
@@ -4466,7 +4482,7 @@ function peg$parse(input, options) {
|
|
|
4466
4482
|
}
|
|
4467
4483
|
|
|
4468
4484
|
function peg$parsetemplateLiteral() {
|
|
4469
|
-
var s0, s1, s2, s3;
|
|
4485
|
+
var s0, s1, s2, s3, s4, s5, s6;
|
|
4470
4486
|
|
|
4471
4487
|
peg$silentFails++;
|
|
4472
4488
|
s0 = peg$currPos;
|
|
@@ -4478,17 +4494,41 @@ function peg$parse(input, options) {
|
|
|
4478
4494
|
if (peg$silentFails === 0) { peg$fail(peg$e98); }
|
|
4479
4495
|
}
|
|
4480
4496
|
if (s1 !== peg$FAILED) {
|
|
4481
|
-
s2 = peg$
|
|
4497
|
+
s2 = peg$parsetemplateLiteralText();
|
|
4498
|
+
s3 = [];
|
|
4499
|
+
s4 = peg$currPos;
|
|
4500
|
+
s5 = peg$parsetemplateSubstitution();
|
|
4501
|
+
if (s5 !== peg$FAILED) {
|
|
4502
|
+
s6 = peg$parsetemplateLiteralText();
|
|
4503
|
+
s5 = [s5, s6];
|
|
4504
|
+
s4 = s5;
|
|
4505
|
+
} else {
|
|
4506
|
+
peg$currPos = s4;
|
|
4507
|
+
s4 = peg$FAILED;
|
|
4508
|
+
}
|
|
4509
|
+
while (s4 !== peg$FAILED) {
|
|
4510
|
+
s3.push(s4);
|
|
4511
|
+
s4 = peg$currPos;
|
|
4512
|
+
s5 = peg$parsetemplateSubstitution();
|
|
4513
|
+
if (s5 !== peg$FAILED) {
|
|
4514
|
+
s6 = peg$parsetemplateLiteralText();
|
|
4515
|
+
s5 = [s5, s6];
|
|
4516
|
+
s4 = s5;
|
|
4517
|
+
} else {
|
|
4518
|
+
peg$currPos = s4;
|
|
4519
|
+
s4 = peg$FAILED;
|
|
4520
|
+
}
|
|
4521
|
+
}
|
|
4482
4522
|
if (input.charCodeAt(peg$currPos) === 96) {
|
|
4483
|
-
|
|
4523
|
+
s4 = peg$c59;
|
|
4484
4524
|
peg$currPos++;
|
|
4485
4525
|
} else {
|
|
4486
|
-
|
|
4526
|
+
s4 = peg$FAILED;
|
|
4487
4527
|
if (peg$silentFails === 0) { peg$fail(peg$e98); }
|
|
4488
4528
|
}
|
|
4489
|
-
if (
|
|
4529
|
+
if (s4 !== peg$FAILED) {
|
|
4490
4530
|
peg$savedPos = s0;
|
|
4491
|
-
s0 = peg$
|
|
4531
|
+
s0 = peg$f71(s2, s3);
|
|
4492
4532
|
} else {
|
|
4493
4533
|
peg$currPos = s0;
|
|
4494
4534
|
s0 = peg$FAILED;
|
|
@@ -4551,41 +4591,6 @@ function peg$parse(input, options) {
|
|
|
4551
4591
|
return s0;
|
|
4552
4592
|
}
|
|
4553
4593
|
|
|
4554
|
-
function peg$parsetemplateLiteralContents() {
|
|
4555
|
-
var s0, s1, s2, s3, s4, s5;
|
|
4556
|
-
|
|
4557
|
-
s0 = peg$currPos;
|
|
4558
|
-
s1 = peg$parsetemplateLiteralText();
|
|
4559
|
-
s2 = [];
|
|
4560
|
-
s3 = peg$currPos;
|
|
4561
|
-
s4 = peg$parsetemplateSubstitution();
|
|
4562
|
-
if (s4 !== peg$FAILED) {
|
|
4563
|
-
s5 = peg$parsetemplateLiteralText();
|
|
4564
|
-
s4 = [s4, s5];
|
|
4565
|
-
s3 = s4;
|
|
4566
|
-
} else {
|
|
4567
|
-
peg$currPos = s3;
|
|
4568
|
-
s3 = peg$FAILED;
|
|
4569
|
-
}
|
|
4570
|
-
while (s3 !== peg$FAILED) {
|
|
4571
|
-
s2.push(s3);
|
|
4572
|
-
s3 = peg$currPos;
|
|
4573
|
-
s4 = peg$parsetemplateSubstitution();
|
|
4574
|
-
if (s4 !== peg$FAILED) {
|
|
4575
|
-
s5 = peg$parsetemplateLiteralText();
|
|
4576
|
-
s4 = [s4, s5];
|
|
4577
|
-
s3 = s4;
|
|
4578
|
-
} else {
|
|
4579
|
-
peg$currPos = s3;
|
|
4580
|
-
s3 = peg$FAILED;
|
|
4581
|
-
}
|
|
4582
|
-
}
|
|
4583
|
-
s1 = [s1, s2];
|
|
4584
|
-
s0 = s1;
|
|
4585
|
-
|
|
4586
|
-
return s0;
|
|
4587
|
-
}
|
|
4588
|
-
|
|
4589
4594
|
function peg$parsetemplateLiteralText() {
|
|
4590
4595
|
var s0, s1, s2;
|
|
4591
4596
|
|
|
@@ -4597,7 +4602,7 @@ function peg$parse(input, options) {
|
|
|
4597
4602
|
s2 = peg$parsetemplateLiteralChar();
|
|
4598
4603
|
}
|
|
4599
4604
|
peg$savedPos = s0;
|
|
4600
|
-
s1 = peg$
|
|
4605
|
+
s1 = peg$f72(s1);
|
|
4601
4606
|
s0 = s1;
|
|
4602
4607
|
|
|
4603
4608
|
return s0;
|
|
@@ -4627,7 +4632,7 @@ function peg$parse(input, options) {
|
|
|
4627
4632
|
}
|
|
4628
4633
|
if (s3 !== peg$FAILED) {
|
|
4629
4634
|
peg$savedPos = s0;
|
|
4630
|
-
s0 = peg$
|
|
4635
|
+
s0 = peg$f73(s2);
|
|
4631
4636
|
} else {
|
|
4632
4637
|
peg$currPos = s0;
|
|
4633
4638
|
s0 = peg$FAILED;
|
|
@@ -4676,7 +4681,7 @@ function peg$parse(input, options) {
|
|
|
4676
4681
|
s3 = peg$parseunaryExpression();
|
|
4677
4682
|
if (s3 !== peg$FAILED) {
|
|
4678
4683
|
peg$savedPos = s0;
|
|
4679
|
-
s0 = peg$
|
|
4684
|
+
s0 = peg$f74(s1, s3);
|
|
4680
4685
|
} else {
|
|
4681
4686
|
peg$currPos = s0;
|
|
4682
4687
|
s0 = peg$FAILED;
|
|
@@ -4706,6 +4711,20 @@ function peg$parse(input, options) {
|
|
|
4706
4711
|
return s0;
|
|
4707
4712
|
}
|
|
4708
4713
|
|
|
4714
|
+
function peg$parsewhitespace() {
|
|
4715
|
+
var s0;
|
|
4716
|
+
|
|
4717
|
+
s0 = peg$parseinlineSpace();
|
|
4718
|
+
if (s0 === peg$FAILED) {
|
|
4719
|
+
s0 = peg$parsenewLine();
|
|
4720
|
+
if (s0 === peg$FAILED) {
|
|
4721
|
+
s0 = peg$parsecomment();
|
|
4722
|
+
}
|
|
4723
|
+
}
|
|
4724
|
+
|
|
4725
|
+
return s0;
|
|
4726
|
+
}
|
|
4727
|
+
|
|
4709
4728
|
function peg$parsewhitespaceWithNewLine() {
|
|
4710
4729
|
var s0, s1, s2, s3, s4;
|
|
4711
4730
|
|
|
@@ -4856,16 +4875,15 @@ const peg$allowedStartRules = [
|
|
|
4856
4875
|
"stringLiteral",
|
|
4857
4876
|
"templateDocument",
|
|
4858
4877
|
"templateDocumentChar",
|
|
4859
|
-
"templateDocumentContents",
|
|
4860
4878
|
"templateDocumentText",
|
|
4861
4879
|
"templateLiteral",
|
|
4862
4880
|
"templateLiteralChar",
|
|
4863
|
-
"templateLiteralContents",
|
|
4864
4881
|
"templateLiteralText",
|
|
4865
4882
|
"templateSubstitution",
|
|
4866
4883
|
"textChar",
|
|
4867
4884
|
"unaryExpression",
|
|
4868
4885
|
"unaryOperator",
|
|
4886
|
+
"whitespace",
|
|
4869
4887
|
"whitespaceWithNewLine"
|
|
4870
4888
|
];
|
|
4871
4889
|
|
|
@@ -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
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
//
|
|
273
|
-
|
|
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,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
extension,
|
|
3
|
+
ObjectTree,
|
|
4
|
+
symbols,
|
|
5
|
+
trailingSlash,
|
|
6
|
+
Tree,
|
|
7
|
+
} from "@weborigami/async-tree";
|
|
2
8
|
import { handleExtension } from "./handlers.js";
|
|
3
9
|
import { evaluate, ops } from "./internal.js";
|
|
4
10
|
|
|
@@ -11,8 +17,8 @@ import { evaluate, ops } from "./internal.js";
|
|
|
11
17
|
*
|
|
12
18
|
* 1. A primitive value (string, etc.). This will be defined directly as an
|
|
13
19
|
* object property.
|
|
14
|
-
* 1. An
|
|
15
|
-
* result defined as an object property.
|
|
20
|
+
* 1. An eager (as opposed to lazy) code entry. This will be evaluated during
|
|
21
|
+
* this call and its result defined as an object property.
|
|
16
22
|
* 1. A code entry that starts with ops.getter. This will be defined as a
|
|
17
23
|
* property getter on the object.
|
|
18
24
|
*
|
|
@@ -25,15 +31,9 @@ export default async function expressionObject(entries, parent) {
|
|
|
25
31
|
if (parent !== null && !Tree.isAsyncTree(parent)) {
|
|
26
32
|
throw new TypeError(`Parent must be an AsyncTree or null`);
|
|
27
33
|
}
|
|
28
|
-
Object.defineProperty(object, symbols.parent, {
|
|
29
|
-
configurable: true,
|
|
30
|
-
enumerable: false,
|
|
31
|
-
value: parent,
|
|
32
|
-
writable: true,
|
|
33
|
-
});
|
|
34
34
|
|
|
35
35
|
let tree;
|
|
36
|
-
const
|
|
36
|
+
const eagerProperties = [];
|
|
37
37
|
for (let [key, value] of entries) {
|
|
38
38
|
// Determine if we need to define a getter or a regular property. If the key
|
|
39
39
|
// has an extension, we need to define a getter. If the value is code (an
|
|
@@ -61,7 +61,6 @@ export default async function expressionObject(entries, parent) {
|
|
|
61
61
|
|
|
62
62
|
if (defineProperty) {
|
|
63
63
|
// Define simple property
|
|
64
|
-
// object[key] = value;
|
|
65
64
|
Object.defineProperty(object, key, {
|
|
66
65
|
configurable: true,
|
|
67
66
|
enumerable,
|
|
@@ -74,7 +73,7 @@ export default async function expressionObject(entries, parent) {
|
|
|
74
73
|
if (value[0] === ops.getter) {
|
|
75
74
|
code = value[1];
|
|
76
75
|
} else {
|
|
77
|
-
|
|
76
|
+
eagerProperties.push(key);
|
|
78
77
|
code = value;
|
|
79
78
|
}
|
|
80
79
|
|
|
@@ -102,9 +101,25 @@ export default async function expressionObject(entries, parent) {
|
|
|
102
101
|
}
|
|
103
102
|
}
|
|
104
103
|
|
|
104
|
+
// Attach a keys method
|
|
105
|
+
Object.defineProperty(object, symbols.keys, {
|
|
106
|
+
configurable: true,
|
|
107
|
+
enumerable: false,
|
|
108
|
+
value: () => keys(object, eagerProperties, entries),
|
|
109
|
+
writable: true,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Attach the parent
|
|
113
|
+
Object.defineProperty(object, symbols.parent, {
|
|
114
|
+
configurable: true,
|
|
115
|
+
enumerable: false,
|
|
116
|
+
value: parent,
|
|
117
|
+
writable: true,
|
|
118
|
+
});
|
|
119
|
+
|
|
105
120
|
// Evaluate any properties that were declared as immediate: get their value
|
|
106
121
|
// and overwrite the property getter with the actual value.
|
|
107
|
-
for (const key of
|
|
122
|
+
for (const key of eagerProperties) {
|
|
108
123
|
const value = await object[key];
|
|
109
124
|
// @ts-ignore Unclear why TS thinks `object` might be undefined here
|
|
110
125
|
const enumerable = Object.getOwnPropertyDescriptor(object, key).enumerable;
|
|
@@ -118,3 +133,31 @@ export default async function expressionObject(entries, parent) {
|
|
|
118
133
|
|
|
119
134
|
return object;
|
|
120
135
|
}
|
|
136
|
+
|
|
137
|
+
function entryKey(object, eagerProperties, entry) {
|
|
138
|
+
const [key, value] = entry;
|
|
139
|
+
|
|
140
|
+
const hasExplicitSlash = trailingSlash.has(key);
|
|
141
|
+
if (hasExplicitSlash) {
|
|
142
|
+
// Return key as is
|
|
143
|
+
return key;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// If eager property value is treelike, add slash to the key
|
|
147
|
+
if (eagerProperties.includes(key) && Tree.isTreelike(object[key])) {
|
|
148
|
+
return trailingSlash.add(key);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// If entry will definitely create a subtree, add a trailing slash
|
|
152
|
+
const entryCreatesSubtree =
|
|
153
|
+
value instanceof Array &&
|
|
154
|
+
(value[0] === ops.object ||
|
|
155
|
+
(value[0] === ops.getter &&
|
|
156
|
+
value[1] instanceof Array &&
|
|
157
|
+
(value[1][0] === ops.object || value[1][0] === ops.merge)));
|
|
158
|
+
return trailingSlash.toggle(key, entryCreatesSubtree);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function keys(object, eagerProperties, entries) {
|
|
162
|
+
return entries.map((entry) => entryKey(object, eagerProperties, entry));
|
|
163
|
+
}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
isPlainObject,
|
|
3
|
+
isUnpackable,
|
|
4
|
+
merge,
|
|
5
|
+
Tree,
|
|
6
|
+
} from "@weborigami/async-tree";
|
|
2
7
|
|
|
3
8
|
/**
|
|
4
9
|
* Create a tree that's the result of merging the given trees.
|
|
@@ -28,8 +33,23 @@ export default async function mergeTrees(...trees) {
|
|
|
28
33
|
);
|
|
29
34
|
|
|
30
35
|
// If all trees are plain objects, return a plain object.
|
|
31
|
-
if (
|
|
32
|
-
|
|
36
|
+
if (
|
|
37
|
+
unpacked.every((tree) => isPlainObject(tree) && !Tree.isAsyncTree(tree))
|
|
38
|
+
) {
|
|
39
|
+
// If we do an Object.assign, we'd evaluate getters.
|
|
40
|
+
// To avoid that, we'll merge property descriptors.
|
|
41
|
+
const result = {};
|
|
42
|
+
for (const obj of unpacked) {
|
|
43
|
+
const descriptors = Object.getOwnPropertyDescriptors(obj);
|
|
44
|
+
for (const [key, descriptor] of Object.entries(descriptors)) {
|
|
45
|
+
if (descriptor.value !== undefined) {
|
|
46
|
+
result[key] = descriptor.value;
|
|
47
|
+
} else {
|
|
48
|
+
Object.defineProperty(result, key, descriptor);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
33
53
|
}
|
|
34
54
|
|
|
35
55
|
// If all trees are arrays, return an array.
|