pipeline_script/ast/
module.rs

1use std::any::Any;
2
3use crate::ast::class::Class;
4use crate::ast::function::Function;
5use crate::ast::r#struct::Struct;
6use crate::ast::stmt::StmtNode;
7use std::collections::HashMap;
8
9use crate::ast::data::Data;
10use crate::ast::NodeTrait;
11use crate::context::Context;
12use crate::postprocessor::module_merger::ModuleMerger;
13use crate::postprocessor::run_visitor;
14use slotmap::DefaultKey;
15
16use crate::ast::type_alias::TypeAlias;
17
18#[derive(Clone, Debug)]
19pub struct Module {
20    name: String,
21    functions: HashMap<String, Function>,
22    classes: HashMap<String, Class>,
23    structs: HashMap<String, Struct>,
24    global_block: Vec<StmtNode>,
25    submodules: HashMap<String, DefaultKey>,
26    type_aliases: HashMap<String, TypeAlias>,
27}
28impl NodeTrait for Module {
29    fn get_id(&self) -> &str {
30        "Module"
31    }
32
33    fn get_data(&self, key: &str) -> Option<Data> {
34        match key {
35            "global_variables" => {
36                let mut global_variables = vec![];
37                for stmt in self.global_block.iter().filter(|e| e.is_val_decl()) {
38                    let name = stmt.get_data("name").unwrap();
39                    global_variables.push(name)
40                }
41                Some(Data::Array(global_variables))
42            }
43            "functions" => {
44                let mut functions = vec![];
45                for (name, _) in self.functions.iter() {
46                    functions.push(Data::String(name.clone()))
47                }
48                for i in self.global_block.iter().filter(|e| {
49                    if !e.is_val_decl() {
50                        return false;
51                    }
52                    e.is_val_decl()
53                }) {
54                    let name = i.get_data("name").unwrap();
55                    let name = name.as_str().unwrap();
56                    functions.push(Data::String(name.to_string()))
57                }
58                Some(Data::Array(functions))
59            }
60            "name" => Some(Data::String(self.name.clone())),
61            _ => None,
62        }
63    }
64
65    fn set_data(&mut self, _: &str, _: Data) {
66        todo!()
67    }
68
69    fn get_children(&self) -> Vec<&dyn NodeTrait> {
70        todo!()
71    }
72
73    fn get_mut_children(&mut self) -> Vec<&mut dyn NodeTrait> {
74        let mut r = vec![];
75        for f in self.functions.values_mut() {
76            r.push(f as &mut dyn NodeTrait)
77        }
78        for stmt in self.global_block.iter_mut() {
79            r.push(stmt as &mut dyn NodeTrait)
80        }
81        r
82    }
83
84    fn get_extra(&self) -> &HashMap<String, Box<dyn Any>> {
85        todo!()
86    }
87}
88impl Module {
89    pub fn new(name: impl Into<String>) -> Self {
90        Self {
91            name: name.into(),
92            functions: HashMap::new(),
93            classes: HashMap::new(),
94            structs: Default::default(),
95            submodules: HashMap::new(),
96            global_block: vec![],
97            type_aliases: HashMap::new(),
98        }
99    }
100    pub fn register_struct(&mut self, name: &str, s: Struct) {
101        self.structs.insert(name.into(), s);
102    }
103    pub fn get_structs(&self) -> &HashMap<String, Struct> {
104        &self.structs
105    }
106    pub fn get_struct(&self, name: &str) -> Option<&Struct> {
107        self.structs.get(name)
108    }
109    pub fn add_stmt(&mut self, stmt: StmtNode) {
110        self.global_block.push(stmt)
111    }
112
113    pub fn get_class(&self, class_name: &str) -> Option<&Class> {
114        self.classes.get(class_name)
115    }
116    pub fn get_functions(&self) -> HashMap<String, Function> {
117        self.functions.clone()
118    }
119    pub fn get_submodules(&self) -> &HashMap<String, DefaultKey> {
120        &self.submodules
121    }
122    pub fn get_mut_functions(&mut self) -> &mut HashMap<String, Function> {
123        &mut self.functions
124    }
125    pub fn register_function(&mut self, name: &str, f: Function) {
126        self.functions.insert(name.into(), f);
127    }
128    pub fn push_block(&mut self, block: Vec<StmtNode>) {
129        block.into_iter().for_each(|e| self.global_block.push(e))
130    }
131
132    pub fn get_global_block(&self) -> &Vec<StmtNode> {
133        &self.global_block
134    }
135    pub fn get_classes(&self) -> &HashMap<String, Class> {
136        &self.classes
137    }
138    pub fn get_class_function(&self, class_name: &str, function_name: &str) -> Option<Function> {
139        let class_result = self.classes.get(class_name);
140        match class_result {
141            None => None,
142            Some(class) => {
143                let function_result = class.methods.get(function_name);
144                function_result.cloned()
145            }
146        }
147    }
148    pub fn register_class_method(
149        &mut self,
150        class_name: impl AsRef<str>,
151        method_name: impl Into<String>,
152        method: Function,
153    ) {
154        let class_result = self.classes.get_mut(class_name.as_ref()).unwrap();
155        class_result.register_method(method_name.into(), method)
156    }
157    pub fn get_name(&self) -> String {
158        self.name.clone()
159    }
160    pub fn merge(&mut self, module: &Module) {
161        let merger = ModuleMerger::new();
162        let mut new_module = module.clone();
163        run_visitor(&mut new_module, &merger);
164        // Merge functions with namespace
165        let new_functions: HashMap<_, _> = module
166            .functions
167            .iter()
168            .filter_map(|(k, v)| {
169                let name = format!("{}:{}", module.name, k);
170                if !self.functions.contains_key(name.as_str()) {
171                    let mut new_function = v.clone();
172                    for stmt in new_function.mut_body() {
173                        if stmt.is_fn_call() {
174                            let name = stmt.get_fn_call_name().unwrap();
175                            if module.functions.contains_key(name.as_str()) {
176                                stmt.set_fn_call_name(format!("{}.{}", module.name, name));
177                            }
178                        }
179                    }
180                    new_function.set_name(name.clone());
181                    Some((name, new_function))
182                } else {
183                    None
184                }
185            })
186            .collect();
187
188        // Merge global block with namespace
189        let mut new_block = new_module.global_block.clone();
190        new_block.extend(self.global_block.clone());
191        self.global_block = new_block;
192        self.functions.extend(new_functions);
193    }
194    pub fn sort_global_block(&mut self) {
195        self.global_block
196            .sort_by(|a, b| a.position().pos.cmp(&b.position().pos));
197    }
198    pub fn get_submodule(&self, name: &str) -> &DefaultKey {
199        let m = self.submodules.get(name).unwrap();
200        m
201    }
202    pub fn merge_into_main(&mut self, ctx: &Context, name: &str) -> bool {
203        let m = self.submodules.get(name);
204        match m {
205            Some(m) => {
206                let module_slot_map = ctx.get_module_slot_map();
207                let module_slot_map = module_slot_map.read().unwrap();
208                let module = module_slot_map.get(*m).unwrap();
209                self.merge(module);
210                true
211            }
212            None => false,
213        }
214    }
215
216    pub fn register_submodule(&mut self, name: &str, module: DefaultKey) {
217        self.submodules.insert(name.into(), module);
218    }
219
220    pub fn get_function(&self, name: impl Into<String>) -> Option<Function> {
221        let r = self.functions.get(name.into().as_str());
222        r.cloned()
223    }
224    pub fn set_name(&mut self, name: impl Into<String>) {
225        self.name = name.into();
226    }
227    pub fn register_type_alias(
228        &mut self,
229        name: &str,
230        ty: crate::ast::r#type::Type,
231        generic_list: Vec<String>,
232    ) {
233        self.type_aliases
234            .insert(name.to_string(), TypeAlias::new(ty, generic_list));
235    }
236
237    pub fn get_type_alias(&self, name: &str) -> Option<&TypeAlias> {
238        self.type_aliases.get(name)
239    }
240
241    pub fn get_type_aliases(&self) -> &HashMap<String, TypeAlias> {
242        &self.type_aliases
243    }
244}