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