@@ -98,7 +98,8 @@ mod private {
9898#[ derive( Copy , Clone , Debug ) ]
9999enum NonTerm {
100100 Expression ,
101- MaybeSwap ,
101+ WExpression ,
102+ Swap ,
102103 MaybeAndV ,
103104 Alt ,
104105 Check ,
@@ -208,6 +209,7 @@ macro_rules! match_token {
208209}
209210
210211///Vec representing terminals stack while decoding.
212+ #[ derive( Debug ) ]
211213struct TerminalStack < Pk : MiniscriptKey , Ctx : ScriptContext > ( Vec < Miniscript < Pk , Ctx > > ) ;
212214
213215impl < Pk : MiniscriptKey , Ctx : ScriptContext > TerminalStack < Pk , Ctx > {
@@ -284,8 +286,8 @@ pub fn parse<Ctx: ScriptContext>(
284286 let mut non_term = Vec :: with_capacity ( tokens. len ( ) ) ;
285287 let mut term = TerminalStack ( Vec :: with_capacity ( tokens. len ( ) ) ) ;
286288
289+ // top level cannot be swap, must be B
287290 non_term. push ( NonTerm :: MaybeAndV ) ;
288- non_term. push ( NonTerm :: MaybeSwap ) ;
289291 non_term. push ( NonTerm :: Expression ) ;
290292 loop {
291293 match non_term. pop ( ) {
@@ -439,34 +441,24 @@ pub fn parse<Ctx: ScriptContext>(
439441 // `OP_ADD` or not and do the right thing
440442 } ,
441443 ) ,
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- } ,
449444 // most other fragments
450445 Tk :: Num ( 0 ) => term. reduce0( Terminal :: False ) ?,
451446 Tk :: Num ( 1 ) => term. reduce0( Terminal :: True ) ?,
452447 Tk :: EndIf => {
453448 non_term. push( NonTerm :: EndIf ) ;
454449 non_term. push( NonTerm :: MaybeAndV ) ;
455- non_term. push( NonTerm :: MaybeSwap ) ;
456450 non_term. push( NonTerm :: Expression ) ;
457451 } ,
458452 // boolean conjunctions and disjunctions
459453 Tk :: BoolAnd => {
460454 non_term. push( NonTerm :: AndB ) ;
461455 non_term. push( NonTerm :: Expression ) ;
462- non_term. push( NonTerm :: MaybeSwap ) ;
463- non_term. push( NonTerm :: Expression ) ;
456+ non_term. push( NonTerm :: WExpression ) ;
464457 } ,
465458 Tk :: BoolOr => {
466459 non_term. push( NonTerm :: OrB ) ;
467460 non_term. push( NonTerm :: Expression ) ;
468- non_term. push( NonTerm :: MaybeSwap ) ;
469- non_term. push( NonTerm :: Expression ) ;
461+ non_term. push( NonTerm :: WExpression ) ;
470462 } ,
471463 // CHECKMULTISIG based multisig
472464 Tk :: CheckMultiSig , Tk :: Num ( n) => {
@@ -522,15 +514,14 @@ pub fn parse<Ctx: ScriptContext>(
522514 non_term. push ( NonTerm :: Expression ) ;
523515 }
524516 }
525- Some ( NonTerm :: MaybeSwap ) => {
517+ Some ( NonTerm :: Swap ) => {
526518 // 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
534525 }
535526 Some ( NonTerm :: Alt ) => {
536527 match_token ! (
@@ -577,14 +568,14 @@ pub fn parse<Ctx: ScriptContext>(
577568 tokens,
578569 Tk :: Add => {
579570 non_term. push( NonTerm :: ThreshW { n: n + 1 , k } ) ;
571+ non_term. push( NonTerm :: WExpression ) ;
580572 } ,
581573 x => {
582574 tokens. un_next( x) ;
583575 non_term. push( NonTerm :: ThreshE { n: n + 1 , k } ) ;
576+ non_term. push( NonTerm :: Expression ) ;
584577 } ,
585578 ) ;
586- non_term. push ( NonTerm :: MaybeSwap ) ;
587- non_term. push ( NonTerm :: Expression ) ;
588579 }
589580 Some ( NonTerm :: ThreshE { n, k } ) => {
590581 let mut subs = Vec :: with_capacity ( n) ;
@@ -599,7 +590,6 @@ pub fn parse<Ctx: ScriptContext>(
599590 Tk :: Else => {
600591 non_term. push( NonTerm :: EndIfElse ) ;
601592 non_term. push( NonTerm :: MaybeAndV ) ;
602- non_term. push( NonTerm :: MaybeSwap ) ;
603593 non_term. push( NonTerm :: Expression ) ;
604594 } ,
605595 Tk :: If => match_token!(
@@ -636,6 +626,14 @@ pub fn parse<Ctx: ScriptContext>(
636626 } ,
637627 ) ;
638628 }
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+ }
639637 None => {
640638 // Done :)
641639 break ;
@@ -650,7 +648,12 @@ pub fn parse<Ctx: ScriptContext>(
650648
651649fn is_and_v ( tokens : & mut TokenIter ) -> bool {
652650 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 ,
654657 _ => true ,
655658 }
656659}
0 commit comments