@@ -5,6 +5,7 @@ import { Seq, sequence } from "lazily-async";
5
5
6
6
import exception from "./exception" ;
7
7
import importModule = require( "./import-module" ) ;
8
+ import { currentId } from "async_hooks" ;
8
9
9
10
const exec = promisify ( child_process . exec ) ;
10
11
@@ -15,6 +16,7 @@ const options = [
15
16
"-c" , // n1,n2,n3 combine a named stages
16
17
"-e" , // shell command
17
18
"-f" , // filter
19
+ "-g" , // n, exp recurse
18
20
"-i" , // import a file or module
19
21
"-j" , // JS expression
20
22
"-l" , // evaluate and log a value to console
@@ -392,21 +394,30 @@ export async function evaluate(
392
394
) {
393
395
return await evaluateInternal (
394
396
args ,
397
+ [ ] ,
395
398
Seq . of ( [ ] ) ,
396
399
mustPrint ,
397
400
onLog ,
398
401
onWrite ,
399
- true
402
+ true ,
403
+ [ ]
400
404
) ;
401
405
}
402
406
407
+ type ExpressionStackEntry = {
408
+ name : string ;
409
+ args : Array < string > ;
410
+ } ;
411
+
403
412
async function evaluateInternal (
404
413
args : Array < string > ,
414
+ prevArgs : Array < string > ,
405
415
input : Seq < PipelineItem > ,
406
416
mustPrint : boolean ,
407
417
onLog : BashoLogFn ,
408
418
onWrite : BashoLogFn ,
409
- isInitialInput : boolean
419
+ isInitialInput : boolean ,
420
+ expressionStack : Array < ExpressionStackEntry >
410
421
) : Promise < BashoEvaluationResult > {
411
422
const cases : Array < [ ( arg : string ) => boolean , ( ) => Promise < any > ] > = [
412
423
/* Enumerate sequence into an array */
@@ -416,6 +427,7 @@ async function evaluateInternal(
416
427
const items = await input . toArray ( ) ;
417
428
return await evalShorthand (
418
429
args . slice ( 1 ) ,
430
+ args ,
419
431
Seq . of ( [
420
432
new PipelineValue (
421
433
items . map ( x => ( x instanceof PipelineValue ? x . value : x ) )
@@ -432,6 +444,7 @@ async function evaluateInternal(
432
444
async ( ) =>
433
445
await evalShorthand (
434
446
args . slice ( 2 ) ,
447
+ args ,
435
448
input . map ( x => {
436
449
const streams = args [ 1 ] . split ( "," ) ;
437
450
return new PipelineValue (
@@ -453,6 +466,7 @@ async function evaluateInternal(
453
466
const { cursor, expression } = munch ( args . slice ( 1 ) ) ;
454
467
return await evalShorthand (
455
468
args . slice ( cursor + 1 ) ,
469
+ args ,
456
470
await shellCmd (
457
471
expression ,
458
472
input ,
@@ -485,7 +499,7 @@ async function evaluateInternal(
485
499
: x ;
486
500
} ) ;
487
501
488
- return await evalShorthand ( args . slice ( cursor + 1 ) , newSeq , false ) ;
502
+ return await evalShorthand ( args . slice ( cursor + 1 ) , args , newSeq , false ) ;
489
503
}
490
504
] ,
491
505
@@ -495,7 +509,61 @@ async function evaluateInternal(
495
509
async ( ) => {
496
510
const { cursor, expression } = munch ( args . slice ( 1 ) ) ;
497
511
const filtered = await filter ( expression , input ) ;
498
- return await evalShorthand ( args . slice ( cursor + 1 ) , filtered , false ) ;
512
+ return await evalShorthand (
513
+ args . slice ( cursor + 1 ) ,
514
+ args ,
515
+ filtered ,
516
+ false
517
+ ) ;
518
+ }
519
+ ] ,
520
+
521
+ /* Recurse/Goto */
522
+ [
523
+ x => x === "-g" ,
524
+ async ( ) => {
525
+ const name = args [ 1 ] ;
526
+ const { cursor, expression } = munch ( args . slice ( 2 ) ) ;
527
+ const recursePoint = expressionStack . find ( e => e . name === name ) ;
528
+ const fn = await evalWithCatch ( `(x, i) => (${ expression } )` ) ;
529
+ const newSeq = input . map (
530
+ async ( x , i ) =>
531
+ recursePoint
532
+ ? x instanceof PipelineValue
533
+ ? await ( async ( ) => {
534
+ const predicateResult = await fn ( await x . value , i ) ;
535
+ return predicateResult === true
536
+ ? await ( async ( ) => {
537
+ const recurseArgs = recursePoint . args . slice (
538
+ 0 ,
539
+ recursePoint . args . length -
540
+ ( args . length - ( cursor + 2 ) )
541
+ ) ;
542
+ const innerEvalResult = await evaluateInternal (
543
+ recurseArgs ,
544
+ [ ] ,
545
+ Seq . of ( [ x ] ) ,
546
+ mustPrint ,
547
+ onLog ,
548
+ onWrite ,
549
+ false ,
550
+ [ ]
551
+ ) ;
552
+ const results = await innerEvalResult . result . toArray ( ) ;
553
+ const result = results [ 0 ] ;
554
+ return result instanceof PipelineValue
555
+ ? new PipelineValue ( result . value , x )
556
+ : result ;
557
+ } ) ( )
558
+ : x ;
559
+ } ) ( )
560
+ : x
561
+ : new PipelineError (
562
+ `The expression ${ name } was not found.` ,
563
+ new Error ( `Missing expression ${ name } .` )
564
+ )
565
+ ) ;
566
+ return await evalShorthand ( args . slice ( cursor + 2 ) , args , newSeq , false ) ;
499
567
}
500
568
] ,
501
569
@@ -506,11 +574,13 @@ async function evaluateInternal(
506
574
evalImport ( args [ 1 ] , args [ 2 ] ) ;
507
575
return await evaluateInternal (
508
576
args . slice ( 3 ) ,
577
+ args ,
509
578
input ,
510
579
mustPrint ,
511
580
onLog ,
512
581
onWrite ,
513
- isInitialInput
582
+ isInitialInput ,
583
+ expressionStack
514
584
) ;
515
585
}
516
586
] ,
@@ -522,6 +592,7 @@ async function evaluateInternal(
522
592
const { cursor, expression } = munch ( args . slice ( 1 ) ) ;
523
593
return await evalShorthand (
524
594
args . slice ( cursor + 1 ) ,
595
+ args ,
525
596
await evalExpression (
526
597
expression ,
527
598
input ,
@@ -534,15 +605,15 @@ async function evaluateInternal(
534
605
] ,
535
606
536
607
/* Logging */
537
- [ x => x === "-l" , getPrinter ( onLog ) ( input , args , evalShorthand ) ] ,
608
+ [ x => x === "-l" , getPrinter ( onLog ) ( input , args ) ] ,
538
609
539
610
/* Flatmap */
540
611
[
541
612
x => x === "-m" ,
542
613
async ( ) => {
543
614
const { cursor, expression } = munch ( args . slice ( 1 ) ) ;
544
615
const mapped = await flatMap ( expression , input ) ;
545
- return await evalShorthand ( args . slice ( cursor + 1 ) , mapped , false ) ;
616
+ return await evalShorthand ( args . slice ( cursor + 1 ) , args , mapped , false ) ;
546
617
}
547
618
] ,
548
619
@@ -551,7 +622,16 @@ async function evaluateInternal(
551
622
x => x === "-n" ,
552
623
async ( ) => {
553
624
const newSeq = input . map ( async ( x , i ) => x . clone ( args [ 1 ] ) ) ;
554
- return await evalShorthand ( args . slice ( 2 ) , newSeq , false ) ;
625
+ return await evaluateInternal (
626
+ args . slice ( 2 ) ,
627
+ args ,
628
+ newSeq ,
629
+ mustPrint ,
630
+ onLog ,
631
+ onWrite ,
632
+ false ,
633
+ expressionStack . concat ( { name : args [ 1 ] , args : prevArgs } )
634
+ ) ;
555
635
}
556
636
] ,
557
637
@@ -561,11 +641,13 @@ async function evaluateInternal(
561
641
async ( ) =>
562
642
await evaluateInternal (
563
643
args . slice ( 1 ) ,
644
+ args ,
564
645
input ,
565
646
mustPrint ,
566
647
onLog ,
567
648
onWrite ,
568
- isInitialInput
649
+ isInitialInput ,
650
+ expressionStack
569
651
)
570
652
] ,
571
653
@@ -575,11 +657,13 @@ async function evaluateInternal(
575
657
async ( ) =>
576
658
await evaluateInternal (
577
659
args . slice ( 1 ) ,
660
+ args ,
578
661
input ,
579
662
false ,
580
663
onLog ,
581
664
onWrite ,
582
- isInitialInput
665
+ isInitialInput ,
666
+ expressionStack
583
667
)
584
668
] ,
585
669
@@ -598,6 +682,7 @@ async function evaluateInternal(
598
682
const reduced = await reduce ( expression , input , initialValue ) ;
599
683
return await evalShorthand (
600
684
args . slice ( cursor + 1 ) ,
685
+ args ,
601
686
Seq . of ( [ reduced ] ) ,
602
687
false
603
688
) ;
@@ -613,6 +698,7 @@ async function evaluateInternal(
613
698
async ( ) =>
614
699
await evalShorthand (
615
700
args . slice ( 2 ) ,
701
+ args ,
616
702
input . map ( x => {
617
703
return new PipelineValue (
618
704
( ( ) => {
@@ -656,14 +742,15 @@ async function evaluateInternal(
656
742
}
657
743
return await evalShorthand (
658
744
args . slice ( cursor + 1 ) ,
745
+ args ,
659
746
new Seq ( asyncGenerator ) ,
660
747
false
661
748
) ;
662
749
}
663
750
] ,
664
751
665
752
/* Writing */
666
- [ x => x === "-w" , getPrinter ( onWrite ) ( input , args , evalShorthand ) ] ,
753
+ [ x => x === "-w" , getPrinter ( onWrite ) ( input , args ) ] ,
667
754
668
755
/* Everything else as JS expressions */
669
756
[
@@ -672,6 +759,7 @@ async function evaluateInternal(
672
759
const { cursor, expression } = munch ( args ) ;
673
760
return await evalShorthand (
674
761
args . slice ( cursor ) ,
762
+ args ,
675
763
await evalExpression (
676
764
expression ,
677
765
input ,
@@ -685,11 +773,7 @@ async function evaluateInternal(
685
773
] ;
686
774
687
775
function getPrinter ( printFn : BashoLogFn ) {
688
- return (
689
- input : Seq < PipelineItem > ,
690
- args : Array < string > ,
691
- evalFn : typeof evalShorthand
692
- ) => async ( ) => {
776
+ return ( input : Seq < PipelineItem > , args : Array < string > ) => async ( ) => {
693
777
const { cursor, expression } = munch ( args . slice ( 1 ) ) ;
694
778
const fn = await evalWithCatch ( `(x, i) => (${ expression } )` ) ;
695
779
const newSeq = input . map ( async ( x , i ) => {
@@ -705,6 +789,7 @@ async function evaluateInternal(
705
789
} ) ;
706
790
return await evalShorthand (
707
791
args . slice ( cursor + 1 ) ,
792
+ args ,
708
793
newSeq ,
709
794
isInitialInput
710
795
) ;
@@ -713,16 +798,19 @@ async function evaluateInternal(
713
798
714
799
async function evalShorthand (
715
800
args : Array < string > ,
801
+ prevArgs : Array < string > ,
716
802
input : Seq < PipelineItem > ,
717
803
isInitialInput : boolean
718
804
) : Promise < BashoEvaluationResult > {
719
805
return await evaluateInternal (
720
806
args ,
807
+ prevArgs ,
721
808
input ,
722
809
mustPrint ,
723
810
onLog ,
724
811
onWrite ,
725
- isInitialInput
812
+ isInitialInput ,
813
+ expressionStack
726
814
) ;
727
815
}
728
816
0 commit comments