swamp_modules/
modules.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/swamp
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5use crate::symtbl::DefinitionTable;
6use seq_map::SeqMap;
7use source_map_node::FileId;
8use std::fmt::{Debug, Formatter};
9use std::rc::Rc;
10use swamp_semantic::prelude::Error;
11use swamp_semantic::{Expression, ExpressionKind, InternalMainExpression};
12
13#[derive(Debug)]
14pub struct Modules {
15    modules: SeqMap<Vec<String>, ModuleRef>,
16    file_id_to_module: SeqMap<FileId, ModuleRef>,
17}
18
19impl Default for Modules {
20    fn default() -> Self {
21        Self::new()
22    }
23}
24
25pub struct Module {
26    pub main_expression: Option<InternalMainExpression>,
27    pub definition_table: DefinitionTable,
28    pub file_id: FileId,
29    pub errors: Vec<Error>,
30}
31
32impl Debug for Module {
33    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
34        writeln!(f, " {:?}", self.definition_table)?;
35
36        if let Some(internal_main) = &self.main_expression {
37            pretty_print(f, &internal_main.expression, 0)?;
38        }
39
40        Ok(())
41    }
42}
43
44/// # Errors
45///
46pub fn pretty_print(
47    f: &mut Formatter<'_>,
48    resolved_expression: &Expression,
49    tabs: usize,
50) -> std::fmt::Result {
51    if let ExpressionKind::Block(expressions) = &resolved_expression.kind {
52        for internal_expr in expressions {
53            pretty_print(f, internal_expr, tabs + 1)?;
54        }
55        Ok(())
56    } else {
57        let tab_str = "..".repeat(tabs);
58        writeln!(
59            f,
60            "{}{},{:?}",
61            tab_str, resolved_expression.ty, resolved_expression.kind
62        )
63    }
64}
65
66pub type ModuleRef = Rc<Module>;
67
68impl Module {
69    #[must_use]
70    pub const fn new(
71        symbol_table: DefinitionTable,
72        errors: Vec<Error>,
73        expression: Option<InternalMainExpression>,
74        file_id: FileId,
75    ) -> Self {
76        Self {
77            definition_table: symbol_table,
78            file_id,
79            main_expression: expression,
80            errors,
81        }
82    }
83}
84
85impl Modules {
86    #[must_use]
87    pub fn new() -> Self {
88        Self {
89            modules: SeqMap::new(),
90            file_id_to_module: SeqMap::new(),
91        }
92    }
93
94    #[must_use]
95    pub const fn modules(&self) -> &SeqMap<Vec<String>, ModuleRef> {
96        &self.modules
97    }
98
99    #[must_use]
100    pub fn contains_key(&self, module_path: &[String]) -> bool {
101        self.modules.contains_key(&module_path.to_vec())
102    }
103
104    pub fn add(&mut self, module: ModuleRef) {
105        let path = module.definition_table.module_path();
106
107        self.modules
108            .insert(path, module.clone())
109            .expect("could not insert");
110        self.file_id_to_module
111            .insert(module.file_id, module.clone());
112    }
113
114    pub fn link_module(&mut self, module_path: &[String], referred_module: ModuleRef) {
115        self.modules
116            .insert(module_path.to_vec(), referred_module.clone())
117            .expect("could not insert");
118        self.file_id_to_module
119            .insert(referred_module.file_id, referred_module)
120            .expect("could not insert");
121    }
122
123    #[must_use]
124    pub fn get(&self, module_path: &[String]) -> Option<&ModuleRef> {
125        self.modules.get(&module_path.to_vec())
126    }
127
128    #[must_use]
129    pub fn get_from_file_id(&self, file_id: FileId) -> Option<&ModuleRef> {
130        self.file_id_to_module.get(&file_id)
131    }
132}