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, 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}
27
28impl Debug for Module {
29    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
30        writeln!(f, " {:?}", self.symbol_table)?;
31
32        if let Some(internal_main) = &self.main_expression {
33            pretty_print(f, &internal_main.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(symbol_table: SymbolTable, expression: Option<InternalMainExpression>) -> Self {
66        Self {
67            symbol_table,
68            main_expression: expression,
69        }
70    }
71}
72
73impl Modules {
74    pub fn new() -> Self {
75        Self {
76            modules: SeqMap::new(),
77        }
78    }
79
80    pub fn modules(&self) -> &SeqMap<Vec<String>, ModuleRef> {
81        &self.modules
82    }
83
84    #[must_use]
85    pub fn contains_key(&self, module_path: &[String]) -> bool {
86        self.modules.contains_key(&module_path.to_vec())
87    }
88
89    pub fn add(&mut self, module: ModuleRef) {
90        let path = module.symbol_table.module_path().clone();
91
92        self.modules.insert(path, module).expect("could not insert");
93    }
94
95    pub fn link_module(&mut self, module_path: &[String], referred_module: ModuleRef) {
96        self.modules
97            .insert(module_path.to_vec(), referred_module)
98            .expect("todo");
99    }
100
101    #[must_use]
102    pub fn get(&self, module_path: &[String]) -> Option<&ModuleRef> {
103        self.modules.get(&module_path.to_vec())
104    }
105}