dpscript/dpscript/validator/helpers/
ast.rs

1use super::ModuleExport;
2use crate::{CheckerContext, Result, AST};
3use std::collections::BTreeMap;
4
5impl AST {
6    pub fn cache_values(&mut self) -> Result<()> {
7        if self.cached {
8            return Ok(());
9        }
10
11        self.indexed = false;
12
13        self.index()?;
14        self.export_nodes()?; // Cache export nodes
15
16        let cx = self.create_checker_context()?;
17
18        for node in &mut self.nodes {
19            node.cache(&cx)?;
20        }
21
22        self.indexed = false;
23
24        // Re-run everything with the new set of nodes
25        self.index()?;
26        self.export_nodes()?;
27
28        let cx = self.create_checker_context()?;
29
30        for node in &mut self.nodes {
31            node.cache(&cx)?;
32        }
33
34        self.cached = true;
35
36        Ok(())
37    }
38
39    pub fn create_checker_context(&mut self) -> Result<CheckerContext> {
40        let ast = self.index()?.clone();
41        let modules = ast.modules.unwrap();
42        let imports = ast.imports.unwrap();
43        let funcs = ast.funcs.unwrap();
44        let vars = ast.vars.unwrap();
45        let blocks = ast.blocks.unwrap();
46        let enums = ast.enums.unwrap();
47        let objectives = ast.objectives.unwrap();
48        let exports = ast.exports.unwrap();
49
50        Ok(CheckerContext {
51            modules: modules.clone(),
52            imports,
53            funcs,
54            vars,
55            blocks,
56            enums,
57            objectives,
58            exports,
59
60            // State
61            cur_fn: None,
62            cur_block: None,
63            cur_conds: Vec::new(),
64            cur_elses: Vec::new(),
65            cur_loops: Vec::new(),
66            cur_modules: Vec::new(),
67            cur_subroutines: Vec::new(),
68        })
69    }
70
71    pub fn export_nodes(&mut self) -> Result<BTreeMap<String, Vec<ModuleExport>>> {
72        if let Some(nodes) = &self.export_nodes {
73            return Ok(nodes.clone());
74        }
75
76        let cx = self.create_checker_context()?;
77        let mut map = BTreeMap::new();
78
79        if let Some(modules) = &self.modules {
80            for (name, module) in modules {
81                map.insert(name.clone(), module.get_exports(&cx)?);
82            }
83        }
84
85        self.export_nodes = Some(map.clone());
86
87        Ok(map)
88    }
89}