swamp_script_semantic/
modules.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/script
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5
6use 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
40/// # Errors
41///
42pub 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}