@hyperfixi/core 2.9.1 → 2.9.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/dist/bundle-generator/index.js +6 -0
- package/dist/bundle-generator/index.mjs +6 -0
- package/dist/bundle-generator/parser-templates.d.ts +1 -1
- package/dist/chunks/{bridge-BYhqTOnL.js → bridge-DwtNLKK3.js} +2 -2
- package/dist/chunks/browser-modular-6HT1r2AH.js +2 -0
- package/dist/chunks/{index-DXgJaDj-.js → index-B8jwvuj_.js} +2 -2
- package/dist/commands/index.js +133 -74
- package/dist/commands/index.mjs +133 -74
- package/dist/hyperfixi-browser-classic-i18n.js +1 -1
- package/dist/hyperfixi-browser-minimal.js +1 -1
- package/dist/hyperfixi-browser-standard.js +1 -1
- package/dist/hyperfixi-browser.js +1 -1
- package/dist/hyperfixi-classic-i18n.js +1 -1
- package/dist/hyperfixi-hx-v4.js +1 -1
- package/dist/hyperfixi-hx.js +1 -1
- package/dist/hyperfixi-hybrid-complete.js +1 -1
- package/dist/hyperfixi-hybrid-hx.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/index.js +233 -79
- package/dist/index.min.js +1 -1
- package/dist/index.mjs +233 -79
- 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/parser/command-parsers/utility-commands.d.ts +1 -1
- package/dist/parser/full-parser.js +133 -74
- package/dist/parser/full-parser.mjs +133 -74
- package/dist/parser/hybrid/index.js +3 -0
- package/dist/parser/hybrid/index.mjs +3 -0
- package/dist/parser/hybrid/parser-core.js +3 -0
- package/dist/parser/hybrid/parser-core.mjs +3 -0
- package/dist/parser/hybrid-parser.js +3 -0
- package/dist/parser/hybrid-parser.mjs +3 -0
- package/dist/reference/index.js +1 -0
- package/dist/reference/index.mjs +1 -0
- package/dist/registry/index.js +133 -74
- package/dist/registry/index.mjs +133 -74
- package/dist/runtime/runtime-base.d.ts +2 -1
- package/dist/types/core.d.ts +1 -0
- package/package.json +6 -6
- package/dist/chunks/browser-modular-D2BHzZFB.js +0 -2
|
@@ -4,7 +4,7 @@ export declare function parseCompoundCommand(ctx: ParserContext, identifierNode:
|
|
|
4
4
|
export declare function parseRegularCommand(ctx: ParserContext, identifierNode: IdentifierNode): CommandNode;
|
|
5
5
|
export declare function parseMultiWordCommand(ctx: ParserContext, commandToken: Token, commandName: string): CommandNode | null;
|
|
6
6
|
export declare function isNakedURLStart(ctx: ParserContext): boolean;
|
|
7
|
-
export declare function parseBareURLPath(ctx: ParserContext
|
|
7
|
+
export declare function parseBareURLPath(ctx: ParserContext): ASTNode | null;
|
|
8
8
|
export declare function parseFetchCommand(ctx: ParserContext, commandToken: Token): CommandNode;
|
|
9
9
|
export declare function parseJsCommand(ctx: ParserContext, identifierNode: IdentifierNode): CommandNode;
|
|
10
10
|
export declare function parseTellCommand(ctx: ParserContext, identifierNode: IdentifierNode): CommandNode;
|
|
@@ -516,13 +516,13 @@ function tokenize(input) {
|
|
|
516
516
|
continue;
|
|
517
517
|
}
|
|
518
518
|
if (char === '{') {
|
|
519
|
-
addToken(tokenizer, TokenKind.OPERATOR, '{');
|
|
520
519
|
advance(tokenizer);
|
|
520
|
+
addToken(tokenizer, TokenKind.OPERATOR, '{');
|
|
521
521
|
continue;
|
|
522
522
|
}
|
|
523
523
|
if (char === '}') {
|
|
524
|
-
addToken(tokenizer, TokenKind.OPERATOR, '}');
|
|
525
524
|
advance(tokenizer);
|
|
525
|
+
addToken(tokenizer, TokenKind.OPERATOR, '}');
|
|
526
526
|
continue;
|
|
527
527
|
}
|
|
528
528
|
if (char === '[') {
|
|
@@ -538,24 +538,24 @@ function tokenize(input) {
|
|
|
538
538
|
prevToken.value === ']') &&
|
|
539
539
|
!isEventCondition;
|
|
540
540
|
if (isMemberAccess) {
|
|
541
|
-
addToken(tokenizer, TokenKind.OPERATOR, '[');
|
|
542
541
|
advance(tokenizer);
|
|
542
|
+
addToken(tokenizer, TokenKind.OPERATOR, '[');
|
|
543
543
|
}
|
|
544
544
|
else {
|
|
545
545
|
if (isEventCondition) {
|
|
546
|
-
addToken(tokenizer, TokenKind.SYMBOL, '[');
|
|
547
546
|
advance(tokenizer);
|
|
547
|
+
addToken(tokenizer, TokenKind.SYMBOL, '[');
|
|
548
548
|
}
|
|
549
549
|
else {
|
|
550
|
-
addToken(tokenizer, TokenKind.OPERATOR, '[');
|
|
551
550
|
advance(tokenizer);
|
|
551
|
+
addToken(tokenizer, TokenKind.OPERATOR, '[');
|
|
552
552
|
}
|
|
553
553
|
}
|
|
554
554
|
continue;
|
|
555
555
|
}
|
|
556
556
|
if (char === ']') {
|
|
557
|
-
addToken(tokenizer, TokenKind.OPERATOR, ']');
|
|
558
557
|
advance(tokenizer);
|
|
558
|
+
addToken(tokenizer, TokenKind.OPERATOR, ']');
|
|
559
559
|
continue;
|
|
560
560
|
}
|
|
561
561
|
if (char === '$') {
|
|
@@ -2762,7 +2762,6 @@ const MULTI_WORD_PATTERNS = [
|
|
|
2762
2762
|
keywords: ['a', 'an', 'from', 'called'],
|
|
2763
2763
|
syntax: 'make (a|an) <type> [from <args>] [called <name>]',
|
|
2764
2764
|
},
|
|
2765
|
-
{ command: 'send', keywords: ['to'], syntax: 'send <event> to <target>' },
|
|
2766
2765
|
{ command: 'throw', keywords: [], syntax: 'throw <error>' },
|
|
2767
2766
|
];
|
|
2768
2767
|
function getMultiWordPattern(commandName) {
|
|
@@ -3063,7 +3062,13 @@ function parseTriggerCommand(ctx, identifierNode) {
|
|
|
3063
3062
|
finalArgs.push(ctx.createIdentifier(keyword));
|
|
3064
3063
|
continue;
|
|
3065
3064
|
}
|
|
3066
|
-
|
|
3065
|
+
const before = ctx.savePosition();
|
|
3066
|
+
const expr = ctx.parsePrimary();
|
|
3067
|
+
if (expr)
|
|
3068
|
+
finalArgs.push(expr);
|
|
3069
|
+
if (ctx.savePosition() === before) {
|
|
3070
|
+
ctx.advance();
|
|
3071
|
+
}
|
|
3067
3072
|
}
|
|
3068
3073
|
return CommandNodeBuilder.fromIdentifier(identifierNode)
|
|
3069
3074
|
.withArgs(...finalArgs)
|
|
@@ -3282,11 +3287,64 @@ function parseRepeatCommand(ctx, commandToken) {
|
|
|
3282
3287
|
}
|
|
3283
3288
|
return builder.endingAt(ctx.getPosition()).build();
|
|
3284
3289
|
}
|
|
3290
|
+
function parseIfBranchCommands(ctx, stopAtElse) {
|
|
3291
|
+
const commands = [];
|
|
3292
|
+
const atTerminator = () => ctx.check(KEYWORDS.END) || (stopAtElse && ctx.check(KEYWORDS.ELSE));
|
|
3293
|
+
while (!ctx.isAtEnd() && !atTerminator()) {
|
|
3294
|
+
if (isComment(ctx.peek())) {
|
|
3295
|
+
ctx.advance();
|
|
3296
|
+
continue;
|
|
3297
|
+
}
|
|
3298
|
+
if (!ctx.checkIsCommand() && !ctx.isCommand(ctx.peek().value))
|
|
3299
|
+
break;
|
|
3300
|
+
ctx.advance();
|
|
3301
|
+
const cmd = ctx.parseCommand();
|
|
3302
|
+
if (cmd) {
|
|
3303
|
+
commands.push(cmd);
|
|
3304
|
+
}
|
|
3305
|
+
if (ctx.check(KEYWORDS.THEN) || ctx.check(KEYWORDS.AND) || ctx.check(',')) {
|
|
3306
|
+
ctx.advance();
|
|
3307
|
+
}
|
|
3308
|
+
}
|
|
3309
|
+
return commands;
|
|
3310
|
+
}
|
|
3311
|
+
const OPERAND_INTRODUCERS = new Set([
|
|
3312
|
+
'is',
|
|
3313
|
+
'am',
|
|
3314
|
+
'are',
|
|
3315
|
+
'not',
|
|
3316
|
+
'no',
|
|
3317
|
+
'and',
|
|
3318
|
+
'or',
|
|
3319
|
+
'==',
|
|
3320
|
+
'===',
|
|
3321
|
+
'!=',
|
|
3322
|
+
'!==',
|
|
3323
|
+
'<',
|
|
3324
|
+
'>',
|
|
3325
|
+
'<=',
|
|
3326
|
+
'>=',
|
|
3327
|
+
'+',
|
|
3328
|
+
'-',
|
|
3329
|
+
'*',
|
|
3330
|
+
'/',
|
|
3331
|
+
'mod',
|
|
3332
|
+
]);
|
|
3333
|
+
function isBodyCommandStart(ctx, prevToken, token) {
|
|
3334
|
+
if (prevToken === null) {
|
|
3335
|
+
return false;
|
|
3336
|
+
}
|
|
3337
|
+
if (OPERAND_INTRODUCERS.has(prevToken.value?.toLowerCase?.() ?? '')) {
|
|
3338
|
+
return false;
|
|
3339
|
+
}
|
|
3340
|
+
return ctx.checkIsCommand() || ctx.isCommand(token.value?.toLowerCase());
|
|
3341
|
+
}
|
|
3285
3342
|
function parseIfCommand(ctx, commandToken) {
|
|
3286
3343
|
const args = [];
|
|
3287
3344
|
let hasThen = false;
|
|
3288
3345
|
const savedPosForThen = ctx.savePosition();
|
|
3289
3346
|
const maxThenLookahead = 500;
|
|
3347
|
+
let prevForThen = null;
|
|
3290
3348
|
for (let i = 0; i < maxThenLookahead && !ctx.isAtEnd(); i++) {
|
|
3291
3349
|
const token = ctx.peek();
|
|
3292
3350
|
if (token.value === KEYWORDS.THEN) {
|
|
@@ -3299,6 +3357,14 @@ function parseIfCommand(ctx, commandToken) {
|
|
|
3299
3357
|
token.value === KEYWORDS.ON) {
|
|
3300
3358
|
break;
|
|
3301
3359
|
}
|
|
3360
|
+
if (token.line !== undefined &&
|
|
3361
|
+
token.line !== commandToken.line &&
|
|
3362
|
+
isBodyCommandStart(ctx, prevForThen, token)) {
|
|
3363
|
+
break;
|
|
3364
|
+
}
|
|
3365
|
+
if (!isComment(token)) {
|
|
3366
|
+
prevForThen = token;
|
|
3367
|
+
}
|
|
3302
3368
|
ctx.advance();
|
|
3303
3369
|
}
|
|
3304
3370
|
ctx.restorePosition(savedPosForThen);
|
|
@@ -3307,9 +3373,14 @@ function parseIfCommand(ctx, commandToken) {
|
|
|
3307
3373
|
const savedPosition = ctx.savePosition();
|
|
3308
3374
|
const ifStatementLine = commandToken.line;
|
|
3309
3375
|
const maxLookahead = 100;
|
|
3376
|
+
let firstCommandOnIfLine = false;
|
|
3377
|
+
let prevToken = null;
|
|
3310
3378
|
while (!ctx.isAtEnd() && ctx.current - savedPosition < maxLookahead) {
|
|
3311
3379
|
const token = ctx.peek();
|
|
3312
3380
|
const tokenValue = token.value?.toLowerCase();
|
|
3381
|
+
if (firstCommandOnIfLine && token.line !== undefined && token.line !== ifStatementLine) {
|
|
3382
|
+
break;
|
|
3383
|
+
}
|
|
3313
3384
|
if (tokenValue === KEYWORDS.BEHAVIOR ||
|
|
3314
3385
|
tokenValue === KEYWORDS.DEF ||
|
|
3315
3386
|
tokenValue === KEYWORDS.ON) {
|
|
@@ -3321,11 +3392,15 @@ function parseIfCommand(ctx, commandToken) {
|
|
|
3321
3392
|
}
|
|
3322
3393
|
break;
|
|
3323
3394
|
}
|
|
3324
|
-
if (ctx
|
|
3395
|
+
if (isBodyCommandStart(ctx, prevToken, token)) {
|
|
3325
3396
|
if (token.line !== undefined && token.line !== ifStatementLine) {
|
|
3326
3397
|
hasImplicitMultiLineEnd = true;
|
|
3327
3398
|
break;
|
|
3328
3399
|
}
|
|
3400
|
+
firstCommandOnIfLine = true;
|
|
3401
|
+
}
|
|
3402
|
+
if (!isComment(token)) {
|
|
3403
|
+
prevToken = token;
|
|
3329
3404
|
}
|
|
3330
3405
|
ctx.advance();
|
|
3331
3406
|
}
|
|
@@ -3340,11 +3415,12 @@ function parseIfCommand(ctx, commandToken) {
|
|
|
3340
3415
|
const conditionTokens = [];
|
|
3341
3416
|
const maxIterations = 20;
|
|
3342
3417
|
let iterations = 0;
|
|
3418
|
+
let firstConditionParse = true;
|
|
3343
3419
|
while (!ctx.isAtEnd() &&
|
|
3344
|
-
!ctx.checkIsCommand() &&
|
|
3345
|
-
!ctx.isCommand(ctx.peek().value) &&
|
|
3346
3420
|
!ctx.check(KEYWORDS.THEN) &&
|
|
3421
|
+
(firstConditionParse || (!ctx.checkIsCommand() && !ctx.isCommand(ctx.peek().value))) &&
|
|
3347
3422
|
iterations < maxIterations) {
|
|
3423
|
+
firstConditionParse = false;
|
|
3348
3424
|
const beforePos = ctx.savePosition();
|
|
3349
3425
|
conditionTokens.push(ctx.parseLogicalAnd());
|
|
3350
3426
|
if (ctx.savePosition() === beforePos) {
|
|
@@ -3371,22 +3447,8 @@ function parseIfCommand(ctx, commandToken) {
|
|
|
3371
3447
|
}
|
|
3372
3448
|
args.push(condition);
|
|
3373
3449
|
if (isMultiLine) {
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
}
|
|
3377
|
-
const thenCommands = [];
|
|
3378
|
-
while (!ctx.isAtEnd() && !ctx.check(KEYWORDS.ELSE) && !ctx.check(KEYWORDS.END)) {
|
|
3379
|
-
if (ctx.checkIsCommand() || ctx.isCommand(ctx.peek().value)) {
|
|
3380
|
-
ctx.advance();
|
|
3381
|
-
const cmd = ctx.parseCommand();
|
|
3382
|
-
if (cmd) {
|
|
3383
|
-
thenCommands.push(cmd);
|
|
3384
|
-
}
|
|
3385
|
-
}
|
|
3386
|
-
else {
|
|
3387
|
-
break;
|
|
3388
|
-
}
|
|
3389
|
-
}
|
|
3450
|
+
consumeOptionalKeyword(ctx, KEYWORDS.THEN);
|
|
3451
|
+
const thenCommands = parseIfBranchCommands(ctx, true);
|
|
3390
3452
|
if (thenCommands.length === 0 && ctx.isAtEnd()) {
|
|
3391
3453
|
throw new Error("Expected command after 'then' in if statement - incomplete conditional");
|
|
3392
3454
|
}
|
|
@@ -3412,19 +3474,7 @@ function parseIfCommand(ctx, commandToken) {
|
|
|
3412
3474
|
consumedElseIf = true;
|
|
3413
3475
|
}
|
|
3414
3476
|
else {
|
|
3415
|
-
const elseCommands =
|
|
3416
|
-
while (!ctx.isAtEnd() && !ctx.check(KEYWORDS.END)) {
|
|
3417
|
-
if (ctx.checkIsCommand() || ctx.isCommand(ctx.peek().value)) {
|
|
3418
|
-
ctx.advance();
|
|
3419
|
-
const cmd = ctx.parseCommand();
|
|
3420
|
-
if (cmd) {
|
|
3421
|
-
elseCommands.push(cmd);
|
|
3422
|
-
}
|
|
3423
|
-
}
|
|
3424
|
-
else {
|
|
3425
|
-
break;
|
|
3426
|
-
}
|
|
3427
|
-
}
|
|
3477
|
+
const elseCommands = parseIfBranchCommands(ctx, false);
|
|
3428
3478
|
args.push(createBlock(elseCommands, {
|
|
3429
3479
|
start: commandToken.start,
|
|
3430
3480
|
end: ctx.getPosition().end,
|
|
@@ -4246,21 +4296,6 @@ const GO_KEYWORDS = new Set([
|
|
|
4246
4296
|
'back',
|
|
4247
4297
|
'forward',
|
|
4248
4298
|
]);
|
|
4249
|
-
const GO_URL_STOP = new Set([
|
|
4250
|
-
'in',
|
|
4251
|
-
'then',
|
|
4252
|
-
'and',
|
|
4253
|
-
'else',
|
|
4254
|
-
'end',
|
|
4255
|
-
'otherwise',
|
|
4256
|
-
'when',
|
|
4257
|
-
'where',
|
|
4258
|
-
'catch',
|
|
4259
|
-
'finally',
|
|
4260
|
-
]);
|
|
4261
|
-
function isGoURLTerminator(ctx) {
|
|
4262
|
-
return ctx.isAtEnd() || GO_URL_STOP.has(ctx.peek().value);
|
|
4263
|
-
}
|
|
4264
4299
|
function stringNode(value, tok) {
|
|
4265
4300
|
return {
|
|
4266
4301
|
type: 'string',
|
|
@@ -4282,7 +4317,7 @@ function parseGoCommand(ctx, identifierNode) {
|
|
|
4282
4317
|
continue;
|
|
4283
4318
|
}
|
|
4284
4319
|
if (isNakedURLStart(ctx)) {
|
|
4285
|
-
const url = parseBareURLPath(ctx
|
|
4320
|
+
const url = parseBareURLPath(ctx);
|
|
4286
4321
|
if (url) {
|
|
4287
4322
|
args.push(url);
|
|
4288
4323
|
continue;
|
|
@@ -4422,13 +4457,6 @@ function parseMultiWordCommand(ctx, commandToken, commandName) {
|
|
|
4422
4457
|
}
|
|
4423
4458
|
return builder.build();
|
|
4424
4459
|
}
|
|
4425
|
-
function isFetchURLTerminator(ctx) {
|
|
4426
|
-
if (ctx.isAtEnd())
|
|
4427
|
-
return true;
|
|
4428
|
-
const val = ctx.peek().value;
|
|
4429
|
-
return (['as', 'with', '{', 'then', 'end', 'else', 'otherwise', ')'].includes(val) ||
|
|
4430
|
-
isCommandBoundary(ctx));
|
|
4431
|
-
}
|
|
4432
4460
|
function isNakedURLStart(ctx) {
|
|
4433
4461
|
const tok = ctx.peek();
|
|
4434
4462
|
if (tok.value === '/')
|
|
@@ -4439,23 +4467,50 @@ function isNakedURLStart(ctx) {
|
|
|
4439
4467
|
}
|
|
4440
4468
|
return false;
|
|
4441
4469
|
}
|
|
4442
|
-
|
|
4470
|
+
const URL_HARD_STOPS = new Set(['{', ')']);
|
|
4471
|
+
function parseBareURLPath(ctx) {
|
|
4443
4472
|
const startPos = ctx.savePosition();
|
|
4473
|
+
const firstTok = ctx.peek();
|
|
4444
4474
|
let path = '';
|
|
4445
|
-
|
|
4446
|
-
|
|
4475
|
+
let prev = null;
|
|
4476
|
+
while (!ctx.isAtEnd()) {
|
|
4477
|
+
const tok = ctx.peek();
|
|
4478
|
+
if (prev && tok.start !== prev.end)
|
|
4479
|
+
break;
|
|
4480
|
+
if (tok.value === '$' && ctx.peekAt(1)?.value === '{') {
|
|
4481
|
+
ctx.advance();
|
|
4482
|
+
let last = ctx.advance();
|
|
4483
|
+
let depth = 1;
|
|
4484
|
+
while (!ctx.isAtEnd() && depth > 0) {
|
|
4485
|
+
last = ctx.advance();
|
|
4486
|
+
if (last.value === '{')
|
|
4487
|
+
depth++;
|
|
4488
|
+
else if (last.value === '}')
|
|
4489
|
+
depth--;
|
|
4490
|
+
}
|
|
4491
|
+
path += ctx.getInputSlice(tok.start, last.end);
|
|
4492
|
+
prev = last;
|
|
4493
|
+
continue;
|
|
4494
|
+
}
|
|
4495
|
+
if (URL_HARD_STOPS.has(tok.value))
|
|
4496
|
+
break;
|
|
4497
|
+
prev = ctx.advance();
|
|
4498
|
+
path += prev.value;
|
|
4447
4499
|
}
|
|
4448
4500
|
if (!path || path === '/') {
|
|
4449
4501
|
ctx.restorePosition(startPos);
|
|
4450
4502
|
return null;
|
|
4451
4503
|
}
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
end: ctx.savePosition(),
|
|
4504
|
+
const span = {
|
|
4505
|
+
start: firstTok.start,
|
|
4506
|
+
end: prev ? prev.end : firstTok.end,
|
|
4507
|
+
line: firstTok.line,
|
|
4508
|
+
column: firstTok.column,
|
|
4458
4509
|
};
|
|
4510
|
+
if (path.includes('${')) {
|
|
4511
|
+
return { type: 'templateLiteral', value: path, ...span };
|
|
4512
|
+
}
|
|
4513
|
+
return { type: 'literal', value: path, raw: path, ...span };
|
|
4459
4514
|
}
|
|
4460
4515
|
function parseFetchCommand(ctx, commandToken) {
|
|
4461
4516
|
const modifiers = {};
|
|
@@ -4686,10 +4741,10 @@ function parseTellCommand(ctx, identifierNode) {
|
|
|
4686
4741
|
catch {
|
|
4687
4742
|
break;
|
|
4688
4743
|
}
|
|
4689
|
-
if (ctx.match(KEYWORDS.AND)) {
|
|
4744
|
+
if (ctx.match(KEYWORDS.AND) || ctx.match(KEYWORDS.THEN)) {
|
|
4690
4745
|
continue;
|
|
4691
4746
|
}
|
|
4692
|
-
if (ctx.check(KEYWORDS.
|
|
4747
|
+
if (ctx.check(KEYWORDS.ELSE) || ctx.check(KEYWORDS.END)) {
|
|
4693
4748
|
break;
|
|
4694
4749
|
}
|
|
4695
4750
|
if (ctx.checkIsCommand()) {
|
|
@@ -4892,6 +4947,7 @@ class Parser {
|
|
|
4892
4947
|
const result = this.parseInternal();
|
|
4893
4948
|
if (this.errors.length > 0) {
|
|
4894
4949
|
result.errors = [...this.errors];
|
|
4950
|
+
result.recovered = true;
|
|
4895
4951
|
}
|
|
4896
4952
|
return result;
|
|
4897
4953
|
}
|
|
@@ -6923,6 +6979,9 @@ class Parser {
|
|
|
6923
6979
|
this.advance();
|
|
6924
6980
|
const cmd = this.parseCommand();
|
|
6925
6981
|
commands.push(cmd);
|
|
6982
|
+
if (this.match('then', 'and', ',')) {
|
|
6983
|
+
continue;
|
|
6984
|
+
}
|
|
6926
6985
|
}
|
|
6927
6986
|
else {
|
|
6928
6987
|
break;
|