@@ -598,13 +598,71 @@ impl From<JetFailed> for ExecutionError {
598598mod tests {
599599 use super :: * ;
600600
601+ use crate :: jet:: Core ;
602+ use crate :: node:: RedeemNode ;
603+
601604 #[ cfg( feature = "elements" ) ]
602605 use crate :: jet:: { elements:: ElementsEnv , Elements } ;
603606 #[ cfg( feature = "elements" ) ]
604- use crate :: { node :: RedeemNode , BitIter } ;
607+ use crate :: BitIter ;
605608 #[ cfg( feature = "elements" ) ]
606609 use hex:: DisplayHex ;
607610
611+ /// Records the combinator name of each node visited during execution, in pre-order.
612+ #[ derive( Default ) ]
613+ struct OrderTracker ( Vec < String > ) ;
614+
615+ impl ExecTracker < Core > for OrderTracker {
616+ fn visit_node ( & mut self , node : & RedeemNode < Core > , _input : FrameIter , _output : NodeOutput ) {
617+ self . 0 . push ( node. inner ( ) . to_string ( ) ) ;
618+ }
619+ }
620+
621+ /// Parse a simplicity program string, run it on the bitmachine with an [`OrderTracker`],
622+ /// and return the list of combinator names visited in execution (pre-)order.
623+ ///
624+ /// The string must contain a `main` root. Use human-encoding syntax, e.g.:
625+ /// `"main := comp iden unit"` or `"main := pair (drop iden) iden : 1 * 1 -> 1 * (1 * 1)"`.
626+ fn exec_order ( s : & str ) -> Vec < String > {
627+ use crate :: human_encoding:: Forest ;
628+ use crate :: types;
629+ use std:: collections:: HashMap ;
630+
631+ types:: Context :: with_context ( |ctx| {
632+ let program = Forest :: < Core > :: parse ( s)
633+ . expect ( "parse" )
634+ . to_witness_node ( & ctx, & HashMap :: new ( ) )
635+ . expect ( "main root" )
636+ . finalize_pruned ( & ( ) )
637+ . expect ( "finalize" ) ;
638+ let mut mac = BitMachine :: for_program ( & program) . expect ( "for_program" ) ;
639+ let mut tracker = OrderTracker :: default ( ) ;
640+ mac. exec_with_tracker ( & program, & ( ) , & mut tracker)
641+ . expect ( "exec" ) ;
642+ tracker. 0
643+ } )
644+ }
645+
646+ /// Execution visits nodes in pre-order: parent before children.
647+ /// Documented example from tracker.rs: comp, iden, unit.
648+ #[ test]
649+ fn execution_order_comp_iden_unit ( ) {
650+ assert_eq ! (
651+ exec_order( "main := comp iden unit" ) ,
652+ [ "comp" , "iden" , "unit" ] ,
653+ ) ;
654+ }
655+
656+ /// pair(drop(iden), iden): pair first, then left subtree (drop → its child iden),
657+ /// then right subtree (iden).
658+ #[ test]
659+ fn execution_order_pair_drop_iden ( ) {
660+ assert_eq ! (
661+ exec_order( "main := comp (pair (take (take iden)) unit) unit: ((1 * 1) * 1) -> 1" ) ,
662+ [ "comp" , "pair" , "take" , "take" , "iden" , "unit" , "unit" ] ,
663+ ) ;
664+ }
665+
608666 #[ cfg( feature = "elements" ) ]
609667 fn run_program_elements (
610668 prog_bytes : & [ u8 ] ,
0 commit comments