Add importer pass, make importer import module properly

This commit is contained in:
Sofia 2025-07-14 20:33:02 +03:00
parent a71843dfe9
commit 848347e4a8
5 changed files with 39 additions and 18 deletions

View File

@ -42,7 +42,9 @@
use std::path::PathBuf;
use mir::{typecheck::TypeCheck, typeinference::TypeInference, typerefs::TypeRefs};
use mir::{
imports::ImportsPass, typecheck::TypeCheck, typeinference::TypeInference, typerefs::TypeRefs,
};
use reid_lib::Context;
use crate::{ast::TopLevelStatement, lexer::Token, token_stream::TokenStream};
@ -65,7 +67,11 @@ pub enum ReidError {
TypeCheckErrors(Vec<mir::pass::Error<mir::typecheck::ErrorKind>>),
}
pub fn compile_module(source: &str, path: Option<PathBuf>) -> Result<mir::Module, ReidError> {
pub fn compile_module(
source: &str,
name: String,
path: Option<PathBuf>,
) -> Result<mir::Module, ReidError> {
let tokens = lexer::tokenize(source)?;
dbg!(&tokens);
@ -80,7 +86,7 @@ pub fn compile_module(source: &str, path: Option<PathBuf>) -> Result<mir::Module
}
let ast_module = ast::Module {
name: "test".to_owned(),
name,
top_level_statements: statements,
path,
};
@ -92,13 +98,23 @@ pub fn compile_module(source: &str, path: Option<PathBuf>) -> Result<mir::Module
/// and `hello.asm` from it, which can be linked using `ld` to produce an
/// executable file.
pub fn compile(source: &str, path: PathBuf) -> Result<String, ReidError> {
let path = path.canonicalize().unwrap();
let mut mir_context = mir::Context::from(
vec![compile_module(source, Some(path.clone()))?],
vec![compile_module(
source,
"main".to_owned(),
Some(path.clone()),
)?],
path.parent().unwrap().to_owned(),
);
println!("{}", &mir_context);
let state = mir_context.pass(&mut ImportsPass);
dbg!(&state);
println!("{}", &mir_context);
let refs = TypeRefs::default();
let state = mir_context.pass(&mut TypeInference { refs: &refs });

View File

@ -40,7 +40,8 @@ impl Display for FunctionDefinition {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"fn {}({}) -> {} ",
"{}fn {}({}) -> {} ",
if self.is_pub { "pub " } else { "" },
self.name,
self.parameters
.iter()

View File

@ -24,7 +24,7 @@ pub enum ErrorKind {
/// Struct used to implement a type-checking pass that can be performed on the
/// MIR.
pub struct ImportsPass {}
pub struct ImportsPass;
impl Pass for ImportsPass {
type TError = ErrorKind;
@ -35,13 +35,9 @@ impl Pass for ImportsPass {
modules.insert(module.name.clone(), module);
}
let mut modules_to_process: Vec<_> = modules.values().cloned().collect();
let iter = modules_to_process.iter_mut();
for module in iter {
let mut new_modules = Vec::new();
let mut modules_to_process: Vec<Module> = modules.values().cloned().collect();
while let Some(mut module) = modules_to_process.pop() {
for import in &module.imports {
let Import(path, _) = import;
if path.len() != 2 {
@ -56,8 +52,10 @@ impl Pass for ImportsPass {
let imported = if let Some(module) = modules.get(module_name) {
module
} else {
let file_path = PathBuf::from(&context.base.clone()).join(module_name);
let file_path =
PathBuf::from(&context.base.clone()).join(module_name.to_owned() + ".reid");
dbg!(&file_path);
let Ok(source) = fs::read_to_string(&file_path) else {
state.ok::<_, Infallible>(
Err(ErrorKind::ModuleNotFound(module_name.clone())),
@ -66,10 +64,12 @@ impl Pass for ImportsPass {
continue;
};
match compile_module(&source, Some(file_path)) {
match compile_module(&source, module_name.clone(), Some(file_path)) {
Ok(m) => {
new_modules.push(m);
new_modules.last().unwrap()
let module_name = module.name.clone();
modules.insert(module_name.clone(), m);
modules_to_process.push(modules.get_mut(&module_name).unwrap().clone());
modules.get(&module_name).unwrap()
}
Err(err) => {
state.ok::<_, Infallible>(
@ -115,6 +115,10 @@ impl Pass for ImportsPass {
kind: super::FunctionDefinitionKind::Extern,
});
}
}
modules.insert(module.name.clone(), module);
}
context.modules = modules.into_values().collect();
}
}

View File

@ -234,7 +234,7 @@ impl Module {
pass.module(self, PassState::from(state, scope));
for function in &mut self.functions {
function.pass(pass, state, scope);
function.pass(pass, state, &mut scope.inner());
}
}
}

View File

@ -92,7 +92,7 @@ impl FunctionDefinition {
let inferred = match &mut self.kind {
FunctionDefinitionKind::Local(block, _) => {
state.scope.return_type_hint = Some(self.return_type.clone());
block.typecheck(state, &hints, Some(&return_type))
block.typecheck(&mut state.inner(), &hints, Some(&return_type))
}
FunctionDefinitionKind::Extern => {
Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown)))