Skip to main content

ssf/ir/
function_application.rs

1use super::expression::Expression;
2use super::variable::Variable;
3use crate::types::Type;
4use std::collections::{HashMap, HashSet};
5
6#[derive(Clone, Debug, PartialEq)]
7pub struct FunctionApplication {
8    function: Variable,
9    arguments: Vec<Expression>,
10}
11
12impl FunctionApplication {
13    pub fn new(function: Variable, arguments: Vec<Expression>) -> Self {
14        Self {
15            function,
16            arguments,
17        }
18    }
19
20    pub fn function(&self) -> &Variable {
21        &self.function
22    }
23
24    pub fn arguments(&self) -> &[Expression] {
25        &self.arguments
26    }
27
28    pub(crate) fn rename_variables(&self, names: &HashMap<String, String>) -> Self {
29        Self::new(
30            self.function.rename_variables(names),
31            self.arguments
32                .iter()
33                .map(|argument| argument.rename_variables(names))
34                .collect(),
35        )
36    }
37
38    pub(crate) fn find_variables(&self, excluded_variables: &HashSet<String>) -> HashSet<String> {
39        let mut variables = self.function.find_variables(excluded_variables);
40
41        for argument in &self.arguments {
42            variables.extend(argument.find_variables(excluded_variables));
43        }
44
45        variables
46    }
47
48    pub(crate) fn infer_environment(
49        &self,
50        variables: &HashMap<String, Type>,
51        global_variables: &HashSet<String>,
52    ) -> Self {
53        Self::new(
54            self.function.clone(),
55            self.arguments
56                .iter()
57                .map(|argument| argument.infer_environment(variables, global_variables))
58                .collect(),
59        )
60    }
61
62    pub(crate) fn convert_types(&self, convert: &impl Fn(&Type) -> Type) -> Self {
63        Self {
64            function: self.function.clone(),
65            arguments: self
66                .arguments
67                .iter()
68                .map(|argument| argument.convert_types(convert))
69                .collect(),
70        }
71    }
72}