Skip to main content

opql/
runner.rs

1// TODO: remove!; tmp implementation
2#![cfg_attr(coverage_nightly, coverage(off))]
3
4use super::*;
5
6pub struct PQLRunner {}
7
8impl PQLRunner {
9    // TODO: check max selectors
10    // TODO: refactor run logic
11    // TODO: remove
12    #[allow(clippy::missing_panics_doc)]
13    pub fn try_run_stmt(stmt: &ast::Stmt<'_>) -> PQLResult<RunnerOutput> {
14        let mut rng = rand::rng();
15        let mut vm = Vm::from_stmt(stmt)?;
16        let n_trails = vm.static_data.n_trails;
17        let game = vm.static_data.game;
18
19        let mut output = RunnerOutput::new(game, &stmt.selectors);
20
21        let where_program = match &stmt.where_clause {
22            Some(expr) => Some(vm::compile_where(&mut vm, expr)?),
23            None => None,
24        };
25
26        let programs = stmt
27            .selectors
28            .iter()
29            .map(|s| vm::compile_selector(&mut vm, s))
30            .collect::<PQLResult<Vec<_>>>()?;
31
32        while output.n_succ < n_trails {
33            if output.n_fail == n_trails {
34                // TODO: fix this
35                return Err(((0, 1), VmError::SamplingFailed).into());
36            }
37
38            match vm.sample(&mut rng) {
39                Some(()) => {
40                    if let Some(wp) = &where_program {
41                        let keep = matches!(
42                            wp.execute(&mut vm.as_context())?,
43                            VmStackValue::Bool(true)
44                        );
45
46                        if !keep {
47                            //TODO: refine this
48                            output.n_fail += 1;
49                            continue;
50                        }
51                    }
52
53                    for (idx, program) in programs.iter().enumerate() {
54                        output.push_value(
55                            idx,
56                            program.execute(&mut vm.as_context())?,
57                        );
58                    }
59                    output.n_succ += 1;
60                }
61                None => output.n_fail += 1,
62            }
63        }
64
65        Ok(output)
66    }
67
68    // tmp function
69    pub fn run<S: io::Write, T: io::Write>(
70        src: &str,
71        stream_out: &mut S,
72        stream_err: &mut T,
73    ) -> io::Result<()> {
74        match parse_pql(src) {
75            Ok(stmts) => {
76                for (i, stmt) in stmts.iter().enumerate() {
77                    if i > 0 {
78                        writeln!(stream_out, "{:-<80}", "")?;
79                    }
80
81                    match Self::try_run_stmt(stmt) {
82                        Ok(output) => {
83                            output.report_to_stream(stmt, stream_out)?;
84                            writeln!(stream_out, "{} trials", output.n_succ)?;
85                        }
86                        Err(err) => {
87                            writeln!(
88                                stream_err,
89                                "{err:?} {}",
90                                &src[err.loc.0..err.loc.1]
91                            )?;
92                        }
93                    }
94                }
95            }
96            Err(err) => writeln!(stream_err, "{err:?}")?,
97        }
98        Ok(())
99    }
100}