@@ -283,7 +283,7 @@ class Composer {
283
283
284
284
repeat ( count ) { // varargs, no options
285
285
if ( typeof count !== 'number' ) throw new ComposerError ( 'Invalid argument' , count )
286
- return this . let ( { count } , this . while ( this . function ( ( ) => count -- > 0 , { helper : 'repeat_1' } ) , this . seq ( ...Array . prototype . slice . call ( arguments , 1 ) ) ) )
286
+ return this . let ( { count } , this . while ( this . function ( ( ) => count -- > 0 , { helper : 'repeat_1' } ) , this . mask ( this . seq ( ...Array . prototype . slice . call ( arguments , 1 ) ) ) ) )
287
287
}
288
288
289
289
retry ( count ) { // varargs, no options
@@ -292,10 +292,15 @@ class Composer {
292
292
return this . let ( { count } ,
293
293
this . function ( params => ( { params } ) , { helper : 'retry_1' } ) ,
294
294
this . dowhile (
295
- this . finally ( this . function ( ( { params } ) => params , { helper : 'retry_2' } ) , attempt ) ,
295
+ this . finally ( this . function ( ( { params } ) => params , { helper : 'retry_2' } ) , this . mask ( attempt ) ) ,
296
296
this . function ( ( { result } ) => typeof result . error !== 'undefined' && count -- > 0 , { helper : 'retry_3' } ) ) ,
297
297
this . function ( ( { result } ) => result , { helper : 'retry_4' } ) )
298
298
}
299
+
300
+ mask ( body , options ) {
301
+ if ( arguments . length > 2 ) throw new ComposerError ( 'Too many arguments' )
302
+ return new Composition ( { type : 'mask' , body : this . task ( body ) } , options )
303
+ }
299
304
}
300
305
301
306
module . exports = new Composer ( )
@@ -333,6 +338,9 @@ function init(__eval__, composition) {
333
338
case 'let' :
334
339
var body = compile ( json . body , path + '.body' )
335
340
return [ [ { type : 'let' , let : json . declarations , path } ] , body , [ { type : 'exit' , path } ] ] . reduce ( chain )
341
+ case 'mask' :
342
+ var body = compile ( json . body , path + '.body' )
343
+ return [ [ { type : 'mask' , path } ] , body , [ { type : 'exit' , path } ] ] . reduce ( chain )
336
344
case 'retain' :
337
345
var body = compile ( json . body , path + '.body' )
338
346
var fsm = [ [ { type : 'push' , path } ] , body , [ { type : 'pop' , collect : true , path } ] ] . reduce ( chain )
@@ -433,14 +441,29 @@ function init(__eval__, composition) {
433
441
434
442
// run function f on current stack
435
443
function run ( f ) {
444
+ // handle let/mask pairs
445
+ const view = [ ]
446
+ let n = 0
447
+ for ( let i in stack ) {
448
+ if ( typeof stack [ i ] . mask !== 'undefined' ) {
449
+ n ++
450
+ } else if ( typeof stack [ i ] . let !== 'undefined' ) {
451
+ if ( n === 0 ) {
452
+ view . push ( stack [ i ] )
453
+ } else {
454
+ n --
455
+ }
456
+ }
457
+ }
458
+
436
459
// update value of topmost matching symbol on stack if any
437
460
function set ( symbol , value ) {
438
- const element = stack . find ( element => typeof element . let !== 'undefined' && typeof element . let [ symbol ] !== 'undefined' )
461
+ const element = view . find ( element => typeof element . let !== 'undefined' && typeof element . let [ symbol ] !== 'undefined' )
439
462
if ( typeof element !== 'undefined' ) element . let [ symbol ] = JSON . parse ( JSON . stringify ( value ) )
440
463
}
441
464
442
465
// collapse stack for invocation
443
- const env = stack . reduceRight ( ( acc , cur ) => typeof cur . let === 'object' ? Object . assign ( acc , cur . let ) : acc , { } )
466
+ const env = view . reduceRight ( ( acc , cur ) => typeof cur . let === 'object' ? Object . assign ( acc , cur . let ) : acc , { } )
444
467
let main = '(function(){try{'
445
468
for ( const name in env ) main += `var ${ name } =arguments[1]['${ name } '];`
446
469
main += `return eval((${ f } ))(arguments[0])}finally{`
@@ -476,6 +499,9 @@ function init(__eval__, composition) {
476
499
case 'let' :
477
500
stack . unshift ( { let : JSON . parse ( JSON . stringify ( json . let ) ) } )
478
501
break
502
+ case 'mask' :
503
+ stack . unshift ( { mask : true } )
504
+ break
479
505
case 'exit' :
480
506
if ( stack . length === 0 ) return internalError ( `State ${ current } attempted to pop from an empty stack` )
481
507
stack . shift ( )
0 commit comments