grit_pattern_matcher/pattern/
call.rs

1use super::{
2    function_definition::FunctionDefinition,
3    functions::{Evaluator, FuncEvaluation},
4    patterns::Matcher,
5    patterns::{Pattern, PatternName},
6    State,
7};
8use crate::{context::ExecContext, context::QueryContext};
9use grit_util::{
10    error::{GritPatternError, GritResult},
11    AnalysisLogs,
12};
13
14#[derive(Clone, Debug)]
15pub struct Call<Q: QueryContext> {
16    pub index: usize,
17    pub args: Vec<Option<Pattern<Q>>>,
18}
19
20impl<Q: QueryContext> Call<Q> {
21    pub fn new(index: usize, args: Vec<Option<Pattern<Q>>>) -> Self {
22        Self { index, args }
23    }
24}
25
26impl<Q: QueryContext> PatternName for Call<Q> {
27    fn name(&self) -> &'static str {
28        "CALL"
29    }
30}
31
32// todo parameters, and name should both be usize references
33// argument should throw an error if its not a parameter at compile time
34impl<Q: QueryContext> Matcher<Q> for Call<Q> {
35    fn execute<'a>(
36        &'a self,
37        binding: &Q::ResolvedPattern<'a>,
38        state: &mut State<'a, Q>,
39        context: &'a Q::ExecContext<'a>,
40        logs: &mut AnalysisLogs,
41    ) -> GritResult<bool> {
42        let pattern_definition = &context.pattern_definitions()[self.index];
43
44        pattern_definition.call(state, binding, context, logs, &self.args)
45    }
46}
47
48#[derive(Debug, Clone)]
49pub struct PrCall<Q: QueryContext> {
50    pub(crate) index: usize,
51    pub args: Vec<Option<Pattern<Q>>>,
52}
53
54impl<Q: QueryContext> PrCall<Q> {
55    pub fn new(index: usize, args: Vec<Option<Pattern<Q>>>) -> Self {
56        Self { index, args }
57    }
58}
59
60impl<Q: QueryContext> PatternName for PrCall<Q> {
61    fn name(&self) -> &'static str {
62        "PREDICATE_CALL"
63    }
64}
65
66impl<Q: QueryContext> Evaluator<Q> for PrCall<Q> {
67    fn execute_func<'a>(
68        &'a self,
69        state: &mut State<'a, Q>,
70        context: &'a Q::ExecContext<'a>,
71        logs: &mut AnalysisLogs,
72    ) -> GritResult<FuncEvaluation<Q>> {
73        let predicate_definition = &context.predicate_definitions().get(self.index);
74        if let Some(predicate_definition) = predicate_definition {
75            let predicator = predicate_definition.call(state, context, &self.args, logs)?;
76            Ok(FuncEvaluation {
77                predicator,
78                ret_val: None,
79            })
80        } else {
81            let function_definition = &context.function_definitions().get(self.index);
82            if let Some(function_definition) = function_definition {
83                let res = function_definition.call(state, context, &self.args, logs)?;
84                Ok(res)
85            } else {
86                Err(GritPatternError::new(format!(
87                    "predicate or function definition not found: {}. Try running grit init.",
88                    self.index
89                )))
90            }
91        }
92    }
93}