pipeline_script/postprocessor/
module_merger.rs

1use crate::ast::data::Data;
2use crate::ast::NodeTrait;
3use crate::postprocessor::{Stage, VisitResult, Visitor};
4use std::cell::RefCell;
5use std::rc::Rc;
6
7pub struct ModuleMerger {
8    global_variables: Rc<RefCell<Vec<String>>>,
9    local_variables: Rc<RefCell<Vec<String>>>,
10    module_name: Rc<RefCell<Option<String>>>,
11    module_functions: Rc<RefCell<Vec<String>>>,
12}
13
14impl ModuleMerger {
15    pub fn new() -> Self {
16        Self {
17            global_variables: Rc::new(RefCell::new(vec![])),
18            local_variables: Rc::new(RefCell::new(vec![])),
19            module_name: Rc::new(RefCell::new(None)),
20            module_functions: Rc::new(RefCell::new(vec![])),
21        }
22    }
23    pub fn is_module_function(&self, name: &str) -> bool {
24        self.module_functions.borrow().contains(&name.into())
25    }
26}
27
28impl Visitor for ModuleMerger {
29    fn stage(&self) -> Stage {
30        todo!()
31    }
32
33    fn match_id(&self, id: &str) -> bool {
34        [
35            "Module",
36            "Function",
37            "ValDecl",
38            "VarDecl",
39            "Expr:Variable",
40            "Expr:FnCall",
41        ]
42        .contains(&id)
43    }
44
45    fn visit(&self, node: &mut (impl NodeTrait + ?Sized)) -> VisitResult
46    where
47        Self: Sized,
48    {
49        let id = node.get_id();
50        match id {
51            "Module" => {
52                let data = node.get_data("global_variables").unwrap();
53                let global_variables = data.as_array().unwrap();
54                for i in global_variables {
55                    self.global_variables
56                        .borrow_mut()
57                        .push(i.as_str().unwrap().to_string());
58                }
59                let data = node.get_data("functions").unwrap();
60                let functions = data.as_array().unwrap();
61                for i in functions {
62                    self.module_functions
63                        .borrow_mut()
64                        .push(i.as_str().unwrap().to_string());
65                }
66                let name = node.get_data("name").unwrap();
67                self.module_name
68                    .borrow_mut()
69                    .replace(name.as_str().unwrap().to_string());
70            }
71            "ValDecl" => {
72                let name = node.get_data("name").unwrap();
73                let name = name.as_str().unwrap();
74                let module_name = self.module_name.borrow();
75                let module_name = module_name.as_ref().unwrap();
76                node.set_data("name", Data::String(format!("{}:{}", module_name, name)));
77            }
78            "VarDecl" => {
79                let name = node.get_data("name").unwrap();
80                let name = name.as_str().unwrap();
81                let module_name = self.module_name.borrow();
82                let module_name = module_name.as_ref().unwrap();
83                node.set_data("name", Data::String(format!("{}:{}", module_name, name)));
84            }
85            "Expr:Variable" => {
86                let name = node.get_data("name").unwrap();
87                let name = name.as_str().unwrap().to_string();
88                // 判断是否是全局block
89                if self.local_variables.borrow().contains(&name) {
90                    return VisitResult::Continue;
91                }
92                if !self.global_variables.borrow().contains(&name) {
93                    return VisitResult::Continue;
94                }
95                let module_name = self.module_name.borrow();
96                let module_name = module_name.as_ref().unwrap();
97                node.set_data("name", Data::String(format!("{}:{}", module_name, name)));
98            }
99            "Expr:FnCall" => {
100                let name = node.get_data("name").unwrap();
101                let name = name.as_str().unwrap();
102                if !self.is_module_function(name) {
103                    return VisitResult::Continue;
104                }
105                let module_name = self.module_name.borrow();
106                let module_name = module_name.as_ref().unwrap();
107                node.set_data("name", Data::String(format!("{}:{}", module_name, name)));
108            }
109            t => {
110                dbg!(t);
111            }
112        }
113        VisitResult::Continue
114    }
115}