@@ -21,6 +21,13 @@ pub struct CodegenOptions {
2121 /// Prefixes to remove when printing file names in generaed files. This
2222 /// helps keep codegen deterministic.
2323 pub prefixes : Vec < Prefix > ,
24+
25+ /// Emit `log::debug!` and `log::trace!` invocations in the generated code to help
26+ /// debug rule matching and execution.
27+ ///
28+ /// In Cranelift this is typically controlled by a cargo feature on the
29+ /// crate that includes the generated code (e.g. `cranelift-codegen`).
30+ pub emit_logging : bool ,
2431}
2532
2633/// A path prefix which should be replaced when printing file names.
@@ -63,16 +70,20 @@ struct BodyContext<'a, W> {
6370 indent : String ,
6471 is_ref : StableSet < BindingId > ,
6572 is_bound : StableSet < BindingId > ,
73+ term_name : & ' a str ,
74+ emit_logging : bool ,
6675}
6776
6877impl < ' a , W : Write > BodyContext < ' a , W > {
69- fn new ( out : & ' a mut W , ruleset : & ' a RuleSet ) -> Self {
78+ fn new ( out : & ' a mut W , ruleset : & ' a RuleSet , term_name : & ' a str , emit_logging : bool ) -> Self {
7079 Self {
7180 out,
7281 ruleset,
7382 indent : Default :: default ( ) ,
7483 is_ref : Default :: default ( ) ,
7584 is_bound : Default :: default ( ) ,
85+ term_name,
86+ emit_logging,
7687 }
7788 }
7889
@@ -130,7 +141,8 @@ impl<'a> Codegen<'a> {
130141 self . generate_header ( & mut code, options) ;
131142 self . generate_ctx_trait ( & mut code) ;
132143 self . generate_internal_types ( & mut code) ;
133- self . generate_internal_term_constructors ( & mut code) . unwrap ( ) ;
144+ self . generate_internal_term_constructors ( & mut code, options)
145+ . unwrap ( ) ;
134146
135147 code
136148 }
@@ -404,13 +416,17 @@ impl<L: Length, C> Length for ContextIterWrapper<L, C> {{
404416 }
405417 }
406418
407- fn generate_internal_term_constructors ( & self , code : & mut String ) -> std:: fmt:: Result {
419+ fn generate_internal_term_constructors (
420+ & self ,
421+ code : & mut String ,
422+ options : & CodegenOptions ,
423+ ) -> std:: fmt:: Result {
408424 for & ( termid, ref ruleset) in self . terms . iter ( ) {
409425 let root = crate :: serialize:: serialize ( ruleset) ;
410- let mut ctx = BodyContext :: new ( code, ruleset) ;
411426
412427 let termdata = & self . termenv . terms [ termid. index ( ) ] ;
413428 let term_name = & self . typeenv . syms [ termdata. name . index ( ) ] ;
429+ let mut ctx = BodyContext :: new ( code, ruleset, term_name, options. emit_logging ) ;
414430 writeln ! ( ctx. out) ?;
415431 writeln ! (
416432 ctx. out,
@@ -664,6 +680,15 @@ impl<L: Length, C> Length for ContextIterWrapper<L, C> {{
664680 & ctx. indent,
665681 pos. pretty_print_line( & self . files)
666682 ) ?;
683+ if ctx. emit_logging {
684+ // Produce a valid Rust string literal with escapes.
685+ let pp = pos. pretty_print_line ( & self . files ) ;
686+ writeln ! (
687+ ctx. out,
688+ "{}log::debug!(\" ISLE {{}} {{}}\" , {:?}, {:?});" ,
689+ & ctx. indent, ctx. term_name, pp
690+ ) ?;
691+ }
667692 write ! ( ctx. out, "{}" , & ctx. indent) ?;
668693 match ret_kind {
669694 ReturnKind :: Plain | ReturnKind :: Option => {
0 commit comments