cortex_lang/preprocessing/ast/
function.rs

1use std::{collections::HashMap, rc::Rc};
2
3use crate::{interpreting::{env::Environment, error::CortexError, heap::Heap, value::CortexValue}, preprocessing::module::ModuleError};
4
5use super::{expression::RExpression, function_address::FunctionAddress, 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    pub fn num_params(&self) -> usize {
38        self.params.len()
39    }
40    pub fn get_param(&self, index: usize) -> Option<&String> {
41        self.params.get(index)
42    }
43}
44
45pub struct FunctionDict {
46    all_functions: HashMap<FunctionAddress, Rc<RFunction>>,
47    name_to_id: HashMap<FunctionAddress, usize>,
48    id_to_name: HashMap<usize, FunctionAddress>,
49    next_id: usize,
50}
51impl FunctionDict {
52    pub fn new() -> Self {
53        Self {
54            all_functions: HashMap::new(),
55            name_to_id: HashMap::new(),
56            id_to_name: HashMap::new(),
57            next_id: 0,
58        }
59    }
60
61    pub(crate) fn add_function(&mut self, name: FunctionAddress, function: RFunction) {
62        self.all_functions.insert(name, Rc::new(function));
63    }
64    pub(crate) fn add_call(&mut self, name: FunctionAddress) -> Result<usize, ModuleError> {
65        if let Some(id) = self.name_to_id.get(&name) {
66            Ok(*id)
67        } else {
68            self.name_to_id.insert(name.clone(), self.next_id);
69            self.id_to_name.insert(self.next_id, name);
70            let result = self.next_id;
71            self.next_id += 1;
72            Ok(result)
73        }
74    }
75
76    pub(crate) fn get(&self, id: usize) -> Option<&Rc<RFunction>> {
77        let name = self.id_to_name.get(&id)?;
78        let func = self.all_functions.get(name)?;
79        Some(func)
80    }
81}