cortex_lang/preprocessing/ast/
function.rs1use 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}