@hyperfixi/core 2.0.0 → 2.2.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/dist/api/hyperscript-api.d.ts +8 -1
- package/dist/ast-utils/index.d.ts +1 -1
- package/dist/ast-utils/index.js +11 -1
- package/dist/ast-utils/index.mjs +11 -1
- package/dist/ast-utils/interchange/index.d.ts +1 -1
- package/dist/ast-utils/interchange/lsp.d.ts +4 -1
- package/dist/behaviors/index.js +13 -5
- package/dist/behaviors/index.mjs +13 -5
- package/dist/bundle-generator/index.js +9 -0
- package/dist/bundle-generator/index.mjs +9 -0
- package/dist/chunks/{bridge-I6ceoWxV.js → bridge-D2DBo02Z.js} +2 -2
- package/dist/chunks/browser-modular-BA3JFmkq.js +2 -0
- package/dist/chunks/feature-eventsource-B5F2-H1r.js +2 -0
- package/dist/chunks/feature-sockets-ClOH7vk7.js +2 -0
- package/dist/chunks/feature-webworker-3bAp0ac9.js +2 -0
- package/dist/chunks/index-C6Fn0jGB.js +2 -0
- package/dist/commands/dom/toggle.d.ts +2 -0
- package/dist/commands/index.js +62 -6
- package/dist/commands/index.mjs +62 -6
- package/dist/debug/debug-controller.d.ts +62 -0
- package/dist/debug/index.d.ts +5 -0
- package/dist/expressions/index.js +16 -79
- package/dist/expressions/index.mjs +16 -79
- package/dist/hyperfixi-classic-i18n.js +1 -1
- package/dist/hyperfixi-hx.js +1 -1
- package/dist/hyperfixi-hybrid-complete.js +1 -1
- package/dist/hyperfixi-minimal.js +1 -1
- package/dist/hyperfixi-multilingual.js +1 -1
- package/dist/hyperfixi-standard.js +1 -1
- package/dist/hyperfixi.js +1 -1
- package/dist/hyperfixi.mjs +1 -1
- package/dist/i18n/error-catalog.d.ts +12 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +35334 -24306
- package/dist/index.min.js +1 -1
- package/dist/index.mjs +35333 -24307
- package/dist/lokascript-browser-classic-i18n.js +1 -1
- package/dist/lokascript-browser-minimal.js +1 -1
- package/dist/lokascript-browser-standard.js +1 -1
- package/dist/lokascript-browser.js +1 -1
- package/dist/lokascript-hybrid-complete.js +1 -1
- package/dist/lokascript-hybrid-hx.js +1 -1
- package/dist/lokascript-multilingual.js +1 -1
- package/dist/lse/index.d.ts +15 -0
- package/dist/lse/index.js +84 -0
- package/dist/lse/index.mjs +71 -0
- package/dist/metadata.d.ts +4 -4
- package/dist/metadata.js +4 -4
- package/dist/metadata.mjs +4 -4
- package/dist/parser/full-parser.js +608 -271
- package/dist/parser/full-parser.mjs +608 -271
- package/dist/parser/helpers/ast-helpers.d.ts +1 -0
- package/dist/parser/hybrid/index.js +35 -2
- package/dist/parser/hybrid/index.mjs +35 -2
- package/dist/parser/hybrid/parser-core.d.ts +1 -0
- package/dist/parser/hybrid/parser-core.js +35 -2
- package/dist/parser/hybrid/parser-core.mjs +35 -2
- package/dist/parser/hybrid/tokenizer.js +5 -0
- package/dist/parser/hybrid/tokenizer.mjs +5 -0
- package/dist/parser/hybrid-parser.js +35 -2
- package/dist/parser/hybrid-parser.mjs +35 -2
- package/dist/parser/parser-types.d.ts +22 -7
- package/dist/parser/parser.d.ts +7 -0
- package/dist/parser/pratt-parser.d.ts +42 -0
- package/dist/parser/token-consumer.d.ts +1 -2
- package/dist/parser/tokenizer.d.ts +0 -33
- package/dist/registry/index.js +16 -79
- package/dist/registry/index.mjs +16 -79
- package/dist/runtime/runtime-base.d.ts +4 -0
- package/dist/types/base-types.d.ts +11 -0
- package/dist/types/core.d.ts +1 -0
- package/package.json +15 -6
- package/dist/chunks/browser-modular-Dv6PAV3c.js +0 -2
- package/dist/chunks/feature-eventsource-DWb514fy.js +0 -2
- package/dist/chunks/feature-sockets-3PFuvCVY.js +0 -2
- package/dist/chunks/feature-webworker-DTm_eh-E.js +0 -2
|
@@ -18,5 +18,6 @@ export declare function createArrayLiteral(elements: ASTNode[], pos: Position):
|
|
|
18
18
|
export declare function createPropertyOfExpression(property: ASTNode, target: ASTNode, pos: Position): PropertyOfExpressionNode;
|
|
19
19
|
export declare function createCommandSequence(commands: ASTNode[]): CommandSequenceNode;
|
|
20
20
|
export declare function createErrorNode(pos: Position): IdentifierNode;
|
|
21
|
+
export declare function createErrorCommandNode(pos: Position, message: string, source?: string): ASTNode;
|
|
21
22
|
export declare function createProgramNode(statements: ASTNode[]): ASTNode;
|
|
22
23
|
//# sourceMappingURL=ast-helpers.d.ts.map
|
|
@@ -78,6 +78,11 @@ const KEYWORDS = new Set([
|
|
|
78
78
|
'init',
|
|
79
79
|
'every',
|
|
80
80
|
'by',
|
|
81
|
+
'halt',
|
|
82
|
+
'via',
|
|
83
|
+
'values',
|
|
84
|
+
'default',
|
|
85
|
+
'event',
|
|
81
86
|
]);
|
|
82
87
|
function tokenize(code) {
|
|
83
88
|
const tokens = [];
|
|
@@ -403,6 +408,7 @@ class HybridParser {
|
|
|
403
408
|
go: () => this.parseGo(),
|
|
404
409
|
return: () => this.parseReturn(),
|
|
405
410
|
transition: () => this.parseTransition(),
|
|
411
|
+
halt: () => this.parseHalt(),
|
|
406
412
|
};
|
|
407
413
|
const normalized = normalizeCommand(this.peek().value);
|
|
408
414
|
if (cmdMap[normalized]) {
|
|
@@ -470,11 +476,17 @@ class HybridParser {
|
|
|
470
476
|
const url = this.parseExpression();
|
|
471
477
|
let responseType = { type: 'literal', value: 'text' };
|
|
472
478
|
let options;
|
|
479
|
+
let method;
|
|
473
480
|
if (this.match('{')) {
|
|
474
481
|
this.pos--;
|
|
475
482
|
options = this.parseExpression();
|
|
476
483
|
}
|
|
477
|
-
for (let i = 0; i <
|
|
484
|
+
for (let i = 0; i < 3; i++) {
|
|
485
|
+
if (this.match('via') && !method) {
|
|
486
|
+
this.advance();
|
|
487
|
+
method = this.parseExpression();
|
|
488
|
+
continue;
|
|
489
|
+
}
|
|
478
490
|
if (this.match('as')) {
|
|
479
491
|
this.advance();
|
|
480
492
|
if (this.match('a') || this.match('an'))
|
|
@@ -492,7 +504,11 @@ class HybridParser {
|
|
|
492
504
|
if (this.match('then'))
|
|
493
505
|
this.advance();
|
|
494
506
|
const body = this.parseCommandSequence();
|
|
495
|
-
return {
|
|
507
|
+
return {
|
|
508
|
+
type: 'fetch',
|
|
509
|
+
condition: { type: 'fetchConfig', url, responseType, options, method },
|
|
510
|
+
body,
|
|
511
|
+
};
|
|
496
512
|
}
|
|
497
513
|
parseToggle() {
|
|
498
514
|
this.expect('toggle');
|
|
@@ -683,6 +699,14 @@ class HybridParser {
|
|
|
683
699
|
}
|
|
684
700
|
return { type: 'command', name: 'return', args: value ? [value] : [] };
|
|
685
701
|
}
|
|
702
|
+
parseHalt() {
|
|
703
|
+
this.expect('halt');
|
|
704
|
+
if (this.match('the'))
|
|
705
|
+
this.advance();
|
|
706
|
+
if (this.match('event', 'default'))
|
|
707
|
+
this.advance();
|
|
708
|
+
return { type: 'command', name: 'halt', args: [] };
|
|
709
|
+
}
|
|
686
710
|
parseTransition() {
|
|
687
711
|
this.expect('transition');
|
|
688
712
|
let target;
|
|
@@ -959,6 +983,15 @@ class HybridParser {
|
|
|
959
983
|
const target = this.parsePositionalTarget();
|
|
960
984
|
return { type: 'positional', position, target };
|
|
961
985
|
}
|
|
986
|
+
if (this.match('values')) {
|
|
987
|
+
this.advance();
|
|
988
|
+
if (this.match('of')) {
|
|
989
|
+
this.advance();
|
|
990
|
+
const target = this.parseExpression();
|
|
991
|
+
return { type: 'valuesOf', target };
|
|
992
|
+
}
|
|
993
|
+
return { type: 'identifier', value: token.value };
|
|
994
|
+
}
|
|
962
995
|
if (token.type === 'identifier' || token.type === 'keyword') {
|
|
963
996
|
this.advance();
|
|
964
997
|
return { type: 'identifier', value: token.value };
|
|
@@ -76,6 +76,11 @@ const KEYWORDS = new Set([
|
|
|
76
76
|
'init',
|
|
77
77
|
'every',
|
|
78
78
|
'by',
|
|
79
|
+
'halt',
|
|
80
|
+
'via',
|
|
81
|
+
'values',
|
|
82
|
+
'default',
|
|
83
|
+
'event',
|
|
79
84
|
]);
|
|
80
85
|
function tokenize(code) {
|
|
81
86
|
const tokens = [];
|
|
@@ -401,6 +406,7 @@ class HybridParser {
|
|
|
401
406
|
go: () => this.parseGo(),
|
|
402
407
|
return: () => this.parseReturn(),
|
|
403
408
|
transition: () => this.parseTransition(),
|
|
409
|
+
halt: () => this.parseHalt(),
|
|
404
410
|
};
|
|
405
411
|
const normalized = normalizeCommand(this.peek().value);
|
|
406
412
|
if (cmdMap[normalized]) {
|
|
@@ -468,11 +474,17 @@ class HybridParser {
|
|
|
468
474
|
const url = this.parseExpression();
|
|
469
475
|
let responseType = { type: 'literal', value: 'text' };
|
|
470
476
|
let options;
|
|
477
|
+
let method;
|
|
471
478
|
if (this.match('{')) {
|
|
472
479
|
this.pos--;
|
|
473
480
|
options = this.parseExpression();
|
|
474
481
|
}
|
|
475
|
-
for (let i = 0; i <
|
|
482
|
+
for (let i = 0; i < 3; i++) {
|
|
483
|
+
if (this.match('via') && !method) {
|
|
484
|
+
this.advance();
|
|
485
|
+
method = this.parseExpression();
|
|
486
|
+
continue;
|
|
487
|
+
}
|
|
476
488
|
if (this.match('as')) {
|
|
477
489
|
this.advance();
|
|
478
490
|
if (this.match('a') || this.match('an'))
|
|
@@ -490,7 +502,11 @@ class HybridParser {
|
|
|
490
502
|
if (this.match('then'))
|
|
491
503
|
this.advance();
|
|
492
504
|
const body = this.parseCommandSequence();
|
|
493
|
-
return {
|
|
505
|
+
return {
|
|
506
|
+
type: 'fetch',
|
|
507
|
+
condition: { type: 'fetchConfig', url, responseType, options, method },
|
|
508
|
+
body,
|
|
509
|
+
};
|
|
494
510
|
}
|
|
495
511
|
parseToggle() {
|
|
496
512
|
this.expect('toggle');
|
|
@@ -681,6 +697,14 @@ class HybridParser {
|
|
|
681
697
|
}
|
|
682
698
|
return { type: 'command', name: 'return', args: value ? [value] : [] };
|
|
683
699
|
}
|
|
700
|
+
parseHalt() {
|
|
701
|
+
this.expect('halt');
|
|
702
|
+
if (this.match('the'))
|
|
703
|
+
this.advance();
|
|
704
|
+
if (this.match('event', 'default'))
|
|
705
|
+
this.advance();
|
|
706
|
+
return { type: 'command', name: 'halt', args: [] };
|
|
707
|
+
}
|
|
684
708
|
parseTransition() {
|
|
685
709
|
this.expect('transition');
|
|
686
710
|
let target;
|
|
@@ -957,6 +981,15 @@ class HybridParser {
|
|
|
957
981
|
const target = this.parsePositionalTarget();
|
|
958
982
|
return { type: 'positional', position, target };
|
|
959
983
|
}
|
|
984
|
+
if (this.match('values')) {
|
|
985
|
+
this.advance();
|
|
986
|
+
if (this.match('of')) {
|
|
987
|
+
this.advance();
|
|
988
|
+
const target = this.parseExpression();
|
|
989
|
+
return { type: 'valuesOf', target };
|
|
990
|
+
}
|
|
991
|
+
return { type: 'identifier', value: token.value };
|
|
992
|
+
}
|
|
960
993
|
if (token.type === 'identifier' || token.type === 'keyword') {
|
|
961
994
|
this.advance();
|
|
962
995
|
return { type: 'identifier', value: token.value };
|
|
@@ -78,6 +78,11 @@ const KEYWORDS = new Set([
|
|
|
78
78
|
'init',
|
|
79
79
|
'every',
|
|
80
80
|
'by',
|
|
81
|
+
'halt',
|
|
82
|
+
'via',
|
|
83
|
+
'values',
|
|
84
|
+
'default',
|
|
85
|
+
'event',
|
|
81
86
|
]);
|
|
82
87
|
function tokenize(code) {
|
|
83
88
|
const tokens = [];
|
|
@@ -397,6 +402,7 @@ class HybridParser {
|
|
|
397
402
|
go: () => this.parseGo(),
|
|
398
403
|
return: () => this.parseReturn(),
|
|
399
404
|
transition: () => this.parseTransition(),
|
|
405
|
+
halt: () => this.parseHalt(),
|
|
400
406
|
};
|
|
401
407
|
const normalized = normalizeCommand(this.peek().value);
|
|
402
408
|
if (cmdMap[normalized]) {
|
|
@@ -464,11 +470,17 @@ class HybridParser {
|
|
|
464
470
|
const url = this.parseExpression();
|
|
465
471
|
let responseType = { type: 'literal', value: 'text' };
|
|
466
472
|
let options;
|
|
473
|
+
let method;
|
|
467
474
|
if (this.match('{')) {
|
|
468
475
|
this.pos--;
|
|
469
476
|
options = this.parseExpression();
|
|
470
477
|
}
|
|
471
|
-
for (let i = 0; i <
|
|
478
|
+
for (let i = 0; i < 3; i++) {
|
|
479
|
+
if (this.match('via') && !method) {
|
|
480
|
+
this.advance();
|
|
481
|
+
method = this.parseExpression();
|
|
482
|
+
continue;
|
|
483
|
+
}
|
|
472
484
|
if (this.match('as')) {
|
|
473
485
|
this.advance();
|
|
474
486
|
if (this.match('a') || this.match('an'))
|
|
@@ -486,7 +498,11 @@ class HybridParser {
|
|
|
486
498
|
if (this.match('then'))
|
|
487
499
|
this.advance();
|
|
488
500
|
const body = this.parseCommandSequence();
|
|
489
|
-
return {
|
|
501
|
+
return {
|
|
502
|
+
type: 'fetch',
|
|
503
|
+
condition: { type: 'fetchConfig', url, responseType, options, method },
|
|
504
|
+
body,
|
|
505
|
+
};
|
|
490
506
|
}
|
|
491
507
|
parseToggle() {
|
|
492
508
|
this.expect('toggle');
|
|
@@ -677,6 +693,14 @@ class HybridParser {
|
|
|
677
693
|
}
|
|
678
694
|
return { type: 'command', name: 'return', args: value ? [value] : [] };
|
|
679
695
|
}
|
|
696
|
+
parseHalt() {
|
|
697
|
+
this.expect('halt');
|
|
698
|
+
if (this.match('the'))
|
|
699
|
+
this.advance();
|
|
700
|
+
if (this.match('event', 'default'))
|
|
701
|
+
this.advance();
|
|
702
|
+
return { type: 'command', name: 'halt', args: [] };
|
|
703
|
+
}
|
|
680
704
|
parseTransition() {
|
|
681
705
|
this.expect('transition');
|
|
682
706
|
let target;
|
|
@@ -953,6 +977,15 @@ class HybridParser {
|
|
|
953
977
|
const target = this.parsePositionalTarget();
|
|
954
978
|
return { type: 'positional', position, target };
|
|
955
979
|
}
|
|
980
|
+
if (this.match('values')) {
|
|
981
|
+
this.advance();
|
|
982
|
+
if (this.match('of')) {
|
|
983
|
+
this.advance();
|
|
984
|
+
const target = this.parseExpression();
|
|
985
|
+
return { type: 'valuesOf', target };
|
|
986
|
+
}
|
|
987
|
+
return { type: 'identifier', value: token.value };
|
|
988
|
+
}
|
|
956
989
|
if (token.type === 'identifier' || token.type === 'keyword') {
|
|
957
990
|
this.advance();
|
|
958
991
|
return { type: 'identifier', value: token.value };
|
|
@@ -76,6 +76,11 @@ const KEYWORDS = new Set([
|
|
|
76
76
|
'init',
|
|
77
77
|
'every',
|
|
78
78
|
'by',
|
|
79
|
+
'halt',
|
|
80
|
+
'via',
|
|
81
|
+
'values',
|
|
82
|
+
'default',
|
|
83
|
+
'event',
|
|
79
84
|
]);
|
|
80
85
|
function tokenize(code) {
|
|
81
86
|
const tokens = [];
|
|
@@ -395,6 +400,7 @@ class HybridParser {
|
|
|
395
400
|
go: () => this.parseGo(),
|
|
396
401
|
return: () => this.parseReturn(),
|
|
397
402
|
transition: () => this.parseTransition(),
|
|
403
|
+
halt: () => this.parseHalt(),
|
|
398
404
|
};
|
|
399
405
|
const normalized = normalizeCommand(this.peek().value);
|
|
400
406
|
if (cmdMap[normalized]) {
|
|
@@ -462,11 +468,17 @@ class HybridParser {
|
|
|
462
468
|
const url = this.parseExpression();
|
|
463
469
|
let responseType = { type: 'literal', value: 'text' };
|
|
464
470
|
let options;
|
|
471
|
+
let method;
|
|
465
472
|
if (this.match('{')) {
|
|
466
473
|
this.pos--;
|
|
467
474
|
options = this.parseExpression();
|
|
468
475
|
}
|
|
469
|
-
for (let i = 0; i <
|
|
476
|
+
for (let i = 0; i < 3; i++) {
|
|
477
|
+
if (this.match('via') && !method) {
|
|
478
|
+
this.advance();
|
|
479
|
+
method = this.parseExpression();
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
470
482
|
if (this.match('as')) {
|
|
471
483
|
this.advance();
|
|
472
484
|
if (this.match('a') || this.match('an'))
|
|
@@ -484,7 +496,11 @@ class HybridParser {
|
|
|
484
496
|
if (this.match('then'))
|
|
485
497
|
this.advance();
|
|
486
498
|
const body = this.parseCommandSequence();
|
|
487
|
-
return {
|
|
499
|
+
return {
|
|
500
|
+
type: 'fetch',
|
|
501
|
+
condition: { type: 'fetchConfig', url, responseType, options, method },
|
|
502
|
+
body,
|
|
503
|
+
};
|
|
488
504
|
}
|
|
489
505
|
parseToggle() {
|
|
490
506
|
this.expect('toggle');
|
|
@@ -675,6 +691,14 @@ class HybridParser {
|
|
|
675
691
|
}
|
|
676
692
|
return { type: 'command', name: 'return', args: value ? [value] : [] };
|
|
677
693
|
}
|
|
694
|
+
parseHalt() {
|
|
695
|
+
this.expect('halt');
|
|
696
|
+
if (this.match('the'))
|
|
697
|
+
this.advance();
|
|
698
|
+
if (this.match('event', 'default'))
|
|
699
|
+
this.advance();
|
|
700
|
+
return { type: 'command', name: 'halt', args: [] };
|
|
701
|
+
}
|
|
678
702
|
parseTransition() {
|
|
679
703
|
this.expect('transition');
|
|
680
704
|
let target;
|
|
@@ -951,6 +975,15 @@ class HybridParser {
|
|
|
951
975
|
const target = this.parsePositionalTarget();
|
|
952
976
|
return { type: 'positional', position, target };
|
|
953
977
|
}
|
|
978
|
+
if (this.match('values')) {
|
|
979
|
+
this.advance();
|
|
980
|
+
if (this.match('of')) {
|
|
981
|
+
this.advance();
|
|
982
|
+
const target = this.parseExpression();
|
|
983
|
+
return { type: 'valuesOf', target };
|
|
984
|
+
}
|
|
985
|
+
return { type: 'identifier', value: token.value };
|
|
986
|
+
}
|
|
954
987
|
if (token.type === 'identifier' || token.type === 'keyword') {
|
|
955
988
|
this.advance();
|
|
956
989
|
return { type: 'identifier', value: token.value };
|
|
@@ -78,6 +78,11 @@ const KEYWORDS = new Set([
|
|
|
78
78
|
'init',
|
|
79
79
|
'every',
|
|
80
80
|
'by',
|
|
81
|
+
'halt',
|
|
82
|
+
'via',
|
|
83
|
+
'values',
|
|
84
|
+
'default',
|
|
85
|
+
'event',
|
|
81
86
|
]);
|
|
82
87
|
function tokenize(code) {
|
|
83
88
|
const tokens = [];
|
|
@@ -403,6 +408,7 @@ class HybridParser {
|
|
|
403
408
|
go: () => this.parseGo(),
|
|
404
409
|
return: () => this.parseReturn(),
|
|
405
410
|
transition: () => this.parseTransition(),
|
|
411
|
+
halt: () => this.parseHalt(),
|
|
406
412
|
};
|
|
407
413
|
const normalized = normalizeCommand(this.peek().value);
|
|
408
414
|
if (cmdMap[normalized]) {
|
|
@@ -470,11 +476,17 @@ class HybridParser {
|
|
|
470
476
|
const url = this.parseExpression();
|
|
471
477
|
let responseType = { type: 'literal', value: 'text' };
|
|
472
478
|
let options;
|
|
479
|
+
let method;
|
|
473
480
|
if (this.match('{')) {
|
|
474
481
|
this.pos--;
|
|
475
482
|
options = this.parseExpression();
|
|
476
483
|
}
|
|
477
|
-
for (let i = 0; i <
|
|
484
|
+
for (let i = 0; i < 3; i++) {
|
|
485
|
+
if (this.match('via') && !method) {
|
|
486
|
+
this.advance();
|
|
487
|
+
method = this.parseExpression();
|
|
488
|
+
continue;
|
|
489
|
+
}
|
|
478
490
|
if (this.match('as')) {
|
|
479
491
|
this.advance();
|
|
480
492
|
if (this.match('a') || this.match('an'))
|
|
@@ -492,7 +504,11 @@ class HybridParser {
|
|
|
492
504
|
if (this.match('then'))
|
|
493
505
|
this.advance();
|
|
494
506
|
const body = this.parseCommandSequence();
|
|
495
|
-
return {
|
|
507
|
+
return {
|
|
508
|
+
type: 'fetch',
|
|
509
|
+
condition: { type: 'fetchConfig', url, responseType, options, method },
|
|
510
|
+
body,
|
|
511
|
+
};
|
|
496
512
|
}
|
|
497
513
|
parseToggle() {
|
|
498
514
|
this.expect('toggle');
|
|
@@ -683,6 +699,14 @@ class HybridParser {
|
|
|
683
699
|
}
|
|
684
700
|
return { type: 'command', name: 'return', args: value ? [value] : [] };
|
|
685
701
|
}
|
|
702
|
+
parseHalt() {
|
|
703
|
+
this.expect('halt');
|
|
704
|
+
if (this.match('the'))
|
|
705
|
+
this.advance();
|
|
706
|
+
if (this.match('event', 'default'))
|
|
707
|
+
this.advance();
|
|
708
|
+
return { type: 'command', name: 'halt', args: [] };
|
|
709
|
+
}
|
|
686
710
|
parseTransition() {
|
|
687
711
|
this.expect('transition');
|
|
688
712
|
let target;
|
|
@@ -959,6 +983,15 @@ class HybridParser {
|
|
|
959
983
|
const target = this.parsePositionalTarget();
|
|
960
984
|
return { type: 'positional', position, target };
|
|
961
985
|
}
|
|
986
|
+
if (this.match('values')) {
|
|
987
|
+
this.advance();
|
|
988
|
+
if (this.match('of')) {
|
|
989
|
+
this.advance();
|
|
990
|
+
const target = this.parseExpression();
|
|
991
|
+
return { type: 'valuesOf', target };
|
|
992
|
+
}
|
|
993
|
+
return { type: 'identifier', value: token.value };
|
|
994
|
+
}
|
|
962
995
|
if (token.type === 'identifier' || token.type === 'keyword') {
|
|
963
996
|
this.advance();
|
|
964
997
|
return { type: 'identifier', value: token.value };
|
|
@@ -76,6 +76,11 @@ const KEYWORDS = new Set([
|
|
|
76
76
|
'init',
|
|
77
77
|
'every',
|
|
78
78
|
'by',
|
|
79
|
+
'halt',
|
|
80
|
+
'via',
|
|
81
|
+
'values',
|
|
82
|
+
'default',
|
|
83
|
+
'event',
|
|
79
84
|
]);
|
|
80
85
|
function tokenize(code) {
|
|
81
86
|
const tokens = [];
|
|
@@ -401,6 +406,7 @@ class HybridParser {
|
|
|
401
406
|
go: () => this.parseGo(),
|
|
402
407
|
return: () => this.parseReturn(),
|
|
403
408
|
transition: () => this.parseTransition(),
|
|
409
|
+
halt: () => this.parseHalt(),
|
|
404
410
|
};
|
|
405
411
|
const normalized = normalizeCommand(this.peek().value);
|
|
406
412
|
if (cmdMap[normalized]) {
|
|
@@ -468,11 +474,17 @@ class HybridParser {
|
|
|
468
474
|
const url = this.parseExpression();
|
|
469
475
|
let responseType = { type: 'literal', value: 'text' };
|
|
470
476
|
let options;
|
|
477
|
+
let method;
|
|
471
478
|
if (this.match('{')) {
|
|
472
479
|
this.pos--;
|
|
473
480
|
options = this.parseExpression();
|
|
474
481
|
}
|
|
475
|
-
for (let i = 0; i <
|
|
482
|
+
for (let i = 0; i < 3; i++) {
|
|
483
|
+
if (this.match('via') && !method) {
|
|
484
|
+
this.advance();
|
|
485
|
+
method = this.parseExpression();
|
|
486
|
+
continue;
|
|
487
|
+
}
|
|
476
488
|
if (this.match('as')) {
|
|
477
489
|
this.advance();
|
|
478
490
|
if (this.match('a') || this.match('an'))
|
|
@@ -490,7 +502,11 @@ class HybridParser {
|
|
|
490
502
|
if (this.match('then'))
|
|
491
503
|
this.advance();
|
|
492
504
|
const body = this.parseCommandSequence();
|
|
493
|
-
return {
|
|
505
|
+
return {
|
|
506
|
+
type: 'fetch',
|
|
507
|
+
condition: { type: 'fetchConfig', url, responseType, options, method },
|
|
508
|
+
body,
|
|
509
|
+
};
|
|
494
510
|
}
|
|
495
511
|
parseToggle() {
|
|
496
512
|
this.expect('toggle');
|
|
@@ -681,6 +697,14 @@ class HybridParser {
|
|
|
681
697
|
}
|
|
682
698
|
return { type: 'command', name: 'return', args: value ? [value] : [] };
|
|
683
699
|
}
|
|
700
|
+
parseHalt() {
|
|
701
|
+
this.expect('halt');
|
|
702
|
+
if (this.match('the'))
|
|
703
|
+
this.advance();
|
|
704
|
+
if (this.match('event', 'default'))
|
|
705
|
+
this.advance();
|
|
706
|
+
return { type: 'command', name: 'halt', args: [] };
|
|
707
|
+
}
|
|
684
708
|
parseTransition() {
|
|
685
709
|
this.expect('transition');
|
|
686
710
|
let target;
|
|
@@ -957,6 +981,15 @@ class HybridParser {
|
|
|
957
981
|
const target = this.parsePositionalTarget();
|
|
958
982
|
return { type: 'positional', position, target };
|
|
959
983
|
}
|
|
984
|
+
if (this.match('values')) {
|
|
985
|
+
this.advance();
|
|
986
|
+
if (this.match('of')) {
|
|
987
|
+
this.advance();
|
|
988
|
+
const target = this.parseExpression();
|
|
989
|
+
return { type: 'valuesOf', target };
|
|
990
|
+
}
|
|
991
|
+
return { type: 'identifier', value: token.value };
|
|
992
|
+
}
|
|
960
993
|
if (token.type === 'identifier' || token.type === 'keyword') {
|
|
961
994
|
this.advance();
|
|
962
995
|
return { type: 'identifier', value: token.value };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { Token, ASTNode, CommandNode } from '../types/core';
|
|
2
|
-
import { TokenType } from './tokenizer';
|
|
3
2
|
export interface Position {
|
|
4
3
|
start: number;
|
|
5
4
|
end: number;
|
|
@@ -86,14 +85,20 @@ export interface MultiWordPattern {
|
|
|
86
85
|
minArgs?: number;
|
|
87
86
|
maxArgs?: number;
|
|
88
87
|
}
|
|
89
|
-
export interface
|
|
88
|
+
export interface TokenStream {
|
|
90
89
|
readonly tokens: Token[];
|
|
91
90
|
current: number;
|
|
92
91
|
advance(): Token;
|
|
93
92
|
peek(): Token;
|
|
94
93
|
previous(): Token;
|
|
95
|
-
consume(expected: string
|
|
94
|
+
consume(expected: string, message: string): Token;
|
|
96
95
|
check(value: string): boolean;
|
|
96
|
+
match(...types: string[]): boolean;
|
|
97
|
+
matchOperator(operator: string): boolean;
|
|
98
|
+
isAtEnd(): boolean;
|
|
99
|
+
peekAt(offset: number): Token | null;
|
|
100
|
+
}
|
|
101
|
+
export interface TokenPredicates {
|
|
97
102
|
checkIdentifierLike(): boolean;
|
|
98
103
|
checkSelector(): boolean;
|
|
99
104
|
checkAnySelector(): boolean;
|
|
@@ -103,9 +108,8 @@ export interface ParserContext {
|
|
|
103
108
|
checkEvent(): boolean;
|
|
104
109
|
checkIsCommand(): boolean;
|
|
105
110
|
checkContextVar(): boolean;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
isAtEnd(): boolean;
|
|
111
|
+
}
|
|
112
|
+
export interface ASTFactory {
|
|
109
113
|
createIdentifier(name: string): IdentifierNode;
|
|
110
114
|
createLiteral(value: unknown, raw: string): ASTNode;
|
|
111
115
|
createSelector(value: string): ASTNode;
|
|
@@ -117,6 +121,8 @@ export interface ParserContext {
|
|
|
117
121
|
createErrorNode(): ASTNode;
|
|
118
122
|
createProgramNode(statements: ASTNode[]): ASTNode;
|
|
119
123
|
createCommandFromIdentifier(identifierNode: IdentifierNode): CommandNode;
|
|
124
|
+
}
|
|
125
|
+
export interface ExpressionParser {
|
|
120
126
|
parseExpression(): ASTNode;
|
|
121
127
|
parsePrimary(): ASTNode;
|
|
122
128
|
parseCall(): ASTNode;
|
|
@@ -139,15 +145,22 @@ export interface ParserContext {
|
|
|
139
145
|
parseAttributeOrArrayLiteral(): ASTNode;
|
|
140
146
|
parseObjectLiteral(): ASTNode;
|
|
141
147
|
parseCSSObjectLiteral(): ASTNode;
|
|
148
|
+
}
|
|
149
|
+
export interface CommandParser {
|
|
142
150
|
parseCommand(): CommandNode;
|
|
143
151
|
parseCommandSequence(): ASTNode;
|
|
144
152
|
parseCommandListUntilEnd(): ASTNode[];
|
|
153
|
+
}
|
|
154
|
+
export interface PositionCheckpoint {
|
|
145
155
|
savePosition(): number;
|
|
146
156
|
restorePosition(pos: number): void;
|
|
147
|
-
peekAt(offset: number): Token | null;
|
|
148
157
|
getPosition(): Position;
|
|
158
|
+
}
|
|
159
|
+
export interface ParserErrorHandler {
|
|
149
160
|
addError(message: string): void;
|
|
150
161
|
addWarning(warning: string): void;
|
|
162
|
+
}
|
|
163
|
+
export interface ParserUtilities {
|
|
151
164
|
isCommand(name: string): boolean;
|
|
152
165
|
isCompoundCommand(name: string): boolean;
|
|
153
166
|
isKeyword(name: string): boolean;
|
|
@@ -155,6 +168,8 @@ export interface ParserContext {
|
|
|
155
168
|
resolveKeyword(value: string): string;
|
|
156
169
|
getInputSlice(start: number, end?: number): string;
|
|
157
170
|
}
|
|
171
|
+
export interface ParserContext extends TokenStream, TokenPredicates, ASTFactory, ExpressionParser, CommandParser, PositionCheckpoint, ParserErrorHandler, ParserUtilities {
|
|
172
|
+
}
|
|
158
173
|
export type CommandParserFunction = (token: Token, context: ParserContext) => CommandNode;
|
|
159
174
|
export type CompoundCommandParserFunction = (identifierNode: IdentifierNode, context: ParserContext) => CommandNode | null;
|
|
160
175
|
export type TokenNavigationFunction = (context: ParserContext) => Token | boolean;
|
package/dist/parser/parser.d.ts
CHANGED
|
@@ -6,17 +6,23 @@ export declare class Parser {
|
|
|
6
6
|
private tokens;
|
|
7
7
|
private current;
|
|
8
8
|
private error;
|
|
9
|
+
private errors;
|
|
9
10
|
private warnings;
|
|
10
11
|
private keywordResolver?;
|
|
11
12
|
private semanticAdapter?;
|
|
12
13
|
private originalInput?;
|
|
13
14
|
private registryIntegration?;
|
|
15
|
+
private prattCache;
|
|
14
16
|
private static readonly POSTFIX_UNARY_OPERATORS;
|
|
15
17
|
constructor(tokens: Token[], options?: ParserOptions, originalInput?: string);
|
|
16
18
|
private resolveKeyword;
|
|
17
19
|
private addWarning;
|
|
18
20
|
parse(): ParseResult;
|
|
21
|
+
private parseInternal;
|
|
19
22
|
private parseExpression;
|
|
23
|
+
private static readonly PRATT_TABLE;
|
|
24
|
+
private parseExpressionPratt;
|
|
25
|
+
private makePrattContext;
|
|
20
26
|
private parseAssignment;
|
|
21
27
|
private parseLogicalOr;
|
|
22
28
|
private parseLogicalAnd;
|
|
@@ -138,6 +144,7 @@ export declare class Parser {
|
|
|
138
144
|
private previous;
|
|
139
145
|
private consume;
|
|
140
146
|
private addError;
|
|
147
|
+
private synchronizeToCommandBoundary;
|
|
141
148
|
private parseAttributeOrArrayLiteral;
|
|
142
149
|
private getPosition;
|
|
143
150
|
getContext(): import('./parser-types').ParserContext;
|