dpscript/dpscript/ast/
mod.rs1mod node;
2
3pub use node::*;
4
5use crate::{module_indexer_add, ModuleExport, Result};
6use serde::Serialize;
7use std::collections::BTreeMap;
8
9#[derive(Debug, Clone, Serialize)]
10pub struct AST {
11 pub nodes: Vec<Node>,
12 pub indexed: bool,
13 pub cached: bool,
14
15 #[serde(skip)]
17 pub modules: Option<BTreeMap<String, Module>>,
18
19 #[serde(skip)]
20 pub top_level: Option<BTreeMap<String, Vec<TopLevelNode>>>,
21
22 #[serde(skip)]
23 pub imports: Option<BTreeMap<String, Vec<Import>>>,
24
25 #[serde(skip)]
26 pub funcs: Option<BTreeMap<String, Vec<Function>>>,
27
28 #[serde(skip)]
29 pub vars: Option<BTreeMap<String, Vec<Variable>>>,
30
31 #[serde(skip)]
32 pub blocks: Option<BTreeMap<String, Vec<Block>>>,
33
34 #[serde(skip)]
35 pub enums: Option<BTreeMap<String, Vec<Enum>>>,
36
37 #[serde(skip)]
38 pub objectives: Option<BTreeMap<String, Vec<Objective>>>,
39
40 #[serde(skip)]
41 pub exports: Option<BTreeMap<String, Vec<Export>>>,
42
43 #[serde(skip)]
44 pub export_nodes: Option<BTreeMap<String, Vec<ModuleExport>>>, }
46
47impl AST {
48 pub fn merge(&mut self, other: AST) -> &mut Self {
49 self.nodes.extend(other.nodes);
50 self
51 }
52
53 pub fn collect_modules(&self) -> BTreeMap<String, Module> {
54 let mut modules: BTreeMap<String, Module> = BTreeMap::new();
55
56 for node in &self.nodes {
57 if let Node::Module(module) = node {
58 let name = module.name();
59
60 if let Some(it) = modules.get_mut(&name) {
61 it.body.extend(module.no_submodules());
62 } else {
63 modules.insert(name.clone(), module.with_no_submodules());
64 }
65
66 for (name, item) in module.collect_submodules(name) {
67 if let Some(it) = modules.get_mut(&name) {
68 it.body.extend(item.body);
69 } else {
70 modules.insert(name, item);
71 }
72 }
73 }
74 }
75
76 modules
77 }
78
79 pub fn index(&mut self) -> Result<&mut Self> {
80 if self.indexed {
81 return Ok(self);
82 }
83
84 let mut modules = self.collect_modules();
85
86 for (_, module) in &mut modules {
87 module.index_top_level_nodes()?;
88 }
89
90 self.modules = Some(modules.clone());
91
92 let mut top_level: BTreeMap<String, Vec<TopLevelNode>> = BTreeMap::new();
93 let mut imports: BTreeMap<String, Vec<Import>> = BTreeMap::new();
94 let mut funcs: BTreeMap<String, Vec<Function>> = BTreeMap::new();
95 let mut vars: BTreeMap<String, Vec<Variable>> = BTreeMap::new();
96 let mut blocks: BTreeMap<String, Vec<Block>> = BTreeMap::new();
97 let mut enums: BTreeMap<String, Vec<Enum>> = BTreeMap::new();
98 let mut objectives: BTreeMap<String, Vec<Objective>> = BTreeMap::new();
99 let mut exports: BTreeMap<String, Vec<Export>> = BTreeMap::new();
100
101 for (name, module) in modules {
102 module_indexer_add!(top_level += (name, module));
103 module_indexer_add!(imports += (name, module));
104 module_indexer_add!(funcs += (name, module));
105 module_indexer_add!(vars += (name, module));
106 module_indexer_add!(blocks += (name, module));
107 module_indexer_add!(enums += (name, module));
108 module_indexer_add!(objectives += (name, module));
109 module_indexer_add!(exports += (name, module));
110 }
111
112 self.top_level = Some(top_level);
113 self.imports = Some(imports);
114 self.funcs = Some(funcs);
115 self.vars = Some(vars);
116 self.blocks = Some(blocks);
117 self.enums = Some(enums);
118 self.objectives = Some(objectives);
119 self.exports = Some(exports);
120 self.indexed = true;
121
122 Ok(self)
123 }
124}