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