@@ -98,7 +98,8 @@ mod private {
98
98
#[ derive( Copy , Clone , Debug ) ]
99
99
enum NonTerm {
100
100
Expression ,
101
- MaybeSwap ,
101
+ WExpression ,
102
+ Swap ,
102
103
MaybeAndV ,
103
104
Alt ,
104
105
Check ,
@@ -208,6 +209,7 @@ macro_rules! match_token {
208
209
}
209
210
210
211
///Vec representing terminals stack while decoding.
212
+ #[ derive( Debug ) ]
211
213
struct TerminalStack < Pk : MiniscriptKey , Ctx : ScriptContext > ( Vec < Miniscript < Pk , Ctx > > ) ;
212
214
213
215
impl < Pk : MiniscriptKey , Ctx : ScriptContext > TerminalStack < Pk , Ctx > {
@@ -284,8 +286,8 @@ pub fn parse<Ctx: ScriptContext>(
284
286
let mut non_term = Vec :: with_capacity ( tokens. len ( ) ) ;
285
287
let mut term = TerminalStack ( Vec :: with_capacity ( tokens. len ( ) ) ) ;
286
288
289
+ // top level cannot be swap, must be B
287
290
non_term. push ( NonTerm :: MaybeAndV ) ;
288
- non_term. push ( NonTerm :: MaybeSwap ) ;
289
291
non_term. push ( NonTerm :: Expression ) ;
290
292
loop {
291
293
match non_term. pop ( ) {
@@ -439,34 +441,24 @@ pub fn parse<Ctx: ScriptContext>(
439
441
// `OP_ADD` or not and do the right thing
440
442
} ,
441
443
) ,
442
- // fromaltstack
443
- Tk :: FromAltStack => {
444
- non_term. push( NonTerm :: Alt ) ;
445
- non_term. push( NonTerm :: MaybeAndV ) ;
446
- non_term. push( NonTerm :: MaybeSwap ) ;
447
- non_term. push( NonTerm :: Expression ) ;
448
- } ,
449
444
// most other fragments
450
445
Tk :: Num ( 0 ) => term. reduce0( Terminal :: False ) ?,
451
446
Tk :: Num ( 1 ) => term. reduce0( Terminal :: True ) ?,
452
447
Tk :: EndIf => {
453
448
non_term. push( NonTerm :: EndIf ) ;
454
449
non_term. push( NonTerm :: MaybeAndV ) ;
455
- non_term. push( NonTerm :: MaybeSwap ) ;
456
450
non_term. push( NonTerm :: Expression ) ;
457
451
} ,
458
452
// boolean conjunctions and disjunctions
459
453
Tk :: BoolAnd => {
460
454
non_term. push( NonTerm :: AndB ) ;
461
455
non_term. push( NonTerm :: Expression ) ;
462
- non_term. push( NonTerm :: MaybeSwap ) ;
463
- non_term. push( NonTerm :: Expression ) ;
456
+ non_term. push( NonTerm :: WExpression ) ;
464
457
} ,
465
458
Tk :: BoolOr => {
466
459
non_term. push( NonTerm :: OrB ) ;
467
460
non_term. push( NonTerm :: Expression ) ;
468
- non_term. push( NonTerm :: MaybeSwap ) ;
469
- non_term. push( NonTerm :: Expression ) ;
461
+ non_term. push( NonTerm :: WExpression ) ;
470
462
} ,
471
463
// CHECKMULTISIG based multisig
472
464
Tk :: CheckMultiSig , Tk :: Num ( n) => {
@@ -522,15 +514,14 @@ pub fn parse<Ctx: ScriptContext>(
522
514
non_term. push ( NonTerm :: Expression ) ;
523
515
}
524
516
}
525
- Some ( NonTerm :: MaybeSwap ) => {
517
+ Some ( NonTerm :: Swap ) => {
526
518
// Handle `SWAP` prefixing
527
- if let Some ( & Tk :: Swap ) = tokens. peek ( ) {
528
- tokens. next ( ) ;
529
- // let top = term.pop().unwrap();
530
- term. reduce1 ( Terminal :: Swap ) ?;
531
- // term.push(Terminal::Swap(Arc::new(top)));
532
- non_term. push ( NonTerm :: MaybeSwap ) ;
533
- }
519
+ match_token ! (
520
+ tokens,
521
+ Tk :: Swap => { } ,
522
+ ) ;
523
+ term. reduce1 ( Terminal :: Swap ) ?;
524
+ // Swap must be always be terminating a NonTerm as it cannot be in and_v
534
525
}
535
526
Some ( NonTerm :: Alt ) => {
536
527
match_token ! (
@@ -577,14 +568,14 @@ pub fn parse<Ctx: ScriptContext>(
577
568
tokens,
578
569
Tk :: Add => {
579
570
non_term. push( NonTerm :: ThreshW { n: n + 1 , k } ) ;
571
+ non_term. push( NonTerm :: WExpression ) ;
580
572
} ,
581
573
x => {
582
574
tokens. un_next( x) ;
583
575
non_term. push( NonTerm :: ThreshE { n: n + 1 , k } ) ;
576
+ non_term. push( NonTerm :: Expression ) ;
584
577
} ,
585
578
) ;
586
- non_term. push ( NonTerm :: MaybeSwap ) ;
587
- non_term. push ( NonTerm :: Expression ) ;
588
579
}
589
580
Some ( NonTerm :: ThreshE { n, k } ) => {
590
581
let mut subs = Vec :: with_capacity ( n) ;
@@ -599,7 +590,6 @@ pub fn parse<Ctx: ScriptContext>(
599
590
Tk :: Else => {
600
591
non_term. push( NonTerm :: EndIfElse ) ;
601
592
non_term. push( NonTerm :: MaybeAndV ) ;
602
- non_term. push( NonTerm :: MaybeSwap ) ;
603
593
non_term. push( NonTerm :: Expression ) ;
604
594
} ,
605
595
Tk :: If => match_token!(
@@ -636,6 +626,14 @@ pub fn parse<Ctx: ScriptContext>(
636
626
} ,
637
627
) ;
638
628
}
629
+ Some ( NonTerm :: WExpression ) => {
630
+ // W expression must be either from swap or Fromaltstack
631
+ match_token ! ( tokens,
632
+ Tk :: FromAltStack => { non_term. push( NonTerm :: Alt ) ; } ,
633
+ tok => { tokens. un_next( tok) ; non_term. push( NonTerm :: Swap ) ; } , ) ;
634
+ non_term. push ( NonTerm :: MaybeAndV ) ;
635
+ non_term. push ( NonTerm :: Expression ) ;
636
+ }
639
637
None => {
640
638
// Done :)
641
639
break ;
@@ -650,7 +648,12 @@ pub fn parse<Ctx: ScriptContext>(
650
648
651
649
fn is_and_v ( tokens : & mut TokenIter ) -> bool {
652
650
match tokens. peek ( ) {
653
- None | Some ( & Tk :: If ) | Some ( & Tk :: NotIf ) | Some ( & Tk :: Else ) | Some ( & Tk :: ToAltStack ) => false ,
651
+ None
652
+ | Some ( & Tk :: If )
653
+ | Some ( & Tk :: NotIf )
654
+ | Some ( & Tk :: Else )
655
+ | Some ( & Tk :: ToAltStack )
656
+ | Some ( & Tk :: Swap ) => false ,
654
657
_ => true ,
655
658
}
656
659
}
0 commit comments