cortex_lang/preprocessing/ast/
function.rs

1use std::{collections::HashMap, rc::Rc};
2
3use crate::{interpreting::{env::Environment, error::CortexError, heap::Heap, value::CortexValue}, parsing::ast::expression::PathIdent, preprocessing::module::ModuleError};
4
5use super::{expression::RExpression, statement::RStatement};
6
7pub enum RBody {
8    Native(Box<dyn Fn(&Environment, &mut Heap) -> Result<CortexValue, CortexError>>),
9    Interpreted(RInterpretedBody),
10}
11
12pub struct RInterpretedBody {
13    pub(crate) statements: Vec<RStatement>,
14    pub(crate) result: Option<RExpression>,
15}
16impl RInterpretedBody {
17    pub(crate) fn new(statements: Vec<RStatement>, result: Option<RExpression>) -> Self {
18        RInterpretedBody {
19            statements,
20            result,
21        }
22    }
23}
24
25pub struct RFunction {
26    pub(crate) params: Vec<String>,
27    pub(crate) body: RBody,
28}
29impl RFunction {
30    pub(crate) fn new(params: Vec<String>, body: RBody) -> Self {
31        RFunction {
32            params,
33            body,
34        }
35    }
36}
37
38pub struct FunctionDict {
39    all_functions: HashMap<PathIdent, Rc<RFunction>>,
40    name_to_id: HashMap<PathIdent, usize>,
41    id_to_name: HashMap<usize, PathIdent>,
42    next_id: usize,
43}
44impl FunctionDict {
45    pub fn new() -> Self {
46        Self {
47            all_functions: HashMap::new(),
48            name_to_id: HashMap::new(),
49            id_to_name: HashMap::new(),
50            next_id: 0,
51        }
52    }
53
54    pub(crate) fn add_function(&mut self, name: PathIdent, function: RFunction) {
55        self.all_functions.insert(name, Rc::new(function));
56    }
57    pub(crate) fn add_call(&mut self, name: PathIdent) -> Result<usize, ModuleError> {
58        if let Some(id) = self.name_to_id.get(&name) {
59            Ok(*id)
60        } else {
61            self.name_to_id.insert(name.clone(), self.next_id);
62            self.id_to_name.insert(self.next_id, name);
63            let result = self.next_id;
64            self.next_id += 1;
65            Ok(result)
66        }
67    }
68
69    pub(crate) fn get(&self, id: usize) -> Option<&Rc<RFunction>> {
70        let name = self.id_to_name.get(&id)?;
71        let func = self.all_functions.get(name)?;
72        Some(func)
73    }
74}