grit_pattern_matcher/pattern/
functions.rs1use super::{
2 function_definition::FunctionDefinition,
3 patterns::{Pattern, PatternName},
4 state::State,
5};
6use crate::{context::ExecContext, context::QueryContext};
7use core::fmt::Debug;
8use grit_util::{
9 error::{GritPatternError, GritResult},
10 AnalysisLogs,
11};
12
13#[derive(Debug, Clone)]
14pub struct FuncEvaluation<'a, Q: QueryContext> {
15 pub predicator: bool,
16 pub ret_val: Option<Q::ResolvedPattern<'a>>,
17}
18
19pub trait Evaluator<Q: QueryContext>: Debug {
20 fn execute_func<'a>(
21 &'a self,
22 state: &mut State<'a, Q>,
23 context: &'a Q::ExecContext<'a>,
24 logs: &mut AnalysisLogs,
25 ) -> GritResult<FuncEvaluation<Q>>;
26}
27
28#[derive(Debug, Clone)]
29pub struct CallFunction<Q: QueryContext> {
30 pub index: usize,
31 pub args: Vec<Option<Pattern<Q>>>,
32}
33
34pub trait GritCall<Q: QueryContext> {
35 fn call<'a>(
36 &'a self,
37 state: &mut State<'a, Q>,
38 context: &'a Q::ExecContext<'a>,
39 logs: &mut AnalysisLogs,
40 ) -> GritResult<Q::ResolvedPattern<'a>>;
41}
42
43impl<Q: QueryContext> CallFunction<Q> {
44 pub fn new(index: usize, args: Vec<Option<Pattern<Q>>>) -> Self {
45 Self { index, args }
46 }
47}
48
49impl<Q: QueryContext> GritCall<Q> for CallFunction<Q> {
50 fn call<'a>(
51 &'a self,
52 state: &mut State<'a, Q>,
53 context: &'a Q::ExecContext<'a>,
54 logs: &mut AnalysisLogs,
55 ) -> GritResult<Q::ResolvedPattern<'a>> {
56 let function_definition = &context.function_definitions()[self.index];
57
58 match function_definition
59 .call(state, context, &self.args, logs)?
60 .ret_val
61 {
62 Some(pattern) => Ok(pattern),
63 None => Err(GritPatternError::new(
64 "Function call did not return a value",
65 )),
66 }
67 }
68}
69
70impl<Q: QueryContext> PatternName for CallFunction<Q> {
71 fn name(&self) -> &'static str {
72 "CALL_FUNCTION"
73 }
74}
75
76#[derive(Debug, Clone)]
77pub struct CallForeignFunction<Q: QueryContext> {
78 pub index: usize,
79 pub args: Vec<Option<Pattern<Q>>>,
80}
81
82impl<Q: QueryContext> CallForeignFunction<Q> {
83 pub fn new(index: usize, args: Vec<Option<Pattern<Q>>>) -> Self {
84 Self { index, args }
85 }
86}
87
88impl<Q: QueryContext> PatternName for CallForeignFunction<Q> {
89 fn name(&self) -> &'static str {
90 "CALL_FUNCTION"
91 }
92}