@weborigami/language 0.3.4-jse.8 → 0.4.0
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/package.json +3 -3
- package/src/compiler/optimize.js +13 -8
- package/src/compiler/origami.pegjs +12 -4
- package/src/compiler/parse.js +146 -72
- package/src/compiler/parserHelpers.js +4 -3
- package/src/runtime/getHandlers.js +1 -1
- package/src/runtime/jsGlobals.js +94 -7
- package/src/runtime/ops.js +11 -6
- package/test/compiler/codeHelpers.js +9 -0
- package/test/compiler/optimize.test.js +6 -1
- package/test/compiler/parse.test.js +15 -23
- package/test/runtime/expressionObject.test.js +1 -1
- package/test/runtime/ops.test.js +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weborigami/language",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Web Origami expression language compiler and runtime",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./main.js",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"typescript": "5.8.2"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@weborigami/async-tree": "0.
|
|
15
|
-
"@weborigami/types": "0.
|
|
14
|
+
"@weborigami/async-tree": "0.4.0",
|
|
15
|
+
"@weborigami/types": "0.4.0",
|
|
16
16
|
"watcher": "2.3.1",
|
|
17
17
|
"yaml": "2.7.0"
|
|
18
18
|
},
|
package/src/compiler/optimize.js
CHANGED
|
@@ -56,7 +56,7 @@ export default function optimize(code, options = {}) {
|
|
|
56
56
|
|
|
57
57
|
case ops.object:
|
|
58
58
|
const entries = args;
|
|
59
|
-
const keys = entries.map(entryKey);
|
|
59
|
+
const keys = entries.map((entry) => entryKey(entry));
|
|
60
60
|
locals.push(keys);
|
|
61
61
|
break;
|
|
62
62
|
}
|
|
@@ -70,13 +70,16 @@ export default function optimize(code, options = {}) {
|
|
|
70
70
|
} else if (op === ops.object && index > 0) {
|
|
71
71
|
const [key, value] = child;
|
|
72
72
|
const adjustedLocals = avoidLocalRecursion(locals, key);
|
|
73
|
-
return
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
73
|
+
return annotate(
|
|
74
|
+
[
|
|
75
|
+
key,
|
|
76
|
+
optimize(/** @type {AnnotatedCode} */ (value), {
|
|
77
|
+
...options,
|
|
78
|
+
locals: adjustedLocals,
|
|
79
|
+
}),
|
|
80
|
+
],
|
|
81
|
+
child.location
|
|
82
|
+
);
|
|
80
83
|
} else if (Array.isArray(child) && "location" in child) {
|
|
81
84
|
// Review: Aside from ops.object (above), what non-instruction arrays
|
|
82
85
|
// does this descend into?
|
|
@@ -191,6 +194,7 @@ function inlineLiteral(code) {
|
|
|
191
194
|
function localReference(key, locals, location) {
|
|
192
195
|
const normalized = trailingSlash.remove(key);
|
|
193
196
|
const depth = getLocalReferenceDepth(locals, normalized);
|
|
197
|
+
/** @type {any[]} */
|
|
194
198
|
const context = [ops.context];
|
|
195
199
|
if (depth > 0) {
|
|
196
200
|
context.push(depth);
|
|
@@ -310,6 +314,7 @@ function resolvePath(code, globals, locals, cache) {
|
|
|
310
314
|
|
|
311
315
|
function scopeCall(locals, location) {
|
|
312
316
|
const depth = locals.length;
|
|
317
|
+
/** @type {any[]} */
|
|
313
318
|
const code = [ops.scope];
|
|
314
319
|
if (depth > 0) {
|
|
315
320
|
// Add context for appropriate depth to scope call
|
|
@@ -651,6 +651,9 @@ primary
|
|
|
651
651
|
program "Origami program"
|
|
652
652
|
= shebang? @expression
|
|
653
653
|
|
|
654
|
+
programMode
|
|
655
|
+
= &{ return options.mode === "program" }
|
|
656
|
+
|
|
654
657
|
propertyAccess
|
|
655
658
|
= __ "." __ property:identifierLiteral {
|
|
656
659
|
return annotate([markers.property, property], location());
|
|
@@ -709,7 +712,10 @@ shiftOperator
|
|
|
709
712
|
// A shorthand lambda expression: `=foo(_)`
|
|
710
713
|
shorthandFunction "lambda function"
|
|
711
714
|
// Avoid a following equal sign (for an equality)
|
|
712
|
-
= shellMode "=" !"=" __ definition:implicitParenthesesCallExpression {
|
|
715
|
+
= (shellMode / programMode) "=" !"=" __ definition:implicitParenthesesCallExpression {
|
|
716
|
+
if (options.mode === "program") {
|
|
717
|
+
console.warn("Warning: the shorthand function syntax is deprecated in Origami programs. Use arrow syntax instead.");
|
|
718
|
+
}
|
|
713
719
|
const lambdaParameters = annotate(
|
|
714
720
|
[annotate([ops.literal, "_"], location())],
|
|
715
721
|
location()
|
|
@@ -866,8 +872,8 @@ uriKey
|
|
|
866
872
|
// A single character in a URI key
|
|
867
873
|
uriKeyChar
|
|
868
874
|
// Accept anything that doesn't end the URI key or path
|
|
869
|
-
//
|
|
870
|
-
= [^/,\)\]\}
|
|
875
|
+
// Reject whitespace; see notes for `whitespace` term
|
|
876
|
+
= char:[^/,\)\]\}] !&{ return /\s/.test(char); } { return char; }
|
|
871
877
|
/ escapedChar
|
|
872
878
|
|
|
873
879
|
// A slash-separated path of keys: `a/b/c`
|
|
@@ -890,10 +896,12 @@ unaryOperator
|
|
|
890
896
|
/ minus
|
|
891
897
|
|
|
892
898
|
whitespace
|
|
899
|
+
= (whitespaceChar / comment)+
|
|
900
|
+
|
|
901
|
+
whitespaceChar
|
|
893
902
|
// JavaScript considers a large number of characters whitespace so we use the
|
|
894
903
|
// `/s` definition to avoid missing any.
|
|
895
904
|
= char:. &{ return /\s/.test(char); } { return char; }
|
|
896
|
-
/ comment
|
|
897
905
|
|
|
898
906
|
whitespaceWithNewLine
|
|
899
907
|
= inlineSpace* comment? newLine __
|
package/src/compiler/parse.js
CHANGED
|
@@ -205,7 +205,7 @@ function peg$parse(input, options) {
|
|
|
205
205
|
var peg$FAILED = {};
|
|
206
206
|
var peg$source = options.grammarSource;
|
|
207
207
|
|
|
208
|
-
var peg$startRuleFunctions = { __: peg$parse__, additiveExpression: peg$parseadditiveExpression, additiveOperator: peg$parseadditiveOperator, angleBracketLiteral: peg$parseangleBracketLiteral, angleBracketPath: peg$parseangleBracketPath, angleBracketKey: peg$parseangleBracketKey, angleBracketPathChar: peg$parseangleBracketPathChar, 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, commaExpression: peg$parsecommaExpression, comment: peg$parsecomment, computedPropertyAccess: peg$parsecomputedPropertyAccess, computedPropertySpace: peg$parsecomputedPropertySpace, 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, expectBacktick: peg$parseexpectBacktick, expectClosingBrace: peg$parseexpectClosingBrace, expectClosingBracket: peg$parseexpectClosingBracket, expectClosingParenthesis: peg$parseexpectClosingParenthesis, expectDoubleQuote: peg$parseexpectDoubleQuote, expectExpression: peg$parseexpectExpression, expectFrontDelimiter: peg$parseexpectFrontDelimiter, expectGuillemet: peg$parseexpectGuillemet, expectSingleQuote: peg$parseexpectSingleQuote, expectPipelineExpression: peg$parseexpectPipelineExpression, expectUnaryExpression: peg$parseexpectUnaryExpression, exponentiationExpression: peg$parseexponentiationExpression, expression: peg$parseexpression, floatLiteral: peg$parsefloatLiteral, frontDelimiter: peg$parsefrontDelimiter, frontMatterExpression: peg$parsefrontMatterExpression, frontMatterText: peg$parsefrontMatterText, frontMatterYaml: peg$parsefrontMatterYaml, group: peg$parsegroup, guillemetString: peg$parseguillemetString, guillemetStringChar: peg$parseguillemetStringChar, host: peg$parsehost, hostname: peg$parsehostname, identifier: peg$parseidentifier, identifierLiteral: peg$parseidentifierLiteral, identifierPart: peg$parseidentifierPart, identifierStart: peg$parseidentifierStart, implicitParenthesesCallExpression: peg$parseimplicitParenthesesCallExpression, implicitParensthesesArguments: peg$parseimplicitParensthesesArguments, inlineSpace: peg$parseinlineSpace, integerLiteral: peg$parseintegerLiteral, key: peg$parsekey, keyChar: peg$parsekeyChar, keyCharStart: peg$parsekeyCharStart, list: peg$parselist, logicalAndExpression: peg$parselogicalAndExpression, logicalOrExpression: peg$parselogicalOrExpression, minus: peg$parseminus, multiLineComment: peg$parsemultiLineComment, multiplicativeExpression: peg$parsemultiplicativeExpression, multiplicativeOperator: peg$parsemultiplicativeOperator, newExpression: peg$parsenewExpression, 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, optionalChaining: peg$parseoptionalChaining, parameter: peg$parseparameter, parameterList: peg$parseparameterList, parameterSingleton: peg$parseparameterSingleton, parenthesesArguments: peg$parseparenthesesArguments, pathArguments: peg$parsepathArguments, pathKeys: peg$parsepathKeys, pathLiteral: peg$parsepathLiteral, pathSegment: peg$parsepathSegment, pipelineExpression: peg$parsepipelineExpression, primary: peg$parseprimary, program: peg$parseprogram, propertyAccess: peg$parsepropertyAccess, regexFlags: peg$parseregexFlags, regexLiteral: peg$parseregexLiteral, regexLiteralChar: peg$parseregexLiteralChar, relationalExpression: peg$parserelationalExpression, relationalOperator: peg$parserelationalOperator, separator: peg$parseseparator, shebang: peg$parseshebang, shellMode: peg$parseshellMode, shiftExpression: peg$parseshiftExpression, shiftOperator: peg$parseshiftOperator, shorthandFunction: peg$parseshorthandFunction, singleArrow: peg$parsesingleArrow, singleLineComment: peg$parsesingleLineComment, singleQuoteString: peg$parsesingleQuoteString, singleQuoteStringChar: peg$parsesingleQuoteStringChar, slash: peg$parseslash, slashes: peg$parseslashes, slashFollows: peg$parseslashFollows, spreadElement: peg$parsespreadElement, stringLiteral: peg$parsestringLiteral, templateBody: peg$parsetemplateBody, templateBodyChar: peg$parsetemplateBodyChar, templateBodyText: peg$parsetemplateBodyText, templateDocument: peg$parsetemplateDocument, templateLiteral: peg$parsetemplateLiteral, templateLiteralChar: peg$parsetemplateLiteralChar, templateLiteralText: peg$parsetemplateLiteralText, templateSubstitution: peg$parsetemplateSubstitution, textChar: peg$parsetextChar, unaryExpression: peg$parseunaryExpression, uri: peg$parseuri, uriExpression: peg$parseuriExpression, uriKey: peg$parseuriKey, uriKeyChar: peg$parseuriKeyChar, uriPath: peg$parseuriPath, uriScheme: peg$parseuriScheme, unaryOperator: peg$parseunaryOperator, whitespace: peg$parsewhitespace, whitespaceWithNewLine: peg$parsewhitespaceWithNewLine };
|
|
208
|
+
var peg$startRuleFunctions = { __: peg$parse__, additiveExpression: peg$parseadditiveExpression, additiveOperator: peg$parseadditiveOperator, angleBracketLiteral: peg$parseangleBracketLiteral, angleBracketPath: peg$parseangleBracketPath, angleBracketKey: peg$parseangleBracketKey, angleBracketPathChar: peg$parseangleBracketPathChar, 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, commaExpression: peg$parsecommaExpression, comment: peg$parsecomment, computedPropertyAccess: peg$parsecomputedPropertyAccess, computedPropertySpace: peg$parsecomputedPropertySpace, 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, expectBacktick: peg$parseexpectBacktick, expectClosingBrace: peg$parseexpectClosingBrace, expectClosingBracket: peg$parseexpectClosingBracket, expectClosingParenthesis: peg$parseexpectClosingParenthesis, expectDoubleQuote: peg$parseexpectDoubleQuote, expectExpression: peg$parseexpectExpression, expectFrontDelimiter: peg$parseexpectFrontDelimiter, expectGuillemet: peg$parseexpectGuillemet, expectSingleQuote: peg$parseexpectSingleQuote, expectPipelineExpression: peg$parseexpectPipelineExpression, expectUnaryExpression: peg$parseexpectUnaryExpression, exponentiationExpression: peg$parseexponentiationExpression, expression: peg$parseexpression, floatLiteral: peg$parsefloatLiteral, frontDelimiter: peg$parsefrontDelimiter, frontMatterExpression: peg$parsefrontMatterExpression, frontMatterText: peg$parsefrontMatterText, frontMatterYaml: peg$parsefrontMatterYaml, group: peg$parsegroup, guillemetString: peg$parseguillemetString, guillemetStringChar: peg$parseguillemetStringChar, host: peg$parsehost, hostname: peg$parsehostname, identifier: peg$parseidentifier, identifierLiteral: peg$parseidentifierLiteral, identifierPart: peg$parseidentifierPart, identifierStart: peg$parseidentifierStart, implicitParenthesesCallExpression: peg$parseimplicitParenthesesCallExpression, implicitParensthesesArguments: peg$parseimplicitParensthesesArguments, inlineSpace: peg$parseinlineSpace, integerLiteral: peg$parseintegerLiteral, key: peg$parsekey, keyChar: peg$parsekeyChar, keyCharStart: peg$parsekeyCharStart, list: peg$parselist, logicalAndExpression: peg$parselogicalAndExpression, logicalOrExpression: peg$parselogicalOrExpression, minus: peg$parseminus, multiLineComment: peg$parsemultiLineComment, multiplicativeExpression: peg$parsemultiplicativeExpression, multiplicativeOperator: peg$parsemultiplicativeOperator, newExpression: peg$parsenewExpression, 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, optionalChaining: peg$parseoptionalChaining, parameter: peg$parseparameter, parameterList: peg$parseparameterList, parameterSingleton: peg$parseparameterSingleton, parenthesesArguments: peg$parseparenthesesArguments, pathArguments: peg$parsepathArguments, pathKeys: peg$parsepathKeys, pathLiteral: peg$parsepathLiteral, pathSegment: peg$parsepathSegment, pipelineExpression: peg$parsepipelineExpression, primary: peg$parseprimary, program: peg$parseprogram, programMode: peg$parseprogramMode, propertyAccess: peg$parsepropertyAccess, regexFlags: peg$parseregexFlags, regexLiteral: peg$parseregexLiteral, regexLiteralChar: peg$parseregexLiteralChar, relationalExpression: peg$parserelationalExpression, relationalOperator: peg$parserelationalOperator, separator: peg$parseseparator, shebang: peg$parseshebang, shellMode: peg$parseshellMode, shiftExpression: peg$parseshiftExpression, shiftOperator: peg$parseshiftOperator, shorthandFunction: peg$parseshorthandFunction, singleArrow: peg$parsesingleArrow, singleLineComment: peg$parsesingleLineComment, singleQuoteString: peg$parsesingleQuoteString, singleQuoteStringChar: peg$parsesingleQuoteStringChar, slash: peg$parseslash, slashes: peg$parseslashes, slashFollows: peg$parseslashFollows, spreadElement: peg$parsespreadElement, stringLiteral: peg$parsestringLiteral, templateBody: peg$parsetemplateBody, templateBodyChar: peg$parsetemplateBodyChar, templateBodyText: peg$parsetemplateBodyText, templateDocument: peg$parsetemplateDocument, templateLiteral: peg$parsetemplateLiteral, templateLiteralChar: peg$parsetemplateLiteralChar, templateLiteralText: peg$parsetemplateLiteralText, templateSubstitution: peg$parsetemplateSubstitution, textChar: peg$parsetextChar, unaryExpression: peg$parseunaryExpression, uri: peg$parseuri, uriExpression: peg$parseuriExpression, uriKey: peg$parseuriKey, uriKeyChar: peg$parseuriKeyChar, uriPath: peg$parseuriPath, uriScheme: peg$parseuriScheme, unaryOperator: peg$parseunaryOperator, whitespace: peg$parsewhitespace, whitespaceChar: peg$parsewhitespaceChar, whitespaceWithNewLine: peg$parsewhitespaceWithNewLine };
|
|
209
209
|
var peg$startRuleFunction = peg$parse__;
|
|
210
210
|
|
|
211
211
|
var peg$c0 = "+";
|
|
@@ -285,7 +285,7 @@ function peg$parse(input, options) {
|
|
|
285
285
|
var peg$r7 = /^[gimuy]/;
|
|
286
286
|
var peg$r8 = /^[^\/\n\r]/;
|
|
287
287
|
var peg$r9 = /^[^\n\r]/;
|
|
288
|
-
var peg$r10 = /^[^\/,)\]}
|
|
288
|
+
var peg$r10 = /^[^\/,)\]}]/;
|
|
289
289
|
var peg$r11 = /^[a-z]/;
|
|
290
290
|
var peg$r12 = /^[a-z0-9+-.]/;
|
|
291
291
|
var peg$r13 = /^[:]/;
|
|
@@ -399,7 +399,7 @@ function peg$parse(input, options) {
|
|
|
399
399
|
var peg$e105 = peg$otherExpectation("template document");
|
|
400
400
|
var peg$e106 = peg$otherExpectation("template literal");
|
|
401
401
|
var peg$e107 = peg$otherExpectation("template substitution");
|
|
402
|
-
var peg$e108 = peg$classExpectation(["/", ",", ")", "]", "}"
|
|
402
|
+
var peg$e108 = peg$classExpectation(["/", ",", ")", "]", "}"], true, false);
|
|
403
403
|
var peg$e109 = peg$otherExpectation("slash-separated path");
|
|
404
404
|
var peg$e110 = peg$classExpectation([["a", "z"]], false, false);
|
|
405
405
|
var peg$e111 = peg$classExpectation([["a", "z"], ["0", "9"], ["+", "."]], false, false);
|
|
@@ -684,54 +684,58 @@ function peg$parse(input, options) {
|
|
|
684
684
|
location()
|
|
685
685
|
);
|
|
686
686
|
};
|
|
687
|
-
var peg$f83 = function(
|
|
687
|
+
var peg$f83 = function() { return options.mode === "program" };
|
|
688
|
+
var peg$f84 = function(property) {
|
|
688
689
|
return annotate([markers.property, property], location());
|
|
689
690
|
};
|
|
690
|
-
var peg$
|
|
691
|
+
var peg$f85 = function(flags) {
|
|
691
692
|
return flags.join("");
|
|
692
693
|
};
|
|
693
|
-
var peg$
|
|
694
|
+
var peg$f86 = function(chars, flags) {
|
|
694
695
|
const regex = new RegExp(chars.join(""), flags);
|
|
695
696
|
return annotate([ops.literal, regex], location());
|
|
696
697
|
};
|
|
697
|
-
var peg$
|
|
698
|
+
var peg$f87 = function(head, tail) {
|
|
698
699
|
return tail.reduce(makeBinaryOperation, head);
|
|
699
700
|
};
|
|
700
|
-
var peg$
|
|
701
|
-
var peg$
|
|
702
|
-
var peg$
|
|
701
|
+
var peg$f88 = function() { return null; };
|
|
702
|
+
var peg$f89 = function() { return options.mode === "shell" };
|
|
703
|
+
var peg$f90 = function(head, tail) {
|
|
703
704
|
return tail.reduce(makeBinaryOperation, head);
|
|
704
705
|
};
|
|
705
|
-
var peg$
|
|
706
|
+
var peg$f91 = function(definition) {
|
|
707
|
+
if (options.mode === "program") {
|
|
708
|
+
console.warn("Warning: the shorthand function syntax is deprecated in Origami programs. Use arrow syntax instead.");
|
|
709
|
+
}
|
|
706
710
|
const lambdaParameters = annotate(
|
|
707
711
|
[annotate([ops.literal, "_"], location())],
|
|
708
712
|
location()
|
|
709
713
|
);
|
|
710
714
|
return annotate([ops.lambda, lambdaParameters, definition], location());
|
|
711
715
|
};
|
|
712
|
-
var peg$
|
|
713
|
-
var peg$
|
|
716
|
+
var peg$f92 = function() { return null; };
|
|
717
|
+
var peg$f93 = function(chars) {
|
|
714
718
|
return annotate([ops.literal, chars.join("")], location());
|
|
715
719
|
};
|
|
716
|
-
var peg$
|
|
720
|
+
var peg$f94 = function() {
|
|
717
721
|
return annotate([ops.literal, "/"], location());
|
|
718
722
|
};
|
|
719
|
-
var peg$
|
|
723
|
+
var peg$f95 = function() {
|
|
720
724
|
return annotate([ops.literal, "/"], location());
|
|
721
725
|
};
|
|
722
|
-
var peg$
|
|
726
|
+
var peg$f96 = function() {
|
|
723
727
|
return true;
|
|
724
728
|
};
|
|
725
|
-
var peg$
|
|
729
|
+
var peg$f97 = function(value) {
|
|
726
730
|
return annotate([ops.spread, value], location());
|
|
727
731
|
};
|
|
728
|
-
var peg$
|
|
732
|
+
var peg$f98 = function(head, tail) {
|
|
729
733
|
return makeTemplate(ops.templateIndent, head, tail, location());
|
|
730
734
|
};
|
|
731
|
-
var peg$
|
|
735
|
+
var peg$f99 = function(chars) {
|
|
732
736
|
return annotate([ops.literal, chars.join("")], location());
|
|
733
737
|
};
|
|
734
|
-
var peg$
|
|
738
|
+
var peg$f100 = function(front, body) {
|
|
735
739
|
// TODO: Deprecate @template
|
|
736
740
|
const macroName = text().includes("@template") ? "@template" : "_template";
|
|
737
741
|
if (macroName === "@template") {
|
|
@@ -740,10 +744,10 @@ function peg$parse(input, options) {
|
|
|
740
744
|
}
|
|
741
745
|
return annotate(applyMacro(front, macroName, body), location());
|
|
742
746
|
};
|
|
743
|
-
var peg$
|
|
747
|
+
var peg$f101 = function(front, body) {
|
|
744
748
|
return makeDocument(front, body, location());
|
|
745
749
|
};
|
|
746
|
-
var peg$
|
|
750
|
+
var peg$f102 = function(body) {
|
|
747
751
|
if (options.front) {
|
|
748
752
|
return makeDocument(options.front, body, location());
|
|
749
753
|
}
|
|
@@ -753,41 +757,43 @@ function peg$parse(input, options) {
|
|
|
753
757
|
);
|
|
754
758
|
return annotate([ops.lambda, lambdaParameters, body], location());
|
|
755
759
|
};
|
|
756
|
-
var peg$
|
|
760
|
+
var peg$f103 = function(head, tail) {
|
|
757
761
|
return makeTemplate(ops.templateTree, head, tail, location());
|
|
758
762
|
};
|
|
759
|
-
var peg$
|
|
763
|
+
var peg$f104 = function(chars) {
|
|
760
764
|
return annotate([ops.literal, chars.join("")], location());
|
|
761
765
|
};
|
|
762
|
-
var peg$
|
|
766
|
+
var peg$f105 = function(expression) {
|
|
763
767
|
return annotate(expression, location());
|
|
764
768
|
};
|
|
765
|
-
var peg$
|
|
769
|
+
var peg$f106 = function(operator, expression) {
|
|
766
770
|
return makeUnaryOperation(operator, expression, location());
|
|
767
771
|
};
|
|
768
|
-
var peg$
|
|
772
|
+
var peg$f107 = function(scheme, host, path) {
|
|
769
773
|
const rest = path ? path[1] : [];
|
|
770
774
|
const keys = annotate([host, ...rest], location());
|
|
771
775
|
return makeCall(scheme, keys, location());
|
|
772
776
|
};
|
|
773
|
-
var peg$
|
|
777
|
+
var peg$f108 = function(scheme, keys) {
|
|
774
778
|
return makeCall(scheme, keys, location());
|
|
775
779
|
};
|
|
776
|
-
var peg$
|
|
780
|
+
var peg$f109 = function(chars) {
|
|
777
781
|
return annotate([ops.literal, text()], location());
|
|
778
782
|
};
|
|
779
|
-
var peg$
|
|
783
|
+
var peg$f110 = function() {
|
|
780
784
|
// A single slash is a path key
|
|
781
785
|
return annotate([ops.literal, ""], location());
|
|
782
786
|
};
|
|
783
|
-
var peg$
|
|
787
|
+
var peg$f111 = function(char) { return /\s/.test(char); };
|
|
788
|
+
var peg$f112 = function(char) { return char; };
|
|
789
|
+
var peg$f113 = function(keys) {
|
|
784
790
|
return annotate(keys, location());
|
|
785
791
|
};
|
|
786
|
-
var peg$
|
|
792
|
+
var peg$f114 = function() {
|
|
787
793
|
return annotate([markers.global, text()], location());
|
|
788
794
|
};
|
|
789
|
-
var peg$
|
|
790
|
-
var peg$
|
|
795
|
+
var peg$f115 = function(char) { return /\s/.test(char); };
|
|
796
|
+
var peg$f116 = function(char) { return char; };
|
|
791
797
|
var peg$currPos = options.peg$currPos | 0;
|
|
792
798
|
var peg$savedPos = peg$currPos;
|
|
793
799
|
var peg$posDetailsCache = [{ line: 1, column: 1 }];
|
|
@@ -4828,6 +4834,20 @@ function peg$parse(input, options) {
|
|
|
4828
4834
|
return s0;
|
|
4829
4835
|
}
|
|
4830
4836
|
|
|
4837
|
+
function peg$parseprogramMode() {
|
|
4838
|
+
var s0;
|
|
4839
|
+
|
|
4840
|
+
peg$savedPos = peg$currPos;
|
|
4841
|
+
s0 = peg$f83();
|
|
4842
|
+
if (s0) {
|
|
4843
|
+
s0 = undefined;
|
|
4844
|
+
} else {
|
|
4845
|
+
s0 = peg$FAILED;
|
|
4846
|
+
}
|
|
4847
|
+
|
|
4848
|
+
return s0;
|
|
4849
|
+
}
|
|
4850
|
+
|
|
4831
4851
|
function peg$parsepropertyAccess() {
|
|
4832
4852
|
var s0, s1, s2, s3, s4;
|
|
4833
4853
|
|
|
@@ -4845,7 +4865,7 @@ function peg$parse(input, options) {
|
|
|
4845
4865
|
s4 = peg$parseidentifierLiteral();
|
|
4846
4866
|
if (s4 !== peg$FAILED) {
|
|
4847
4867
|
peg$savedPos = s0;
|
|
4848
|
-
s0 = peg$
|
|
4868
|
+
s0 = peg$f84(s4);
|
|
4849
4869
|
} else {
|
|
4850
4870
|
peg$currPos = s0;
|
|
4851
4871
|
s0 = peg$FAILED;
|
|
@@ -4881,7 +4901,7 @@ function peg$parse(input, options) {
|
|
|
4881
4901
|
}
|
|
4882
4902
|
}
|
|
4883
4903
|
peg$savedPos = s0;
|
|
4884
|
-
s1 = peg$
|
|
4904
|
+
s1 = peg$f85(s1);
|
|
4885
4905
|
s0 = s1;
|
|
4886
4906
|
|
|
4887
4907
|
return s0;
|
|
@@ -4915,7 +4935,7 @@ function peg$parse(input, options) {
|
|
|
4915
4935
|
if (s3 !== peg$FAILED) {
|
|
4916
4936
|
s4 = peg$parseregexFlags();
|
|
4917
4937
|
peg$savedPos = s0;
|
|
4918
|
-
s0 = peg$
|
|
4938
|
+
s0 = peg$f86(s2, s4);
|
|
4919
4939
|
} else {
|
|
4920
4940
|
peg$currPos = s0;
|
|
4921
4941
|
s0 = peg$FAILED;
|
|
@@ -4998,7 +5018,7 @@ function peg$parse(input, options) {
|
|
|
4998
5018
|
}
|
|
4999
5019
|
}
|
|
5000
5020
|
peg$savedPos = s0;
|
|
5001
|
-
s0 = peg$
|
|
5021
|
+
s0 = peg$f87(s1, s2);
|
|
5002
5022
|
} else {
|
|
5003
5023
|
peg$currPos = s0;
|
|
5004
5024
|
s0 = peg$FAILED;
|
|
@@ -5113,7 +5133,7 @@ function peg$parse(input, options) {
|
|
|
5113
5133
|
}
|
|
5114
5134
|
}
|
|
5115
5135
|
peg$savedPos = s0;
|
|
5116
|
-
s0 = peg$
|
|
5136
|
+
s0 = peg$f88();
|
|
5117
5137
|
} else {
|
|
5118
5138
|
peg$currPos = s0;
|
|
5119
5139
|
s0 = peg$FAILED;
|
|
@@ -5126,7 +5146,7 @@ function peg$parse(input, options) {
|
|
|
5126
5146
|
var s0;
|
|
5127
5147
|
|
|
5128
5148
|
peg$savedPos = peg$currPos;
|
|
5129
|
-
s0 = peg$
|
|
5149
|
+
s0 = peg$f89();
|
|
5130
5150
|
if (s0) {
|
|
5131
5151
|
s0 = undefined;
|
|
5132
5152
|
} else {
|
|
@@ -5179,7 +5199,7 @@ function peg$parse(input, options) {
|
|
|
5179
5199
|
}
|
|
5180
5200
|
}
|
|
5181
5201
|
peg$savedPos = s0;
|
|
5182
|
-
s0 = peg$
|
|
5202
|
+
s0 = peg$f90(s1, s2);
|
|
5183
5203
|
} else {
|
|
5184
5204
|
peg$currPos = s0;
|
|
5185
5205
|
s0 = peg$FAILED;
|
|
@@ -5226,6 +5246,9 @@ function peg$parse(input, options) {
|
|
|
5226
5246
|
peg$silentFails++;
|
|
5227
5247
|
s0 = peg$currPos;
|
|
5228
5248
|
s1 = peg$parseshellMode();
|
|
5249
|
+
if (s1 === peg$FAILED) {
|
|
5250
|
+
s1 = peg$parseprogramMode();
|
|
5251
|
+
}
|
|
5229
5252
|
if (s1 !== peg$FAILED) {
|
|
5230
5253
|
if (input.charCodeAt(peg$currPos) === 61) {
|
|
5231
5254
|
s2 = peg$c54;
|
|
@@ -5256,7 +5279,7 @@ function peg$parse(input, options) {
|
|
|
5256
5279
|
s5 = peg$parseimplicitParenthesesCallExpression();
|
|
5257
5280
|
if (s5 !== peg$FAILED) {
|
|
5258
5281
|
peg$savedPos = s0;
|
|
5259
|
-
s0 = peg$
|
|
5282
|
+
s0 = peg$f91(s5);
|
|
5260
5283
|
} else {
|
|
5261
5284
|
peg$currPos = s0;
|
|
5262
5285
|
s0 = peg$FAILED;
|
|
@@ -5339,7 +5362,7 @@ function peg$parse(input, options) {
|
|
|
5339
5362
|
}
|
|
5340
5363
|
}
|
|
5341
5364
|
peg$savedPos = s0;
|
|
5342
|
-
s0 = peg$
|
|
5365
|
+
s0 = peg$f92();
|
|
5343
5366
|
} else {
|
|
5344
5367
|
peg$currPos = s0;
|
|
5345
5368
|
s0 = peg$FAILED;
|
|
@@ -5370,7 +5393,7 @@ function peg$parse(input, options) {
|
|
|
5370
5393
|
s3 = peg$parseexpectSingleQuote();
|
|
5371
5394
|
if (s3 !== peg$FAILED) {
|
|
5372
5395
|
peg$savedPos = s0;
|
|
5373
|
-
s0 = peg$
|
|
5396
|
+
s0 = peg$f93(s2);
|
|
5374
5397
|
} else {
|
|
5375
5398
|
peg$currPos = s0;
|
|
5376
5399
|
s0 = peg$FAILED;
|
|
@@ -5434,7 +5457,7 @@ function peg$parse(input, options) {
|
|
|
5434
5457
|
s1 = peg$parseslashFollows();
|
|
5435
5458
|
if (s1 !== peg$FAILED) {
|
|
5436
5459
|
peg$savedPos = s0;
|
|
5437
|
-
s1 = peg$
|
|
5460
|
+
s1 = peg$f94();
|
|
5438
5461
|
}
|
|
5439
5462
|
s0 = s1;
|
|
5440
5463
|
|
|
@@ -5469,7 +5492,7 @@ function peg$parse(input, options) {
|
|
|
5469
5492
|
}
|
|
5470
5493
|
if (s1 !== peg$FAILED) {
|
|
5471
5494
|
peg$savedPos = s0;
|
|
5472
|
-
s1 = peg$
|
|
5495
|
+
s1 = peg$f95();
|
|
5473
5496
|
}
|
|
5474
5497
|
s0 = s1;
|
|
5475
5498
|
|
|
@@ -5498,7 +5521,7 @@ function peg$parse(input, options) {
|
|
|
5498
5521
|
}
|
|
5499
5522
|
if (s1 !== peg$FAILED) {
|
|
5500
5523
|
peg$savedPos = s0;
|
|
5501
|
-
s1 = peg$
|
|
5524
|
+
s1 = peg$f96();
|
|
5502
5525
|
}
|
|
5503
5526
|
s0 = s1;
|
|
5504
5527
|
|
|
@@ -5515,7 +5538,7 @@ function peg$parse(input, options) {
|
|
|
5515
5538
|
s3 = peg$parseexpectPipelineExpression();
|
|
5516
5539
|
if (s3 !== peg$FAILED) {
|
|
5517
5540
|
peg$savedPos = s0;
|
|
5518
|
-
s0 = peg$
|
|
5541
|
+
s0 = peg$f97(s3);
|
|
5519
5542
|
} else {
|
|
5520
5543
|
peg$currPos = s0;
|
|
5521
5544
|
s0 = peg$FAILED;
|
|
@@ -5592,7 +5615,7 @@ function peg$parse(input, options) {
|
|
|
5592
5615
|
}
|
|
5593
5616
|
}
|
|
5594
5617
|
peg$savedPos = s0;
|
|
5595
|
-
s0 = peg$
|
|
5618
|
+
s0 = peg$f98(s1, s2);
|
|
5596
5619
|
peg$silentFails--;
|
|
5597
5620
|
s1 = peg$FAILED;
|
|
5598
5621
|
if (peg$silentFails === 0) { peg$fail(peg$e102); }
|
|
@@ -5648,7 +5671,7 @@ function peg$parse(input, options) {
|
|
|
5648
5671
|
s2 = peg$parsetemplateBodyChar();
|
|
5649
5672
|
}
|
|
5650
5673
|
peg$savedPos = s0;
|
|
5651
|
-
s1 = peg$
|
|
5674
|
+
s1 = peg$f99(s1);
|
|
5652
5675
|
s0 = s1;
|
|
5653
5676
|
peg$silentFails--;
|
|
5654
5677
|
s1 = peg$FAILED;
|
|
@@ -5667,7 +5690,7 @@ function peg$parse(input, options) {
|
|
|
5667
5690
|
s2 = peg$parse__();
|
|
5668
5691
|
s3 = peg$parsetemplateBody();
|
|
5669
5692
|
peg$savedPos = s0;
|
|
5670
|
-
s0 = peg$
|
|
5693
|
+
s0 = peg$f100(s1, s3);
|
|
5671
5694
|
} else {
|
|
5672
5695
|
peg$currPos = s0;
|
|
5673
5696
|
s0 = peg$FAILED;
|
|
@@ -5678,7 +5701,7 @@ function peg$parse(input, options) {
|
|
|
5678
5701
|
if (s1 !== peg$FAILED) {
|
|
5679
5702
|
s2 = peg$parsetemplateBody();
|
|
5680
5703
|
peg$savedPos = s0;
|
|
5681
|
-
s0 = peg$
|
|
5704
|
+
s0 = peg$f101(s1, s2);
|
|
5682
5705
|
} else {
|
|
5683
5706
|
peg$currPos = s0;
|
|
5684
5707
|
s0 = peg$FAILED;
|
|
@@ -5687,7 +5710,7 @@ function peg$parse(input, options) {
|
|
|
5687
5710
|
s0 = peg$currPos;
|
|
5688
5711
|
s1 = peg$parsetemplateBody();
|
|
5689
5712
|
peg$savedPos = s0;
|
|
5690
|
-
s1 = peg$
|
|
5713
|
+
s1 = peg$f102(s1);
|
|
5691
5714
|
s0 = s1;
|
|
5692
5715
|
}
|
|
5693
5716
|
}
|
|
@@ -5741,7 +5764,7 @@ function peg$parse(input, options) {
|
|
|
5741
5764
|
s4 = peg$parseexpectBacktick();
|
|
5742
5765
|
if (s4 !== peg$FAILED) {
|
|
5743
5766
|
peg$savedPos = s0;
|
|
5744
|
-
s0 = peg$
|
|
5767
|
+
s0 = peg$f103(s2, s3);
|
|
5745
5768
|
} else {
|
|
5746
5769
|
peg$currPos = s0;
|
|
5747
5770
|
s0 = peg$FAILED;
|
|
@@ -5815,7 +5838,7 @@ function peg$parse(input, options) {
|
|
|
5815
5838
|
s2 = peg$parsetemplateLiteralChar();
|
|
5816
5839
|
}
|
|
5817
5840
|
peg$savedPos = s0;
|
|
5818
|
-
s1 = peg$
|
|
5841
|
+
s1 = peg$f104(s1);
|
|
5819
5842
|
s0 = s1;
|
|
5820
5843
|
|
|
5821
5844
|
return s0;
|
|
@@ -5845,7 +5868,7 @@ function peg$parse(input, options) {
|
|
|
5845
5868
|
}
|
|
5846
5869
|
if (s3 !== peg$FAILED) {
|
|
5847
5870
|
peg$savedPos = s0;
|
|
5848
|
-
s0 = peg$
|
|
5871
|
+
s0 = peg$f105(s2);
|
|
5849
5872
|
} else {
|
|
5850
5873
|
peg$currPos = s0;
|
|
5851
5874
|
s0 = peg$FAILED;
|
|
@@ -5894,7 +5917,7 @@ function peg$parse(input, options) {
|
|
|
5894
5917
|
s3 = peg$parseexpectUnaryExpression();
|
|
5895
5918
|
if (s3 !== peg$FAILED) {
|
|
5896
5919
|
peg$savedPos = s0;
|
|
5897
|
-
s0 = peg$
|
|
5920
|
+
s0 = peg$f106(s1, s3);
|
|
5898
5921
|
} else {
|
|
5899
5922
|
peg$currPos = s0;
|
|
5900
5923
|
s0 = peg$FAILED;
|
|
@@ -5951,7 +5974,7 @@ function peg$parse(input, options) {
|
|
|
5951
5974
|
s4 = null;
|
|
5952
5975
|
}
|
|
5953
5976
|
peg$savedPos = s0;
|
|
5954
|
-
s0 = peg$
|
|
5977
|
+
s0 = peg$f107(s1, s3, s4);
|
|
5955
5978
|
} else {
|
|
5956
5979
|
peg$currPos = s0;
|
|
5957
5980
|
s0 = peg$FAILED;
|
|
@@ -5971,7 +5994,7 @@ function peg$parse(input, options) {
|
|
|
5971
5994
|
s2 = peg$parsepathKeys();
|
|
5972
5995
|
if (s2 !== peg$FAILED) {
|
|
5973
5996
|
peg$savedPos = s0;
|
|
5974
|
-
s0 = peg$
|
|
5997
|
+
s0 = peg$f108(s1, s2);
|
|
5975
5998
|
} else {
|
|
5976
5999
|
peg$currPos = s0;
|
|
5977
6000
|
s0 = peg$FAILED;
|
|
@@ -6025,7 +6048,7 @@ function peg$parse(input, options) {
|
|
|
6025
6048
|
s2 = null;
|
|
6026
6049
|
}
|
|
6027
6050
|
peg$savedPos = s0;
|
|
6028
|
-
s0 = peg$
|
|
6051
|
+
s0 = peg$f109(s1);
|
|
6029
6052
|
} else {
|
|
6030
6053
|
peg$currPos = s0;
|
|
6031
6054
|
s0 = peg$FAILED;
|
|
@@ -6041,7 +6064,7 @@ function peg$parse(input, options) {
|
|
|
6041
6064
|
}
|
|
6042
6065
|
if (s1 !== peg$FAILED) {
|
|
6043
6066
|
peg$savedPos = s0;
|
|
6044
|
-
s1 = peg$
|
|
6067
|
+
s1 = peg$f110();
|
|
6045
6068
|
}
|
|
6046
6069
|
s0 = s1;
|
|
6047
6070
|
}
|
|
@@ -6050,15 +6073,44 @@ function peg$parse(input, options) {
|
|
|
6050
6073
|
}
|
|
6051
6074
|
|
|
6052
6075
|
function peg$parseuriKeyChar() {
|
|
6053
|
-
var s0;
|
|
6076
|
+
var s0, s1, s2, s3;
|
|
6054
6077
|
|
|
6055
|
-
s0 =
|
|
6056
|
-
|
|
6078
|
+
s0 = peg$currPos;
|
|
6079
|
+
s1 = input.charAt(peg$currPos);
|
|
6080
|
+
if (peg$r10.test(s1)) {
|
|
6057
6081
|
peg$currPos++;
|
|
6058
6082
|
} else {
|
|
6059
|
-
|
|
6083
|
+
s1 = peg$FAILED;
|
|
6060
6084
|
if (peg$silentFails === 0) { peg$fail(peg$e108); }
|
|
6061
6085
|
}
|
|
6086
|
+
if (s1 !== peg$FAILED) {
|
|
6087
|
+
s2 = peg$currPos;
|
|
6088
|
+
peg$silentFails++;
|
|
6089
|
+
peg$savedPos = peg$currPos;
|
|
6090
|
+
s3 = peg$f111(s1);
|
|
6091
|
+
if (s3) {
|
|
6092
|
+
s3 = undefined;
|
|
6093
|
+
} else {
|
|
6094
|
+
s3 = peg$FAILED;
|
|
6095
|
+
}
|
|
6096
|
+
peg$silentFails--;
|
|
6097
|
+
if (s3 === peg$FAILED) {
|
|
6098
|
+
s2 = undefined;
|
|
6099
|
+
} else {
|
|
6100
|
+
peg$currPos = s2;
|
|
6101
|
+
s2 = peg$FAILED;
|
|
6102
|
+
}
|
|
6103
|
+
if (s2 !== peg$FAILED) {
|
|
6104
|
+
peg$savedPos = s0;
|
|
6105
|
+
s0 = peg$f112(s1);
|
|
6106
|
+
} else {
|
|
6107
|
+
peg$currPos = s0;
|
|
6108
|
+
s0 = peg$FAILED;
|
|
6109
|
+
}
|
|
6110
|
+
} else {
|
|
6111
|
+
peg$currPos = s0;
|
|
6112
|
+
s0 = peg$FAILED;
|
|
6113
|
+
}
|
|
6062
6114
|
if (s0 === peg$FAILED) {
|
|
6063
6115
|
s0 = peg$parseescapedChar();
|
|
6064
6116
|
}
|
|
@@ -6086,7 +6138,7 @@ function peg$parse(input, options) {
|
|
|
6086
6138
|
}
|
|
6087
6139
|
if (s1 !== peg$FAILED) {
|
|
6088
6140
|
peg$savedPos = s0;
|
|
6089
|
-
s1 = peg$
|
|
6141
|
+
s1 = peg$f113(s1);
|
|
6090
6142
|
}
|
|
6091
6143
|
s0 = s1;
|
|
6092
6144
|
peg$silentFails--;
|
|
@@ -6137,7 +6189,7 @@ function peg$parse(input, options) {
|
|
|
6137
6189
|
}
|
|
6138
6190
|
if (s3 !== peg$FAILED) {
|
|
6139
6191
|
peg$savedPos = s0;
|
|
6140
|
-
s0 = peg$
|
|
6192
|
+
s0 = peg$f114();
|
|
6141
6193
|
} else {
|
|
6142
6194
|
peg$currPos = s0;
|
|
6143
6195
|
s0 = peg$FAILED;
|
|
@@ -6205,6 +6257,29 @@ function peg$parse(input, options) {
|
|
|
6205
6257
|
}
|
|
6206
6258
|
|
|
6207
6259
|
function peg$parsewhitespace() {
|
|
6260
|
+
var s0, s1;
|
|
6261
|
+
|
|
6262
|
+
s0 = [];
|
|
6263
|
+
s1 = peg$parsewhitespaceChar();
|
|
6264
|
+
if (s1 === peg$FAILED) {
|
|
6265
|
+
s1 = peg$parsecomment();
|
|
6266
|
+
}
|
|
6267
|
+
if (s1 !== peg$FAILED) {
|
|
6268
|
+
while (s1 !== peg$FAILED) {
|
|
6269
|
+
s0.push(s1);
|
|
6270
|
+
s1 = peg$parsewhitespaceChar();
|
|
6271
|
+
if (s1 === peg$FAILED) {
|
|
6272
|
+
s1 = peg$parsecomment();
|
|
6273
|
+
}
|
|
6274
|
+
}
|
|
6275
|
+
} else {
|
|
6276
|
+
s0 = peg$FAILED;
|
|
6277
|
+
}
|
|
6278
|
+
|
|
6279
|
+
return s0;
|
|
6280
|
+
}
|
|
6281
|
+
|
|
6282
|
+
function peg$parsewhitespaceChar() {
|
|
6208
6283
|
var s0, s1, s2;
|
|
6209
6284
|
|
|
6210
6285
|
s0 = peg$currPos;
|
|
@@ -6217,7 +6292,7 @@ function peg$parse(input, options) {
|
|
|
6217
6292
|
}
|
|
6218
6293
|
if (s1 !== peg$FAILED) {
|
|
6219
6294
|
peg$savedPos = peg$currPos;
|
|
6220
|
-
s2 = peg$
|
|
6295
|
+
s2 = peg$f115(s1);
|
|
6221
6296
|
if (s2) {
|
|
6222
6297
|
s2 = undefined;
|
|
6223
6298
|
} else {
|
|
@@ -6225,7 +6300,7 @@ function peg$parse(input, options) {
|
|
|
6225
6300
|
}
|
|
6226
6301
|
if (s2 !== peg$FAILED) {
|
|
6227
6302
|
peg$savedPos = s0;
|
|
6228
|
-
s0 = peg$
|
|
6303
|
+
s0 = peg$f116(s1);
|
|
6229
6304
|
} else {
|
|
6230
6305
|
peg$currPos = s0;
|
|
6231
6306
|
s0 = peg$FAILED;
|
|
@@ -6234,9 +6309,6 @@ function peg$parse(input, options) {
|
|
|
6234
6309
|
peg$currPos = s0;
|
|
6235
6310
|
s0 = peg$FAILED;
|
|
6236
6311
|
}
|
|
6237
|
-
if (s0 === peg$FAILED) {
|
|
6238
|
-
s0 = peg$parsecomment();
|
|
6239
|
-
}
|
|
6240
6312
|
|
|
6241
6313
|
return s0;
|
|
6242
6314
|
}
|
|
@@ -6395,6 +6467,7 @@ const peg$allowedStartRules = [
|
|
|
6395
6467
|
"pipelineExpression",
|
|
6396
6468
|
"primary",
|
|
6397
6469
|
"program",
|
|
6470
|
+
"programMode",
|
|
6398
6471
|
"propertyAccess",
|
|
6399
6472
|
"regexFlags",
|
|
6400
6473
|
"regexLiteral",
|
|
@@ -6434,6 +6507,7 @@ const peg$allowedStartRules = [
|
|
|
6434
6507
|
"uriScheme",
|
|
6435
6508
|
"unaryOperator",
|
|
6436
6509
|
"whitespace",
|
|
6510
|
+
"whitespaceChar",
|
|
6437
6511
|
"whitespaceWithNewLine"
|
|
6438
6512
|
];
|
|
6439
6513
|
|
|
@@ -28,7 +28,7 @@ export const markers = {
|
|
|
28
28
|
* If a parse result is an object that will be evaluated at runtime, attach the
|
|
29
29
|
* location of the source code that produced it for debugging and error messages.
|
|
30
30
|
*
|
|
31
|
-
* @param {
|
|
31
|
+
* @param {any[]} code
|
|
32
32
|
* @param {CodeLocation} location
|
|
33
33
|
*/
|
|
34
34
|
export function annotate(code, location) {
|
|
@@ -375,11 +375,12 @@ export function makePath(keys) {
|
|
|
375
375
|
const reference = annotate([markers.reference, headKey], head.location);
|
|
376
376
|
|
|
377
377
|
let code = [markers.traverse, reference, ...tail];
|
|
378
|
-
|
|
378
|
+
const location = spanLocations(code);
|
|
379
|
+
code = annotate(code, location);
|
|
379
380
|
|
|
380
381
|
// Last key has trailing slash implies unpack operation
|
|
381
382
|
if (trailingSlash.has(args.at(-1)[1])) {
|
|
382
|
-
code = annotate([ops.unpack, code],
|
|
383
|
+
code = annotate([ops.unpack, code], location);
|
|
383
384
|
}
|
|
384
385
|
|
|
385
386
|
return code;
|
package/src/runtime/jsGlobals.js
CHANGED
|
@@ -12,22 +12,46 @@ import path from "node:path";
|
|
|
12
12
|
* Fetch API
|
|
13
13
|
* URL API
|
|
14
14
|
*/
|
|
15
|
-
|
|
15
|
+
const globals = {
|
|
16
|
+
AbortController,
|
|
17
|
+
AbortSignal,
|
|
16
18
|
AggregateError,
|
|
17
19
|
Array,
|
|
18
20
|
ArrayBuffer,
|
|
21
|
+
// @ts-ignore this exists despite what TypeScript thinks
|
|
22
|
+
AsyncDisposableStack,
|
|
19
23
|
Atomics,
|
|
20
24
|
BigInt,
|
|
21
25
|
BigInt64Array,
|
|
22
26
|
BigUint64Array,
|
|
27
|
+
Blob,
|
|
23
28
|
Boolean,
|
|
29
|
+
BroadcastChannel,
|
|
30
|
+
Buffer,
|
|
31
|
+
ByteLengthQueuingStrategy,
|
|
32
|
+
CloseEvent,
|
|
33
|
+
CompressionStream,
|
|
34
|
+
CountQueuingStrategy,
|
|
35
|
+
Crypto,
|
|
36
|
+
CryptoKey,
|
|
37
|
+
CustomEvent,
|
|
38
|
+
DOMException,
|
|
24
39
|
DataView,
|
|
25
40
|
Date,
|
|
41
|
+
DecompressionStream,
|
|
42
|
+
// @ts-ignore this exists despite what TypeScript thinks
|
|
43
|
+
DisposableStack,
|
|
26
44
|
Error,
|
|
27
45
|
EvalError,
|
|
46
|
+
Event,
|
|
47
|
+
EventTarget,
|
|
48
|
+
File,
|
|
28
49
|
FinalizationRegistry,
|
|
50
|
+
// @ts-ignore this exists despite what TypeScript thinks
|
|
51
|
+
Float16Array,
|
|
29
52
|
Float32Array,
|
|
30
53
|
Float64Array,
|
|
54
|
+
FormData,
|
|
31
55
|
Function,
|
|
32
56
|
Headers,
|
|
33
57
|
Infinity,
|
|
@@ -35,17 +59,33 @@ export default {
|
|
|
35
59
|
Int32Array,
|
|
36
60
|
Int8Array,
|
|
37
61
|
Intl,
|
|
38
|
-
// @ts-ignore
|
|
62
|
+
// @ts-ignore this exists despite what TypeScript thinks
|
|
39
63
|
Iterator,
|
|
40
64
|
JSON,
|
|
41
65
|
Map,
|
|
42
66
|
Math,
|
|
67
|
+
MessageChannel,
|
|
68
|
+
MessageEvent,
|
|
69
|
+
MessagePort,
|
|
43
70
|
NaN,
|
|
44
71
|
Number,
|
|
45
72
|
Object,
|
|
73
|
+
Performance,
|
|
74
|
+
PerformanceEntry,
|
|
75
|
+
PerformanceMark,
|
|
76
|
+
PerformanceMeasure,
|
|
77
|
+
PerformanceObserver,
|
|
78
|
+
PerformanceObserverEntryList,
|
|
79
|
+
PerformanceResourceTiming,
|
|
46
80
|
Promise,
|
|
47
81
|
Proxy,
|
|
48
82
|
RangeError,
|
|
83
|
+
ReadableByteStreamController,
|
|
84
|
+
ReadableStream,
|
|
85
|
+
ReadableStreamBYOBReader,
|
|
86
|
+
ReadableStreamBYOBRequest,
|
|
87
|
+
ReadableStreamDefaultController,
|
|
88
|
+
ReadableStreamDefaultReader,
|
|
49
89
|
ReferenceError,
|
|
50
90
|
Reflect,
|
|
51
91
|
RegExp,
|
|
@@ -54,10 +94,23 @@ export default {
|
|
|
54
94
|
Set,
|
|
55
95
|
SharedArrayBuffer,
|
|
56
96
|
String,
|
|
97
|
+
SubtleCrypto,
|
|
98
|
+
// @ts-ignore this exists despite what TypeScript thinks
|
|
99
|
+
SuppressedError,
|
|
57
100
|
Symbol,
|
|
58
101
|
SyntaxError,
|
|
102
|
+
TextDecoder,
|
|
103
|
+
TextDecoderStream,
|
|
104
|
+
TextEncoder,
|
|
105
|
+
TextEncoderStream,
|
|
106
|
+
TransformStream,
|
|
107
|
+
TransformStreamDefaultController,
|
|
59
108
|
TypeError,
|
|
60
109
|
URIError,
|
|
110
|
+
URL,
|
|
111
|
+
// @ts-ignore this exists despite what TypeScript thinks
|
|
112
|
+
URLPattern,
|
|
113
|
+
URLSearchParams,
|
|
61
114
|
Uint16Array,
|
|
62
115
|
Uint32Array,
|
|
63
116
|
Uint8Array,
|
|
@@ -65,24 +118,58 @@ export default {
|
|
|
65
118
|
WeakMap,
|
|
66
119
|
WeakRef,
|
|
67
120
|
WeakSet,
|
|
121
|
+
WebAssembly,
|
|
122
|
+
WebSocket,
|
|
123
|
+
WritableStream,
|
|
124
|
+
WritableStreamDefaultController,
|
|
125
|
+
WritableStreamDefaultWriter,
|
|
126
|
+
atob,
|
|
127
|
+
btoa,
|
|
128
|
+
clearImmediate,
|
|
129
|
+
clearInterval,
|
|
130
|
+
clearTimeout,
|
|
131
|
+
console,
|
|
132
|
+
crypto,
|
|
68
133
|
decodeURI,
|
|
69
134
|
decodeURIComponent,
|
|
70
135
|
encodeURI,
|
|
71
136
|
encodeURIComponent,
|
|
137
|
+
escape,
|
|
72
138
|
eval,
|
|
73
|
-
|
|
74
|
-
fetch: fetchWrapper, // special case
|
|
139
|
+
// fetch -- special case, see below
|
|
75
140
|
globalThis,
|
|
76
|
-
import: importWrapper, // not a function in JS but acts like one
|
|
77
141
|
isFinite,
|
|
78
142
|
isNaN,
|
|
79
|
-
null: null, // treat like a global
|
|
80
143
|
parseFloat,
|
|
81
144
|
parseInt,
|
|
82
|
-
|
|
145
|
+
performance,
|
|
146
|
+
process,
|
|
147
|
+
queueMicrotask,
|
|
148
|
+
setImmediate,
|
|
149
|
+
setInterval,
|
|
150
|
+
setTimeout,
|
|
151
|
+
structuredClone,
|
|
83
152
|
undefined,
|
|
153
|
+
unescape,
|
|
154
|
+
|
|
155
|
+
// Treat these like globals
|
|
156
|
+
false: false,
|
|
157
|
+
null: null,
|
|
158
|
+
true: true,
|
|
159
|
+
|
|
160
|
+
// Special cases
|
|
161
|
+
fetch: fetchWrapper,
|
|
162
|
+
import: importWrapper,
|
|
84
163
|
};
|
|
85
164
|
|
|
165
|
+
// Give access to our own custom globals as `globalThis`
|
|
166
|
+
Object.defineProperty(globals, "globalThis", {
|
|
167
|
+
enumerable: true,
|
|
168
|
+
value: globals,
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
export default globals;
|
|
172
|
+
|
|
86
173
|
async function fetchWrapper(resource, options) {
|
|
87
174
|
const response = await fetch(resource, options);
|
|
88
175
|
return response.ok ? await response.arrayBuffer() : undefined;
|
package/src/runtime/ops.js
CHANGED
|
@@ -99,13 +99,18 @@ cache.unevaluatedArgs = true;
|
|
|
99
99
|
/**
|
|
100
100
|
* JavaScript comma operator, returns the last argument.
|
|
101
101
|
*
|
|
102
|
-
* @
|
|
103
|
-
* @
|
|
102
|
+
* @this {AsyncTree|null}
|
|
103
|
+
* @param {...AnnotatedCode} args
|
|
104
104
|
*/
|
|
105
|
-
export function comma(...args) {
|
|
106
|
-
|
|
105
|
+
export async function comma(...args) {
|
|
106
|
+
let result;
|
|
107
|
+
for (const arg of args) {
|
|
108
|
+
result = await evaluate.call(this, arg);
|
|
109
|
+
}
|
|
110
|
+
return result;
|
|
107
111
|
}
|
|
108
112
|
addOpLabel(comma, "«ops.comma»");
|
|
113
|
+
comma.unevaluatedArgs = true;
|
|
109
114
|
|
|
110
115
|
/**
|
|
111
116
|
* Concatenate the given arguments.
|
|
@@ -204,7 +209,7 @@ addOpLabel(greaterThanOrEqual, "«ops.greaterThanOrEqual»");
|
|
|
204
209
|
export async function homeDirectory(...keys) {
|
|
205
210
|
const tree = new OrigamiFiles(os.homedir());
|
|
206
211
|
// Use the same handlers as the current tree
|
|
207
|
-
tree.handlers = getHandlers(this);
|
|
212
|
+
/** @type {any} */ (tree).handlers = getHandlers(this);
|
|
208
213
|
return keys.length > 0 ? Tree.traverse(tree, ...keys) : tree;
|
|
209
214
|
}
|
|
210
215
|
addOpLabel(homeDirectory, "«ops.homeDirectory»");
|
|
@@ -424,7 +429,7 @@ addOpLabel(remainder, "«ops.remainder»");
|
|
|
424
429
|
export async function rootDirectory(...keys) {
|
|
425
430
|
const tree = new OrigamiFiles("/");
|
|
426
431
|
// Use the same handlers as the current tree
|
|
427
|
-
tree.handlers = getHandlers(this);
|
|
432
|
+
/** @type {any} */ (tree).handlers = getHandlers(this);
|
|
428
433
|
return keys.length > 0 ? Tree.traverse(tree, ...keys) : tree;
|
|
429
434
|
}
|
|
430
435
|
addOpLabel(rootDirectory, "«ops.rootDirectory»");
|
|
@@ -7,6 +7,15 @@ export function assertCodeEqual(actual, expected) {
|
|
|
7
7
|
assert.deepStrictEqual(actualStripped, expectedStripped);
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
export function assertCodeLocations(code) {
|
|
11
|
+
assert(code.location, "no location");
|
|
12
|
+
for (const item of code) {
|
|
13
|
+
if (Array.isArray(item)) {
|
|
14
|
+
assertCodeLocations(item);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
10
19
|
/**
|
|
11
20
|
* Adds a fake source to code.
|
|
12
21
|
*
|
|
@@ -4,7 +4,11 @@ import * as compile from "../../src/compiler/compile.js";
|
|
|
4
4
|
import optimize from "../../src/compiler/optimize.js";
|
|
5
5
|
import { markers } from "../../src/compiler/parserHelpers.js";
|
|
6
6
|
import { ops } from "../../src/runtime/internal.js";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
assertCodeEqual,
|
|
9
|
+
assertCodeLocations,
|
|
10
|
+
createCode,
|
|
11
|
+
} from "./codeHelpers.js";
|
|
8
12
|
|
|
9
13
|
describe("optimize", () => {
|
|
10
14
|
test("change local references to context references", () => {
|
|
@@ -277,5 +281,6 @@ function assertCompile(expression, expected, mode = "shell") {
|
|
|
277
281
|
const globals = new ObjectTree({});
|
|
278
282
|
const fn = compile.expression(expression, { globals, mode, parent });
|
|
279
283
|
const actual = fn.code;
|
|
284
|
+
assertCodeLocations(actual);
|
|
280
285
|
assertCodeEqual(actual, expected);
|
|
281
286
|
}
|
|
@@ -3,7 +3,7 @@ import { describe, test } from "node:test";
|
|
|
3
3
|
import { parse } from "../../src/compiler/parse.js";
|
|
4
4
|
import { markers } from "../../src/compiler/parserHelpers.js";
|
|
5
5
|
import * as ops from "../../src/runtime/ops.js";
|
|
6
|
-
import { assertCodeEqual } from "./codeHelpers.js";
|
|
6
|
+
import { assertCodeEqual, assertCodeLocations } from "./codeHelpers.js";
|
|
7
7
|
|
|
8
8
|
describe("Origami parser", () => {
|
|
9
9
|
test("additiveExpression", () => {
|
|
@@ -1537,19 +1537,6 @@ Body text`,
|
|
|
1537
1537
|
assertParse("uriScheme", "https:", [markers.global, "https:"]);
|
|
1538
1538
|
});
|
|
1539
1539
|
|
|
1540
|
-
test("whitespace block", () => {
|
|
1541
|
-
assertParse(
|
|
1542
|
-
"__",
|
|
1543
|
-
`
|
|
1544
|
-
// First comment
|
|
1545
|
-
// Second comment
|
|
1546
|
-
`,
|
|
1547
|
-
null,
|
|
1548
|
-
"jse",
|
|
1549
|
-
false
|
|
1550
|
-
);
|
|
1551
|
-
});
|
|
1552
|
-
|
|
1553
1540
|
test("unaryExpression", () => {
|
|
1554
1541
|
assertParse("unaryExpression", "!true", [
|
|
1555
1542
|
ops.logicalNot,
|
|
@@ -1566,6 +1553,19 @@ Body text`,
|
|
|
1566
1553
|
assertParse("unaryOperator", "-", "-");
|
|
1567
1554
|
assertParse("unaryOperator", "~", "~");
|
|
1568
1555
|
});
|
|
1556
|
+
|
|
1557
|
+
test("whitespace block", () => {
|
|
1558
|
+
assertParse(
|
|
1559
|
+
"__",
|
|
1560
|
+
`
|
|
1561
|
+
// First comment
|
|
1562
|
+
// Second comment
|
|
1563
|
+
`,
|
|
1564
|
+
null,
|
|
1565
|
+
"jse",
|
|
1566
|
+
false
|
|
1567
|
+
);
|
|
1568
|
+
});
|
|
1569
1569
|
});
|
|
1570
1570
|
|
|
1571
1571
|
function assertParse(
|
|
@@ -1596,16 +1596,8 @@ function assertParse(
|
|
|
1596
1596
|
assertCodeEqual(code, expected);
|
|
1597
1597
|
}
|
|
1598
1598
|
|
|
1599
|
-
function assertCodeLocations(code) {
|
|
1600
|
-
assert(code.location, "no location");
|
|
1601
|
-
for (const item of code) {
|
|
1602
|
-
if (Array.isArray(item)) {
|
|
1603
|
-
assertCodeLocations(item);
|
|
1604
|
-
}
|
|
1605
|
-
}
|
|
1606
|
-
}
|
|
1607
|
-
|
|
1608
1599
|
function assertThrows(startRule, source, message, position, mode = "shell") {
|
|
1600
|
+
// @ts-ignore We declare this so we can inspect it in debugger
|
|
1609
1601
|
let code;
|
|
1610
1602
|
try {
|
|
1611
1603
|
code = parse(source, {
|
|
@@ -54,7 +54,7 @@ describe("expressionObject", () => {
|
|
|
54
54
|
test("returned object values can be unpacked", async () => {
|
|
55
55
|
const entries = [["data.json", `{ "a": 1 }`]];
|
|
56
56
|
const parent = new ObjectTree({});
|
|
57
|
-
parent.handlers = {
|
|
57
|
+
/** @type {any} */ (parent).handlers = {
|
|
58
58
|
"json.handler": {
|
|
59
59
|
unpack: JSON.parse,
|
|
60
60
|
},
|
package/test/runtime/ops.test.js
CHANGED
|
@@ -358,7 +358,7 @@ describe("ops", () => {
|
|
|
358
358
|
const a = await tree.get("a");
|
|
359
359
|
const b = await a.get("b");
|
|
360
360
|
const scope = await ops.scope.call(b);
|
|
361
|
-
assert.equal(await scope
|
|
361
|
+
assert.equal(await scope?.get("c"), 1);
|
|
362
362
|
});
|
|
363
363
|
|
|
364
364
|
test("accepts an optional context", async () => {
|
|
@@ -372,7 +372,7 @@ describe("ops", () => {
|
|
|
372
372
|
const a = await tree.get("a");
|
|
373
373
|
const b = await a.get("b");
|
|
374
374
|
const scope = await ops.scope.call(b, tree);
|
|
375
|
-
assert.equal(await scope
|
|
375
|
+
assert.equal(await scope?.get("c"), 1);
|
|
376
376
|
});
|
|
377
377
|
});
|
|
378
378
|
|