@weborigami/language 0.3.3-jse.2 → 0.3.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.
- package/main.js +1 -1
- package/package.json +3 -3
- package/src/compiler/compile.js +0 -2
- package/src/compiler/origami.pegjs +28 -118
- package/src/compiler/parse.js +818 -1502
- package/src/compiler/parserHelpers.js +12 -13
- package/src/runtime/handlers.js +1 -4
- package/src/runtime/ops.js +10 -34
- package/src/runtime/{templateIndent.js → taggedTemplateIndent.js} +2 -2
- package/test/compiler/parse.test.js +24 -142
- package/test/runtime/ops.test.js +2 -11
- package/test/runtime/taggedTemplateIndent.test.js +1 -1
- package/src/runtime/templateStandard.js +0 -13
- package/test/runtime/templateText.test.js +0 -18
package/main.js
CHANGED
|
@@ -14,6 +14,6 @@ export { default as InvokeFunctionsTransform } from "./src/runtime/InvokeFunctio
|
|
|
14
14
|
export * as moduleCache from "./src/runtime/moduleCache.js";
|
|
15
15
|
export { default as OrigamiFiles } from "./src/runtime/OrigamiFiles.js";
|
|
16
16
|
export * as symbols from "./src/runtime/symbols.js";
|
|
17
|
-
export { default as taggedTemplateIndent } from "./src/runtime/
|
|
17
|
+
export { default as taggedTemplateIndent } from "./src/runtime/taggedTemplateIndent.js";
|
|
18
18
|
export { default as TreeEvent } from "./src/runtime/TreeEvent.js";
|
|
19
19
|
export { default as WatchFilesMixin } from "./src/runtime/WatchFilesMixin.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weborigami/language",
|
|
3
|
-
"version": "0.3.3
|
|
3
|
+
"version": "0.3.3",
|
|
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.3.3
|
|
15
|
-
"@weborigami/types": "0.3.3
|
|
14
|
+
"@weborigami/async-tree": "0.3.3",
|
|
15
|
+
"@weborigami/types": "0.3.3",
|
|
16
16
|
"watcher": "2.3.1",
|
|
17
17
|
"yaml": "2.7.0"
|
|
18
18
|
},
|
package/src/compiler/compile.js
CHANGED
|
@@ -4,14 +4,12 @@ import { parse } from "./parse.js";
|
|
|
4
4
|
|
|
5
5
|
function compile(source, options) {
|
|
6
6
|
const { macros, startRule } = options;
|
|
7
|
-
const mode = options.mode ?? "shell";
|
|
8
7
|
const enableCaching = options.scopeCaching ?? true;
|
|
9
8
|
if (typeof source === "string") {
|
|
10
9
|
source = { text: source };
|
|
11
10
|
}
|
|
12
11
|
const code = parse(source.text, {
|
|
13
12
|
grammarSource: source,
|
|
14
|
-
mode,
|
|
15
13
|
startRule,
|
|
16
14
|
});
|
|
17
15
|
const optimized = optimize(code, enableCaching, macros);
|
|
@@ -40,7 +40,7 @@ __
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
additiveExpression
|
|
43
|
-
= head:multiplicativeExpression tail:(
|
|
43
|
+
= head:multiplicativeExpression tail:(whitespace @additiveOperator whitespace @multiplicativeExpression)* {
|
|
44
44
|
return tail.reduce(makeBinaryOperation, head);
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -48,49 +48,11 @@ additiveOperator
|
|
|
48
48
|
= "+"
|
|
49
49
|
/ "-"
|
|
50
50
|
|
|
51
|
-
angleBracketLiteral
|
|
52
|
-
= "<" __ protocol:angleBracketProtocol "//" path:angleBracketPath __ ">" {
|
|
53
|
-
return annotate([protocol, ...path], location());
|
|
54
|
-
}
|
|
55
|
-
/ "<" protocol:angleBracketProtocol path:angleBracketPath ">" {
|
|
56
|
-
const [head, ...tail] = path;
|
|
57
|
-
const root = annotate([protocol, head], location());
|
|
58
|
-
return annotate([ops.traverse, root, ...tail], location());
|
|
59
|
-
}
|
|
60
|
-
/ "<" __ path:angleBracketPath __ ">" {
|
|
61
|
-
const [head, ...tail] = path;
|
|
62
|
-
const root = annotate([ops.scope, head[1]], location());
|
|
63
|
-
return tail.length === 0
|
|
64
|
-
? root
|
|
65
|
-
: annotate([ops.traverse, root, ...tail], location())
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
angleBracketPath
|
|
69
|
-
= @angleBracketPathKey|0.., "/"| "/"?
|
|
70
|
-
|
|
71
|
-
angleBracketPathKey
|
|
72
|
-
= chars:angleBracketPathChar+ slashFollows:slashFollows? {
|
|
73
|
-
// Append a trailing slash if one follows (but don't consume it)
|
|
74
|
-
const key = chars.join("") + (slashFollows ? "/" : "");
|
|
75
|
-
return annotate([ops.literal, key], location());
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// A single character in a slash-separated path segment
|
|
79
|
-
angleBracketPathChar
|
|
80
|
-
= [^/:<>] // Much more permissive than an identifier
|
|
81
|
-
/ escapedChar
|
|
82
|
-
|
|
83
|
-
angleBracketProtocol
|
|
84
|
-
= protocol:jsIdentifier ":" {
|
|
85
|
-
return annotate([ops.builtin, `${protocol}:`], location());
|
|
86
|
-
}
|
|
87
|
-
|
|
88
51
|
arguments "function arguments"
|
|
89
52
|
= parenthesesArguments
|
|
90
|
-
/
|
|
53
|
+
/ pathArguments
|
|
91
54
|
/ jsPropertyAccess
|
|
92
55
|
/ computedPropertyAccess
|
|
93
|
-
/ optionalChaining
|
|
94
56
|
/ templateLiteral
|
|
95
57
|
|
|
96
58
|
arrayLiteral "array"
|
|
@@ -368,10 +330,17 @@ implicitParenthesesCallExpression "function call with implicit parentheses"
|
|
|
368
330
|
// A separated list of values for an implicit parens call. This differs from
|
|
369
331
|
// `list` in that the value term can't be a pipeline.
|
|
370
332
|
implicitParensthesesArguments
|
|
371
|
-
=
|
|
333
|
+
= values:shorthandFunction|1.., separator| separator? {
|
|
372
334
|
return annotate(values, location());
|
|
373
335
|
}
|
|
374
336
|
|
|
337
|
+
inherited
|
|
338
|
+
= rootDirectory
|
|
339
|
+
/ homeDirectory
|
|
340
|
+
/ qualifiedReference
|
|
341
|
+
/ namespace
|
|
342
|
+
/ scopeReference
|
|
343
|
+
|
|
375
344
|
inlineSpace
|
|
376
345
|
= [ \t]
|
|
377
346
|
|
|
@@ -380,9 +349,6 @@ integerLiteral "integer"
|
|
|
380
349
|
return annotate([ops.literal, parseInt(text())], location());
|
|
381
350
|
}
|
|
382
351
|
|
|
383
|
-
jseMode
|
|
384
|
-
= &{ return options.mode === "jse" }
|
|
385
|
-
|
|
386
352
|
jsIdentifier
|
|
387
353
|
= $( jsIdentifierStart jsIdentifierPart* )
|
|
388
354
|
|
|
@@ -402,17 +368,16 @@ jsPropertyAccess
|
|
|
402
368
|
return annotate([ops.traverse, literal], location());
|
|
403
369
|
}
|
|
404
370
|
|
|
405
|
-
jsReference "identifier reference"
|
|
406
|
-
= id:jsIdentifier {
|
|
407
|
-
return annotate([ops.scope, id], location());
|
|
408
|
-
}
|
|
409
|
-
|
|
410
371
|
// A separated list of values
|
|
411
372
|
list "list"
|
|
412
373
|
= values:pipelineExpression|1.., separator| separator? {
|
|
413
374
|
return annotate(values, location());
|
|
414
375
|
}
|
|
415
376
|
|
|
377
|
+
literal
|
|
378
|
+
= numericLiteral
|
|
379
|
+
/ stringLiteral
|
|
380
|
+
|
|
416
381
|
logicalAndExpression
|
|
417
382
|
= head:bitwiseOrExpression tail:(__ "&&" __ @bitwiseOrExpression)* {
|
|
418
383
|
return tail.length === 0
|
|
@@ -437,7 +402,7 @@ multiLineComment
|
|
|
437
402
|
= "/*" (!"*/" .)* "*/" { return null; }
|
|
438
403
|
|
|
439
404
|
multiplicativeExpression
|
|
440
|
-
= head:exponentiationExpression tail:(
|
|
405
|
+
= head:exponentiationExpression tail:(whitespace @multiplicativeOperator whitespace @exponentiationExpression)* {
|
|
441
406
|
return tail.reduce(makeBinaryOperation, head);
|
|
442
407
|
}
|
|
443
408
|
|
|
@@ -452,13 +417,6 @@ namespace
|
|
|
452
417
|
return annotate([ops.builtin, chars.join("") + ":"], location());
|
|
453
418
|
}
|
|
454
419
|
|
|
455
|
-
// A new expression: `new Foo()`
|
|
456
|
-
newExpression
|
|
457
|
-
= "new" __ head:jsReference tail:parenthesesArguments {
|
|
458
|
-
const args = tail?.[0] !== undefined ? tail : [];
|
|
459
|
-
return annotate([ops.construct, head, ...args], location());
|
|
460
|
-
}
|
|
461
|
-
|
|
462
420
|
newLine
|
|
463
421
|
= "\n"
|
|
464
422
|
/ "\r\n"
|
|
@@ -528,18 +486,13 @@ objectShorthandProperty "object identifier"
|
|
|
528
486
|
|
|
529
487
|
objectPublicKey
|
|
530
488
|
= identifier:identifier slash:"/"? {
|
|
531
|
-
|
|
532
|
-
|
|
489
|
+
return identifier + (slash ?? "");
|
|
490
|
+
}
|
|
533
491
|
/ string:stringLiteral {
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
optionalChaining
|
|
539
|
-
= __ "?." __ property:jsIdentifier {
|
|
540
|
-
const literal = annotate([ops.literal, property], location());
|
|
541
|
-
return annotate([ops.optionalTraverse, literal], location());
|
|
492
|
+
// Remove `ops.literal` from the string code
|
|
493
|
+
return string[1];
|
|
542
494
|
}
|
|
495
|
+
|
|
543
496
|
parameter
|
|
544
497
|
= identifier:identifier {
|
|
545
498
|
return annotate([ops.literal, identifier], location());
|
|
@@ -609,27 +562,12 @@ pipelineExpression
|
|
|
609
562
|
}
|
|
610
563
|
|
|
611
564
|
primary
|
|
612
|
-
=
|
|
613
|
-
/ stringLiteral
|
|
565
|
+
= literal
|
|
614
566
|
/ arrayLiteral
|
|
615
567
|
/ objectLiteral
|
|
616
568
|
/ group
|
|
617
569
|
/ templateLiteral
|
|
618
|
-
/
|
|
619
|
-
/ jseMode @primaryJse
|
|
620
|
-
|
|
621
|
-
// Primary allowed in JSE mode
|
|
622
|
-
primaryJse
|
|
623
|
-
= angleBracketLiteral
|
|
624
|
-
/ jsReference
|
|
625
|
-
/ regexLiteral
|
|
626
|
-
|
|
627
|
-
primaryShell
|
|
628
|
-
= rootDirectory
|
|
629
|
-
/ homeDirectory
|
|
630
|
-
/ qualifiedReference
|
|
631
|
-
/ namespace
|
|
632
|
-
/ scopeReference
|
|
570
|
+
/ inherited
|
|
633
571
|
|
|
634
572
|
// Top-level Origami progam with possible shebang directive (which is ignored)
|
|
635
573
|
program "Origami program"
|
|
@@ -641,7 +579,6 @@ protocolExpression
|
|
|
641
579
|
const keys = annotate([host, ...(path ?? [])], location());
|
|
642
580
|
return makeCall(fn, keys);
|
|
643
581
|
}
|
|
644
|
-
/ newExpression
|
|
645
582
|
/ primary
|
|
646
583
|
|
|
647
584
|
// A namespace followed by a key: `foo:x`
|
|
@@ -651,21 +588,6 @@ qualifiedReference
|
|
|
651
588
|
return makeCall(fn, [literal]);
|
|
652
589
|
}
|
|
653
590
|
|
|
654
|
-
regexFlags
|
|
655
|
-
= flags:[gimuy]* {
|
|
656
|
-
return flags.join("");
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
regexLiteral
|
|
660
|
-
= "/" chars:regexLiteralChar* "/" flags:regexFlags? {
|
|
661
|
-
const regex = new RegExp(chars.join(""), flags);
|
|
662
|
-
return annotate([ops.literal, regex], location());
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
regexLiteralChar
|
|
666
|
-
= [^/\n\r] // No unescaped slashes or newlines
|
|
667
|
-
/ escapedChar
|
|
668
|
-
|
|
669
591
|
relationalExpression
|
|
670
592
|
= head:shiftExpression tail:(__ @relationalOperator __ @shiftExpression)* {
|
|
671
593
|
return tail.reduce(makeBinaryOperation, head);
|
|
@@ -695,14 +617,11 @@ scopeReference "scope reference"
|
|
|
695
617
|
|
|
696
618
|
separator
|
|
697
619
|
= __ "," __
|
|
698
|
-
/
|
|
620
|
+
/ whitespaceWithNewLine
|
|
699
621
|
|
|
700
622
|
shebang
|
|
701
623
|
= "#!" [^\n\r]* { return null; }
|
|
702
624
|
|
|
703
|
-
shellMode
|
|
704
|
-
= &{ return options.mode === "shell" }
|
|
705
|
-
|
|
706
625
|
shiftExpression
|
|
707
626
|
= head:additiveExpression tail:(__ @shiftOperator __ @additiveExpression)* {
|
|
708
627
|
return tail.reduce(makeBinaryOperation, head);
|
|
@@ -716,7 +635,7 @@ shiftOperator
|
|
|
716
635
|
// A shorthand lambda expression: `=foo(_)`
|
|
717
636
|
shorthandFunction "lambda function"
|
|
718
637
|
// Avoid a following equal sign (for an equality)
|
|
719
|
-
=
|
|
638
|
+
= "=" !"=" __ definition:implicitParenthesesCallExpression {
|
|
720
639
|
const lambdaParameters = annotate(
|
|
721
640
|
[annotate([ops.literal, "_"], location())],
|
|
722
641
|
location()
|
|
@@ -761,7 +680,7 @@ spreadElement
|
|
|
761
680
|
stringLiteral "string"
|
|
762
681
|
= doubleQuoteString
|
|
763
682
|
/ singleQuoteString
|
|
764
|
-
/
|
|
683
|
+
/ guillemetString
|
|
765
684
|
|
|
766
685
|
// The body of a template document is a kind of template literal that can
|
|
767
686
|
// contain backticks at the top level.
|
|
@@ -788,8 +707,7 @@ templateBodyText "template text"
|
|
|
788
707
|
|
|
789
708
|
templateDocument "template document"
|
|
790
709
|
= front:frontMatterExpression __ body:templateBody {
|
|
791
|
-
|
|
792
|
-
return annotate(applyMacro(front, macroName, body), location());
|
|
710
|
+
return annotate(applyMacro(front, "@template", body), location());
|
|
793
711
|
}
|
|
794
712
|
/ front:frontMatterYaml? body:templateBody {
|
|
795
713
|
return front
|
|
@@ -800,8 +718,7 @@ templateDocument "template document"
|
|
|
800
718
|
// A backtick-quoted template literal
|
|
801
719
|
templateLiteral "template literal"
|
|
802
720
|
= "`" head:templateLiteralText tail:(templateSubstitution templateLiteralText)* expectBacktick {
|
|
803
|
-
|
|
804
|
-
return makeTemplate(op, head, tail, location());
|
|
721
|
+
return makeTemplate(ops.template, head, tail, location());
|
|
805
722
|
}
|
|
806
723
|
|
|
807
724
|
templateLiteralChar
|
|
@@ -833,9 +750,7 @@ unaryExpression
|
|
|
833
750
|
unaryOperator
|
|
834
751
|
= "!"
|
|
835
752
|
/ "+"
|
|
836
|
-
|
|
837
|
-
// lookahead !"--\n" doesn't work.
|
|
838
|
-
/ @"-" !"-\n"
|
|
753
|
+
/ "-"
|
|
839
754
|
/ "~"
|
|
840
755
|
|
|
841
756
|
whitespace
|
|
@@ -843,10 +758,5 @@ whitespace
|
|
|
843
758
|
/ newLine
|
|
844
759
|
/ comment
|
|
845
760
|
|
|
846
|
-
// Whitespace requires in shell mode, optional in JSE mode
|
|
847
|
-
whitespaceShell
|
|
848
|
-
= shellMode whitespace
|
|
849
|
-
/ jseMode __
|
|
850
|
-
|
|
851
761
|
whitespaceWithNewLine
|
|
852
762
|
= inlineSpace* comment? newLine __
|