grit_pattern_matcher/pattern/
if.rs1use 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}