1
use std::fmt::Debug;
2

            
3
use clap::ValueEnum;
4

            
5
use merc_aterm::ATerm;
6
use merc_data::to_untyped_data_expression;
7
use merc_sabre::InnermostRewriter;
8
use merc_sabre::NaiveRewriter;
9
use merc_sabre::RewriteEngine;
10
use merc_sabre::RewriteSpecification;
11
use merc_sabre::SabreRewriter;
12
use merc_utilities::MercError;
13
use merc_utilities::Timing;
14

            
15
/// Selects the rewriter to use.
16
#[derive(ValueEnum, Debug, Clone)]
17
pub enum Rewriter {
18
    Naive,
19
    Innermost,
20
    Sabre,
21
}
22

            
23
/// Rewrites the given REC specification.
24
pub fn rewrite_rec(
25
    rewriter: Rewriter,
26
    spec: &RewriteSpecification,
27
    syntax_terms: &[ATerm],
28
    output: bool,
29
    timing: &Timing,
30
) -> Result<(), MercError> {
31
    timing.measure("rewrite_rec", || {
32
        match rewriter {
33
            Rewriter::Naive => {
34
                let mut inner = NaiveRewriter::new(spec);
35

            
36
                for term in syntax_terms {
37
                    let term = to_untyped_data_expression(term.clone(), None);
38
                    let result = inner.rewrite(&term);
39
                    if output {
40
                        println!("{}", result)
41
                    }
42
                }
43
            }
44
            Rewriter::Innermost => {
45
                let mut inner = InnermostRewriter::new(spec);
46

            
47
                for term in syntax_terms {
48
                    let term = to_untyped_data_expression(term.clone(), None);
49
                    let result = inner.rewrite(&term);
50
                    if output {
51
                        println!("{}", result)
52
                    }
53
                }
54
            }
55
            Rewriter::Sabre => {
56
                let mut sa = SabreRewriter::new(spec);
57

            
58
                for term in syntax_terms {
59
                    let term = to_untyped_data_expression(term.clone(), None);
60
                    let result = sa.rewrite(&term);
61
                    if output {
62
                        println!("{}", result)
63
                    }
64
                }
65
            }
66
        }
67

            
68
        Ok(())
69
    })
70
}