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        for (idx, selector) in stmt.selectors.iter().enumerate() {
27            let program = vm::compile_selector(&mut vm, selector)?;
28            while output.n_succ < n_trails {
29                if output.n_fail == n_trails {
30                    // TODO: fix this
31                    return Err(((0, 1), VmError::SamplingFailed).into());
32                }
33
34                match vm.sample(&mut rng) {
35                    Some(()) => {
36                        if let Some(wp) = &where_program {
37                            let keep = matches!(
38                                wp.execute(&mut vm.as_context())?,
39                                VmStackValue::Bool(true)
40                            );
41
42                            if !keep {
43                                //TODO: refine this
44                                output.n_fail += 1;
45                                continue;
46                            }
47                        }
48
49                        output.push_value(
50                            idx,
51                            program.execute(&mut vm.as_context())?,
52                        );
53                        output.n_succ += 1;
54                    }
55                    None => output.n_fail += 1,
56                }
57            }
58        }
59
60        Ok(output)
61    }
62
63    // tmp function
64    pub fn run<S: io::Write, T: io::Write>(
65        src: &str,
66        stream_out: &mut S,
67        stream_err: &mut T,
68    ) -> io::Result<()> {
69        match parse_pql(src) {
70            Ok(stmts) => {
71                for (i, stmt) in stmts.iter().enumerate() {
72                    if i > 0 {
73                        writeln!(stream_out, "{:-<80}", "")?;
74                    }
75
76                    match Self::try_run_stmt(stmt) {
77                        Ok(output) => {
78                            output.report_to_stream(stmt, stream_out)?;
79                            writeln!(stream_out, "{} trials", output.n_succ)?;
80                        }
81                        Err(err) => {
82                            writeln!(
83                                stream_err,
84                                "{err:?} {}",
85                                &src[err.loc.0..err.loc.1]
86                            )?;
87                        }
88                    }
89                }
90            }
91            Err(err) => writeln!(stream_err, "{err:?}")?,
92        }
93        Ok(())
94    }
95}