1
use std::fmt::Debug;
2
use std::path::Path;
3

            
4
use clap::ValueEnum;
5

            
6
use merc_data::to_untyped_data_expression;
7
use merc_rec_tests::load_rec_from_file;
8
use merc_sabre::InnermostRewriter;
9
use merc_sabre::NaiveRewriter;
10
use merc_sabre::RewriteEngine;
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
    filename_specification: &Path,
27
    output: bool,
28
    timing: &Timing,
29
) -> Result<(), MercError> {
30
    let (syntax_spec, syntax_terms) = load_rec_from_file(filename_specification)?;
31

            
32
    let spec = syntax_spec.to_rewrite_spec();
33

            
34
    timing.measure("rewrite_rec", || {
35
        match rewriter {
36
            Rewriter::Naive => {
37
                let mut inner = NaiveRewriter::new(&spec);
38

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

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

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

            
71
        Ok(())
72
    })
73
}