grit_pattern_matcher/pattern/
if.rs

1use super::{
2    functions::{Evaluator, FuncEvaluation},
3    patterns::{Matcher, Pattern, PatternName},
4    predicates::Predicate,
5    State,
6};
7use crate::context::QueryContext;
8use core::fmt::Debug;
9use grit_util::{
10    error::{GritPatternError, GritResult},
11    AnalysisLogs,
12};
13
14#[derive(Debug, Clone)]
15pub struct If<Q: QueryContext> {
16    pub if_: Predicate<Q>,
17    pub then: Pattern<Q>,
18    pub else_: Pattern<Q>,
19}
20impl<Q: QueryContext> If<Q> {
21    pub fn new(if_: Predicate<Q>, then: Pattern<Q>, else_: Option<Pattern<Q>>) -> Self {
22        Self {
23            if_,
24            then,
25            else_: else_.unwrap_or(Pattern::Top),
26        }
27    }
28}
29
30impl<Q: QueryContext> PatternName for If<Q> {
31    fn name(&self) -> &'static str {
32        "IF"
33    }
34}
35
36impl<Q: QueryContext> Matcher<Q> for If<Q> {
37    fn execute<'a>(
38        &'a self,
39        binding: &Q::ResolvedPattern<'a>,
40        init_state: &mut State<'a, Q>,
41        context: &'a Q::ExecContext<'a>,
42        logs: &mut AnalysisLogs,
43    ) -> GritResult<bool> {
44        let mut state = init_state.clone();
45        if self.if_.execute_func(&mut state, context, logs)?.predicator {
46            *init_state = state;
47            self.then.execute(binding, init_state, context, logs)
48        } else {
49            self.else_.execute(binding, init_state, context, logs)
50        }
51    }
52}
53
54#[derive(Debug, Clone)]
55pub struct PrIf<Q: QueryContext> {
56    pub if_: Predicate<Q>,
57    pub then: Predicate<Q>,
58    pub else_: Predicate<Q>,
59}
60
61impl<Q: QueryContext> PrIf<Q> {
62    pub fn new(if_: Predicate<Q>, then: Predicate<Q>, else_: Option<Predicate<Q>>) -> Self {
63        Self {
64            if_,
65            then,
66            else_: else_.unwrap_or(Predicate::True),
67        }
68    }
69}
70
71impl<Q: QueryContext> PatternName for PrIf<Q> {
72    fn name(&self) -> &'static str {
73        "PREDICATE_IF"
74    }
75}
76
77impl<Q: QueryContext> Evaluator<Q> for PrIf<Q> {
78    fn execute_func<'a>(
79        &'a self,
80        init_state: &mut State<'a, Q>,
81        context: &'a Q::ExecContext<'a>,
82        logs: &mut AnalysisLogs,
83    ) -> GritResult<FuncEvaluation<Q>> {
84        let mut state = init_state.clone();
85        let condition = self.if_.execute_func(&mut state, context, logs)?;
86        if condition.ret_val.is_some() {
87            return Err(GritPatternError::new(
88                "Cannot return from within if condition",
89            ));
90        }
91        if condition.predicator {
92            *init_state = state;
93            self.then.execute_func(init_state, context, logs)
94        } else {
95            self.else_.execute_func(init_state, context, logs)
96        }
97    }
98}