From 3b3b21d4dcc15e5c0da5cd5e67fd250fe9014bdd Mon Sep 17 00:00:00 2001 From: sofia Date: Sun, 3 Aug 2025 22:32:31 +0300 Subject: [PATCH] Add possibility to pre-define module-ids --- examples/module_impoter.reid | 2 +- reid-lsp/src/analysis.rs | 2 -- reid-lsp/src/main.rs | 51 +++++++++++++++++++++++++++++++----- reid/src/error_raporting.rs | 48 +++++++++++++++++++++++++-------- reid/src/lib.rs | 11 +++++--- reid/src/mir/linker.rs | 10 +++++-- reid/tests/e2e.rs | 2 +- 7 files changed, 100 insertions(+), 26 deletions(-) diff --git a/examples/module_impoter.reid b/examples/module_impoter.reid index 1f8b0ba..f27b419 100644 --- a/examples/module_impoter.reid +++ b/examples/module_impoter.reid @@ -6,6 +6,6 @@ import module_importee::test; fn main() -> u32 { let value = 0b110; let other = 0o17; - + return value * other + test().field * -value; } \ No newline at end of file diff --git a/reid-lsp/src/analysis.rs b/reid-lsp/src/analysis.rs index 76833e6..bdd9ccc 100644 --- a/reid-lsp/src/analysis.rs +++ b/reid-lsp/src/analysis.rs @@ -69,8 +69,6 @@ impl StaticAnalysis { } } - dbg!(&references); - Some(references) } } diff --git a/reid-lsp/src/main.rs b/reid-lsp/src/main.rs index 5afb303..8ef42d5 100644 --- a/reid-lsp/src/main.rs +++ b/reid-lsp/src/main.rs @@ -6,6 +6,7 @@ use reid::ast::lexer::{FullToken, Position}; use reid::error_raporting::{self, ErrorModules, ReidError}; use reid::mir::SourceModuleId; use reid::parse_module; +use tokio::sync::Mutex; use tower_lsp::lsp_types::{ self, CompletionItem, CompletionOptions, CompletionParams, CompletionResponse, Diagnostic, DiagnosticSeverity, DidChangeTextDocumentParams, DidOpenTextDocumentParams, DocumentFilter, GotoDefinitionParams, @@ -26,6 +27,9 @@ mod analysis; struct Backend { client: Client, analysis: DashMap, + module_to_url: DashMap, + url_to_module: DashMap, + module_id_counter: Mutex, } #[tower_lsp::async_trait] @@ -116,7 +120,6 @@ impl LanguageServer for Backend { let list = if let Some((idx, _)) = token { if let Some(analysis) = self.analysis.get(&file_name).unwrap().state.map.get(&idx) { - dbg!(&analysis); analysis .autocomplete .iter() @@ -379,10 +382,32 @@ impl Backend { let path = PathBuf::from(params.uri.clone().path()); let file_name = path.file_name().unwrap().to_str().unwrap().to_owned(); - let mut map = Default::default(); - let parse_res = parse(¶ms.text, path.clone(), &mut map); + let mut map: ErrorModules = Default::default(); + for url_module in self.url_to_module.iter() { + let (url, module) = url_module.pair(); + map.add_module( + url.file_name().unwrap().to_str().unwrap().to_owned(), + Some(url.clone()), + Some(*module), + ); + } + + let module_id = if let Some(module_id) = self.url_to_module.get(&path) { + *module_id + } else { + let mut lock = self.module_id_counter.lock().await; + let module_id = lock.increment(); + drop(lock); + self.url_to_module.insert(path.clone(), module_id); + module_id + }; + + let parse_res = parse(¶ms.text, path.clone(), &mut map, module_id); let (tokens, result) = match parse_res { - Ok((module_id, tokens)) => (tokens.clone(), analyze(module_id, tokens, path, &mut map)), + Ok((module_id, tokens)) => { + dbg!("compiled: ", module_id); + (tokens.clone(), analyze(module_id, tokens, path, &mut map)) + } Err(e) => (Vec::new(), Err(e)), }; @@ -449,10 +474,21 @@ fn reid_error_into_diagnostic(error: &error_raporting::ErrorKind, tokens: &Vec Result<(SourceModuleId, Vec), ReidError> { +fn parse( + source: &str, + path: PathBuf, + map: &mut ErrorModules, + module_id: SourceModuleId, +) -> Result<(SourceModuleId, Vec), ReidError> { let file_name = path.file_name().unwrap().to_str().unwrap().to_owned(); - Ok(parse_module(source, file_name.clone(), map)?) + Ok(parse_module( + source, + file_name.clone(), + Some(path), + map, + Some(module_id), + )?) } #[tokio::main] @@ -463,6 +499,9 @@ async fn main() { let (service, socket) = LspService::new(|client| Backend { client, analysis: DashMap::new(), + module_to_url: DashMap::new(), + url_to_module: DashMap::new(), + module_id_counter: Mutex::new(SourceModuleId(0)), }); Server::new(stdin, stdout, socket).serve(service).await; } diff --git a/reid/src/error_raporting.rs b/reid/src/error_raporting.rs index 3286952..dddaf6d 100644 --- a/reid/src/error_raporting.rs +++ b/reid/src/error_raporting.rs @@ -1,6 +1,7 @@ use std::{ collections::HashMap, fmt::{Debug, Write}, + path::PathBuf, }; use crate::{ @@ -95,21 +96,46 @@ pub struct ErrorModule { #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct ErrorModules { pub(super) module_map: HashMap, + pub(super) source_id_map: HashMap, module_counter: mir::SourceModuleId, } impl ErrorModules { - pub fn add_module>(&mut self, name: T) -> Option { - let id = self.module_counter.increment(); - self.module_map.insert( - id, - ErrorModule { - name: name.into(), - tokens: None, - source: None, - }, - ); - Some(id) + pub fn add_module>( + &mut self, + name: T, + path: Option, + external_module_id: Option, + ) -> Option { + let module_id = path.as_ref().and_then(|p| self.source_id_map.get(p)); + + if let Some(module_id) = module_id { + Some(*module_id) + } else { + let id = if let Some(module_id) = external_module_id { + self.module_counter = SourceModuleId(module_id.0.max(self.module_counter.0)); + if let Some(_) = self.module_map.get(&module_id) { + panic!("Can not use external module id: Module already exists!") + } + module_id + } else { + self.module_counter.increment() + }; + + if let Some(path) = path { + self.source_id_map.insert(path, id); + } + + self.module_map.insert( + id, + ErrorModule { + name: name.into(), + tokens: None, + source: None, + }, + ); + Some(id) + } } pub fn set_tokens(&mut self, id: mir::SourceModuleId, tokens: Vec) { diff --git a/reid/src/lib.rs b/reid/src/lib.rs index b954363..37610c4 100644 --- a/reid/src/lib.rs +++ b/reid/src/lib.rs @@ -69,7 +69,10 @@ use reid_lib::{compile::CompileOutput, Context}; use crate::{ ast::TopLevelStatement, - mir::macros::{form_macros, MacroModule, MacroPass}, + mir::{ + macros::{form_macros, MacroModule, MacroPass}, + SourceModuleId, + }, }; pub mod ast; @@ -83,9 +86,11 @@ mod util; pub fn parse_module<'map, T: Into>( source: &str, name: T, + path: Option, map: &'map mut ErrorModules, + module_id: Option, ) -> Result<(mir::SourceModuleId, Vec), ReidError> { - let id = map.add_module(name.into()).unwrap(); + let id = map.add_module(name.into(), path, module_id).unwrap(); map.set_source(id, source.to_owned()); let tokens = ReidError::from_lexer(lexer::tokenize(source), map.clone(), id)?; @@ -317,7 +322,7 @@ pub fn compile_and_pass<'map>( let path = path.canonicalize().unwrap(); let name = path.file_name().unwrap().to_str().unwrap().to_owned(); - let (id, tokens) = parse_module(source, name, module_map)?; + let (id, tokens) = parse_module(source, name, Some(path.clone()), module_map, None)?; let module = compile_module(id, tokens, module_map, Some(path.clone()), true)?.map_err(|(_, e)| e)?; let mut mir_context = mir::Context::from(vec![module], path.parent().unwrap().to_owned()); diff --git a/reid/src/mir/linker.rs b/reid/src/mir/linker.rs index 747c059..0772f37 100644 --- a/reid/src/mir/linker.rs +++ b/reid/src/mir/linker.rs @@ -51,7 +51,7 @@ pub enum ErrorKind { } pub fn compile_std(module_map: &mut ErrorModules) -> Result { - let (id, tokens) = parse_module(STD_SOURCE, STD_NAME, module_map)?; + let (id, tokens) = parse_module(STD_SOURCE, STD_NAME, None, module_map, None)?; let module = compile_module(id, tokens, module_map, None, false)?.map_err(|(_, e)| e)?; let module_id = module.module_id; @@ -143,7 +143,13 @@ impl<'map> Pass for LinkerPass<'map> { continue; }; - let (id, tokens) = match parse_module(&source, module_name.clone(), &mut self.module_map) { + let (id, tokens) = match parse_module( + &source, + module_name.clone(), + Some(file_path.clone()), + &mut self.module_map, + None, + ) { Ok(val) => val, Err(err) => { state.ok::<_, Infallible>( diff --git a/reid/tests/e2e.rs b/reid/tests/e2e.rs index db30f45..7ba6c9f 100644 --- a/reid/tests/e2e.rs +++ b/reid/tests/e2e.rs @@ -14,7 +14,7 @@ mod util; fn test_compile(source: &str, name: &str) -> CompileOutput { assert_err(assert_err(std::panic::catch_unwind(|| { let mut map = Default::default(); - let (id, tokens) = assert_err(parse_module(source, name, &mut map)); + let (id, tokens) = assert_err(parse_module(source, name, None, &mut map, None)); let module = assert_err(assert_err(compile_module(id, tokens, &mut map, None, true)).map_err(|(_, e)| e)); let mut mir_context = mir::Context::from(vec![module], Default::default());