@@ -129,3 +129,77 @@ impl<J: Jet> ExecTracker<J> for NoTracker {
129129 }
130130 }
131131}
132+
133+ /// Tracker that just outputs all its activity to stderr.
134+ #[ derive( Clone , Debug , Default ) ]
135+ pub struct StderrTracker {
136+ exec_count : usize ,
137+ inner : SetTracker ,
138+ }
139+
140+ impl StderrTracker {
141+ /// Constructs a new empty [`StderrTracker`], ready for use.
142+ pub fn new ( ) -> Self {
143+ Self :: default ( )
144+ }
145+ }
146+
147+ impl < J : Jet > ExecTracker < J > for StderrTracker {
148+ fn visit_node (
149+ & mut self ,
150+ node : & RedeemNode < J > ,
151+ mut input : super :: FrameIter ,
152+ output : NodeOutput ,
153+ ) {
154+ let input_val = Value :: from_padded_bits ( & mut input, & node. arrow ( ) . source )
155+ . expect ( "input from bit machine will always be well-formed" ) ;
156+ eprintln ! (
157+ "[{:4}] exec {:10} {}" ,
158+ self . exec_count,
159+ node. inner( ) ,
160+ node. arrow( )
161+ ) ;
162+ eprintln ! ( " input {input_val}" ) ;
163+ match output {
164+ NodeOutput :: NonTerminal => { /* don't bother describing non-terminal output */ }
165+ NodeOutput :: JetFailed => eprintln ! ( " JET FAILED" ) ,
166+ NodeOutput :: Success ( mut output) => {
167+ let output_val = Value :: from_padded_bits ( & mut output, & node. arrow ( ) . target )
168+ . expect ( "input from bit machine will always be well-formed" ) ;
169+ eprintln ! ( " output {output_val}" ) ;
170+ }
171+ }
172+
173+ if let crate :: node:: Inner :: AssertL ( _, cmr) = node. inner ( ) {
174+ // SimplicityHL, when compiling in "debug mode", tags nodes by inserting
175+ // synthetic AssertL nodes where the "cmr" is actually a key into a lookup
176+ // table of debug information. An implementation of ExecTracker within
177+ // the compiler itself might do a lookup here to output more useful
178+ // information to the user.
179+ eprintln ! ( " [debug] assertL CMR {cmr}" ) ;
180+ }
181+
182+ self . exec_count += 1 ;
183+ eprintln ! ( ) ;
184+ }
185+ }
186+
187+ impl < J : Jet > PruneTracker < J > for StderrTracker {
188+ fn contains_left ( & self , ihr : Ihr ) -> bool {
189+ if PruneTracker :: < J > :: contains_left ( & self . inner , ihr) {
190+ true
191+ } else {
192+ eprintln ! ( "Pruning unexecuted left child of IHR {ihr}" ) ;
193+ false
194+ }
195+ }
196+
197+ fn contains_right ( & self , ihr : Ihr ) -> bool {
198+ if PruneTracker :: < J > :: contains_right ( & self . inner , ihr) {
199+ true
200+ } else {
201+ eprintln ! ( "Pruning unexecuted right child of IHR {ihr}" ) ;
202+ false
203+ }
204+ }
205+ }
0 commit comments