cortex_lang/preprocessing/ast/
function_address.rs

1use crate::parsing::{ast::expression::{PathError, PathIdent}, codegen::r#trait::SimpleCodeGen};
2
3/// Represents an address/path to a function: so the key in a map to function signatures
4/// If an extension/member function, then target will be set to Some, and point to the calling type
5/// Otherwise, target will be None
6/// So example Geometry::Point has a getX function, it will have path = Geometry::getX and target = Geometry::Point
7/// Removes need for special paths such as "Point`getX"
8#[derive(PartialEq, Eq, Hash, Clone)]
9pub struct FunctionAddress {
10    pub(crate) own_module_path: PathIdent,
11    pub(crate) target: Option<PathIdent>,
12}
13impl FunctionAddress {
14    pub(crate) fn concat(prefix: &PathIdent, addr: &FunctionAddress) -> FunctionAddress {
15        FunctionAddress {
16            own_module_path: PathIdent::concat(prefix, &addr.own_module_path),
17            target: addr.target.as_ref().map(|t| PathIdent::concat(prefix, t)),
18        }
19    }
20    pub(crate) fn simple(path: PathIdent) -> FunctionAddress {
21        FunctionAddress {
22            own_module_path: path,
23            target: None,
24        }
25    }
26    pub(crate) fn member_func(path: PathIdent, target: PathIdent) -> FunctionAddress {
27        FunctionAddress {
28            own_module_path: path,
29            target: Some(target),
30        }
31    }
32
33    pub(crate) fn without_last(&self) -> PathIdent {
34        self.own_module_path.without_last()
35    }
36    pub(crate) fn get_back(self) -> Result<FunctionAddress, PathError> {
37        let prefix = self.own_module_path.without_last();
38        Ok(
39            FunctionAddress {
40                own_module_path: PathIdent::simple(self.own_module_path.get_back()?.clone()),
41                target: self.target.map(|t| Ok(t.subtract(&prefix)?)).transpose()?,
42            }
43        )
44    }
45}
46impl SimpleCodeGen for FunctionAddress {
47    fn codegen(&self, indent: usize) -> String {
48        if let Some(target) = &self.target {
49            format!("{} (on type {})", self.own_module_path.codegen(indent), target.codegen(indent))
50        } else {
51            self.own_module_path.codegen(indent)
52        }
53    }
54}