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