Add possibility to pre-define module-ids

This commit is contained in:
Sofia 2025-08-03 22:32:31 +03:00
parent 7809aeb2b5
commit 3b3b21d4dc
7 changed files with 100 additions and 26 deletions

View File

@ -6,6 +6,6 @@ import module_importee::test;
fn main() -> u32 {
let value = 0b110;
let other = 0o17;
return value * other + test().field * -value;
}

View File

@ -69,8 +69,6 @@ impl StaticAnalysis {
}
}
dbg!(&references);
Some(references)
}
}

View File

@ -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<String, StaticAnalysis>,
module_to_url: DashMap<SourceModuleId, PathBuf>,
url_to_module: DashMap<PathBuf, SourceModuleId>,
module_id_counter: Mutex<SourceModuleId>,
}
#[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(&params.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(&params.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<F
}
}
fn parse(source: &str, path: PathBuf, map: &mut ErrorModules) -> Result<(SourceModuleId, Vec<FullToken>), ReidError> {
fn parse(
source: &str,
path: PathBuf,
map: &mut ErrorModules,
module_id: SourceModuleId,
) -> Result<(SourceModuleId, Vec<FullToken>), 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;
}

View File

@ -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<mir::SourceModuleId, ErrorModule>,
pub(super) source_id_map: HashMap<PathBuf, mir::SourceModuleId>,
module_counter: mir::SourceModuleId,
}
impl ErrorModules {
pub fn add_module<T: Into<String>>(&mut self, name: T) -> Option<mir::SourceModuleId> {
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<T: Into<String>>(
&mut self,
name: T,
path: Option<PathBuf>,
external_module_id: Option<SourceModuleId>,
) -> Option<mir::SourceModuleId> {
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<FullToken>) {

View File

@ -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<String>>(
source: &str,
name: T,
path: Option<PathBuf>,
map: &'map mut ErrorModules,
module_id: Option<SourceModuleId>,
) -> Result<(mir::SourceModuleId, Vec<FullToken>), 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());

View File

@ -51,7 +51,7 @@ pub enum ErrorKind {
}
pub fn compile_std(module_map: &mut ErrorModules) -> Result<Module, ReidError> {
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>(

View File

@ -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());