grit_pattern_matcher/pattern/
or.rs1use super::{
2 ast_node_pattern::AstNodePattern,
3 functions::{Evaluator, FuncEvaluation},
4 patterns::{Matcher, Pattern, PatternName},
5 predicates::Predicate,
6 resolved_pattern::ResolvedPattern,
7 State,
8};
9use crate::{binding::Binding, context::QueryContext};
10use core::fmt::Debug;
11use grit_util::{error::GritResult, AnalysisLogs};
12
13#[derive(Debug, Clone)]
14pub struct Or<Q: QueryContext> {
15 pub patterns: Vec<Pattern<Q>>,
16}
17
18impl<Q: QueryContext> Or<Q> {
19 pub fn new(patterns: Vec<Pattern<Q>>) -> Self {
20 Self { patterns }
21 }
22}
23
24impl<Q: QueryContext> PatternName for Or<Q> {
25 fn name(&self) -> &'static str {
26 "OR"
27 }
28}
29
30impl<Q: QueryContext> Matcher<Q> for Or<Q> {
31 fn execute<'a>(
32 &'a self,
33 resolved: &Q::ResolvedPattern<'a>,
34 init_state: &mut State<'a, Q>,
35 context: &'a Q::ExecContext<'a>,
36 logs: &mut AnalysisLogs,
37 ) -> GritResult<bool> {
38 if let Some(binding) = resolved.get_last_binding() {
39 for p in self.patterns.iter() {
40 if let (Some(binding_node), Pattern::AstNode(node_pattern)) = (binding.as_node(), p)
42 {
43 if !node_pattern.matches_kind_of(&binding_node) {
44 continue;
45 }
46 }
47 let mut state = init_state.clone();
48 let res = p.execute(resolved, &mut state, context, logs)?;
49 if res {
50 *init_state = state;
51 return Ok(true);
52 }
53 }
54 } else {
55 for p in self.patterns.iter() {
56 let mut state = init_state.clone();
57 let res = p.execute(resolved, &mut state, context, logs)?;
58 if res {
59 *init_state = state;
60 return Ok(true);
61 }
62 }
63 };
64 Ok(false)
65 }
66}
67
68#[derive(Debug, Clone)]
69pub struct PrOr<Q: QueryContext> {
70 pub predicates: Vec<Predicate<Q>>,
71}
72
73impl<Q: QueryContext> PrOr<Q> {
74 pub fn new(predicates: Vec<Predicate<Q>>) -> Self {
75 Self { predicates }
76 }
77}
78
79impl<Q: QueryContext> PatternName for PrOr<Q> {
80 fn name(&self) -> &'static str {
81 "PREDICATE_OR"
82 }
83}
84
85impl<Q: QueryContext> Evaluator<Q> for PrOr<Q> {
86 fn execute_func<'a>(
87 &'a self,
88 init_state: &mut State<'a, Q>,
89 context: &'a Q::ExecContext<'a>,
90 logs: &mut AnalysisLogs,
91 ) -> GritResult<FuncEvaluation<Q>> {
92 for p in self.predicates.iter() {
93 let mut state = init_state.clone();
94 let res = p.execute_func(&mut state, context, logs)?;
95 if res.predicator || res.ret_val.is_some() {
96 *init_state = state;
97 return Ok(res);
98 }
99 }
100 Ok(FuncEvaluation {
101 predicator: false,
102 ret_val: None,
103 })
104 }
105}