swamp_script_semantic/
modules.rs1use crate::ns::Namespace;
7use crate::ns::NamespacePath;
8use crate::symtbl::SymbolTable;
9use crate::{Expression, ExpressionKind};
10use seq_map::SeqMap;
11use std::fmt::{Debug, Formatter};
12use std::rc::Rc;
13
14#[derive(Debug)]
15pub struct Modules {
16 modules: SeqMap<Vec<String>, ModuleRef>,
17}
18
19impl Default for Modules {
20 fn default() -> Self {
21 Self::new()
22 }
23}
24
25pub struct Module {
26 pub namespace: Namespace,
27 pub expression: Option<Expression>,
28}
29
30impl Debug for Module {
31 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
32 if let Some(resolved_expression) = &self.expression {
33 pretty_print(f, resolved_expression, 0)?;
34 }
35
36 Ok(())
37 }
38}
39
40pub fn pretty_print(
43 f: &mut Formatter<'_>,
44 resolved_expression: &Expression,
45 tabs: usize,
46) -> std::fmt::Result {
47 if let ExpressionKind::Block(expressions) = &resolved_expression.kind {
48 for internal_expr in expressions {
49 pretty_print(f, internal_expr, tabs + 1)?;
50 }
51 Ok(())
52 } else {
53 let tab_str = "..".repeat(tabs);
54 writeln!(
55 f,
56 "{}{},{:?}",
57 tab_str, resolved_expression.ty, resolved_expression.kind
58 )
59 }
60}
61
62pub type ModuleRef = Rc<Module>;
63
64impl Module {
65 pub fn new(
66 module_path: &[String],
67 symbol_table: SymbolTable,
68 expression: Option<Expression>,
69 ) -> Self {
70 Self {
71 namespace: Namespace::new(NamespacePath::from(module_path), symbol_table),
72 expression,
73 }
74 }
75}
76
77impl Modules {
78 pub fn new() -> Self {
79 Self {
80 modules: SeqMap::new(),
81 }
82 }
83
84 pub fn modules(&self) -> &SeqMap<Vec<String>, ModuleRef> {
85 &self.modules
86 }
87
88 #[must_use]
89 pub fn contains_key(&self, module_path: &[String]) -> bool {
90 self.modules.contains_key(&module_path.to_vec())
91 }
92
93 pub fn add(&mut self, module: ModuleRef) {
94 let path = module.clone().namespace.path.clone();
95
96 self.modules.insert(path, module).expect("could not insert");
97 }
98
99 pub fn link_module(&mut self, module_path: &[String], referred_module: ModuleRef) {
100 self.modules
101 .insert(module_path.to_vec(), referred_module)
102 .expect("todo");
103 }
104
105 #[must_use]
106 pub fn get(&self, module_path: &[String]) -> Option<&ModuleRef> {
107 self.modules.get(&module_path.to_vec())
108 }
109}